[PATCH weston] shell: Change stacking order calculation for popup surfaces

Emilio Pozuelo Monfort pochu27 at gmail.com
Tue Feb 11 01:52:09 PST 2014


From: Philip Withnall <philip.withnall at collabora.co.uk>

Always put them as the top-most layer in the layer list of their parent.
This ensures that, for example, the popup menu produced by
right-clicking on a surface (which is not currently at the top of the
stacking order in the current workspace) is displayed at the top of the
stacking order.

[ Emilio: handle popups with non-shell-surface parents ]

https://bugs.freedesktop.org/show_bug.cgi?id=74831

Signed-off-by: Philip Withnall <philip.withnall at collabora.co.uk>
Co-authored-by: Emilio Pozuelo Monfort <emilio.pozuelo at collabora.co.uk>
---
 desktop-shell/shell.c | 47 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index a73e8e0..d362f5f 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -2090,15 +2090,49 @@ shell_surface_calculate_layer_link (struct shell_surface *shsurf)
 	struct weston_view *parent;
 
 	switch (shsurf->type) {
-	case SHELL_SURFACE_POPUP:
-	case SHELL_SURFACE_TOPLEVEL:
+	case SHELL_SURFACE_POPUP: {
+		/* Popups should go at the front of the workspace of their
+		 * parent surface, rather than just in front of the parent. This
+		 * fixes the situation where there are two top-level windows:
+		 *  - Above
+		 *  - Below
+		 * and a pop-up menu is created for 'Below'. We want:
+		 *  - Popup
+		 *  - Above
+		 *  - Below
+		 * not:
+		 *  - Above
+		 *  - Popup
+		 *  - Below
+		 */
+		struct shell_surface *parent_shsurf;
+
+		parent_shsurf = get_shell_surface(shsurf->parent);
+
+		if (parent_shsurf != NULL)
+			return shell_surface_calculate_layer_link(parent_shsurf);
+		else if (shsurf->parent) {
+			/* The parent surface may not be a shell surface, e.g.
+			 * for right clicks on the panel. */
+			parent = get_default_view(shsurf->parent);
+
+			if (parent)
+				return parent->layer_link.prev;
+		}
+
+		break;
+	}
+
+	case SHELL_SURFACE_TOPLEVEL: {
 		if (shsurf->state.fullscreen) {
 			return &shsurf->shell->fullscreen_layer.view_list;
 		} else if (shsurf->parent) {
-			/* Move the surface to its parent layer so
-			 * that surfaces which are transient for
-			 * fullscreen surfaces don't get hidden by the
-			 * fullscreen surfaces. */
+			/* Move the surface to its parent layer so that
+			 * surfaces which are transient for fullscreen surfaces
+			 * don't get hidden by the fullscreen surfaces.
+			 * However, unlike popups, transient surfaces are
+			 * stacked in front of their parent but not in front of
+			 * other surfaces of the same type. */
 
 			/* TODO: Handle a parent with multiple views */
 			parent = get_default_view(shsurf->parent);
@@ -2106,6 +2140,7 @@ shell_surface_calculate_layer_link (struct shell_surface *shsurf)
 				return parent->layer_link.prev;
 		}
 		break;
+	}
 
 	case SHELL_SURFACE_XWAYLAND:
 		return &shsurf->shell->fullscreen_layer.view_list;
-- 
1.9.rc1



More information about the wayland-devel mailing list