[Xfce4-commits] <xfce4-settings:master> Share manager selection code of the helper and clipboard.

Jérôme Guelfucci noreply at xfce.org
Sat Jan 2 13:00:13 CET 2010


Updating branch refs/heads/master
         to 0b997936c202fcf1ca1c3242a2ab860331d5b79c (commit)
       from b37bb5bf745da84083dcd5e22249e2fcdb6e4e58 (commit)

commit 0b997936c202fcf1ca1c3242a2ab860331d5b79c
Author: Nick Schermer <nick at xfce.org>
Date:   Fri Nov 27 11:05:26 2009 +0100

    Share manager selection code of the helper and clipboard.
    
    Code is rougly the same, so this should probably work.
    
    Also properly stop the clipboard daemon.

 xfce4-settings-helper/Makefile.am              |    2 +
 xfce4-settings-helper/main.c                   |   83 ++++---------------
 xfce4-settings-helper/utils.c                  |  107 ++++++++++++++++++++++++
 xfce4-settings-helper/utils.h                  |   28 ++++++
 xfce4-settings-helper/xfce-clipboard-manager.c |   70 ++--------------
 5 files changed, 160 insertions(+), 130 deletions(-)

diff --git a/xfce4-settings-helper/Makefile.am b/xfce4-settings-helper/Makefile.am
index dc23081..e5ad7b0 100644
--- a/xfce4-settings-helper/Makefile.am
+++ b/xfce4-settings-helper/Makefile.am
@@ -26,6 +26,8 @@ xfce4_settings_helper_SOURCES = \
 	keyboard-layout.h \
 	pointers.c \
 	pointers.h \
+	utils.c \
+	utils.h \
 	workspaces.c \
 	workspaces.h \
 	xfce-clipboard-manager.c \
diff --git a/xfce4-settings-helper/main.c b/xfce4-settings-helper/main.c
index 054fba2..2d731ff 100644
--- a/xfce4-settings-helper/main.c
+++ b/xfce4-settings-helper/main.c
@@ -56,6 +56,7 @@
 #include "keyboard-shortcuts.h"
 #include "workspaces.h"
 #include "xfce-clipboard-manager.h"
+#include "utils.h"
 
 #ifdef HAVE_XRANDR
 #include "displays.h"
@@ -125,13 +126,14 @@ xfce_settings_helper_set_autostart_enabled (gboolean enabled)
 
 
 
-#ifdef GDK_WINDOWING_X11
 static GdkFilterReturn
 xfce_settings_helper_selection_watcher (GdkXEvent *xevt,
                                         GdkEvent *evt,
                                         gpointer user_data)
 {
-    Window xwin = GPOINTER_TO_UINT(user_data);
+#ifdef GDK_WINDOWING_X11
+    GtkWidget *invisible = GTK_WIDGET (user_data);
+    Window xwin = GDK_WINDOW_XID (invisible->window);
     XEvent *xe = (XEvent *)xevt;
 
     if (xe->type == SelectionClear && xe->xclient.window == xwin)
@@ -140,70 +142,10 @@ xfce_settings_helper_selection_watcher (GdkXEvent *xevt,
             xfce_sm_client_set_restart_style (sm_client, XFCE_SM_CLIENT_RESTART_NORMAL);
         gtk_main_quit ();
     }
-
+#endif
     return GDK_FILTER_CONTINUE;
 }
-#endif
-
-static gboolean
-xfce_settings_helper_acquire_selection (gboolean force)
-{
-#ifdef GDK_WINDOWING_X11
-    GdkDisplay *gdpy = gdk_display_get_default ();
-    GtkWidget *invisible;
-    Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
-    GdkWindow *rootwin = gdk_screen_get_root_window (gdk_display_get_screen (gdpy, 0));
-    Window xroot = GDK_WINDOW_XID (rootwin);
-    GdkAtom selection_atom;
-    Atom selection_atom_x11;
-    XClientMessageEvent xev;
-
-    selection_atom = gdk_atom_intern (SELECTION_NAME, FALSE);
-    selection_atom_x11 = gdk_x11_atom_to_xatom_for_display (gdpy, selection_atom);
-
-    /* can't use gdk for the selection owner here because it returns NULL
-     * if the selection owner is in another process */
-    if (!force && XGetSelectionOwner (dpy, selection_atom_x11) != None)
-        return FALSE;
-
-    invisible = gtk_invisible_new ();
-    gtk_widget_realize (invisible);
-    gtk_widget_add_events (invisible, GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK);
-
-    if (!gdk_selection_owner_set_for_display (gdpy, invisible->window,
-                                              selection_atom, GDK_CURRENT_TIME,
-                                              TRUE))
-    {
-        g_critical ("Unable to get selection " SELECTION_NAME);
-        gtk_widget_destroy (invisible);
-        return FALSE;
-    }
-
-    /* but we can use gdk here since we only care if it's our window */
-    if (gdk_selection_owner_get_for_display (gdpy, selection_atom) != invisible->window)
-    {
-        gtk_widget_destroy (invisible);
-        return FALSE;
-    }
-
-    xev.type = ClientMessage;
-    xev.window = xroot;
-    xev.message_type = gdk_x11_get_xatom_by_name_for_display (gdpy, "MANAGER");
-    xev.format = 32;
-    xev.data.l[0] = CurrentTime;
-    xev.data.l[1] = selection_atom_x11;
-    xev.data.l[2] = GDK_WINDOW_XID (invisible->window);
-    xev.data.l[3] = xev.data.l[4] = 0;
-
-    XSendEvent (dpy, xroot, False, StructureNotifyMask, (XEvent *)&xev);
 
-    gdk_window_add_filter (invisible->window,
-                           xfce_settings_helper_selection_watcher,
-                           GUINT_TO_POINTER (GDK_WINDOW_XID (invisible->window)));
-#endif
-
-    return TRUE;
-}
 
 
 gint
@@ -290,7 +232,8 @@ main (gint argc, gchar **argv)
     }
 
     in_session = xfce_sm_client_is_resumed (sm_client);
-    if (!xfce_settings_helper_acquire_selection (in_session))
+    if (!xfce_utils_selection_owner (SELECTION_NAME, in_session,
+                                     xfce_settings_helper_selection_watcher))
     {
         g_printerr ("%s is already running\n", G_LOG_DOMAIN);
         g_object_unref (G_OBJECT (sm_client));
@@ -331,7 +274,11 @@ main (gint argc, gchar **argv)
 
     /* Try to start the clipboard daemon */
     clipboard_daemon = xfce_clipboard_manager_new ();
-    xfce_clipboard_manager_start (clipboard_daemon);
+    if (!xfce_clipboard_manager_start (clipboard_daemon))
+    {
+        g_object_unref (G_OBJECT (clipboard_daemon));
+        clipboard_daemon = NULL;
+    }
 
     /* setup signal handlers to properly quit the main loop */
     if (xfce_posix_signal_handler_init (NULL))
@@ -355,7 +302,11 @@ main (gint argc, gchar **argv)
     g_object_unref (G_OBJECT (workspaces_helper));
 
     /* Stop the clipboard daemon */
-    xfce_clipboard_manager_stop (clipboard_daemon);
+    if (G_LIKELY (clipboard_daemon != NULL))
+    {
+        xfce_clipboard_manager_stop (clipboard_daemon);
+        g_object_unref (G_OBJECT (clipboard_daemon));
+    }
 
     /* shutdown xfconf */
     xfconf_shutdown ();
diff --git a/xfce4-settings-helper/utils.c b/xfce4-settings-helper/utils.c
new file mode 100644
index 0000000..345db69
--- /dev/null
+++ b/xfce4-settings-helper/utils.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#endif
+
+#include "utils.h"
+
+gboolean
+xfce_utils_selection_owner (const gchar   *selection_name,
+                            gboolean       force,
+                            GdkFilterFunc  filter_func)
+{
+#ifdef GDK_WINDOWING_X11
+    GdkDisplay *gdpy = gdk_display_get_default ();
+    GtkWidget *invisible;
+    Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
+    GdkWindow *rootwin = gdk_screen_get_root_window (gdk_display_get_screen (gdpy, 0));
+    Window xroot = GDK_WINDOW_XID (rootwin);
+    GdkAtom selection_atom;
+    Atom selection_atom_x11;
+    XClientMessageEvent xev;
+    gboolean has_owner;
+
+    g_return_val_if_fail (selection_name != NULL, FALSE);
+
+    selection_atom = gdk_atom_intern (selection_name, FALSE);
+    selection_atom_x11 = gdk_x11_atom_to_xatom_for_display (gdpy, selection_atom);
+
+    /* can't use gdk for the selection owner here because it returns NULL
+     * if the selection owner is in another process */
+    if (!force)
+    {
+        gdk_error_trap_push ();
+        has_owner = XGetSelectionOwner (dpy, selection_atom_x11) != None;
+        gdk_flush ();
+        gdk_error_trap_pop ();
+        if (has_owner)
+            return FALSE;
+    }
+
+    invisible = gtk_invisible_new ();
+    gtk_widget_realize (invisible);
+    gtk_widget_add_events (invisible, GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK);
+
+    if (!gdk_selection_owner_set_for_display (gdpy, invisible->window,
+                                              selection_atom, GDK_CURRENT_TIME,
+                                              TRUE))
+    {
+        g_critical ("Unable to get selection %s", selection_name);
+        gtk_widget_destroy (invisible);
+        return FALSE;
+    }
+
+    /* but we can use gdk here since we only care if it's our window */
+    if (gdk_selection_owner_get_for_display (gdpy, selection_atom) != invisible->window)
+    {
+        gtk_widget_destroy (invisible);
+        return FALSE;
+    }
+
+    xev.type = ClientMessage;
+    xev.window = xroot;
+    xev.message_type = gdk_x11_get_xatom_by_name_for_display (gdpy, "MANAGER");
+    xev.format = 32;
+    xev.data.l[0] = CurrentTime;
+    xev.data.l[1] = selection_atom_x11;
+    xev.data.l[2] = GDK_WINDOW_XID (invisible->window);
+    xev.data.l[3] = xev.data.l[4] = 0;
+
+    gdk_error_trap_push ();
+    XSendEvent (dpy, xroot, False, StructureNotifyMask, (XEvent *)&xev);
+    gdk_flush ();
+    if (gdk_error_trap_pop ())
+      g_critical ("Failed to send client event");
+
+    if (filter_func != NULL)
+        gdk_window_add_filter (invisible->window, filter_func, invisible);
+#endif
+
+    return TRUE;
+}
+
diff --git a/xfce4-settings-helper/utils.h b/xfce4-settings-helper/utils.h
new file mode 100644
index 0000000..8f5843f
--- /dev/null
+++ b/xfce4-settings-helper/utils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __XFCE_UTILS_H__
+#define __XFCE_UTILS_H__
+
+gboolean
+xfce_utils_selection_owner (const gchar   *selection_name,
+                            gboolean       force,
+                            GdkFilterFunc  filter_func);
+
+#endif
diff --git a/xfce4-settings-helper/xfce-clipboard-manager.c b/xfce4-settings-helper/xfce-clipboard-manager.c
index cef54d2..85e98a9 100644
--- a/xfce4-settings-helper/xfce-clipboard-manager.c
+++ b/xfce4-settings-helper/xfce-clipboard-manager.c
@@ -29,6 +29,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 
+#include "utils.h"
 #include "xfce-clipboard-manager.h"
 
 struct _XfceClipboardManagerClass
@@ -47,8 +48,6 @@ struct _XfceClipboardManager
   gchar        *primary_cache;
 
   gboolean      internal_change;
-
-  GtkWidget    *window;
 };
 
 
@@ -78,25 +77,6 @@ xfce_clipboard_manager_init (XfceClipboardManager *manager)
 
 
 
-Atom XA_CLIPBOARD_MANAGER;
-Atom XA_MANAGER;
-
-static void
-init_atoms (Display *display)
-{
-  static int _init_atoms = 0;
-
-  if (_init_atoms > 0)
-    return;
-
-  XA_CLIPBOARD_MANAGER = XInternAtom (display, "CLIPBOARD_MANAGER", False);
-  XA_MANAGER = XInternAtom (display, "MANAGER", False);
-
-  _init_atoms = 1;
-}
-
-
-
 static void
 xfce_clipboard_manager_default_store (XfceClipboardManager *manager)
 {
@@ -299,16 +279,8 @@ xfce_clipboard_manager_new (void)
 gboolean
 xfce_clipboard_manager_start (XfceClipboardManager *manager)
 {
-  XClientMessageEvent     xev;
-  Display                *display;
-  Window                  window;
-  Time                    timestamp;
-
   g_return_val_if_fail (XFCE_IS_CLIPBOARD_MANAGER (manager), FALSE);
 
-  display = GDK_DISPLAY ();
-  init_atoms (display);
-
   /* Check if there is a clipboard manager running */
   if (gdk_display_supports_clipboard_persistence (gdk_display_get_default ()))
     {
@@ -316,14 +288,11 @@ xfce_clipboard_manager_start (XfceClipboardManager *manager)
       return FALSE;
     }
 
-  manager->window = gtk_invisible_new ();
-  gtk_widget_realize (manager->window);
-
-  window = GDK_WINDOW_XID (manager->window->window);
-  timestamp = GDK_CURRENT_TIME;
-
-  XSelectInput (display, window, PropertyChangeMask);
-  XSetSelectionOwner (display, XA_CLIPBOARD_MANAGER, window, timestamp);
+  if (!xfce_utils_selection_owner ("CLIPBOARD_MANAGER", FALSE, NULL))
+    {
+      g_warning ("Unable to get the clipboard manager selection.");
+      return FALSE;
+    }
 
   g_signal_connect_swapped (manager->default_clipboard, "owner-change",
                             G_CALLBACK (xfce_clipboard_manager_default_owner_change),
@@ -332,30 +301,6 @@ xfce_clipboard_manager_start (XfceClipboardManager *manager)
                             G_CALLBACK (xfce_clipboard_manager_primary_owner_change),
                             manager);
 
-  /* Check to see if we managed to claim the selection. If not,
-   * we treat it as if we got it then immediately lost it
-   */
-  if (XGetSelectionOwner (display, XA_CLIPBOARD_MANAGER) == window)
-    {
-      xev.type = ClientMessage;
-      xev.window = DefaultRootWindow (display);
-      xev.message_type = XA_MANAGER;
-      xev.format = 32;
-      xev.data.l[0] = timestamp;
-      xev.data.l[1] = XA_CLIPBOARD_MANAGER;
-      xev.data.l[2] = window;
-      xev.data.l[3] = 0;      /* manager specific data */
-      xev.data.l[4] = 0;      /* manager specific data */
-
-      XSendEvent (display, DefaultRootWindow (display), False,
-                  StructureNotifyMask, (XEvent *)&xev);
-    }
-  else
-    {
-      xfce_clipboard_manager_stop (manager);
-      return FALSE;
-    }
-
   return TRUE;
 }
 
@@ -366,15 +311,12 @@ xfce_clipboard_manager_stop (XfceClipboardManager *manager)
 {
   g_return_if_fail (XFCE_IS_CLIPBOARD_MANAGER (manager));
 
-  g_debug ("Stopping clipboard manager");
-
   g_signal_handlers_disconnect_by_func (manager->default_clipboard,
                                         xfce_clipboard_manager_default_owner_change,
                                         manager);
   g_signal_handlers_disconnect_by_func (manager->primary_clipboard,
                                         xfce_clipboard_manager_primary_owner_change,
                                         manager);
-  gtk_widget_destroy (manager->window);
 
   if (manager->default_cache != NULL)
     {



More information about the Xfce4-commits mailing list