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>
This commit is contained in:
parent
179124dc61
commit
7eb0130425
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user