[mutter] stack: Delegate layer calculation to a window vfunc
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] stack: Delegate layer calculation to a window vfunc
- Date: Fri, 29 Nov 2019 15:46:56 +0000 (UTC)
commit c843102eecff1248e4256488f5a254c7ab07b800
Author: Florian Müllner <fmuellner gnome org>
Date: Tue Nov 26 20:53:24 2019 +0100
stack: Delegate layer calculation to a window vfunc
While most of the code to compute a window's layer isn't explicitly
windowing backend specific, it is in practice: On wayland there are
no DESKTOP windows(*), docks(*) or groups.
Reflect that by introducing a calculate_layer() vfunc that computes
(and sets) a window's layer.
(*) they shall burn in hell, amen!
https://gitlab.gnome.org/GNOME/mutter/merge_requests/949
src/core/stack.c | 128 +-------------------------------------
src/core/window-private.h | 4 ++
src/core/window.c | 6 ++
src/wayland/meta-window-wayland.c | 7 +++
src/x11/window-x11.c | 119 +++++++++++++++++++++++++++++++++++
5 files changed, 137 insertions(+), 127 deletions(-)
---
diff --git a/src/core/stack.c b/src/core/stack.c
index f97909a58..6518be9b3 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -441,132 +441,6 @@ meta_stack_update_window_tile_matches (MetaStack *stack,
g_list_free (windows);
}
-/* Get layer ignoring any transient or group relationships */
-static MetaStackLayer
-get_standalone_layer (MetaWindow *window)
-{
- MetaStackLayer layer;
-
- switch (window->type)
- {
- case META_WINDOW_DESKTOP:
- layer = META_LAYER_DESKTOP;
- break;
-
- case META_WINDOW_DOCK:
- if (window->wm_state_below ||
- (window->monitor && window->monitor->in_fullscreen))
- layer = META_LAYER_BOTTOM;
- else
- layer = META_LAYER_DOCK;
- break;
-
- case META_WINDOW_DROPDOWN_MENU:
- case META_WINDOW_POPUP_MENU:
- case META_WINDOW_TOOLTIP:
- case META_WINDOW_NOTIFICATION:
- case META_WINDOW_COMBO:
- case META_WINDOW_OVERRIDE_OTHER:
- switch (window->client_type)
- {
- case META_WINDOW_CLIENT_TYPE_X11:
- layer = META_LAYER_OVERRIDE_REDIRECT;
- break;
- case META_WINDOW_CLIENT_TYPE_WAYLAND:
- layer = META_LAYER_NORMAL;
- break;
- default:
- g_assert_not_reached ();
- }
- break;
- default:
- layer = meta_window_get_default_layer (window);
- break;
- }
-
- return layer;
-}
-
-/* Note that this function can never use window->layer only
- * get_standalone_layer, or we'd have issues.
- */
-static MetaStackLayer
-get_maximum_layer_in_group (MetaWindow *window)
-{
- GSList *members;
- MetaGroup *group;
- GSList *tmp;
- MetaStackLayer max;
- MetaStackLayer layer;
-
- max = META_LAYER_DESKTOP;
-
- group = meta_window_get_group (window);
-
- if (group != NULL)
- members = meta_group_list_windows (group);
- else
- members = NULL;
-
- tmp = members;
- while (tmp != NULL)
- {
- MetaWindow *w = tmp->data;
-
- if (!w->override_redirect)
- {
- layer = get_standalone_layer (w);
- if (layer > max)
- max = layer;
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (members);
-
- return max;
-}
-
-static void
-compute_layer (MetaWindow *window)
-{
- window->layer = get_standalone_layer (window);
-
- /* We can only do promotion-due-to-group for dialogs and other
- * transients, or weird stuff happens like the desktop window and
- * nautilus windows getting in the same layer, or all gnome-terminal
- * windows getting in fullscreen layer if any terminal is
- * fullscreen.
- */
- if (window->layer != META_LAYER_DESKTOP &&
- meta_window_has_transient_type (window) &&
- window->transient_for == NULL)
- {
- /* We only do the group thing if the dialog is NOT transient for
- * a particular window. Imagine a group with a normal window, a dock,
- * and a dialog transient for the normal window; you don't want the dialog
- * above the dock if it wouldn't normally be.
- */
-
- MetaStackLayer group_max;
-
- group_max = get_maximum_layer_in_group (window);
-
- if (group_max > window->layer)
- {
- meta_topic (META_DEBUG_STACK,
- "Promoting window %s from layer %u to %u due to group membership\n",
- window->desc, window->layer, group_max);
- window->layer = group_max;
- }
- }
-
- meta_topic (META_DEBUG_STACK, "Window %s on layer %u type = %u has_focus = %d\n",
- window->desc, window->layer,
- window->type, window->has_focus);
-}
-
/* Front of the layer list is the topmost window,
* so the lower stack position is later in the list
*/
@@ -957,7 +831,7 @@ stack_do_relayer (MetaStack *stack)
w = tmp->data;
old_layer = w->layer;
- compute_layer (w);
+ w->layer = meta_window_calculate_layer (w);
if (w->layer != old_layer)
{
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 3fd9f146e..6e7563f8e 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -589,6 +589,8 @@ struct _MetaWindowClass
gboolean (*can_ping) (MetaWindow *window);
gboolean (*are_updates_frozen) (MetaWindow *window);
+ MetaStackLayer (*calculate_layer) (MetaWindow *window);
+
void (* map) (MetaWindow *window);
void (* unmap) (MetaWindow *window);
};
@@ -693,6 +695,8 @@ gboolean meta_window_is_focusable (MetaWindow *window);
gboolean meta_window_can_ping (MetaWindow *window);
+MetaStackLayer meta_window_calculate_layer (MetaWindow *window);
+
void meta_window_current_workspace_changed (MetaWindow *window);
void meta_window_show_menu (MetaWindow *window,
diff --git a/src/core/window.c b/src/core/window.c
index 45c9c6ca6..dc6b5c795 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -8582,6 +8582,12 @@ meta_window_is_stackable (MetaWindow *window)
return META_WINDOW_GET_CLASS (window)->is_stackable (window);
}
+MetaStackLayer
+meta_window_calculate_layer (MetaWindow *window)
+{
+ return META_WINDOW_GET_CLASS (window)->calculate_layer (window);
+}
+
/**
* meta_window_get_id:
* @window: a #MetaWindow
diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c
index 802b7e223..5d193c4f5 100644
--- a/src/wayland/meta-window-wayland.c
+++ b/src/wayland/meta-window-wayland.c
@@ -634,6 +634,12 @@ meta_window_wayland_are_updates_frozen (MetaWindow *window)
return !wl_window->has_been_shown;
}
+static MetaStackLayer
+meta_window_wayland_calculate_layer (MetaWindow *window)
+{
+ return meta_window_get_default_layer (window);
+}
+
static void
meta_window_wayland_map (MetaWindow *window)
{
@@ -667,6 +673,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
window_class->is_stackable = meta_window_wayland_is_stackable;
window_class->can_ping = meta_window_wayland_can_ping;
window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen;
+ window_class->calculate_layer = meta_window_wayland_calculate_layer;
window_class->map = meta_window_wayland_map;
window_class->unmap = meta_window_wayland_unmap;
}
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 5389e10ac..4c7956dd1 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -1855,6 +1855,124 @@ meta_window_x11_are_updates_frozen (MetaWindow *window)
return FALSE;
}
+/* Get layer ignoring any transient or group relationships */
+static MetaStackLayer
+get_standalone_layer (MetaWindow *window)
+{
+ MetaStackLayer layer;
+
+ switch (window->type)
+ {
+ case META_WINDOW_DESKTOP:
+ layer = META_LAYER_DESKTOP;
+ break;
+
+ case META_WINDOW_DOCK:
+ if (window->wm_state_below ||
+ (window->monitor && window->monitor->in_fullscreen))
+ layer = META_LAYER_BOTTOM;
+ else
+ layer = META_LAYER_DOCK;
+ break;
+
+ case META_WINDOW_DROPDOWN_MENU:
+ case META_WINDOW_POPUP_MENU:
+ case META_WINDOW_TOOLTIP:
+ case META_WINDOW_NOTIFICATION:
+ case META_WINDOW_COMBO:
+ case META_WINDOW_OVERRIDE_OTHER:
+ layer = META_LAYER_OVERRIDE_REDIRECT;
+ break;
+
+ default:
+ layer = meta_window_get_default_layer (window);
+ break;
+ }
+
+ return layer;
+}
+
+/* Note that this function can never use window->layer only
+ * get_standalone_layer, or we'd have issues.
+ */
+static MetaStackLayer
+get_maximum_layer_in_group (MetaWindow *window)
+{
+ GSList *members;
+ MetaGroup *group;
+ GSList *tmp;
+ MetaStackLayer max;
+ MetaStackLayer layer;
+
+ max = META_LAYER_DESKTOP;
+
+ group = meta_window_get_group (window);
+
+ if (group != NULL)
+ members = meta_group_list_windows (group);
+ else
+ members = NULL;
+
+ tmp = members;
+ while (tmp != NULL)
+ {
+ MetaWindow *w = tmp->data;
+
+ if (!w->override_redirect)
+ {
+ layer = get_standalone_layer (w);
+ if (layer > max)
+ max = layer;
+ }
+
+ tmp = tmp->next;
+ }
+
+ g_slist_free (members);
+
+ return max;
+}
+
+static MetaStackLayer
+meta_window_x11_calculate_layer (MetaWindow *window)
+{
+ MetaStackLayer layer = get_standalone_layer (window);
+
+ /* We can only do promotion-due-to-group for dialogs and other
+ * transients, or weird stuff happens like the desktop window and
+ * nautilus windows getting in the same layer, or all gnome-terminal
+ * windows getting in fullscreen layer if any terminal is
+ * fullscreen.
+ */
+ if (layer != META_LAYER_DESKTOP &&
+ meta_window_has_transient_type (window) &&
+ window->transient_for == NULL)
+ {
+ /* We only do the group thing if the dialog is NOT transient for
+ * a particular window. Imagine a group with a normal window, a dock,
+ * and a dialog transient for the normal window; you don't want the dialog
+ * above the dock if it wouldn't normally be.
+ */
+
+ MetaStackLayer group_max;
+
+ group_max = get_maximum_layer_in_group (window);
+
+ if (group_max > layer)
+ {
+ meta_topic (META_DEBUG_STACK,
+ "Promoting window %s from layer %u to %u due to group membership\n",
+ window->desc, layer, group_max);
+ layer = group_max;
+ }
+ }
+
+ meta_topic (META_DEBUG_STACK, "Window %s on layer %u type = %u has_focus = %d\n",
+ window->desc, layer,
+ window->type, window->has_focus);
+ return layer;
+}
+
static void
meta_window_x11_map (MetaWindow *window)
{
@@ -1903,6 +2021,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
window_class->is_stackable = meta_window_x11_is_stackable;
window_class->can_ping = meta_window_x11_can_ping;
window_class->are_updates_frozen = meta_window_x11_are_updates_frozen;
+ window_class->calculate_layer = meta_window_x11_calculate_layer;
window_class->map = meta_window_x11_map;
window_class->unmap = meta_window_x11_unmap;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]