Merge "force_focus_wrapping" option into "focus_wrapping force"

Allow enabling forced focus wrapping by specifying "focus_wrapping
force" in i3's configuration. This syntax supersedes the previous
"force_focus_wrapping yes" one, which remains available for backwards
compatibility.
This commit is contained in:
Vladimir Panteleev 2017-09-22 23:41:38 +00:00
parent 28f7e14650
commit 50edf495aa
No known key found for this signature in database
GPG Key ID: 5004F0FAD051576D
7 changed files with 64 additions and 42 deletions

View File

@ -1044,38 +1044,34 @@ opposite window will be focused when trying to move the focus over the edge of
a container (and there are no other containers in that direction) -- the focus a container (and there are no other containers in that direction) -- the focus
wraps. wraps.
If desired, you can disable this behavior using the +focus_wrapping+ If desired, you can disable this behavior by setting the +focus_wrapping+
configuration directive: configuration directive to the value +no+.
*Syntax*: When enabled, focus wrapping does not occur by default if there is another
--------------------- window or container in the specified direction, and focus will instead be set
focus_wrapping yes|no on that window or container. This is the default behavior so you can navigate
--------------------- to all your windows without having to use +focus parent+.
*Example*:
-----------------
focus_wrapping no
-----------------
By default, focus wrapping does not occur if there is another window or
container in the specified direction, and focus will instead be set on that
window or container. This is the default behavior so you can navigate to all
your windows without having to use +focus parent+.
If you want the focus to *always* wrap and you are aware of using +focus If you want the focus to *always* wrap and you are aware of using +focus
parent+ to switch to different containers, you can use the parent+ to switch to different containers, you can instead set +focus_wrapping+
+force_focus_wrapping+ configuration directive. After enabling it, the focus to the value +force+.
will always wrap.
*Syntax*: *Syntax*:
--------------------------- ---------------------------
force_focus_wrapping yes|no focus_wrapping yes|no|force
# Legacy syntax, equivalent to "focus_wrapping force"
force_focus_wrapping yes
--------------------------- ---------------------------
*Example*: *Examples*:
------------------------ -----------------
force_focus_wrapping yes # Disable focus wrapping
------------------------ focus_wrapping no
# Force focus wrapping
focus_wrapping force
-----------------
=== Forcing Xinerama === Forcing Xinerama

View File

@ -142,18 +142,19 @@ struct Config {
* direction in which there are no more containers to focus) will * direction in which there are no more containers to focus) will
* cause the focus to wrap to the opposite edge of the current * cause the focus to wrap to the opposite edge of the current
* container. When it is disabled, nothing happens; the current * container. When it is disabled, nothing happens; the current
* focus is preserved. */ * focus is preserved.
bool focus_wrapping; *
* Additionally, focus wrapping may be forced. Think of the
/** Think of the following layout: Horizontal workspace with a tabbed * following layout: Horizontal workspace with a tabbed con on the
* con on the left of the screen and a terminal on the right of the * left of the screen and a terminal on the right of the
* screen. You are in the second container in the tabbed container and * screen. You are in the second container in the tabbed container
* focus to the right. By default, i3 will set focus to the terminal on * and focus to the right. By default, i3 will set focus to the
* the right. If you are in the first container in the tabbed container * terminal on the right. If you are in the first container in the
* however, focusing to the left will wrap. This option forces i3 to * tabbed container however, focusing to the left will
* always wrap, which will result in you having to use "focus parent" * wrap. Setting focus_wrapping to FOCUS_WRAPPING_FORCE forces i3
* more often. */ * to always wrap, which will result in you having to use "focus
bool force_focus_wrapping; * parent" more often. */
focus_wrapping_t focus_wrapping;
/** By default, use the RandR API for multi-monitor setups. /** By default, use the RandR API for multi-monitor setups.
* Unfortunately, the nVidia binary graphics driver doesn't support * Unfortunately, the nVidia binary graphics driver doesn't support

View File

@ -133,6 +133,15 @@ typedef enum {
POINTER_WARPING_NONE = 1 POINTER_WARPING_NONE = 1
} warping_t; } warping_t;
/**
* Focus wrapping modes.
*/
typedef enum {
FOCUS_WRAPPING_OFF = 0,
FOCUS_WRAPPING_ON = 1,
FOCUS_WRAPPING_FORCE = 2
} focus_wrapping_t;
/** /**
* Stores a rectangle, for example the size of a window, the child window etc. * Stores a rectangle, for example the size of a window, the child window etc.
* It needs to be packed so that the compiler will not add any padding bytes. * It needs to be packed so that the compiler will not add any padding bytes.

View File

@ -206,7 +206,7 @@ state MOUSE_WARPING:
# focus_wrapping # focus_wrapping
state FOCUS_WRAPPING: state FOCUS_WRAPPING:
value = word value = '1', 'yes', 'true', 'on', 'enable', 'active', '0', 'no', 'false', 'off', 'disable', 'inactive', 'force'
-> call cfg_focus_wrapping($value) -> call cfg_focus_wrapping($value)
# force_focus_wrapping # force_focus_wrapping

View File

@ -227,7 +227,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
if (config.workspace_urgency_timer == 0) if (config.workspace_urgency_timer == 0)
config.workspace_urgency_timer = 0.5; config.workspace_urgency_timer = 0.5;
config.focus_wrapping = true; config.focus_wrapping = FOCUS_WRAPPING_ON;
parse_configuration(override_configpath, true); parse_configuration(override_configpath, true);

View File

@ -265,11 +265,26 @@ CFGFUN(disable_randr15, const char *value) {
} }
CFGFUN(focus_wrapping, const char *value) { CFGFUN(focus_wrapping, const char *value) {
config.focus_wrapping = eval_boolstr(value); if (strcmp(value, "force") == 0) {
config.focus_wrapping = FOCUS_WRAPPING_FORCE;
} else if (eval_boolstr(value)) {
config.focus_wrapping = FOCUS_WRAPPING_ON;
} else {
config.focus_wrapping = FOCUS_WRAPPING_OFF;
}
} }
CFGFUN(force_focus_wrapping, const char *value) { CFGFUN(force_focus_wrapping, const char *value) {
config.force_focus_wrapping = eval_boolstr(value); /* Legacy syntax. */
if (eval_boolstr(value)) {
config.focus_wrapping = FOCUS_WRAPPING_FORCE;
} else {
/* For "force_focus_wrapping off", don't enable or disable
* focus wrapping, just ensure it's not forced. */
if (config.focus_wrapping == FOCUS_WRAPPING_FORCE) {
config.focus_wrapping = FOCUS_WRAPPING_ON;
}
}
} }
CFGFUN(workspace_back_and_forth, const char *value) { CFGFUN(workspace_back_and_forth, const char *value) {

View File

@ -641,7 +641,7 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap)
next = TAILQ_PREV(current, nodes_head, nodes); next = TAILQ_PREV(current, nodes_head, nodes);
if (!next) { if (!next) {
if (!config.force_focus_wrapping) { if (config.focus_wrapping != FOCUS_WRAPPING_FORCE) {
/* If there is no next/previous container, we check if we can focus one /* If there is no next/previous container, we check if we can focus one
* when going higher (without wrapping, though). If so, we are done, if * when going higher (without wrapping, though). If so, we are done, if
* not, we wrap */ * not, we wrap */
@ -675,7 +675,8 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap)
* *
*/ */
void tree_next(char way, orientation_t orientation) { void tree_next(char way, orientation_t orientation) {
_tree_next(focused, way, orientation, config.focus_wrapping); _tree_next(focused, way, orientation,
config.focus_wrapping != FOCUS_WRAPPING_OFF);
} }
/* /*