From bcb64bfb821db2cb700676cf16ba0f78b6754370 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 21 Jan 2020 12:51:34 -0500 Subject: [PATCH] import mutter-3.32.2-26.el8 --- ...1-Add-support-for-quad-buffer-stereo.patch | 38 +- .../0001-EGL-Include-EGL-eglmesaext.h.patch | 68 ++++ ...enable-tap-to-click-drag-on-opaque-W.patch | 80 ++++ ...oth-input-settings-and-mapper-for-ta.patch | 96 +++++ ...r-pen-eraser-devices-when-looking-fo.patch | 30 ++ ...erve-multiple-pad-mode-switch-button.patch | 118 ++++++ ...e-unused-OFFSCREEN_BLIT-feature-flag.patch | 37 ++ ...e-switch-events-always-go-through-Me.patch | 64 +++ ...ding-pointer-events-without-a-window.patch | 122 ++++++ ...xrender-picture-formats-when-creatin.patch | 136 +++++++ ...xrandr-Move-dpms-state-and-screen-si.patch | 114 ++++++ ...ylus-serials-on-meta_wayland_seat_ca.patch | 109 +++++ ...us-only-ancestors-that-are-focusable.patch | 83 ++++ ...button-flags-to-determine-whether-bu.patch | 53 +++ ...l-Fix-doc-for-_cogl_blit_framebuffer.patch | 42 ++ ...xrandr-Create-dummy-screen-sized-mon.patch | 185 +++++++++ ...rror-and-return-when-trying-to-activ.patch | 42 ++ ...als-for-reporting-suspend-and-resume.patch | 55 ++- ...LE-with-GLES3-and-NV-framebuffer_bli.patch | 77 ++++ ...l-Relax-formats-on-glBlitFramebuffer.patch | 100 +++++ ...tFramebuffer-between-onscreen-offscr.patch | 145 +++++++ ...ure-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch | 115 ++++++ ...07-cogl-Expose-cogl_blit_framebuffer.patch | 261 ++++++++++++ ...ew-Use-cogl_blit_framebuffer-for-sha.patch | 42 ++ ...ew-Ignore-clipping-rectangle-for-off.patch | 49 +++ ...0-cogl-Flush-journal-before-blitting.patch | 34 ++ ...view-Separate-offscreen-and-shadowfb.patch | 304 ++++++++++++++ ...tive-Separate-offscreen-and-shadowfb.patch | 98 +++++ ...for-plain-old-x-device-configuration.patch | 2 +- SOURCES/idle-monitor-reset-fix.patch | 128 ++++++ SOURCES/inherit-xrandr-metamodes.patch | 365 +++++++++++++++++ SOURCES/input-after-long-idle-fix.patch | 374 ++++++++++++++++++ SPECS/mutter.spec | 145 ++++++- 33 files changed, 3679 insertions(+), 32 deletions(-) create mode 100644 SOURCES/0001-EGL-Include-EGL-eglmesaext.h.patch create mode 100644 SOURCES/0001-backends-Always-enable-tap-to-click-drag-on-opaque-W.patch create mode 100644 SOURCES/0001-backends-Check-both-input-settings-and-mapper-for-ta.patch create mode 100644 SOURCES/0001-backends-Consider-pen-eraser-devices-when-looking-fo.patch create mode 100644 SOURCES/0001-backends-x11-Observe-multiple-pad-mode-switch-button.patch create mode 100644 SOURCES/0001-cogl-Remove-unused-OFFSCREEN_BLIT-feature-flag.patch create mode 100644 SOURCES/0001-core-Let-pad-mode-switch-events-always-go-through-Me.patch create mode 100644 SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch create mode 100644 SOURCES/0001-iconcache-Avoid-xrender-picture-formats-when-creatin.patch create mode 100644 SOURCES/0001-monitor-manager-xrandr-Move-dpms-state-and-screen-si.patch create mode 100644 SOURCES/0001-wayland-Check-stylus-serials-on-meta_wayland_seat_ca.patch create mode 100644 SOURCES/0001-workspace-Focus-only-ancestors-that-are-focusable.patch create mode 100644 SOURCES/0001-x11-Check-wacom-button-flags-to-determine-whether-bu.patch create mode 100644 SOURCES/0002-cogl-Fix-doc-for-_cogl_blit_framebuffer.patch create mode 100644 SOURCES/0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch create mode 100644 SOURCES/0002-window-Emit-an-error-and-return-when-trying-to-activ.patch create mode 100644 SOURCES/0003-cogl-Replace-ANGLE-with-GLES3-and-NV-framebuffer_bli.patch create mode 100644 SOURCES/0004-cogl-Relax-formats-on-glBlitFramebuffer.patch create mode 100644 SOURCES/0005-cogl-Allow-glBlitFramebuffer-between-onscreen-offscr.patch create mode 100644 SOURCES/0006-cogl-Rename-feature-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch create mode 100644 SOURCES/0007-cogl-Expose-cogl_blit_framebuffer.patch create mode 100644 SOURCES/0008-clutter-stage-view-Use-cogl_blit_framebuffer-for-sha.patch create mode 100644 SOURCES/0009-clutter-stage-view-Ignore-clipping-rectangle-for-off.patch create mode 100644 SOURCES/0010-cogl-Flush-journal-before-blitting.patch create mode 100644 SOURCES/0011-clutter-stage-view-Separate-offscreen-and-shadowfb.patch create mode 100644 SOURCES/0012-renderer-native-Separate-offscreen-and-shadowfb.patch create mode 100644 SOURCES/idle-monitor-reset-fix.patch create mode 100644 SOURCES/inherit-xrandr-metamodes.patch create mode 100644 SOURCES/input-after-long-idle-fix.patch diff --git a/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch b/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch index 8e12a79..397dc41 100644 --- a/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch +++ b/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch @@ -1,4 +1,4 @@ -From 2b45c3e37da7a590227e965d8a18e89337b791ba Mon Sep 17 00:00:00 2001 +From d0ad5ea18bb02112837bcdf7270d58d8ad235a4d Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 8 May 2014 18:44:15 -0400 Subject: [PATCH] Add support for quad-buffer stereo @@ -21,7 +21,7 @@ texture_from_pixmap. src/compositor/compositor-private.h | 9 ++ src/compositor/compositor.c | 125 +++++++++++++++ src/compositor/meta-shaped-texture-private.h | 5 +- - src/compositor/meta-shaped-texture.c | 86 ++++++++++- + src/compositor/meta-shaped-texture.c | 84 +++++++++- src/compositor/meta-surface-actor-wayland.c | 2 +- src/compositor/meta-surface-actor-x11.c | 54 ++++++- src/compositor/meta-surface-actor-x11.h | 5 + @@ -32,7 +32,7 @@ texture_from_pixmap. src/core/stereo.h | 28 ++++ src/meson.build | 2 + src/wayland/meta-wayland-surface.c | 2 +- - 14 files changed, 483 insertions(+), 20 deletions(-) + 14 files changed, 481 insertions(+), 20 deletions(-) create mode 100644 src/core/stereo.c create mode 100644 src/core/stereo.h @@ -265,7 +265,7 @@ index a86a2bff0..d0efdd4dc 100644 gboolean is_y_inverted); void meta_shaped_texture_set_snippet (MetaShapedTexture *stex, diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c -index ea8daa03d..9665ce2b6 100644 +index ea8daa03d..9a00ccd6d 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -102,8 +102,10 @@ struct _MetaShapedTexture @@ -279,17 +279,15 @@ index ea8daa03d..9665ce2b6 100644 CoglTexture *mask_texture; CoglSnippet *snippet; -@@ -193,6 +195,9 @@ meta_shaped_texture_init (MetaShapedTexture *stex) +@@ -192,6 +194,7 @@ meta_shaped_texture_init (MetaShapedTexture *stex) + clutter_backend_get_cogl_context (clutter_backend); stex->paint_tower = meta_texture_tower_new (); - -+ stex->paint_tower = meta_texture_tower_new (); + stex->paint_tower_right = NULL; /* demand create */ -+ + stex->texture = NULL; stex->mask_texture = NULL; - stex->create_mipmaps = TRUE; -@@ -335,6 +340,9 @@ meta_shaped_texture_dispose (GObject *object) +@@ -335,6 +338,9 @@ meta_shaped_texture_dispose (GObject *object) meta_texture_tower_free (stex->paint_tower); stex->paint_tower = NULL; @@ -299,7 +297,7 @@ index ea8daa03d..9665ce2b6 100644 g_clear_pointer (&stex->texture, cogl_object_unref); g_clear_pointer (&stex->opaque_region, cairo_region_destroy); -@@ -611,8 +619,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex, +@@ -611,8 +617,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex, } static void @@ -311,7 +309,7 @@ index ea8daa03d..9665ce2b6 100644 { int width, height; -@@ -620,10 +629,13 @@ set_cogl_texture (MetaShapedTexture *stex, +@@ -620,10 +627,13 @@ set_cogl_texture (MetaShapedTexture *stex, if (stex->texture) cogl_object_unref (stex->texture); @@ -325,7 +323,7 @@ index ea8daa03d..9665ce2b6 100644 if (cogl_tex != NULL) { -@@ -637,6 +649,9 @@ set_cogl_texture (MetaShapedTexture *stex, +@@ -637,6 +647,9 @@ set_cogl_texture (MetaShapedTexture *stex, height = 0; } @@ -335,7 +333,7 @@ index ea8daa03d..9665ce2b6 100644 if (stex->tex_width != width || stex->tex_height != height) { -@@ -650,8 +665,23 @@ set_cogl_texture (MetaShapedTexture *stex, +@@ -650,8 +663,23 @@ set_cogl_texture (MetaShapedTexture *stex, * previous buffer. We only queue a redraw in response to surface * damage. */ @@ -360,7 +358,7 @@ index ea8daa03d..9665ce2b6 100644 } static gboolean -@@ -927,7 +957,9 @@ meta_shaped_texture_paint (ClutterActor *actor) +@@ -927,7 +955,9 @@ meta_shaped_texture_paint (ClutterActor *actor) { MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor); CoglTexture *paint_tex; @@ -370,7 +368,7 @@ index ea8daa03d..9665ce2b6 100644 if (!stex->texture) return; -@@ -989,7 +1021,32 @@ meta_shaped_texture_paint (ClutterActor *actor) +@@ -989,7 +1019,32 @@ meta_shaped_texture_paint (ClutterActor *actor) return; fb = cogl_get_draw_framebuffer (); @@ -404,7 +402,7 @@ index ea8daa03d..9665ce2b6 100644 } static void -@@ -1063,6 +1120,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, +@@ -1063,6 +1118,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, stex->create_mipmaps = create_mipmaps; base_texture = create_mipmaps ? stex->texture : NULL; meta_texture_tower_set_base_texture (stex->paint_tower, base_texture); @@ -417,7 +415,7 @@ index ea8daa03d..9665ce2b6 100644 } } -@@ -1256,6 +1319,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, +@@ -1256,6 +1317,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, clip.y, clip.width, clip.height); @@ -430,7 +428,7 @@ index ea8daa03d..9665ce2b6 100644 stex->prev_invalidation = stex->last_invalidation; stex->last_invalidation = g_get_monotonic_time (); -@@ -1302,17 +1371,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, +@@ -1302,17 +1369,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, } /** @@ -905,5 +903,5 @@ index da0acfcbb..ddad1a45c 100644 meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted); g_clear_pointer (&snippet, cogl_object_unref); -- -2.21.0 +2.23.0 diff --git a/SOURCES/0001-EGL-Include-EGL-eglmesaext.h.patch b/SOURCES/0001-EGL-Include-EGL-eglmesaext.h.patch new file mode 100644 index 0000000..ae7ff46 --- /dev/null +++ b/SOURCES/0001-EGL-Include-EGL-eglmesaext.h.patch @@ -0,0 +1,68 @@ +From abfc64268d4135663fb46c5f3529cd5f082a5c20 Mon Sep 17 00:00:00 2001 +From: "Jan Alexander Steffens (heftig)" +Date: Sun, 20 Oct 2019 12:04:31 +0200 +Subject: [PATCH] EGL: Include EGL/eglmesaext.h + +The eglext.h shipped by libglvnd does not include the Mesa extensions, +unlike the header shipped in Mesa. + +Fixes https://gitlab.gnome.org/GNOME/mutter/issues/876 +--- + cogl/cogl/meson.build | 2 +- + src/backends/meta-egl-ext.h | 1 + + src/backends/meta-egl.c | 1 + + src/backends/meta-egl.h | 1 + + 4 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build +index cb940420a..8032669e4 100644 +--- a/cogl/cogl/meson.build ++++ b/cogl/cogl/meson.build +@@ -48,7 +48,7 @@ cogl_gl_header_h = configure_file( + built_headers += [cogl_gl_header_h] + + if have_egl +- cogl_egl_includes_string = '#include \n#include ' ++ cogl_egl_includes_string = '#include \n#include \n#include ' + else + cogl_egl_includes_string = '' + endif +diff --git a/src/backends/meta-egl-ext.h b/src/backends/meta-egl-ext.h +index 8705e7d5b..db0b74f76 100644 +--- a/src/backends/meta-egl-ext.h ++++ b/src/backends/meta-egl-ext.h +@@ -29,6 +29,7 @@ + + #include + #include ++#include + + /* + * This is a little different to the tests shipped with EGL implementations, +diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c +index 8b953449a..a28eef4ca 100644 +--- a/src/backends/meta-egl.c ++++ b/src/backends/meta-egl.c +@@ -26,6 +26,7 @@ + + #include + #include ++#include + #include + #include + #include +diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h +index ff37f124f..81b53b32d 100644 +--- a/src/backends/meta-egl.h ++++ b/src/backends/meta-egl.h +@@ -27,6 +27,7 @@ + + #include + #include ++#include + #include + + #define META_EGL_ERROR meta_egl_error_quark () +-- +2.23.0 + diff --git a/SOURCES/0001-backends-Always-enable-tap-to-click-drag-on-opaque-W.patch b/SOURCES/0001-backends-Always-enable-tap-to-click-drag-on-opaque-W.patch new file mode 100644 index 0000000..0420251 --- /dev/null +++ b/SOURCES/0001-backends-Always-enable-tap-to-click-drag-on-opaque-W.patch @@ -0,0 +1,80 @@ +From eeff82f534f81b086d10d53124362d9e316e2cf9 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 12 Dec 2019 18:05:08 +0100 +Subject: [PATCH] backends: Always enable tap-to-click/drag on opaque Wacom + tablets + +Touch-wise, those are essentially giant touchpads, but have no buttons +associated to the "touchpad" device (There may be pad buttons, but +those are not mouse buttons). + +Without tap-to-click/drag, touch in those devices is somewhat useless +out of the box. Have them always enable these features, despite the +setting. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/968 +--- + src/backends/meta-input-settings.c | 33 ++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c +index 2e6672d9c..28dc387ef 100644 +--- a/src/backends/meta-input-settings.c ++++ b/src/backends/meta-input-settings.c +@@ -517,6 +517,33 @@ update_touchpad_disable_while_typing (MetaInputSettings *input_settings, + } + } + ++static gboolean ++device_is_tablet_touchpad (MetaInputSettings *input_settings, ++ ClutterInputDevice *device) ++{ ++#ifdef HAVE_LIBWACOM ++ WacomIntegrationFlags flags = 0; ++ WacomDevice *wacom_device; ++ ++ if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) ++ return FALSE; ++ ++ wacom_device = ++ meta_input_settings_get_tablet_wacom_device (input_settings, ++ device); ++ if (wacom_device) ++ { ++ flags = libwacom_get_integration_flags (wacom_device); ++ ++ if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM | ++ WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0) ++ return TRUE; ++ } ++#endif ++ ++ return FALSE; ++} ++ + static void + update_touchpad_tap_enabled (MetaInputSettings *input_settings, + ClutterInputDevice *device) +@@ -531,7 +558,8 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings, + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); +- enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click"); ++ enabled = device_is_tablet_touchpad (input_settings, device) || ++ g_settings_get_boolean (priv->touchpad_settings, "tap-to-click"); + + if (device) + { +@@ -561,7 +589,8 @@ update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings, + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); +- enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag"); ++ enabled = device_is_tablet_touchpad (input_settings, device) || ++ g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag"); + + if (device) + { +-- +2.23.0 + diff --git a/SOURCES/0001-backends-Check-both-input-settings-and-mapper-for-ta.patch b/SOURCES/0001-backends-Check-both-input-settings-and-mapper-for-ta.patch new file mode 100644 index 0000000..1aa7725 --- /dev/null +++ b/SOURCES/0001-backends-Check-both-input-settings-and-mapper-for-ta.patch @@ -0,0 +1,96 @@ +From f14730e7307679cb979aa521b20f246dfc5082da Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Fri, 13 Dec 2019 15:26:05 +0100 +Subject: [PATCH] backends: Check both input settings and mapper for tablet + monitors + +The upper layers (OSDs basically) want to know the monitor that a +tablet is currently assigned to, not the monitor just as configured +through settings. + +This broke proper OSD positioning for display-attached tablets since +commit 87858a4e01d9, as the MetaInputMapper kicks in precisely when +there is no configured monitor for the given device. + +Consulting both about the assigned output will make OSDs pop up +again in the right place. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/971 +--- + src/backends/meta-input-mapper-private.h | 3 +++ + src/backends/meta-input-mapper.c | 26 ++++++++++++++++++++++++ + src/backends/meta-input-settings.c | 11 ++++++++-- + 3 files changed, 38 insertions(+), 2 deletions(-) + +diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h +index 34314577f..cdfdccde9 100644 +--- a/src/backends/meta-input-mapper-private.h ++++ b/src/backends/meta-input-mapper-private.h +@@ -42,5 +42,8 @@ ClutterInputDevice * + meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper, + MetaLogicalMonitor *logical_monitor, + ClutterInputDeviceType device_type); ++MetaLogicalMonitor * ++meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, ++ ClutterInputDevice *device); + + #endif /* META_INPUT_MAPPER_H */ +diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c +index acc9b1618..571b3983c 100644 +--- a/src/backends/meta-input-mapper.c ++++ b/src/backends/meta-input-mapper.c +@@ -684,3 +684,29 @@ meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper, + + return NULL; + } ++ ++MetaLogicalMonitor * ++meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, ++ ClutterInputDevice *device) ++{ ++ MetaMapperOutputInfo *output; ++ MetaLogicalMonitor *logical_monitor; ++ GHashTableIter iter; ++ GList *l; ++ ++ g_hash_table_iter_init (&iter, mapper->output_devices); ++ ++ while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor, ++ (gpointer *) &output)) ++ { ++ for (l = output->input_devices; l; l = l->next) ++ { ++ MetaMapperInputInfo *input = l->data; ++ ++ if (input->device == device) ++ return logical_monitor; ++ } ++ } ++ ++ return NULL; ++} +diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c +index b7aec8d6d..a923aa971 100644 +--- a/src/backends/meta-input-settings.c ++++ b/src/backends/meta-input-settings.c +@@ -1922,8 +1922,15 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, + if (!info) + return NULL; + +- meta_input_settings_find_monitor (settings, info->settings, device, +- NULL, &logical_monitor); ++ logical_monitor = ++ meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device); ++ ++ if (!logical_monitor) ++ { ++ meta_input_settings_find_monitor (settings, info->settings, device, ++ NULL, &logical_monitor); ++ } ++ + return logical_monitor; + } + +-- +2.23.0 + diff --git a/SOURCES/0001-backends-Consider-pen-eraser-devices-when-looking-fo.patch b/SOURCES/0001-backends-Consider-pen-eraser-devices-when-looking-fo.patch new file mode 100644 index 0000000..f7fa3b2 --- /dev/null +++ b/SOURCES/0001-backends-Consider-pen-eraser-devices-when-looking-fo.patch @@ -0,0 +1,30 @@ +From e512c397a640994807f239c570333e9942717ef5 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Fri, 13 Dec 2019 17:01:44 +0100 +Subject: [PATCH] backends: Consider pen/eraser devices when looking for + matching WacomDevice + +Those device types are still in use through the X11 backend, breaking some +checks around on that backend... + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/972 +--- + src/backends/meta-input-settings.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c +index 2e6672d9c..18ae52dd7 100644 +--- a/src/backends/meta-input-settings.c ++++ b/src/backends/meta-input-settings.c +@@ -1589,6 +1589,8 @@ check_add_mappable_device (MetaInputSettings *input_settings, + + #ifdef HAVE_LIBWACOM + if (device_type == CLUTTER_TABLET_DEVICE || ++ device_type == CLUTTER_PEN_DEVICE || ++ device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_PAD_DEVICE) + { + WacomError *error = libwacom_error_new (); +-- +2.23.0 + diff --git a/SOURCES/0001-backends-x11-Observe-multiple-pad-mode-switch-button.patch b/SOURCES/0001-backends-x11-Observe-multiple-pad-mode-switch-button.patch new file mode 100644 index 0000000..3735f0d --- /dev/null +++ b/SOURCES/0001-backends-x11-Observe-multiple-pad-mode-switch-button.patch @@ -0,0 +1,118 @@ +From a8f12e7afdb35ebda581cee6a32b295cb6e643ec Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Fri, 13 Dec 2019 14:22:12 +0100 +Subject: [PATCH] backends/x11: Observe multiple pad mode switch buttons in a + group + +Some tablets like the Cintiq 24HDT have several mode switch buttons +per group. Those are meant to jump straight to a given mode, however +we just handle cycling across modes (as most other tablets have a +single mode switch button per group). + +So spice up the mode switch handling so we handle multiple mode +switch buttons, assigning each of them a mode. If the device only +has one mode switch button, we do the old-fashioned cycling. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/970 +--- + .../clutter/x11/clutter-input-device-xi2.c | 71 ++++++++++++++++--- + 1 file changed, 60 insertions(+), 11 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c +index 1254aca3a..c33adffc2 100644 +--- a/clutter/clutter/x11/clutter-input-device-xi2.c ++++ b/clutter/clutter/x11/clutter-input-device-xi2.c +@@ -318,6 +318,57 @@ clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device, + return g_array_index (device_xi2->group_modes, guint, group); + } + ++static gboolean ++pad_switch_mode (ClutterInputDevice *device, ++ uint32_t button, ++ uint32_t group, ++ uint32_t *mode) ++{ ++ ClutterInputDeviceXI2 *device_x11 = CLUTTER_INPUT_DEVICE_XI2 (device); ++ uint32_t n_buttons, n_modes, button_group, next_mode, i; ++ GList *switch_buttons = NULL; ++ ++ n_buttons = libwacom_get_num_buttons (device_x11->wacom_device); ++ ++ for (i = 0; i < n_buttons; i++) ++ { ++ button_group = clutter_input_device_xi2_get_button_group (device, i); ++ if (button_group == group) ++ switch_buttons = g_list_prepend (switch_buttons, GINT_TO_POINTER (button)); ++ } ++ ++ switch_buttons = g_list_reverse (switch_buttons); ++ n_modes = clutter_input_device_get_group_n_modes (device, group); ++ ++ if (g_list_length (switch_buttons) > 1) ++ { ++ /* If there's multiple switch buttons, we don't toggle but assign a mode ++ * to each of those buttons. ++ */ ++ next_mode = g_list_position (switch_buttons, GINT_TO_POINTER (button)); ++ } ++ else if (switch_buttons) ++ { ++ uint32_t cur_mode; ++ ++ /* If there is a single button, have it toggle across modes */ ++ cur_mode = g_array_index (device_x11->group_modes, uint32_t, group); ++ next_mode = (cur_mode + 1) % n_modes; ++ } ++ else ++ { ++ return FALSE; ++ } ++ ++ g_list_free (switch_buttons); ++ ++ if (next_mode < 0 || next_mode > n_modes) ++ return FALSE; ++ ++ *mode = next_mode; ++ return TRUE; ++} ++ + void + clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, + guint button, +@@ -330,23 +381,21 @@ clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, + gboolean is_mode_switch = FALSE; + + button_group = clutter_input_device_xi2_get_button_group (device, button); +- is_mode_switch = button_group >= 0; + +- /* Assign all non-mode-switch buttons to group 0 so far */ +- button_group = MAX (0, button_group); +- +- if (button_group >= device_xi2->group_modes->len) +- return; ++ if (button_group < 0 || button_group >= device_xi2->group_modes->len) ++ { ++ *group = *mode = 0; ++ return; ++ } + + group_mode = &g_array_index (device_xi2->group_modes, guint, button_group); + +- if (is_mode_switch && state) ++ if (state) + { +- guint next, n_modes; ++ uint32_t next_mode; + +- n_modes = clutter_input_device_get_group_n_modes (device, button_group); +- next = (*group_mode + 1) % n_modes; +- *group_mode = next; ++ if (pad_switch_mode (device, button, button_group, &next_mode)) ++ *group_mode = next_mode; + } + + if (group) +-- +2.23.0 + diff --git a/SOURCES/0001-cogl-Remove-unused-OFFSCREEN_BLIT-feature-flag.patch b/SOURCES/0001-cogl-Remove-unused-OFFSCREEN_BLIT-feature-flag.patch new file mode 100644 index 0000000..b2965a3 --- /dev/null +++ b/SOURCES/0001-cogl-Remove-unused-OFFSCREEN_BLIT-feature-flag.patch @@ -0,0 +1,37 @@ +From 251ef4ff4bacefac211e21873e10da7fa067dd68 Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Fri, 26 Apr 2019 12:23:18 +0300 +Subject: [PATCH 01/12] cogl: Remove unused OFFSCREEN_BLIT feature flag + +This named constant is never used anywhere. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 + +(cherry picked from commit c08a24bb40ad7aa7746e86251c9dbe6c264b4d7c) +--- + cogl/cogl/cogl-types.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h +index 690daa16a..69d304cf0 100644 +--- a/cogl/cogl/cogl-types.h ++++ b/cogl/cogl/cogl-types.h +@@ -325,7 +325,6 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ + * @COGL_FEATURE_SHADERS_GLSL: GLSL support + * @COGL_FEATURE_OFFSCREEN: FBO support + * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs +- * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs + * @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available + * @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support + * @COGL_FEATURE_VBOS: VBO support +@@ -368,7 +367,6 @@ typedef enum + COGL_FEATURE_SHADERS_GLSL = (1 << 5), + COGL_FEATURE_OFFSCREEN = (1 << 6), + COGL_FEATURE_OFFSCREEN_MULTISAMPLE = (1 << 7), +- COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8), + COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9), + COGL_FEATURE_STENCIL_BUFFER = (1 << 10), + COGL_FEATURE_VBOS = (1 << 11), +-- +2.21.0 + diff --git a/SOURCES/0001-core-Let-pad-mode-switch-events-always-go-through-Me.patch b/SOURCES/0001-core-Let-pad-mode-switch-events-always-go-through-Me.patch new file mode 100644 index 0000000..5ee31d1 --- /dev/null +++ b/SOURCES/0001-core-Let-pad-mode-switch-events-always-go-through-Me.patch @@ -0,0 +1,64 @@ +From 5cab6bac4d4fb06e60d3198dc654a5d70fa6240e Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Mon, 16 Dec 2019 13:53:26 +0100 +Subject: [PATCH] core: Let pad mode switch events always go through + MetaInputSettings + +We used to inhibit all pad actions while the OSD is shown, but one we +would actually want to handle are mode switches while the OSD is open. +So it has an opportunity to catch up to the mode switch. + +This lets MetaInputSettings reflect the mode switch (eg. when querying +action labels), so the OSD has an opportunity to update the current +actions. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/975 +--- + src/core/events.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +diff --git a/src/core/events.c b/src/core/events.c +index d383778629..44f28d0b97 100644 +--- a/src/core/events.c ++++ b/src/core/events.c +@@ -256,13 +256,31 @@ meta_display_handle_event (MetaDisplay *display, + } + #endif + +- if (!display->current_pad_osd && +- (event->type == CLUTTER_PAD_BUTTON_PRESS || +- event->type == CLUTTER_PAD_BUTTON_RELEASE || +- event->type == CLUTTER_PAD_RING || +- event->type == CLUTTER_PAD_STRIP)) ++ if (event->type == CLUTTER_PAD_BUTTON_PRESS || ++ event->type == CLUTTER_PAD_BUTTON_RELEASE || ++ event->type == CLUTTER_PAD_RING || ++ event->type == CLUTTER_PAD_STRIP) + { +- if (meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend), ++ gboolean handle_pad_event = TRUE; ++ gboolean is_mode_switch = FALSE; ++ ++ if (event->type == CLUTTER_PAD_BUTTON_PRESS || ++ event->type == CLUTTER_PAD_BUTTON_RELEASE) ++ { ++ ClutterInputDevice *pad; ++ uint32_t button; ++ ++ pad = clutter_event_get_source_device (event); ++ button = clutter_event_get_button (event); ++ ++ is_mode_switch = ++ clutter_input_device_get_mode_switch_button_group (pad, button) >= 0; ++ } ++ ++ handle_pad_event = !display->current_pad_osd || is_mode_switch; ++ ++ if (handle_pad_event && ++ meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend), + event)) + { + bypass_wayland = bypass_clutter = TRUE; +-- +2.24.0 + diff --git a/SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch b/SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch new file mode 100644 index 0000000..3ba3963 --- /dev/null +++ b/SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch @@ -0,0 +1,122 @@ +From f108395c32351cda8722130e0e2970827b18e5a9 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Wed, 2 Oct 2019 16:49:28 +0200 +Subject: [PATCH] events: Sync pending pointer events without a window + +Mutter issues a synchronous grab on the pointer for unfocused client +windows to be able to catch the button events first and raise/focus +client windows accordingly. + +When there is a synchronous grab in effect, all events are queued until +the grabbing client releases the event queue as it processes the events. + +Mutter does release the events in its event handler function but does so +only if it is able to find the window matching the event. If the window +is a shell widget, that matching may fail and therefore Mutter will not +release the events, hence causing a freeze in pointer events delivery. + +To avoid the issue, make sure we sync the pointer events in case we +can't find a matching window. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/821 +--- + src/core/events.c | 62 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 51 insertions(+), 11 deletions(-) + +diff --git a/src/core/events.c b/src/core/events.c +index 5b8e49fc7..831cb007b 100644 +--- a/src/core/events.c ++++ b/src/core/events.c +@@ -50,6 +50,12 @@ + #define IS_KEY_EVENT(e) ((e)->type == CLUTTER_KEY_PRESS || \ + (e)->type == CLUTTER_KEY_RELEASE) + ++typedef enum ++{ ++ EVENTS_UNFREEZE_SYNC, ++ EVENTS_UNFREEZE_REPLAY, ++} EventsUnfreezeMethod; ++ + static gboolean + stage_has_key_focus (void) + { +@@ -167,6 +173,43 @@ sequence_is_pointer_emulated (MetaDisplay *display, + return FALSE; + } + ++static void ++maybe_unfreeze_pointer_events (MetaBackend *backend, ++ const ClutterEvent *event, ++ EventsUnfreezeMethod unfreeze_method) ++{ ++ Display *xdisplay; ++ int event_mode; ++ int device_id; ++ ++ if (event->type != CLUTTER_BUTTON_PRESS) ++ return; ++ ++ if (!META_IS_BACKEND_X11 (backend)) ++ return; ++ ++ device_id = clutter_event_get_device_id (event); ++ switch (unfreeze_method) ++ { ++ case EVENTS_UNFREEZE_SYNC: ++ event_mode = XISyncDevice; ++ meta_verbose ("Syncing events time %u device %i\n", ++ (unsigned int) event->button.time, device_id); ++ break; ++ case EVENTS_UNFREEZE_REPLAY: ++ event_mode = XIReplayDevice; ++ meta_verbose ("Replaying events time %u device %i\n", ++ (unsigned int) event->button.time, device_id); ++ break; ++ default: ++ g_assert_not_reached (); ++ return; ++ } ++ ++ xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ XIAllowEvents (xdisplay, device_id, event_mode, event->button.time); ++} ++ + static gboolean + meta_display_handle_event (MetaDisplay *display, + const ClutterEvent *event) +@@ -366,17 +409,7 @@ meta_display_handle_event (MetaDisplay *display, + { + /* Only replay button press events, since that's where we + * have the synchronous grab. */ +- if (event->type == CLUTTER_BUTTON_PRESS) +- { +- if (META_IS_BACKEND_X11 (backend)) +- { +- Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); +- meta_verbose ("Allowing events time %u\n", +- (unsigned int)event->button.time); +- XIAllowEvents (xdisplay, clutter_event_get_device_id (event), +- XIReplayDevice, event->button.time); +- } +- } ++ maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY); + + /* If the focus window has an active close dialog let clutter + * events go through, so fancy clutter dialogs can get to handle +@@ -392,6 +425,13 @@ meta_display_handle_event (MetaDisplay *display, + + goto out; + } ++ else ++ { ++ /* We could not match the event with a window, make sure we sync ++ * the pointer to discard the sequence and don't keep events frozen. ++ */ ++ maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_SYNC); ++ } + + out: + /* If the compositor has a grab, don't pass that through to Wayland */ +-- +2.23.0 + diff --git a/SOURCES/0001-iconcache-Avoid-xrender-picture-formats-when-creatin.patch b/SOURCES/0001-iconcache-Avoid-xrender-picture-formats-when-creatin.patch new file mode 100644 index 0000000..0ed0857 --- /dev/null +++ b/SOURCES/0001-iconcache-Avoid-xrender-picture-formats-when-creatin.patch @@ -0,0 +1,136 @@ +From 80f79e0cc7509b79b38193a006b0d98d03432044 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 5 Aug 2019 14:39:21 -0400 +Subject: [PATCH] iconcache: Avoid xrender picture formats when creating cairo + surface + +If an application provides its window icon via wmhints, then mutter +loads the pixmap specified by the application into a cairo xlib surface. When +creating the surface it specifies the visual, indirectly, via an XRender +picture format. + +This is suboptimal, since XRender picture formats don't have a way to specify +16bpp depth, which an application may be using. + +In particular, applications are likely to use 16bpp depth pixmaps for their +icons, if the video card offers a 16bpp framebuffer/root window. + +This commit drops the XRender middleman, and just tells cairo a visual to use +directly. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/715 +--- + src/x11/iconcache.c | 31 ++++++------------------------- + 1 file changed, 6 insertions(+), 25 deletions(-) + +diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c +index 15d72da65..521c77b8d 100644 +--- a/src/x11/iconcache.c ++++ b/src/x11/iconcache.c +@@ -261,97 +261,78 @@ get_pixmap_geometry (MetaX11Display *x11_display, + Pixmap pixmap, + int *w, + int *h, + int *d) + { + Window root_ignored; + int x_ignored, y_ignored; + guint width, height; + guint border_width_ignored; + guint depth; + + if (w) + *w = 1; + if (h) + *h = 1; + if (d) + *d = 1; + + XGetGeometry (x11_display->xdisplay, + pixmap, &root_ignored, &x_ignored, &y_ignored, + &width, &height, &border_width_ignored, &depth); + + if (w) + *w = width; + if (h) + *h = height; + if (d) + *d = depth; + } + +-static int +-standard_pict_format_for_depth (int depth) +-{ +- switch (depth) +- { +- case 1: +- return PictStandardA1; +- case 24: +- return PictStandardRGB24; +- case 32: +- return PictStandardARGB32; +- default: +- g_assert_not_reached (); +- } +- return 0; +-} +- +-static XRenderPictFormat * +-pict_format_for_depth (Display *xdisplay, int depth) +-{ +- return XRenderFindStandardFormat (xdisplay, standard_pict_format_for_depth (depth)); +-} +- + static cairo_surface_t * + surface_from_pixmap (Display *xdisplay, Pixmap xpixmap, + int width, int height) + { + Window root_return; ++ XVisualInfo visual_info; + int x_ret, y_ret; + unsigned int w_ret, h_ret, bw_ret, depth_ret; + + if (!XGetGeometry (xdisplay, xpixmap, &root_return, + &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) + return NULL; + +- return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay), +- pict_format_for_depth (xdisplay, depth_ret), w_ret, h_ret); ++ if (!XMatchVisualInfo (xdisplay, DefaultScreen (xdisplay), ++ depth_ret, TrueColor, &visual_info)) ++ return NULL; ++ ++ return cairo_xlib_surface_create (xdisplay, xpixmap, visual_info.visual, w_ret, h_ret); + } + + static gboolean + try_pixmap_and_mask (MetaX11Display *x11_display, + Pixmap src_pixmap, + Pixmap src_mask, + cairo_surface_t **iconp) + { + Display *xdisplay = x11_display->xdisplay; + cairo_surface_t *icon, *mask = NULL; + int w, h, d; + + if (src_pixmap == None) + return FALSE; + + meta_x11_error_trap_push (x11_display); + + get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d); + icon = surface_from_pixmap (xdisplay, src_pixmap, w, h); + + if (icon && src_mask != None) + { + get_pixmap_geometry (x11_display, src_mask, &w, &h, &d); + + if (d == 1) + mask = surface_from_pixmap (xdisplay, src_mask, w, h); + } + + meta_x11_error_trap_pop (x11_display); + +-- +2.21.0 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Move-dpms-state-and-screen-si.patch b/SOURCES/0001-monitor-manager-xrandr-Move-dpms-state-and-screen-si.patch new file mode 100644 index 0000000..8a0242c --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Move-dpms-state-and-screen-si.patch @@ -0,0 +1,114 @@ +From 078547521dd709d41ac3791322f711030ccc50e9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 27 Nov 2019 19:03:50 +0100 +Subject: [PATCH 1/2] monitor-manager-xrandr: Move dpms state and screen size + updating into helpers + +To be used by no-Xrandr fallback path. +--- + src/backends/x11/meta-gpu-xrandr.c | 37 +++++++++++++------ + .../x11/meta-monitor-manager-xrandr.c | 18 ++++++--- + 2 files changed, 38 insertions(+), 17 deletions(-) + +diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c +index 90b33d486..1884278ca 100644 +--- a/src/backends/x11/meta-gpu-xrandr.c ++++ b/src/backends/x11/meta-gpu-xrandr.c +@@ -91,6 +91,30 @@ meta_gpu_xrandr_poll_hardware (MetaGpu *gpu) + gpu_xrandr->need_hardware_poll = TRUE; + } + ++static void ++update_screen_size (MetaGpuXrandr *gpu_xrandr) ++{ ++ MetaGpu *gpu = META_GPU (gpu_xrandr); ++ MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu); ++ MetaMonitorManagerXrandr *monitor_manager_xrandr = ++ META_MONITOR_MANAGER_XRANDR (monitor_manager); ++ Display *xdisplay = ++ meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); ++ int min_width, min_height; ++ Screen *screen; ++ ++ XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay), ++ &min_width, ++ &min_height, ++ &gpu_xrandr->max_screen_width, ++ &gpu_xrandr->max_screen_height); ++ ++ screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay)); ++ /* This is updated because we called XRRUpdateConfiguration. */ ++ monitor_manager->screen_width = WidthOfScreen (screen); ++ monitor_manager->screen_height = HeightOfScreen (screen); ++} ++ + static gboolean + meta_gpu_xrandr_read_current (MetaGpu *gpu, + GError **error) +@@ -105,8 +129,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, + RROutput primary_output; + unsigned int i, j; + GList *l; +- int min_width, min_height; +- Screen *screen; + GList *outputs = NULL; + GList *modes = NULL; + GList *crtcs = NULL; +@@ -115,16 +137,7 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, + XRRFreeScreenResources (gpu_xrandr->resources); + gpu_xrandr->resources = NULL; + +- XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay), +- &min_width, +- &min_height, +- &gpu_xrandr->max_screen_width, +- &gpu_xrandr->max_screen_height); +- +- screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay)); +- /* This is updated because we called XRRUpdateConfiguration. */ +- monitor_manager->screen_width = WidthOfScreen (screen); +- monitor_manager->screen_height = HeightOfScreen (screen); ++ update_screen_size (gpu_xrandr); + + if (gpu_xrandr->need_hardware_poll) + { +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index b8d6342b6..7a0b43ac4 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -146,12 +146,9 @@ x11_dpms_state_to_power_save (CARD16 dpms_state) + } + + static void +-meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager) ++meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr) + { +- MetaMonitorManagerXrandr *manager_xrandr = +- META_MONITOR_MANAGER_XRANDR (manager); +- MetaMonitorManagerClass *parent_class = +- META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class); ++ MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + Display *xdisplay = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr); + BOOL dpms_capable, dpms_enabled; + CARD16 dpms_state; +@@ -167,6 +164,17 @@ meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager) + power_save_mode = META_POWER_SAVE_UNSUPPORTED; + + meta_monitor_manager_power_save_mode_changed (manager, power_save_mode); ++} ++ ++static void ++meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = ++ META_MONITOR_MANAGER_XRANDR (manager); ++ MetaMonitorManagerClass *parent_class = ++ META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class); ++ ++ meta_monitor_manager_xrandr_update_dpms_state (manager_xrandr); + + parent_class->read_current_state (manager); + } +-- +2.23.0 + diff --git a/SOURCES/0001-wayland-Check-stylus-serials-on-meta_wayland_seat_ca.patch b/SOURCES/0001-wayland-Check-stylus-serials-on-meta_wayland_seat_ca.patch new file mode 100644 index 0000000..486df56 --- /dev/null +++ b/SOURCES/0001-wayland-Check-stylus-serials-on-meta_wayland_seat_ca.patch @@ -0,0 +1,109 @@ +From f2b3dd318f1165849b45a86251724939b100ef7d Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Mon, 28 Oct 2019 18:07:31 +0100 +Subject: [PATCH] wayland: Check stylus serials on + meta_wayland_seat_can_popup() + +This allows xdg_popup.grab() to work with styli. Without this check +we would bail out and emit xdg_popup.popup_done, leaving stylus users +unable to interact with popup menus, comboboxes, etc... + +Closes: https://gitlab.gnome.org/GNOME/mutter/issues/886 +--- + src/wayland/meta-wayland-seat.c | 10 +++++++++- + src/wayland/meta-wayland-tablet-seat.c | 17 +++++++++++++++++ + src/wayland/meta-wayland-tablet-seat.h | 2 ++ + src/wayland/meta-wayland-tablet-tool.c | 7 +++++++ + src/wayland/meta-wayland-tablet-tool.h | 2 ++ + 5 files changed, 37 insertions(+), 1 deletion(-) + +diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c +index 91fe376ff..cf41d6eb8 100644 +--- a/src/wayland/meta-wayland-seat.c ++++ b/src/wayland/meta-wayland-seat.c +@@ -504,9 +504,17 @@ gboolean + meta_wayland_seat_can_popup (MetaWaylandSeat *seat, + uint32_t serial) + { ++ MetaWaylandCompositor *compositor; ++ MetaWaylandTabletSeat *tablet_seat; ++ ++ compositor = meta_wayland_compositor_get_default (); ++ tablet_seat = ++ meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat); ++ + return (meta_wayland_pointer_can_popup (seat->pointer, serial) || + meta_wayland_keyboard_can_popup (seat->keyboard, serial) || +- meta_wayland_touch_can_popup (seat->touch, serial)); ++ meta_wayland_touch_can_popup (seat->touch, serial) || ++ meta_wayland_tablet_seat_can_popup (tablet_seat, serial)); + } + + gboolean +diff --git a/src/wayland/meta-wayland-tablet-seat.c b/src/wayland/meta-wayland-tablet-seat.c +index b4bc4aa58..b1964714a 100644 +--- a/src/wayland/meta-wayland-tablet-seat.c ++++ b/src/wayland/meta-wayland-tablet-seat.c +@@ -552,3 +552,20 @@ meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat, + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &pad)) + meta_wayland_tablet_pad_set_focus (pad, surface); + } ++ ++gboolean ++meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat, ++ uint32_t serial) ++{ ++ MetaWaylandTabletTool *tool; ++ GHashTableIter iter; ++ ++ g_hash_table_iter_init (&iter, tablet_seat->tools); ++ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tool)) ++ { ++ if (meta_wayland_tablet_tool_can_popup (tool, serial)) ++ return TRUE; ++ } ++ ++ return FALSE; ++} +diff --git a/src/wayland/meta-wayland-tablet-seat.h b/src/wayland/meta-wayland-tablet-seat.h +index c083dec5f..e3be5f264 100644 +--- a/src/wayland/meta-wayland-tablet-seat.h ++++ b/src/wayland/meta-wayland-tablet-seat.h +@@ -75,5 +75,7 @@ MetaWaylandTablet *meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylan + MetaWaylandTabletPad *pad); + GList *meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTablet *tablet); ++gboolean meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat, ++ uint32_t serial); + + #endif /* META_WAYLAND_TABLET_SEAT_H */ +diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c +index c02831d73..065c834bb 100644 +--- a/src/wayland/meta-wayland-tablet-tool.c ++++ b/src/wayland/meta-wayland-tablet-tool.c +@@ -1018,3 +1018,10 @@ meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, + return ((tool->down_serial == serial || tool->button_serial == serial) && + tablet_tool_can_grab_surface (tool, surface)); + } ++ ++gboolean ++meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool, ++ uint32_t serial) ++{ ++ return tool->down_serial == serial || tool->button_serial == serial; ++} +diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h +index 71bc86643..315e26bde 100644 +--- a/src/wayland/meta-wayland-tablet-tool.h ++++ b/src/wayland/meta-wayland-tablet-tool.h +@@ -85,5 +85,7 @@ void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *t + gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, + MetaWaylandSurface *surface, + uint32_t serial); ++gboolean meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool, ++ uint32_t serial); + + #endif /* META_WAYLAND_TABLET_TOOL_H */ +-- +2.23.0 + diff --git a/SOURCES/0001-workspace-Focus-only-ancestors-that-are-focusable.patch b/SOURCES/0001-workspace-Focus-only-ancestors-that-are-focusable.patch new file mode 100644 index 0000000..94a73d8 --- /dev/null +++ b/SOURCES/0001-workspace-Focus-only-ancestors-that-are-focusable.patch @@ -0,0 +1,83 @@ +From eca25ab6a12770a2a767458d9b0129d4fde3995c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 13 Nov 2018 08:31:52 +0100 +Subject: [PATCH 1/2] workspace: Focus only ancestors that are focusable + +When destroying a window that has a parent, we initially try to focus one of +its ancestors. However if no ancestor can be focused, then we should instead +focus the default focus window instead of trying to request focus for a window +that can't get focus anyways. + +Fixes https://gitlab.gnome.org/GNOME/mutter/issues/308 +(cherry picked from commit eccc791f3b3451216f957e67fec47a73b65ed2b2) +--- + src/core/workspace.c | 37 +++++++++++++++++++++++++++---------- + 1 file changed, 27 insertions(+), 10 deletions(-) + +diff --git a/src/core/workspace.c b/src/core/workspace.c +index f2b2c2c48..58fcfa78c 100644 +--- a/src/core/workspace.c ++++ b/src/core/workspace.c +@@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData + MetaRectangle logical_monitor_work_area; + } MetaWorkspaceLogicalMonitorData; + ++typedef struct _MetaWorkspaceFocusableAncestorData ++{ ++ MetaWorkspace *workspace; ++ MetaWindow *out_window; ++} MetaWorkspaceFocusableAncestorData; ++ + static MetaWorkspaceLogicalMonitorData * + meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor) +@@ -1322,13 +1328,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, + } + + static gboolean +-record_ancestor (MetaWindow *window, +- void *data) ++find_focusable_ancestor (MetaWindow *window, ++ gpointer user_data) + { +- MetaWindow **result = data; ++ MetaWorkspaceFocusableAncestorData *data = user_data; ++ ++ if (!window->unmanaging && meta_window_is_focusable (window) && ++ meta_window_located_on_workspace (window, data->workspace) && ++ meta_window_showing_on_its_workspace (window)) ++ { ++ data->out_window = window; ++ return FALSE; ++ } + +- *result = window; +- return FALSE; /* quit with the first ancestor we find */ ++ return TRUE; + } + + /* Focus ancestor of not_this_one if there is one */ +@@ -1350,11 +1363,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, + if (not_this_one) + { + MetaWindow *ancestor; +- ancestor = NULL; +- meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); +- if (ancestor != NULL && +- meta_window_located_on_workspace (ancestor, workspace) && +- meta_window_showing_on_its_workspace (ancestor)) ++ MetaWorkspaceFocusableAncestorData data; ++ ++ data = (MetaWorkspaceFocusableAncestorData) { ++ .workspace = workspace, ++ }; ++ meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data); ++ ancestor = data.out_window; ++ ++ if (ancestor) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s, ancestor of %s\n", +-- +2.21.0 + diff --git a/SOURCES/0001-x11-Check-wacom-button-flags-to-determine-whether-bu.patch b/SOURCES/0001-x11-Check-wacom-button-flags-to-determine-whether-bu.patch new file mode 100644 index 0000000..5303bbc --- /dev/null +++ b/SOURCES/0001-x11-Check-wacom-button-flags-to-determine-whether-bu.patch @@ -0,0 +1,53 @@ +From 57b3a2ea620f754cfd38f1ed4851dd8223efbcab Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 28 Nov 2019 22:50:36 +0100 +Subject: [PATCH] x11: Check wacom button flags to determine whether button is + mode switch + +Checking the leds is not really accurate, since some devices have mode +switch buttons without leds. Check in the button flags whether they are +mode switch buttons for any of ring/ring2/strip/strip2, and return the +appropriate group. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/952 +--- + .../clutter/x11/clutter-input-device-xi2.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c +index 1254aca3ae..4e5e2fd12c 100644 +--- a/clutter/clutter/x11/clutter-input-device-xi2.c ++++ b/clutter/clutter/x11/clutter-input-device-xi2.c +@@ -155,14 +155,25 @@ clutter_input_device_xi2_get_button_group (ClutterInputDevice *device, + + if (device_xi2->wacom_device) + { ++ WacomButtonFlags flags; ++ + if (button >= libwacom_get_num_buttons (device_xi2->wacom_device)) + return -1; + +- return libwacom_get_button_led_group (device_xi2->wacom_device, +- 'A' + button); ++ flags = libwacom_get_button_flag (device_xi2->wacom_device, ++ 'A' + button); ++ ++ if (flags & ++ (WACOM_BUTTON_RING_MODESWITCH | ++ WACOM_BUTTON_TOUCHSTRIP_MODESWITCH)) ++ return 0; ++ if (flags & ++ (WACOM_BUTTON_RING2_MODESWITCH | ++ WACOM_BUTTON_TOUCHSTRIP2_MODESWITCH)) ++ return 1; + } +- else +- return -1; ++ ++ return -1; + } + #endif + +-- +2.24.0 + diff --git a/SOURCES/0002-cogl-Fix-doc-for-_cogl_blit_framebuffer.patch b/SOURCES/0002-cogl-Fix-doc-for-_cogl_blit_framebuffer.patch new file mode 100644 index 0000000..510b926 --- /dev/null +++ b/SOURCES/0002-cogl-Fix-doc-for-_cogl_blit_framebuffer.patch @@ -0,0 +1,42 @@ +From 801da0dab1d2928578e9b191ee1684bcc7154081 Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Tue, 30 Apr 2019 17:01:04 +0300 +Subject: [PATCH 02/12] cogl: Fix doc for _cogl_blit_framebuffer + +Commit 38921701e533b7fda38a236cc45aec2ed3afef8a added explicit source and +destination parameters. Fix the documentation to match. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 + +(cherry picked from commit fc0ce11fcd997af12fc2253eeb37e03cebb5964f) +--- + cogl/cogl/cogl-framebuffer-private.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h +index 296788c2b..de886b64f 100644 +--- a/cogl/cogl/cogl-framebuffer-private.h ++++ b/cogl/cogl/cogl-framebuffer-private.h +@@ -4,6 +4,7 @@ + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2007,2008,2009 Intel Corporation. ++ * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation +@@ -377,9 +378,8 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + * @width: Width of region to copy + * @height: Height of region to copy + * +- * This blits a region of the color buffer of the current draw buffer +- * to the current read buffer. The draw and read buffers can be set up +- * using _cogl_push_framebuffers(). This function should only be ++ * This blits a region of the color buffer of the source buffer ++ * to the destination buffer. This function should only be + * called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is + * advertised. The two buffers must both be offscreen and have the + * same format. +-- +2.21.0 + diff --git a/SOURCES/0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch b/SOURCES/0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch new file mode 100644 index 0000000..93756e4 --- /dev/null +++ b/SOURCES/0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch @@ -0,0 +1,185 @@ +From 85484d8f5d75764ab74308da7b21411c3fe4a2da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 3 Oct 2018 10:50:47 +0200 +Subject: [PATCH 2/2] monitor-manager/xrandr: Create dummy screen sized monitor + if no RANDR + +When there is no RANDR support enabled in the X server, we wont get +notified of any monitors, resulting in mutter believing we're being +headless. To get at least something working, although with no way +configuration ability, lets pretend the whole screen is just a single +monitor with a single output, crtc and mode. +--- + src/backends/x11/meta-gpu-xrandr.c | 60 +++++++++++++++++++ + .../x11/meta-monitor-manager-xrandr.c | 22 ++++++- + .../x11/meta-monitor-manager-xrandr.h | 4 ++ + 3 files changed, 85 insertions(+), 1 deletion(-) + +diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c +index 1884278ca..22e7e70e0 100644 +--- a/src/backends/x11/meta-gpu-xrandr.c ++++ b/src/backends/x11/meta-gpu-xrandr.c +@@ -115,6 +115,63 @@ update_screen_size (MetaGpuXrandr *gpu_xrandr) + monitor_manager->screen_height = HeightOfScreen (screen); + } + ++static gboolean ++read_current_fallback (MetaGpuXrandr *gpu_xrandr, ++ MetaMonitorManagerXrandr *monitor_manager_xrandr) ++{ ++ MetaGpu *gpu = META_GPU (gpu_xrandr); ++ MetaMonitorManager *monitor_manager = ++ META_MONITOR_MANAGER (monitor_manager_xrandr); ++ MetaCrtcMode *mode; ++ MetaCrtc *crtc; ++ MetaOutput *output; ++ ++ meta_monitor_manager_xrandr_update_dpms_state (monitor_manager_xrandr); ++ update_screen_size (gpu_xrandr); ++ ++ mode = g_object_new (META_TYPE_CRTC_MODE, NULL); ++ mode->mode_id = 0; ++ mode->width = monitor_manager->screen_width; ++ mode->height = monitor_manager->screen_height; ++ mode->refresh_rate = 60.0; ++ mode->name = g_strdup_printf ("%dx%d", mode->width, mode->height); ++ ++ meta_gpu_take_modes (gpu, g_list_prepend (NULL, mode)); ++ ++ crtc = g_object_new (META_TYPE_CRTC, NULL); ++ crtc->gpu = gpu; ++ crtc->crtc_id = 0; ++ crtc->rect = (MetaRectangle) { .width = mode->width, .height = mode->height }; ++ crtc->current_mode = mode; ++ ++ meta_gpu_take_crtcs (gpu, g_list_prepend (NULL, crtc)); ++ ++ output = g_object_new (META_TYPE_OUTPUT, NULL); ++ output->gpu = gpu; ++ output->winsys_id = 0; ++ output->name = g_strdup ("X11 Screen"); ++ output->vendor = g_strdup ("unknown"); ++ output->product = g_strdup ("unknown"); ++ output->serial = g_strdup ("unknown"); ++ output->hotplug_mode_update = TRUE; ++ output->suggested_x = -1; ++ output->suggested_y = -1; ++ output->connector_type = META_CONNECTOR_TYPE_Unknown; ++ output->modes = g_new0 (MetaCrtcMode *, 1); ++ output->modes[0] = mode; ++ output->n_modes = 1; ++ output->preferred_mode = mode; ++ output->possible_crtcs = g_new0 (MetaCrtc *, 1); ++ output->possible_crtcs[0] = crtc; ++ output->n_possible_crtcs = 1; ++ meta_output_assign_crtc (output, crtc); ++ output->is_primary = TRUE; ++ ++ meta_gpu_take_outputs (gpu, g_list_prepend (NULL, output)); ++ ++ return TRUE; ++} ++ + static gboolean + meta_gpu_xrandr_read_current (MetaGpu *gpu, + GError **error) +@@ -133,6 +190,9 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, + GList *modes = NULL; + GList *crtcs = NULL; + ++ if (!meta_monitor_manager_xrandr_has_randr (monitor_manager_xrandr)) ++ return read_current_fallback (gpu_xrandr, monitor_manager_xrandr); ++ + if (gpu_xrandr->resources) + XRRFreeScreenResources (gpu_xrandr->resources); + gpu_xrandr->resources = NULL; +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 7a0b43ac4..d6306faeb 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -75,6 +75,7 @@ struct _MetaMonitorManagerXrandr + guint logind_watch_id; + guint logind_signal_sub_id; + ++ gboolean has_randr; + gboolean has_randr15; + + /* +@@ -114,6 +115,12 @@ meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xran + return manager_xrandr->xdisplay; + } + ++gboolean ++meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr) ++{ ++ return manager_xrandr->has_randr; ++} ++ + gboolean + meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr) + { +@@ -145,7 +152,7 @@ x11_dpms_state_to_power_save (CARD16 dpms_state) + } + } + +-static void ++void + meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr) + { + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); +@@ -637,9 +644,18 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana + MetaMonitorsConfigMethod method, + GError **error) + { ++ MetaMonitorManagerXrandr *manager_xrandr = ++ META_MONITOR_MANAGER_XRANDR (manager); + GPtrArray *crtc_infos; + GPtrArray *output_infos; + ++ if (!manager_xrandr->has_randr) ++ { ++ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, ++ "Tried to change configuration without XRANDR support"); ++ return FALSE; ++ } ++ + if (!config) + { + meta_monitor_manager_xrandr_rebuild_derived (manager, NULL); +@@ -1105,11 +1121,15 @@ meta_monitor_manager_xrandr_constructed (GObject *object) + &manager_xrandr->rr_event_base, + &manager_xrandr->rr_error_base)) + { ++ g_warning ("No RANDR support, monitor configuration disabled"); + return; + } + else + { + int major_version, minor_version; ++ ++ manager_xrandr->has_randr = TRUE; ++ + /* We only use ScreenChangeNotify, but GDK uses the others, + and we don't want to step on its toes */ + XRRSelectInput (manager_xrandr->xdisplay, +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.h b/src/backends/x11/meta-monitor-manager-xrandr.h +index d55b3d2b8..dc75134a5 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.h ++++ b/src/backends/x11/meta-monitor-manager-xrandr.h +@@ -33,9 +33,13 @@ G_DECLARE_FINAL_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, + + Display * meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr); + ++gboolean meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr); ++ + gboolean meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr); + + gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager, + XEvent *event); + ++void meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr); ++ + #endif /* META_MONITOR_MANAGER_XRANDR_H */ +-- +2.23.0 + diff --git a/SOURCES/0002-window-Emit-an-error-and-return-when-trying-to-activ.patch b/SOURCES/0002-window-Emit-an-error-and-return-when-trying-to-activ.patch new file mode 100644 index 0000000..fedf5ce --- /dev/null +++ b/SOURCES/0002-window-Emit-an-error-and-return-when-trying-to-activ.patch @@ -0,0 +1,42 @@ +From 9a8bb8a205656ca1089444a041c99c5591477642 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Fri, 3 May 2019 18:10:47 +0000 +Subject: [PATCH 2/2] window: Emit an error and return when trying to activate + an unmanaged + +If something (i.e. gnome-shell or an extension) tries to activate an unmanaged +window, we should warn about this and avoid to perform further actions as this +could lead to a crash of mutter, since the window has not valid flags (like +workspace) set anymore at this stage. + +Fixes https://gitlab.gnome.org/GNOME/mutter/issues/580 + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/564 + + +(cherry picked from commit a6fc656e917fd48b8708b8d9f4bf9f8b15581313) +--- + src/core/window.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/core/window.c b/src/core/window.c +index d2c24506b..725cca7ce 100644 +--- a/src/core/window.c ++++ b/src/core/window.c +@@ -3683,6 +3683,13 @@ meta_window_activate_full (MetaWindow *window, + { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + gboolean allow_workspace_switch; ++ ++ if (window->unmanaging) ++ { ++ g_warning ("Trying to activate unmanaged window '%s'", window->desc); ++ return; ++ } ++ + meta_topic (META_DEBUG_FOCUS, + "_NET_ACTIVE_WINDOW message sent for %s at time %u " + "by client type %u.\n", +-- +2.21.0 + diff --git a/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch b/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch index 911ac79..03adc3a 100644 --- a/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch +++ b/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch @@ -1,4 +1,4 @@ -From 9f566208d584ec4d8da797390b6806157c7d2402 Mon Sep 17 00:00:00 2001 +From c5020c3d303ab211a970d88638e7d723034688db Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 10 Jan 2019 10:47:19 -0500 Subject: [PATCH 3/9] backend: add signals for reporting suspend and resume @@ -9,14 +9,24 @@ to MetaBackend. It's preliminary work needed for tracking when to purge and recreate all textures (needed by nvidia). --- - src/backends/meta-backend.c | 83 ++++++++++++++++++++++++++++++++----- - 1 file changed, 72 insertions(+), 11 deletions(-) + src/backends/meta-backend.c | 98 ++++++++++++++++++++++++++++++---- + src/org.freedesktop.login1.xml | 1 + + 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c -index 5d71977c6..c980cf150 100644 +index 5d71977c6..f59b899b7 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c -@@ -87,6 +87,8 @@ enum +@@ -53,6 +53,8 @@ + + #include + ++#include ++ + #include "backends/meta-cursor-tracker-private.h" + #include "backends/meta-idle-monitor-private.h" + #include "backends/meta-input-settings-private.h" +@@ -87,6 +89,8 @@ enum LAST_DEVICE_CHANGED, LID_IS_CLOSED_CHANGED, @@ -25,7 +35,7 @@ index 5d71977c6..c980cf150 100644 N_SIGNALS }; -@@ -745,6 +747,20 @@ meta_backend_class_init (MetaBackendClass *klass) +@@ -745,6 +749,20 @@ meta_backend_class_init (MetaBackendClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); @@ -46,7 +56,7 @@ index 5d71977c6..c980cf150 100644 mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS"); stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0; -@@ -768,15 +784,53 @@ meta_backend_create_renderer (MetaBackend *backend, +@@ -768,15 +786,66 @@ meta_backend_create_renderer (MetaBackend *backend, return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error); } @@ -55,7 +65,9 @@ index 5d71977c6..c980cf150 100644 +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + g_autoptr (GVariant) fd_variant = NULL; ++ g_autoptr (GUnixFDList) fd_list = NULL; + g_autoptr (GError) error = NULL; ++ int handle, fd; + + if (priv->inhibit_sleep_fd >= 0) + return; @@ -65,7 +77,9 @@ index 5d71977c6..c980cf150 100644 + "Display Server", + "Prepare for suspend", + "delay", ++ NULL, + &fd_variant, ++ &fd_list, + priv->cancellable, + &error)) + { @@ -73,7 +87,16 @@ index 5d71977c6..c980cf150 100644 + return; + } + -+ priv->inhibit_sleep_fd = g_variant_get_handle (fd_variant); ++ handle = g_variant_get_handle (fd_variant); ++ fd = g_unix_fd_list_get (fd_list, handle, &error); ++ ++ if (fd < 0) ++ { ++ g_warning ("Failed to fetch sleep inhibitor fd: %s", error->message); ++ return; ++ } ++ ++ priv->inhibit_sleep_fd = fd; +} + +static void @@ -104,7 +127,7 @@ index 5d71977c6..c980cf150 100644 meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ()); } -@@ -803,6 +857,7 @@ system_bus_gotten_cb (GObject *object, +@@ -803,6 +872,7 @@ system_bus_gotten_cb (GObject *object, GAsyncResult *res, gpointer user_data) { @@ -112,7 +135,7 @@ index 5d71977c6..c980cf150 100644 MetaBackendPrivate *priv; g_autoptr (GError) error = NULL; GDBusConnection *bus; -@@ -814,15 +869,21 @@ system_bus_gotten_cb (GObject *object, +@@ -814,15 +884,21 @@ system_bus_gotten_cb (GObject *object, priv = meta_backend_get_instance_private (user_data); priv->system_bus = bus; priv->logind_proxy = get_logind_proxy (priv->cancellable, &error); @@ -141,6 +164,18 @@ index 5d71977c6..c980cf150 100644 } static gboolean +diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml +index 1ecfd976f..7db8f373c 100644 +--- a/src/org.freedesktop.login1.xml ++++ b/src/org.freedesktop.login1.xml +@@ -46,6 +46,7 @@ + + + ++ + + + -- 2.21.0 diff --git a/SOURCES/0003-cogl-Replace-ANGLE-with-GLES3-and-NV-framebuffer_bli.patch b/SOURCES/0003-cogl-Replace-ANGLE-with-GLES3-and-NV-framebuffer_bli.patch new file mode 100644 index 0000000..b41fa93 --- /dev/null +++ b/SOURCES/0003-cogl-Replace-ANGLE-with-GLES3-and-NV-framebuffer_bli.patch @@ -0,0 +1,77 @@ +From 04d921c2c1da571c8c61a4ca12a380bc3b9623fe Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Mon, 6 May 2019 13:40:31 +0300 +Subject: [PATCH 03/12] cogl: Replace ANGLE with GLES3 and NV framebuffer_blit + +ANGLE extensions are only provided by Google's Almost Native Graphics Layer +Engine (ANGLE) implementation. Therefore they do not seem too useful for +Mutter. + +The reason to drop GL_ANGLE_framebuffer_blit support is that it has more +limitations compared to the glBlitFramebuffer in GL_EXT_framebuffer_blit, +GL_NV_framebuffer_bit, OpenGL 3.0 and OpenGL ES 3.0. Most importantly, the +ANGLE version cannot flip the image while copying, which limits +_cogl_blit_framebuffer to only off-screen <-> off-screen copies. Follow-up work +will need off-screen <-> on-screen copies. + +Instead of adding yet more capability flags to Cogl, dropping ANGLE support +seems appropriate. + +The NV extension is added to the list of glBlitFramebuffer providers because it +provides the same support as ANGLE and more. + +Likewise OpenGL ES 3.0 is added to the list of glBlitFramebuffer providers +because e.g. Mesa GLES implementation usually provides it and that makes it +widely available, again surpassing the ANGLE supported features. + +Follow-up patches will lift some of the Cogl assumptions of what +glBlitFramebuffer cannot do. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 + +(cherry picked from commit 3e68c9e8faa78298039fa3583898f18550740812) +--- + cogl/cogl/cogl-framebuffer-private.h | 3 +-- + cogl/cogl/gl-prototypes/cogl-all-functions.h | 5 +++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h +index de886b64f..3aab852c4 100644 +--- a/cogl/cogl/cogl-framebuffer-private.h ++++ b/cogl/cogl/cogl-framebuffer-private.h +@@ -387,8 +387,7 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + * Note that this function differs a lot from the glBlitFramebuffer + * function provided by the GL_EXT_framebuffer_blit extension. Notably + * it doesn't support having different sizes for the source and +- * destination rectangle. This isn't supported by the corresponding +- * GL_ANGLE_framebuffer_blit extension on GLES2.0 and it doesn't seem ++ * destination rectangle. This doesn't seem + * like a particularly useful feature. If the application wanted to + * scale the results it may make more sense to draw a primitive + * instead. +diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h +index 924ee349d..0af126059 100644 +--- a/cogl/cogl/gl-prototypes/cogl-all-functions.h ++++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h +@@ -4,6 +4,7 @@ + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2009, 2011 Intel Corporation. ++ * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation +@@ -132,8 +133,8 @@ COGL_EXT_END () + + + COGL_EXT_BEGIN (offscreen_blit, 3, 0, +- 0, /* not in either GLES */ +- "EXT\0ANGLE\0", ++ COGL_EXT_IN_GLES3, ++ "EXT\0NV\0", + "framebuffer_blit\0") + COGL_EXT_FUNCTION (void, glBlitFramebuffer, + (GLint srcX0, +-- +2.21.0 + diff --git a/SOURCES/0004-cogl-Relax-formats-on-glBlitFramebuffer.patch b/SOURCES/0004-cogl-Relax-formats-on-glBlitFramebuffer.patch new file mode 100644 index 0000000..751e0cb --- /dev/null +++ b/SOURCES/0004-cogl-Relax-formats-on-glBlitFramebuffer.patch @@ -0,0 +1,100 @@ +From 6c6c6ad5412f5bb13592630d7cb3b7aed25d159b Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Mon, 6 May 2019 14:09:16 +0300 +Subject: [PATCH 04/12] cogl: Relax formats on glBlitFramebuffer + +Depends on: "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit" + +As a possible ANGLE implementation is not longer limiting the pixel format +matching, lift the requirement of having the same pixel format. + +We still cannot do a premult <-> non-premult conversion during a blit, so guard +against that. + +This will be useful in follow-up work to copy from onscreen primary GPU +framebuffer to an offscreen secondary GPU framebuffer if the formats do not +match exactly. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 + +(cherry picked from commit 6df34eb4b7c65210f4066f7eb9bd462278b7279b) +--- + cogl/cogl/cogl-blit.c | 10 ++++++---- + cogl/cogl/cogl-framebuffer-private.h | 8 ++++++-- + cogl/cogl/cogl-framebuffer.c | 6 ++++-- + 3 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c +index 74f404f3d..a61eb66d2 100644 +--- a/cogl/cogl/cogl-blit.c ++++ b/cogl/cogl/cogl-blit.c +@@ -4,6 +4,7 @@ + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2011 Intel Corporation. ++ * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation +@@ -152,10 +153,11 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data) + CoglFramebuffer *dst_fb, *src_fb; + CoglError *ignore_error = NULL; + +- /* We can only blit between FBOs if both textures are the same +- format and the blit framebuffer extension is supported */ +- if ((_cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) != +- (_cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) || ++ /* We can only blit between FBOs if both textures have the same ++ premult convention and the blit framebuffer extension is ++ supported. */ ++ if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) != ++ (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) || + !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)) + return FALSE; + +diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h +index 3aab852c4..b06fbaee1 100644 +--- a/cogl/cogl/cogl-framebuffer-private.h ++++ b/cogl/cogl/cogl-framebuffer-private.h +@@ -381,8 +381,12 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + * This blits a region of the color buffer of the source buffer + * to the destination buffer. This function should only be + * called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is +- * advertised. The two buffers must both be offscreen and have the +- * same format. ++ * advertised. The two buffers must both be offscreen. ++ * ++ * The two buffers must have the same value types (e.g. floating-point, ++ * unsigned int, signed int, or fixed-point), but color formats do not ++ * need to match. This limitation comes from OpenGL ES 3.0 definition ++ * of glBlitFramebuffer. + * + * Note that this function differs a lot from the glBlitFramebuffer + * function provided by the GL_EXT_framebuffer_blit extension. Notably +diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c +index bd8a7fa42..0bc225945 100644 +--- a/cogl/cogl/cogl-framebuffer.c ++++ b/cogl/cogl/cogl-framebuffer.c +@@ -4,6 +4,7 @@ + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2007,2008,2009,2012 Intel Corporation. ++ * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation +@@ -1468,8 +1469,9 @@ _cogl_blit_framebuffer (CoglFramebuffer *src, + support this */ + _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src)); + _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest)); +- /* The buffers must be the same format */ +- _COGL_RETURN_IF_FAIL (src->internal_format == dest->internal_format); ++ /* The buffers must use the same premult convention */ ++ _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) == ++ (dest->internal_format & COGL_PREMULT_BIT)); + + /* Make sure the current framebuffers are bound. We explicitly avoid + flushing the clip state so we can bind our own empty state */ +-- +2.21.0 + diff --git a/SOURCES/0005-cogl-Allow-glBlitFramebuffer-between-onscreen-offscr.patch b/SOURCES/0005-cogl-Allow-glBlitFramebuffer-between-onscreen-offscr.patch new file mode 100644 index 0000000..81d49d6 --- /dev/null +++ b/SOURCES/0005-cogl-Allow-glBlitFramebuffer-between-onscreen-offscr.patch @@ -0,0 +1,145 @@ +From e4b2234d9918e9d3357ac3c7ca3898599725d3da Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Mon, 6 May 2019 15:08:29 +0300 +Subject: [PATCH 05/12] cogl: Allow glBlitFramebuffer between + onscreen/offscreen + +Depends on "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit" + +Allow blitting between onscreen and offscreen framebuffers by doing the y-flip +as necessary. This was not possible with ANGLE, but now with ANGLE gone, +glBlitFramebuffer supports flipping the copied image. + +This will be useful in follow-up work to copy from onscreen primary GPU +framebuffer to an offscreen secondary GPU framebuffer. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 + +(cherry picked from commit 45289b3d65e308117f1bc8fe6a4c88c1baaacca7) +--- + cogl/cogl/cogl-framebuffer-private.h | 14 +++---- + cogl/cogl/cogl-framebuffer.c | 46 ++++++++++++++++++----- + cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 5 +-- + 3 files changed, 43 insertions(+), 22 deletions(-) + +diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h +index b06fbaee1..f68153d8b 100644 +--- a/cogl/cogl/cogl-framebuffer-private.h ++++ b/cogl/cogl/cogl-framebuffer-private.h +@@ -381,7 +381,11 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + * This blits a region of the color buffer of the source buffer + * to the destination buffer. This function should only be + * called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is +- * advertised. The two buffers must both be offscreen. ++ * advertised. ++ * ++ * The source and destination rectangles are defined in offscreen ++ * framebuffer orientation. When copying between an offscreen and ++ * onscreen framebuffers, the image is y-flipped accordingly. + * + * The two buffers must have the same value types (e.g. floating-point, + * unsigned int, signed int, or fixed-point), but color formats do not +@@ -396,14 +400,6 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + * scale the results it may make more sense to draw a primitive + * instead. + * +- * We can only really support blitting between two offscreen buffers +- * for this function on GLES2.0. This is because we effectively render +- * upside down to offscreen buffers to maintain Cogl's representation +- * of the texture coordinate system where 0,0 is the top left of the +- * texture. If we were to blit from an offscreen to an onscreen buffer +- * then we would need to mirror the blit along the x-axis but the GLES +- * extension does not support this. +- * + * The GL function is documented to be affected by the scissor. This + * function therefore ensure that an empty clip stack is flushed + * before performing the blit which means the scissor is effectively +diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c +index 0bc225945..90976a611 100644 +--- a/cogl/cogl/cogl-framebuffer.c ++++ b/cogl/cogl/cogl-framebuffer.c +@@ -1460,15 +1460,12 @@ _cogl_blit_framebuffer (CoglFramebuffer *src, + int height) + { + CoglContext *ctx = src->context; ++ int src_x1, src_y1, src_x2, src_y2; ++ int dst_x1, dst_y1, dst_x2, dst_y2; + + _COGL_RETURN_IF_FAIL (_cogl_has_private_feature + (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)); + +- /* We can only support blitting between offscreen buffers because +- otherwise we would need to mirror the image and GLES2.0 doesn't +- support this */ +- _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src)); +- _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest)); + /* The buffers must use the same premult convention */ + _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) == + (dest->internal_format & COGL_PREMULT_BIT)); +@@ -1492,10 +1489,41 @@ _cogl_blit_framebuffer (CoglFramebuffer *src, + * as changed */ + ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; + +- ctx->glBlitFramebuffer (src_x, src_y, +- src_x + width, src_y + height, +- dst_x, dst_y, +- dst_x + width, dst_y + height, ++ /* Offscreens we do the normal way, onscreens need an y-flip. Even if ++ * we consider offscreens to be rendered upside-down, the offscreen ++ * orientation is in this function's API. */ ++ if (cogl_is_offscreen (src)) ++ { ++ src_x1 = src_x; ++ src_y1 = src_y; ++ src_x2 = src_x + width; ++ src_y2 = src_y + height; ++ } ++ else ++ { ++ src_x1 = src_x; ++ src_y1 = cogl_framebuffer_get_height (src) - src_y; ++ src_x2 = src_x + width; ++ src_y2 = src_y1 - height; ++ } ++ ++ if (cogl_is_offscreen (dest)) ++ { ++ dst_x1 = dst_x; ++ dst_y1 = dst_y; ++ dst_x2 = dst_x + width; ++ dst_y2 = dst_y + height; ++ } ++ else ++ { ++ dst_x1 = dst_x; ++ dst_y1 = cogl_framebuffer_get_height (dest) - dst_y; ++ dst_x2 = dst_x + width; ++ dst_y2 = dst_y1 - height; ++ } ++ ++ ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2, ++ dst_x1, dst_y1, dst_x2, dst_y2, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + } +diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +index 5402a7075..83e1d263a 100644 +--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c ++++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +@@ -400,12 +400,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer, + else + { + /* NB: Currently we only take advantage of binding separate +- * read/write buffers for offscreen framebuffer blit +- * purposes. */ ++ * read/write buffers for framebuffer blit purposes. */ + _COGL_RETURN_IF_FAIL (_cogl_has_private_feature + (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)); +- _COGL_RETURN_IF_FAIL (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN); +- _COGL_RETURN_IF_FAIL (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN); + + _cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER); + _cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER); +-- +2.21.0 + diff --git a/SOURCES/0006-cogl-Rename-feature-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch b/SOURCES/0006-cogl-Rename-feature-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch new file mode 100644 index 0000000..6bc5e2c --- /dev/null +++ b/SOURCES/0006-cogl-Rename-feature-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch @@ -0,0 +1,115 @@ +From 579c85d17b17fc7ad3d6c88af39932ce8faeaabe Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Mon, 6 May 2019 15:58:33 +0300 +Subject: [PATCH 06/12] cogl: Rename feature OFFSCREEN_BLIT to BLIT_FRAMEBUFFER + +The feature is not limited to offscreen framebuffer blits anymore since +"cogl: Allow glBlitFramebuffer between onscreen/offscreen". + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 + +(cherry picked from commit 55c084e6e1059d8f94c699b01c408523ed504196) +--- + cogl/cogl/cogl-blit.c | 2 +- + cogl/cogl/cogl-framebuffer-private.h | 2 +- + cogl/cogl/cogl-framebuffer.c | 2 +- + cogl/cogl/cogl-private.h | 2 +- + cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 2 +- + cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 2 +- + cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 2 +- + 7 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c +index a61eb66d2..c561b2e45 100644 +--- a/cogl/cogl/cogl-blit.c ++++ b/cogl/cogl/cogl-blit.c +@@ -158,7 +158,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data) + supported. */ + if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) != + (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) || +- !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)) ++ !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)) + return FALSE; + + dst_offscreen = _cogl_offscreen_new_with_texture_full +diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h +index f68153d8b..cb1f87354 100644 +--- a/cogl/cogl/cogl-framebuffer-private.h ++++ b/cogl/cogl/cogl-framebuffer-private.h +@@ -380,7 +380,7 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + * + * This blits a region of the color buffer of the source buffer + * to the destination buffer. This function should only be +- * called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is ++ * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is + * advertised. + * + * The source and destination rectangles are defined in offscreen +diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c +index 90976a611..5cc4eada4 100644 +--- a/cogl/cogl/cogl-framebuffer.c ++++ b/cogl/cogl/cogl-framebuffer.c +@@ -1464,7 +1464,7 @@ _cogl_blit_framebuffer (CoglFramebuffer *src, + int dst_x1, dst_y1, dst_x2, dst_y2; + + _COGL_RETURN_IF_FAIL (_cogl_has_private_feature +- (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)); ++ (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)); + + /* The buffers must use the same premult convention */ + _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) == +diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h +index 9f918b851..d9fbe68c7 100644 +--- a/cogl/cogl/cogl-private.h ++++ b/cogl/cogl/cogl-private.h +@@ -42,7 +42,7 @@ typedef enum + { + COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, + COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, +- COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, ++ COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, + COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES, + COGL_PRIVATE_FEATURE_PBOS, + COGL_PRIVATE_FEATURE_VBOS, +diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +index 83e1d263a..90d08954d 100644 +--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c ++++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +@@ -402,7 +402,7 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer, + /* NB: Currently we only take advantage of binding separate + * read/write buffers for framebuffer blit purposes. */ + _COGL_RETURN_IF_FAIL (_cogl_has_private_feature +- (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)); ++ (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)); + + _cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER); + _cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER); +diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +index 4d46844d5..e06e27961 100644 +--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c ++++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +@@ -467,7 +467,7 @@ _cogl_driver_update_features (CoglContext *ctx, + + if (ctx->glBlitFramebuffer) + COGL_FLAGS_SET (private_features, +- COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE); ++ COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE); + + if (ctx->glRenderbufferStorageMultisampleIMG) + { +diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +index 23158d5c7..bcb0bdf07 100644 +--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c ++++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +@@ -326,7 +326,7 @@ _cogl_driver_update_features (CoglContext *context, + + if (context->glBlitFramebuffer) + COGL_FLAGS_SET (private_features, +- COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE); ++ COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE); + + if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions)) + { +-- +2.21.0 + diff --git a/SOURCES/0007-cogl-Expose-cogl_blit_framebuffer.patch b/SOURCES/0007-cogl-Expose-cogl_blit_framebuffer.patch new file mode 100644 index 0000000..a5c9686 --- /dev/null +++ b/SOURCES/0007-cogl-Expose-cogl_blit_framebuffer.patch @@ -0,0 +1,261 @@ +From be13d3c844a6623563ae4e74dbb3409baf16fc9c Mon Sep 17 00:00:00 2001 +From: Pekka Paalanen +Date: Mon, 3 Dec 2018 14:34:41 +0200 +Subject: [PATCH 07/12] cogl: Expose cogl_blit_framebuffer + +The function will be used in copying from a primary GPU framebuffer to a +secondary GPU framebuffer using the primary GPU specifically when the +secondary GPU is not render-capable. + +To allow falling back in case glBlitFramebuffer cannot be used, add boolean +return value, and GError argument for debugging purposes. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/615 +(cherry picked from commit 6061abbf90cd1d62e262ebf3636470d2219e04a7) +--- + cogl/cogl/cogl-blit.c | 11 ++--- + cogl/cogl/cogl-framebuffer-private.h | 55 ----------------------- + cogl/cogl/cogl-framebuffer.c | 40 +++++++++++------ + cogl/cogl/cogl-framebuffer.h | 66 +++++++++++++++++++++++++++- + 4 files changed, 98 insertions(+), 74 deletions(-) + +diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c +index c561b2e45..ae5a8a345 100644 +--- a/cogl/cogl/cogl-blit.c ++++ b/cogl/cogl/cogl-blit.c +@@ -207,11 +207,12 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data, + int width, + int height) + { +- _cogl_blit_framebuffer (data->src_fb, +- data->dest_fb, +- src_x, src_y, +- dst_x, dst_y, +- width, height); ++ cogl_blit_framebuffer (data->src_fb, ++ data->dest_fb, ++ src_x, src_y, ++ dst_x, dst_y, ++ width, height, ++ NULL); + } + + static void +diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h +index cb1f87354..7d71fb1dc 100644 +--- a/cogl/cogl/cogl-framebuffer-private.h ++++ b/cogl/cogl/cogl-framebuffer-private.h +@@ -367,61 +367,6 @@ void + _cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + CoglFramebuffer *read_buffer); + +-/* +- * _cogl_blit_framebuffer: +- * @src: The source #CoglFramebuffer +- * @dest: The destination #CoglFramebuffer +- * @src_x: Source x position +- * @src_y: Source y position +- * @dst_x: Destination x position +- * @dst_y: Destination y position +- * @width: Width of region to copy +- * @height: Height of region to copy +- * +- * This blits a region of the color buffer of the source buffer +- * to the destination buffer. This function should only be +- * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is +- * advertised. +- * +- * The source and destination rectangles are defined in offscreen +- * framebuffer orientation. When copying between an offscreen and +- * onscreen framebuffers, the image is y-flipped accordingly. +- * +- * The two buffers must have the same value types (e.g. floating-point, +- * unsigned int, signed int, or fixed-point), but color formats do not +- * need to match. This limitation comes from OpenGL ES 3.0 definition +- * of glBlitFramebuffer. +- * +- * Note that this function differs a lot from the glBlitFramebuffer +- * function provided by the GL_EXT_framebuffer_blit extension. Notably +- * it doesn't support having different sizes for the source and +- * destination rectangle. This doesn't seem +- * like a particularly useful feature. If the application wanted to +- * scale the results it may make more sense to draw a primitive +- * instead. +- * +- * The GL function is documented to be affected by the scissor. This +- * function therefore ensure that an empty clip stack is flushed +- * before performing the blit which means the scissor is effectively +- * ignored. +- * +- * The function also doesn't support specifying the buffers to copy +- * and instead only the color buffer is copied. When copying the depth +- * or stencil buffers the extension on GLES2.0 only supports copying +- * the full buffer which would be awkward to document with this +- * API. If we wanted to support that feature it may be better to have +- * a separate function to copy the entire buffer for a given mask. +- */ +-void +-_cogl_blit_framebuffer (CoglFramebuffer *src, +- CoglFramebuffer *dest, +- int src_x, +- int src_y, +- int dst_x, +- int dst_y, +- int width, +- int height); +- + void + _cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer); + +diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c +index 5cc4eada4..6d35c6b13 100644 +--- a/cogl/cogl/cogl-framebuffer.c ++++ b/cogl/cogl/cogl-framebuffer.c +@@ -1449,26 +1449,38 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, + return ret; + } + +-void +-_cogl_blit_framebuffer (CoglFramebuffer *src, +- CoglFramebuffer *dest, +- int src_x, +- int src_y, +- int dst_x, +- int dst_y, +- int width, +- int height) ++gboolean ++cogl_blit_framebuffer (CoglFramebuffer *src, ++ CoglFramebuffer *dest, ++ int src_x, ++ int src_y, ++ int dst_x, ++ int dst_y, ++ int width, ++ int height, ++ GError **error) + { + CoglContext *ctx = src->context; + int src_x1, src_y1, src_x2, src_y2; + int dst_x1, dst_y1, dst_x2, dst_y2; + +- _COGL_RETURN_IF_FAIL (_cogl_has_private_feature +- (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)); ++ if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)) ++ { ++ g_set_error_literal (error, COGL_SYSTEM_ERROR, ++ COGL_SYSTEM_ERROR_UNSUPPORTED, ++ "Cogl BLIT_FRAMEBUFFER is not supported by the system."); ++ return FALSE; ++ } + + /* The buffers must use the same premult convention */ +- _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) == +- (dest->internal_format & COGL_PREMULT_BIT)); ++ if ((src->internal_format & COGL_PREMULT_BIT) != ++ (dest->internal_format & COGL_PREMULT_BIT)) ++ { ++ g_set_error_literal (error, COGL_SYSTEM_ERROR, ++ COGL_SYSTEM_ERROR_UNSUPPORTED, ++ "cogl_blit_framebuffer premult mismatch."); ++ return FALSE; ++ } + + /* Make sure the current framebuffers are bound. We explicitly avoid + flushing the clip state so we can bind our own empty state */ +@@ -1526,6 +1538,8 @@ _cogl_blit_framebuffer (CoglFramebuffer *src, + dst_x1, dst_y1, dst_x2, dst_y2, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); ++ ++ return TRUE; + } + + void +diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h +index 48a77e1ed..230a78627 100644 +--- a/cogl/cogl/cogl-framebuffer.h ++++ b/cogl/cogl/cogl-framebuffer.h +@@ -3,7 +3,8 @@ + * + * A Low Level GPU Graphics and Utilities API + * +- * Copyright (C) 2011 Intel Corporation. ++ * Copyright (C) 2007,2008,2009,2011 Intel Corporation. ++ * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation +@@ -1846,6 +1847,69 @@ typedef enum /*< prefix=COGL_FRAMEBUFFER_ERROR >*/ + gboolean + cogl_is_framebuffer (void *object); + ++/** ++ * cogl_blit_framebuffer: ++ * @src: The source #CoglFramebuffer ++ * @dest: The destination #CoglFramebuffer ++ * @src_x: Source x position ++ * @src_y: Source y position ++ * @dst_x: Destination x position ++ * @dst_y: Destination y position ++ * @width: Width of region to copy ++ * @height: Height of region to copy ++ * @error: optional error object ++ * ++ * @return FALSE for an immediately detected error, TRUE otherwise. ++ * ++ * This blits a region of the color buffer of the source buffer ++ * to the destination buffer. This function should only be ++ * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is ++ * advertised. ++ * ++ * The source and destination rectangles are defined in offscreen ++ * framebuffer orientation. When copying between an offscreen and ++ * onscreen framebuffers, the image is y-flipped accordingly. ++ * ++ * The two buffers must have the same value types (e.g. floating-point, ++ * unsigned int, signed int, or fixed-point), but color formats do not ++ * need to match. This limitation comes from OpenGL ES 3.0 definition ++ * of glBlitFramebuffer. ++ * ++ * Note that this function differs a lot from the glBlitFramebuffer ++ * function provided by the GL_EXT_framebuffer_blit extension. Notably ++ * it doesn't support having different sizes for the source and ++ * destination rectangle. This doesn't seem ++ * like a particularly useful feature. If the application wanted to ++ * scale the results it may make more sense to draw a primitive ++ * instead. ++ * ++ * The GL function is documented to be affected by the scissor. This ++ * function therefore ensure that an empty clip stack is flushed ++ * before performing the blit which means the scissor is effectively ++ * ignored. ++ * ++ * The function also doesn't support specifying the buffers to copy ++ * and instead only the color buffer is copied. When copying the depth ++ * or stencil buffers the extension on GLES2.0 only supports copying ++ * the full buffer which would be awkward to document with this ++ * API. If we wanted to support that feature it may be better to have ++ * a separate function to copy the entire buffer for a given mask. ++ * ++ * The @c error argument is optional, it can be NULL. If it is not NULL ++ * and this function returns FALSE, an error object with a code from ++ * COGL_SYSTEM_ERROR will be created. ++ */ ++gboolean ++cogl_blit_framebuffer (CoglFramebuffer *src, ++ CoglFramebuffer *dest, ++ int src_x, ++ int src_y, ++ int dst_x, ++ int dst_y, ++ int width, ++ int height, ++ GError **error); ++ + G_END_DECLS + + #endif /* __COGL_FRAMEBUFFER_H */ +-- +2.21.0 + diff --git a/SOURCES/0008-clutter-stage-view-Use-cogl_blit_framebuffer-for-sha.patch b/SOURCES/0008-clutter-stage-view-Use-cogl_blit_framebuffer-for-sha.patch new file mode 100644 index 0000000..09e8db9 --- /dev/null +++ b/SOURCES/0008-clutter-stage-view-Use-cogl_blit_framebuffer-for-sha.patch @@ -0,0 +1,42 @@ +From bbeb161e8ab31bbef3c7d378e9a8d4ecc786c25d Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Thu, 26 Sep 2019 10:20:36 +0200 +Subject: [PATCH 08/12] clutter/stage-view: Use cogl_blit_framebuffer() for + shadow FB + +If there is no transformation, use `cogl_blit_framebuffer()` as a +shortcut in `clutter_stage_view_blit_offscreen()`, that dramatically +improves performance when using a shadow framebuffer. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/809 +(cherry picked from commit 3400c555a032832a689c208486891352a6cb92de) +--- + clutter/clutter/clutter-stage-view.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c +index cd6cd35cb..00cbfd1ce 100644 +--- a/clutter/clutter/clutter-stage-view.c ++++ b/clutter/clutter/clutter-stage-view.c +@@ -126,6 +126,18 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view, + clutter_stage_view_get_instance_private (view); + CoglMatrix matrix; + ++ clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); ++ if (cogl_matrix_is_identity (&matrix)) ++ { ++ if (cogl_blit_framebuffer (priv->offscreen, ++ priv->framebuffer, ++ rect->x, rect->y, ++ rect->x, rect->y, ++ rect->width, rect->height, ++ NULL)) ++ return; ++ } ++ + clutter_stage_view_ensure_offscreen_blit_pipeline (view); + cogl_framebuffer_push_matrix (priv->framebuffer); + +-- +2.21.0 + diff --git a/SOURCES/0009-clutter-stage-view-Ignore-clipping-rectangle-for-off.patch b/SOURCES/0009-clutter-stage-view-Ignore-clipping-rectangle-for-off.patch new file mode 100644 index 0000000..ea67449 --- /dev/null +++ b/SOURCES/0009-clutter-stage-view-Ignore-clipping-rectangle-for-off.patch @@ -0,0 +1,49 @@ +From 46bb54bcd9c90f90dd170355209f8c379680d5c1 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 1 Oct 2019 14:16:25 +0200 +Subject: [PATCH 09/12] clutter/stage-view: Ignore clipping rectangle for + offscreen blit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In `clutter_stage_view_blit_offscreen()`, the given clipping rectangle +is in “view” coordinates whereas we intend to copy the whole actual +framebuffer, meaning that we cannot use the clipping rectangle. + +Use the actual framebuffer size, starting at (0, 0) instead. + +That fixes the issue with partial repainting with shadow framebuffer +when fractional scaling is enabled. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/820 +(cherry picked from commit 0a3f25c3039b586f5b5721e91136c5d2fccecca1) +--- + clutter/clutter/clutter-stage-view.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c +index 00cbfd1ce..503c31e78 100644 +--- a/clutter/clutter/clutter-stage-view.c ++++ b/clutter/clutter/clutter-stage-view.c +@@ -129,11 +129,14 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view, + clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); + if (cogl_matrix_is_identity (&matrix)) + { ++ int fb_width = cogl_framebuffer_get_width (priv->framebuffer); ++ int fb_height = cogl_framebuffer_get_height (priv->framebuffer); ++ + if (cogl_blit_framebuffer (priv->offscreen, + priv->framebuffer, +- rect->x, rect->y, +- rect->x, rect->y, +- rect->width, rect->height, ++ 0, 0, ++ 0, 0, ++ fb_width, fb_height, + NULL)) + return; + } +-- +2.21.0 + diff --git a/SOURCES/0010-cogl-Flush-journal-before-blitting.patch b/SOURCES/0010-cogl-Flush-journal-before-blitting.patch new file mode 100644 index 0000000..f3935eb --- /dev/null +++ b/SOURCES/0010-cogl-Flush-journal-before-blitting.patch @@ -0,0 +1,34 @@ +From 4c7fe200e05f9a028d440ed2032961d1b798c83b Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 1 Oct 2019 15:54:47 +0200 +Subject: [PATCH 10/12] cogl: Flush journal before blitting + +Make sure to submit all pending primitives before blitting, otherwise +rendering from the shell may be incomplete leaving partial drawing of +the shell widgets. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/820 +(cherry picked from commit 0cdf13ac12c570d38737fddb68946157c0b7a4d2) +--- + cogl/cogl/cogl-framebuffer.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c +index 6d35c6b13..948cd112d 100644 +--- a/cogl/cogl/cogl-framebuffer.c ++++ b/cogl/cogl/cogl-framebuffer.c +@@ -1482,6 +1482,11 @@ cogl_blit_framebuffer (CoglFramebuffer *src, + return FALSE; + } + ++ /* Make sure any batched primitives get submitted to the driver ++ * before blitting ++ */ ++ _cogl_framebuffer_flush_journal (src); ++ + /* Make sure the current framebuffers are bound. We explicitly avoid + flushing the clip state so we can bind our own empty state */ + _cogl_framebuffer_flush_state (dest, +-- +2.21.0 + diff --git a/SOURCES/0011-clutter-stage-view-Separate-offscreen-and-shadowfb.patch b/SOURCES/0011-clutter-stage-view-Separate-offscreen-and-shadowfb.patch new file mode 100644 index 0000000..9dd46a0 --- /dev/null +++ b/SOURCES/0011-clutter-stage-view-Separate-offscreen-and-shadowfb.patch @@ -0,0 +1,304 @@ +From cf8f1fb8478e4b76c91e825d1537396b014689a0 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 22 Oct 2019 17:03:03 +0200 +Subject: [PATCH 11/12] clutter/stage-view: Separate offscreen and shadowfb + +Previously, we would use a single offscreen framebuffer for both +transformations and when a shadow framebuffer should be used, but that +can be dreadfully slow when using software rendering with a discrete GPU +due to bandwidth limitations. + +Keep the offscreen framebuffer for transformations only and add another +intermediate shadow framebuffer used as a copy of the onscreen +framebuffer. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/917 + +(cherry picked from commit 2b8b450fe16c21f0f37a1779560c0e5da61a9b89) +--- + clutter/clutter/clutter-stage-view.c | 162 +++++++++++++++++----- + clutter/clutter/cogl/clutter-stage-cogl.c | 6 +- + 2 files changed, 128 insertions(+), 40 deletions(-) + +diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c +index 503c31e78..c536ac720 100644 +--- a/clutter/clutter/clutter-stage-view.c ++++ b/clutter/clutter/clutter-stage-view.c +@@ -29,6 +29,7 @@ enum + PROP_LAYOUT, + PROP_FRAMEBUFFER, + PROP_OFFSCREEN, ++ PROP_SHADOWFB, + PROP_SCALE, + + PROP_LAST +@@ -43,7 +44,10 @@ typedef struct _ClutterStageViewPrivate + CoglFramebuffer *framebuffer; + + CoglOffscreen *offscreen; +- CoglPipeline *pipeline; ++ CoglPipeline *offscreen_pipeline; ++ ++ CoglOffscreen *shadowfb; ++ CoglPipeline *shadowfb_pipeline; + + guint dirty_viewport : 1; + guint dirty_projection : 1; +@@ -69,6 +73,8 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view) + + if (priv->offscreen) + return priv->offscreen; ++ else if (priv->shadowfb) ++ return priv->shadowfb; + else + return priv->framebuffer; + } +@@ -82,6 +88,24 @@ clutter_stage_view_get_onscreen (ClutterStageView *view) + return priv->framebuffer; + } + ++static CoglPipeline * ++clutter_stage_view_create_framebuffer_pipeline (CoglFramebuffer *framebuffer) ++{ ++ CoglPipeline *pipeline; ++ ++ pipeline = cogl_pipeline_new (cogl_framebuffer_get_context (framebuffer)); ++ ++ cogl_pipeline_set_layer_filters (pipeline, 0, ++ COGL_PIPELINE_FILTER_NEAREST, ++ COGL_PIPELINE_FILTER_NEAREST); ++ cogl_pipeline_set_layer_texture (pipeline, 0, ++ cogl_offscreen_get_texture (framebuffer)); ++ cogl_pipeline_set_layer_wrap_mode (pipeline, 0, ++ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); ++ ++ return pipeline; ++} ++ + static void + clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) + { +@@ -92,71 +116,122 @@ clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) + + g_assert (priv->offscreen != NULL); + +- if (priv->pipeline) ++ if (priv->offscreen_pipeline) + return; + +- priv->pipeline = +- cogl_pipeline_new (cogl_framebuffer_get_context (priv->offscreen)); +- cogl_pipeline_set_layer_filters (priv->pipeline, 0, +- COGL_PIPELINE_FILTER_NEAREST, +- COGL_PIPELINE_FILTER_NEAREST); +- cogl_pipeline_set_layer_texture (priv->pipeline, 0, +- cogl_offscreen_get_texture (priv->offscreen)); +- cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, +- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); ++ priv->offscreen_pipeline = ++ clutter_stage_view_create_framebuffer_pipeline (priv->offscreen); + + if (view_class->setup_offscreen_blit_pipeline) +- view_class->setup_offscreen_blit_pipeline (view, priv->pipeline); ++ view_class->setup_offscreen_blit_pipeline (view, priv->offscreen_pipeline); + } + +-void +-clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) ++static void ++clutter_stage_view_ensure_shadowfb_blit_pipeline (ClutterStageView *view) + { + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + +- g_clear_pointer (&priv->pipeline, cogl_object_unref); ++ if (priv->shadowfb_pipeline) ++ return; ++ ++ priv->shadowfb_pipeline = ++ clutter_stage_view_create_framebuffer_pipeline (priv->shadowfb); + } + + void +-clutter_stage_view_blit_offscreen (ClutterStageView *view, +- const cairo_rectangle_int_t *rect) ++clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) + { + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); ++ ++ g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); ++} ++ ++static void ++clutter_stage_view_copy_to_framebuffer (ClutterStageView *view, ++ const cairo_rectangle_int_t *rect, ++ CoglPipeline *pipeline, ++ CoglFramebuffer *src_framebuffer, ++ CoglFramebuffer *dst_framebuffer, ++ gboolean can_blit) ++{ + CoglMatrix matrix; + +- clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); +- if (cogl_matrix_is_identity (&matrix)) ++ /* First, try with blit */ ++ if (can_blit) + { +- int fb_width = cogl_framebuffer_get_width (priv->framebuffer); +- int fb_height = cogl_framebuffer_get_height (priv->framebuffer); +- +- if (cogl_blit_framebuffer (priv->offscreen, +- priv->framebuffer, ++ if (cogl_blit_framebuffer (src_framebuffer, ++ dst_framebuffer, + 0, 0, + 0, 0, +- fb_width, fb_height, ++ cogl_framebuffer_get_width (dst_framebuffer), ++ cogl_framebuffer_get_height (dst_framebuffer), + NULL)) + return; + } + +- clutter_stage_view_ensure_offscreen_blit_pipeline (view); +- cogl_framebuffer_push_matrix (priv->framebuffer); ++ /* If blit fails, fallback to the slower painting method */ ++ cogl_framebuffer_push_matrix (dst_framebuffer); + +- /* Set transform so 0,0 is on the top left corner and 1,1 on +- * the bottom right corner. +- */ + cogl_matrix_init_identity (&matrix); + cogl_matrix_translate (&matrix, -1, 1, 0); + cogl_matrix_scale (&matrix, 2, -2, 0); +- cogl_framebuffer_set_projection_matrix (priv->framebuffer, &matrix); ++ cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix); + +- cogl_framebuffer_draw_rectangle (priv->framebuffer, +- priv->pipeline, ++ cogl_framebuffer_draw_rectangle (dst_framebuffer, ++ pipeline, + 0, 0, 1, 1); + +- cogl_framebuffer_pop_matrix (priv->framebuffer); ++ cogl_framebuffer_pop_matrix (dst_framebuffer); ++} ++ ++void ++clutter_stage_view_blit_offscreen (ClutterStageView *view, ++ const cairo_rectangle_int_t *rect) ++{ ++ ClutterStageViewPrivate *priv = ++ clutter_stage_view_get_instance_private (view); ++ ++ if (priv->offscreen) ++ { ++ gboolean can_blit; ++ CoglMatrix matrix; ++ ++ clutter_stage_view_ensure_offscreen_blit_pipeline (view); ++ clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); ++ can_blit = cogl_matrix_is_identity (&matrix); ++ ++ if (priv->shadowfb) ++ { ++ clutter_stage_view_copy_to_framebuffer (view, ++ rect, ++ priv->offscreen_pipeline, ++ priv->offscreen, ++ priv->shadowfb, ++ can_blit); ++ } ++ else ++ { ++ clutter_stage_view_copy_to_framebuffer (view, ++ rect, ++ priv->offscreen_pipeline, ++ priv->offscreen, ++ priv->framebuffer, ++ can_blit); ++ } ++ } ++ ++ if (priv->shadowfb) ++ { ++ clutter_stage_view_ensure_shadowfb_blit_pipeline (view); ++ clutter_stage_view_copy_to_framebuffer (view, ++ rect, ++ priv->shadowfb_pipeline, ++ priv->shadowfb, ++ priv->framebuffer, ++ TRUE); ++ } + } + + float +@@ -256,6 +331,9 @@ clutter_stage_view_get_property (GObject *object, + case PROP_OFFSCREEN: + g_value_set_boxed (value, priv->offscreen); + break; ++ case PROP_SHADOWFB: ++ g_value_set_boxed (value, priv->shadowfb); ++ break; + case PROP_SCALE: + g_value_set_float (value, priv->scale); + break; +@@ -301,6 +379,9 @@ clutter_stage_view_set_property (GObject *object, + case PROP_OFFSCREEN: + priv->offscreen = g_value_dup_boxed (value); + break; ++ case PROP_SHADOWFB: ++ priv->shadowfb = g_value_dup_boxed (value); ++ break; + case PROP_SCALE: + priv->scale = g_value_get_float (value); + break; +@@ -317,8 +398,10 @@ clutter_stage_view_dispose (GObject *object) + clutter_stage_view_get_instance_private (view); + + g_clear_pointer (&priv->framebuffer, cogl_object_unref); ++ g_clear_pointer (&priv->shadowfb, cogl_object_unref); + g_clear_pointer (&priv->offscreen, cogl_object_unref); +- g_clear_pointer (&priv->pipeline, cogl_object_unref); ++ g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); ++ g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref); + + G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object); + } +@@ -373,6 +456,15 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass) + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + ++ obj_props[PROP_SHADOWFB] = ++ g_param_spec_boxed ("shadowfb", ++ "Shadow framebuffer", ++ "Framebuffer used as intermediate shadow buffer", ++ COGL_TYPE_HANDLE, ++ G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS); ++ + obj_props[PROP_SCALE] = + g_param_spec_float ("scale", + "View scale", +diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c +index e0c39185b..eab76e52f 100644 +--- a/clutter/clutter/cogl/clutter-stage-cogl.c ++++ b/clutter/clutter/cogl/clutter-stage-cogl.c +@@ -477,11 +477,7 @@ paint_stage (ClutterStageCogl *stage_cogl, + _clutter_stage_maybe_setup_viewport (stage, view); + _clutter_stage_paint_view (stage, view, clip); + +- if (clutter_stage_view_get_onscreen (view) != +- clutter_stage_view_get_framebuffer (view)) +- { +- clutter_stage_view_blit_offscreen (view, clip); +- } ++ clutter_stage_view_blit_offscreen (view, clip); + } + + static void +-- +2.21.0 + diff --git a/SOURCES/0012-renderer-native-Separate-offscreen-and-shadowfb.patch b/SOURCES/0012-renderer-native-Separate-offscreen-and-shadowfb.patch new file mode 100644 index 0000000..cd748a9 --- /dev/null +++ b/SOURCES/0012-renderer-native-Separate-offscreen-and-shadowfb.patch @@ -0,0 +1,98 @@ +From ca3e9e3b3b84fe95affbe5485212c6ecfa1a4b51 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 22 Oct 2019 17:05:46 +0200 +Subject: [PATCH 12/12] renderer-native: Separate offscreen and shadowfb + +Create the intermediate shadow framebuffer for use exclusively when a +shadowfb is required. + +Keep the previous offscreen framebuffer is as an intermediate +framebuffer for transformations only. + +This way, we can apply transformations between in-memory framebuffers +prior to blit the result to screen, and achieve acceptable performance +even with software rendering on discrete GPU. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/917 + +(cherry picked from commit 551641c74822ca2e3c685e49603836ebf5397df2) +--- + src/backends/native/meta-renderer-native.c | 29 ++++++++++++++++++---- + 1 file changed, 24 insertions(+), 5 deletions(-) + +diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c +index 3cd01bcb7..ffb64a6bd 100644 +--- a/src/backends/native/meta-renderer-native.c ++++ b/src/backends/native/meta-renderer-native.c +@@ -3287,7 +3287,6 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, + static CoglOffscreen * + meta_renderer_native_create_offscreen (MetaRendererNative *renderer, + CoglContext *context, +- MetaMonitorTransform transform, + gint view_width, + gint view_height, + GError **error) +@@ -3489,6 +3488,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer, + MetaMonitorTransform view_transform; + CoglOnscreen *onscreen = NULL; + CoglOffscreen *offscreen = NULL; ++ CoglOffscreen *shadowfb = NULL; + float scale; + int width, height; + MetaRendererView *view; +@@ -3515,18 +3515,35 @@ meta_renderer_native_create_view (MetaRenderer *renderer, + if (!onscreen) + g_error ("Failed to allocate onscreen framebuffer: %s", error->message); + +- if (view_transform != META_MONITOR_TRANSFORM_NORMAL || +- should_force_shadow_fb (renderer_native, +- renderer_native->primary_gpu_kms)) ++ if (view_transform != META_MONITOR_TRANSFORM_NORMAL) + { + offscreen = meta_renderer_native_create_offscreen (renderer_native, + cogl_context, +- view_transform, + width, + height, + &error); + if (!offscreen) + g_error ("Failed to allocate back buffer texture: %s", error->message); ++ ++ } ++ ++ if (should_force_shadow_fb (renderer_native, ++ renderer_native->primary_gpu_kms)) ++ { ++ int shadow_width; ++ int shadow_height; ++ ++ /* The shadowfb must be the same size as the on-screen framebuffer */ ++ shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen)); ++ shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen)); ++ ++ shadowfb = meta_renderer_native_create_offscreen (renderer_native, ++ cogl_context, ++ shadow_width, ++ shadow_height, ++ &error); ++ if (!shadowfb) ++ g_error ("Failed to allocate shadow buffer texture: %s", error->message); + } + + view = g_object_new (META_TYPE_RENDERER_VIEW, +@@ -3534,10 +3551,12 @@ meta_renderer_native_create_view (MetaRenderer *renderer, + "scale", scale, + "framebuffer", onscreen, + "offscreen", offscreen, ++ "shadowfb", shadowfb, + "logical-monitor", logical_monitor, + "transform", view_transform, + NULL); + g_clear_pointer (&offscreen, cogl_object_unref); ++ g_clear_pointer (&shadowfb, cogl_object_unref); + + meta_onscreen_native_set_view (onscreen, view); + +-- +2.21.0 + diff --git a/SOURCES/add-support-for-plain-old-x-device-configuration.patch b/SOURCES/add-support-for-plain-old-x-device-configuration.patch index 53813c1..beefaf2 100644 --- a/SOURCES/add-support-for-plain-old-x-device-configuration.patch +++ b/SOURCES/add-support-for-plain-old-x-device-configuration.patch @@ -352,7 +352,7 @@ index 12a592c75..80e5ed10e 100644 g_object_unref (settings); return; } -+ else if (!is_device_libinput (device)) ++ else if (!is_device_libinput (device) && device_type != CLUTTER_PAD_DEVICE) + { + change_x_device_left_handed (device, enabled); + return; diff --git a/SOURCES/idle-monitor-reset-fix.patch b/SOURCES/idle-monitor-reset-fix.patch new file mode 100644 index 0000000..b67e015 --- /dev/null +++ b/SOURCES/idle-monitor-reset-fix.patch @@ -0,0 +1,128 @@ +From 35333114a991440d671e3642170aa080df45a171 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 16 Sep 2019 16:17:48 +0200 +Subject: [PATCH 1/3] idle-monitor: Make helper function static + +It wasn't used outside the file, so no reason to not have it static. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/799 +--- + src/backends/meta-idle-monitor-private.h | 1 - + src/backends/meta-idle-monitor.c | 8 ++++---- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/backends/meta-idle-monitor-private.h b/src/backends/meta-idle-monitor-private.h +index 93948b14b..cc08f8c8e 100644 +--- a/src/backends/meta-idle-monitor-private.h ++++ b/src/backends/meta-idle-monitor-private.h +@@ -54,7 +54,6 @@ struct _MetaIdleMonitorClass + GObjectClass parent_class; + }; + +-void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch); + void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor); + + #endif /* META_IDLE_MONITOR_PRIVATE_H */ +diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c +index e83d6c778..de1c7e0ba 100644 +--- a/src/backends/meta-idle-monitor.c ++++ b/src/backends/meta-idle-monitor.c +@@ -54,8 +54,8 @@ static GParamSpec *obj_props[PROP_LAST]; + + G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) + +-void +-_meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) ++static void ++meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) + { + MetaIdleMonitor *monitor; + guint id; +@@ -324,7 +324,7 @@ idle_monitor_dispatch_timeout (GSource *source, + if (ready_time > now) + return G_SOURCE_CONTINUE; + +- _meta_idle_monitor_watch_fire (watch); ++ meta_idle_monitor_watch_fire (watch); + g_source_set_ready_time (watch->timeout_source, -1); + + return G_SOURCE_CONTINUE; +@@ -511,7 +511,7 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) + + if (watch->timeout_msec == 0) + { +- _meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch); ++ meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch); + } + else + { +-- +2.23.0 + + +From 07276cf94d84489d450c17b7dec5a8075c60440a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 16 Sep 2019 16:36:05 +0200 +Subject: [PATCH 2/3] idle-monitor: Remove redundant type cast + +No need to type cast a `MetaIdleMonitorWatch *` to a +`MetaIdleMonitorWatch *`. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/799 +--- + src/backends/meta-idle-monitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c +index de1c7e0ba..e5124abc1 100644 +--- a/src/backends/meta-idle-monitor.c ++++ b/src/backends/meta-idle-monitor.c +@@ -511,7 +511,7 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) + + if (watch->timeout_msec == 0) + { +- meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch); ++ meta_idle_monitor_watch_fire (watch); + } + else + { +-- +2.23.0 + + +From 73c1f387765ef528c7323e6e7ca3c05899cfcc4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 16 Sep 2019 16:36:51 +0200 +Subject: [PATCH 3/3] idle-monitor: Reset timeout before firing watch + +The watch might be removed during firing, meaning the source is +destroyed after returning. Avoid use-after-free by unsetting the timeout +before firing. Returning G_SOURCE_CONTINUE in that case is harmless, as +source is destroyed. + +Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/796 + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/799 +--- + src/backends/meta-idle-monitor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c +index e5124abc1..9fa481742 100644 +--- a/src/backends/meta-idle-monitor.c ++++ b/src/backends/meta-idle-monitor.c +@@ -324,9 +324,10 @@ idle_monitor_dispatch_timeout (GSource *source, + if (ready_time > now) + return G_SOURCE_CONTINUE; + +- meta_idle_monitor_watch_fire (watch); + g_source_set_ready_time (watch->timeout_source, -1); + ++ meta_idle_monitor_watch_fire (watch); ++ + return G_SOURCE_CONTINUE; + } + +-- +2.23.0 + diff --git a/SOURCES/inherit-xrandr-metamodes.patch b/SOURCES/inherit-xrandr-metamodes.patch new file mode 100644 index 0000000..9f3f6c9 --- /dev/null +++ b/SOURCES/inherit-xrandr-metamodes.patch @@ -0,0 +1,365 @@ +From 2fd3910c29d2af2a7c64b82f075cd3647d7e4bee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 18 Mar 2019 17:08:11 +0100 +Subject: [PATCH 1/2] monitor-config-manager: Use current mode when deriving + current config + +Instead of overriding the existing mode with the preferred mode of the monitor, +use the one already configured. Also use the MetaMonitor API for deriving the +position of the monitor in the screen coordinate space. +--- + src/backends/meta-monitor-config-manager.c | 77 +++++++++++++--------- + 1 file changed, 47 insertions(+), 30 deletions(-) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index c09edbe00..a3387aa0f 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -592,20 +592,19 @@ create_monitor_config (MetaMonitor *monitor, + } + + static MetaLogicalMonitorConfig * +-create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager, +- MetaMonitor *monitor, +- int x, +- int y, +- MetaLogicalMonitorConfig *primary_logical_monitor_config, +- MetaLogicalMonitorLayoutMode layout_mode) ++create_logical_monitor_config (MetaMonitorManager *monitor_manager, ++ MetaMonitor *monitor, ++ MetaMonitorMode *mode, ++ int x, ++ int y, ++ MetaLogicalMonitorConfig *primary_logical_monitor_config, ++ MetaLogicalMonitorLayoutMode layout_mode) + { +- MetaMonitorMode *mode; + int width, height; + float scale; + MetaMonitorConfig *monitor_config; + MetaLogicalMonitorConfig *logical_monitor_config; + +- mode = meta_monitor_get_preferred_mode (monitor); + meta_monitor_mode_get_resolution (mode, &width, &height); + + if ((meta_monitor_manager_get_capabilities (monitor_manager) & +@@ -645,22 +644,40 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma + } + + static MetaLogicalMonitorConfig * +-create_logical_monitor_config_from_output (MetaMonitorManager *monitor_manager, +- MetaMonitor *monitor, +- MetaLogicalMonitorConfig *primary_logical_monitor_config, +- MetaLogicalMonitorLayoutMode layout_mode) ++create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager, ++ MetaMonitor *monitor, ++ int x, ++ int y, ++ MetaLogicalMonitorConfig *primary_logical_monitor_config, ++ MetaLogicalMonitorLayoutMode layout_mode) + { +- MetaOutput *output; +- MetaCrtc *crtc; ++ return create_logical_monitor_config (monitor_manager, ++ monitor, ++ meta_monitor_get_preferred_mode (monitor), ++ x, y, ++ primary_logical_monitor_config, ++ layout_mode); ++} + +- output = meta_monitor_get_main_output (monitor); +- crtc = meta_output_get_assigned_crtc (output); +- return create_preferred_logical_monitor_config (monitor_manager, +- monitor, +- crtc->rect.x, +- crtc->rect.y, +- primary_logical_monitor_config, +- layout_mode); ++static MetaLogicalMonitorConfig * ++create_logical_monitor_config_from_monitor (MetaMonitorManager *monitor_manager, ++ MetaMonitor *monitor, ++ MetaLogicalMonitorConfig *primary_logical_monitor_config, ++ MetaLogicalMonitorLayoutMode layout_mode) ++{ ++ MetaRectangle monitor_layout; ++ MetaMonitorMode *mode; ++ ++ meta_monitor_derive_layout (monitor, &monitor_layout); ++ mode = meta_monitor_get_current_mode (monitor); ++ ++ return create_logical_monitor_config (monitor_manager, ++ monitor, ++ mode, ++ monitor_layout.x, ++ monitor_layout.y, ++ primary_logical_monitor_config, ++ layout_mode); + } + + MetaMonitorsConfig * +@@ -688,10 +705,10 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + primary_logical_monitor_config = +- create_logical_monitor_config_from_output (monitor_manager, +- primary_monitor, +- NULL, +- layout_mode); ++ create_logical_monitor_config_from_monitor (monitor_manager, ++ primary_monitor, ++ NULL, ++ layout_mode); + + primary_logical_monitor_config->is_primary = TRUE; + logical_monitor_configs = g_list_append (NULL, +@@ -710,10 +727,10 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man + continue; + + logical_monitor_config = +- create_logical_monitor_config_from_output (monitor_manager, +- monitor, +- primary_logical_monitor_config, +- layout_mode); ++ create_logical_monitor_config_from_monitor (monitor_manager, ++ monitor, ++ primary_logical_monitor_config, ++ layout_mode); + + logical_monitor_configs = g_list_append (logical_monitor_configs, + logical_monitor_config); +-- +2.21.0 + + +From d8c34e4cd7e500567e72e0f219295d7c2162dcf3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 18 Mar 2019 17:10:37 +0100 +Subject: [PATCH 2/2] monitor-manager: Don't try to derive current config on + non-X11 + +This commit also reworks the initial config state reading some. Appart from +avoiding trying to inherit from backends where it doesn't make sense, it does +the following changes: + + * Replace the name "initial" with "inherited", as the initial config in the + context of monitor management is the one used initialization. E.g. if there is + a applicable configuration in monitors.xml, the initial config is taken from + there. + + * Don't make "_create_()" functions have side effects. Previously + meta_monitor_config_manager_create_initial() also set state on the config + manager object. Instead, add a meta_monitor_config_manager_ensure_inherited() + and meta_monitor_manager_get_inherited_config() function to make things more + explicit. + + * Don't recreate "is-applicable" logic, just use the existing helper. +--- + src/backends/meta-monitor-config-manager.c | 39 +++++++++++-------- + src/backends/meta-monitor-config-manager.h | 5 +++ + src/backends/meta-monitor-manager-private.h | 4 +- + src/backends/meta-monitor-manager.c | 32 ++++++++------- + .../x11/meta-monitor-manager-xrandr.c | 3 +- + 5 files changed, 49 insertions(+), 34 deletions(-) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index a3387aa0f..bc1a39db8 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -42,7 +42,7 @@ struct _MetaMonitorConfigManager + MetaMonitorConfigStore *config_store; + + MetaMonitorsConfig *current_config; +- MetaMonitorsConfig *initial_config; ++ MetaMonitorsConfig *inherited_config; + GQueue config_history; + }; + +@@ -680,11 +680,10 @@ create_logical_monitor_config_from_monitor (MetaMonitorManager *monito + layout_mode); + } + +-MetaMonitorsConfig * +-meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager) ++static MetaMonitorsConfig * ++meta_monitor_config_manager_derive_current (MetaMonitorConfigManager *config_manager) + { + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; +- MetaMonitorsConfig *initial_config; + GList *logical_monitor_configs; + MetaMonitor *primary_monitor; + MetaLogicalMonitorLayoutMode layout_mode; +@@ -692,12 +691,6 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man + GList *monitors; + GList *l; + +- if (config_manager->initial_config != NULL) +- return g_object_ref (config_manager->initial_config); +- +- if (meta_monitor_config_store_get_config_count (config_manager->config_store) > 0) +- return NULL; +- + primary_monitor = find_primary_monitor (monitor_manager); + if (!primary_monitor || !meta_monitor_is_active (primary_monitor)) + return NULL; +@@ -736,14 +729,26 @@ meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_man + logical_monitor_config); + } + +- initial_config = meta_monitors_config_new (monitor_manager, +- logical_monitor_configs, +- layout_mode, +- META_MONITORS_CONFIG_FLAG_NONE); ++ return meta_monitors_config_new (monitor_manager, ++ logical_monitor_configs, ++ layout_mode, ++ META_MONITORS_CONFIG_FLAG_NONE); ++} ++ ++void ++meta_monitor_config_manager_ensure_inherited_config (MetaMonitorConfigManager *config_manager) ++{ ++ if (config_manager->inherited_config) ++ return; + +- config_manager->initial_config = g_object_ref (initial_config); ++ config_manager->inherited_config = ++ meta_monitor_config_manager_derive_current (config_manager); ++} + +- return initial_config; ++MetaMonitorsConfig * ++meta_monitor_config_manager_get_inherited_config (MetaMonitorConfigManager *config_manager) ++{ ++ return config_manager->inherited_config; + } + + MetaMonitorsConfig * +@@ -1282,7 +1287,7 @@ meta_monitor_config_manager_dispose (GObject *object) + META_MONITOR_CONFIG_MANAGER (object); + + g_clear_object (&config_manager->current_config); +- g_clear_object (&config_manager->initial_config); ++ g_clear_object (&config_manager->inherited_config); + meta_monitor_config_manager_clear_history (config_manager); + + G_OBJECT_CLASS (meta_monitor_config_manager_parent_class)->dispose (object); +diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h +index 409611bb0..bb847b96e 100644 +--- a/src/backends/meta-monitor-config-manager.h ++++ b/src/backends/meta-monitor-config-manager.h +@@ -96,6 +96,11 @@ MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigMa + + META_EXPORT_TEST + MetaMonitorsConfig * meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager); ++ ++void meta_monitor_config_manager_ensure_inherited_config (MetaMonitorConfigManager *config_manager); ++ ++MetaMonitorsConfig * meta_monitor_config_manager_get_inherited_config (MetaMonitorConfigManager *config_manager); ++ + META_EXPORT_TEST + MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager); + +diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h +index cdb8f4209..223b5dfbd 100644 +--- a/src/backends/meta-monitor-manager-private.h ++++ b/src/backends/meta-monitor-manager-private.h +@@ -44,7 +44,8 @@ typedef enum _MetaMonitorManagerCapability + META_MONITOR_MANAGER_CAPABILITY_NONE = 0, + META_MONITOR_MANAGER_CAPABILITY_MIRRORING = (1 << 0), + META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 1), +- META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 2) ++ META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 2), ++ META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT = (1 << 3), + } MetaMonitorManagerCapability; + + /* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */ +@@ -133,6 +134,7 @@ struct _MetaMonitorManager + int persistent_timeout_id; + + MetaMonitorConfigManager *config_manager; ++ MetaMonitorsConfig *initial_config; + + GnomePnpIds *pnp_ids; + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index bb4b44188..076dca8cb 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -531,14 +531,21 @@ should_use_stored_config (MetaMonitorManager *manager) + !meta_monitor_manager_has_hotplug_mode_update (manager)); + } + ++static gboolean ++can_derive_current_config (MetaMonitorManager *manager) ++{ ++ MetaMonitorManagerCapability capabilities; ++ ++ capabilities = meta_monitor_manager_get_capabilities (manager); ++ return !!(capabilities & META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT); ++} ++ + MetaMonitorsConfig * + meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) + { +- g_autoptr (MetaMonitorsConfig) initial_config = NULL; + MetaMonitorsConfig *config = NULL; + GError *error = NULL; + gboolean use_stored_config; +- MetaMonitorsConfigKey *current_state_key; + MetaMonitorsConfigMethod method; + MetaMonitorsConfigMethod fallback_method = + META_MONITORS_CONFIG_METHOD_TEMPORARY; +@@ -549,17 +556,8 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) + else + method = META_MONITORS_CONFIG_METHOD_TEMPORARY; + +- initial_config = meta_monitor_config_manager_create_initial (manager->config_manager); +- +- if (initial_config) +- { +- current_state_key = meta_create_monitors_config_key_for_current_state (manager); +- +- /* don't ever reuse initial configuration, if the monitor topology changed +- */ +- if (current_state_key && !meta_monitors_config_key_equal (current_state_key, initial_config->key)) +- g_clear_object (&initial_config); +- } ++ if (can_derive_current_config (manager)) ++ meta_monitor_config_manager_ensure_inherited_config (manager->config_manager); + + if (use_stored_config) + { +@@ -628,9 +626,13 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) + g_clear_object (&config); + } + +- config = g_steal_pointer (&initial_config); +- if (config) ++ config = ++ meta_monitor_config_manager_get_inherited_config (manager->config_manager); ++ if (config && ++ meta_monitor_manager_is_config_complete (manager, config)) + { ++ config = g_object_ref (config); ++ + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + method, +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index d60f00325..b8d6342b6 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -999,7 +999,8 @@ static MetaMonitorManagerCapability + meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager) + { + return (META_MONITOR_MANAGER_CAPABILITY_MIRRORING | +- META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED); ++ META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED | ++ META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT); + } + + static gboolean +-- +2.21.0 + diff --git a/SOURCES/input-after-long-idle-fix.patch b/SOURCES/input-after-long-idle-fix.patch new file mode 100644 index 0000000..9c4c2a6 --- /dev/null +++ b/SOURCES/input-after-long-idle-fix.patch @@ -0,0 +1,374 @@ +From 05bca153bb92c5daa5b961214ff7f80af88cb7cf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Thu, 24 Oct 2019 21:19:36 +0200 +Subject: [PATCH 1/2] display: Move finishing of touch sequence to the backend + +We need to manipulate an X11 grab when a touch sequence ends; move that +logic to where it belongs - in the X11 backend. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/886 +--- + src/backends/meta-backend-private.h | 16 ++++++++++++ + src/backends/meta-backend.c | 14 +++++++++++ + src/backends/x11/meta-backend-x11.c | 23 +++++++++++++++++ + src/core/display.c | 33 +++++++++++-------------- + src/core/meta-gesture-tracker-private.h | 9 +------ + 5 files changed, 69 insertions(+), 26 deletions(-) + +diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h +index 7eba1806b..81ec81e5f 100644 +--- a/src/backends/meta-backend-private.h ++++ b/src/backends/meta-backend-private.h +@@ -49,6 +49,14 @@ + #define DEFAULT_XKB_RULES_FILE "evdev" + #define DEFAULT_XKB_MODEL "pc105+inet" + ++typedef enum ++{ ++ META_SEQUENCE_NONE, ++ META_SEQUENCE_ACCEPTED, ++ META_SEQUENCE_REJECTED, ++ META_SEQUENCE_PENDING_END ++} MetaSequenceState; ++ + struct _MetaBackendClass + { + GObjectClass parent_class; +@@ -71,6 +79,10 @@ struct _MetaBackendClass + int device_id, + uint32_t timestamp); + ++ void (* finish_touch_sequence) (MetaBackend *backend, ++ ClutterEventSequence *sequence, ++ MetaSequenceState state); ++ + void (* warp_pointer) (MetaBackend *backend, + int x, + int y); +@@ -135,6 +147,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp); + ++void meta_backend_finish_touch_sequence (MetaBackend *backend, ++ ClutterEventSequence *sequence, ++ MetaSequenceState state); ++ + void meta_backend_warp_pointer (MetaBackend *backend, + int x, + int y); +diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c +index c980cf150..bb7d66f2a 100644 +--- a/src/backends/meta-backend.c ++++ b/src/backends/meta-backend.c +@@ -1086,6 +1086,20 @@ meta_backend_ungrab_device (MetaBackend *backend, + return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp); + } + ++/** ++ * meta_backend_finish_touch_sequence: (skip) ++ */ ++void ++meta_backend_finish_touch_sequence (MetaBackend *backend, ++ ClutterEventSequence *sequence, ++ MetaSequenceState state) ++{ ++ if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence) ++ META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend, ++ sequence, ++ state); ++} ++ + /** + * meta_backend_warp_pointer: (skip) + */ +diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c +index c10365f9d..cdefa50a9 100644 +--- a/src/backends/x11/meta-backend-x11.c ++++ b/src/backends/x11/meta-backend-x11.c +@@ -591,6 +591,28 @@ meta_backend_x11_ungrab_device (MetaBackend *backend, + return (ret == Success); + } + ++static void ++meta_backend_x11_finish_touch_sequence (MetaBackend *backend, ++ ClutterEventSequence *sequence, ++ MetaSequenceState state) ++{ ++ MetaBackendX11 *x11 = META_BACKEND_X11 (backend); ++ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); ++ int event_mode; ++ ++ if (state == META_SEQUENCE_ACCEPTED) ++ event_mode = XIAcceptTouch; ++ else if (state == META_SEQUENCE_REJECTED) ++ event_mode = XIRejectTouch; ++ else ++ g_return_if_reached (); ++ ++ XIAllowTouchEvents (priv->xdisplay, ++ META_VIRTUAL_CORE_POINTER_ID, ++ clutter_x11_event_sequence_get_touch_detail (sequence), ++ DefaultRootWindow (priv->xdisplay), event_mode); ++} ++ + static void + meta_backend_x11_warp_pointer (MetaBackend *backend, + int x, +@@ -776,6 +798,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass) + backend_class->post_init = meta_backend_x11_post_init; + backend_class->grab_device = meta_backend_x11_grab_device; + backend_class->ungrab_device = meta_backend_x11_ungrab_device; ++ backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence; + backend_class->warp_pointer = meta_backend_x11_warp_pointer; + backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor; + backend_class->get_keymap = meta_backend_x11_get_keymap; +diff --git a/src/core/display.c b/src/core/display.c +index 4c8907f40..eb7dc43b6 100644 +--- a/src/core/display.c ++++ b/src/core/display.c +@@ -42,6 +42,7 @@ + #include + #include + ++#include "backends/meta-backend-private.h" + #include "backends/meta-cursor-sprite-xcursor.h" + #include "backends/meta-cursor-tracker-private.h" + #include "backends/meta-idle-monitor-dbus.h" +@@ -598,27 +599,23 @@ gesture_tracker_state_changed (MetaGestureTracker *tracker, + MetaSequenceState state, + MetaDisplay *display) + { +- if (meta_is_wayland_compositor ()) ++ switch (state) + { +- if (state == META_SEQUENCE_ACCEPTED) +- meta_display_cancel_touch (display); +- } +- else +- { +- MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); +- int event_mode; ++ case META_SEQUENCE_NONE: ++ case META_SEQUENCE_PENDING_END: ++ return; ++ case META_SEQUENCE_ACCEPTED: ++ meta_display_cancel_touch (display); + +- if (state == META_SEQUENCE_ACCEPTED) +- event_mode = XIAcceptTouch; +- else if (state == META_SEQUENCE_REJECTED) +- event_mode = XIRejectTouch; +- else +- return; ++ /* Intentional fall-through */ ++ case META_SEQUENCE_REJECTED: ++ { ++ MetaBackend *backend; + +- XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend), +- META_VIRTUAL_CORE_POINTER_ID, +- clutter_x11_event_sequence_get_touch_detail (sequence), +- DefaultRootWindow (display->x11_display->xdisplay), event_mode); ++ backend = meta_get_backend (); ++ meta_backend_finish_touch_sequence (backend, sequence, state); ++ break; ++ } + } + } + +diff --git a/src/core/meta-gesture-tracker-private.h b/src/core/meta-gesture-tracker-private.h +index a9db35ebc..e7bfc5472 100644 +--- a/src/core/meta-gesture-tracker-private.h ++++ b/src/core/meta-gesture-tracker-private.h +@@ -26,6 +26,7 @@ + + #include + ++#include "backends/meta-backend-private.h" + #include "clutter/clutter.h" + #include "meta/window.h" + +@@ -39,14 +40,6 @@ + typedef struct _MetaGestureTracker MetaGestureTracker; + typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass; + +-typedef enum +-{ +- META_SEQUENCE_NONE, +- META_SEQUENCE_ACCEPTED, +- META_SEQUENCE_REJECTED, +- META_SEQUENCE_PENDING_END +-} MetaSequenceState; +- + struct _MetaGestureTracker + { + GObject parent_instance; +-- +2.23.0 + + +From 8cf4f500defb421d5c96f2c1f9fcf7bb5545d70d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Fri, 25 Oct 2019 10:06:55 +0200 +Subject: [PATCH 2/2] x11: Limit touch replay pointer events to when replaying + +When a touch sequence was rejected, the emulated pointer events would be +replayed with old timestamps. This caused issues with grabs as they +would be ignored due to being too old. This was mitigated by making sure +device event timestamps never travelled back in time by tampering with +any event that had a timestamp seemingly in the past. + +This failed when the most recent timestamp that had been received were +much older than the timestamp of the new event. This could for example +happen when a session was left not interacted with for 40+ days or so; +when interacted with again, as any new timestamp would according to +XSERVER_TIME_IS_BEFORE() still be in the past compared to the "most +recent" one. The effect is that we'd always use the `latest_evtime` for +all new device events without ever updating it. + +The end result of this was that passive grabs would become active when +interacted with, but would then newer be released, as the timestamps to +XIAllowEvents() would out of date, resulting in the desktop effectively +freezing, as the Shell would have an active pointer grab. + +To avoid the situation where we get stuck with an old `latest_evtime` +timestamp, limit the tampering with device event timestamp to 1) only +pointer events, and 2) only during the replay sequence. The second part +is implemented by sending an asynchronous message via the X server after +rejecting a touch sequence, only potentially tampering with the device +event timestamps until the reply. This should avoid the stuck timestamp +as in those situations, we'll always have a relatively up to date +`latest_evtime` meaning XSERVER_TIME_IS_BEFORE() will not get confused. + +https://gitlab.gnome.org/GNOME/mutter/merge_requests/886 +--- + src/backends/x11/meta-backend-x11.c | 71 +++++++++++++++++++++++------ + 1 file changed, 58 insertions(+), 13 deletions(-) + +diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c +index cdefa50a9..821b30f5b 100644 +--- a/src/backends/x11/meta-backend-x11.c ++++ b/src/backends/x11/meta-backend-x11.c +@@ -66,6 +66,10 @@ struct _MetaBackendX11Private + XSyncAlarm user_active_alarm; + XSyncCounter counter; + ++ int current_touch_replay_sync_serial; ++ int pending_touch_replay_sync_serial; ++ Atom touch_replay_sync_atom; ++ + int xinput_opcode; + int xinput_event_base; + int xinput_error_base; +@@ -174,6 +178,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11, + backend_x11_class->translate_device_event (x11, device_event); + } + ++static void ++maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11, ++ XIDeviceEvent *device_event) ++{ ++ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); ++ ++ if (!device_event->send_event && ++ device_event->time != META_CURRENT_TIME && ++ priv->current_touch_replay_sync_serial != ++ priv->pending_touch_replay_sync_serial && ++ XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime)) ++ { ++ /* Emulated pointer events received after XIRejectTouch is received ++ * on a passive touch grab will contain older timestamps, update those ++ * so we dont get InvalidTime at grabs. ++ */ ++ device_event->time = priv->latest_evtime; ++ } ++} ++ + static void + translate_device_event (MetaBackendX11 *x11, + XIDeviceEvent *device_event) +@@ -183,19 +207,7 @@ translate_device_event (MetaBackendX11 *x11, + meta_backend_x11_translate_device_event (x11, device_event); + + if (!device_event->send_event && device_event->time != META_CURRENT_TIME) +- { +- if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime)) +- { +- /* Emulated pointer events received after XIRejectTouch is received +- * on a passive touch grab will contain older timestamps, update those +- * so we dont get InvalidTime at grabs. +- */ +- device_event->time = priv->latest_evtime; +- } +- +- /* Update the internal latest evtime, for any possible later use */ +- priv->latest_evtime = device_event->time; +- } ++ priv->latest_evtime = device_event->time; + } + + static void +@@ -260,6 +272,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11, + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: ++ maybe_translate_touch_replay_pointer_event (x11, ++ (XIDeviceEvent *) input_event); ++ /* Intentional fall-through */ + case XI_KeyPress: + case XI_KeyRelease: + case XI_TouchBegin: +@@ -327,6 +342,17 @@ handle_host_xevent (MetaBackend *backend, + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + gboolean bypass_clutter = FALSE; + ++ switch (event->type) ++ { ++ case ClientMessage: ++ if (event->xclient.window == meta_backend_x11_get_xwindow (x11) && ++ event->xclient.message_type == priv->touch_replay_sync_atom) ++ priv->current_touch_replay_sync_serial = event->xclient.data.l[0]; ++ break; ++ default: ++ break; ++ } ++ + XGetEventData (priv->xdisplay, &event->xcookie); + + { +@@ -534,6 +560,10 @@ meta_backend_x11_post_init (MetaBackend *backend) + monitor_manager = meta_backend_get_monitor_manager (backend); + g_signal_connect (monitor_manager, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed), backend); ++ ++ priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay, ++ "_MUTTER_TOUCH_SEQUENCE_SYNC", ++ False); + } + + static ClutterBackend * +@@ -611,6 +641,21 @@ meta_backend_x11_finish_touch_sequence (MetaBackend *backend, + META_VIRTUAL_CORE_POINTER_ID, + clutter_x11_event_sequence_get_touch_detail (sequence), + DefaultRootWindow (priv->xdisplay), event_mode); ++ ++ if (state == META_SEQUENCE_REJECTED) ++ { ++ XClientMessageEvent ev; ++ ++ ev = (XClientMessageEvent) { ++ .type = ClientMessage, ++ .window = meta_backend_x11_get_xwindow (x11), ++ .message_type = priv->touch_replay_sync_atom, ++ .format = 32, ++ .data.l[0] = ++priv->pending_touch_replay_sync_serial, ++ }; ++ XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11), ++ False, 0, (XEvent *) &ev); ++ } + } + + static void +-- +2.23.0 + diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec index 4bcf864..4b99e7a 100644 --- a/SPECS/mutter.spec +++ b/SPECS/mutter.spec @@ -8,7 +8,7 @@ Name: mutter Version: 3.32.2 -Release: 4%{?dist} +Release: 26%{?dist} Summary: Window and compositing manager based on Clutter License: GPLv2+ @@ -57,6 +57,60 @@ Patch112: add-support-for-plain-old-x-device-configuration.patch Patch113: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch Patch114: 0001-clutter-Only-reset-scroll-axes-on-slave-devices.patch +# Inherit xorg.conf (rhbz#1690506) +Patch115: inherit-xrandr-metamodes.patch + +# Fix test blocker when running on cirrus (rhbz#1735382) +Patch116: 0001-iconcache-Avoid-xrender-picture-formats-when-creatin.patch + +# Don't focus or activate unmanaging windows (rhbz#1741547) +Patch117: 0001-workspace-Focus-only-ancestors-that-are-focusable.patch +Patch118: 0002-window-Emit-an-error-and-return-when-trying-to-activ.patch + +# Don't freeze on rapid input (rhbz#1759525) +Patch119: 0001-events-Sync-pending-pointer-events-without-a-window.patch + +# Don't freeze if input happens after many days of inactivity (rhbz#1766649) +Patch120: input-after-long-idle-fix.patch + +# Fix invalid read in idle monitor (rhbz#1766695) +Patch121: idle-monitor-reset-fix.patch + +# Improve shadow-fb performance on llvmpipe +# https://bugzilla.redhat.com/1737553 +Patch201: 0001-cogl-Remove-unused-OFFSCREEN_BLIT-feature-flag.patch +Patch202: 0002-cogl-Fix-doc-for-_cogl_blit_framebuffer.patch +Patch203: 0003-cogl-Replace-ANGLE-with-GLES3-and-NV-framebuffer_bli.patch +Patch204: 0004-cogl-Relax-formats-on-glBlitFramebuffer.patch +Patch205: 0005-cogl-Allow-glBlitFramebuffer-between-onscreen-offscr.patch +Patch206: 0006-cogl-Rename-feature-OFFSCREEN_BLIT-to-BLIT_FRAMEBUFF.patch +Patch207: 0007-cogl-Expose-cogl_blit_framebuffer.patch +Patch208: 0008-clutter-stage-view-Use-cogl_blit_framebuffer-for-sha.patch +Patch209: 0009-clutter-stage-view-Ignore-clipping-rectangle-for-off.patch +Patch210: 0010-cogl-Flush-journal-before-blitting.patch +Patch211: 0011-clutter-stage-view-Separate-offscreen-and-shadowfb.patch +Patch212: 0012-renderer-native-Separate-offscreen-and-shadowfb.patch + +# Handle lack of RANDR (#1776530) +Patch250: 0001-monitor-manager-xrandr-Move-dpms-state-and-screen-si.patch +Patch251: 0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch + +# Fix build due to egl.pc provider change +Patch260: 0001-EGL-Include-EGL-eglmesaext.h.patch + +# Fix popups with styli +Patch261: 0001-wayland-Check-stylus-serials-on-meta_wayland_seat_ca.patch + +# Fix led-less pad mode switch buttons +Patch262: 0001-x11-Check-wacom-button-flags-to-determine-whether-bu.patch + +# Wacom fixes +Patch263: 0001-backends-Consider-pen-eraser-devices-when-looking-fo.patch +Patch264: 0001-backends-Always-enable-tap-to-click-drag-on-opaque-W.patch +Patch265: 0001-backends-x11-Observe-multiple-pad-mode-switch-button.patch +Patch266: 0001-backends-Check-both-input-settings-and-mapper-for-ta.patch +Patch267: 0001-core-Let-pad-mode-switch-events-always-go-through-Me.patch + BuildRequires: chrpath BuildRequires: pango-devel BuildRequires: startup-notification-devel @@ -198,6 +252,95 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop %{_datadir}/mutter-%{mutter_api_version}/tests %changelog +* Mon Dec 16 2019 Carlos Garnacho - 3.32.2-26 +- Let pad OSD update on mode switching + Resolves: #1716774 + +* Fri Dec 13 2019 Carlos Garnacho - 3.32.2-25 +- Fix Wacom OSDs so they appear on the right monitor + Resolves: #1777556 + +* Fri Dec 13 2019 Carlos Garnacho - 3.32.2-24 +- Handle multiple mode switch buttons in Cintiq 27QHD + Resolves: #1687979 + +* Fri Dec 13 2019 Carlos Garnacho - 3.32.2-23 +- Enable tapping features by default on standalone Wacom tablets + Resolves: #1716754 + +* Fri Dec 13 2019 Carlos Garnacho - 3.32.2-22 +- Fix detection of Wacom tablet features on X11 + Resolves: #1759619 + +* Wed Dec 04 2019 Carlos Garnacho - 3.32.2-21 +- Fix mode switch pad buttons without LEDs + Resolves: #1666070 + +* Mon Dec 01 2019 Tomas Pelka - 3.32.2-20 +- Need rebuild in correct build target + Resolves: #1730891 + +* Fri Nov 29 2019 Carlos Garnacho - 3.32.2-19 +- Fix pop ups with stylus input + Resolves: #1730891 + +* Wed Nov 27 2019 Jonas Ådahl - 3.32.2-18 +- Revert memory leak fix + Resolves: #1777911 + +* Wed Nov 27 2019 Florian Müllner - 3.32.2-17 +- Fix some memory leaks + Resolves: #1719819 + +* Wed Nov 27 2019 Jonas Ådahl - 3.32.2-16 +- Fix build due to egl.pc provider change + Related: #1776530 + +* Wed Nov 27 2019 Jonas Ådahl - 3.32.2-15 +- Handle lack of RANDR + Resolves: #1776530 + +* Mon Nov 4 2019 Olivier Fourdan - 3.32.2-14 +- Backports shadow FB improvements on llvmpipe + Resolves: #1737553 + +* Wed Oct 30 2019 Jonas Ådahl - 3.32.2-13 +- Fix invalid read in idle monitor + Resolves: #1766695 + +* Wed Oct 30 2019 Jonas Ådahl - 3.32.2-12 +- Don't freeze if input happens after many days of inactivity + Resolves: #1766649 + +* Fri Oct 25 2019 Jonas Ådahl - 3.32.2-11 +- Don't freeze on rapid input + Resolves: #1759525 + +* Fri Aug 16 2019 Jonas Ådahl - 3.32.2-10 +- Don't focus or activate unmanaging windows + Resolves: #1741547 + +* Mon Aug 05 2019 Ray Strode - 3.32.2-9 +- Another 16bpp graphics card crash + Related: #1735382 + Resolves: #1737326 + +* Fri Aug 02 2019 Ray Strode - 3.32.2-8 +- Fix crash in window icon handling on 16bpp graphics cards + Resolves: #1735382 + +* Tue Jul 23 2019 Ray Strode - 3.32.2-7 +- Fix bug leading to 100% cpu usage on suspend/resume + Resolves: #1724551 + +* Mon Jul 15 2019 Jonas Ådahl - 3.32.2-6 +- Don't ignore current mode when deriving current config + Resolves: #1690506 + +* Thu Jun 20 2019 Carlos Garnacho - 3.32.2-5 +- Ensure pad XDevices do not get buttons remapped + Resolves: #1687949 + * Wed Jun 12 2019 Florian Müllner - 3.32.2-4 - Expose workspace layout as properties Related: #1704360