[mutter/wayland] window: Move client-type-specific managing / unmanaging to a vfunc
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] window: Move client-type-specific managing / unmanaging to a vfunc
- Date: Thu, 20 Mar 2014 15:03:33 +0000 (UTC)
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]