osd: allow window switcher to temporary unshade windows

This can be configured with a new unshade="yes|no"
argument for windowSwitcher in rc.xml

Fixes: #3111
This commit is contained in:
Consolatis 2025-10-03 02:10:00 +02:00
parent babd7af8f8
commit 364a1d5207
7 changed files with 29 additions and 5 deletions

View file

@ -346,7 +346,7 @@ this is for compatibility with Openbox.
</windowSwitcher> </windowSwitcher>
``` ```
*<windowSwitcher show="" style="" preview="" outlines="" allWorkspaces="">* *<windowSwitcher show="" style="" preview="" outlines="" allWorkspaces="" unshade="">*
*show* [yes|no] Draw the OnScreenDisplay when switching between *show* [yes|no] Draw the OnScreenDisplay when switching between
windows. Default is yes. windows. Default is yes.
@ -364,6 +364,9 @@ this is for compatibility with Openbox.
they are on. Default no (that is only windows on the current workspace they are on. Default no (that is only windows on the current workspace
are shown). are shown).
*unshade* [yes|no] Temporarily unshade windows when switching between
them and permanently unshade on the final selection. Default is yes.
*<windowSwitcher><fields><field content="" width="%">* *<windowSwitcher><fields><field content="" width="%">*
Define window switcher fields when using *<windowSwitcher style="classic" />*. Define window switcher fields when using *<windowSwitcher style="classic" />*.

View file

@ -79,7 +79,8 @@
</font> </font>
</theme> </theme>
<windowSwitcher show="yes" style="classic" preview="yes" outlines="yes" allWorkspaces="no"> <windowSwitcher show="yes" style="classic" preview="yes"
outlines="yes" allWorkspaces="no" unshade="yes">
<fields> <fields>
<field content="icon" width="5%" /> <field content="icon" width="5%" />
<field content="desktop_entry_name" width="30%" /> <field content="desktop_entry_name" width="30%" />

View file

@ -179,6 +179,7 @@ struct rcxml {
bool show; bool show;
bool preview; bool preview;
bool outlines; bool outlines;
bool unshade;
enum lab_view_criteria criteria; enum lab_view_criteria criteria;
struct wl_list fields; /* struct window_switcher_field.link */ struct wl_list fields; /* struct window_switcher_field.link */
enum window_switcher_style style; enum window_switcher_style style;

View file

@ -303,6 +303,7 @@ struct server {
/* Set when in cycle (alt-tab) mode */ /* Set when in cycle (alt-tab) mode */
struct osd_state { struct osd_state {
struct view *cycle_view; struct view *cycle_view;
bool preview_was_shaded;
bool preview_was_enabled; bool preview_was_enabled;
struct wlr_scene_node *preview_node; struct wlr_scene_node *preview_node;
struct wlr_scene_tree *preview_parent; struct wlr_scene_tree *preview_parent;

View file

@ -1217,6 +1217,8 @@ entry(xmlNode *node, char *nodename, char *content)
rc.window_switcher.criteria &= rc.window_switcher.criteria &=
~LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; ~LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
} }
} else if (!strcasecmp(nodename, "unshade.windowSwitcher")) {
set_bool(content, &rc.window_switcher.unshade);
/* Remove this long term - just a friendly warning for now */ /* Remove this long term - just a friendly warning for now */
} else if (strstr(nodename, "windowswitcher.core")) { } else if (strstr(nodename, "windowswitcher.core")) {
@ -1429,6 +1431,7 @@ rcxml_init(void)
rc.window_switcher.style = WINDOW_SWITCHER_CLASSIC; rc.window_switcher.style = WINDOW_SWITCHER_CLASSIC;
rc.window_switcher.preview = true; rc.window_switcher.preview = true;
rc.window_switcher.outlines = true; rc.window_switcher.outlines = true;
rc.window_switcher.unshade = true;
rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE
| LAB_VIEW_CRITERIA_ROOT_TOPLEVEL | LAB_VIEW_CRITERIA_ROOT_TOPLEVEL
| LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER; | LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER;

View file

@ -96,6 +96,9 @@ end_cycling(struct server *server)
/* FIXME: osd_finish() transiently sets focus to the old surface */ /* FIXME: osd_finish() transiently sets focus to the old surface */
osd_finish(server); osd_finish(server);
/* Note that server->osd_state.cycle_view is cleared at this point */ /* Note that server->osd_state.cycle_view is cleared at this point */
if (rc.window_switcher.unshade) {
view_set_shade(cycle_view, false);
}
desktop_focus_view(cycle_view, /*raise*/ true); desktop_focus_view(cycle_view, /*raise*/ true);
} }

View file

@ -9,6 +9,7 @@
#include "common/scene-helpers.h" #include "common/scene-helpers.h"
#include "config/rcxml.h" #include "config/rcxml.h"
#include "labwc.h" #include "labwc.h"
#include "node.h"
#include "output.h" #include "output.h"
#include "scaled-buffer/scaled-font-buffer.h" #include "scaled-buffer/scaled-font-buffer.h"
#include "scaled-buffer/scaled-icon-buffer.h" #include "scaled-buffer/scaled-icon-buffer.h"
@ -160,9 +161,14 @@ restore_preview_node(struct server *server)
if (!osd_state->preview_was_enabled) { if (!osd_state->preview_was_enabled) {
wlr_scene_node_set_enabled(osd_state->preview_node, false); wlr_scene_node_set_enabled(osd_state->preview_node, false);
} }
if (osd_state->preview_was_shaded) {
struct view *view = node_view_from_node(osd_state->preview_node);
view_set_shade(view, true);
}
osd_state->preview_node = NULL; osd_state->preview_node = NULL;
osd_state->preview_parent = NULL; osd_state->preview_parent = NULL;
osd_state->preview_anchor = NULL; osd_state->preview_anchor = NULL;
osd_state->preview_was_shaded = false;
} }
} }
@ -203,6 +209,7 @@ osd_finish(struct server *server)
server->osd_state.preview_node = NULL; server->osd_state.preview_node = NULL;
server->osd_state.preview_anchor = NULL; server->osd_state.preview_anchor = NULL;
server->osd_state.cycle_view = NULL; server->osd_state.cycle_view = NULL;
server->osd_state.preview_was_shaded = false;
destroy_osd_scenes(server); destroy_osd_scenes(server);
@ -244,6 +251,10 @@ preview_cycled_view(struct view *view)
if (!osd_state->preview_was_enabled) { if (!osd_state->preview_was_enabled) {
wlr_scene_node_set_enabled(osd_state->preview_node, true); wlr_scene_node_set_enabled(osd_state->preview_node, true);
} }
if (rc.window_switcher.unshade && view->shaded) {
view_set_shade(view, false);
osd_state->preview_was_shaded = true;
}
/* /*
* FIXME: This abuses an implementation detail of the always-on-top tree. * FIXME: This abuses an implementation detail of the always-on-top tree.
@ -294,6 +305,10 @@ update_osd(struct server *server)
} }
} }
if (rc.window_switcher.preview) {
preview_cycled_view(server->osd_state.cycle_view);
}
/* Outline current window */ /* Outline current window */
if (rc.window_switcher.outlines) { if (rc.window_switcher.outlines) {
if (view_is_focusable(server->osd_state.cycle_view)) { if (view_is_focusable(server->osd_state.cycle_view)) {
@ -301,9 +316,6 @@ update_osd(struct server *server)
} }
} }
if (rc.window_switcher.preview) {
preview_cycled_view(server->osd_state.cycle_view);
}
out: out:
wl_array_release(&views); wl_array_release(&views);
} }