[Xfce4-commits] <xfce4-panel:xfce-4.8> Panel: Wait until the wm is ready on all screens (bug #7161).
Nick Schermer
noreply at xfce.org
Sat Jul 9 15:54:01 CEST 2011
Updating branch refs/heads/xfce-4.8
to cabbdfd1c04caf20a71e0af773accf809135a03d (commit)
from 8e5b6c8214413bdcd2e6dafb63ad86a57f329d83 (commit)
commit cabbdfd1c04caf20a71e0af773accf809135a03d
Author: Nick Schermer <nick at xfce.org>
Date: Sat Jul 9 15:51:33 2011 +0200
Panel: Wait until the wm is ready on all screens (bug #7161).
(cherry picked from commit 4e14f278ea242dae6b7f4a3e0ebc1a98f79a1c55)
(cherry picked from commit e3e6be1c591c8e9cce625722866a1c7b129ecdfd)
(cherry picked from commit 9a2407b90828a8716d4972433d1fe2169cbff08c)
panel/main.c | 3 +
panel/panel-application.c | 152 ++++++++++++++++++++++++++++++++++++++++++---
panel/panel-application.h | 3 +
3 files changed, 149 insertions(+), 9 deletions(-)
diff --git a/panel/main.c b/panel/main.c
index 76c851a..15600c8 100644
--- a/panel/main.c
+++ b/panel/main.c
@@ -58,6 +58,7 @@ static gchar *opt_add = NULL;
static gboolean opt_restart = FALSE;
static gboolean opt_quit = FALSE;
static gboolean opt_version = FALSE;
+static gboolean opt_disable_wm_check = FALSE;
static gchar *opt_plugin_event = NULL;
static gchar **opt_arguments = NULL;
static gboolean sm_client_saved_state = FALSE;
@@ -81,6 +82,7 @@ static GOptionEntry option_entries[] =
{ "add", '\0', 0, G_OPTION_ARG_STRING, &opt_add, N_("Add a new plugin to the panel"), N_("PLUGIN-NAME") },
{ "restart", 'r', 0, G_OPTION_ARG_NONE, &opt_restart, N_("Restart the running panel instance"), NULL },
{ "quit", 'q', 0, G_OPTION_ARG_NONE, &opt_quit, N_("Quit the running panel instance"), NULL },
+ { "disable-wm-check", 'd', 0, G_OPTION_ARG_NONE, &opt_disable_wm_check, N_("Do not wait for a window manager on startup"), NULL },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &opt_version, N_("Print version information and exit"), NULL },
{ "plugin-event", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_plugin_event, NULL, NULL },
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_arguments, NULL, NULL },
@@ -345,6 +347,7 @@ main (gint argc, gchar **argv)
signal (signums[i], panel_signal_handler);
application = panel_application_get ();
+ panel_application_load (application, opt_disable_wm_check);
/* save the state before the quit signal if we can, this is a bit safer */
g_signal_connect (G_OBJECT (sm_client), "save-state",
diff --git a/panel/panel-application.c b/panel/panel-application.c
index 03a6004..02a9cc6 100644
--- a/panel/panel-application.c
+++ b/panel/panel-application.c
@@ -30,6 +30,11 @@
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#endif
+
#include <common/panel-private.h>
#include <common/panel-xfconf.h>
#include <common/panel-debug.h>
@@ -55,7 +60,6 @@
static void panel_application_finalize (GObject *object);
-static void panel_application_load (PanelApplication *application);
static void panel_application_plugin_move (GtkWidget *item,
PanelApplication *application);
static gboolean panel_application_plugin_insert (PanelApplication *application,
@@ -126,6 +130,10 @@ struct _PanelApplication
/* autosave timeout */
guint autosave_timeout_id;
+#ifdef GDK_WINDOWING_X11
+ guint wait_for_wm_timeout_id;
+#endif
+
/* drag and drop data */
guint drop_data_ready : 1;
guint drop_occurred : 1;
@@ -133,6 +141,20 @@ struct _PanelApplication
guint drop_index;
};
+#ifdef GDK_WINDOWING_X11
+typedef struct
+{
+ PanelApplication *application;
+
+ Display *dpy;
+ Atom *atoms;
+ guint atom_count;
+ guint have_wm : 1;
+ guint counter;
+}
+WaitForWM;
+#endif
+
enum
{
TARGET_PLUGIN_NAME,
@@ -204,18 +226,11 @@ panel_application_init (PanelApplication *application)
/* get a factory reference so it never unloads */
application->factory = panel_module_factory_get ();
- /* load setup */
- panel_application_load (application);
-
/* start the autosave timeout */
application->autosave_timeout_id =
g_timeout_add_seconds (AUTOSAVE_INTERVAL,
panel_application_save_timeout,
application);
-
- /* create empty window if everything else failed */
- if (G_UNLIKELY (application->windows == NULL))
- panel_application_new_window (application, NULL, TRUE);
}
@@ -231,6 +246,12 @@ panel_application_finalize (GObject *object)
/* stop the autosave timeout */
g_source_remove (application->autosave_timeout_id);
+#ifdef GDK_WINDOWING_X11
+ /* stop autostart timeout */
+ if (application->wait_for_wm_timeout_id != 0)
+ g_source_remove (application->wait_for_wm_timeout_id);
+#endif
+
/* free all windows */
for (li = application->windows; li != NULL; li = li->next)
{
@@ -298,7 +319,7 @@ panel_application_xfconf_window_bindings (PanelApplication *application,
static void
-panel_application_load (PanelApplication *application)
+panel_application_load_real (PanelApplication *application)
{
PanelWindow *window;
guint i, j, n_panels;
@@ -375,11 +396,75 @@ panel_application_load (PanelApplication *application)
xfconf_array_free (array);
}
+
+ /* create empty window if everything else failed */
+ if (G_UNLIKELY (application->windows == NULL))
+ panel_application_new_window (application, NULL, TRUE);
+}
+
+
+
+#ifdef GDK_WINDOWING_X11
+static gboolean
+panel_application_wait_for_window_manager (gpointer data)
+{
+ WaitForWM *wfwm = data;
+ guint i;
+ gboolean have_wm = TRUE;
+
+ for (i = 0; i < wfwm->atom_count; i++)
+ {
+ if (XGetSelectionOwner (wfwm->dpy, wfwm->atoms[i]) == None)
+ {
+ panel_debug (PANEL_DEBUG_APPLICATION, "window manager not ready on screen %d", i);
+
+ have_wm = FALSE;
+ break;
+ }
+ }
+
+ wfwm->have_wm = have_wm;
+
+ /* abort if a window manager is found or 5 seconds expired */
+ return wfwm->counter++ < 20 * 5 && !wfwm->have_wm;
}
static void
+panel_application_wait_for_window_manager_destroyed (gpointer data)
+{
+ WaitForWM *wfwm = data;
+ PanelApplication *application = wfwm->application;
+
+ application->wait_for_wm_timeout_id = 0;
+
+ if (!wfwm->have_wm)
+ {
+ g_printerr (G_LOG_DOMAIN ": No window manager registered on screen 0. "
+ "To start the panel without this check, run with --disable-wm-check.\n");
+ }
+ else
+ {
+ panel_debug (PANEL_DEBUG_APPLICATION, "found window manager after %d tries",
+ wfwm->counter);
+ }
+
+ g_free (wfwm->atoms);
+ XCloseDisplay (wfwm->dpy);
+ g_slice_free (WaitForWM, wfwm);
+
+ /* start loading the panels, hopefully a window manager is found, but it
+ * probably also works fine without... */
+ GDK_THREADS_ENTER ();
+ panel_application_load_real (application);
+ GDK_THREADS_LEAVE ();
+}
+#endif
+
+
+
+static void
panel_application_plugin_move_drag_data_get (GtkWidget *item,
GdkDragContext *drag_context,
GtkSelectionData *selection_data,
@@ -1092,6 +1177,55 @@ panel_application_get (void)
void
+panel_application_load (PanelApplication *application,
+ gboolean disable_wm_check)
+{
+#ifdef GDK_WINDOWING_X11
+ WaitForWM *wfwm;
+ guint i;
+ gchar **atom_names;
+
+ if (!disable_wm_check)
+ {
+ /* setup data for wm checking */
+ wfwm = g_slice_new0 (WaitForWM);
+ wfwm->application = application;
+ wfwm->dpy = XOpenDisplay (NULL);
+ wfwm->have_wm = FALSE;
+ wfwm->counter = 0;
+
+ /* preload wm atoms for all screens */
+ wfwm->atom_count = XScreenCount (wfwm->dpy);
+ wfwm->atoms = g_new (Atom, wfwm->atom_count);
+ atom_names = g_new0 (gchar *, wfwm->atom_count + 1);
+
+ for (i = 0; i < wfwm->atom_count; i++)
+ atom_names[i] = g_strdup_printf ("WM_S%d", i);
+
+ if (!XInternAtoms (wfwm->dpy, atom_names, wfwm->atom_count, False, wfwm->atoms))
+ wfwm->atom_count = 0;
+
+ g_strfreev (atom_names);
+
+ /* setup timeout to check for a window manager */
+ application->wait_for_wm_timeout_id =
+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 50, panel_application_wait_for_window_manager,
+ wfwm, panel_application_wait_for_window_manager_destroyed);
+ }
+ else
+ {
+ /* directly launch */
+ panel_application_load_real (application);
+ }
+#else
+ /* directly launch */
+ panel_application_load_real (application);
+#endif
+}
+
+
+
+void
panel_application_save (PanelApplication *application,
gboolean save_plugin_providers)
{
diff --git a/panel/panel-application.h b/panel/panel-application.h
index 17238b1..5073821 100644
--- a/panel/panel-application.h
+++ b/panel/panel-application.h
@@ -38,6 +38,9 @@ GType panel_application_get_type (void) G_GNUC_CONST;
PanelApplication *panel_application_get (void);
+void panel_application_load (PanelApplication *application,
+ gboolean disable_wm_check);
+
void panel_application_save (PanelApplication *application,
gboolean save_plugin_providers);
More information about the Xfce4-commits
mailing list