diff --git a/panel/panel-application.c b/panel/panel-application.c index 2e78eb9..9b9e7a6 100644 --- a/panel/panel-application.c +++ b/panel/panel-application.c @@ -30,6 +30,11 @@ #include #include +#ifdef GDK_WINDOWING_X11 +#include +#include +#endif + #include #include #include @@ -54,45 +59,49 @@ -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, - PanelWindow *window, - const gchar *name, - gint unique_id, - gchar **arguments, - gint position); -static gboolean panel_application_save_timeout (gpointer user_data); -static void panel_application_window_destroyed (GtkWidget *window, - PanelApplication *application); -static void panel_application_dialog_destroyed (GtkWindow *dialog, - PanelApplication *application); -static void panel_application_drag_data_received (PanelWindow *window, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint drag_time, - GtkWidget *itembar); -static gboolean panel_application_drag_motion (GtkWidget *window, - GdkDragContext *context, - gint x, - gint y, - guint drag_time, - PanelApplication *application); -static gboolean panel_application_drag_drop (GtkWidget *window, - GdkDragContext *context, - gint x, - gint y, - guint drag_time, - PanelApplication *application); -static void panel_application_drag_leave (GtkWidget *window, - GdkDragContext *context, - guint drag_time, - PanelApplication *application); +static void panel_application_finalize (GObject *object); +#ifdef GDK_WINDOWING_X11 +static gboolean panel_application_wait_for_window_manager (gpointer data); +static void panel_application_wait_for_window_manager_destroyed (gpointer data); +#endif +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, + PanelWindow *window, + const gchar *name, + gint unique_id, + gchar **arguments, + gint position); +static gboolean panel_application_save_timeout (gpointer user_data); +static void panel_application_window_destroyed (GtkWidget *window, + PanelApplication *application); +static void panel_application_dialog_destroyed (GtkWindow *dialog, + PanelApplication *application); +static void panel_application_drag_data_received (PanelWindow *window, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint drag_time, + GtkWidget *itembar); +static gboolean panel_application_drag_motion (GtkWidget *window, + GdkDragContext *context, + gint x, + gint y, + guint drag_time, + PanelApplication *application); +static gboolean panel_application_drag_drop (GtkWidget *window, + GdkDragContext *context, + gint x, + gint y, + guint drag_time, + PanelApplication *application); +static void panel_application_drag_leave (GtkWidget *window, + GdkDragContext *context, + guint drag_time, + PanelApplication *application); @@ -126,6 +135,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 +146,19 @@ struct _PanelApplication guint drop_index; }; +#ifdef GDK_WINDOWING_X11 +typedef struct +{ + PanelApplication *application; + + Display *dpy; + Atom wm_cm_atom; + guint have_wm : 1; + guint counter; +} +WaitForWM; +#endif + enum { TARGET_PLUGIN_NAME, @@ -175,7 +201,8 @@ panel_application_class_init (PanelApplicationClass *klass) static void panel_application_init (PanelApplication *application) { - GError *error = NULL; + GError *error = NULL; + WaitForWM *wfwm; application->windows = NULL; application->dialogs = NULL; @@ -204,18 +231,39 @@ 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); +#ifdef GDK_WINDOWING_X11 + /* setup data for wm checking */ + wfwm = g_slice_new0 (WaitForWM); + wfwm->application = application; + wfwm->dpy = XOpenDisplay (NULL); + wfwm->wm_cm_atom = XInternAtom (wfwm->dpy, "_NET_WM_CM_S0", False); + wfwm->have_wm = FALSE; + wfwm->counter = 0; + + /* directly launch or wait for wm */ + panel_application_wait_for_window_manager (wfwm); + if (wfwm->have_wm) + { + /* cleanup struct and load panels */ + panel_application_wait_for_window_manager_destroyed (wfwm); + } + else + { + /* 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 (application); +#endif } @@ -231,6 +279,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) { @@ -297,6 +351,52 @@ panel_application_xfconf_window_bindings (PanelApplication *application, +#ifdef GDK_WINDOWING_X11 +static gboolean +panel_application_wait_for_window_manager (gpointer data) +{ + WaitForWM *wfwm = data; + + if (XGetSelectionOwner (wfwm->dpy, wfwm->wm_cm_atom) != None) + wfwm->have_wm = TRUE; + + /* 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."); + } + else + { + g_message ("found window manager after %d tries", wfwm->counter); + panel_debug (PANEL_DEBUG_APPLICATION, "found window manager after %d tries", + wfwm->counter); + } + + 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... */ + panel_application_load (application); +} +#endif + + + static void panel_application_load (PanelApplication *application) { @@ -375,6 +475,10 @@ 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); } diff --git a/panel/panel-base-window.c b/panel/panel-base-window.c index 7025621..a53f70f 100644 --- a/panel/panel-base-window.c +++ b/panel/panel-base-window.c @@ -673,7 +673,7 @@ panel_base_window_composited_changed (GtkWidget *widget) /* set new compositing state */ window->is_composited = gtk_widget_is_composited (widget); - if (window->is_composited == was_composited) + if (window->is_composited == was_composited) return; if (window->is_composited) @@ -692,7 +692,7 @@ panel_base_window_composited_changed (GtkWidget *widget) if (window->is_composited != was_composited) g_object_notify (G_OBJECT (widget), "composited"); - +g_message ("composite: %d -> %d", window->is_composited, was_composited); /* make sure the entire window is redrawn */ gdkwindow = gtk_widget_get_window (widget); if (gdkwindow != NULL)