[Xfce4-commits] <xfce4-settings:master> Fix double spawning of the helper.
Nick Schermer
noreply at xfce.org
Tue Jul 27 20:58:01 CEST 2010
Updating branch refs/heads/master
to 0bd600f5d3d26aa48e482ecd9a75f961b86a5ace (commit)
from 2ddb597ed86f235e7cb3b4233a716d03b00a84d8 (commit)
commit 0bd600f5d3d26aa48e482ecd9a75f961b86a5ace
Author: Nick Schermer <nick at xfce.org>
Date: Tue Jul 27 20:53:54 2010 +0200
Fix double spawning of the helper.
The old code was crapy, use dbus to check for running instances
so never 2 processes are running.
xfce4-settings-helper/Makefile.am | 2 -
xfce4-settings-helper/clipboard-manager.c | 82 +++++++++++++++++++++-
xfce4-settings-helper/main.c | 83 ++++++++--------------
xfce4-settings-helper/utils.c | 110 -----------------------------
xfce4-settings-helper/utils.h | 28 -------
xfce4-settings-helper/workspaces.c | 1 -
6 files changed, 110 insertions(+), 196 deletions(-)
diff --git a/xfce4-settings-helper/Makefile.am b/xfce4-settings-helper/Makefile.am
index 7036699..e4ca94f 100644
--- a/xfce4-settings-helper/Makefile.am
+++ b/xfce4-settings-helper/Makefile.am
@@ -28,8 +28,6 @@ xfce4_settings_helper_SOURCES = \
keyboard-layout.h \
pointers.c \
pointers.h \
- utils.c \
- utils.h \
workspaces.c \
workspaces.h
diff --git a/xfce4-settings-helper/clipboard-manager.c b/xfce4-settings-helper/clipboard-manager.c
index d214dbe..a67b4b3 100644
--- a/xfce4-settings-helper/clipboard-manager.c
+++ b/xfce4-settings-helper/clipboard-manager.c
@@ -305,6 +305,86 @@ xfce_clipboard_manager_primary_owner_change (XfceClipboardManager *manager,
+static gboolean
+xfce_clipboard_manager_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));
+ GdkWindow *invisible_window;
+ 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);
+
+ invisible_window = gtk_widget_get_window (invisible);
+
+ 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;
+}
+
+
+
XfceClipboardManager *
xfce_clipboard_manager_new (void)
{
@@ -325,7 +405,7 @@ xfce_clipboard_manager_start (XfceClipboardManager *manager)
return FALSE;
}
- if (!xfce_utils_selection_owner ("CLIPBOARD_MANAGER", FALSE, NULL))
+ if (!xfce_clipboard_manager_selection_owner ("CLIPBOARD_MANAGER", FALSE, NULL))
{
g_warning ("Unable to get the clipboard manager selection.");
return FALSE;
diff --git a/xfce4-settings-helper/main.c b/xfce4-settings-helper/main.c
index 4d2b9e0..d6d994f 100644
--- a/xfce4-settings-helper/main.c
+++ b/xfce4-settings-helper/main.c
@@ -38,6 +38,7 @@
#include <glib.h>
#include <gtk/gtk.h>
+#include <dbus/dbus.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
@@ -56,17 +57,12 @@
#include "keyboard-shortcuts.h"
#include "workspaces.h"
#include "clipboard-manager.h"
-#include "utils.h"
#ifdef HAVE_XRANDR
#include "displays.h"
#endif
-#define SELECTION_NAME "_XFCE_SETTINGS_HELPER"
-
-static GdkFilterReturn xfce_settings_helper_selection_watcher (GdkXEvent *xevt,
- GdkEvent *evt,
- gpointer user_data);
+#define HELPER_DBUS_NAME "org.xfce.SettingsHelper"
static XfceSMClient *sm_client = NULL;
@@ -126,28 +122,6 @@ xfce_settings_helper_set_autostart_enabled (gboolean enabled)
-static GdkFilterReturn
-xfce_settings_helper_selection_watcher (GdkXEvent *xevt,
- GdkEvent *evt,
- gpointer 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)
- {
- if (sm_client)
- xfce_sm_client_set_restart_style (sm_client, XFCE_SM_CLIENT_RESTART_NORMAL);
- gtk_main_quit ();
- }
-#endif
- return GDK_FILTER_CONTINUE;
-}
-
-
-
gint
main (gint argc, gchar **argv)
{
@@ -166,36 +140,32 @@ main (gint argc, gchar **argv)
GObject *workspaces_helper;
pid_t pid;
guint i;
- const gint signums[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM };
+ const gint signums[] = { SIGQUIT, SIGTERM };
+ DBusConnection *dbus_connection;
+ gint result;
- /* setup translation domain */
xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
- /* create option context */
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, option_entries, GETTEXT_PACKAGE);
g_option_context_add_group (context, gtk_get_option_group (FALSE));
g_option_context_add_group (context, xfce_sm_client_get_option_group (argc, argv));
- /* initialize gtk */
gtk_init (&argc, &argv);
/* parse options */
if (!g_option_context_parse (context, &argc, &argv, &error))
{
- /* print error */
g_print ("%s: %s.\n", G_LOG_DOMAIN, error->message);
g_print (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
g_print ("\n");
- /* cleanup */
g_error_free (error);
g_option_context_free (context);
return EXIT_FAILURE;
}
- /* cleanup */
g_option_context_free (context);
/* check if we should print version information */
@@ -210,10 +180,24 @@ main (gint argc, gchar **argv)
return EXIT_SUCCESS;
}
- /* initialize xfconf */
+ dbus_connection = dbus_bus_get (DBUS_BUS_SESSION, NULL);
+ if (G_LIKELY (dbus_connection != NULL))
+ {
+ result = dbus_bus_request_name (dbus_connection, HELPER_DBUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL);
+ if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ {
+ g_printerr (G_LOG_DOMAIN ": %s\n", "Another instance is already running. Leaving...");
+ return EXIT_SUCCESS;
+ }
+ }
+ else
+ {
+ g_error ("Failed to connect to the dbus session bus.");
+ return EXIT_FAILURE;
+ }
+
if (!xfconf_init (&error))
{
- /* print error and exit */
g_error ("Failed to connect to xfconf daemon: %s.", error->message);
g_error_free (error);
@@ -231,17 +215,10 @@ main (gint argc, gchar **argv)
g_error_free (error);
}
+ /* if this instance is started from a saved session, disable autostart so
+ * the helper is not spawned twice */
in_session = xfce_sm_client_is_resumed (sm_client);
- 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));
- return EXIT_FAILURE;
- }
-
- /* if we were restarted as part of the session, remove us from autostart */
- xfce_settings_helper_set_autostart_enabled (!in_session);
+ xfce_settings_helper_set_autostart_enabled (in_session);
/* daemonize the process when not running in debug mode */
if (!opt_debug)
@@ -256,7 +233,7 @@ main (gint argc, gchar **argv)
}
else if (pid > 0)
{
- /* succesfully created a fork, leave this instance */
+ /* succesfully created a fork */
_exit (EXIT_SUCCESS);
}
}
@@ -272,7 +249,6 @@ main (gint argc, gchar **argv)
#endif
workspaces_helper = g_object_new (XFCE_TYPE_WORKSPACES_HELPER, NULL);
- /* Try to start the clipboard daemon */
clipboard_daemon = xfce_clipboard_manager_new ();
if (!xfce_clipboard_manager_start (clipboard_daemon))
{
@@ -287,9 +263,12 @@ main (gint argc, gchar **argv)
xfce_posix_signal_handler_set_handler (signums[i], signal_handler, NULL, NULL);
}
- /* enter the main loop */
gtk_main();
+ /* release the dbus name */
+ if (dbus_connection != NULL)
+ dbus_bus_release_name (dbus_connection, HELPER_DBUS_NAME, NULL);
+
/* release the sub daemons */
g_object_unref (G_OBJECT (pointer_helper));
g_object_unref (G_OBJECT (keyboards_helper));
@@ -301,17 +280,13 @@ main (gint argc, gchar **argv)
#endif
g_object_unref (G_OBJECT (workspaces_helper));
- /* Stop the 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 ();
-
- /* release sm client */
g_object_unref (G_OBJECT (sm_client));
return EXIT_SUCCESS;
diff --git a/xfce4-settings-helper/utils.c b/xfce4-settings-helper/utils.c
deleted file mode 100644
index 2d8692a..0000000
--- a/xfce4-settings-helper/utils.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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));
- GdkWindow *invisible_window;
- 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);
-
- invisible_window = gtk_widget_get_window (invisible);
-
- 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
deleted file mode 100644
index 8f5843f..0000000
--- a/xfce4-settings-helper/utils.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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/workspaces.c b/xfce4-settings-helper/workspaces.c
index a6840cc..1a45cb7 100644
--- a/xfce4-settings-helper/workspaces.c
+++ b/xfce4-settings-helper/workspaces.c
@@ -223,7 +223,6 @@ xfce_workspaces_helper_prop_changed(XfconfChannel *channel,
return;
display = gdk_display_get_default();
-
for(s = 0; helper->screens[s]; ++s) {
wnck_screen_force_update(helper->screens[s]);
n_workspaces = wnck_screen_get_workspace_count(helper->screens[s]);
More information about the Xfce4-commits
mailing list