input: stash current node and surface in cursor

If an actively constrained surface is partially occluded by another node
(say, by a floating node), the cursor should remain constrained and pass
"under" the floating node.

Previously, this did not always happen, as `node_at_coords` is a simple
top-down hit test that doesn't (and shouldn't) cover constraints.

Furthermore, whether the cursor should remain constrained is a function
of the input device type: only pointer devices should be constrained.

This commit addresses this issue by stashing the surface and node that
currently have cursor input focus, and using the stashed values
everywhere.

When `wlr_cursor_move` and friends are called, one must now take care to
also call `cursor_update_current_node` with the `wlr_input_device` that
initiated the movement.

Fixes #6073.
This commit is contained in:
Tudor Brindus 2021-03-02 23:55:10 -05:00
parent 1afedcb94c
commit bfc22725b8
5 changed files with 82 additions and 48 deletions

View file

@ -22,6 +22,15 @@ struct sway_cursor {
double x, y;
struct sway_node *node;
} previous;
// Not to be confused with `previous` above; they store entirely unrelated
// data.
struct {
double sx, sy;
struct sway_node *node;
struct wlr_surface *surface;
} current;
struct wlr_xcursor_manager *xcursor_manager;
struct wl_list tablets;
struct wl_list tablet_pads;
@ -79,10 +88,6 @@ struct sway_cursor {
struct sway_node;
struct sway_node *node_at_coords(
struct sway_seat *seat, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy);
void sway_cursor_destroy(struct sway_cursor *cursor);
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);