snap: cache and ignore last-snapped edge when growing or shrinking

When growing or shrinking a view by snapping to an edge, a client may
ignore the requested size and instead keep its original size or
substitute a different (possibly constrained) size. In this case, the
view may not actually contact the snapped edge, and a subsequent snap
attempt will just keep re-trying (and failing) to contact the same ege.

To mitigate this, remember the last-snapped view, snapping direction and
offset of the snapping edge in snap.c; when re-attempting a snap for the
same view in the same direction, ignore the edge that was last "hit", to
allow snapping to progress beyond the problematic edge.
This commit is contained in:
Andrew J. Hesford 2024-04-02 15:58:50 -04:00 committed by Johan Malm
parent 9de487cecf
commit 2bf285a2c6
11 changed files with 271 additions and 44 deletions

View file

@ -108,15 +108,14 @@ resistance_move_apply(struct view *view, double *x, double *y)
if (rc.screen_edge_strength != 0) {
/* Find any relevant output edges encountered by this move */
edges_find_outputs(&next_edges, view, target, NULL,
check_edge_output, /* use_pending */ false);
edges_find_outputs(&next_edges, view,
view->current, target, NULL, check_edge_output);
}
if (rc.window_edge_strength != 0) {
/* Find any relevant window edges encountered by this move */
edges_find_neighbors(&next_edges,
view, target, NULL, check_edge_window,
/* use_pending */ false, /* ignore_hidden */ true);
edges_find_neighbors(&next_edges, view, view->current, target,
NULL, check_edge_window, /* ignore_hidden */ true);
}
/* If any "best" edges were encountered during this move, snap motion */
@ -138,15 +137,14 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_geom)
if (rc.screen_edge_strength != 0) {
/* Find any relevant output edges encountered by this move */
edges_find_outputs(&next_edges, view, *new_geom, NULL,
check_edge_output, /* use_pending */ false);
edges_find_outputs(&next_edges, view,
view->current, *new_geom, NULL, check_edge_output);
}
if (rc.window_edge_strength != 0) {
/* Find any relevant window edges encountered by this move */
edges_find_neighbors(&next_edges,
view, *new_geom, NULL, check_edge_window,
/* use_pending */ false, /* ignore_hidden */ true);
edges_find_neighbors(&next_edges, view, view->current, *new_geom,
NULL, check_edge_window, /* ignore_hidden */ true);
}
/* If any "best" edges were encountered during this move, snap motion */