[gnome-settings-daemon] Make 'Locate Pointer a separate process



commit ba9e7dcb6fc38335c6c2bb216f1c619bdae807d1
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Aug 31 15:29:07 2009 -0400

    Make 'Locate Pointer a separate process
    
    This avoids interference with other plugins X event filtering needs.
    Also, make the locate pointer code work with GTK+ 2.17.
    Bug 524499.

 plugins/mouse/Makefile.am          |   21 +++-
 plugins/mouse/gsd-locate-pointer.c |  189 ++++++++++++++++++++++++++++++++----
 plugins/mouse/gsd-mouse-manager.c  |  172 ++++++---------------------------
 3 files changed, 216 insertions(+), 166 deletions(-)
---
diff --git a/plugins/mouse/Makefile.am b/plugins/mouse/Makefile.am
index 385588d..315e1bc 100644
--- a/plugins/mouse/Makefile.am
+++ b/plugins/mouse/Makefile.am
@@ -4,11 +4,7 @@ libmouse_la_SOURCES = 		\
 	gsd-mouse-plugin.h	\
 	gsd-mouse-plugin.c	\
 	gsd-mouse-manager.h	\
-	gsd-mouse-manager.c	\
-	gsd-locate-pointer.h	\
-	gsd-locate-pointer.c	\
-	gsd-timeline.h		\
-	gsd-timeline.c
+	gsd-mouse-manager.c
 
 libmouse_la_CPPFLAGS = \
 	-I$(top_srcdir)/gnome-settings-daemon		\
@@ -30,6 +26,21 @@ plugin_in_files = mouse.gnome-settings-plugin.in
 
 plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
 
+libexec_PROGRAMS = gsd-locate-pointer
+
+gsd_locate_pointer_SOURCES = 	\
+	gsd-locate-pointer.h	\
+	gsd-locate-pointer.c	\
+	gsd-timeline.h		\
+	gsd-timeline.c
+
+gsd_locate_pointer_CFLAGS = \
+	$(SETTINGS_PLUGIN_CFLAGS)	\
+	$(AM_CFLAGS)
+
+gsd_locate_pointer_LDADD  = 		\
+	$(SETTINGS_PLUGIN_LIBS)
+
 EXTRA_DIST = $(plugin_in_files)
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
diff --git a/plugins/mouse/gsd-locate-pointer.c b/plugins/mouse/gsd-locate-pointer.c
index 121cdc8..e033b0e 100644
--- a/plugins/mouse/gsd-locate-pointer.c
+++ b/plugins/mouse/gsd-locate-pointer.c
@@ -21,6 +21,10 @@
 #include "gsd-timeline.h"
 #include "gsd-locate-pointer.h"
 
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+#include <X11/keysym.h>
+
 #define ANIMATION_LENGTH 750
 #define WINDOW_SIZE 101
 #define N_CIRCLES 4
@@ -114,40 +118,38 @@ locate_pointer_paint (GsdLocatePointerData *data,
 }
 
 static gboolean
-locate_pointer_expose (GtkWidget *widget,
+locate_pointer_expose (GtkWidget      *widget,
 		       GdkEventExpose *event,
 		       gpointer        user_data)
 {
   GsdLocatePointerData *data = (GsdLocatePointerData *) user_data;
   cairo_t *cr;
-  GdkBitmap *mask;
 
   if (event->window != data->window)
     return FALSE;
 
   cr = gdk_cairo_create (data->window);
-
-  if (gtk_widget_is_composited (data->widget))
-    locate_pointer_paint (data, cr, TRUE);
-  else
-    {
-      locate_pointer_paint (data, cr, FALSE);
-      cairo_destroy (cr);
-
-      /* create a bitmap for the shape, reuse the cairo_t to paint on it */
-      mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
-      cr = gdk_cairo_create (mask);
-      locate_pointer_paint (data, cr, FALSE);
-      gdk_window_shape_combine_mask (data->window, mask, 0, 0);
-      g_object_unref (mask);
-    }
-
+  locate_pointer_paint (data, cr, gtk_widget_is_composited (data->widget));
   cairo_destroy (cr);
 
   return TRUE;
 }
 
 static void
+update_shape (GsdLocatePointerData *data)
+{
+  cairo_t *cr;
+  GdkBitmap *mask;
+
+  mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
+  cr = gdk_cairo_create (mask);
+  locate_pointer_paint (data, cr, FALSE);
+  gdk_window_shape_combine_mask (data->window, mask, 0, 0);
+  g_object_unref (mask);
+  cairo_destroy (cr);
+}
+
+static void
 timeline_frame_cb (GsdTimeline *timeline,
 		   gdouble      progress,
 		   gpointer     user_data)
@@ -164,6 +166,7 @@ timeline_frame_cb (GsdTimeline *timeline,
   else if (progress >= data->progress + CIRCLES_PROGRESS_INTERVAL)
     {
       /* only invalidate window each circle interval */
+      update_shape (data);
       gdk_window_invalidate_rect (data->window, NULL, FALSE);
       data->progress += CIRCLES_PROGRESS_INTERVAL;
     }
@@ -336,10 +339,156 @@ gsd_locate_pointer (GdkScreen *screen)
   g_signal_connect (data->widget, "composited-changed",
                     G_CALLBACK (composited_changed), data);
 
+  move_locate_pointer_window (data, screen);
   composited_changed (data->widget, data);
-
   gdk_window_show (data->window);
-  move_locate_pointer_window (data, screen);
 
   gsd_timeline_start (data->timeline);
 }
+
+
+#define KEYBOARD_GROUP_SHIFT 13
+#define KEYBOARD_GROUP_MASK ((1 << 13) | (1 << 14))
+
+/* Owen magic */
+static GdkFilterReturn
+filter (GdkXEvent *xevent,
+        GdkEvent  *event,
+        gpointer   data)
+{
+  XEvent *xev = (XEvent *) xevent;
+  guint keyval;
+  gint group;
+
+  GdkScreen *screen = (GdkScreen *)data;
+
+  if (xev->type == KeyPress || xev->type == KeyRelease)
+    {
+      /* get the keysym */
+      group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT;
+      gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
+                                           xev->xkey.keycode,
+                                           xev->xkey.state,
+                                           group,
+                                           &keyval,
+                                           NULL, NULL, NULL);
+      if (keyval == GDK_Control_L || keyval == GDK_Control_R)
+        {
+          if (xev->type == KeyPress)
+            {
+              XAllowEvents (xev->xkey.display,
+                            SyncKeyboard,
+                            xev->xkey.time);
+            }
+          else
+            {
+              XAllowEvents (xev->xkey.display,
+                            AsyncKeyboard,
+                            xev->xkey.time);
+              gsd_locate_pointer (screen);
+            }
+        }
+      else
+        {
+          XAllowEvents (xev->xkey.display,
+                        ReplayKeyboard,
+                        xev->xkey.time);
+          XUngrabKeyboard (gdk_x11_get_default_xdisplay (),
+                           xev->xkey.time);
+        }
+    }
+
+  return GDK_FILTER_CONTINUE;
+}
+
+set_locate_pointer (void)
+{
+  GdkKeymapKey *keys;
+  GdkDisplay *display;
+  int n_screens;
+  int n_keys;
+  gboolean has_entries;
+  static const guint keyvals[] = { GDK_Control_L, GDK_Control_R };
+  unsigned j;
+
+  display = gdk_display_get_default ();
+  n_screens = gdk_display_get_n_screens (display);
+
+  for (j = 0 ; j < G_N_ELEMENTS (keyvals) ; j++)
+    {
+      has_entries = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
+                                                       keyvals[j],
+                                                       &keys,
+                                                       &n_keys);
+      if (has_entries)
+        {
+          gint i, j;
+          for (i = 0; i < n_keys; i++)
+            {
+              for (j=0; j< n_screens; j++)
+                {
+                  GdkScreen *screen;
+                  Window xroot;
+
+                  screen = gdk_display_get_screen (display, j);
+                  xroot = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (screen));
+
+                  XGrabKey (GDK_DISPLAY_XDISPLAY (display),
+                            keys[i].keycode,
+                            0,
+                            xroot,
+                            False,
+                            GrabModeAsync,
+                            GrabModeSync);
+                  XGrabKey (GDK_DISPLAY_XDISPLAY (display),
+                            keys[i].keycode,
+                            LockMask,
+                            xroot,
+                            False,
+                            GrabModeAsync,
+                            GrabModeSync);
+                  XGrabKey (GDK_DISPLAY_XDISPLAY (display),
+                            keys[i].keycode,
+                            Mod2Mask,
+                            xroot,
+                            False,
+                            GrabModeAsync,
+                            GrabModeSync);
+                  XGrabKey (GDK_DISPLAY_XDISPLAY (display),
+                            keys[i].keycode,
+                            Mod4Mask,
+                            xroot,
+                            False,
+                            GrabModeAsync,
+                            GrabModeSync);
+                }
+            }
+
+          g_free (keys);
+
+          for (i = 0; i < n_screens; i++)
+            {
+              GdkScreen *screen;
+
+              screen = gdk_display_get_screen (display, i);
+              gdk_window_add_filter (gdk_screen_get_root_window (screen),
+                                     filter,
+                                     screen);
+            }
+        }
+    }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  gtk_init (&argc, &argv);
+
+  set_locate_pointer ();
+
+  gtk_main ();
+
+  return 0;
+}
+
diff --git a/plugins/mouse/gsd-mouse-manager.c b/plugins/mouse/gsd-mouse-manager.c
index 08bd3a8..1b121ae 100644
--- a/plugins/mouse/gsd-mouse-manager.c
+++ b/plugins/mouse/gsd-mouse-manager.c
@@ -50,8 +50,6 @@
 #include "gnome-settings-profile.h"
 #include "gsd-mouse-manager.h"
 
-#include "gsd-locate-pointer.h"
-
 #define GSD_MOUSE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MOUSE_MANAGER, GsdMouseManagerPrivate))
 
 #define GCONF_MOUSE_DIR         "/desktop/gnome/peripherals/mouse"
@@ -78,6 +76,8 @@ struct GsdMouseManagerPrivate
         gboolean mousetweaks_daemon_running;
         gboolean syndaemon_spawned;
         GPid syndaemon_pid;
+	gboolean locate_pointer_spawned;
+	GPid locate_pointer_pid;
 };
 
 static void     gsd_mouse_manager_class_init  (GsdMouseManagerClass *klass);
@@ -703,149 +703,39 @@ set_edge_scroll (int method)
         return 0;
 }
 
-#define KEYBOARD_GROUP_SHIFT 13
-#define KEYBOARD_GROUP_MASK ((1 << 13) | (1 << 14))
-
-/* Owen magic */
-static GdkFilterReturn
-filter (GdkXEvent *xevent,
-        GdkEvent  *event,
-        gpointer   data)
-{
-        XEvent *xev = (XEvent *) xevent;
-        guint keyval;
-        gint group;
-
-        GdkScreen *screen = (GdkScreen *)data;
-
-        if (xev->type == KeyPress ||
-            xev->type == KeyRelease) {
-                /* get the keysym */
-                group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT;
-                gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
-                                                     xev->xkey.keycode,
-                                                     xev->xkey.state,
-                                                     group,
-                                                     &keyval,
-                                                     NULL, NULL, NULL);
-                if (keyval == GDK_Control_L || keyval == GDK_Control_R) {
-                        if (xev->type == KeyPress) {
-                                XAllowEvents (xev->xkey.display,
-                                              SyncKeyboard,
-                                              xev->xkey.time);
-                        } else {
-                                XAllowEvents (xev->xkey.display,
-                                              AsyncKeyboard,
-                                              xev->xkey.time);
-                                gsd_locate_pointer (screen);
-                        }
-                } else {
-                        XAllowEvents (xev->xkey.display,
-                                      ReplayKeyboard,
-                                      xev->xkey.time);
-                        XUngrabKeyboard (gdk_x11_get_default_xdisplay (),
-                                         xev->xkey.time);
-                }
-        }
-        return GDK_FILTER_CONTINUE;
-}
-
 static void
 set_locate_pointer (GsdMouseManager *manager,
-                    gboolean         locate_pointer)
+                    gboolean         state)
 {
-        GdkKeymapKey *keys;
-        GdkDisplay *display;
-        int n_screens;
-        int n_keys;
-        gboolean has_entries;
-        static const guint keyvals[] = { GDK_Control_L, GDK_Control_R };
-        unsigned j;
-
-        display = gdk_display_get_default ();
-        n_screens = gdk_display_get_n_screens (display);
-
-        for (j = 0 ; j < G_N_ELEMENTS (keyvals) ; j++) {
-                has_entries = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
-                                                                 keyvals[j],
-                                                                 &keys,
-                                                                 &n_keys);
-                if (has_entries) {
-                        gint i, j;
-
-                        for (i = 0; i < n_keys; i++) {
-                                for(j=0; j< n_screens; j++) {
-                                        GdkScreen *screen = gdk_display_get_screen (display, j);
-                                        Window xroot = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (screen));
-
-                                        if (locate_pointer) {
-                                                XGrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                          keys[i].keycode,
-                                                          0,
-                                                          xroot,
-                                                          False,
-                                                          GrabModeAsync,
-                                                          GrabModeSync);
-                                                XGrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                          keys[i].keycode,
-                                                          LockMask,
-                                                          xroot,
-                                                          False,
-                                                          GrabModeAsync,
-                                                          GrabModeSync);
-                                                XGrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                          keys[i].keycode,
-                                                          Mod2Mask,
-                                                          xroot,
-                                                          False,
-                                                          GrabModeAsync,
-                                                          GrabModeSync);
-                                                XGrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                          keys[i].keycode,
-                                                          Mod4Mask,
-                                                          xroot,
-                                                          False,
-                                                          GrabModeAsync,
-                                                          GrabModeSync);
-                                        } else {
-                                                XUngrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                            keys[i].keycode,
-                                                            Mod4Mask,
-                                                            xroot);
-                                                XUngrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                            keys[i].keycode,
-                                                            Mod2Mask,
-                                                            xroot);
-                                                XUngrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                            keys[i].keycode,
-                                                            LockMask,
-                                                            xroot);
-                                                XUngrabKey (GDK_DISPLAY_XDISPLAY (display),
-                                                            keys[i].keycode,
-                                                            0,
-                                                            xroot);
-                                        }
-                                }
-                        }
-                        g_free (keys);
-                        if (locate_pointer) {
-                                for (i = 0; i < n_screens; i++) {
-                                        GdkScreen *screen;
-                                        screen = gdk_display_get_screen (display, i);
-                                        gdk_window_add_filter (gdk_screen_get_root_window (screen),
-                                                               filter,
-                                                               screen);
-                                }
-                        } else {
-                                for (i = 0; i < n_screens; i++) {
-                                        GdkScreen *screen;
-                                        screen = gdk_display_get_screen (display, i);
-                                        gdk_window_remove_filter (gdk_screen_get_root_window (screen),
-                                                                  filter,
-                                                                  screen);
-                                }
-                        }
+        if (state) {
+                GError        *error = NULL;
+                const char *args[2];
+
+                if (manager->priv->locate_pointer_spawned)
+                        return 0;
+
+                args[0] = "/usr/libexec/gsd-locate-pointer";
+                args[1] = NULL;
+
+                g_spawn_async (NULL, args, NULL,
+                               0, NULL, NULL,
+                               &manager->priv->locate_pointer_pid, &error);
+
+                manager->priv->locate_pointer_spawned = (error == NULL);
+
+                if (error) {
+                        GConfClient *client;
+                        client = gconf_client_get_default ();
+                        gconf_client_set_bool (client, KEY_LOCATE_POINTER, FALSE, NULL);
+                        g_object_unref (client);
+                        g_error_free (error);
                 }
+
+        }
+	else if (manager->priv->locate_pointer_spawned) {
+                kill (manager->priv->locate_pointer_pid, SIGHUP);
+                g_spawn_close_pid (manager->priv->locate_pointer_pid);
+                manager->priv->locate_pointer_spawned = FALSE;
         }
 }
 



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