[mutter] screen: Behave better about CM selections



commit fa97364fa842b4ef27b7cf442bf97d64303b4171
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sun Dec 28 19:11:45 2014 -0800

    screen: Behave better about CM selections

 src/core/screen-private.h |    2 -
 src/core/screen.c         |  198 +++++++++++++++++++--------------------------
 src/meta/screen.h         |    1 -
 3 files changed, 85 insertions(+), 116 deletions(-)
---
diff --git a/src/core/screen-private.h b/src/core/screen-private.h
index c9f4231..9d520e5 100644
--- a/src/core/screen-private.h
+++ b/src/core/screen-private.h
@@ -100,8 +100,6 @@ struct _MetaScreen
 #endif
 
   Window wm_cm_selection_window;
-  guint32 wm_cm_timestamp;
-
   guint work_area_later;
   guint check_fullscreen_later;
 
diff --git a/src/core/screen.c b/src/core/screen.c
index b26137e..496e693 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -496,6 +496,81 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
   return guard_window;
 }
 
+static Window
+take_manager_selection (MetaDisplay *display,
+                        Window       xroot,
+                        Atom         manager_atom,
+                        int          timestamp,
+                        gboolean     should_replace)
+{
+  Display *xdisplay = display->xdisplay;
+  Window current_owner, new_owner;
+
+  current_owner = XGetSelectionOwner (xdisplay, manager_atom);
+  if (current_owner != None)
+    {
+      XSetWindowAttributes attrs;
+
+      if (should_replace)
+        {
+          /* We want to find out when the current selection owner dies */
+          meta_error_trap_push (display);
+          attrs.event_mask = StructureNotifyMask;
+          XChangeWindowAttributes (xdisplay, current_owner, CWEventMask, &attrs);
+          if (meta_error_trap_pop_with_return (display) != Success)
+            current_owner = None; /* don't wait for it to die later on */
+        }
+      else
+        {
+          meta_warning (_("Display \"%s\" already has a window manager; try using the --replace option to 
replace the current window manager."),
+                        display->name);
+          return None;
+        }
+    }
+
+  /* We need SelectionClear and SelectionRequest events on the new owner,
+   * but those cannot be masked, so we only need NoEventMask.
+   */
+  new_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
+
+  XSetSelectionOwner (xdisplay, manager_atom, new_owner, timestamp);
+
+  if (XGetSelectionOwner (xdisplay, manager_atom) != new_owner)
+    {
+      meta_warning ("Could not acquire selection: %s", XGetAtomName (xdisplay, manager_atom));
+      return None;
+    }
+
+  {
+    /* Send client message indicating that we are now the selection owner */
+    XClientMessageEvent ev;
+
+    ev.type = ClientMessage;
+    ev.window = xroot;
+    ev.message_type = display->atom_MANAGER;
+    ev.format = 32;
+    ev.data.l[0] = timestamp;
+    ev.data.l[1] = manager_atom;
+
+    XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent *) &ev);
+  }
+
+  /* Wait for old window manager to go away */
+  if (current_owner != None)
+    {
+      XEvent event;
+
+      /* We sort of block infinitely here which is probably lame. */
+
+      meta_verbose ("Waiting for old window manager to exit\n");
+      do
+        XWindowEvent (xdisplay, current_owner, StructureNotifyMask, &event);
+      while (event.type != DestroyNotify);
+    }
+
+  return new_owner;
+}
+
 MetaScreen*
 meta_screen_new (MetaDisplay *display,
                  int          number,
@@ -505,11 +580,9 @@ meta_screen_new (MetaDisplay *display,
   Window xroot;
   Display *xdisplay;
   Window new_wm_sn_owner;
-  Window current_wm_sn_owner;
   gboolean replace_current_wm;
   Atom wm_sn_atom;
   char buf[128];
-  guint32 manager_timestamp;
   MetaMonitorManager *manager;
 
   replace_current_wm = meta_get_replace_current_wm ();
@@ -537,83 +610,11 @@ meta_screen_new (MetaDisplay *display,
     }
 
   sprintf (buf, "WM_S%d", number);
-  wm_sn_atom = XInternAtom (xdisplay, buf, False);
-
-  current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
-
-  if (current_wm_sn_owner != None)
-    {
-      XSetWindowAttributes attrs;
-
-      if (!replace_current_wm)
-        {
-          meta_warning (_("Screen %d on display \"%s\" already has a window manager; try using the --replace 
option to replace the current window manager.\n"),
-                        number, display->name);
-
-          return NULL;
-        }
-
-      /* We want to find out when the current selection owner dies */
-      meta_error_trap_push (display);
-      attrs.event_mask = StructureNotifyMask;
-      XChangeWindowAttributes (xdisplay,
-                               current_wm_sn_owner, CWEventMask, &attrs);
-      if (meta_error_trap_pop_with_return (display) != Success)
-        current_wm_sn_owner = None; /* don't wait for it to die later on */
-    }
 
-  /* We need SelectionClear and SelectionRequest events on the new_wm_sn_owner,
-   * but those cannot be masked, so we only need NoEventMask.
-   */
-  new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
-
-  manager_timestamp = timestamp;
-
-  XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner,
-                      manager_timestamp);
-
-  if (XGetSelectionOwner (xdisplay, wm_sn_atom) != new_wm_sn_owner)
-    {
-      meta_warning ("Could not acquire window manager selection on screen %d display \"%s\"\n",
-                    number, display->name);
-
-      XDestroyWindow (xdisplay, new_wm_sn_owner);
-
-      return NULL;
-    }
-
-  {
-    /* Send client message indicating that we are now the WM */
-    XClientMessageEvent ev;
-
-    ev.type = ClientMessage;
-    ev.window = xroot;
-    ev.message_type = display->atom_MANAGER;
-    ev.format = 32;
-    ev.data.l[0] = manager_timestamp;
-    ev.data.l[1] = wm_sn_atom;
-
-    XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent*)&ev);
-  }
-
-  /* Wait for old window manager to go away */
-  if (current_wm_sn_owner != None)
-    {
-      XEvent event;
-
-      /* We sort of block infinitely here which is probably lame. */
-
-      meta_verbose ("Waiting for old window manager to exit\n");
-      do
-        {
-          XWindowEvent (xdisplay, current_wm_sn_owner,
-                        StructureNotifyMask, &event);
-        }
-      while (event.type != DestroyNotify);
-    }
-
-  /* select our root window events */
-  meta_error_trap_push (display);
+  wm_sn_atom = XInternAtom (xdisplay, buf, False);
+  new_wm_sn_owner = take_manager_selection (display, xroot, wm_sn_atom, timestamp, replace_current_wm);
+  if (new_wm_sn_owner == None)
+    return NULL;
 
   {
     long event_mask;
@@ -638,16 +639,6 @@ meta_screen_new (MetaDisplay *display,
     XSelectInput (xdisplay, xroot, event_mask);
   }
 
-  if (meta_error_trap_pop_with_return (display) != Success)
-    {
-      meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
-                    number, display->name);
-
-      XDestroyWindow (xdisplay, new_wm_sn_owner);
-
-      return NULL;
-    }
-
   /* Select for cursor changes so the cursor tracker is up to date. */
   XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask);
 
@@ -675,11 +666,7 @@ meta_screen_new (MetaDisplay *display,
 
   screen->wm_sn_selection_window = new_wm_sn_owner;
   screen->wm_sn_atom = wm_sn_atom;
-  screen->wm_sn_timestamp = manager_timestamp;
-
-  screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
-                                                                 xroot,
-                                                                 NoEventMask);
+  screen->wm_sn_timestamp = timestamp;
   screen->work_area_later = 0;
   screen->check_fullscreen_later = 0;
 
@@ -2898,27 +2885,12 @@ meta_screen_set_cm_selection (MetaScreen *screen)
 {
   char selection[32];
   Atom a;
+  guint32 timestamp;
 
-  screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip (
-                                                               screen->display);
-
-  g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
-  meta_verbose ("Setting selection: %s\n", selection);
-  a = XInternAtom (screen->display->xdisplay, selection, FALSE);
-  XSetSelectionOwner (screen->display->xdisplay, a,
-                      screen->wm_cm_selection_window, screen->wm_cm_timestamp);
-}
-
-void
-meta_screen_unset_cm_selection (MetaScreen *screen)
-{
-  char selection[32];
-  Atom a;
-
-  g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
-  a = XInternAtom (screen->display->xdisplay, selection, FALSE);
-  XSetSelectionOwner (screen->display->xdisplay, a,
-                      None, screen->wm_cm_timestamp);
+  timestamp = meta_display_get_current_time_roundtrip (screen->display);
+  g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", screen->number);
+  a = XInternAtom (xdisplay, selection, False);
+  screen->wm_cm_selection_window = take_manager_selection (screen->display, screen->xroot, a, timestamp, 
TRUE);
 }
 
 /**
diff --git a/src/meta/screen.h b/src/meta/screen.h
index 4c3c52e..500871b 100644
--- a/src/meta/screen.h
+++ b/src/meta/screen.h
@@ -45,7 +45,6 @@ void meta_screen_get_size (MetaScreen *screen,
                            int        *height);
 
 void meta_screen_set_cm_selection (MetaScreen *screen);
-void meta_screen_unset_cm_selection (MetaScreen *screen);
 
 GSList *meta_screen_get_startup_sequences (MetaScreen *screen);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]