## WINDOW SWITCHER
```
-<windowSwitcher show="yes" style="classic" preview="yes" outlines="yes" allWorkspaces="no" thumbnailLabelFormat="%T">
+<windowSwitcher preview="yes" outlines="yes" allWorkspaces="no">
+ <osd show="yes" style="classic" output="all" thumbnailLabelFormat="%T" />
<fields>
<field content="icon" width="5%" />
<field content="desktop_entry_name" width="30%" />
</windowSwitcher>
```
-*<windowSwitcher show="" style="" preview="" outlines="" allWorkspaces="" unshade="" thumbnailLabelFormat="">*
- *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.
-
+*<windowSwitcher preview="" outlines="" allWorkspaces="" unshade="">*
*preview* [yes|no] Preview the contents of the selected window when
switching between windows. Default is yes.
*unshade* [yes|no] Temporarily unshade windows when switching between
them and permanently unshade on the final selection. Default is yes.
+*<osd show="" style="" output="" thumbnailLabelFormat="" />*
+ *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 *<windowSwitcher style="thumbnail" />*.
+ field below, only applied when using *<osd style="thumbnail" />*.
Default is "%T".
*<windowSwitcher><fields><field content="" width="%">*
- Define window switcher fields when using *<windowSwitcher style="classic" />*.
+ Define window switcher fields when using *<osd style="classic" />*.
*content* defines what the field shows and can be any of:
</font>
</theme>
- <windowSwitcher show="yes" style="classic" preview="yes"
- outlines="yes" allWorkspaces="no" unshade="yes">
+ <windowSwitcher preview="yes" outlines="yes" allWorkspaces="no" unshade="yes">
+ <osd show="yes" style="classic" output="all" thumbnailLabelFormat="%T" />
<fields>
<field content="icon" width="5%" />
<field content="desktop_entry_name" width="30%" />
Some contents are fixed-length and others are variable-length.
See "man 5 labwc-config" for details.
- <windowSwitcher show="yes" preview="no" outlines="no" allWorkspaces="yes">
+ <windowSwitcher preview="no" outlines="no" allWorkspaces="yes">
+ <osd show="yes" />
<fields>
<field content="workspace" width="5%" />
<field content="state" width="3%" />
then workspace name, then identifier/app-id, then the window title.
It uses 100% of OSD window width.
- <windowSwitcher show="yes" preview="no" outlines="no" allWorkspaces="yes">
+ <windowSwitcher preview="no" outlines="no" allWorkspaces="yes">
+ <osd show="yes" />
<fields>
<field content="custom" format="foobar %b %3s %-10o %-20W %-10i %t" width="100%" />
</fields>
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;
WINDOW_SWITCHER_THUMBNAIL,
};
+enum osd_output_criteria {
+ OSD_OUTPUT_ALL,
+ OSD_OUTPUT_POINTER,
+ OSD_OUTPUT_KEYBOARD,
+};
+
#endif /* LABWC_CONFIG_TYPES_H */
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)) {
wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient");
}
- /* <windowSwitcher show="" preview="" outlines="" /> */
+ /*
+ * <windowSwitcher preview="" outlines="">
+ * <osd show="" style="" output="" thumbnailLabelFormat="" />
+ * </windowSwitcher>
+ *
+ * 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, "<windowSwitcher show=\"\" /> is deprecated."
+ " Use <osd show=\"\" />");
} 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, "<windowSwitcher style=\"\" /> is deprecated."
+ " Use <osd style=\"\" />");
+
} else if (!strcasecmp(nodename, "preview.windowSwitcher")) {
set_bool(content, &rc.window_switcher.preview);
} else if (!strcasecmp(nodename, "outlines.windowSwitcher")) {
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;
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)
{
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);
}
}