]> git.mdlowis.com Git - proto/labwc.git/commitdiff
xdg: show modal dialog above parent window
authorJohan Malm <jgm323@gmail.com>
Mon, 17 Jul 2023 19:16:21 +0000 (20:16 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sat, 5 Aug 2023 14:25:00 +0000 (15:25 +0100)
This behaviour is consistent with that of mutter and openbox.

Fixes: issue #823
src/xdg.c

index b397587a6a8604b3217c257832b0d12eacea45af..8bfad78ba8f51bcf514b575a331d6e2531fe020a 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -320,6 +320,71 @@ xdg_toplevel_view_minimize(struct view *view, bool minimized)
        /* noop */
 }
 
+static struct wlr_xdg_toplevel *
+top_parent_of(struct view *view)
+{
+       struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(view);
+       while (toplevel->parent) {
+               toplevel = toplevel->parent;
+       }
+       return toplevel;
+}
+
+enum z_direction {
+       LAB_TO_FRONT,
+       LAB_TO_BACK,
+};
+
+static void
+move_sub_views(struct view *parent, enum z_direction z_direction)
+{
+       assert(parent);
+
+       if (parent->type != LAB_XDG_SHELL_VIEW) {
+               return;
+       }
+
+       struct wlr_xdg_toplevel *parent_toplevel = xdg_toplevel_from_view(parent);
+       struct view *view, *next;
+       wl_list_for_each_reverse_safe(view, next, &parent->server->views, link)
+       {
+               /* need to stop here, otherwise loops keeps going forever */
+               if (view == parent) {
+                       break;
+               }
+               if (view->type != LAB_XDG_SHELL_VIEW) {
+                       continue;
+               }
+               if (!view->mapped && !view->minimized) {
+                       continue;
+               }
+               if (top_parent_of(view) != parent_toplevel) {
+                       continue;
+               }
+               if (z_direction == LAB_TO_FRONT) {
+                       view_impl_move_to_front(view);
+               } else if (z_direction == LAB_TO_BACK) {
+                       view_impl_move_to_back(view);
+               }
+       }
+}
+
+static void
+xdg_toplevel_view_move_to_front(struct view *view)
+{
+       view_impl_move_to_front(view);
+
+       /* Show modal dialog above parent window */
+       move_sub_views(view, LAB_TO_FRONT);
+}
+
+static void
+xdg_toplevel_view_move_to_back(struct view *view)
+{
+       view_impl_move_to_back(view);
+       move_sub_views(view, LAB_TO_BACK);
+}
+
 static void
 xdg_toplevel_view_set_activated(struct view *view, bool activated)
 {
@@ -472,8 +537,8 @@ static const struct view_impl xdg_toplevel_view_impl = {
        .unmap = xdg_toplevel_view_unmap,
        .maximize = xdg_toplevel_view_maximize,
        .minimize = xdg_toplevel_view_minimize,
-       .move_to_front = view_impl_move_to_front,
-       .move_to_back = view_impl_move_to_back,
+       .move_to_front = xdg_toplevel_view_move_to_front,
+       .move_to_back = xdg_toplevel_view_move_to_back,
 };
 
 void