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

@ -1262,6 +1262,14 @@ run_action(struct view *view, struct server *server, struct action *action,
break;
case ACTION_TYPE_MOVE:
if (view) {
/*
* If triggered by mousebind, grab context was already
* set by button press handling. For keybind-triggered
* Move, set it now from current cursor position.
*/
if (view != server->seat.pressed.ctx.view) {
interactive_set_grab_context(ctx);
}
interactive_begin(view, LAB_INPUT_STATE_MOVE,
LAB_EDGE_NONE);
}
@ -1285,9 +1293,13 @@ run_action(struct view *view, struct server *server, struct action *action,
*/
enum lab_edge resize_edges =
action_get_int(action, "direction", LAB_EDGE_NONE);
if (resize_edges == LAB_EDGE_NONE) {
resize_edges = cursor_get_resize_edges(
server->seat.cursor, ctx);
/*
* If triggered by mousebind, grab context was already
* set by button press handling. For keybind-triggered
* Resize, set it now from current cursor position.
*/
if (view != server->seat.pressed.ctx.view) {
interactive_set_grab_context(ctx);
}
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
resize_edges);