Author: olivier
Date: 2008-10-23 17:18:16 +0000 (Thu, 23 Oct 2008)
New Revision: 28384

Modified:
   xfwm4/branches/xfce_4_4/NEWS
   xfwm4/branches/xfce_4_4/src/main.c
   xfwm4/branches/xfce_4_4/src/screen.c
   xfwm4/branches/xfce_4_4/src/screen.h
Log:
Add a "--replace" command line option to replace ICCCM2 compliant window 
managers (Bug #3731)

Modified: xfwm4/branches/xfce_4_4/NEWS
===================================================================
--- xfwm4/branches/xfce_4_4/NEWS        2008-10-23 16:52:38 UTC (rev 28383)
+++ xfwm4/branches/xfce_4_4/NEWS        2008-10-23 17:18:16 UTC (rev 28384)
@@ -20,6 +20,8 @@
   with standard (bug #3634)
 - Add client windows to save set to avoid loosing all windows in case of crash
 - Use guint32 instead of Time internally to avoid potential issues in 64bits
+- Add a "--replace" command line option to replace ICCCM2 compliant window 
+  managers (Bug #3731)
 
 4.4.2
 =====

Modified: xfwm4/branches/xfce_4_4/src/main.c
===================================================================
--- xfwm4/branches/xfce_4_4/src/main.c  2008-10-23 16:52:38 UTC (rev 28383)
+++ xfwm4/branches/xfce_4_4/src/main.c  2008-10-23 17:18:16 UTC (rev 28384)
@@ -263,7 +263,7 @@
 #ifdef HAVE_COMPOSITOR
              "[--compositor=off|on|auto] "
 #endif
-             "[--daemon] [--version|-V] [--help|-H]\n", PACKAGE);
+             "[--daemon] [--replace] [--version|-V] [--help|-H]\n", PACKAGE);
 }
 
 static void
@@ -393,7 +393,7 @@
 #endif /* HAVE_COMPOSITOR */
 
 static int
-initialize (int argc, char **argv, gint compositor_mode)
+initialize (int argc, char **argv, gint compositor_mode, gboolean replace_wm)
 {
     struct sigaction act;
     long ws;
@@ -447,7 +447,7 @@
         GdkScreen *gscr;
 
         gscr = gdk_display_get_screen (display_info->gdisplay, i);
-        screen_info = myScreenInit (display_info, gscr, MAIN_EVENT_MASK);
+        screen_info = myScreenInit (display_info, gscr, MAIN_EVENT_MASK, 
replace_wm);
 
         if (!screen_info)
         {
@@ -529,6 +529,7 @@
 main (int argc, char **argv)
 {
     gboolean daemon_mode;
+    gboolean replace_wm;
     gint compositor;
     int status;
     int i;
@@ -536,6 +537,7 @@
     DBG ("xfwm4 starting");
 
     daemon_mode = FALSE;
+    replace_wm = FALSE;
     compositor = -1;
     for (i = 1; i < argc; i++)
     {
@@ -549,6 +551,10 @@
             compositor = parse_compositor (argv[i]);
         }
 #endif /* HAVE_COMPOSITOR */
+        else if (!strcmp (argv[i], "--replace"))
+        {
+            replace_wm = TRUE;
+        }
         else if (!strcmp (argv[i], "--version") || !strcmp (argv[i], "-V"))
         {
             print_version ();
@@ -561,7 +567,7 @@
         }
     }
 
-    status = initialize (argc, argv, compositor);
+    status = initialize (argc, argv, compositor, replace_wm);
     /*
        status  < 0   =>   Error, cancel execution
        status == 0   =>   Run w/out session manager

Modified: xfwm4/branches/xfce_4_4/src/screen.c
===================================================================
--- xfwm4/branches/xfce_4_4/src/screen.c        2008-10-23 16:52:38 UTC (rev 
28383)
+++ xfwm4/branches/xfce_4_4/src/screen.c        2008-10-23 17:18:16 UTC (rev 
28384)
@@ -43,18 +43,96 @@
 
 #include "display.h"
 #include "screen.h"
+#include "misc.h"
 #include "mywindow.h"
-#include "mywindow.h"
 #include "compositor.h"
 
+gboolean
+myScreenCheckWMAtom (ScreenInfo *screen_info, Atom atom)
+{
+    gchar selection[32];
+    Atom wm_sn_atom;
+
+    TRACE ("entering myScreenCheckWMAtom");
+    g_snprintf (selection, sizeof (selection), "WM_S%d", screen_info->screen);
+    wm_sn_atom = XInternAtom (myScreenGetXDisplay (screen_info), selection, 
FALSE);
+
+    return (atom == wm_sn_atom);
+}
+
+static gboolean
+myScreenSetWMAtom (ScreenInfo *screen_info, gboolean replace_wm)
+{
+    gchar selection[32];
+    gulong wait, timeout;
+    DisplayInfo *display_info;
+    XSetWindowAttributes attrs;
+    Window current_wm;
+    XEvent event;
+    Atom wm_sn_atom;
+
+    g_return_val_if_fail (screen_info, FALSE);
+    g_return_val_if_fail (screen_info->display_info, FALSE);
+
+    TRACE ("entering myScreenReplaceWM");
+
+    display_info = screen_info->display_info;
+    g_snprintf (selection, sizeof (selection), "WM_S%d", screen_info->screen);
+    wm_sn_atom = XInternAtom (display_info->dpy, selection, FALSE);
+
+    current_wm = XGetSelectionOwner (display_info->dpy, wm_sn_atom);
+    if (current_wm)
+    {
+        if (!replace_wm)
+        {
+            g_message (_("To replace the window manager, try with 
\"--replace\"\n"));
+            return FALSE;
+        }
+        gdk_error_trap_push ();
+        attrs.event_mask = StructureNotifyMask;
+        XChangeWindowAttributes (display_info->dpy, current_wm, CWEventMask, 
&attrs);
+        if (gdk_error_trap_pop ())
+        {
+            current_wm = None;
+        }
+    }
+
+    if (!setXAtomManagerOwner (display_info, wm_sn_atom, screen_info->xroot, 
screen_info->xfwm4_win))
+    {
+        g_warning (_("Cannot acquire window manager selection on screen 
%d\n"), screen_info->screen);
+        return FALSE;
+    }
+
+    /* Waiting for previous window manager to exit */
+    if (current_wm)
+    {
+        wait = 0;
+        timeout = 10 * G_USEC_PER_SEC;
+        while (wait < timeout)
+        {
+            if (XCheckWindowEvent (display_info->dpy, current_wm, 
StructureNotifyMask, &event) && (event.type == DestroyNotify))
+            {
+                break;
+            }
+            g_usleep(G_USEC_PER_SEC / 10);
+            wait += G_USEC_PER_SEC / 10;
+        }
+
+        if (wait >= timeout)
+        {
+            g_warning(_("Previous window manager on screen %d is not 
exiting"), screen_info->screen);
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
 ScreenInfo *
-myScreenInit (DisplayInfo *display_info, GdkScreen *gscr, unsigned long 
event_mask)
+myScreenInit (DisplayInfo *display_info, GdkScreen *gscr, unsigned long 
event_mask, gboolean replace_wm)
 {
-    gchar selection[32];
     ScreenInfo *screen_info;
     GdkWindow *event_win;
     PangoLayout *layout;
-    Atom wm_sn_atom;
     long desktop_visible;
     int i;
 
@@ -88,6 +166,23 @@
     pango_layout_get_pixel_extents (layout, NULL, NULL);
     g_object_unref (G_OBJECT (layout));
 
+    screen_info->xscreen = gdk_x11_screen_get_xscreen (gscr);
+    screen_info->xroot = (Window) GDK_DRAWABLE_XID(gdk_screen_get_root_window 
(gscr));
+    screen_info->screen = gdk_screen_get_number (gscr);
+    screen_info->cmap = GDK_COLORMAP_XCOLORMAP(gdk_screen_get_rgb_colormap 
(gscr));
+    screen_info->depth = DefaultDepth (display_info->dpy, screen_info->screen);
+    screen_info->width = WidthOfScreen (screen_info->xscreen);
+    screen_info->height = HeightOfScreen (screen_info->xscreen);
+    screen_info->visual = DefaultVisual (display_info->dpy, 
screen_info->screen);
+
+    screen_info->xfwm4_win = GDK_WINDOW_XWINDOW (screen_info->gtk_win->window);
+    if (!myScreenSetWMAtom (screen_info, replace_wm))
+    {
+        gtk_widget_destroy (screen_info->gtk_win);
+        g_free (screen_info);
+        return NULL;
+    }
+
     event_win = eventFilterAddWin (gscr, event_mask);
     if (!event_win)
     {
@@ -97,14 +192,6 @@
     }
     gdk_window_set_user_data (event_win, screen_info->gtk_win);
 
-    screen_info->xscreen = gdk_x11_screen_get_xscreen (gscr);
-    screen_info->xroot = (Window) GDK_DRAWABLE_XID(gdk_screen_get_root_window 
(gscr));
-    screen_info->screen = gdk_screen_get_number (gscr);
-    screen_info->cmap = GDK_COLORMAP_XCOLORMAP(gdk_screen_get_rgb_colormap 
(gscr));
-    screen_info->depth = DefaultDepth (display_info->dpy, screen_info->screen);
-    screen_info->width = WidthOfScreen (screen_info->xscreen);
-    screen_info->height = HeightOfScreen (screen_info->xscreen);
-    screen_info->visual = DefaultVisual (display_info->dpy, 
screen_info->screen);
     screen_info->current_ws = 0;
     screen_info->previous_ws = 0;
     screen_info->current_ws = 0;
@@ -178,18 +265,12 @@
                     EnterWindowMask,
                     TRUE);
 
-    screen_info->xfwm4_win = GDK_WINDOW_XWINDOW (screen_info->gtk_win->window);
-
 #ifdef ENABLE_KDE_SYSTRAY_PROXY
     g_snprintf (selection, sizeof (selection), "_NET_SYSTEM_TRAY_S%d", 
screen_info->screen);
     screen_info->net_system_tray_selection = XInternAtom (display_info->dpy, 
selection, FALSE);
     screen_info->systray = getSystrayWindow (display_info, 
screen_info->net_system_tray_selection);
 #endif
 
-    g_snprintf (selection, sizeof (selection), "WM_S%d", screen_info->screen);
-    wm_sn_atom = XInternAtom (display_info->dpy, selection, FALSE);
-    XSetSelectionOwner (display_info->dpy, wm_sn_atom, screen_info->xfwm4_win, 
CurrentTime);
-
     screen_info->box_gc = None;
     screen_info->black_gc = NULL;
     screen_info->white_gc = NULL;
@@ -328,18 +409,6 @@
 }
 
 gboolean
-myScreenCheckWMAtom (ScreenInfo *screen_info, Atom atom)
-{
-    gchar selection[32];
-    Atom wm_sn_atom;
-
-    g_snprintf (selection, sizeof (selection), "WM_S%d", screen_info->screen);
-    wm_sn_atom = XInternAtom (myScreenGetXDisplay (screen_info), selection, 
FALSE);
-
-    return (atom == wm_sn_atom);
-}
-
-gboolean
 myScreenGrabPointer (ScreenInfo *screen_info, unsigned int event_mask, Cursor 
cursor, guint32 time)
 {
     gboolean grab;

Modified: xfwm4/branches/xfce_4_4/src/screen.h
===================================================================
--- xfwm4/branches/xfce_4_4/src/screen.h        2008-10-23 16:52:38 UTC (rev 
28383)
+++ xfwm4/branches/xfce_4_4/src/screen.h        2008-10-23 17:18:16 UTC (rev 
28384)
@@ -158,16 +158,17 @@
 #endif /* HAVE_COMPOSITOR */
 };
 
+gboolean                 myScreenCheckWMAtom                    (ScreenInfo *,
+                                                                 Atom atom);
 ScreenInfo              *myScreenInit                           (DisplayInfo *,
                                                                  GdkScreen *,
-                                                                 unsigned 
long);
+                                                                 unsigned long,
+                                                                 gboolean);
 ScreenInfo              *myScreenClose                          (ScreenInfo *);
 Display                 *myScreenGetXDisplay                    (ScreenInfo *);
 GtkWidget               *myScreenGetGtkWidget                   (ScreenInfo *);
 GtkWidget               *myScreenGetGtkWidget                   (ScreenInfo *);
 GdkWindow               *myScreenGetGdkWindow                   (ScreenInfo *);
-gboolean                 myScreenCheckWMAtom                    (ScreenInfo *,
-                                                                 Atom atom);
 gboolean                 myScreenGrabKeyboard                   (ScreenInfo *,
                                                                  guint32);
 gboolean                 myScreenGrabPointer                    (ScreenInfo *,

_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to