]> git.mdlowis.com Git - proto/labwc.git/commitdiff
alt-tab preview: restore functionality after move to scene-graph
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 26 Apr 2022 21:56:27 +0000 (23:56 +0200)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Sun, 28 Aug 2022 18:40:36 +0000 (20:40 +0200)
include/common/scene-helpers.h
include/labwc.h
src/common/scene-helpers.c
src/desktop.c
src/keyboard.c
src/osd.c
src/view.c

index a124d0a36ddfea5ad66c5c87b2d266ddab4ab9a5..921ff56abc7ded0ceb87285fe11aa4353a94c991 100644 (file)
@@ -1,7 +1,17 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
-#include <wlr/types/wlr_scene.h>
+struct wlr_scene_node;
+struct wlr_scene_rect;
+struct wlr_scene_tree;
+struct wlr_surface;
 
 struct wlr_scene_rect *lab_wlr_scene_get_rect(struct wlr_scene_node *node);
 struct wlr_scene_tree *lab_scene_tree_from_node(struct wlr_scene_node *node);
 struct wlr_surface *lab_wlr_surface_from_node(struct wlr_scene_node *node);
+
+/**
+ * lab_get_prev_node - return previous (sibling) node
+ * @node: node to find the previous node from
+ * Return NULL if previous link is list-head which means node is bottom-most
+ */
+struct wlr_scene_node *lab_wlr_scene_get_prev_node(struct wlr_scene_node *node);
index 5b9c25bb3ea305046ca503d18972c4a0e6f93e80..df328f4170236dbbb938c86a689e8dde334362ef 100644 (file)
@@ -233,6 +233,7 @@ struct server {
        /* Set when in cycle (alt-tab) mode */
        struct osd_state {
                struct view *cycle_view;
+               bool preview_was_enabled;
                struct wlr_scene_node *preview_node;
                struct wlr_scene_node *preview_anchor;
        } osd_state;
@@ -577,9 +578,12 @@ void server_init(struct server *server);
 void server_start(struct server *server);
 void server_finish(struct server *server);
 
-/* update onscreen display 'alt-tab' buffer */
-void osd_finish(struct server *server);
+/* Updates onscreen display 'alt-tab' buffer */
 void osd_update(struct server *server);
+/* Closes the OSD */
+void osd_finish(struct server *server);
+/* Moves preview views back into their original stacking order and state */
+void osd_preview_restore(struct server *server);
 
 /*
  * wlroots "input inhibitor" extension (required for swaylock) blocks
index ae1220bffeae97788dbc74aa1bfad77627620115..6bda9bd7aaa1f99e12d007d04fa01f8f46d3db49 100644 (file)
@@ -32,3 +32,15 @@ lab_wlr_surface_from_node(struct wlr_scene_node *node)
        }
        return NULL;
 }
+
+struct wlr_scene_node *
+lab_wlr_scene_get_prev_node(struct wlr_scene_node *node)
+{
+       assert(node);
+       struct wlr_scene_node *prev;
+       prev = wl_container_of(node->link.prev, node, link);
+       if (&prev->link == &node->parent->children) {
+               return NULL;
+       }
+       return prev;
+}
index ab5e00ce02c5a5d302ee495a78c2f5c698d48ed2..224cdf494b99955d32753a7dc6f4a3d0f7d2df98 100644 (file)
@@ -203,6 +203,9 @@ desktop_cycle_view(struct server *server, struct view *start_view,
        /* Scene nodes are ordered like last node == displayed topmost */
        iter = dir == LAB_CYCLE_DIR_FORWARD ? get_prev_item : get_next_item;
 
+       /* Make sure to have all nodes in their actual ordering */
+       osd_preview_restore(server);
+
        do {
                list_item = iter(list_item);
                if (list_item == list_head) {
index 2cad76fcf867be50c1fb6fda19cbe74cd93db249..2d44a9dbb39bb0a3075c9e7be6d1faa83d0d12dd 100644 (file)
@@ -150,6 +150,7 @@ handle_compositor_keybindings(struct wl_listener *listener,
                        for (int i = 0; i < nsyms; i++) {
                                if (syms[i] == XKB_KEY_Escape) {
                                        /* cancel */
+                                       osd_preview_restore(server);
                                        /* osd_finish() additionally resets cycle_view to NULL */
                                        osd_finish(server);
                                        return true;
index 9cfc9ccbda07814ec0e849f17007c527c4cd14a9..e2b98d0fa97b84da1bdc80cf38100b3989294b77 100644 (file)
--- a/src/osd.c
+++ b/src/osd.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include "config.h"
+#include <assert.h>
 #include <cairo.h>
 #include <drm_fourcc.h>
 #include <pango/pangocairo.h>
@@ -8,6 +9,7 @@
 #include "common/buf.h"
 #include "common/font.h"
 #include "common/graphic-helpers.h"
+#include "common/scene-helpers.h"
 #include "config/rcxml.h"
 #include "labwc.h"
 #include "theme.h"
@@ -110,6 +112,8 @@ void
 osd_finish(struct server *server)
 {
        server->osd_state.cycle_view = NULL;
+       server->osd_state.preview_node = NULL;
+       server->osd_state.preview_anchor = NULL;
 
        struct output *output;
        wl_list_for_each(output, &server->outputs, link) {
@@ -123,6 +127,53 @@ osd_finish(struct server *server)
        }
 }
 
+void
+osd_preview_restore(struct server *server)
+{
+       struct osd_state *osd_state = &server->osd_state;
+       if (osd_state->preview_node) {
+               if (osd_state->preview_anchor) {
+                       wlr_scene_node_place_above(osd_state->preview_node,
+                               osd_state->preview_anchor);
+               } else {
+                       /* Selected view was the first node */
+                       wlr_scene_node_lower_to_bottom(osd_state->preview_node);
+               }
+
+               /* Node was disabled / minimized before, disable again */
+               if (!osd_state->preview_was_enabled) {
+                       wlr_scene_node_set_enabled(osd_state->preview_node, false);
+               }
+               osd_state->preview_node = NULL;
+               osd_state->preview_anchor = NULL;
+       }
+}
+
+static void
+preview_cycled_view(struct view *view)
+{
+       assert(view);
+       assert(view->scene_tree);
+       struct osd_state *osd_state = &view->server->osd_state;
+
+       /* Move previous selected node back to its original place */
+       osd_preview_restore(view->server);
+
+       /* Remember the sibling right before the selected node */
+       osd_state->preview_node = &view->scene_tree->node;
+       osd_state->preview_anchor = lab_wlr_scene_get_prev_node(
+               osd_state->preview_node);
+
+       /* Store node enabled / minimized state and force-enable if disabled */
+       osd_state->preview_was_enabled = osd_state->preview_node->enabled;
+       if (!osd_state->preview_was_enabled) {
+               wlr_scene_node_set_enabled(osd_state->preview_node, true);
+       }
+
+       /* Finally raise selected node to the top */
+       wlr_scene_node_raise_to_top(osd_state->preview_node);
+}
+
 void
 osd_update(struct server *server)
 {
@@ -294,4 +345,8 @@ osd_update(struct server *server)
                wlr_scene_node_set_enabled(&output->osd_tree->node, true);
        }
        free(buf.buf);
+
+       if (rc.cycle_preview_contents) {
+               preview_cycled_view(server->osd_state.cycle_view);
+       }
 }
index e8c556487fb0c4754e99c29cab7911ac0c66048d..fa3a51ca71137ccef46caa440fd9e42da759baf2 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <strings.h>
 #include <xcb/xcb_icccm.h>
+#include "common/scene-helpers.h"
 #include "labwc.h"
 #include "ssd.h"
 #include "menu/menu.h"
@@ -833,8 +834,16 @@ view_destroy(struct view *view)
        }
 
        if (view->scene_tree) {
+               struct wlr_scene_node *node = &view->scene_tree->node;
+               if (osd_state->preview_anchor == node) {
+                       /*
+                        * If we are the anchor for the current OSD selected view,
+                        * replace the anchor with the node before us.
+                        */
+                       osd_state->preview_anchor = lab_wlr_scene_get_prev_node(node);
+               }
                ssd_destroy(view);
-               wlr_scene_node_destroy(&view->scene_tree->node);
+               wlr_scene_node_destroy(node);
                view->scene_tree = NULL;
        }