diff options
author | Vincent Untz <vuntz@gnome.org> | 2009-07-15 16:29:48 +0200 |
---|---|---|
committer | Vincent Untz <vuntz@gnome.org> | 2009-07-27 12:26:48 +0200 |
commit | 1ca602c3d7163242e00f03e2af02cfc006c3ddd0 (patch) | |
tree | 6a1ead0a97cfa09c70f593795d66de05e0763476 | |
parent | aed3a2b0e714f8d475129c06e03ef1b78daa6c10 (diff) | |
download | libwnck-1ca602c3d7163242e00f03e2af02cfc006c3ddd0.tar.gz |
[urgency] Add the wnck-urgency-monitor utility
This small utility monitors windows that have the urgency hint set, and
displays a notification icon for each of them. It's useful for people
not using the window list and who don't want to miss something happening
in some window.
-rw-r--r-- | libwnck/Makefile.am | 10 | ||||
-rw-r--r-- | libwnck/wnck-urgency-monitor.c | 218 |
2 files changed, 226 insertions, 2 deletions
diff --git a/libwnck/Makefile.am b/libwnck/Makefile.am index 5fc6a7c..9b6e8a8 100644 --- a/libwnck/Makefile.am +++ b/libwnck/Makefile.am @@ -61,6 +61,9 @@ $(libwnck_1_la_OBJECTS): inlinepixbufs.h wnckprop_SOURCES= \ wnckprop.c +wnck_urgency_monitor_SOURCES= \ + wnck-urgency-monitor.c + test_wnck_SOURCES= \ test-wnck.c @@ -74,10 +77,10 @@ test_pager_SOURCES= \ test-pager.c bin_PROGRAMS= \ - wnckprop + wnckprop \ + wnck-urgency-monitor noinst_PROGRAMS= \ - wnckprop \ test-pager \ test-wnck \ test-selector \ @@ -94,6 +97,9 @@ libwnck_1_la_LIBADD= \ wnckprop_LDADD= \ @LIBWNCK_LIBS@ ./$(lib_LTLIBRARIES) +wnck_urgency_monitor_LDADD= \ + @LIBWNCK_LIBS@ ./$(lib_LTLIBRARIES) + test_wnck_LDADD=@LIBWNCK_LIBS@ ./$(lib_LTLIBRARIES) test_tasklist_LDADD=@LIBWNCK_LIBS@ ./$(lib_LTLIBRARIES) test_selector_LDADD=@LIBWNCK_LIBS@ ./$(lib_LTLIBRARIES) diff --git a/libwnck/wnck-urgency-monitor.c b/libwnck/wnck-urgency-monitor.c new file mode 100644 index 0000000..da88234 --- /dev/null +++ b/libwnck/wnck-urgency-monitor.c @@ -0,0 +1,218 @@ +/* vim: set sw=2 et: */ +/* + * Copyright (C) 2009 Vincent Untz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * Vincent Untz <vuntz@gnome.org> + */ + +#include <config.h> + +#include <stdlib.h> +#include <string.h> + +#include <gtk/gtk.h> + +#include <libwnck/libwnck.h> + +static void +status_icon_activated (GtkStatusIcon *icon, + WnckWindow *window) +{ + WnckWorkspace *workspace; + guint32 timestamp; + + /* We're in an activate callback, so gtk_get_current_time() works... */ + timestamp = gtk_get_current_event_time (); + + /* FIXME: THIS IS SICK AND WRONG AND BUGGY. See the end of + * http://mail.gnome.org/archives/wm-spec-list/2005-July/msg00032.html + * There should only be *one* activate call. + */ + workspace = wnck_window_get_workspace (window); + if (workspace) + wnck_workspace_activate (workspace, timestamp); + + wnck_window_activate (window, timestamp); +} + +static GtkStatusIcon * +status_icon_get (WnckWindow *window) +{ + return g_object_get_data (G_OBJECT (window), "wnck-urgency-icon"); +} + +static void +status_icon_update (WnckWindow *window) +{ + GtkStatusIcon *icon; + + icon = status_icon_get (window); + + if (icon == NULL) + { + return; + } + + if (wnck_window_get_icon_is_fallback (window)) + { + gtk_status_icon_set_from_icon_name (icon, "dialog-information"); + } + else + { + gtk_status_icon_set_from_pixbuf (icon, + wnck_window_get_mini_icon (window)); + } + + gtk_status_icon_set_tooltip_text (icon, wnck_window_get_name (window)); +} + +static void +status_icon_create (WnckWindow *window) +{ + GtkStatusIcon *icon; + + icon = gtk_status_icon_new (); + g_object_set_data (G_OBJECT (window), "wnck-urgency-icon", icon); + + g_signal_connect (icon, "activate", + G_CALLBACK (status_icon_activated), window); + + status_icon_update (window); +} + +static void +status_icon_remove (WnckWindow *window) +{ + GtkStatusIcon *icon; + + icon = status_icon_get (window); + if (icon != NULL) + { + gtk_status_icon_set_visible (icon, FALSE); + g_object_unref (icon); + g_object_set_data (G_OBJECT (window), "wnck-urgency-icon", NULL); + } +} + +static void +window_state_changed (WnckWindow *window, + WnckWindowState changed_mask, + WnckWindowState new_state, + gpointer data) +{ + GtkStatusIcon *icon; + + if (! + (changed_mask & + (WNCK_WINDOW_STATE_DEMANDS_ATTENTION | + WNCK_WINDOW_STATE_URGENT))) + return; + + icon = status_icon_get (window); + + if (wnck_window_or_transient_needs_attention (window)) + { + if (icon == NULL) + { + status_icon_create (window); + } + } + else + { + status_icon_remove (window); + } +} + +static void +window_icon_changed (WnckWindow *window, + gpointer data) +{ + status_icon_update (window); +} + +static void +window_name_changed (WnckWindow *window, + gpointer data) +{ + status_icon_update (window); +} + +static void +connect_to_window (WnckScreen *screen, + WnckWindow *window) +{ + if (wnck_window_or_transient_needs_attention (window)) + { + status_icon_create (window); + } + + g_signal_connect (window, "state_changed", + G_CALLBACK (window_state_changed), NULL); + g_signal_connect (window, "icon_changed", + G_CALLBACK (window_icon_changed), NULL); + g_signal_connect (window, "name_changed", + G_CALLBACK (window_name_changed), NULL); +} + +static void +disconnect_from_window (WnckScreen *screen, + WnckWindow *window) +{ + status_icon_remove (window); +} + +int +main (int argc, char **argv) +{ + GOptionContext *ctxt; + GError *error; + WnckScreen *screen; + + ctxt = g_option_context_new (NULL); + g_option_context_set_summary (ctxt, "Monitor windows with the urgency hint " + "set, and display a notification icon " + "for each of them."); + g_option_context_add_group (ctxt, gtk_get_option_group (TRUE)); + + error = NULL; + if (!g_option_context_parse (ctxt, &argc, &argv, &error)) + { + g_printerr ("Error while parsing arguments: %s\n", error->message); + g_option_context_free (ctxt); + g_error_free (error); + return 1; + } + + g_option_context_free (ctxt); + ctxt = NULL; + + gtk_init (&argc, &argv); + + wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER); + + screen = wnck_screen_get_default (); + g_signal_connect (screen, "window_opened", + G_CALLBACK (connect_to_window), NULL); + g_signal_connect (screen, "window_closed", + G_CALLBACK (disconnect_from_window), NULL); + + gtk_main (); + + return 0; +} |