From: Philip Withnall <philip.withn...@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.withn...@collabora.co.uk>
Co-authored-by: Emilio Pozuelo Monfort <emilio.pozu...@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

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to