]> git.mdlowis.com Git - proto/labwc.git/commitdiff
desktop: Cycle first to topmost view if not already focused
authorJohn Lindgren <john@jlindgren.net>
Fri, 2 Sep 2022 20:41:27 +0000 (16:41 -0400)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 6 Sep 2022 22:27:03 +0000 (00:27 +0200)
The topmost view may not always be the focused view; for example,
when Audacious's main window is focused but the floating Search
Tool window remains on top of it.  In that case the floating window
(not the main window) should be the first view selected in the
window switcher.

src/desktop.c

index 224cdf494b99955d32753a7dc6f4a3d0f7d2df98..e6d09080d3cba2754683e7c049105ddd1236db73 100644 (file)
@@ -188,11 +188,38 @@ struct view *
 desktop_cycle_view(struct server *server, struct view *start_view,
                enum lab_cycle_dir dir)
 {
-       struct view *view = start_view ? start_view : first_view(server);
-       if (!view) {
-               return NULL;
+       /*
+        * Views are listed in stacking order, topmost first.  Usually
+        * the topmost view is already focused, so we pre-select the
+        * view second from the top:
+        *
+        *   View #1 (on top, currently focused)
+        *   View #2 (pre-selected)
+        *   View #3
+        *   ...
+        *
+        * This assumption doesn't always hold with XWayland views,
+        * where a main application window may be focused but an
+        * focusable sub-view (e.g. an about dialog) may still be on
+        * top of it.  In that case, we pre-select the sub-view:
+        *
+        *   Sub-view of #1 (on top, pre-selected)
+        *   Main view #1 (currently focused)
+        *   Main view #2
+        *   ...
+        *
+        * The general rule is:
+        *
+        *   - Pre-select the top view if NOT already focused
+        *   - Otherwise select the view second from the top
+        */
+       if (!start_view) {
+               start_view = first_view(server);
+               if (!start_view || start_view != desktop_focused_view(server)) {
+                       return start_view;  /* may be NULL */
+               }
        }
-       start_view = view;
+       struct view *view = start_view;
        struct wlr_scene_node *node = &view->scene_tree->node;
 
        assert(node->parent);