diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd
index 7788d551..56c840a6 100644
--- a/docs/labwc-actions.5.scd
+++ b/docs/labwc-actions.5.scd
@@ -125,13 +125,17 @@ Actions are used in menus and keyboard/mouse bindings.
Resize and move the active window back to its untiled or unmaximized
position if it had been maximized or tiled to a direction or region.
-**++
-**
+**++
+**
Cycle focus to next/previous window, respectively.
- Default keybind for NextWindow is Alt-Tab.
+ Default keybinds for NextWindow and PreviousWindow are Alt-Tab and
+ Shift-Alt-Tab. While cycling through windows, the arrow keys move the
+ selected window forwards/backwards and the escape key halts the cycling.
- The arrow keys are used to move forwards/backwards while cycling.
+ *workspace* [all|current]
+ This determines whether to cycle through windows on all workspaces or the
+ current workspace. Default is "current".
**
Re-load configuration and theme files.
diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd
index 85363354..a1cedb20 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
```
-
+
@@ -349,17 +349,13 @@ this is for compatibility with Openbox.
```
-**
+**
*preview* [yes|no] Preview the contents of the selected window when
switching between windows. Default is yes.
*outlines* [yes|no] Draw an outline around the selected window when
switching between windows. Default is yes.
- *allWorkspaces* [yes|no] Show windows regardless of what workspace
- they are on. Default no (that is only windows on the current workspace
- 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 a99aa997..dd348300 100644
--- a/docs/rc.xml.all
+++ b/docs/rc.xml.all
@@ -77,7 +77,7 @@
-
+
@@ -119,7 +119,7 @@
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 8fd11aa0..6036be9c 100644
--- a/include/config/rcxml.h
+++ b/include/config/rcxml.h
@@ -182,7 +182,7 @@ struct rcxml {
bool outlines;
bool unshade;
enum window_switcher_order order;
- enum lab_view_criteria criteria;
+ enum cycle_workspace_filter workspace_filter; /* deprecated */
struct {
bool show;
enum cycle_osd_style style;
diff --git a/include/config/types.h b/include/config/types.h
index 540f609f..81d8fd36 100644
--- a/include/config/types.h
+++ b/include/config/types.h
@@ -117,6 +117,11 @@ enum cycle_osd_style {
CYCLE_OSD_STYLE_THUMBNAIL,
};
+enum cycle_workspace_filter {
+ CYCLE_WORKSPACE_ALL,
+ CYCLE_WORKSPACE_CURRENT,
+};
+
enum cycle_output_filter {
CYCLE_OUTPUT_ALL,
CYCLE_OUTPUT_CURSOR,
diff --git a/include/cycle.h b/include/cycle.h
index ba58b88d..2f2c5a2a 100644
--- a/include/cycle.h
+++ b/include/cycle.h
@@ -4,6 +4,7 @@
#include
#include
+#include "config/types.h"
struct output;
@@ -42,13 +43,18 @@ struct cycle_osd_field {
struct wl_list link; /* struct rcxml.window_switcher.osd.fields */
};
+struct cycle_filter {
+ enum cycle_workspace_filter workspace;
+};
+
struct buf;
struct view;
struct server;
struct wlr_scene_node;
/* Begin window switcher */
-void cycle_begin(struct server *server, enum lab_cycle_dir direction);
+void cycle_begin(struct server *server, enum lab_cycle_dir direction,
+ struct cycle_filter filter);
/* Cycle the selected view in the window switcher */
void cycle_step(struct server *server, enum lab_cycle_dir direction);
diff --git a/include/labwc.h b/include/labwc.h
index 3d3ca2a3..ee10af12 100644
--- a/include/labwc.h
+++ b/include/labwc.h
@@ -5,6 +5,7 @@
#include
#include
#include "common/set.h"
+#include "cycle.h"
#include "input/cursor.h"
#include "overlay.h"
@@ -310,6 +311,7 @@ struct server {
struct wlr_scene_node *preview_node;
struct wlr_scene_node *preview_dummy;
struct lab_scene_rect *preview_outline;
+ struct cycle_filter filter;
} cycle;
struct theme *theme;
diff --git a/src/action.c b/src/action.c
index 7ddba0be..9fb7ca22 100644
--- a/src/action.c
+++ b/src/action.c
@@ -366,6 +366,20 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
goto cleanup;
}
break;
+ case ACTION_TYPE_NEXT_WINDOW:
+ case ACTION_TYPE_PREVIOUS_WINDOW:
+ if (!strcasecmp(argument, "workspace")) {
+ if (!strcasecmp(content, "all")) {
+ action_arg_add_int(action, argument, CYCLE_WORKSPACE_ALL);
+ } else if (!strcasecmp(content, "current")) {
+ action_arg_add_int(action, argument, CYCLE_WORKSPACE_CURRENT);
+ } else {
+ wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
+ action_names[action->type], argument, content);
+ }
+ goto cleanup;
+ }
+ break;
case ACTION_TYPE_SHOW_MENU:
if (!strcmp(argument, "menu")) {
action_arg_add_str(action, argument, content);
@@ -1126,19 +1140,20 @@ run_action(struct view *view, struct server *server, struct action *action,
}
break;
case ACTION_TYPE_NEXT_WINDOW:
+ case ACTION_TYPE_PREVIOUS_WINDOW: {
+ enum lab_cycle_dir dir = (action->type == ACTION_TYPE_NEXT_WINDOW) ?
+ LAB_CYCLE_DIR_FORWARD : LAB_CYCLE_DIR_BACKWARD;
+ struct cycle_filter filter = {
+ .workspace = action_get_int(action, "workspace",
+ rc.window_switcher.workspace_filter),
+ };
if (server->input_mode == LAB_INPUT_STATE_CYCLE) {
- cycle_step(server, LAB_CYCLE_DIR_FORWARD);
+ cycle_step(server, dir);
} else {
- cycle_begin(server, LAB_CYCLE_DIR_FORWARD);
- }
- break;
- case ACTION_TYPE_PREVIOUS_WINDOW:
- if (server->input_mode == LAB_INPUT_STATE_CYCLE) {
- cycle_step(server, LAB_CYCLE_DIR_BACKWARD);
- } else {
- cycle_begin(server, LAB_CYCLE_DIR_BACKWARD);
+ cycle_begin(server, dir, filter);
}
break;
+ }
case ACTION_TYPE_RECONFIGURE:
kill(getpid(), SIGHUP);
break;
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index 60e709f2..00217596 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -1269,10 +1269,16 @@ entry(xmlNode *node, char *nodename, char *content)
} else if (!strcasecmp(nodename, "outlines.windowSwitcher")) {
set_bool(content, &rc.window_switcher.outlines);
} else if (!strcasecmp(nodename, "allWorkspaces.windowSwitcher")) {
- if (parse_bool(content, -1) == true) {
- rc.window_switcher.criteria &=
- ~LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
+ int ret = parse_bool(content, -1);
+ if (ret < 0) {
+ wlr_log(WLR_ERROR, "Invalid value for : '%s'", content);
+ } else {
+ rc.window_switcher.workspace_filter = ret ?
+ CYCLE_WORKSPACE_ALL : CYCLE_WORKSPACE_CURRENT;
}
+ wlr_log(WLR_ERROR, " is deprecated."
+ " Use instead.");
} else if (!strcasecmp(nodename, "unshade.windowSwitcher")) {
set_bool(content, &rc.window_switcher.unshade);
@@ -1493,9 +1499,7 @@ rcxml_init(void)
rc.window_switcher.preview = true;
rc.window_switcher.outlines = true;
rc.window_switcher.unshade = true;
- rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE
- | LAB_VIEW_CRITERIA_ROOT_TOPLEVEL
- | LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER;
+ rc.window_switcher.workspace_filter = CYCLE_WORKSPACE_CURRENT;
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS;
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c
index 067c9929..9ae5b9b0 100644
--- a/src/cycle/cycle.c
+++ b/src/cycle/cycle.c
@@ -17,7 +17,7 @@
#include "theme.h"
#include "view.h"
-static bool init_cycle(struct server *server);
+static bool init_cycle(struct server *server, struct cycle_filter filter);
static void update_cycle(struct server *server);
static void destroy_cycle(struct server *server);
@@ -93,9 +93,10 @@ cycle_reinitialize(struct server *server)
struct view *selected_view = cycle->selected_view;
struct view *selected_view_prev =
get_next_selected_view(server, LAB_CYCLE_DIR_BACKWARD);
+ struct cycle_filter filter = cycle->filter;
destroy_cycle(server);
- if (init_cycle(server)) {
+ if (init_cycle(server, filter)) {
/*
* Preserve the selected view (or its previous view) if it's
* still in the cycle list
@@ -152,13 +153,14 @@ restore_preview_node(struct server *server)
}
void
-cycle_begin(struct server *server, enum lab_cycle_dir direction)
+cycle_begin(struct server *server, enum lab_cycle_dir direction,
+ struct cycle_filter filter)
{
if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
return;
}
- if (!init_cycle(server)) {
+ if (!init_cycle(server, filter)) {
return;
}
@@ -314,10 +316,17 @@ insert_view_ordered_by_age(struct wl_list *views, struct view *new_view)
/* Return false on failure */
static bool
-init_cycle(struct server *server)
+init_cycle(struct server *server, struct cycle_filter filter)
{
+ enum lab_view_criteria criteria =
+ LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER
+ | LAB_VIEW_CRITERIA_ROOT_TOPLEVEL;
+ if (filter.workspace == CYCLE_WORKSPACE_CURRENT) {
+ criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
+ }
+
struct view *view;
- for_each_view(view, &server->views, rc.window_switcher.criteria) {
+ for_each_view(view, &server->views, criteria) {
if (rc.window_switcher.order == WINDOW_SWITCHER_ORDER_AGE) {
insert_view_ordered_by_age(&server->cycle.views, view);
} else {
@@ -328,6 +337,7 @@ init_cycle(struct server *server)
wlr_log(WLR_DEBUG, "no views to switch between");
return false;
}
+ server->cycle.filter = filter;
if (rc.window_switcher.osd.show) {
/* Create OSD */
@@ -406,4 +416,5 @@ destroy_cycle(struct server *server)
}
server->cycle.selected_view = NULL;
+ server->cycle.filter = (struct cycle_filter){0};
}