From 81c4bb135687cdb77c27b1bfd060b800fa0c8d82 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 27 Sep 2022 05:21:56 -0400 Subject: [PATCH] import mutter-3.32.2-65.el8 --- ...sure-_NET_WM_FRAME_DRAWN-timestamp-h.patch | 265 ++++++++++++++++++ ...entTime-to-XIAllowEvents-when-unfree.patch | 26 ++ SPECS/mutter.spec | 16 +- 3 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0001-compositor-Make-sure-_NET_WM_FRAME_DRAWN-timestamp-h.patch create mode 100644 SOURCES/0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch diff --git a/SOURCES/0001-compositor-Make-sure-_NET_WM_FRAME_DRAWN-timestamp-h.patch b/SOURCES/0001-compositor-Make-sure-_NET_WM_FRAME_DRAWN-timestamp-h.patch new file mode 100644 index 0000000..2a2bb03 --- /dev/null +++ b/SOURCES/0001-compositor-Make-sure-_NET_WM_FRAME_DRAWN-timestamp-h.patch @@ -0,0 +1,265 @@ +From b0f3604cdb653ef133f9684adffeb6b93f6906f8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 26 Jan 2022 10:51:07 +0100 +Subject: [PATCH] compositor: Make sure _NET_WM_FRAME_DRAWN timestamp has the + right scope + +The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high +resolution X server timestamps", meaning they should have the same scope +as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at +the same time. + +This was not done correctly when mutter had determined the X server used +the monotonic clock, where it'd just forward the monotonic clock, +confusing any client using _NET_WM_FRAME_DRAWN and friends. + +Fix this by 1) splitting the timestamp conversiot into an X11 case and a +display server case, where the display server case simply clamps the +monotonic clock, as it is assumed Xwayland is always usign the monotonic +clock, and 2) if we're a X11 compositing manager, if the X server is +using the monotonic clock, apply the same semantics as the display +server case and always just clamp, or if not, calculate the offset every +10 seconds, and offset the monotonic clock timestamp with the calculated +X server timestamp offset. + +This fixes an issue that would occur if mutter (or rather GNOME Shell) +would have been started before a X11 timestamp overflow, after the +overflow happened. In this case, GTK3 clients would get unclamped +timestamps, and get very confused, resulting in frames queued several +weeks into the future. +--- + src/compositor/compositor-private.h | 9 +- + src/compositor/compositor.c | 117 +++++++++++++++++++------ + src/compositor/meta-window-actor-x11.c | 12 +-- + 3 files changed, 104 insertions(+), 34 deletions(-) + +diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h +index f7008751215d..4588a8af7f2f 100644 +--- a/src/compositor/compositor-private.h ++++ b/src/compositor/compositor-private.h +@@ -49,6 +49,10 @@ struct _MetaCompositor + + gboolean frame_has_updated_xsurfaces; + gboolean have_x11_sync_object; ++ ++ gboolean xserver_uses_monotonic_clock; ++ int64_t xserver_time_query_time_us; ++ int64_t xserver_time_offset_us; + }; + + /* Wait 2ms after vblank before starting to draw next frame */ +@@ -64,8 +68,9 @@ void meta_end_modal_for_plugin (MetaCompositor *compositor, + MetaPlugin *plugin, + guint32 timestamp); + +-gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, +- gint64 monotonic_time); ++int64_t ++meta_compositor_monotonic_to_high_res_xserver_time (MetaDisplay *display, ++ int64_t monotonic_time_us); + + gboolean meta_compositor_window_is_stereo (MetaDisplay *display, + Window xwindow); +diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c +index ce2c1b8a3bc1..a3fbe5d888f9 100644 +--- a/src/compositor/compositor.c ++++ b/src/compositor/compositor.c +@@ -88,6 +88,40 @@ + #include "wayland/meta-wayland-private.h" + #endif + ++static inline int64_t ++us (int64_t us) ++{ ++ return us; ++} ++ ++static inline int64_t ++ms2us (int64_t ms) ++{ ++ return us (ms * 1000); ++} ++ ++static inline int64_t ++s2us (int64_t s) ++{ ++ return ms2us(s * 1000); ++} ++ ++/* ++ * This function takes a 64 bit time stamp from the monotonic clock, and clamps ++ * it to the scope of the X server clock, without losing the granularity. ++ */ ++static inline int64_t ++meta_translate_to_high_res_xserver_time (int64_t time_us) ++{ ++ int64_t us; ++ int64_t ms; ++ ++ us = time_us % 1000; ++ ms = time_us / 1000; ++ ++ return ms2us (ms & 0xffffffff) + us; ++} ++ + static void + on_presented (ClutterStage *stage, + CoglFrameEvent event, +@@ -612,6 +646,37 @@ meta_compositor_select_stereo_notify (MetaDisplay *display, + } + } + ++static void ++determine_server_clock_source (MetaCompositor *compositor) ++{ ++ MetaDisplay *display = compositor->display; ++ MetaX11Display *x11_display = display->x11_display; ++ uint32_t server_time_ms; ++ int64_t server_time_us; ++ int64_t translated_monotonic_now_us; ++ ++ if (meta_is_wayland_compositor ()) ++ { ++ compositor->xserver_uses_monotonic_clock = TRUE; ++ return; ++ } ++ ++ server_time_ms = meta_x11_display_get_current_time_roundtrip (x11_display); ++ server_time_us = ms2us (server_time_ms); ++ translated_monotonic_now_us = ++ meta_translate_to_high_res_xserver_time (g_get_monotonic_time ()); ++ ++ /* If the server time offset is within a second of the monotonic time, we ++ * assume that they are identical. This seems like a big margin, but we want ++ * to be as robust as possible even if the system is under load and our ++ * processing of the server response is delayed. ++ */ ++ if (ABS (server_time_us - translated_monotonic_now_us) < s2us (1)) ++ compositor->xserver_uses_monotonic_clock = TRUE; ++ else ++ compositor->xserver_uses_monotonic_clock = FALSE; ++} ++ + void + meta_compositor_manage (MetaCompositor *compositor) + { +@@ -622,6 +687,9 @@ meta_compositor_manage (MetaCompositor *compositor) + if (display->x11_display) + { + xdisplay = display->x11_display->xdisplay; ++ ++ determine_server_clock_source (compositor); ++ + meta_x11_display_set_cm_selection (display->x11_display); + + compositor->stereo_tree_ext = display_has_stereo_tree_ext (display->x11_display); +@@ -1593,7 +1661,7 @@ meta_compositor_flash_window (MetaCompositor *compositor, + } + + /** +- * meta_compositor_monotonic_time_to_server_time: ++ * meta_compositor_monotonic_to_high_res_xserver_time: + * @display: a #MetaDisplay + * @monotonic_time: time in the units of g_get_monotonic_time() + * +@@ -1606,38 +1674,35 @@ meta_compositor_flash_window (MetaCompositor *compositor, + * a time representation with high accuracy. If there is not a common + * time source, then the time synchronization will be less accurate. + */ +-gint64 +-meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, +- gint64 monotonic_time) ++int64_t ++meta_compositor_monotonic_to_high_res_xserver_time (MetaDisplay *display, ++ int64_t monotonic_time_us) + { + MetaCompositor *compositor = display->compositor; ++ int64_t now_us; ++ ++ if (compositor->xserver_uses_monotonic_clock) ++ return meta_translate_to_high_res_xserver_time (monotonic_time_us); + +- if (compositor->server_time_query_time == 0 || +- (!compositor->server_time_is_monotonic_time && +- monotonic_time > compositor->server_time_query_time + 10*1000*1000)) /* 10 seconds */ ++ now_us = g_get_monotonic_time (); ++ ++ if (compositor->xserver_time_query_time_us == 0 || ++ now_us > (compositor->xserver_time_query_time_us + s2us (10))) + { +- guint32 server_time = meta_display_get_current_time_roundtrip (display); +- gint64 server_time_usec = (gint64)server_time * 1000; +- gint64 current_monotonic_time = g_get_monotonic_time (); +- compositor->server_time_query_time = current_monotonic_time; +- +- /* If the server time is within a second of the monotonic time, +- * we assume that they are identical. This seems like a big margin, +- * but we want to be as robust as possible even if the system +- * is under load and our processing of the server response is +- * delayed. +- */ +- if (server_time_usec > current_monotonic_time - 1000*1000 && +- server_time_usec < current_monotonic_time + 1000*1000) +- compositor->server_time_is_monotonic_time = TRUE; ++ MetaDisplay *display = compositor->display; ++ MetaX11Display *x11_display = display->x11_display; ++ uint32_t xserver_time_ms; ++ int64_t xserver_time_us; + +- compositor->server_time_offset = server_time_usec - current_monotonic_time; ++ compositor->xserver_time_query_time_us = now_us; ++ ++ xserver_time_ms = ++ meta_x11_display_get_current_time_roundtrip (x11_display); ++ xserver_time_us = ms2us (xserver_time_ms); ++ compositor->xserver_time_offset_us = xserver_time_us - now_us; + } + +- if (compositor->server_time_is_monotonic_time) +- return monotonic_time; +- else +- return monotonic_time + compositor->server_time_offset; ++ return monotonic_time_us + compositor->xserver_time_offset_us; + } + + void +diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c +index a364323fe057..2b9c25510dc9 100644 +--- a/src/compositor/meta-window-actor-x11.c ++++ b/src/compositor/meta-window-actor-x11.c +@@ -105,8 +105,8 @@ do_send_frame_drawn (MetaWindowActorX11 *actor_x11, + XClientMessageEvent ev = { 0, }; + + frame->frame_drawn_time = +- meta_compositor_monotonic_time_to_server_time (display, +- g_get_monotonic_time ()); ++ meta_compositor_monotonic_to_high_res_xserver_time (display, ++ g_get_monotonic_time ()); + actor_x11->frame_drawn_time = frame->frame_drawn_time; + + ev.type = ClientMessage; +@@ -147,8 +147,8 @@ do_send_frame_timings (MetaWindowActorX11 *actor_x11, + if (presentation_time != 0) + { + int64_t presentation_time_server = +- meta_compositor_monotonic_time_to_server_time (display, +- presentation_time); ++ meta_compositor_monotonic_to_high_res_xserver_time (display, ++ presentation_time); + int64_t presentation_time_offset = presentation_time_server - frame->frame_drawn_time; + if (presentation_time_offset == 0) + presentation_time_offset = 1; +@@ -246,8 +246,8 @@ queue_send_frame_messages_timeout (MetaWindowActorX11 *actor_x11) + } + + current_time = +- meta_compositor_monotonic_time_to_server_time (display, +- g_get_monotonic_time ()); ++ meta_compositor_monotonic_to_high_res_xserver_time (display, ++ g_get_monotonic_time ()); + interval = (int) (1000000 / refresh_rate) * 6; + offset = MAX (0, actor_x11->frame_drawn_time + interval - current_time) / 1000; + +-- +2.33.1 + diff --git a/SOURCES/0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch b/SOURCES/0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch new file mode 100644 index 0000000..24a5bcd --- /dev/null +++ b/SOURCES/0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch @@ -0,0 +1,26 @@ +From 65ffd7e4df42cd62633f93107644f87208881578 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Thu, 14 Apr 2022 18:07:41 +0200 +Subject: [PATCH] events: Pass CurrentTime to XIAllowEvents() when unfreezing + pointer + +--- + src/core/events.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/events.c b/src/core/events.c +index 0dc3a73222..dd9b4ec981 100644 +--- a/src/core/events.c ++++ b/src/core/events.c +@@ -205,7 +205,7 @@ maybe_unfreeze_pointer_events (MetaBackend *backend, + } + + xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); +- XIAllowEvents (xdisplay, device_id, event_mode, event->button.time); ++ XIAllowEvents (xdisplay, device_id, event_mode, CurrentTime); + } + + static gboolean +-- +2.34.1 + diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec index 866a3c0..9a12088 100644 --- a/SPECS/mutter.spec +++ b/SPECS/mutter.spec @@ -8,7 +8,7 @@ Name: mutter Version: 3.32.2 -Release: 63%{?dist} +Release: 65%{?dist} Summary: Window and compositing manager based on Clutter License: GPLv2+ @@ -198,6 +198,12 @@ Patch525: monitor-config-policy.patch # Backport EGLStream overview fixes (#1977721) Patch526: eglstream-overview-fixes.patch +# Backport fix for stuck _NET_WM_FRAME_DRAWN handling (#2060305) +Patch527: 0001-compositor-Make-sure-_NET_WM_FRAME_DRAWN-timestamp-h.patch + +# Fix race condition causing stuck pointer grabs (#2090168) +Patch528: 0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch + BuildRequires: chrpath BuildRequires: pango-devel BuildRequires: startup-notification-devel @@ -339,6 +345,14 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop %{_datadir}/mutter-%{mutter_api_version}/tests %changelog +* Mon Jun 27 2022 Jonas Ådahl ) - 3.32.2-65 +- Fix race condition causing stuck pointer grabs + Resolves: #2090168 + +* Fri Mar 18 2022 Jonas Ådahl - 3.32.2-64 +- Backport fix for stuck _NET_WM_FRAME_DRAWN handling + Resolves: #2060305 + * Thu Feb 24 2022 Jonas Ådahl - 3.32.2-63 - Fix EGLStream overview fixes backport Related: #1977721