diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 8ae75f229..ba624a600 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -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; }