From 764cd942eb4cef721b615866a05b43e2237fbc76 Mon Sep 17 00:00:00 2001 From: Samet Aylak Date: Sun, 2 Nov 2025 08:54:29 -0500 Subject: [PATCH] Add `allOutputs` option to window switcher Introduces a new configuration option for the window switcher that allows users to filter windows by output (monitor). Changes: - Added `allOutputs` attribute to - Default is "no" (only shows windows on the cursor's output) - When set to "yes", shows windows from all outputs - Introduced LAB_VIEW_CRITERIA_CURSOR_OUTPUT flag to filter views by output - Windows are matched against the output nearest to the cursor - Bit positions of existing criteria flags shifted to accommodate new flag - Modified OSD display behavior to show only on the cursor's output - Previously, the OSD would appear on all outputs simultaneously - Now displays only on the output nearest to the cursor location This provides better multi-monitor support by allowing users to focus on windows relevant to their current screen, reducing visual clutter when working across multiple displays. --- docs/labwc-config.5.scd | 8 ++++++-- docs/rc.xml.all | 6 +++--- include/config/types.h | 13 +++++++------ src/config/rcxml.c | 6 ++++++ src/osd/osd.c | 19 ++++++++++++++----- src/view.c | 7 +++++++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 00817898..fd87e5cd 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -339,7 +339,7 @@ this is for compatibility with Openbox. ## WINDOW SWITCHER ``` - + @@ -348,7 +348,7 @@ this is for compatibility with Openbox. ``` -** +** *show* [yes|no] Draw the OnScreenDisplay when switching between windows. Default is yes. @@ -366,6 +366,10 @@ this is for compatibility with Openbox. they are on. Default no (that is only windows on the current workspace are shown). + *allOutputs* [yes|no] Show windows regardless of what output + they are on. Default no (that is only windows on the cursor output + are shown). + *unshade* [yes|no] Temporarily unshade windows when switching between them and permanently unshade on the final selection. Default is yes. diff --git a/docs/rc.xml.all b/docs/rc.xml.all index c581ff51..d55ad754 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -78,7 +78,7 @@ + outlines="yes" allWorkspaces="no" allOutputs="no" unshade="yes"> @@ -98,7 +98,7 @@ Some contents are fixed-length and others are variable-length. See "man 5 labwc-config" for details. - + @@ -118,7 +118,7 @@ then workspace name, then identifier/app-id, then the window title. It uses 100% of OSD window width. - + diff --git a/include/config/types.h b/include/config/types.h index e832a658..b4e41318 100644 --- a/include/config/types.h +++ b/include/config/types.h @@ -67,16 +67,17 @@ enum lab_view_criteria { * what is visible on the current workspace */ LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0, + LAB_VIEW_CRITERIA_CURSOR_OUTPUT = 1 << 1, /* Positive criteria */ - LAB_VIEW_CRITERIA_FULLSCREEN = 1 << 1, - LAB_VIEW_CRITERIA_ALWAYS_ON_TOP = 1 << 2, - LAB_VIEW_CRITERIA_ROOT_TOPLEVEL = 1 << 3, + LAB_VIEW_CRITERIA_FULLSCREEN = 1 << 2, + LAB_VIEW_CRITERIA_ALWAYS_ON_TOP = 1 << 3, + LAB_VIEW_CRITERIA_ROOT_TOPLEVEL = 1 << 4, /* Negative criteria */ - LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 6, - LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 7, - LAB_VIEW_CRITERIA_NO_OMNIPRESENT = 1 << 8, + LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 7, + LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 8, + LAB_VIEW_CRITERIA_NO_OMNIPRESENT = 1 << 9, }; /* diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 6ed1522b..84a4b43f 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1217,6 +1217,11 @@ entry(xmlNode *node, char *nodename, char *content) rc.window_switcher.criteria &= ~LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; } + } else if (!strcasecmp(nodename, "allOutputs.windowSwitcher")) { + if (parse_bool(content, -1) == true) { + rc.window_switcher.criteria &= + ~LAB_VIEW_CRITERIA_CURSOR_OUTPUT; + } } else if (!strcasecmp(nodename, "unshade.windowSwitcher")) { set_bool(content, &rc.window_switcher.unshade); @@ -1433,6 +1438,7 @@ rcxml_init(void) rc.window_switcher.outlines = true; rc.window_switcher.unshade = true; rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE + | LAB_VIEW_CRITERIA_CURSOR_OUTPUT | LAB_VIEW_CRITERIA_ROOT_TOPLEVEL | LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER; diff --git a/src/osd/osd.c b/src/osd/osd.c index e436c19e..345890d3 100644 --- a/src/osd/osd.c +++ b/src/osd/osd.c @@ -292,11 +292,20 @@ update_osd(struct server *server) if (rc.window_switcher.show) { /* Display the actual OSD */ - struct output *output; - wl_list_for_each(output, &server->outputs, link) { - if (!output_is_usable(output)) { - continue; - } + // struct output *output; + // wl_list_for_each(output, &server->outputs, link) { + // if (!output_is_usable(output)) { + // continue; + // } + // if (!output->osd_scene.tree) { + // osd_impl->create(output, &views); + // assert(output->osd_scene.tree); + // } + // osd_impl->update(output); + // } + + struct output *output = output_nearest_to_cursor(server); + if (output_is_usable(output)) { if (!output->osd_scene.tree) { osd_impl->create(output, &views); assert(output->osd_scene.tree); diff --git a/src/view.c b/src/view.c index 87ef8566..a093cd16 100644 --- a/src/view.c +++ b/src/view.c @@ -277,6 +277,13 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria) return false; } } + if (criteria & LAB_VIEW_CRITERIA_CURSOR_OUTPUT) { + struct server *server = view->server; + struct output *output = output_nearest_to_cursor(server); + if (view->output != output) { + return false; + } + } if (criteria & LAB_VIEW_CRITERIA_FULLSCREEN) { if (!view->fullscreen) { return false;