[mutter/wayland] window: Move client-type-specific managing / unmanaging to a vfunc



commit a377a1a11082ed138a519707a41aa47982428ea5
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Mar 19 09:36:15 2014 -0400

    window: Move client-type-specific managing / unmanaging to a vfunc

 src/core/window-private.h    |    2 +
 src/core/window.c            |  240 +-----------------------------------------
 src/wayland/window-wayland.c |   38 +++++++
 src/x11/window-x11.c         |  206 ++++++++++++++++++++++++++++++++++++
 4 files changed, 250 insertions(+), 236 deletions(-)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index b70e04f..d706ff9 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -454,6 +454,8 @@ struct _MetaWindowClass
 {
   GObjectClass parent_class;
 
+  void (*manage)                 (MetaWindow *window);
+  void (*unmanage)               (MetaWindow *window);
   void (*get_default_skip_hints) (MetaWindow *window,
                                   gboolean   *skip_taskbar_out,
                                   gboolean   *skip_pager_out);
diff --git a/src/core/window.c b/src/core/window.c
index 852321a..4e930dc 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -73,7 +73,6 @@
 static int destroying_windows_disallowed = 0;
 
 
-static void     update_sm_hints           (MetaWindow     *window);
 static void     update_net_frame_extents  (MetaWindow     *window);
 static void     invalidate_work_areas     (MetaWindow     *window);
 static void     set_wm_state              (MetaWindow     *window);
@@ -971,25 +970,9 @@ _meta_window_shared_new (MetaDisplay         *display,
    */
   window->stable_sequence = ++display->window_sequence_counter;
 
-  if (client_type == META_WINDOW_CLIENT_TYPE_X11)
-    {
-      meta_display_register_x_window (display, &window->xwindow, window);
-      meta_window_x11_update_shape_region (window);
-      meta_window_x11_update_input_region (window);
-    }
-  else
-    meta_display_register_wayland_window (display, window);
-
   window->opacity = 0xFF;
 
-  /* assign the window to its group, or create a new group if needed
-   */
-  window->group = NULL;
-  window->xgroup_leader = None;
-  meta_window_compute_group (window);
-
-  if (client_type == META_WINDOW_CLIENT_TYPE_X11)
-    meta_window_load_initial_properties (window);
+  META_WINDOW_GET_CLASS (window)->manage (window);
 
   if (window->override_redirect)
     {
@@ -1001,13 +984,6 @@ _meta_window_shared_new (MetaDisplay         *display,
       window->has_resize_func = FALSE;
     }
 
-  if (!window->override_redirect &&
-      client_type == META_WINDOW_CLIENT_TYPE_X11)
-    update_sm_hints (window); /* must come after transient_for */
-
-  if (client_type == META_WINDOW_CLIENT_TYPE_X11)
-    meta_window_x11_update_net_wm_type (window);
-
   if (!window->override_redirect)
     meta_window_update_icon_now (window);
 
@@ -1068,16 +1044,6 @@ _meta_window_shared_new (MetaDisplay         *display,
   if (window->decorated)
     meta_window_ensure_frame (window);
 
-  if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
-    {
-      MetaStackWindow stack_window;
-      stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
-      stack_window.wayland.meta_window = window;
-      meta_stack_tracker_record_add (window->screen->stack_tracker,
-                                     &stack_window,
-                                     0);
-    }
-
   meta_window_grab_keys (window);
   if (window->type != META_WINDOW_DOCK && !window->override_redirect)
     {
@@ -1502,19 +1468,11 @@ meta_window_unmanage (MetaWindow  *window,
 
   meta_verbose ("Unmanaging 0x%lx\n", window->xwindow);
 
+  /* This needs to happen for both Wayland and XWayland clients,
+   * so it can't be in MetaWindowWayland. */
   if (window->surface)
     meta_wayland_surface_window_unmanaged (window->surface);
 
-  if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
-    {
-      MetaStackWindow stack_window;
-      stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
-      stack_window.wayland.meta_window = window;
-      meta_stack_tracker_record_remove (window->screen->stack_tracker,
-                                        &stack_window,
-                                        0);
-    }
-
   if (window->visible_to_compositor)
     meta_compositor_hide_window (window->display->compositor, window,
                                  META_COMP_EFFECT_DESTROY);
@@ -1670,105 +1628,15 @@ meta_window_unmanage (MetaWindow  *window,
    */
   meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker);
 
-  if (window->withdrawn)
-    {
-      /* We need to clean off the window's state so it
-       * won't be restored if the app maps it again.
-       */
-      meta_error_trap_push (window->display);
-      meta_verbose ("Cleaning state from window %s\n", window->desc);
-      XDeleteProperty (window->display->xdisplay,
-                       window->xwindow,
-                       window->display->atom__NET_WM_DESKTOP);
-      XDeleteProperty (window->display->xdisplay,
-                       window->xwindow,
-                       window->display->atom__NET_WM_STATE);
-      XDeleteProperty (window->display->xdisplay,
-                       window->xwindow,
-                       window->display->atom__NET_WM_FULLSCREEN_MONITORS);
-      set_wm_state (window);
-      meta_error_trap_pop (window->display);
-    }
-  else
-    {
-      /* We need to put WM_STATE so that others will understand it on
-       * restart.
-       */
-      if (!window->minimized)
-        {
-          meta_error_trap_push (window->display);
-          set_wm_state (window);
-          meta_error_trap_pop (window->display);
-        }
-
-      /* If we're unmanaging a window that is not withdrawn, then
-       * either (a) mutter is exiting, in which case we need to map
-       * the window so the next WM will know that it's not Withdrawn,
-       * or (b) we want to create a new MetaWindow to replace the
-       * current one, which will happen automatically if we re-map
-       * the X Window.
-       */
-      meta_error_trap_push (window->display);
-      XMapWindow (window->display->xdisplay,
-                  window->xwindow);
-      meta_error_trap_pop (window->display);
-    }
-
   meta_window_ungrab_keys (window);
   meta_display_ungrab_window_buttons (window->display, window->xwindow);
   meta_display_ungrab_focus_window_button (window->display, window);
   if (window->display->autoraise_window == window)
     meta_display_remove_autoraise_callback (window->display);
 
-  if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
-    {
-      meta_display_unregister_x_window (window->display, window->xwindow);
-
-      meta_error_trap_push (window->display);
-
-      /* Put back anything we messed up */
-      if (window->border_width != 0)
-        XSetWindowBorderWidth (window->display->xdisplay,
-                               window->xwindow,
-                               window->border_width);
-
-      /* No save set */
-      XRemoveFromSaveSet (window->display->xdisplay,
-                          window->xwindow);
-
-      /* Even though the window is now unmanaged, we can't unselect events. This
-       * window might be a window from this process, like a GdkMenu, in
-       * which case it will have pointer events and so forth selected
-       * for it by GDK. There's no way to disentangle those events from the events
-       * we've selected. Even for a window from a different X client,
-       * GDK could also have selected events for it for IPC purposes, so we
-       * can't unselect in that case either.
-       *
-       * Similarly, we can't unselected for events on window->user_time_window.
-       * It might be our own GDK focus window, or it might be a window that a
-       * different client is using for multiple different things:
-       * _NET_WM_USER_TIME_WINDOW and IPC, perhaps.
-       */
-
-      if (window->user_time_window != None)
-        {
-          meta_display_unregister_x_window (window->display,
-                                            window->user_time_window);
-          window->user_time_window = None;
-        }
-
-#ifdef HAVE_SHAPE
-      if (META_DISPLAY_HAS_SHAPE (window->display))
-        XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask);
-#endif
-
-      meta_error_trap_pop (window->display);
-    }
-  else
-    meta_display_unregister_wayland_window (window->display, window);
+  META_WINDOW_GET_CLASS (window)->unmanage (window);
 
   meta_prefs_remove_listener (prefs_changed_callback, window);
-
   meta_screen_queue_check_fullscreen (window->screen);
 
   g_signal_emit (window, window_signals[UNMANAGED], 0);
@@ -6541,106 +6409,6 @@ meta_window_set_icon_geometry (MetaWindow    *window,
     }
 }
 
-static Window
-read_client_leader (MetaDisplay *display,
-                    Window       xwindow)
-{
-  Window retval = None;
-
-  meta_prop_get_window (display, xwindow,
-                        display->atom_WM_CLIENT_LEADER,
-                        &retval);
-
-  return retval;
-}
-
-typedef struct
-{
-  Window leader;
-} ClientLeaderData;
-
-static gboolean
-find_client_leader_func (MetaWindow *ancestor,
-                         void       *data)
-{
-  ClientLeaderData *d;
-
-  d = data;
-
-  d->leader = read_client_leader (ancestor->display,
-                                  ancestor->xwindow);
-
-  /* keep going if no client leader found */
-  return d->leader == None;
-}
-
-static void
-update_sm_hints (MetaWindow *window)
-{
-  Window leader;
-
-  window->xclient_leader = None;
-  window->sm_client_id = NULL;
-
-  /* If not on the current window, we can get the client
-   * leader from transient parents. If we find a client
-   * leader, we read the SM_CLIENT_ID from it.
-   */
-  leader = read_client_leader (window->display, window->xwindow);
-  if (leader == None)
-    {
-      ClientLeaderData d;
-      d.leader = None;
-      meta_window_foreach_ancestor (window, find_client_leader_func,
-                                    &d);
-      leader = d.leader;
-    }
-
-  if (leader != None)
-    {
-      char *str;
-
-      window->xclient_leader = leader;
-
-      if (meta_prop_get_latin1_string (window->display, leader,
-                                       window->display->atom_SM_CLIENT_ID,
-                                       &str))
-        {
-          window->sm_client_id = g_strdup (str);
-          meta_XFree (str);
-        }
-    }
-  else
-    {
-      meta_verbose ("Didn't find a client leader for %s\n", window->desc);
-
-      if (!meta_prefs_get_disable_workarounds ())
-        {
-          /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app
-           * instead of the client leader
-           */
-          char *str;
-
-          str = NULL;
-          if (meta_prop_get_latin1_string (window->display, window->xwindow,
-                                           window->display->atom_SM_CLIENT_ID,
-                                           &str))
-            {
-              if (window->sm_client_id == NULL) /* first time through */
-                meta_warning ("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER 
window as specified in the ICCCM.\n",
-                              window->desc);
-
-              window->sm_client_id = g_strdup (str);
-              meta_XFree (str);
-            }
-        }
-    }
-
-  meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n",
-                window->desc, window->xclient_leader,
-                window->sm_client_id ? window->sm_client_id : "none");
-}
-
 static void
 redraw_icon (MetaWindow *window)
 {
diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c
index 627755d..9a0a15c 100644
--- a/src/wayland/window-wayland.c
+++ b/src/wayland/window-wayland.c
@@ -27,6 +27,8 @@
 #include "window-wayland.h"
 
 #include "window-private.h"
+#include "stack-tracker.h"
+#include "meta-wayland-surface.h"
 
 struct _MetaWindowWayland
 {
@@ -41,6 +43,38 @@ struct _MetaWindowWaylandClass
 G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW)
 
 static void
+meta_window_wayland_manage (MetaWindow *window)
+{
+  MetaDisplay *display = window->display;
+
+  meta_display_register_wayland_window (display, window);
+
+  {
+    MetaStackWindow stack_window;
+    stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
+    stack_window.wayland.meta_window = window;
+    meta_stack_tracker_record_add (window->screen->stack_tracker,
+                                   &stack_window,
+                                   0);
+  }
+}
+
+static void
+meta_window_wayland_unmanage (MetaWindow *window)
+{
+  {
+    MetaStackWindow stack_window;
+    stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
+    stack_window.wayland.meta_window = window;
+    meta_stack_tracker_record_remove (window->screen->stack_tracker,
+                                      &stack_window,
+                                      0);
+  }
+
+  meta_display_unregister_wayland_window (window->display, window);
+}
+
+static void
 meta_window_wayland_init (MetaWindowWayland *window_wayland)
 {
 }
@@ -48,4 +82,8 @@ meta_window_wayland_init (MetaWindowWayland *window_wayland)
 static void
 meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
 {
+  MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
+
+  window_class->manage = meta_window_wayland_manage;
+  window_class->unmanage = meta_window_wayland_unmanage;
 }
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index ec87494..f1f98b2 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -58,6 +58,210 @@ meta_window_x11_init (MetaWindowX11 *window_x11)
   window_x11->priv = meta_window_x11_get_instance_private (window_x11);
 }
 
+static Window
+read_client_leader (MetaDisplay *display,
+                    Window       xwindow)
+{
+  Window retval = None;
+
+  meta_prop_get_window (display, xwindow,
+                        display->atom_WM_CLIENT_LEADER,
+                        &retval);
+
+  return retval;
+}
+
+typedef struct
+{
+  Window leader;
+} ClientLeaderData;
+
+static gboolean
+find_client_leader_func (MetaWindow *ancestor,
+                         void       *data)
+{
+  ClientLeaderData *d;
+
+  d = data;
+
+  d->leader = read_client_leader (ancestor->display,
+                                  ancestor->xwindow);
+
+  /* keep going if no client leader found */
+  return d->leader == None;
+}
+
+static void
+update_sm_hints (MetaWindow *window)
+{
+  Window leader;
+
+  window->xclient_leader = None;
+  window->sm_client_id = NULL;
+
+  /* If not on the current window, we can get the client
+   * leader from transient parents. If we find a client
+   * leader, we read the SM_CLIENT_ID from it.
+   */
+  leader = read_client_leader (window->display, window->xwindow);
+  if (leader == None)
+    {
+      ClientLeaderData d;
+      d.leader = None;
+      meta_window_foreach_ancestor (window, find_client_leader_func,
+                                    &d);
+      leader = d.leader;
+    }
+
+  if (leader != None)
+    {
+      char *str;
+
+      window->xclient_leader = leader;
+
+      if (meta_prop_get_latin1_string (window->display, leader,
+                                       window->display->atom_SM_CLIENT_ID,
+                                       &str))
+        {
+          window->sm_client_id = g_strdup (str);
+          meta_XFree (str);
+        }
+    }
+  else
+    {
+      meta_verbose ("Didn't find a client leader for %s\n", window->desc);
+
+      if (!meta_prefs_get_disable_workarounds ())
+        {
+          /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app
+           * instead of the client leader
+           */
+          char *str;
+
+          str = NULL;
+          if (meta_prop_get_latin1_string (window->display, window->xwindow,
+                                           window->display->atom_SM_CLIENT_ID,
+                                           &str))
+            {
+              if (window->sm_client_id == NULL) /* first time through */
+                meta_warning ("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER 
window as specified in the ICCCM.\n",
+                              window->desc);
+
+              window->sm_client_id = g_strdup (str);
+              meta_XFree (str);
+            }
+        }
+    }
+
+  meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n",
+                window->desc, window->xclient_leader,
+                window->sm_client_id ? window->sm_client_id : "none");
+}
+
+static void
+meta_window_x11_manage (MetaWindow *window)
+{
+  MetaDisplay *display = window->display;
+
+  meta_display_register_x_window (display, &window->xwindow, window);
+  meta_window_x11_update_shape_region (window);
+  meta_window_x11_update_input_region (window);
+
+  /* assign the window to its group, or create a new group if needed */
+  window->group = NULL;
+  window->xgroup_leader = None;
+  meta_window_compute_group (window);
+
+  meta_window_load_initial_properties (window);
+
+  if (!window->override_redirect)
+    update_sm_hints (window); /* must come after transient_for */
+
+  meta_window_x11_update_net_wm_type (window);
+}
+
+static void
+meta_window_x11_unmanage (MetaWindow *window)
+{
+  meta_error_trap_push (window->display);
+
+  if (window->withdrawn)
+    {
+      /* We need to clean off the window's state so it
+       * won't be restored if the app maps it again.
+       */
+      meta_verbose ("Cleaning state from window %s\n", window->desc);
+      XDeleteProperty (window->display->xdisplay,
+                       window->xwindow,
+                       window->display->atom__NET_WM_DESKTOP);
+      XDeleteProperty (window->display->xdisplay,
+                       window->xwindow,
+                       window->display->atom__NET_WM_STATE);
+      XDeleteProperty (window->display->xdisplay,
+                       window->xwindow,
+                       window->display->atom__NET_WM_FULLSCREEN_MONITORS);
+      meta_window_x11_set_wm_state (window);
+    }
+  else
+    {
+      /* We need to put WM_STATE so that others will understand it on
+       * restart.
+       */
+      if (!window->minimized)
+        meta_window_x11_set_wm_state (window);
+
+      /* If we're unmanaging a window that is not withdrawn, then
+       * either (a) mutter is exiting, in which case we need to map
+       * the window so the next WM will know that it's not Withdrawn,
+       * or (b) we want to create a new MetaWindow to replace the
+       * current one, which will happen automatically if we re-map
+       * the X Window.
+       */
+      XMapWindow (window->display->xdisplay,
+                  window->xwindow);
+    }
+
+  meta_display_unregister_x_window (window->display, window->xwindow);
+
+  /* Put back anything we messed up */
+  if (window->border_width != 0)
+    XSetWindowBorderWidth (window->display->xdisplay,
+                           window->xwindow,
+                           window->border_width);
+
+  /* No save set */
+  XRemoveFromSaveSet (window->display->xdisplay,
+                      window->xwindow);
+
+  /* Even though the window is now unmanaged, we can't unselect events. This
+   * window might be a window from this process, like a GdkMenu, in
+   * which case it will have pointer events and so forth selected
+   * for it by GDK. There's no way to disentangle those events from the events
+   * we've selected. Even for a window from a different X client,
+   * GDK could also have selected events for it for IPC purposes, so we
+   * can't unselect in that case either.
+   *
+   * Similarly, we can't unselected for events on window->user_time_window.
+   * It might be our own GDK focus window, or it might be a window that a
+   * different client is using for multiple different things:
+   * _NET_WM_USER_TIME_WINDOW and IPC, perhaps.
+   */
+
+  if (window->user_time_window != None)
+    {
+      meta_display_unregister_x_window (window->display,
+                                        window->user_time_window);
+      window->user_time_window = None;
+    }
+
+#ifdef HAVE_SHAPE
+  if (META_DISPLAY_HAS_SHAPE (window->display))
+    XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask);
+#endif
+
+  meta_error_trap_pop (window->display);
+}
+
 static void
 meta_window_x11_get_default_skip_hints (MetaWindow *window,
                                         gboolean   *skip_taskbar_out,
@@ -75,6 +279,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
 {
   MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
 
+  window_class->manage = meta_window_x11_manage;
+  window_class->unmanage = meta_window_x11_unmanage;
   window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints;
 }
 


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