/* 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);
/* 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;
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
// SPDX-License-Identifier: GPL-2.0-only
#include "config.h"
+#include <assert.h>
#include <cairo.h>
#include <drm_fourcc.h>
#include <pango/pangocairo.h>
#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"
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) {
}
}
+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)
{
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);
+ }
}
#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"
}
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;
}