diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2023-03-29 16:03:49 +0200 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2023-03-29 16:36:28 +0000 |
commit | 7eb01304259b5977feaee3b2d0a2073b70312d89 (patch) | |
tree | 4c3cd55db4a285dead805b30f7f8fa3f144b1ddc | |
parent | 179124dc61bb628ff2eeb2f3127f18c365dafa21 (diff) | |
download | mutter-7eb01304259b5977feaee3b2d0a2073b70312d89.tar.gz |
compositor: Use relative anchor coordinates for window drags
The anchor position calculations are somewhat unnecessarily complex
based on root coordinates of pointer and frame positions. This requires
tracking both things, and we don't always get it quite right with the
latter (e.g. window repositions, resizes or overshrinks, leaving the
anchor position visually outside the window).
In order to improve this, capture the window-relative coordinates
when starting the window drag, and ensure the window is always repositioned
in that position, relative to its current size.
This avoids these glitches when unmaximizing a window (e.g. dragged from
the bottom through super+button1 press), or moving windows between monitors
with different scales.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2730
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2942>
-rw-r--r-- | src/compositor/meta-window-drag.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/compositor/meta-window-drag.c b/src/compositor/meta-window-drag.c index 86b29c71f..dca159845 100644 --- a/src/compositor/meta-window-drag.c +++ b/src/compositor/meta-window-drag.c @@ -57,6 +57,8 @@ struct _MetaWindowDrag { ClutterInputDevice *leading_device; ClutterEventSequence *leading_touch_sequence; + double anchor_rel_x; + double anchor_rel_y; int anchor_root_x; int anchor_root_y; MetaRectangle anchor_window_pos; @@ -1188,7 +1190,7 @@ update_move (MetaWindowDrag *window_drag, MetaWindow *window; int dx, dy; int new_x, new_y; - MetaRectangle old; + MetaRectangle old, frame_rect; int shake_threshold; window = window_drag->effective_grab_window; @@ -1203,15 +1205,16 @@ update_move (MetaWindowDrag *window_drag, dx = x - window_drag->anchor_root_x; dy = y - window_drag->anchor_root_y; - new_x = window_drag->anchor_window_pos.x + dx; - new_y = window_drag->anchor_window_pos.y + dy; + meta_window_get_frame_rect (window, &frame_rect); + new_x = x - (frame_rect.width * window_drag->anchor_rel_x); + new_y = y - (frame_rect.height * window_drag->anchor_rel_y); - meta_verbose ("x,y = %d,%d anchor ptr %d,%d anchor pos %d,%d dx,dy %d,%d", + meta_verbose ("x,y = %d,%d anchor ptr %d,%d rel anchor pos %f,%f dx,dy %d,%d", x, y, window_drag->anchor_root_x, window_drag->anchor_root_y, - window_drag->anchor_window_pos.x, - window_drag->anchor_window_pos.y, + window_drag->anchor_rel_x, + window_drag->anchor_rel_y, dx, dy); /* Don't bother doing anything if no move has been specified. (This @@ -1879,6 +1882,15 @@ meta_window_drag_begin (MetaWindowDrag *window_drag, &window_drag->initial_window_pos); window_drag->anchor_window_pos = window_drag->initial_window_pos; + window_drag->anchor_rel_x = + CLAMP ((double) (root_x - window_drag->initial_window_pos.x) / + window_drag->initial_window_pos.width, + 0, 1); + window_drag->anchor_rel_y = + CLAMP ((double) (root_y - window_drag->initial_window_pos.y) / + window_drag->initial_window_pos.height, + 0, 1); + if (meta_is_wayland_compositor ()) { meta_display_sync_wayland_input_focus (display); |