interactive: set grab parameters at cursor press

Add interactive_set_grab_context() which is called when the mouse button
is first pressed, before interactive_begin(). This fixes two small issues:

- The cursor origin position for interactive move/resize was slightly
  off (depending on mouse resolution), because it was set after the
  mouse had already moved slightly. Now it's exact.

- If app- or keybind-initiated maximize (etc.) happened after the button
  press but before the mouse was moved, then interactive_begin() would
  still start move/resize even though the view might now be far away
  from the cursor. Now interactive_cancel() works as expected, even if
  called before interactive_begin().

Also, make sure to call interactive_cancel() for un-maximize as well.
This commit is contained in:
John Lindgren 2026-02-09 23:49:42 -05:00 committed by Johan Malm
parent 3ea46ba45a
commit a672e8a9fd
7 changed files with 90 additions and 36 deletions

View file

@ -454,11 +454,11 @@ handle_request_move(struct wl_listener *listener, void *data)
* the provided serial against a list of button press serials sent to
* this client, to prevent the client from requesting this whenever they
* want.
*
* Note: interactive_begin() checks that view == server->grabbed_view.
*/
struct view *view = wl_container_of(listener, view, request_move);
if (view == view->server->seat.pressed.ctx.view) {
interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE);
}
interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE);
}
static void
@ -471,12 +471,12 @@ handle_request_resize(struct wl_listener *listener, void *data)
* the provided serial against a list of button press serials sent to
* this client, to prevent the client from requesting this whenever they
* want.
*
* Note: interactive_begin() checks that view == server->grabbed_view.
*/
struct wlr_xdg_toplevel_resize_event *event = data;
struct view *view = wl_container_of(listener, view, request_resize);
if (view == view->server->seat.pressed.ctx.view) {
interactive_begin(view, LAB_INPUT_STATE_RESIZE, event->edges);
}
interactive_begin(view, LAB_INPUT_STATE_RESIZE, event->edges);
}
static void