diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index fe468cd1..33be0c26 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -125,8 +125,8 @@ 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 keybinds for NextWindow and PreviousWindow are Alt-Tab and @@ -145,6 +145,10 @@ Actions are used in menus and keyboard/mouse bindings. This determines whether to cycle through all windows or only windows of the same application as the currently focused window. Default is "all". + *window* [root|all] + This determines whether to cycle through only topmost (root) windows or + all windows including child windows such as dialogs. Default is "root". + ** Re-load configuration and theme files. diff --git a/include/config/types.h b/include/config/types.h index fc293cd8..23e32a4f 100644 --- a/include/config/types.h +++ b/include/config/types.h @@ -133,4 +133,9 @@ enum cycle_app_id_filter { CYCLE_APP_ID_CURRENT, }; +enum cycle_window_filter { + CYCLE_WINDOW_ROOT, + CYCLE_WINDOW_ALL, +}; + #endif /* LABWC_CONFIG_TYPES_H */ diff --git a/include/cycle.h b/include/cycle.h index c6e42810..5c2adf10 100644 --- a/include/cycle.h +++ b/include/cycle.h @@ -49,6 +49,7 @@ struct cycle_filter { enum cycle_workspace_filter workspace; enum cycle_output_filter output; enum cycle_app_id_filter app_id; + enum cycle_window_filter window; }; struct cycle_state { diff --git a/src/action.c b/src/action.c index 7f974917..b86fb1a1 100644 --- a/src/action.c +++ b/src/action.c @@ -403,6 +403,17 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char } goto cleanup; } + if (!strcasecmp(argument, "window")) { + if (!strcasecmp(content, "root")) { + action_arg_add_int(action, argument, CYCLE_WINDOW_ROOT); + } else if (!strcasecmp(content, "all")) { + action_arg_add_int(action, argument, CYCLE_WINDOW_ALL); + } 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")) { @@ -1174,6 +1185,8 @@ run_action(struct view *view, struct server *server, struct action *action, CYCLE_OUTPUT_ALL), .app_id = action_get_int(action, "identifier", CYCLE_APP_ID_ALL), + .window = action_get_int(action, "window", + CYCLE_WINDOW_ROOT), }; if (server->input_mode == LAB_INPUT_STATE_CYCLE) { cycle_step(server, dir); diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 32a7438f..7bbf7d55 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -331,8 +331,10 @@ static bool 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; + LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER; + if (filter.window == CYCLE_WINDOW_ROOT) { + criteria |= LAB_VIEW_CRITERIA_ROOT_TOPLEVEL; + } if (filter.workspace == CYCLE_WORKSPACE_CURRENT) { criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; }