[libwnck] [urgency] Add the wnck-urgency-monitor utility



commit 1ca602c3d7163242e00f03e2af02cfc006c3ddd0
Author: Vincent Untz <vuntz gnome org>
Date:   Wed Jul 15 16:29:48 2009 +0200

    [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.

 libwnck/Makefile.am            |   10 ++-
 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;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]