mirror of
https://github.com/labwc/labwc.git
synced 2026-02-05 04:06:33 -05:00
cycle: support <action name="NextWindow" workspace="current|all">
This commit deprecates <windowSwitcher allWorkspaces="yes|no"> and adds per-action argument <action name="NextWindow" workspace="current|all">.
This commit is contained in:
parent
caa9b90e80
commit
a5c6ff499c
10 changed files with 78 additions and 35 deletions
|
|
@ -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
|
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.
|
position if it had been maximized or tiled to a direction or region.
|
||||||
|
|
||||||
*<action name="NextWindow" />*++
|
*<action name="NextWindow" workspace="current" />*++
|
||||||
*<action name="PreviousWindow" />*
|
*<action name="PreviousWindow" workspace="current" />*
|
||||||
Cycle focus to next/previous window, respectively.
|
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".
|
||||||
|
|
||||||
*<action name="Reconfigure" />*
|
*<action name="Reconfigure" />*
|
||||||
Re-load configuration and theme files.
|
Re-load configuration and theme files.
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,7 @@ this is for compatibility with Openbox.
|
||||||
## WINDOW SWITCHER
|
## WINDOW SWITCHER
|
||||||
|
|
||||||
```
|
```
|
||||||
<windowSwitcher preview="yes" outlines="yes" allWorkspaces="no">
|
<windowSwitcher preview="yes" outlines="yes">
|
||||||
<osd show="yes" style="classic" output="all" thumbnailLabelFormat="%T" />
|
<osd show="yes" style="classic" output="all" thumbnailLabelFormat="%T" />
|
||||||
<fields>
|
<fields>
|
||||||
<field content="icon" width="5%" />
|
<field content="icon" width="5%" />
|
||||||
|
|
@ -349,17 +349,13 @@ this is for compatibility with Openbox.
|
||||||
</windowSwitcher>
|
</windowSwitcher>
|
||||||
```
|
```
|
||||||
|
|
||||||
*<windowSwitcher preview="" outlines="" allWorkspaces="" unshade="" order="">*
|
*<windowSwitcher preview="" outlines="" unshade="" order="">*
|
||||||
*preview* [yes|no] Preview the contents of the selected window when
|
*preview* [yes|no] Preview the contents of the selected window when
|
||||||
switching between windows. Default is yes.
|
switching between windows. Default is yes.
|
||||||
|
|
||||||
*outlines* [yes|no] Draw an outline around the selected window when
|
*outlines* [yes|no] Draw an outline around the selected window when
|
||||||
switching between windows. Default is yes.
|
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
|
*unshade* [yes|no] Temporarily unshade windows when switching between
|
||||||
them and permanently unshade on the final selection. Default is yes.
|
them and permanently unshade on the final selection. Default is yes.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
</font>
|
</font>
|
||||||
</theme>
|
</theme>
|
||||||
|
|
||||||
<windowSwitcher preview="yes" outlines="yes" allWorkspaces="no" unshade="yes">
|
<windowSwitcher preview="yes" outlines="yes" unshade="yes">
|
||||||
<osd show="yes" style="classic" output="all" thumbnailLabelFormat="%T" />
|
<osd show="yes" style="classic" output="all" thumbnailLabelFormat="%T" />
|
||||||
<fields>
|
<fields>
|
||||||
<field content="icon" width="5%" />
|
<field content="icon" width="5%" />
|
||||||
|
|
@ -119,7 +119,7 @@
|
||||||
then workspace name, then identifier/app-id, then the window title.
|
then workspace name, then identifier/app-id, then the window title.
|
||||||
It uses 100% of OSD window width.
|
It uses 100% of OSD window width.
|
||||||
|
|
||||||
<windowSwitcher preview="no" outlines="no" allWorkspaces="yes">
|
<windowSwitcher preview="no" outlines="no">
|
||||||
<osd show="yes" />
|
<osd show="yes" />
|
||||||
<fields>
|
<fields>
|
||||||
<field content="custom" format="foobar %b %3s %-10o %-20W %-10i %t" width="100%" />
|
<field content="custom" format="foobar %b %3s %-10o %-20W %-10i %t" width="100%" />
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ struct rcxml {
|
||||||
bool outlines;
|
bool outlines;
|
||||||
bool unshade;
|
bool unshade;
|
||||||
enum window_switcher_order order;
|
enum window_switcher_order order;
|
||||||
enum lab_view_criteria criteria;
|
enum cycle_workspace_filter workspace_filter; /* deprecated */
|
||||||
struct {
|
struct {
|
||||||
bool show;
|
bool show;
|
||||||
enum cycle_osd_style style;
|
enum cycle_osd_style style;
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,11 @@ enum cycle_osd_style {
|
||||||
CYCLE_OSD_STYLE_THUMBNAIL,
|
CYCLE_OSD_STYLE_THUMBNAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum cycle_workspace_filter {
|
||||||
|
CYCLE_WORKSPACE_ALL,
|
||||||
|
CYCLE_WORKSPACE_CURRENT,
|
||||||
|
};
|
||||||
|
|
||||||
enum cycle_output_filter {
|
enum cycle_output_filter {
|
||||||
CYCLE_OUTPUT_ALL,
|
CYCLE_OUTPUT_ALL,
|
||||||
CYCLE_OUTPUT_CURSOR,
|
CYCLE_OUTPUT_CURSOR,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
#include "config/types.h"
|
||||||
|
|
||||||
struct output;
|
struct output;
|
||||||
|
|
||||||
|
|
@ -42,13 +43,18 @@ struct cycle_osd_field {
|
||||||
struct wl_list link; /* struct rcxml.window_switcher.osd.fields */
|
struct wl_list link; /* struct rcxml.window_switcher.osd.fields */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cycle_filter {
|
||||||
|
enum cycle_workspace_filter workspace;
|
||||||
|
};
|
||||||
|
|
||||||
struct buf;
|
struct buf;
|
||||||
struct view;
|
struct view;
|
||||||
struct server;
|
struct server;
|
||||||
struct wlr_scene_node;
|
struct wlr_scene_node;
|
||||||
|
|
||||||
/* Begin window switcher */
|
/* 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 */
|
/* Cycle the selected view in the window switcher */
|
||||||
void cycle_step(struct server *server, enum lab_cycle_dir direction);
|
void cycle_step(struct server *server, enum lab_cycle_dir direction);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <wlr/util/box.h>
|
#include <wlr/util/box.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "common/set.h"
|
#include "common/set.h"
|
||||||
|
#include "cycle.h"
|
||||||
#include "input/cursor.h"
|
#include "input/cursor.h"
|
||||||
#include "overlay.h"
|
#include "overlay.h"
|
||||||
|
|
||||||
|
|
@ -310,6 +311,7 @@ struct server {
|
||||||
struct wlr_scene_node *preview_node;
|
struct wlr_scene_node *preview_node;
|
||||||
struct wlr_scene_node *preview_dummy;
|
struct wlr_scene_node *preview_dummy;
|
||||||
struct lab_scene_rect *preview_outline;
|
struct lab_scene_rect *preview_outline;
|
||||||
|
struct cycle_filter filter;
|
||||||
} cycle;
|
} cycle;
|
||||||
|
|
||||||
struct theme *theme;
|
struct theme *theme;
|
||||||
|
|
|
||||||
33
src/action.c
33
src/action.c
|
|
@ -366,6 +366,20 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case ACTION_TYPE_SHOW_MENU:
|
||||||
if (!strcmp(argument, "menu")) {
|
if (!strcmp(argument, "menu")) {
|
||||||
action_arg_add_str(action, argument, content);
|
action_arg_add_str(action, argument, content);
|
||||||
|
|
@ -1126,19 +1140,20 @@ run_action(struct view *view, struct server *server, struct action *action,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_TYPE_NEXT_WINDOW:
|
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) {
|
if (server->input_mode == LAB_INPUT_STATE_CYCLE) {
|
||||||
cycle_step(server, LAB_CYCLE_DIR_FORWARD);
|
cycle_step(server, dir);
|
||||||
} else {
|
} else {
|
||||||
cycle_begin(server, LAB_CYCLE_DIR_FORWARD);
|
cycle_begin(server, dir, filter);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ACTION_TYPE_RECONFIGURE:
|
case ACTION_TYPE_RECONFIGURE:
|
||||||
kill(getpid(), SIGHUP);
|
kill(getpid(), SIGHUP);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1269,10 +1269,16 @@ entry(xmlNode *node, char *nodename, char *content)
|
||||||
} else if (!strcasecmp(nodename, "outlines.windowSwitcher")) {
|
} else if (!strcasecmp(nodename, "outlines.windowSwitcher")) {
|
||||||
set_bool(content, &rc.window_switcher.outlines);
|
set_bool(content, &rc.window_switcher.outlines);
|
||||||
} else if (!strcasecmp(nodename, "allWorkspaces.windowSwitcher")) {
|
} else if (!strcasecmp(nodename, "allWorkspaces.windowSwitcher")) {
|
||||||
if (parse_bool(content, -1) == true) {
|
int ret = parse_bool(content, -1);
|
||||||
rc.window_switcher.criteria &=
|
if (ret < 0) {
|
||||||
~LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
|
wlr_log(WLR_ERROR, "Invalid value for <windowSwitcher"
|
||||||
|
" allWorkspaces=\"\">: '%s'", content);
|
||||||
|
} else {
|
||||||
|
rc.window_switcher.workspace_filter = ret ?
|
||||||
|
CYCLE_WORKSPACE_ALL : CYCLE_WORKSPACE_CURRENT;
|
||||||
}
|
}
|
||||||
|
wlr_log(WLR_ERROR, "<windowSwitcher allWorkspaces=\"\" /> is deprecated."
|
||||||
|
" Use <action name=\"NextWindow\" workspace=\"\"> instead.");
|
||||||
} else if (!strcasecmp(nodename, "unshade.windowSwitcher")) {
|
} else if (!strcasecmp(nodename, "unshade.windowSwitcher")) {
|
||||||
set_bool(content, &rc.window_switcher.unshade);
|
set_bool(content, &rc.window_switcher.unshade);
|
||||||
|
|
||||||
|
|
@ -1493,9 +1499,7 @@ rcxml_init(void)
|
||||||
rc.window_switcher.preview = true;
|
rc.window_switcher.preview = true;
|
||||||
rc.window_switcher.outlines = true;
|
rc.window_switcher.outlines = true;
|
||||||
rc.window_switcher.unshade = true;
|
rc.window_switcher.unshade = true;
|
||||||
rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE
|
rc.window_switcher.workspace_filter = CYCLE_WORKSPACE_CURRENT;
|
||||||
| LAB_VIEW_CRITERIA_ROOT_TOPLEVEL
|
|
||||||
| LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER;
|
|
||||||
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS;
|
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS;
|
||||||
|
|
||||||
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
|
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.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 update_cycle(struct server *server);
|
||||||
static void destroy_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 = cycle->selected_view;
|
||||||
struct view *selected_view_prev =
|
struct view *selected_view_prev =
|
||||||
get_next_selected_view(server, LAB_CYCLE_DIR_BACKWARD);
|
get_next_selected_view(server, LAB_CYCLE_DIR_BACKWARD);
|
||||||
|
struct cycle_filter filter = cycle->filter;
|
||||||
|
|
||||||
destroy_cycle(server);
|
destroy_cycle(server);
|
||||||
if (init_cycle(server)) {
|
if (init_cycle(server, filter)) {
|
||||||
/*
|
/*
|
||||||
* Preserve the selected view (or its previous view) if it's
|
* Preserve the selected view (or its previous view) if it's
|
||||||
* still in the cycle list
|
* still in the cycle list
|
||||||
|
|
@ -152,13 +153,14 @@ restore_preview_node(struct server *server)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!init_cycle(server)) {
|
if (!init_cycle(server, filter)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,10 +316,17 @@ insert_view_ordered_by_age(struct wl_list *views, struct view *new_view)
|
||||||
|
|
||||||
/* Return false on failure */
|
/* Return false on failure */
|
||||||
static bool
|
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;
|
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) {
|
if (rc.window_switcher.order == WINDOW_SWITCHER_ORDER_AGE) {
|
||||||
insert_view_ordered_by_age(&server->cycle.views, view);
|
insert_view_ordered_by_age(&server->cycle.views, view);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -328,6 +337,7 @@ init_cycle(struct server *server)
|
||||||
wlr_log(WLR_DEBUG, "no views to switch between");
|
wlr_log(WLR_DEBUG, "no views to switch between");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
server->cycle.filter = filter;
|
||||||
|
|
||||||
if (rc.window_switcher.osd.show) {
|
if (rc.window_switcher.osd.show) {
|
||||||
/* Create OSD */
|
/* Create OSD */
|
||||||
|
|
@ -406,4 +416,5 @@ destroy_cycle(struct server *server)
|
||||||
}
|
}
|
||||||
|
|
||||||
server->cycle.selected_view = NULL;
|
server->cycle.selected_view = NULL;
|
||||||
|
server->cycle.filter = (struct cycle_filter){0};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue