diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 6be5f5f6..9b0f8291 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -339,7 +339,8 @@ this is for compatibility with Openbox. ## WINDOW SWITCHER ``` - + + @@ -348,14 +349,7 @@ this is for compatibility with Openbox. ``` -** - *show* [yes|no] Draw the OnScreenDisplay when switching between - windows. Default is yes. - - *style* [classic|thumbnail] Configures the style of the OnScreenDisplay. - "classic" displays window information like icons and titles in a vertical list. - "thumbnail" shows window thumbnail, icon and title in grids. - +** *preview* [yes|no] Preview the contents of the selected window when switching between windows. Default is yes. @@ -369,12 +363,26 @@ this is for compatibility with Openbox. *unshade* [yes|no] Temporarily unshade windows when switching between them and permanently unshade on the final selection. Default is yes. +** + *show* [yes|no] Draw the OnScreenDisplay when switching between + windows. Default is yes. + + *style* [classic|thumbnail] Configures the style of the OSD. + "classic" displays window information like icons and titles in a vertical list. + "thumbnail" shows window thumbnail, icon and title in grids. + + *output* [all|pointer|keyboard] Configures which monitor(s) show the OSD. + "all" displays the OSD on all monitors. + "pointer" displays the OSD on the monitor containing the mouse pointer. + "keyboard" displays the OSD on the monitor with keyboard focus. + Default is "all". + *thumbnailLabelFormat* Format to be used for the thumbnail label according to *custom* - field below, only applied when using **. + field below, only applied when using **. Default is "%T". ** - Define window switcher fields when using **. + Define window switcher fields when using **. *content* defines what the field shows and can be any of: diff --git a/docs/rc.xml.all b/docs/rc.xml.all index c581ff51..97698aac 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -77,8 +77,8 @@ - + + @@ -98,7 +98,8 @@ Some contents are fixed-length and others are variable-length. See "man 5 labwc-config" for details. - + + @@ -118,7 +119,8 @@ then workspace name, then identifier/app-id, then the window title. It uses 100% of OSD window width. - + + diff --git a/include/config/rcxml.h b/include/config/rcxml.h index c20cd800..91a73d58 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -183,6 +183,7 @@ struct rcxml { enum lab_view_criteria criteria; struct wl_list fields; /* struct window_switcher_field.link */ enum window_switcher_style style; + enum osd_output_criteria output_criteria; char *thumbnail_label_format; } window_switcher; diff --git a/include/config/types.h b/include/config/types.h index e832a658..76e699a4 100644 --- a/include/config/types.h +++ b/include/config/types.h @@ -112,4 +112,10 @@ enum window_switcher_style { WINDOW_SWITCHER_THUMBNAIL, }; +enum osd_output_criteria { + OSD_OUTPUT_ALL, + OSD_OUTPUT_POINTER, + OSD_OUTPUT_KEYBOARD, +}; + #endif /* LABWC_CONFIG_TYPES_H */ diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 1acdd825..264c65a8 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1068,7 +1068,7 @@ entry(xmlNode *node, char *nodename, char *content) load_default_mouse_bindings(); } else if (!strcasecmp(nodename, "prefix.desktops")) { xstrdup_replace(rc.workspace_config.prefix, content); - } else if (!strcasecmp(nodename, "thumbnailLabelFormat.windowSwitcher")) { + } else if (!strcasecmp(nodename, "thumbnailLabelFormat.osd.windowSwitcher")) { xstrdup_replace(rc.window_switcher.thumbnail_label_format, content); } else if (!lab_xml_node_is_leaf(node)) { @@ -1201,15 +1201,50 @@ entry(xmlNode *node, char *nodename, char *content) wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient"); } - /* */ + /* + * + * + * + * + * thumnailLabelFormat is handled above to allow for an empty value + */ + } else if (!strcasecmp(nodename, "show.osd.windowSwitcher")) { + set_bool(content, &rc.window_switcher.show); + } else if (!strcasecmp(nodename, "style.osd.windowSwitcher")) { + if (!strcasecmp(content, "classic")) { + rc.window_switcher.style = WINDOW_SWITCHER_CLASSIC; + } else if (!strcasecmp(content, "thumbnail")) { + rc.window_switcher.style = WINDOW_SWITCHER_THUMBNAIL; + } else { + wlr_log(WLR_ERROR, "Invalid windowSwitcher style %s: " + "should be one of classic|thumbnail", content); + } + } else if (!strcasecmp(nodename, "output.osd.windowSwitcher")) { + if (!strcasecmp(content, "all")) { + rc.window_switcher.output_criteria = OSD_OUTPUT_ALL; + } else if (!strcasecmp(content, "pointer")) { + rc.window_switcher.output_criteria = OSD_OUTPUT_POINTER; + } else if (!strcasecmp(content, "keyboard")) { + rc.window_switcher.output_criteria = OSD_OUTPUT_KEYBOARD; + } else { + wlr_log(WLR_ERROR, "Invalid windowSwitcher output %s: " + "should be one of all|pointer|keyboard", content); + } + + /* The following two are for backward compatibility only. */ } else if (!strcasecmp(nodename, "show.windowSwitcher")) { set_bool(content, &rc.window_switcher.show); + wlr_log(WLR_ERROR, " is deprecated." + " Use "); } else if (!strcasecmp(nodename, "style.windowSwitcher")) { if (!strcasecmp(content, "classic")) { rc.window_switcher.style = WINDOW_SWITCHER_CLASSIC; } else if (!strcasecmp(content, "thumbnail")) { rc.window_switcher.style = WINDOW_SWITCHER_THUMBNAIL; } + wlr_log(WLR_ERROR, " is deprecated." + " Use "); + } else if (!strcasecmp(nodename, "preview.windowSwitcher")) { set_bool(content, &rc.window_switcher.preview); } else if (!strcasecmp(nodename, "outlines.windowSwitcher")) { @@ -1431,6 +1466,7 @@ rcxml_init(void) rc.window_switcher.show = true; rc.window_switcher.style = WINDOW_SWITCHER_CLASSIC; + rc.window_switcher.output_criteria = OSD_OUTPUT_ALL; rc.window_switcher.thumbnail_label_format = xstrdup("%T"); rc.window_switcher.preview = true; rc.window_switcher.outlines = true; diff --git a/src/osd/osd.c b/src/osd/osd.c index ca64920c..3f2d8074 100644 --- a/src/osd/osd.c +++ b/src/osd/osd.c @@ -294,6 +294,20 @@ preview_cycled_view(struct view *view) wlr_scene_node_raise_to_top(osd_state->preview_node); } +static void +update_osd_on_output(struct server *server, struct output *output, + struct osd_impl *osd_impl, struct wl_array *views) +{ + if (!output_is_usable(output)) { + return; + } + if (!output->osd_scene.tree) { + osd_impl->create(output, views); + assert(output->osd_scene.tree); + } + osd_impl->update(output); +} + static void update_osd(struct server *server) { @@ -318,16 +332,29 @@ 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; + switch (rc.window_switcher.output_criteria) { + case OSD_OUTPUT_ALL: { + struct output *output; + wl_list_for_each(output, &server->outputs, link) { + update_osd_on_output(server, output, osd_impl, &views); + } + break; } - if (!output->osd_scene.tree) { - osd_impl->create(output, &views); - assert(output->osd_scene.tree); + case OSD_OUTPUT_POINTER: + update_osd_on_output(server, + output_nearest_to_cursor(server), osd_impl, &views); + break; + case OSD_OUTPUT_KEYBOARD: { + struct output *output; + if (server->active_view) { + output = server->active_view->output; + } else { + /* Fallback to pointer, if there is no active_view */ + output = output_nearest_to_cursor(server); + } + update_osd_on_output(server, output, osd_impl, &views); + break; } - osd_impl->update(output); } }