mirror of
https://github.com/swaywm/sway.git
synced 2026-07-04 00:06:09 -04:00
commands/focus: implement focus wrapping for floating windows
When switching focus between floating windows, those in exactly the same location (like newly floated windows) have a relative distance of 0. Previously, since 0 is not `< 0`, all were considered valid candidates for focus in any direction. This led to two issues: 1. It was not possible to directionally focus away from a set of windows in the same location, as the distance of 0 to the other window in that location was considered closer than a floating window in another location. 2. If floating windows were moved from the same location, any window in the opposite direction had a negative distance and would be ignored as a focus candidate, so focus switching did not "wrap". Focusing a window raises it to the end of workspace->floating. A set of windows in the same location were always valid focus candidates, so shuffling focus between them created the illusion that focus was wrapping, when it was actually just "trapped" in that location. This change fixes both issues: 1. The distance check is changed to `<= 0`. Windows at distance 0 are no longer considered valid candidates in the target direction, allowing directional focus change to escape windows in the same location. 2. The furthest window in the opposite direction is now tracked. If no focus candidates are found in the target direction and focus wrapping is enabled, focus will now wrap around to the furthest window in the opposite direction.
This commit is contained in:
parent
d5f2f2a413
commit
f3b6431104
1 changed files with 13 additions and 1 deletions
|
|
@ -230,6 +230,8 @@ static struct sway_node *node_get_in_direction_floating(
|
|||
double ref_ly = con->pending.y + con->pending.height / 2;
|
||||
double closest_distance = DBL_MAX;
|
||||
struct sway_container *closest_con = NULL;
|
||||
double furthest_distance = 1;
|
||||
struct sway_container *furthest_con = NULL;
|
||||
|
||||
if (!con->pending.workspace) {
|
||||
return NULL;
|
||||
|
|
@ -246,7 +248,12 @@ static struct sway_node *node_get_in_direction_floating(
|
|||
if (dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_UP) {
|
||||
distance = -distance;
|
||||
}
|
||||
if (distance < 0) {
|
||||
if (distance <= 0) {
|
||||
// Track the furthest window in the opposite direction for wrapping
|
||||
if (distance < furthest_distance) {
|
||||
furthest_distance = distance;
|
||||
furthest_con = floater;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (distance < closest_distance) {
|
||||
|
|
@ -254,6 +261,11 @@ static struct sway_node *node_get_in_direction_floating(
|
|||
closest_con = floater;
|
||||
}
|
||||
}
|
||||
// If there is no window in the requested direction, wrap around to the
|
||||
// furthest window in the opposite direction.
|
||||
if (!closest_con && config->focus_wrapping != WRAP_NO) {
|
||||
closest_con = furthest_con;
|
||||
}
|
||||
|
||||
return closest_con ? &closest_con->node : NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue