From deaa9480a84938cc0120e433fa9f3607acdfa29c Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Thu, 15 Oct 2020 14:23:41 +0200 Subject: [PATCH] window-props: Check for actual size hints changes The XSizeHints set by X11 clients give a hint to the window manager about size increment, aspect ratio, base, minimum and maximum size, etc. When an X11 client changes those values, there is a good chance that it will affect the actual window size in some way, and mutter rightfully queue a window resize in that case. However, mutter does not check if any of the hints have actually changed and unconditionally queue a window resize whenever a client changes its WM_NORMAL_HINTS property. That can be a problem when a zealous client such as xterm decides to update its WM_NORMAL_HINTS property on resize, because in return mutter will queue a non-user driven resize in the middle of user-driven events, hence defeating the purpose of the META_MOVE_RESIZE_USER_ACTION flag. To avoid that issue, make mutter a bit smarter and avoid queuing a window resize if the XSizeHints haven't actually changed. https://gitlab.gnome.org/GNOME/mutter/-/issues/543 --- src/x11/window-props.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/x11/window-props.c b/src/x11/window-props.c index d0ef19f79..ab3cae89a 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -1140,6 +1140,22 @@ spew_size_hints_differences (const XSizeHints *old, old->win_gravity, new->win_gravity); } +static gboolean +hints_have_changed (const XSizeHints *old, + const XSizeHints *new) +{ + return FLAG_CHANGED (old, new, USPosition) || + FLAG_CHANGED (old, new, USSize) || + FLAG_CHANGED (old, new, PPosition) || + FLAG_CHANGED (old, new, PSize) || + FLAG_CHANGED (old, new, PMinSize) || + FLAG_CHANGED (old, new, PMaxSize) || + FLAG_CHANGED (old, new, PResizeInc) || + FLAG_CHANGED (old, new, PAspect) || + FLAG_CHANGED (old, new, PBaseSize) || + FLAG_CHANGED (old, new, PWinGravity); +} + void meta_set_normal_hints (MetaWindow *window, XSizeHints *hints) @@ -1490,6 +1506,7 @@ reload_normal_hints (MetaWindow *window, if (value->type != META_PROP_VALUE_INVALID) { XSizeHints old_hints; + gboolean hints_have_differences; meta_topic (META_DEBUG_GEOMETRY, "Updating WM_NORMAL_HINTS for %s", window->desc); @@ -1497,12 +1514,16 @@ reload_normal_hints (MetaWindow *window, meta_set_normal_hints (window, value->v.size_hints.hints); - spew_size_hints_differences (&old_hints, &window->size_hints); + hints_have_differences = hints_have_changed (&old_hints, + &window->size_hints); + if (hints_have_differences) + { + spew_size_hints_differences (&old_hints, &window->size_hints); + meta_window_recalc_features (window); - meta_window_recalc_features (window); - - if (!initial) - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); + if (!initial) + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + } } }