summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2023-03-29 16:03:49 +0200
committerMarge Bot <marge-bot@gnome.org>2023-03-29 16:36:28 +0000
commit7eb01304259b5977feaee3b2d0a2073b70312d89 (patch)
tree4c3cd55db4a285dead805b30f7f8fa3f144b1ddc
parent179124dc61bb628ff2eeb2f3127f18c365dafa21 (diff)
downloadmutter-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.c24
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);