diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efa9477 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mutter-40.4.tar.xz diff --git a/.mutter.metadata b/.mutter.metadata new file mode 100644 index 0000000..4344d2e --- /dev/null +++ b/.mutter.metadata @@ -0,0 +1 @@ +e97fff99b075736fc6f0d5bd5713d89983fe99e1 SOURCES/mutter-40.4.tar.xz diff --git a/SOURCES/0001-Revert-build-Do-not-provide-built-sources-as-libmutt.patch b/SOURCES/0001-Revert-build-Do-not-provide-built-sources-as-libmutt.patch new file mode 100644 index 0000000..bd18e8a --- /dev/null +++ b/SOURCES/0001-Revert-build-Do-not-provide-built-sources-as-libmutt.patch @@ -0,0 +1,26 @@ +From 3899a01cd6cb00ca686946d3065d58f59f5c2099 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Tue, 17 Nov 2020 14:00:02 +0100 +Subject: [PATCH] Revert "build: Do not provide built sources as libmutter_dep + sources" + +This reverts commit 4e9a2e479969973bf3063c740ceff149036b3af4. +--- + src/meson.build | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/meson.build b/src/meson.build +index e7c99caee..8fe484ec2 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -955,6 +955,7 @@ libmutter = shared_library(libmutter_name, + libmutter_dep = declare_dependency( + link_with: libmutter, + include_directories: mutter_includes, ++ sources: mutter_built_sources, + dependencies: [ + libmutter_cogl_dep, + libmutter_clutter_dep, +-- +2.28.0 + diff --git a/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch b/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch new file mode 100644 index 0000000..622ce5f --- /dev/null +++ b/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch @@ -0,0 +1,35 @@ +From a8746403352be96bae7dfd73ac31fe0253f884b8 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 9 Mar 2021 17:21:59 -0800 +Subject: [PATCH] Test: deny atomic KMS for "tegra" (RHBZ #1936991) + +Signed-off-by: Adam Williamson +--- + data/61-mutter.rules | 1 + + src/backends/native/meta-kms-device.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/data/61-mutter.rules b/data/61-mutter.rules +index edc03e6c1..d8e3c5f00 100644 +--- a/data/61-mutter.rules ++++ b/data/61-mutter.rules +@@ -3,3 +3,4 @@ DRIVERS=="nouveau", SUBSYSTEM=="drm", TAG+="mutter-device-disable-kms-modifiers" + DRIVERS=="amdgpu", SUBSYSTEM=="drm", TAG+="mutter-device-disable-kms-modifiers" + DRIVERS=="radeon", SUBSYSTEM=="drm", TAG+="mutter-device-disable-kms-modifiers" + ENV{ID_PATH}=="platform-vkms", TAG+="mutter-device-ignore" ++DRIVER=="tegra", SUBSYSTEM=="platform", TAG+="mutter-device-disable-atomic-kms" +diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c +index c388096d5..ef65cf82b 100644 +--- a/src/backends/native/meta-kms-device.c ++++ b/src/backends/native/meta-kms-device.c +@@ -252,6 +252,7 @@ is_atomic_allowed (const char *driver_name) + "vmwgfx", + "vboxvideo", + "nvidia-drm", ++ "tegra", + NULL, + }; + +-- +2.28.0 + diff --git a/SOURCES/0001-backend-Clean-up-renderer-after-clutter-backendm.patch b/SOURCES/0001-backend-Clean-up-renderer-after-clutter-backendm.patch new file mode 100644 index 0000000..e1d9c4d --- /dev/null +++ b/SOURCES/0001-backend-Clean-up-renderer-after-clutter-backendm.patch @@ -0,0 +1,92 @@ +From ff4dc8cc8274dc5f6ed11515e05a341e4e2cec28 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 12 Aug 2021 14:13:23 -0400 +Subject: [PATCH] backend: Clean up renderer after clutter backendm + +commit c4a73e795020722eda3e2bec0c16d96f9f37333b added +code to cleanup the renderer when the meta backend is +disposed. Unfortunately, this introduced a crash when +the window manager is replaced. + +This is because cleaning up the renderer involves talking +to the X server over a display connection that's closed +two lines higher as part of the clutter_backend_destroy +call. + +This commit fixes the crash by swapping their order. +--- + src/backends/meta-backend.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c +index ff84bfe6a..7e8b4ee95 100644 +--- a/src/backends/meta-backend.c ++++ b/src/backends/meta-backend.c +@@ -216,63 +216,63 @@ meta_backend_dispose (GObject *object) + + if (priv->sleep_signal_id) + { + g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id); + priv->sleep_signal_id = 0; + } + + if (priv->upower_watch_id) + { + g_bus_unwatch_name (priv->upower_watch_id); + priv->upower_watch_id = 0; + } + + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); + g_clear_object (&priv->system_bus); + g_clear_object (&priv->upower_proxy); + + g_clear_handle_id (&priv->device_update_idle_id, g_source_remove); + + g_clear_pointer (&priv->device_monitors, g_hash_table_destroy); + + g_clear_object (&priv->settings); + + #ifdef HAVE_PROFILER + g_clear_object (&priv->profiler); + #endif + + g_clear_pointer (&priv->default_seat, clutter_seat_destroy); + g_clear_pointer (&priv->stage, clutter_actor_destroy); +- g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy); + g_clear_object (&priv->renderer); + g_clear_list (&priv->gpus, g_object_unref); ++ g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy); + + G_OBJECT_CLASS (meta_backend_parent_class)->dispose (object); + } + + static void + meta_backend_destroy (MetaBackend *backend) + { + g_object_run_dispose (G_OBJECT (backend)); + g_object_unref (backend); + } + + static void + meta_backend_sync_screen_size (MetaBackend *backend) + { + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + int width, height; + + meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height); + + META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height); + } + + static void + reset_pointer_position (MetaBackend *backend) + { + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaMonitorManager *monitor_manager = priv->monitor_manager; + ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); + MetaLogicalMonitor *primary; + +-- +2.31.1 + diff --git a/SOURCES/0001-constraints-Enforce-X11-size-limits.patch b/SOURCES/0001-constraints-Enforce-X11-size-limits.patch new file mode 100644 index 0000000..a09a40b --- /dev/null +++ b/SOURCES/0001-constraints-Enforce-X11-size-limits.patch @@ -0,0 +1,85 @@ +From 1ab51efc968d7d3c6244d9b7efcdf4bae4fc0a9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 12 Mar 2014 02:04:13 +0100 +Subject: [PATCH] constraints: Enforce X11 size limits + +X11 limits windows to a maximum of 32767x32767, enforce that restriction +to keep insanely huge windows from crashing the WM. +--- + src/core/constraints.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/src/core/constraints.c b/src/core/constraints.c +index 4b1d95338a..eee16dc48f 100644 +--- a/src/core/constraints.c ++++ b/src/core/constraints.c +@@ -109,6 +109,7 @@ typedef enum + PRIORITY_TITLEBAR_VISIBLE = 4, + PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4, + PRIORITY_CUSTOM_RULE = 4, ++ PRIORITY_XLIMITS = 4, + PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */ + } ConstraintPriority; + +@@ -204,6 +205,10 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, + ConstraintInfo *info, + ConstraintPriority priority, + gboolean check_only); ++static gboolean constrain_xlimits (MetaWindow *window, ++ ConstraintInfo *info, ++ ConstraintPriority priority, ++ gboolean check_only); + + static void setup_constraint_info (ConstraintInfo *info, + MetaWindow *window, +@@ -239,6 +244,7 @@ static const Constraint all_constraints[] = { + {constrain_fully_onscreen, "constrain_fully_onscreen"}, + {constrain_titlebar_visible, "constrain_titlebar_visible"}, + {constrain_partially_onscreen, "constrain_partially_onscreen"}, ++ {constrain_xlimits, "constrain_xlimits"}, + {NULL, NULL} + }; + +@@ -1876,3 +1882,39 @@ constrain_partially_onscreen (MetaWindow *window, + + return retval; + } ++ ++ ++#define MAX_WINDOW_SIZE 32767 ++ ++static gboolean ++constrain_xlimits (MetaWindow *window, ++ ConstraintInfo *info, ++ ConstraintPriority priority, ++ gboolean check_only) ++{ ++ int max_w, max_h; ++ gboolean constraint_already_satisfied; ++ ++ if (priority > PRIORITY_XLIMITS) ++ return TRUE; ++ ++ max_w = max_h = MAX_WINDOW_SIZE; ++ ++ if (window->frame) ++ { ++ MetaFrameBorders borders; ++ meta_frame_calc_borders (window->frame, &borders); ++ ++ max_w -= (borders.total.left + borders.total.right); ++ max_h -= (borders.total.top + borders.total.bottom); ++ } ++ ++ constraint_already_satisfied = info->current.width < max_w && info->current.height < max_h; ++ if (check_only || constraint_already_satisfied) ++ return constraint_already_satisfied; ++ ++ info->current.width = MIN (info->current.width, max_w); ++ info->current.height = MIN (info->current.height, max_h); ++ ++ return TRUE; ++} +-- +2.31.1 + diff --git a/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch new file mode 100644 index 0000000..2ff5f1b --- /dev/null +++ b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch @@ -0,0 +1,42 @@ +From 7ac5b7bad8f2d0e61700610f68282f6687cc9d2e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 21 Jul 2016 15:43:12 +0200 +Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed + +(https://bugzilla.redhat.com/show_bug.cgi?id=1358535) +--- + src/x11/events.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/x11/events.c b/src/x11/events.c +index efa8f9856b..388eff0ac7 100644 +--- a/src/x11/events.c ++++ b/src/x11/events.c +@@ -839,6 +839,16 @@ crossing_serial_is_ignored (MetaX11Display *x11_display, + return FALSE; + } + ++static gboolean ++event_has_button_mask (XIEnterEvent *enter_event) ++{ ++ int i; ++ for (i = 0; i < enter_event->buttons.mask_len; i++) ++ if (enter_event->buttons.mask[i] != '\0') ++ return TRUE; ++ return FALSE; ++} ++ + static gboolean + handle_input_xevent (MetaX11Display *x11_display, + XIEvent *input_event, +@@ -883,6 +893,7 @@ handle_input_xevent (MetaX11Display *x11_display, + * avoid races. + */ + if (window && !crossing_serial_is_ignored (x11_display, serial) && ++ !event_has_button_mask (enter_event) && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + enter_event->detail != XINotifyInferior && +-- +2.31.1 + diff --git a/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch new file mode 100644 index 0000000..806ad38 --- /dev/null +++ b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch @@ -0,0 +1,49 @@ +From 99c74360451a85fca9dacad531ed22adbc1b0805 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 13 Feb 2018 09:44:50 -0500 +Subject: [PATCH] main: be more aggressive in assuming X11 backend + +If the session is started by vncserver right now, the +XDG_SESSION_TYPE won't be X11. Ideally that would be +fixed, but for backward compatibility we should default +to X11 if the session type isn't set to wayland explicitly. +--- + src/core/main.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index a07dda9ecc..0d241f952b 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -407,7 +407,6 @@ find_session_type (void) + char *session_id; + char *session_type; + const char *session_type_env; +- gboolean is_tty = FALSE; + int ret, i; + + ret = sd_pid_get_session (0, &session_id); +@@ -420,8 +419,7 @@ find_session_type (void) + { + if (session_type_is_supported (session_type)) + goto out; +- else +- is_tty = g_strcmp0 (session_type, "tty") == 0; ++ + free (session_type); + } + } +@@ -453,8 +451,8 @@ find_session_type (void) + goto out; + } + +- /* Legacy support for starting through xinit */ +- if (is_tty && (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY"))) ++ /* Legacy support for starting through xinit or vncserver */ ++ if (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY")) + { + session_type = strdup ("x11"); + goto out; +-- +2.31.1 + diff --git a/SOURCES/0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch b/SOURCES/0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch new file mode 100644 index 0000000..14c9f10 --- /dev/null +++ b/SOURCES/0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch @@ -0,0 +1,35 @@ +From 6e2ef652cd58136aa668d0c1bd843fe83f11a0ab Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Fri, 26 Oct 2018 08:49:39 +0200 +Subject: [PATCH] wayland: Allow Xwayland grabs on selected apps + +Allow Xwayland grabs on a selected set of X11 applications. +--- + data/org.gnome.mutter.wayland.gschema.xml.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/data/org.gnome.mutter.wayland.gschema.xml.in b/data/org.gnome.mutter.wayland.gschema.xml.in +index 8a1878e105..5527a46bc6 100644 +--- a/data/org.gnome.mutter.wayland.gschema.xml.in ++++ b/data/org.gnome.mutter.wayland.gschema.xml.in +@@ -66,7 +66,7 @@ + gettext-domain="@GETTEXT_DOMAIN@"> + + +- false ++ true + Allow X11 grabs to lock keyboard focus with Xwayland + + Allow all keyboard events to be routed to X11 “override redirect” +@@ -86,7 +86,7 @@ + + + +- [] ++ ['@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@'] + Xwayland applications allowed to issue keyboard grabs + + List the resource names or resource class of X11 windows either +-- +2.31.1 + diff --git a/SOURCES/0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch b/SOURCES/0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch new file mode 100644 index 0000000..5a9783b --- /dev/null +++ b/SOURCES/0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch @@ -0,0 +1,192 @@ +From 5e4a1290ce75ed94e3f0f457d35a225f2ef3878c Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 28 Nov 2017 10:54:08 +0100 +Subject: [PATCH] wayland: Avoid a race in wl_seat capabilities + +The way wl_seat capabilities work, by notifying clients of capabilities +changes, and clients consequently requesting the relevant interface +objects (pointer, keyboard, touch) is inherently racy. + +On quick VT changes for example, capabilities on the seat will be added +and removed, and by the time the client receives the capability change +notification and requests the relevant keyboard, pointer or touch, +another VT switch might have occurred and the wl_pointer, wl_keyboard or +wl_touch already destroyed, leading to a protocol error which kills the +client. + +To avoid this, create the objects when requested regardless of the +capabilities. + +Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1797 +Related: https://bugzilla.gnome.org/show_bug.cgi?id=790932 +--- + src/wayland/meta-wayland-pointer.c | 45 ++++++++++++++++++++++++------ + src/wayland/meta-wayland-seat.c | 9 ++---- + src/wayland/meta-wayland-touch.c | 8 ------ + 3 files changed, 40 insertions(+), 22 deletions(-) + +diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c +index 3132abfd2..abd779ad7 100644 +--- a/src/wayland/meta-wayland-pointer.c ++++ b/src/wayland/meta-wayland-pointer.c +@@ -109,7 +109,7 @@ meta_wayland_pointer_client_new (void) + } + + static void +-meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client) ++meta_wayland_pointer_make_resources_inert (MetaWaylandPointerClient *pointer_client) + { + struct wl_resource *resource, *next; + +@@ -141,10 +141,25 @@ meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client) + wl_list_init (wl_resource_get_link (resource)); + wl_resource_set_user_data (resource, NULL); + } ++} + ++static void ++meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client) ++{ ++ meta_wayland_pointer_make_resources_inert (pointer_client); + g_free (pointer_client); + } + ++static void ++make_resources_inert_foreach (gpointer key, ++ gpointer value, ++ gpointer data) ++{ ++ MetaWaylandPointerClient *pointer_client = value; ++ ++ meta_wayland_pointer_make_resources_inert (pointer_client); ++} ++ + static gboolean + meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client) + { +@@ -158,8 +173,6 @@ MetaWaylandPointerClient * + meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer, + struct wl_client *client) + { +- if (!pointer->pointer_clients) +- return NULL; + return g_hash_table_lookup (pointer->pointer_clients, client); + } + +@@ -475,10 +488,6 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer) + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterSeat *clutter_seat; + +- pointer->pointer_clients = +- g_hash_table_new_full (NULL, NULL, NULL, +- (GDestroyNotify) meta_wayland_pointer_client_free); +- + pointer->cursor_surface = NULL; + + clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); +@@ -508,6 +517,10 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer) + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); + ++ g_hash_table_foreach (pointer->pointer_clients, ++ make_resources_inert_foreach, ++ NULL); ++ + g_signal_handlers_disconnect_by_func (cursor_tracker, + (gpointer) meta_wayland_pointer_on_cursor_changed, + pointer); +@@ -531,7 +544,6 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer) + meta_wayland_pointer_set_focus (pointer, NULL); + meta_wayland_pointer_set_current (pointer, NULL); + +- g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref); + pointer->cursor_surface = NULL; + } + +@@ -1356,11 +1368,28 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer) + pointer->default_grab.interface = &default_pointer_grab_interface; + pointer->default_grab.pointer = pointer; + pointer->grab = &pointer->default_grab; ++ pointer->pointer_clients = ++ g_hash_table_new_full (NULL, NULL, NULL, ++ (GDestroyNotify) meta_wayland_pointer_client_free); ++} ++ ++static void ++meta_wayland_pointer_finalize (GObject *object) ++{ ++ MetaWaylandPointer *pointer = META_WAYLAND_POINTER (object); ++ ++ g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref); ++ ++ G_OBJECT_CLASS (meta_wayland_pointer_parent_class)->finalize (object); + } + + static void + meta_wayland_pointer_class_init (MetaWaylandPointerClass *klass) + { ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ ++ object_class->finalize = meta_wayland_pointer_finalize; ++ + signals[FOCUS_SURFACE_CHANGED] = g_signal_new ("focus-surface-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, +diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c +index c6390dde7..efce6d6d6 100644 +--- a/src/wayland/meta-wayland-seat.c ++++ b/src/wayland/meta-wayland-seat.c +@@ -46,8 +46,7 @@ seat_get_pointer (struct wl_client *client, + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandPointer *pointer = seat->pointer; + +- if (meta_wayland_seat_has_pointer (seat)) +- meta_wayland_pointer_create_new_resource (pointer, client, resource, id); ++ meta_wayland_pointer_create_new_resource (pointer, client, resource, id); + } + + static void +@@ -58,8 +57,7 @@ seat_get_keyboard (struct wl_client *client, + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandKeyboard *keyboard = seat->keyboard; + +- if (meta_wayland_seat_has_keyboard (seat)) +- meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id); ++ meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id); + } + + static void +@@ -70,8 +68,7 @@ seat_get_touch (struct wl_client *client, + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandTouch *touch = seat->touch; + +- if (meta_wayland_seat_has_touch (seat)) +- meta_wayland_touch_create_new_resource (touch, client, resource, id); ++ meta_wayland_touch_create_new_resource (touch, client, resource, id); + } + + static void +diff --git a/src/wayland/meta-wayland-touch.c b/src/wayland/meta-wayland-touch.c +index 002ff16f7..15f0312eb 100644 +--- a/src/wayland/meta-wayland-touch.c ++++ b/src/wayland/meta-wayland-touch.c +@@ -521,16 +521,8 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch, + struct wl_resource *seat_resource, + uint32_t id) + { +- MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *cr; + +- if (!meta_wayland_seat_has_touch (seat)) +- { +- wl_resource_post_error (seat_resource, WL_DISPLAY_ERROR_INVALID_METHOD, +- "Cannot retrieve touch interface without touch capability"); +- return; +- } +- + cr = wl_resource_create (client, &wl_touch_interface, wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource); + wl_list_insert (&touch->resource_list, wl_resource_get_link (cr)); +-- +2.31.1 + diff --git a/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch new file mode 100644 index 0000000..36d50b6 --- /dev/null +++ b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch @@ -0,0 +1,35 @@ +From 9efcc35102b4c41265e93461b35a1193b3d5822d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 12 May 2017 13:40:31 +0200 +Subject: [PATCH] window-actor: Special-case shaped Java windows + +OpenJDK wrongly assumes that shaping a window implies no shadows. +They got lucky until commit b975676c changed the fallback case, +but now their compliance tests are broken. Make them happy again +by special-casing shaped Java windows. +--- + src/compositor/meta-window-actor-x11.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c +index b7032e0ba..b05d5e158 100644 +--- a/src/compositor/meta-window-actor-x11.c ++++ b/src/compositor/meta-window-actor-x11.c +@@ -528,6 +528,14 @@ has_shadow (MetaWindowActorX11 *actor_x11) + */ + if (window->has_custom_frame_extents) + return FALSE; ++ ++ /* ++ * OpenJDK wrongly assumes that shaping a window implies no compositor ++ * shadows; make its compliance tests happy to give it what it wants ... ++ */ ++ if (g_strcmp0 (window->res_name, "sun-awt-X11-XWindowPeer") == 0 && ++ window->shape_region != NULL) ++ return FALSE; + + /* + * Generate shadows for all other windows. +-- +2.23.0 + diff --git a/SOURCES/glx-stereo-support.patch b/SOURCES/glx-stereo-support.patch new file mode 100644 index 0000000..8083db4 --- /dev/null +++ b/SOURCES/glx-stereo-support.patch @@ -0,0 +1,1242 @@ +From 768818c8d071f066a2ab68f83381829838b5bf29 Mon Sep 17 00:00:00 2001 +From: "Owen W. Taylor" +Date: Thu, 8 May 2014 18:44:15 -0400 +Subject: [PATCH 1/2] Add support for quad-buffer stereo + +Track the stereo status of windows using the new EXT_stereo_tree +GLX extension. + +When stereo is enabled or disabled, a restart is triggered via +meta_restart() after a timeout, setting a _META_ENABLE_STEREO +property on the root window to indicate whether we should +turn on a stereo stage for clutter. The property avoids a loop, +since we need to enable stereo *before* initializing Clutter and GL, +but we need GL to figure out whether we have stereo windows. + +Stereo windows are drawn to the stage using new functionality +in Cogl to setup a stereo context, select which buffer to draw +to, and draw either the left or right buffer of a stereo +texture_from_pixmap. +--- + clutter/clutter/clutter-paint-nodes.c | 103 +++++++++++ + clutter/clutter/clutter-paint-nodes.h | 13 ++ + src/compositor/compositor.c | 8 + + src/compositor/meta-compositor-x11.c | 127 +++++++++++++ + src/compositor/meta-compositor-x11.h | 6 + + src/compositor/meta-shaped-texture-private.h | 5 +- + src/compositor/meta-shaped-texture.c | 176 +++++++++++++++---- + src/compositor/meta-surface-actor-wayland.c | 2 +- + src/compositor/meta-surface-actor-x11.c | 55 +++++- + src/compositor/meta-surface-actor-x11.h | 5 + + src/compositor/meta-window-actor-private.h | 5 + + src/compositor/meta-window-actor.c | 22 +++ + src/core/main.c | 4 + + src/core/stereo.c | 154 ++++++++++++++++ + src/core/stereo.h | 28 +++ + src/meson.build | 2 + + src/wayland/meta-wayland-actor-surface.c | 4 +- + 17 files changed, 667 insertions(+), 52 deletions(-) + create mode 100644 src/core/stereo.c + create mode 100644 src/core/stereo.h + +diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c +index f1f7fce318..29a673e9c7 100644 +--- a/clutter/clutter/clutter-paint-nodes.c ++++ b/clutter/clutter/clutter-paint-nodes.c +@@ -1970,3 +1970,106 @@ clutter_blur_node_new (unsigned int width, + out: + return (ClutterPaintNode *) blur_node; + } ++ ++/* ++ * ClutterStereoNode ++ */ ++ ++struct _ClutterStereoNode ++{ ++ ClutterPaintNode parent_instance; ++ ++ CoglStereoMode stereo_mode; ++}; ++ ++struct _ClutterStereoNodeClass ++{ ++ ClutterPaintNodeClass parent_class; ++}; ++ ++G_DEFINE_TYPE (ClutterStereoNode, clutter_stereo_node, CLUTTER_TYPE_PAINT_NODE) ++ ++static gboolean ++clutter_stereo_node_pre_draw (ClutterPaintNode *node, ++ ClutterPaintContext *paint_context) ++{ ++ ClutterStereoNode *stereo_node = CLUTTER_STEREO_NODE (node); ++ CoglFramebuffer *fb = ++ clutter_paint_context_get_framebuffer (paint_context); ++ ++ g_warn_if_fail (cogl_framebuffer_get_is_stereo (fb)); ++ ++ cogl_framebuffer_set_stereo_mode (fb, stereo_node->stereo_mode); ++ ++ return TRUE; ++} ++ ++static void ++clutter_stereo_node_post_draw (ClutterPaintNode *node, ++ ClutterPaintContext *paint_context) ++{ ++ CoglFramebuffer *fb = ++ clutter_paint_context_get_framebuffer (paint_context); ++ ++ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH); ++} ++ ++static const char * ++stereo_mode_to_string (CoglStereoMode stereo_mode) ++{ ++ switch (stereo_mode) ++ { ++ case COGL_STEREO_BOTH: ++ return "both"; ++ case COGL_STEREO_LEFT: ++ return "left"; ++ case COGL_STEREO_RIGHT: ++ return "right"; ++ } ++ ++ g_assert_not_reached (); ++} ++ ++static JsonNode * ++clutter_stereo_node_serialize (ClutterPaintNode *node) ++{ ++ ClutterStereoNode *stereo_node = CLUTTER_STEREO_NODE (node); ++ g_autoptr (JsonBuilder) builder = NULL; ++ const char *stereo_mode_str; ++ ++ builder = json_builder_new (); ++ json_builder_begin_object (builder); ++ json_builder_set_member_name (builder, "stereo-mode"); ++ stereo_mode_str = stereo_mode_to_string (stereo_node->stereo_mode); ++ json_builder_add_string_value (builder, stereo_mode_str); ++ json_builder_end_object (builder); ++ ++ return json_builder_get_root (builder); ++} ++ ++static void ++clutter_stereo_node_class_init (ClutterStereoNodeClass *klass) ++{ ++ ClutterPaintNodeClass *node_class; ++ ++ node_class = CLUTTER_PAINT_NODE_CLASS (klass); ++ node_class->pre_draw = clutter_stereo_node_pre_draw; ++ node_class->post_draw = clutter_stereo_node_post_draw; ++ node_class->serialize = clutter_stereo_node_serialize; ++} ++ ++static void ++clutter_stereo_node_init (ClutterStereoNode *stereo_node) ++{ ++} ++ ++ClutterPaintNode * ++clutter_stereo_node_new (CoglStereoMode stereo_mode) ++{ ++ ClutterStereoNode *stereo_node; ++ ++ stereo_node = _clutter_paint_node_create (CLUTTER_TYPE_STEREO_NODE); ++ stereo_node->stereo_mode = stereo_mode; ++ ++ return CLUTTER_PAINT_NODE (stereo_node); ++} +diff --git a/clutter/clutter/clutter-paint-nodes.h b/clutter/clutter/clutter-paint-nodes.h +index 7f0d12857a..77d1ab05b6 100644 +--- a/clutter/clutter/clutter-paint-nodes.h ++++ b/clutter/clutter/clutter-paint-nodes.h +@@ -284,6 +284,19 @@ ClutterPaintNode * clutter_blur_node_new (unsigned int width, + unsigned int height, + float sigma); + ++#define CLUTTER_TYPE_STEREO_NODE (clutter_stereo_node_get_type ()) ++#define CLUTTER_STEREO_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STEREO_NODE, ClutterStereoNode)) ++#define CLUTTER_IS_STEREO_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STEREO_NODE)) ++ ++typedef struct _ClutterStereoNode ClutterStereoNode; ++typedef struct _ClutterStereoNodeClass ClutterStereoNodeClass; ++ ++CLUTTER_EXPORT ++GType clutter_stereo_node_get_type (void) G_GNUC_CONST; ++ ++CLUTTER_EXPORT ++ClutterPaintNode * clutter_stereo_node_new (CoglStereoMode stereo_mode); ++ + G_END_DECLS + + #endif /* __CLUTTER_PAINT_NODES_H__ */ +diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c +index 1770550d4c..a4bd1252ae 100644 +--- a/src/compositor/compositor.c ++++ b/src/compositor/compositor.c +@@ -66,6 +66,7 @@ + #include "compositor/meta-window-actor-private.h" + #include "compositor/meta-window-group-private.h" + #include "core/frame.h" ++#include "core/stereo.h" + #include "core/util-private.h" + #include "core/window-private.h" + #include "meta/compositor-mutter.h" +@@ -910,6 +911,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor, + meta_compositor_get_instance_private (compositor); + MetaWindowActor *top_window_actor; + GList *old_stack; ++ int stereo_window_count = 0; + + /* This is painful because hidden windows that we are in the process + * of animating out of existence. They'll be at the bottom of the +@@ -986,12 +988,18 @@ meta_compositor_sync_stack (MetaCompositor *compositor, + */ + priv->windows = g_list_prepend (priv->windows, actor); + ++ if (meta_window_actor_is_stereo (actor)) ++ stereo_window_count++; ++ + stack = g_list_remove (stack, window); + old_stack = g_list_remove (old_stack, actor); + } + + sync_actor_stacking (compositor); + ++ if (!meta_is_wayland_compositor ()) ++ meta_stereo_set_have_stereo_windows (stereo_window_count > 0); ++ + top_window_actor = get_top_visible_window_actor (compositor); + + if (priv->top_window_actor == top_window_actor) +diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c +index 1d0ba4c8d8..afbe3f57e2 100644 +--- a/src/compositor/meta-compositor-x11.c ++++ b/src/compositor/meta-compositor-x11.c +@@ -31,6 +31,8 @@ + #include "compositor/meta-sync-ring.h" + #include "compositor/meta-window-actor-x11.h" + #include "core/display-private.h" ++#include "core/stack-tracker.h" ++#include "core/stereo.h" + #include "x11/meta-x11-display-private.h" + + struct _MetaCompositorX11 +@@ -50,8 +52,24 @@ struct _MetaCompositorX11 + gboolean xserver_uses_monotonic_clock; + int64_t xserver_time_query_time_us; + int64_t xserver_time_offset_us; ++ ++ int glx_opcode; ++ gboolean stereo_tree_ext; ++ gboolean have_stereo_windows; + }; + ++typedef struct ++{ ++ int type; ++ unsigned long serial; ++ Bool send_event; ++ Display *display; ++ int extension; ++ int evtype; ++ Drawable window; ++ Bool stereo_tree; ++} StereoNotifyEvent; ++ + G_DEFINE_TYPE (MetaCompositorX11, meta_compositor_x11, META_TYPE_COMPOSITOR) + + static void +@@ -95,6 +113,27 @@ meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, + if (window) + process_damage (compositor_x11, (XDamageNotifyEvent *) xevent, window); + } ++ else if (xevent->type == GenericEvent && ++ xevent->xcookie.extension == compositor_x11->glx_opcode) ++ { ++ if (xevent->xcookie.evtype == GLX_STEREO_NOTIFY_EXT) ++ { ++ StereoNotifyEvent *stereo_event = ++ (StereoNotifyEvent *) (xevent->xcookie.data); ++ ++ window = meta_x11_display_lookup_x_window (x11_display, ++ stereo_event->window); ++ if (window) ++ { ++ MetaWindowActor *window_actor = meta_window_actor_from_window (window); ++ MetaDisplay *display = meta_window_get_display (window); ++ ++ meta_window_actor_stereo_notify (window_actor, ++ stereo_event->stereo_tree); ++ meta_stack_tracker_queue_sync_stack (display->stack_tracker); ++ } ++ } ++ } + + if (compositor_x11->have_x11_sync_object) + meta_sync_ring_handle_event (xevent); +@@ -107,6 +146,85 @@ meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, + meta_x11_handle_event (xevent); + } + ++#define GLX_STEREO_TREE_EXT 0x20F5 ++#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 ++#define GLX_STEREO_NOTIFY_EXT 0x00000000 ++ ++static gboolean ++display_has_stereo_tree_ext (MetaX11Display *x11_display) ++{ ++ Display *xdisplay = x11_display->xdisplay; ++ const char *extensions_string; ++ ++ static const char * (*query_extensions_string) (Display *display, ++ int screen); ++ ++ if (query_extensions_string == NULL) ++ query_extensions_string = ++ (const char * (*) (Display *, int)) ++ cogl_get_proc_address ("glXQueryExtensionsString"); ++ ++ extensions_string = query_extensions_string (xdisplay, ++ meta_x11_display_get_screen_number (x11_display)); ++ ++ return extensions_string && strstr (extensions_string, "EXT_stereo_tree") != 0; ++} ++ ++#include ++ ++gboolean ++meta_compositor_x11_window_is_stereo (MetaCompositorX11 *compositor_x11, ++ Window xwindow) ++{ ++ MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); ++ MetaDisplay *display = meta_compositor_get_display (compositor); ++ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); ++ ++ static int (*query_drawable) (Display *dpy, ++ Drawable draw, ++ int attribute, ++ unsigned int *value); ++ ++ if (compositor_x11->stereo_tree_ext) ++ { ++ unsigned int stereo_tree = 0; ++ ++ if (query_drawable == NULL) ++ query_drawable = ++ (int (*) (Display *, Drawable, int, unsigned int *)) ++ cogl_get_proc_address ("glXQueryDrawable"); ++ ++ query_drawable (xdisplay, xwindow, GLX_STEREO_TREE_EXT, &stereo_tree); ++ ++ return stereo_tree != 0; ++ } ++ else ++ return FALSE; ++} ++ ++void ++meta_compositor_x11_select_stereo_notify (MetaCompositorX11 *compositor_x11, ++ Window xwindow) ++{ ++ MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); ++ MetaDisplay *display = meta_compositor_get_display (compositor); ++ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); ++ ++ static void (*select_event) (Display *dpy, ++ Drawable draw, ++ unsigned long event_mask); ++ ++ if (compositor_x11->stereo_tree_ext) ++ { ++ if (select_event == NULL) ++ select_event = ++ (void (*) (Display *, Drawable, unsigned long)) ++ cogl_get_proc_address ("glXSelectEvent"); ++ ++ select_event (xdisplay, xwindow, GLX_STEREO_NOTIFY_MASK_EXT); ++ } ++} ++ + static void + determine_server_clock_source (MetaCompositorX11 *compositor_x11) + { +@@ -142,6 +260,7 @@ meta_compositor_x11_manage (MetaCompositor *compositor, + MetaX11Display *x11_display = display->x11_display; + Display *xdisplay = meta_x11_display_get_xdisplay (x11_display); + int composite_version; ++ int glx_major_opcode, glx_first_event, glx_first_error; + MetaBackend *backend = meta_get_backend (); + Window xwindow; + +@@ -166,10 +285,18 @@ meta_compositor_x11_manage (MetaCompositor *compositor, + return FALSE; + } + ++ if (XQueryExtension (xdisplay, ++ "GLX", ++ &glx_major_opcode, &glx_first_event, &glx_first_error)) ++ compositor_x11->glx_opcode = glx_major_opcode; ++ + determine_server_clock_source (compositor_x11); + + meta_x11_display_set_cm_selection (display->x11_display); + ++ compositor_x11->stereo_tree_ext = ++ display_has_stereo_tree_ext (display->x11_display); ++ + compositor_x11->output = display->x11_display->composite_overlay_window; + + xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); +diff --git a/src/compositor/meta-compositor-x11.h b/src/compositor/meta-compositor-x11.h +index 42554feb39..61f3cd5950 100644 +--- a/src/compositor/meta-compositor-x11.h ++++ b/src/compositor/meta-compositor-x11.h +@@ -36,4 +36,10 @@ void meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, + + Window meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11); + ++gboolean meta_compositor_x11_window_is_stereo (MetaCompositorX11 *compositor_x11, ++ Window xwindow); ++ ++void meta_compositor_x11_select_stereo_notify (MetaCompositorX11 *compositor_x11, ++ Window xwindow); ++ + #endif /* META_COMPOSITOR_X11_H */ +diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h +index 2fe1b8ea48..fadad07d69 100644 +--- a/src/compositor/meta-shaped-texture-private.h ++++ b/src/compositor/meta-shaped-texture-private.h +@@ -31,8 +31,9 @@ + #include "meta/meta-shaped-texture.h" + + MetaShapedTexture *meta_shaped_texture_new (void); +-void meta_shaped_texture_set_texture (MetaShapedTexture *stex, +- CoglTexture *texture); ++void meta_shaped_texture_set_textures (MetaShapedTexture *stex, ++ CoglTexture *texture, ++ CoglTexture *texture_right); + void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex, + 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 6a8af828f0..43170a195d 100644 +--- a/src/compositor/meta-shaped-texture.c ++++ b/src/compositor/meta-shaped-texture.c +@@ -83,8 +83,10 @@ struct _MetaShapedTexture + GObject parent; + + MetaTextureTower *paint_tower; ++ MetaTextureTower *paint_tower_right; + + CoglTexture *texture; ++ CoglTexture *texture_right; + CoglTexture *mask_texture; + CoglSnippet *snippet; + +@@ -151,6 +153,7 @@ static void + meta_shaped_texture_init (MetaShapedTexture *stex) + { + stex->paint_tower = meta_texture_tower_new (); ++ stex->paint_tower_right = NULL; + + stex->buffer_scale = 1; + stex->texture = NULL; +@@ -251,11 +254,11 @@ meta_shaped_texture_dispose (GObject *object) + + g_clear_handle_id (&stex->remipmap_timeout_id, g_source_remove); + +- if (stex->paint_tower) +- meta_texture_tower_free (stex->paint_tower); +- stex->paint_tower = NULL; ++ g_clear_pointer (&stex->paint_tower, meta_texture_tower_free); ++ g_clear_pointer (&stex->paint_tower_right, meta_texture_tower_free); + + g_clear_pointer (&stex->texture, cogl_object_unref); ++ g_clear_pointer (&stex->texture_right, cogl_object_unref); + + meta_shaped_texture_set_mask_texture (stex, NULL); + meta_shaped_texture_reset_pipelines (stex); +@@ -521,14 +524,19 @@ paint_clipped_rectangle_node (MetaShapedTexture *stex, + } + + static void +-set_cogl_texture (MetaShapedTexture *stex, +- CoglTexture *cogl_tex) ++set_cogl_textures (MetaShapedTexture *stex, ++ CoglTexture *cogl_tex, ++ CoglTexture *cogl_tex_right) + { + int width, height; + + cogl_clear_object (&stex->texture); ++ cogl_clear_object (&stex->texture_right); + +- if (cogl_tex != NULL) ++ stex->texture = cogl_tex; ++ stex->texture_right = cogl_tex_right; ++ ++ if (cogl_tex) + { + stex->texture = cogl_object_ref (cogl_tex); + width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex)); +@@ -540,6 +548,9 @@ set_cogl_texture (MetaShapedTexture *stex, + height = 0; + } + ++ if (cogl_tex_right) ++ cogl_object_ref (cogl_tex_right); ++ + if (stex->tex_width != width || + stex->tex_height != height) + { +@@ -553,8 +564,23 @@ set_cogl_texture (MetaShapedTexture *stex, + * previous buffer. We only queue a redraw in response to surface + * damage. */ + ++ if (cogl_tex_right) ++ { ++ if (!stex->paint_tower_right) ++ stex->paint_tower_right = meta_texture_tower_new (); ++ } ++ else ++ { ++ g_clear_pointer (&stex->paint_tower_right, meta_texture_tower_free); ++ } ++ + if (stex->create_mipmaps) +- meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex); ++ { ++ meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex); ++ ++ if (stex->paint_tower_right) ++ meta_texture_tower_set_base_texture (stex->paint_tower_right, cogl_tex_right); ++ } + } + + static gboolean +@@ -582,6 +608,19 @@ flip_ints (int *x, + *y = tmp; + } + ++static CoglFramebuffer * ++get_target_framebuffer (ClutterPaintNode *root_node, ++ ClutterPaintContext *paint_context) ++{ ++ CoglFramebuffer *framebuffer; ++ ++ framebuffer = clutter_paint_node_get_framebuffer (root_node); ++ if (!framebuffer) ++ framebuffer = clutter_paint_context_get_framebuffer (paint_context); ++ ++ return framebuffer; ++} ++ + static void + do_paint_content (MetaShapedTexture *stex, + ClutterPaintNode *root_node, +@@ -622,9 +661,7 @@ do_paint_content (MetaShapedTexture *stex, + * improves performance, especially with software rendering. + */ + +- framebuffer = clutter_paint_node_get_framebuffer (root_node); +- if (!framebuffer) +- framebuffer = clutter_paint_context_get_framebuffer (paint_context); ++ framebuffer = get_target_framebuffer (root_node, paint_context); + + if (stex->has_viewport_src_rect) + { +@@ -826,13 +863,27 @@ do_paint_content (MetaShapedTexture *stex, + + static CoglTexture * + select_texture_for_paint (MetaShapedTexture *stex, +- ClutterPaintContext *paint_context) ++ ClutterPaintContext *paint_context, ++ CoglStereoMode stereo_mode) + { + CoglTexture *texture = NULL; + int64_t now; ++ gboolean use_right_texture = FALSE; + +- if (!stex->texture) +- return NULL; ++ switch (stereo_mode) ++ { ++ case COGL_STEREO_LEFT: ++ case COGL_STEREO_BOTH: ++ if (!stex->texture) ++ return NULL; ++ use_right_texture = FALSE; ++ break; ++ case COGL_STEREO_RIGHT: ++ if (!stex->texture_right) ++ return NULL; ++ use_right_texture = TRUE; ++ break; ++ } + + now = g_get_monotonic_time (); + +@@ -843,14 +894,24 @@ select_texture_for_paint (MetaShapedTexture *stex, + if (age >= MIN_MIPMAP_AGE_USEC || + stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) + { +- texture = meta_texture_tower_get_paint_texture (stex->paint_tower, ++ MetaTextureTower *paint_tower; ++ ++ if (use_right_texture) ++ paint_tower = stex->paint_tower_right; ++ else ++ paint_tower = stex->paint_tower; ++ ++ texture = meta_texture_tower_get_paint_texture (paint_tower, + paint_context); + } + } + + if (!texture) + { +- texture = stex->texture; ++ if (use_right_texture) ++ texture = stex->texture_right; ++ else ++ texture = stex->texture; + + if (stex->create_mipmaps) + { +@@ -876,35 +937,57 @@ meta_shaped_texture_paint_content (ClutterContent *content, + { + MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); + ClutterActorBox alloc; +- CoglTexture *paint_tex = NULL; + uint8_t opacity; ++ CoglFramebuffer *framebuffer; ++ gboolean is_stereo; + + if (stex->clip_region && cairo_region_is_empty (stex->clip_region)) + return; + +- /* The GL EXT_texture_from_pixmap extension does allow for it to be +- * used together with SGIS_generate_mipmap, however this is very +- * rarely supported. Also, even when it is supported there +- * are distinct performance implications from: +- * +- * - Updating mipmaps that we don't need +- * - Having to reallocate pixmaps on the server into larger buffers +- * +- * So, we just unconditionally use our mipmap emulation code. If we +- * wanted to use SGIS_generate_mipmap, we'd have to query COGL to +- * see if it was supported (no API currently), and then if and only +- * if that was the case, set the clutter texture quality to HIGH. +- * Setting the texture quality to high without SGIS_generate_mipmap +- * support for TFP textures will result in fallbacks to XGetImage. +- */ +- paint_tex = select_texture_for_paint (stex, paint_context); +- if (!paint_tex) ++ if (!stex->texture) + return; + + opacity = clutter_actor_get_paint_opacity (actor); + clutter_actor_get_content_box (actor, &alloc); + +- do_paint_content (stex, root_node, paint_context, paint_tex, &alloc, opacity); ++ framebuffer = get_target_framebuffer (root_node, paint_context); ++ is_stereo = (stex->texture_right && ++ cogl_framebuffer_get_is_stereo (framebuffer)); ++ ++ if (is_stereo) ++ { ++ CoglTexture *texture_left; ++ CoglTexture *texture_right; ++ g_autoptr (ClutterPaintNode) left_node = NULL; ++ g_autoptr (ClutterPaintNode) right_node = NULL; ++ ++ texture_left = select_texture_for_paint (stex, paint_context, ++ COGL_STEREO_LEFT); ++ texture_right = select_texture_for_paint (stex, paint_context, ++ COGL_STEREO_RIGHT); ++ ++ left_node = clutter_stereo_node_new (COGL_STEREO_LEFT); ++ clutter_paint_node_set_static_name (left_node, "MetaShapedTexture (left)"); ++ right_node = clutter_stereo_node_new (COGL_STEREO_RIGHT); ++ clutter_paint_node_set_static_name (right_node, "MetaShapedTexture (right)"); ++ ++ clutter_paint_node_add_child (root_node, left_node); ++ clutter_paint_node_add_child (root_node, right_node); ++ ++ do_paint_content (stex, left_node, paint_context, ++ texture_left, &alloc, opacity); ++ do_paint_content (stex, right_node, paint_context, ++ texture_right, &alloc, opacity); ++ } ++ else ++ { ++ CoglTexture *texture; ++ ++ texture = select_texture_for_paint (stex, paint_context, ++ COGL_STEREO_BOTH); ++ do_paint_content (stex, root_node, paint_context, ++ texture, &alloc, opacity); ++ } + } + + static gboolean +@@ -946,6 +1029,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); ++ ++ if (stex->paint_tower_right) ++ { ++ base_texture = create_mipmaps ? stex->texture_right : NULL; ++ meta_texture_tower_set_base_texture (stex->paint_tower_right, base_texture); ++ } + } + } + +@@ -1079,6 +1168,14 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, + y, + width, + height); ++ if (stex->paint_tower_right) ++ { ++ meta_texture_tower_update_area (stex->paint_tower_right, ++ x, ++ y, ++ width, ++ height); ++ } + + stex->prev_invalidation = stex->last_invalidation; + stex->last_invalidation = g_get_monotonic_time (); +@@ -1098,20 +1195,21 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, + } + + /** +- * meta_shaped_texture_set_texture: ++ * meta_shaped_texture_set_textures: + * @stex: The #MetaShapedTexture + * @pixmap: The #CoglTexture to display + */ + void +-meta_shaped_texture_set_texture (MetaShapedTexture *stex, +- CoglTexture *texture) ++meta_shaped_texture_set_textures (MetaShapedTexture *stex, ++ CoglTexture *texture, ++ CoglTexture *texture_right) + { + g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + +- if (stex->texture == texture) ++ if (stex->texture == texture && stex->texture_right == texture_right) + return; + +- set_cogl_texture (stex, texture); ++ set_cogl_textures (stex, texture, texture_right); + } + + /** +diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c +index a182ad8513..1ddc83db2b 100644 +--- a/src/compositor/meta-surface-actor-wayland.c ++++ b/src/compositor/meta-surface-actor-wayland.c +@@ -148,7 +148,7 @@ meta_surface_actor_wayland_dispose (GObject *object) + + stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + if (stex) +- meta_shaped_texture_set_texture (stex, NULL); ++ meta_shaped_texture_set_textures (stex, NULL, NULL); + + if (self->surface) + { +diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c +index 41ae2dffbc..c7c3d08c36 100644 +--- a/src/compositor/meta-surface-actor-x11.c ++++ b/src/compositor/meta-surface-actor-x11.c +@@ -30,6 +30,7 @@ + #include + + #include "cogl/winsys/cogl-texture-pixmap-x11.h" ++#include "compositor/meta-compositor-x11.h" + #include "compositor/meta-cullable.h" + #include "compositor/meta-shaped-texture-private.h" + #include "compositor/meta-window-actor-private.h" +@@ -47,6 +48,7 @@ struct _MetaSurfaceActorX11 + MetaDisplay *display; + + CoglTexture *texture; ++ CoglTexture *texture_right; + Pixmap pixmap; + Damage damage; + +@@ -62,6 +64,8 @@ struct _MetaSurfaceActorX11 + guint size_changed : 1; + + guint unredirected : 1; ++ ++ guint stereo : 1; + }; + + G_DEFINE_TYPE (MetaSurfaceActorX11, +@@ -101,7 +105,7 @@ detach_pixmap (MetaSurfaceActorX11 *self) + * you are supposed to be able to free a GLXPixmap after freeing the underlying + * pixmap, but it certainly doesn't work with current DRI/Mesa + */ +- meta_shaped_texture_set_texture (stex, NULL); ++ meta_shaped_texture_set_textures (stex, NULL, NULL); + cogl_flush (); + + meta_x11_error_trap_push (display->x11_display); +@@ -110,6 +114,7 @@ detach_pixmap (MetaSurfaceActorX11 *self) + meta_x11_error_trap_pop (display->x11_display); + + g_clear_pointer (&self->texture, cogl_object_unref); ++ g_clear_pointer (&self->texture_right, cogl_object_unref); + } + + static void +@@ -119,23 +124,37 @@ set_pixmap (MetaSurfaceActorX11 *self, + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + GError *error = NULL; +- CoglTexture *texture; ++ CoglTexturePixmapX11 *texture; ++ CoglTexturePixmapX11 *texture_right; + + g_assert (self->pixmap == None); + self->pixmap = pixmap; + +- texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error)); ++ if (self->stereo) ++ texture = cogl_texture_pixmap_x11_new_left (ctx, pixmap, FALSE, &error); ++ else ++ texture = cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, &error); ++ ++ if (self->stereo) ++ texture_right = cogl_texture_pixmap_x11_new_right (texture); ++ else ++ texture_right = NULL; + + if (error != NULL) + { + g_warning ("Failed to allocate stex texture: %s", error->message); + g_error_free (error); + } +- else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) ++ else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (texture))) + g_warning ("NOTE: Not using GLX TFP!"); + +- self->texture = texture; +- meta_shaped_texture_set_texture (stex, texture); ++ self->texture = COGL_TEXTURE (texture); ++ if (self->stereo) ++ self->texture_right = COGL_TEXTURE (texture_right); ++ ++ meta_shaped_texture_set_textures (stex, ++ COGL_TEXTURE (texture), ++ COGL_TEXTURE (texture_right));; + } + + static void +@@ -372,8 +391,8 @@ reset_texture (MetaSurfaceActorX11 *self) + /* Setting the texture to NULL will cause all the FBO's cached by the + * shaped texture's MetaTextureTower to be discarded and recreated. + */ +- meta_shaped_texture_set_texture (stex, NULL); +- meta_shaped_texture_set_texture (stex, self->texture); ++ meta_shaped_texture_set_textures (stex, NULL, NULL); ++ meta_shaped_texture_set_textures (stex, self->texture, self->texture_right); + } + + MetaSurfaceActor * +@@ -381,12 +400,18 @@ meta_surface_actor_x11_new (MetaWindow *window) + { + MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); + MetaDisplay *display = meta_window_get_display (window); ++ MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (display->compositor); ++ Window xwindow; + + g_assert (!meta_is_wayland_compositor ()); + + self->window = window; + self->display = display; + ++ xwindow = meta_window_x11_get_toplevel_xwindow (window); ++ self->stereo = meta_compositor_x11_window_is_stereo (compositor_x11, xwindow); ++ meta_compositor_x11_select_stereo_notify (compositor_x11, xwindow); ++ + g_signal_connect_object (self->display, "gl-video-memory-purged", + G_CALLBACK (reset_texture), self, G_CONNECT_SWAPPED); + +@@ -420,3 +445,17 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + self->last_height = height; + meta_shaped_texture_set_fallback_size (stex, width, height); + } ++ ++void ++meta_surface_actor_x11_stereo_notify (MetaSurfaceActorX11 *self, ++ gboolean stereo_tree) ++{ ++ self->stereo = stereo_tree != FALSE; ++ detach_pixmap (self); ++} ++ ++gboolean ++meta_surface_actor_x11_is_stereo (MetaSurfaceActorX11 *self) ++{ ++ return self->stereo; ++} +diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h +index 0a8517236a..369f631ae0 100644 +--- a/src/compositor/meta-surface-actor-x11.h ++++ b/src/compositor/meta-surface-actor-x11.h +@@ -57,6 +57,11 @@ gboolean meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self); + + void meta_surface_actor_x11_handle_updates (MetaSurfaceActorX11 *self); + ++void meta_surface_actor_x11_stereo_notify (MetaSurfaceActorX11 *self, ++ gboolean stereo_tree); ++ ++gboolean meta_surface_actor_x11_is_stereo (MetaSurfaceActorX11 *self); ++ + G_END_DECLS + + #endif /* __META_SURFACE_ACTOR_X11_H__ */ +diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h +index 64741e4167..d498879902 100644 +--- a/src/compositor/meta-window-actor-private.h ++++ b/src/compositor/meta-window-actor-private.h +@@ -99,4 +99,9 @@ void meta_window_actor_update_regions (MetaWindowActor *self); + + gboolean meta_window_actor_can_freeze_commits (MetaWindowActor *self); + ++void meta_window_actor_stereo_notify (MetaWindowActor *actor, ++ gboolean stereo_tree); ++ ++gboolean meta_window_actor_is_stereo (MetaWindowActor *actor); ++ + #endif /* META_WINDOW_ACTOR_PRIVATE_H */ +diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c +index d4fc9a43a0..56c85e1788 100644 +--- a/src/compositor/meta-window-actor.c ++++ b/src/compositor/meta-window-actor.c +@@ -1557,3 +1557,25 @@ out: + clutter_actor_uninhibit_culling (actor); + return surface; + } ++ ++void ++meta_window_actor_stereo_notify (MetaWindowActor *self, ++ gboolean stereo_tree) ++{ ++ MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self); ++ ++ if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) ++ meta_surface_actor_x11_stereo_notify (META_SURFACE_ACTOR_X11 (priv->surface), ++ stereo_tree); ++} ++ ++gboolean ++meta_window_actor_is_stereo (MetaWindowActor *self) ++{ ++ MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self); ++ ++ if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) ++ return meta_surface_actor_x11_is_stereo (META_SURFACE_ACTOR_X11 (priv->surface)); ++ else ++ return FALSE; ++} +diff --git a/src/core/main.c b/src/core/main.c +index 6dabcfe73e..a07dda9ecc 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -88,6 +88,7 @@ + #include "meta/meta-backend.h" + #include "meta/meta-x11-errors.h" + #include "meta/prefs.h" ++#include "stereo.h" + #include "ui/ui.h" + #include "x11/session.h" + +@@ -848,6 +849,9 @@ meta_init (void) + if (!meta_is_wayland_compositor ()) + meta_select_display (opt_display_name); + ++ if (!meta_is_wayland_compositor ()) ++ meta_stereo_init (); ++ + meta_init_backend (backend_gtype, n_properties, prop_names, prop_values); + + for (i = 0; i < n_properties; i++) +diff --git a/src/core/stereo.c b/src/core/stereo.c +new file mode 100644 +index 0000000000..817056527f +--- /dev/null ++++ b/src/core/stereo.c +@@ -0,0 +1,154 @@ ++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ ++ ++/* ++ * Copyright (C) 2014 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++/* ++ * SECTION:stereo ++ * @short_description: Keep track of whether we are a stereo compositor ++ * ++ * With GLX, we need to use a different GL context for stereo and ++ * non-stereo support. Support for multiple GL contexts is unfinished ++ * in Cogl and entirely lacking in Clutter, so it's by far easier ++ * to just restart Mutter when we detect a stereo window. ++ * ++ * A property _MUTTER_ENABLE_STEREO is maintained on the root window ++ * to know whether we should initialize clutter for stereo or not. ++ * When the presence or absence of stereo windows mismatches the ++ * stereo-enabled state for a sufficiently long period of time, ++ * we restart Mutter. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "display-private.h" ++#include ++#include ++#include ++#include "stereo.h" ++#include "ui/ui.h" ++#include "util-private.h" ++ ++static guint stereo_switch_id = 0; ++static gboolean stereo_enabled = FALSE; ++/* -1 so the first time meta_stereo_set_have_stereo_windows() is called ++ * we avoid the short-circuit and set up a timeout to restart ++ * if necessary */ ++static gboolean stereo_have_windows = (gboolean)-1; ++static gboolean stereo_restart = FALSE; ++ ++#define STEREO_ENABLE_WAIT 1000 ++#define STEREO_DISABLE_WAIT 5000 ++ ++void ++meta_stereo_init (void) ++{ ++ Display *xdisplay; ++ Window root; ++ Atom atom_enable_stereo; ++ Atom type; ++ int format; ++ unsigned long n_items, bytes_after; ++ guchar *data; ++ ++ xdisplay = XOpenDisplay (NULL); ++ if (xdisplay == NULL) ++ meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL)); ++ ++ root = DefaultRootWindow (xdisplay); ++ atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False); ++ ++ XGetWindowProperty (xdisplay, root, atom_enable_stereo, ++ 0, 1, False, XA_INTEGER, ++ &type, &format, &n_items, &bytes_after, &data); ++ if (type == XA_INTEGER) ++ { ++ if (format == 32 && n_items == 1 && bytes_after == 0) ++ { ++ stereo_enabled = *(long *)data; ++ } ++ else ++ { ++ meta_warning ("Bad value for _MUTTER_ENABLE_STEREO property\n"); ++ } ++ ++ XFree (data); ++ } ++ else if (type != None) ++ { ++ meta_warning ("Bad type for _MUTTER_ENABLE_STEREO property\n"); ++ } ++ ++ meta_verbose ("On startup, _MUTTER_ENABLE_STEREO=%s", ++ stereo_enabled ? "yes" : "no"); ++ clutter_x11_set_use_stereo_stage (stereo_enabled); ++ XCloseDisplay (xdisplay); ++} ++ ++static gboolean ++meta_stereo_switch (gpointer data) ++{ ++ stereo_switch_id = 0; ++ stereo_restart = TRUE; ++ ++ meta_restart (stereo_have_windows ? ++ _("Enabling stereo...") : ++ _("Disabling stereo...")); ++ ++ return FALSE; ++} ++ ++void ++meta_stereo_set_have_stereo_windows (gboolean have_windows) ++{ ++ have_windows = have_windows != FALSE; ++ ++ if (!stereo_restart && have_windows != stereo_have_windows) ++ { ++ MetaDisplay *display = meta_get_display (); ++ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); ++ Window root = DefaultRootWindow (xdisplay); ++ Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False); ++ long value; ++ ++ stereo_have_windows = have_windows; ++ ++ if (stereo_have_windows) ++ meta_verbose ("Detected stereo windows\n"); ++ else ++ meta_verbose ("No stereo windows detected\n"); ++ ++ value = stereo_have_windows; ++ XChangeProperty (xdisplay, root, ++ atom_enable_stereo, XA_INTEGER, 32, ++ PropModeReplace, (guchar *)&value, 1); ++ ++ if (stereo_switch_id != 0) ++ { ++ g_source_remove (stereo_switch_id); ++ stereo_switch_id = 0; ++ } ++ ++ if (stereo_have_windows != stereo_enabled) ++ stereo_switch_id = g_timeout_add (stereo_have_windows ? STEREO_ENABLE_WAIT : STEREO_DISABLE_WAIT, ++ meta_stereo_switch, NULL); ++ } ++} +diff --git a/src/core/stereo.h b/src/core/stereo.h +new file mode 100644 +index 0000000000..ccd1d702a1 +--- /dev/null ++++ b/src/core/stereo.h +@@ -0,0 +1,28 @@ ++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ ++ ++/* ++ * Copyright (C) 2014 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#ifndef META_STEREO_H ++#define META_STEREO_H ++ ++void meta_stereo_init (void); ++void meta_stereo_set_have_stereo_windows (gboolean have_windows); ++gboolean meta_stereo_is_restart (void); ++void meta_stereo_finish_restart (void); ++ ++#endif +diff --git a/src/meson.build b/src/meson.build +index 284bdf5220..c56438fbbe 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -394,6 +394,8 @@ mutter_sources = [ + 'core/stack.h', + 'core/stack-tracker.c', + 'core/stack-tracker.h', ++ 'core/stereo.c', ++ 'core/stereo.h', + 'core/startup-notification.c', + 'core/startup-notification-private.h', + 'core/util.c', +diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c +index 797795f861..d8d1f3ce16 100644 +--- a/src/wayland/meta-wayland-actor-surface.c ++++ b/src/wayland/meta-wayland-actor-surface.c +@@ -193,7 +193,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor + snippet = meta_wayland_buffer_create_snippet (buffer); + is_y_inverted = meta_wayland_buffer_is_y_inverted (buffer); + +- meta_shaped_texture_set_texture (stex, surface->texture); ++ meta_shaped_texture_set_textures (stex, surface->texture, NULL); + meta_shaped_texture_set_snippet (stex, snippet); + meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted); + meta_shaped_texture_set_buffer_scale (stex, surface->scale); +@@ -201,7 +201,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor + } + else + { +- meta_shaped_texture_set_texture (stex, NULL); ++ meta_shaped_texture_set_textures (stex, NULL, NULL); + } + + surface_rect = (cairo_rectangle_int_t) { +-- +2.31.1 + + +From 36517cd245584c5bcd3b730efaf6c3d2e7c9472d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 2 Jun 2021 16:55:45 +0200 +Subject: [PATCH 2/2] compositor: Only check for stereo when using GLX + +If EGL Xlib is used, we'll get bogus return value and crash. +--- + src/compositor/meta-compositor-x11.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c +index afbe3f57e2..4345f38b6f 100644 +--- a/src/compositor/meta-compositor-x11.c ++++ b/src/compositor/meta-compositor-x11.c +@@ -153,9 +153,17 @@ meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, + static gboolean + display_has_stereo_tree_ext (MetaX11Display *x11_display) + { ++ MetaBackend *backend = meta_get_backend (); ++ ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); ++ CoglContext *cogl_context = ++ clutter_backend_get_cogl_context (clutter_backend); ++ CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context); + Display *xdisplay = x11_display->xdisplay; + const char *extensions_string; + ++ if (cogl_renderer_get_winsys_id (cogl_renderer) != COGL_WINSYS_ID_GLX) ++ return FALSE; ++ + static const char * (*query_extensions_string) (Display *display, + int screen); + +-- +2.31.1 + diff --git a/SOURCES/legacy-x11-input-configuration.patch b/SOURCES/legacy-x11-input-configuration.patch new file mode 100644 index 0000000..597e0d7 --- /dev/null +++ b/SOURCES/legacy-x11-input-configuration.patch @@ -0,0 +1,819 @@ +From 705818340dec181335b48ab73d6411e639daaeae Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 1 Jun 2021 11:44:20 +0200 +Subject: [PATCH 1/6] backends/x11: Support synaptics configuration + +The code is taken mostly as-is from g-s-d, so we can drag the +dead horse a bit longer. +--- + src/backends/x11/meta-input-settings-x11.c | 275 +++++++++++++++++++++ + 1 file changed, 275 insertions(+) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 96390285a6..0631fd2fee 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -26,6 +26,7 @@ + #include "backends/x11/meta-input-settings-x11.h" + + #include ++#include + #include + #include + #include +@@ -165,6 +166,184 @@ change_property (ClutterInputDevice *device, + meta_XFree (data_ret); + } + ++static gboolean ++is_device_synaptics (ClutterInputDevice *device) ++{ ++ guchar *has_setting; ++ ++ /* We just need looking for a synaptics-specific property */ ++ has_setting = get_property (device, "Synaptics Off", XA_INTEGER, 8, 1); ++ if (!has_setting) ++ return FALSE; ++ ++ meta_XFree (has_setting); ++ return TRUE; ++} ++ ++static void ++change_synaptics_tap_left_handed (ClutterInputDevice *device, ++ gboolean tap_enabled, ++ gboolean left_handed) ++{ ++ MetaDisplay *display = meta_get_display (); ++ MetaX11Display *x11_display = display ? display->x11_display : NULL; ++ MetaBackend *backend = meta_get_backend (); ++ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ int device_id; ++ XDevice *xdevice; ++ guchar *tap_action, *buttons; ++ guint buttons_capacity = 16, n_buttons; ++ ++ device_id = meta_input_device_x11_get_device_id (device); ++ xdevice = XOpenDevice (xdisplay, device_id); ++ if (!xdevice) ++ return; ++ ++ tap_action = get_property (device, "Synaptics Tap Action", ++ XA_INTEGER, 8, 7); ++ if (!tap_action) ++ goto out; ++ ++ tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0; ++ tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0; ++ tap_action[6] = tap_enabled ? 2 : 0; ++ ++ change_property (device, "Synaptics Tap Action", ++ XA_INTEGER, 8, tap_action, 7); ++ meta_XFree (tap_action); ++ ++ if (x11_display) ++ meta_x11_error_trap_push (x11_display); ++ buttons = g_new (guchar, buttons_capacity); ++ n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice, ++ buttons, buttons_capacity); ++ ++ while (n_buttons > buttons_capacity) ++ { ++ buttons_capacity = n_buttons; ++ buttons = (guchar *) g_realloc (buttons, ++ buttons_capacity * sizeof (guchar)); ++ ++ n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice, ++ buttons, buttons_capacity); ++ } ++ ++ buttons[0] = left_handed ? 3 : 1; ++ buttons[2] = left_handed ? 1 : 3; ++ XSetDeviceButtonMapping (xdisplay, xdevice, buttons, n_buttons); ++ g_free (buttons); ++ ++ if (x11_display && meta_x11_error_trap_pop_with_return (x11_display)) ++ { ++ g_warning ("Could not set synaptics touchpad left-handed for %s", ++ clutter_input_device_get_device_name (device)); ++ } ++ ++ out: ++ XCloseDevice (xdisplay, xdevice); ++} ++ ++static void ++change_synaptics_speed (ClutterInputDevice *device, ++ gdouble speed) ++{ ++ MetaDisplay *display = meta_get_display (); ++ MetaX11Display *x11_display = display ? display->x11_display : NULL; ++ MetaBackend *backend = meta_get_backend (); ++ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ int device_id; ++ XDevice *xdevice; ++ XPtrFeedbackControl feedback; ++ XFeedbackState *states, *state; ++ int i, num_feedbacks, motion_threshold, numerator, denominator; ++ gfloat motion_acceleration; ++ ++ device_id = meta_input_device_x11_get_device_id (device); ++ xdevice = XOpenDevice (xdisplay, device_id); ++ if (!xdevice) ++ return; ++ /* Get the list of feedbacks for the device */ ++ states = XGetFeedbackControl (xdisplay, xdevice, &num_feedbacks); ++ if (!states) ++ return; ++ ++ /* Calculate acceleration and threshold */ ++ motion_acceleration = (speed + 1) * 5; /* speed is [-1..1], map to [0..10] */ ++ motion_threshold = CLAMP (10 - floor (motion_acceleration), 1, 10); ++ ++ if (motion_acceleration >= 1.0) ++ { ++ /* we want to get the acceleration, with a resolution of 0.5 ++ */ ++ if ((motion_acceleration - floor (motion_acceleration)) < 0.25) ++ { ++ numerator = floor (motion_acceleration); ++ denominator = 1; ++ } ++ else if ((motion_acceleration - floor (motion_acceleration)) < 0.5) ++ { ++ numerator = ceil (2.0 * motion_acceleration); ++ denominator = 2; ++ } ++ else if ((motion_acceleration - floor (motion_acceleration)) < 0.75) ++ { ++ numerator = floor (2.0 *motion_acceleration); ++ denominator = 2; ++ } ++ else ++ { ++ numerator = ceil (motion_acceleration); ++ denominator = 1; ++ } ++ } ++ else if (motion_acceleration < 1.0 && motion_acceleration > 0) ++ { ++ /* This we do to 1/10ths */ ++ numerator = floor (motion_acceleration * 10) + 1; ++ denominator= 10; ++ } ++ else ++ { ++ numerator = -1; ++ denominator = -1; ++ } ++ ++ if (x11_display) ++ meta_x11_error_trap_push (x11_display); ++ ++ state = (XFeedbackState *) states; ++ ++ for (i = 0; i < num_feedbacks; i++) ++ { ++ if (state->class == PtrFeedbackClass) ++ { ++ /* And tell the device */ ++ feedback.class = PtrFeedbackClass; ++ feedback.length = sizeof (XPtrFeedbackControl); ++ feedback.id = state->id; ++ feedback.threshold = motion_threshold; ++ feedback.accelNum = numerator; ++ feedback.accelDenom = denominator; ++ ++ XChangeFeedbackControl (xdisplay, xdevice, ++ DvAccelNum | DvAccelDenom | DvThreshold, ++ (XFeedbackControl *) &feedback); ++ break; ++ } ++ ++ state = (XFeedbackState *) ((char *) state + state->length); ++ } ++ ++ if (x11_display && meta_x11_error_trap_pop_with_return (x11_display)) ++ { ++ g_warning ("Could not set synaptics touchpad acceleration for %s", ++ clutter_input_device_get_device_name (device)); ++ } ++ ++ XFreeFeedbackList (states); ++ XCloseDevice (xdisplay, xdevice); ++} ++ + static void + meta_input_settings_x11_set_send_events (MetaInputSettings *settings, + ClutterInputDevice *device, +@@ -173,6 +352,13 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings, + guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */ + guchar *available; + ++ if (is_device_synaptics (device)) ++ { ++ values[0] = mode != G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED; ++ change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1); ++ return; ++ } ++ + available = get_property (device, "libinput Send Events Modes Available", + XA_INTEGER, 8, 2); + if (!available) +@@ -225,6 +411,12 @@ meta_input_settings_x11_set_speed (MetaInputSettings *settings, + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + gfloat value = speed; + ++ if (is_device_synaptics (device)) ++ { ++ change_synaptics_speed (device, speed); ++ return; ++ } ++ + change_property (device, "libinput Accel Speed", + XInternAtom (xdisplay, "FLOAT", False), + 32, &value, 1); +@@ -251,6 +443,19 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings, + else + { + value = enabled ? 1 : 0; ++ ++ if (is_device_synaptics (device)) ++ { ++ GSettings *settings; ++ ++ settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad"); ++ change_synaptics_tap_left_handed (device, ++ g_settings_get_boolean (settings, "tap-to-click"), ++ enabled); ++ g_object_unref (settings); ++ return; ++ } ++ + change_property (device, "libinput Left Handed Enabled", + XA_INTEGER, 8, &value, 1); + } +@@ -274,6 +479,20 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings, + { + guchar value = (enabled) ? 1 : 0; + ++ if (is_device_synaptics (device)) ++ { ++ GDesktopTouchpadHandedness handedness; ++ GSettings *settings; ++ ++ settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad"); ++ handedness = g_settings_get_enum (settings, "left-handed"); ++ g_object_unref (settings); ++ ++ change_synaptics_tap_left_handed (device, enabled, ++ handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT); ++ return; ++ } ++ + change_property (device, "libinput Tapping Enabled", + XA_INTEGER, 8, &value, 1); + } +@@ -307,6 +526,27 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings, + { + guchar value = (inverted) ? 1 : 0; + ++ if (is_device_synaptics (device)) ++ { ++ gint32 *scrolling_distance; ++ ++ scrolling_distance = get_property (device, "Synaptics Scrolling Distance", ++ XA_INTEGER, 32, 2); ++ if (scrolling_distance) ++ { ++ scrolling_distance[0] = inverted ? ++ -abs (scrolling_distance[0]) : abs (scrolling_distance[0]); ++ scrolling_distance[1] = inverted ? ++ -abs (scrolling_distance[1]) : abs (scrolling_distance[1]); ++ ++ change_property (device, "Synaptics Scrolling Distance", ++ XA_INTEGER, 32, scrolling_distance, 2); ++ meta_XFree (scrolling_distance); ++ } ++ ++ return; ++ } ++ + change_property (device, "libinput Natural Scrolling Enabled", + XA_INTEGER, 8, &value, 1); + } +@@ -320,6 +560,41 @@ change_scroll_method (ClutterInputDevice *device, + guchar *current = NULL; + guchar *available = NULL; + ++ if (is_device_synaptics (device)) ++ { ++ switch (method) ++ { ++ case SCROLL_METHOD_FIELD_EDGE: ++ current = get_property (device, "Synaptics Edge Scrolling", ++ XA_INTEGER, 8, 3); ++ if (current) ++ { ++ current[0] = enabled; ++ current[1] = enabled; ++ change_property (device, "Synaptics Edge Scrolling", ++ XA_INTEGER, 8, current, 3); ++ meta_XFree (current); ++ } ++ break; ++ case SCROLL_METHOD_FIELD_2FG: ++ current = get_property (device, "Synaptics Two-Finger Scrolling", ++ XA_INTEGER, 8, 2); ++ if (current) ++ { ++ current[0] = enabled; ++ current[1] = enabled; ++ change_property (device, "Synaptics Two-Finger Scrolling", ++ XA_INTEGER, 8, current, 2); ++ meta_XFree (current); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return; ++ } ++ + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[method]) +-- +2.31.1 + + +From 50c4733acf56b3b67a2706d32f5c455cb51f9458 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 13 Feb 2018 11:44:40 +0100 +Subject: [PATCH 2/6] clutter: Extend touchpad device property check for + Synaptics + +So we reliably get CLUTTER_TOUCHPAD_DEVICE for those. The other heuristics +to get the device type may fall short. +--- + src/backends/x11/meta-seat-x11.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c +index d43834bd7b..73938e22e0 100644 +--- a/src/backends/x11/meta-seat-x11.c ++++ b/src/backends/x11/meta-seat-x11.c +@@ -246,7 +246,8 @@ is_touch_device (XIAnyClassInfo **classes, + } + + static gboolean +-is_touchpad_device (XIDeviceInfo *info) ++query_exists_device_property (XIDeviceInfo *info, ++ const char *property) + { + gulong nitems, bytes_after; + uint32_t *data = NULL; +@@ -254,7 +255,7 @@ is_touchpad_device (XIDeviceInfo *info) + Atom type; + Atom prop; + +- prop = XInternAtom (clutter_x11_get_default_display (), "libinput Tapping Enabled", True); ++ prop = XInternAtom (clutter_x11_get_default_display (), property, True); + if (prop == None) + return FALSE; + +@@ -275,6 +276,18 @@ is_touchpad_device (XIDeviceInfo *info) + return TRUE; + } + ++static gboolean ++is_touchpad_device (XIDeviceInfo *info) ++{ ++ if (query_exists_device_property (info, "libinput Tapping Enabled")) ++ return TRUE; ++ ++ if (query_exists_device_property (info, "Synaptics Off")) ++ return TRUE; ++ ++ return FALSE; ++} ++ + static gboolean + get_device_ids (XIDeviceInfo *info, + char **vendor_id, +-- +2.31.1 + + +From 307970305d11cdca1b97c53c85bda8b809ff4f0f Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 9 Oct 2017 18:39:52 +0200 +Subject: [PATCH 3/6] backends/x11: Add a synaptics check for two finger scroll + availability + +Commit "backends/x11: Support synaptics configuration" added support +for synaptics two finger scrolling but didn't add the code to check +that it is available resulting in the upper layer always assuming it +isn't. +--- + src/backends/x11/meta-input-settings-x11.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 0631fd2fee..2ac080127c 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -638,6 +638,17 @@ meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings *settings, + guchar *available = NULL; + gboolean has_two_finger = TRUE; + ++ if (is_device_synaptics (device)) ++ { ++ available = get_property (device, "Synaptics Capabilities", ++ XA_INTEGER, 8, 4); ++ if (!available || !available[3]) ++ has_two_finger = FALSE; ++ ++ meta_XFree (available); ++ return has_two_finger; ++ } ++ + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_2FG]) +-- +2.31.1 + + +From cba31f88ddbfb7355de1daa34397aba8e8607765 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 9 Oct 2017 18:55:56 +0200 +Subject: [PATCH 4/6] backends/x11: Add disable while typing support for + synaptics + +This is basically a copy of the old g-s-d mouse plugin code to manage +syndaemon when the synaptics driver is being used. +--- + src/backends/x11/meta-input-settings-x11.c | 112 +++++++++++++++++++++ + 1 file changed, 112 insertions(+) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 2ac080127c..2658b82172 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -35,6 +35,9 @@ + #ifdef HAVE_LIBGUDEV + #include + #endif ++#ifdef __linux ++#include ++#endif + + #include "backends/x11/meta-backend-x11.h" + #include "backends/x11/meta-input-device-x11.h" +@@ -46,6 +49,8 @@ typedef struct _MetaInputSettingsX11Private + #ifdef HAVE_LIBGUDEV + GUdevClient *udev_client; + #endif ++ gboolean syndaemon_spawned; ++ GPid syndaemon_pid; + } MetaInputSettingsX11Private; + + G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11, +@@ -344,6 +349,107 @@ change_synaptics_speed (ClutterInputDevice *device, + XCloseDevice (xdisplay, xdevice); + } + ++/* Ensure that syndaemon dies together with us, to avoid running several of ++ * them */ ++static void ++setup_syndaemon (gpointer user_data) ++{ ++#ifdef __linux ++ prctl (PR_SET_PDEATHSIG, SIGHUP); ++#endif ++} ++ ++static gboolean ++have_program_in_path (const char *name) ++{ ++ gchar *path; ++ gboolean result; ++ ++ path = g_find_program_in_path (name); ++ result = (path != NULL); ++ g_free (path); ++ return result; ++} ++ ++static void ++syndaemon_died (GPid pid, ++ gint status, ++ gpointer user_data) ++{ ++ MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (user_data); ++ MetaInputSettingsX11Private *priv = ++ meta_input_settings_x11_get_instance_private (settings_x11); ++ GError *error = NULL; ++ ++ if (!g_spawn_check_exit_status (status, &error)) ++ { ++ if ((WIFSIGNALED (status) && WTERMSIG (status) != SIGHUP) || ++ error->domain == G_SPAWN_EXIT_ERROR) ++ g_warning ("Syndaemon exited unexpectedly: %s", error->message); ++ g_error_free (error); ++ } ++ ++ g_spawn_close_pid (pid); ++ priv->syndaemon_spawned = FALSE; ++} ++ ++static void ++set_synaptics_disable_w_typing (MetaInputSettings *settings, ++ gboolean state) ++{ ++ MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (settings); ++ MetaInputSettingsX11Private *priv = ++ meta_input_settings_x11_get_instance_private (settings_x11); ++ ++ if (state) ++ { ++ GError *error = NULL; ++ GPtrArray *args; ++ ++ if (priv->syndaemon_spawned) ++ return; ++ ++ if (!have_program_in_path ("syndaemon")) ++ return; ++ ++ args = g_ptr_array_new (); ++ ++ g_ptr_array_add (args, (gpointer)"syndaemon"); ++ g_ptr_array_add (args, (gpointer)"-i"); ++ g_ptr_array_add (args, (gpointer)"1.0"); ++ g_ptr_array_add (args, (gpointer)"-t"); ++ g_ptr_array_add (args, (gpointer)"-K"); ++ g_ptr_array_add (args, (gpointer)"-R"); ++ g_ptr_array_add (args, NULL); ++ ++ /* we must use G_SPAWN_DO_NOT_REAP_CHILD to avoid ++ * double-forking, otherwise syndaemon will immediately get ++ * killed again through (PR_SET_PDEATHSIG when the intermediate ++ * process dies */ ++ g_spawn_async (g_get_home_dir (), (char **) args->pdata, NULL, ++ G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, setup_syndaemon, NULL, ++ &priv->syndaemon_pid, &error); ++ ++ priv->syndaemon_spawned = (error == NULL); ++ g_ptr_array_free (args, TRUE); ++ ++ if (error) ++ { ++ g_warning ("Failed to launch syndaemon: %s", error->message); ++ g_error_free (error); ++ } ++ else ++ { ++ g_child_watch_add (priv->syndaemon_pid, syndaemon_died, settings); ++ } ++ } ++ else if (priv->syndaemon_spawned) ++ { ++ kill (priv->syndaemon_pid, SIGHUP); ++ priv->syndaemon_spawned = FALSE; ++ } ++} ++ + static void + meta_input_settings_x11_set_send_events (MetaInputSettings *settings, + ClutterInputDevice *device, +@@ -468,6 +574,12 @@ meta_input_settings_x11_set_disable_while_typing (MetaInputSettings *settings, + { + guchar value = (enabled) ? 1 : 0; + ++ if (is_device_synaptics (device)) ++ { ++ set_synaptics_disable_w_typing (settings, enabled); ++ return; ++ } ++ + change_property (device, "libinput Disable While Typing Enabled", + XA_INTEGER, 8, &value, 1); + } +-- +2.31.1 + + +From 354d34263534d0c7a5c7f7169d8b4a3dba79491c Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Wed, 13 Jun 2018 13:48:24 +0200 +Subject: [PATCH 5/6] clutter: Only reset scroll axes on slave devices + +As a plus, unknown source device IDs will just warn instead of crash. +--- + src/backends/x11/meta-seat-x11.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c +index 73938e22e0..6d2c7d3740 100644 +--- a/src/backends/x11/meta-seat-x11.c ++++ b/src/backends/x11/meta-seat-x11.c +@@ -2362,7 +2362,9 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, + seat->has_pointer_focus = FALSE; + } + +- meta_input_device_x11_reset_scroll_info (source_device); ++ if (clutter_input_device_get_device_mode (source_device) == ++ CLUTTER_INPUT_MODE_PHYSICAL) ++ meta_input_device_x11_reset_scroll_info (source_device); + + clutter_event_set_device (event, device); + clutter_event_set_source_device (event, source_device); +-- +2.31.1 + + +From b7f94b5dd09953d5a4c8aee1b79491d71f8c1e0e Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Tue, 10 Oct 2017 19:07:27 +0200 +Subject: [PATCH 6/6] backends/x11: Support plain old X device configuration + +We re-use part of the code added to support synaptics and add a few +bits specific for xorg-x11-drv-evdev devices. +--- + src/backends/x11/meta-input-settings-x11.c | 98 +++++++++++++++++----- + 1 file changed, 75 insertions(+), 23 deletions(-) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 2658b82172..80bc33c6b5 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -185,10 +185,23 @@ is_device_synaptics (ClutterInputDevice *device) + return TRUE; + } + ++static gboolean ++is_device_libinput (ClutterInputDevice *device) ++{ ++ guchar *has_setting; ++ ++ /* We just need looking for a synaptics-specific property */ ++ has_setting = get_property (device, "libinput Send Events Modes Available", XA_INTEGER, 8, 2); ++ if (!has_setting) ++ return FALSE; ++ ++ meta_XFree (has_setting); ++ return TRUE; ++} ++ + static void +-change_synaptics_tap_left_handed (ClutterInputDevice *device, +- gboolean tap_enabled, +- gboolean left_handed) ++change_x_device_left_handed (ClutterInputDevice *device, ++ gboolean left_handed) + { + MetaDisplay *display = meta_get_display (); + MetaX11Display *x11_display = display ? display->x11_display : NULL; +@@ -196,7 +209,7 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device, + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + int device_id; + XDevice *xdevice; +- guchar *tap_action, *buttons; ++ guchar *buttons; + guint buttons_capacity = 16, n_buttons; + + device_id = meta_input_device_x11_get_device_id (device); +@@ -204,19 +217,6 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device, + if (!xdevice) + return; + +- tap_action = get_property (device, "Synaptics Tap Action", +- XA_INTEGER, 8, 7); +- if (!tap_action) +- goto out; +- +- tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0; +- tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0; +- tap_action[6] = tap_enabled ? 2 : 0; +- +- change_property (device, "Synaptics Tap Action", +- XA_INTEGER, 8, tap_action, 7); +- meta_XFree (tap_action); +- + if (x11_display) + meta_x11_error_trap_push (x11_display); + buttons = g_new (guchar, buttons_capacity); +@@ -240,17 +240,39 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device, + + if (x11_display && meta_x11_error_trap_pop_with_return (x11_display)) + { +- g_warning ("Could not set synaptics touchpad left-handed for %s", ++ g_warning ("Could not set left-handed for %s", + clutter_input_device_get_device_name (device)); + } + +- out: + XCloseDevice (xdisplay, xdevice); + } + + static void +-change_synaptics_speed (ClutterInputDevice *device, +- gdouble speed) ++change_synaptics_tap_left_handed (ClutterInputDevice *device, ++ gboolean tap_enabled, ++ gboolean left_handed) ++{ ++ guchar *tap_action; ++ ++ tap_action = get_property (device, "Synaptics Tap Action", ++ XA_INTEGER, 8, 7); ++ if (!tap_action) ++ return; ++ ++ tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0; ++ tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0; ++ tap_action[6] = tap_enabled ? 2 : 0; ++ ++ change_property (device, "Synaptics Tap Action", ++ XA_INTEGER, 8, tap_action, 7); ++ meta_XFree (tap_action); ++ ++ change_x_device_left_handed (device, left_handed); ++} ++ ++static void ++change_x_device_speed (ClutterInputDevice *device, ++ gdouble speed) + { + MetaDisplay *display = meta_get_display (); + MetaX11Display *x11_display = display ? display->x11_display : NULL; +@@ -349,6 +371,23 @@ change_synaptics_speed (ClutterInputDevice *device, + XCloseDevice (xdisplay, xdevice); + } + ++static void ++change_x_device_scroll_button (ClutterInputDevice *device, ++ guint button) ++{ ++ guchar value; ++ ++ value = button > 0 ? 1 : 0; ++ change_property (device, "Evdev Wheel Emulation", ++ XA_INTEGER, 8, &value, 1); ++ if (button > 0) ++ { ++ value = button; ++ change_property (device, "Evdev Wheel Emulation Button", ++ XA_INTEGER, 8, &value, 1); ++ } ++} ++ + /* Ensure that syndaemon dies together with us, to avoid running several of + * them */ + static void +@@ -517,9 +556,10 @@ meta_input_settings_x11_set_speed (MetaInputSettings *settings, + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + gfloat value = speed; + +- if (is_device_synaptics (device)) ++ if (is_device_synaptics (device) || ++ !is_device_libinput (device)) + { +- change_synaptics_speed (device, speed); ++ change_x_device_speed (device, speed); + return; + } + +@@ -561,6 +601,11 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings, + g_object_unref (settings); + return; + } ++ else if (!is_device_libinput (device) && device_type != CLUTTER_PAD_DEVICE) ++ { ++ change_x_device_left_handed (device, enabled); ++ return; ++ } + + change_property (device, "libinput Left Handed Enabled", + XA_INTEGER, 8, &value, 1); +@@ -778,7 +823,14 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings, + { + gchar lock = button_lock; + ++ if (!is_device_libinput (device)) ++ { ++ change_x_device_scroll_button (device, button); ++ return; ++ } ++ + change_scroll_method (device, SCROLL_METHOD_FIELD_BUTTON, button != 0); ++ + change_property (device, "libinput Button Scrolling Button", + XA_CARDINAL, 32, &button, 1); + change_property (device, "libinput Button Scrolling Button Lock Enabled", +-- +2.31.1 + diff --git a/SOURCES/x11-monitor-configuration-patches.patch b/SOURCES/x11-monitor-configuration-patches.patch new file mode 100644 index 0000000..d0402be --- /dev/null +++ b/SOURCES/x11-monitor-configuration-patches.patch @@ -0,0 +1,1375 @@ +From 9c7c46384ec5e64fbfad84366c93ece52aabd26a Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Tue, 6 Oct 2015 21:16:18 +0200 +Subject: [PATCH 1/9] monitor-manager-xrandr: Work around spurious hotplugs on + Xvnc + +Xvnc turns its outputs off/on on every mode set which makes us believe +there was an hotplug when there actually wasn't. Work around this by +requiring new randr configuration timestamps to be ahead of the last +set timestamp by at least 100 ms for us to consider them an actual +hotplug. +--- + .../x11/meta-monitor-manager-xrandr.c | 21 ++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 489a9b4241..1ddc2a7870 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -1100,6 +1100,20 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) + g_quark_from_static_string ("-meta-monitor-xrandr-data"); + } + ++static gboolean ++is_xvnc (MetaMonitorManager *manager) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); ++ MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); ++ GList *l; ++ ++ for (l = meta_gpu_get_outputs (gpu); l; l = l->next) ++ if (g_str_has_prefix (meta_output_get_name (l->data), "VNC-")) ++ return TRUE; ++ ++ return FALSE; ++} ++ + gboolean + meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, + XEvent *event) +@@ -1110,6 +1124,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + XRRScreenResources *resources; + gboolean is_hotplug; + gboolean is_our_configuration; ++ unsigned int timestamp; + + if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) + return FALSE; +@@ -1121,7 +1136,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + gpu_xrandr = META_GPU_XRANDR (gpu); + resources = meta_gpu_xrandr_get_resources (gpu_xrandr); + +- is_hotplug = resources->timestamp < resources->configTimestamp; ++ timestamp = resources->timestamp; ++ if (is_xvnc (manager)) ++ timestamp += 100; ++ ++ is_hotplug = (timestamp < resources->configTimestamp); + is_our_configuration = (resources->timestamp == + manager_xrandr->last_xrandr_set_timestamp); + if (is_hotplug) +-- +2.31.1 + + +From 17d9494cc08e833a6e896daa4f85a15b81df1554 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 4 Jun 2018 16:35:04 -0400 +Subject: [PATCH 2/9] monitor-manager-xrandr: Force an update when resuming + from suspend + +The stack below us isn't as reliable as we'd like and in some cases +doesn't generate RRScreenChangeNotify events when e.g. resuming a +laptop on a dock, meaning that we'd miss newly attached outputs. +--- + src/backends/meta-gpu.c | 7 ++ + src/backends/meta-gpu.h | 4 + + src/backends/x11/meta-gpu-xrandr.c | 26 ++++- + .../x11/meta-monitor-manager-xrandr.c | 98 +++++++++++++++++-- + 4 files changed, 125 insertions(+), 10 deletions(-) + +diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c +index ce4353bf01..6b3086e747 100644 +--- a/src/backends/meta-gpu.c ++++ b/src/backends/meta-gpu.c +@@ -66,6 +66,13 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu) + return FALSE; + } + ++void ++meta_gpu_poll_hardware (MetaGpu *gpu) ++{ ++ if (META_GPU_GET_CLASS (gpu)->poll_hardware) ++ META_GPU_GET_CLASS (gpu)->poll_hardware (gpu); ++} ++ + gboolean + meta_gpu_read_current (MetaGpu *gpu, + GError **error) +diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h +index 9d12f95a72..37b76bd0fa 100644 +--- a/src/backends/meta-gpu.h ++++ b/src/backends/meta-gpu.h +@@ -36,8 +36,12 @@ struct _MetaGpuClass + + gboolean (* read_current) (MetaGpu *gpu, + GError **error); ++ void (* poll_hardware) (MetaGpu *gpu); + }; + ++META_EXPORT_TEST ++void meta_gpu_poll_hardware (MetaGpu *gpu); ++ + META_EXPORT_TEST + gboolean meta_gpu_read_current (MetaGpu *gpu, + GError **error); +diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c +index bc3292d368..6a96e53979 100644 +--- a/src/backends/x11/meta-gpu-xrandr.c ++++ b/src/backends/x11/meta-gpu-xrandr.c +@@ -46,6 +46,8 @@ struct _MetaGpuXrandr + + int max_screen_width; + int max_screen_height; ++ ++ gboolean need_hardware_poll; + }; + + G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU) +@@ -86,6 +88,14 @@ get_xmode_name (XRRModeInfo *xmode) + return g_strdup_printf ("%dx%d", width, height); + } + ++static void ++meta_gpu_xrandr_poll_hardware (MetaGpu *gpu) ++{ ++ MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu); ++ ++ gpu_xrandr->need_hardware_poll = TRUE; ++} ++ + static gboolean + meta_gpu_xrandr_read_current (MetaGpu *gpu, + GError **error) +@@ -123,8 +133,18 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, + monitor_manager->screen_width = WidthOfScreen (screen); + monitor_manager->screen_height = HeightOfScreen (screen); + +- resources = XRRGetScreenResourcesCurrent (xdisplay, +- DefaultRootWindow (xdisplay)); ++ if (gpu_xrandr->need_hardware_poll) ++ { ++ resources = XRRGetScreenResources (xdisplay, ++ DefaultRootWindow (xdisplay)); ++ gpu_xrandr->need_hardware_poll = FALSE; ++ } ++ else ++ { ++ resources = XRRGetScreenResourcesCurrent (xdisplay, ++ DefaultRootWindow (xdisplay)); ++ } ++ + if (!resources) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, +@@ -263,6 +283,7 @@ meta_gpu_xrandr_finalize (GObject *object) + static void + meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr) + { ++ gpu_xrandr->need_hardware_poll = TRUE; + } + + static void +@@ -274,4 +295,5 @@ meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass) + object_class->finalize = meta_gpu_xrandr_finalize; + + gpu_class->read_current = meta_gpu_xrandr_read_current; ++ gpu_class->poll_hardware = meta_gpu_xrandr_poll_hardware; + } +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 1ddc2a7870..61e13f459d 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -72,6 +72,10 @@ struct _MetaMonitorManagerXrandr + Display *xdisplay; + int rr_event_base; + int rr_error_base; ++ ++ guint logind_watch_id; ++ guint logind_signal_sub_id; ++ + gboolean has_randr15; + + xcb_timestamp_t last_xrandr_set_timestamp; +@@ -96,6 +100,8 @@ typedef struct _MetaMonitorXrandrData + + GQuark quark_meta_monitor_xrandr_data; + ++static void meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr); ++ + Display * + meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr) + { +@@ -1009,6 +1015,64 @@ meta_monitor_manager_xrandr_set_output_ctm (MetaOutput *output, + meta_output_xrandr_set_ctm (META_OUTPUT_XRANDR (output), ctm); + } + ++static void ++logind_signal_handler (GDBusConnection *connection, ++ const gchar *sender_name, ++ const gchar *object_path, ++ const gchar *interface_name, ++ const gchar *signal_name, ++ GVariant *parameters, ++ gpointer user_data) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = user_data; ++ gboolean suspending; ++ ++ if (!g_str_equal (signal_name, "PrepareForSleep")) ++ return; ++ ++ g_variant_get (parameters, "(b)", &suspending); ++ if (!suspending) ++ { ++ MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); ++ ++ meta_gpu_poll_hardware (gpu); ++ meta_monitor_manager_xrandr_update (manager_xrandr); ++ } ++} ++ ++static void ++logind_appeared (GDBusConnection *connection, ++ const gchar *name, ++ const gchar *name_owner, ++ gpointer user_data) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = user_data; ++ ++ manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection, ++ "org.freedesktop.login1", ++ "org.freedesktop.login1.Manager", ++ "PrepareForSleep", ++ "/org/freedesktop/login1", ++ NULL, ++ G_DBUS_SIGNAL_FLAGS_NONE, ++ logind_signal_handler, ++ manager_xrandr, ++ NULL); ++} ++ ++static void ++logind_vanished (GDBusConnection *connection, ++ const gchar *name, ++ gpointer user_data) ++{ ++ MetaMonitorManagerXrandr *manager_xrandr = user_data; ++ ++ if (connection && manager_xrandr->logind_signal_sub_id > 0) ++ g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id); ++ ++ manager_xrandr->logind_signal_sub_id = 0; ++} ++ + static void + meta_monitor_manager_xrandr_constructed (GObject *object) + { +@@ -1061,12 +1125,23 @@ meta_monitor_manager_xrandr_finalize (GObject *object) + g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms); + g_free (manager_xrandr->supported_scales); + ++ if (manager_xrandr->logind_watch_id > 0) ++ g_bus_unwatch_name (manager_xrandr->logind_watch_id); ++ manager_xrandr->logind_watch_id = 0; ++ + G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); + } + + static void + meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) + { ++ manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, ++ "org.freedesktop.login1", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ logind_appeared, ++ logind_vanished, ++ manager_xrandr, ++ NULL); + } + + static void +@@ -1114,9 +1189,8 @@ is_xvnc (MetaMonitorManager *manager) + return FALSE; + } + +-gboolean +-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, +- XEvent *event) ++static void ++meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr) + { + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); +@@ -1126,11 +1200,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + gboolean is_our_configuration; + unsigned int timestamp; + +- if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) +- return FALSE; +- +- XRRUpdateConfiguration (event); +- + meta_monitor_manager_read_current_state (manager); + + gpu_xrandr = META_GPU_XRANDR (gpu); +@@ -1165,6 +1234,19 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + + meta_monitor_manager_xrandr_rebuild_derived (manager, config); + } ++} ++ ++gboolean ++meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, ++ XEvent *event) ++{ ++ ++ if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) ++ return FALSE; ++ ++ XRRUpdateConfiguration (event); ++ ++ meta_monitor_manager_xrandr_update (manager_xrandr); + + return TRUE; + } +-- +2.31.1 + + +From 7a04949b978ebe96cd088d7bd255fd3f52c7c355 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 24 Feb 2020 16:09:59 +0100 +Subject: [PATCH 3/9] Revert "MetaMonitorManager: ignore hotplug_mode_update at + startup" + +This reverts commit 183f4b0c13f3dc9565bf5f693f2e5d61ca0199c9. +--- + src/backends/meta-monitor-manager.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index a75da9329e..c291ddb5d3 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -609,8 +609,7 @@ meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager) + static gboolean + should_use_stored_config (MetaMonitorManager *manager) + { +- return (manager->in_init || +- !meta_monitor_manager_has_hotplug_mode_update (manager)); ++ return !meta_monitor_manager_has_hotplug_mode_update (manager); + } + + MetaMonitorsConfig * +-- +2.31.1 + + +From babcf2a6d09136bcf1bf2dc958046aaa0334b85e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 28 Jan 2016 15:26:33 +0100 +Subject: [PATCH 4/9] monitor-manager: Consider external layout before default + linear config + +In case of no existing configuration, we use a default layout of +aligning attached displays horizontally. This sidesteps any layout +configuration that is done externally, for instance via xorg.conf, +which is not desirable. Instead, base the initial configuration on +the existing layout if it passes some sanity checks before falling +back to the default linear config. +--- + src/backends/meta-monitor-config-manager.c | 86 ++++++++++++++++++++++ + src/backends/meta-monitor-config-manager.h | 2 + + src/backends/meta-monitor-manager.c | 19 +++++ + 3 files changed, 107 insertions(+) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index 0253e072ff..2f6cc3856f 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -739,6 +739,92 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma + return logical_monitor_config; + } + ++static MetaLogicalMonitorConfig * ++create_logical_monitor_config_from_output (MetaMonitorManager *monitor_manager, ++ MetaMonitor *monitor, ++ MetaLogicalMonitorConfig *primary_logical_monitor_config, ++ MetaLogicalMonitorLayoutMode layout_mode) ++{ ++ MetaOutput *output; ++ MetaCrtc *crtc; ++ const MetaCrtcConfig *crtc_config; ++ ++ output = meta_monitor_get_main_output (monitor); ++ crtc = meta_output_get_assigned_crtc (output); ++ crtc_config = meta_crtc_get_config (crtc); ++ if (!crtc_config) ++ return NULL; ++ ++ return create_preferred_logical_monitor_config (monitor_manager, ++ monitor, ++ (int) crtc_config->layout.origin.x, ++ (int) crtc_config->layout.origin.y, ++ primary_logical_monitor_config, ++ layout_mode); ++} ++ ++MetaMonitorsConfig * ++meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager) ++{ ++ MetaMonitorManager *monitor_manager = config_manager->monitor_manager; ++ GList *logical_monitor_configs; ++ MetaMonitor *primary_monitor; ++ MetaLogicalMonitorLayoutMode layout_mode; ++ MetaLogicalMonitorConfig *primary_logical_monitor_config; ++ GList *monitors; ++ GList *l; ++ ++ 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; ++ ++ 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); ++ if (!primary_logical_monitor_config) ++ return NULL; ++ ++ primary_logical_monitor_config->is_primary = TRUE; ++ logical_monitor_configs = g_list_append (NULL, ++ primary_logical_monitor_config); ++ ++ monitors = meta_monitor_manager_get_monitors (monitor_manager); ++ for (l = monitors; l; l = l->next) ++ { ++ MetaMonitor *monitor = l->data; ++ MetaLogicalMonitorConfig *logical_monitor_config; ++ ++ if (monitor == primary_monitor) ++ continue; ++ ++ if (!meta_monitor_is_active (monitor)) ++ continue; ++ ++ logical_monitor_config = ++ create_logical_monitor_config_from_output (monitor_manager, ++ monitor, ++ primary_logical_monitor_config, ++ layout_mode); ++ if (!logical_monitor_config) ++ continue; ++ ++ logical_monitor_configs = g_list_append (logical_monitor_configs, ++ logical_monitor_config); ++ } ++ ++ return meta_monitors_config_new (monitor_manager, ++ logical_monitor_configs, ++ layout_mode, ++ META_MONITORS_CONFIG_FLAG_NONE); ++} ++ + MetaMonitorsConfig * + meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager) + { +diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h +index 86756a7e33..961d604bd5 100644 +--- a/src/backends/meta-monitor-config-manager.h ++++ b/src/backends/meta-monitor-config-manager.h +@@ -94,6 +94,8 @@ gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager, + META_EXPORT_TEST + MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager); + ++META_EXPORT_TEST ++MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager); + META_EXPORT_TEST + MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager); + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index c291ddb5d3..96f0d6b84a 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -695,6 +695,25 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) + g_clear_object (&config); + } + ++ config = meta_monitor_config_manager_create_current (manager->config_manager); ++ if (config) ++ { ++ if (!meta_monitor_manager_apply_monitors_config (manager, ++ config, ++ method, ++ &error)) ++ { ++ g_clear_object (&config); ++ g_warning ("Failed to use current monitor configuration: %s", ++ error->message); ++ g_clear_error (&error); ++ } ++ else ++ { ++ goto done; ++ } ++ } ++ + config = meta_monitor_config_manager_create_linear (manager->config_manager); + if (config) + { +-- +2.31.1 + + +From ada8c9b1346fe261a8fa04f68149c79d95c969ac Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 11 Sep 2018 10:19:44 -0400 +Subject: [PATCH 5/9] monitor-manager: only reuse initial-config if monitor + topology matches startup + +Right now we try to apply the current monitor config when a new +monitor is attached. The current config obviously doesn't include the +new monitor, so the new monitor isn't lit up. + +The only reason we apply the current config at all is to handle the +startup case: We want to reuse the config set in Xorg when first +logging in. + +This commit changes the code to look at the *initial config* instead +of the current config, and only if the new monitor topology matches +the start up topology. +--- + src/backends/meta-monitor-config-manager.c | 20 +++++++++++++++----- + src/backends/meta-monitor-config-manager.h | 2 +- + src/backends/meta-monitor-manager.c | 16 +++++++++++++++- + 3 files changed, 31 insertions(+), 7 deletions(-) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index 2f6cc3856f..46249755bc 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -42,6 +42,7 @@ struct _MetaMonitorConfigManager + MetaMonitorConfigStore *config_store; + + MetaMonitorsConfig *current_config; ++ MetaMonitorsConfig *initial_config; + GQueue config_history; + }; + +@@ -764,9 +765,10 @@ create_logical_monitor_config_from_output (MetaMonitorManager *monitor + } + + MetaMonitorsConfig * +-meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager) ++meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager) + { + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; ++ MetaMonitorsConfig *initial_config; + GList *logical_monitor_configs; + MetaMonitor *primary_monitor; + MetaLogicalMonitorLayoutMode layout_mode; +@@ -774,6 +776,9 @@ meta_monitor_config_manager_create_current (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; + +@@ -819,10 +824,14 @@ meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_man + logical_monitor_config); + } + +- return meta_monitors_config_new (monitor_manager, +- logical_monitor_configs, +- layout_mode, +- META_MONITORS_CONFIG_FLAG_NONE); ++ initial_config = meta_monitors_config_new (monitor_manager, ++ logical_monitor_configs, ++ layout_mode, ++ META_MONITORS_CONFIG_FLAG_NONE); ++ ++ config_manager->initial_config = g_object_ref (initial_config); ++ ++ return initial_config; + } + + MetaMonitorsConfig * +@@ -1453,6 +1462,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); + 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 961d604bd5..dc273c961b 100644 +--- a/src/backends/meta-monitor-config-manager.h ++++ b/src/backends/meta-monitor-config-manager.h +@@ -95,7 +95,7 @@ META_EXPORT_TEST + MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager); + + META_EXPORT_TEST +-MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager); ++MetaMonitorsConfig * meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager); + META_EXPORT_TEST + MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager); + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index 96f0d6b84a..baf5bf2f9f 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -615,9 +615,11 @@ should_use_stored_config (MetaMonitorManager *manager) + 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; +@@ -628,6 +630,18 @@ 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 (use_stored_config) + { + config = meta_monitor_config_manager_get_stored (manager->config_manager); +@@ -695,7 +709,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) + g_clear_object (&config); + } + +- config = meta_monitor_config_manager_create_current (manager->config_manager); ++ config = g_steal_pointer (&initial_config); + if (config) + { + if (!meta_monitor_manager_apply_monitors_config (manager, +-- +2.31.1 + + +From baa22f3ac77f549bd36c2a0ea45ba4caee434ddc 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 6/9] 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 | 80 +++++++++++++--------- + 1 file changed, 46 insertions(+), 34 deletions(-) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index 46249755bc..f355879c3e 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -678,21 +678,20 @@ get_monitor_transform (MetaMonitorManager *monitor_manager, + } + + 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; + MetaMonitorTransform transform; + 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) & +@@ -741,27 +740,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; +- const MetaCrtcConfig *crtc_config; ++ 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); +- crtc_config = meta_crtc_get_config (crtc); +- if (!crtc_config) +- return NULL; ++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_preferred_logical_monitor_config (monitor_manager, +- monitor, +- (int) crtc_config->layout.origin.x, +- (int) crtc_config->layout.origin.y, +- primary_logical_monitor_config, +- layout_mode); ++ return create_logical_monitor_config (monitor_manager, ++ monitor, ++ mode, ++ monitor_layout.x, ++ monitor_layout.y, ++ primary_logical_monitor_config, ++ layout_mode); + } + + MetaMonitorsConfig * +@@ -789,10 +801,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); + if (!primary_logical_monitor_config) + return NULL; + +@@ -813,10 +825,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); + if (!logical_monitor_config) + continue; + +-- +2.31.1 + + +From 52622c80f747a03738823471be9d275c7a2fd8c0 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 7/9] 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 f355879c3e..4b37657d34 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; + }; + +@@ -776,11 +776,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; +@@ -788,12 +787,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; +@@ -836,14 +829,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 * +@@ -1474,7 +1479,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 dc273c961b..641ed1bc1a 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 60c1e90821..571b9000dc 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_LAYOUT_MODE = (1 << 0), +- META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 1) ++ META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 1), ++ META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT = (1 << 2), + } MetaMonitorManagerCapability; + + /* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */ +@@ -145,6 +146,7 @@ struct _MetaMonitorManager + guint panel_orientation_managed : 1; + + 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 baf5bf2f9f..9e57db94cd 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -612,14 +612,21 @@ should_use_stored_config (MetaMonitorManager *manager) + return !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; +@@ -630,17 +637,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) + { +@@ -709,9 +707,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 61e13f459d..90ccb74053 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -984,7 +984,8 @@ meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager + static MetaMonitorManagerCapability + meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager) + { +- return META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED; ++ return (META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED | ++ META_MONITOR_MANAGER_CAPABILITY_CAN_DERIVE_CURRENT); + } + + static gboolean +-- +2.31.1 + + +From e15c812ef8525d6dd6db730c1c6a1f8ad839bb09 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 8/9] 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 | 39 +++++++++++++------ + .../x11/meta-monitor-manager-xrandr.c | 18 ++++++--- + 2 files changed, 40 insertions(+), 17 deletions(-) + +diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c +index 6a96e53979..e8361c77bc 100644 +--- a/src/backends/x11/meta-gpu-xrandr.c ++++ b/src/backends/x11/meta-gpu-xrandr.c +@@ -96,6 +96,32 @@ 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); ++ MetaBackend *backend = meta_gpu_get_backend (gpu); ++ MetaMonitorManager *monitor_manager = ++ meta_backend_get_monitor_manager (backend); ++ 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) +@@ -112,8 +138,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; +@@ -122,16 +146,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 90ccb74053..1b35545a09 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -140,12 +140,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; +@@ -161,6 +158,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.31.1 + + +From 49307c3171b086ba5cdebe633f97a217042c8903 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 9/9] 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 | 86 +++++++++++++++++++ + .../x11/meta-monitor-manager-xrandr.c | 22 ++++- + .../x11/meta-monitor-manager-xrandr.h | 4 + + 3 files changed, 111 insertions(+), 1 deletion(-) + +diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c +index e8361c77bc..3ecb80bb2c 100644 +--- a/src/backends/x11/meta-gpu-xrandr.c ++++ b/src/backends/x11/meta-gpu-xrandr.c +@@ -122,6 +122,89 @@ 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); ++ g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; ++ g_autofree char *mode_name = NULL; ++ MetaCrtcMode *mode; ++ MetaCrtc *crtc; ++ g_autoptr (MetaOutputInfo) output_info = NULL; ++ MetaOutputAssignment output_assignment; ++ MetaOutput *output; ++ ++ meta_monitor_manager_xrandr_update_dpms_state (monitor_manager_xrandr); ++ update_screen_size (gpu_xrandr); ++ ++ crtc_mode_info = meta_crtc_mode_info_new (); ++ crtc_mode_info->width = monitor_manager->screen_width; ++ crtc_mode_info->height = monitor_manager->screen_height; ++ crtc_mode_info->refresh_rate = 60.0; ++ ++ mode_name = g_strdup_printf ("%dx%d", ++ crtc_mode_info->width, ++ crtc_mode_info->height); ++ mode = g_object_new (META_TYPE_CRTC_MODE, ++ "id", 0, ++ "name", mode_name, ++ "info", crtc_mode_info, ++ NULL); ++ ++ meta_gpu_take_modes (gpu, g_list_prepend (NULL, mode)); ++ ++ crtc = g_object_new (META_TYPE_CRTC_XRANDR, ++ "id", 0, ++ "gpu", gpu, ++ NULL); ++ meta_crtc_set_config (crtc, ++ &(graphene_rect_t) { ++ .size = { ++ .width = crtc_mode_info->width, ++ .height = crtc_mode_info->width, ++ }, ++ }, ++ mode, ++ META_MONITOR_TRANSFORM_NORMAL); ++ ++ meta_gpu_take_crtcs (gpu, g_list_prepend (NULL, crtc)); ++ ++ output_info = meta_output_info_new (); ++ output_info->name = g_strdup ("X11 Screen"); ++ output_info->vendor = g_strdup ("unknown"); ++ output_info->product = g_strdup ("unknown"); ++ output_info->serial = g_strdup ("unknown"); ++ output_info->hotplug_mode_update = TRUE; ++ output_info->suggested_x = -1; ++ output_info->suggested_y = -1; ++ output_info->connector_type = META_CONNECTOR_TYPE_Unknown; ++ output_info->modes = g_new0 (MetaCrtcMode *, 1); ++ output_info->modes[0] = mode; ++ output_info->n_modes = 1; ++ output_info->preferred_mode = mode; ++ output_info->possible_crtcs = g_new0 (MetaCrtc *, 1); ++ output_info->possible_crtcs[0] = crtc; ++ output_info->n_possible_crtcs = 1; ++ ++ output = g_object_new (META_TYPE_OUTPUT_XRANDR, ++ "id", (uint64_t) 0, ++ "gpu", gpu, ++ "info", output_info, ++ NULL); ++ ++ output_assignment = (MetaOutputAssignment) { ++ .output = output, ++ .is_primary = TRUE, ++ }; ++ meta_output_assign_crtc (output, crtc, &output_assignment); ++ meta_gpu_take_outputs (gpu, g_list_prepend (NULL, output)); ++ ++ return TRUE; ++} ++ + static gboolean + meta_gpu_xrandr_read_current (MetaGpu *gpu, + GError **error) +@@ -142,6 +225,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 1b35545a09..98eb080b6b 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -76,6 +76,7 @@ struct _MetaMonitorManagerXrandr + guint logind_watch_id; + guint logind_signal_sub_id; + ++ gboolean has_randr; + gboolean has_randr15; + + xcb_timestamp_t last_xrandr_set_timestamp; +@@ -108,6 +109,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) + { +@@ -139,7 +146,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); +@@ -615,9 +622,18 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana + MetaMonitorsConfigMethod method, + GError **error) + { ++ MetaMonitorManagerXrandr *manager_xrandr = ++ META_MONITOR_MANAGER_XRANDR (manager); + GPtrArray *crtc_assignments; + GPtrArray *output_assignments; + ++ 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) + { + if (!manager->in_init) +@@ -1097,11 +1113,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 d55b3d2b88..dc75134a56 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.31.1 + diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec new file mode 100644 index 0000000..7b45a0e --- /dev/null +++ b/SPECS/mutter.spec @@ -0,0 +1,1329 @@ +%global gtk3_version 3.19.8 +%global glib_version 2.53.2 +%global gsettings_desktop_schemas_version 40~alpha +%global json_glib_version 0.12.0 +%global libinput_version 1.4 +%global pipewire_version 0.3.0 +%global mutter_api_version 8 + +%global tarball_version %%(echo %{version} | tr '~' '.') + +Name: mutter +Version: 40.4 +Release: 3%{?dist} +Summary: Window and compositing manager based on Clutter + +License: GPLv2+ +URL: http://www.gnome.org +Source0: http://download.gnome.org/sources/%{name}/40/%{name}-%{tarball_version}.tar.xz + +# Work-around for OpenJDK's compliance test +Patch0: 0001-window-actor-Special-case-shaped-Java-windows.patch + +# To make s390x build pass +Patch1: 0001-Revert-build-Do-not-provide-built-sources-as-libmutt.patch + +# Workaround for RHBZ#1936991 (blocks atomic KMS on "tegra" driver) +Patch2: 0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch + +# Allow Xwayland grabs by default, on a selected set of X11 apps (rhbz#1500399) +Patch3: 0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch + +# X11 window management work arounds +Patch4: 0001-constraints-Enforce-X11-size-limits.patch + +# X11/VM monitor configuration patches (rhbz#1265511, rhbz#1618632, +# rhbz#1497303, rhbz#1690506, rhbz#1776530, rhbz#1365717, rhbz#1690170) +Patch5: x11-monitor-configuration-patches.patch + +# Sloppy focus fix (rhbz#1358535) +Patch6: 0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch + +# Legacy X11 configuration support (synaptics/plain) +Patch7: legacy-x11-input-configuration.patch + +# GLX Stereo (nvidia) +Patch8: glx-stereo-support.patch + +# Work around vncserver not setting the right XDG_SESSION_TYPE +Patch9: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch + +# Fixes --replace +Patch10: 0001-backend-Clean-up-renderer-after-clutter-backendm.patch + +# Fixes a race in wl_seat capabilities (rhbz#1957807) +# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/77 +Patch11: 0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch + +BuildRequires: chrpath +BuildRequires: pango-devel +BuildRequires: startup-notification-devel +BuildRequires: gnome-desktop3-devel +BuildRequires: glib2-devel >= %{glib_version} +BuildRequires: gtk3-devel >= %{gtk3_version} +BuildRequires: pkgconfig +BuildRequires: gobject-introspection-devel >= 1.41.0 +BuildRequires: libSM-devel +BuildRequires: libwacom-devel +BuildRequires: libX11-devel +BuildRequires: libXdamage-devel +BuildRequires: libXext-devel +BuildRequires: libXfixes-devel +BuildRequires: libXi-devel +BuildRequires: libXrandr-devel +BuildRequires: libXrender-devel +BuildRequires: libXcursor-devel +BuildRequires: libXcomposite-devel +BuildRequires: libxcb-devel +BuildRequires: libxkbcommon-devel +BuildRequires: libxkbcommon-x11-devel +BuildRequires: libxkbfile-devel +BuildRequires: libXtst-devel +BuildRequires: mesa-libEGL-devel +BuildRequires: mesa-libGLES-devel +BuildRequires: mesa-libGL-devel +BuildRequires: mesa-libgbm-devel +BuildRequires: pkgconfig(glesv2) +BuildRequires: pkgconfig(graphene-gobject-1.0) +BuildRequires: pam-devel +BuildRequires: pkgconfig(libpipewire-0.3) >= %{pipewire_version} +BuildRequires: pkgconfig(sysprof-capture-4) +BuildRequires: sysprof-devel +BuildRequires: systemd-devel +BuildRequires: upower-devel +BuildRequires: xorg-x11-server-Xorg +BuildRequires: xkeyboard-config-devel +BuildRequires: zenity +BuildRequires: desktop-file-utils +# Bootstrap requirements +BuildRequires: gtk-doc gnome-common gettext-devel git +BuildRequires: libcanberra-devel +BuildRequires: gsettings-desktop-schemas-devel >= %{gsettings_desktop_schemas_version} +BuildRequires: gnome-settings-daemon-devel +BuildRequires: meson +BuildRequires: pkgconfig(gudev-1.0) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(gbm) +BuildRequires: pkgconfig(wayland-server) +BuildRequires: pkgconfig(wayland-eglstream) + +BuildRequires: json-glib-devel >= %{json_glib_version} +BuildRequires: libgudev1-devel +BuildRequires: libinput-devel >= %{libinput_version} +BuildRequires: pkgconfig(xwayland) + +Requires: control-center-filesystem +Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas_version} +Requires: gnome-settings-daemon +Requires: gtk3%{?_isa} >= %{gtk3_version} +Requires: pipewire%{_isa} >= %{pipewire_version} +Requires: startup-notification +Requires: dbus +Requires: zenity + +Requires: json-glib%{?_isa} >= %{json_glib_version} +Requires: libinput%{?_isa} >= %{libinput_version} + +# Cogl and Clutter were forked at these versions, but have diverged +# significantly since then. +Provides: bundled(cogl) = 1.22.0 +Provides: bundled(clutter) = 1.26.0 + +%description +Mutter is a window and compositing manager that displays and manages +your desktop via OpenGL. Mutter combines a sophisticated display engine +using the Clutter toolkit with solid window-management logic inherited +from the Metacity window manager. + +While Mutter can be used stand-alone, it is primarily intended to be +used as the display core of a larger system such as GNOME Shell. For +this reason, Mutter is very extensible via plugins, which are used both +to add fancy visual effects and to rework the window management +behaviors to meet the needs of the environment. + +%package devel +Summary: Development package for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Header files and libraries for developing Mutter plugins. Also includes +utilities for testing Metacity/Mutter themes. + +%package tests +Summary: Tests for the %{name} package +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tests +The %{name}-tests package contains tests that can be used to verify +the functionality of the installed %{name} package. + +%prep +%autosetup -S git -n %{name}-%{tarball_version} + +%build +%meson -Degl_device=true -Dwayland_eglstream=true +%meson_build + +%install +%meson_install + +%find_lang %{name} + +# Mutter contains a .desktop file so we just need to validate it +desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop + +%ldconfig_scriptlets + +%files -f %{name}.lang +%license COPYING +%doc NEWS +%{_bindir}/mutter +%{_datadir}/applications/*.desktop +%{_libdir}/lib*.so.* +%{_libdir}/mutter-%{mutter_api_version}/ +%{_libexecdir}/mutter-restart-helper +%{_datadir}/GConf/gsettings/mutter-schemas.convert +%{_datadir}/glib-2.0/schemas/org.gnome.mutter.gschema.xml +%{_datadir}/glib-2.0/schemas/org.gnome.mutter.wayland.gschema.xml +%{_datadir}/gnome-control-center/keybindings/50-mutter-*.xml +%{_mandir}/man1/mutter.1* +%{_udevrulesdir}/61-mutter.rules + +%files devel +%{_includedir}/* +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/* + +%files tests +%{_libexecdir}/installed-tests/mutter-%{mutter_api_version} +%{_datadir}/installed-tests/mutter-%{mutter_api_version} +%{_datadir}/mutter-%{mutter_api_version}/tests + +%changelog +* Fri Sep 10 2021 Olivier Fourdan - 40.4-3 +- Fixes a race in wl_seat capabilities + Resolves: #1957807 + +* Wed Aug 27 2021 Florian Müllner - 40.4-2 +- Remove firstboot(windowmanager) provide + Resolves: #1975355 + +* Wed Aug 18 2021 Florian Müllner - 40.4-1 +- Update to 40.4 + Resolves: #1995093 + +* Thu Aug 12 2021 Ray Strode - 40.3-3 +- Fix crash in shutdown path + Related: #1992986 + +* Mon Aug 09 2021 Mohan Boddu - 40.3-2 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Mon Jul 12 2021 Florian Müllner - 40.3-1 +- Update to 40.3 + Resolves: #1974211 + +* Mon Jun 14 2021 Florian Müllner - 40.2.1-1 +- Update to 40.2.1 + Resolves: #1971437 + +* Thu Jun 03 2021 Jonas Ådahl - 40.1-3 +- Forward port downstream patches from RHEL8 + Resolves: #1965949 + +* Wed Jun 02 2021 Florian Müllner - 40.1-2 +- Don't emit ::key-focus-out on destroyed actors + Resolves: #1964386 + +* Thu May 13 2021 Florian Müllner - 40.1-1 +- Update to 40.1 + Resolves: #1951146 + +* Fri Apr 16 2021 Mohan Boddu - 40.0-5 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Mar 30 2021 Kalev Lember - 40.0-4 +- Fix enter, space, backspace keys not working with input methods (#1942294) +- Drop old obsoletes and conflicts + +* Mon Mar 29 2021 Jonas Ådahl - 40.0-3 +- Fix crash on resume (rhbz#1941971) + +* Fri Mar 26 2021 Kalev Lember - 40.0-2 +- Rebuild to fix sysprof-capture symbols leaking into libraries consuming it + +* Sat Mar 20 2021 Florian Müllner - 40.0-1 +- Update to 40.0 + +* Mon Mar 15 2021 Florian Müllner - 40.0~rc-1 +- Update to 40.rc + +* Fri Mar 12 2021 Benjamin Berg - 40.0~beta-3 +- Pull in Xwayland autostart fix for non-systemd startup + Resolves: #1924908 + +* Tue Mar 09 2021 Adam Williamson - 40.0~beta-2 +- Add a workaround for RHBZ#1936991 (disable atomic KMS on tegra) + +* Mon Feb 22 2021 Florian Müllner - 40.0~beta-1 +- Update to 40.beta + +* Tue Feb 02 2021 Florian Müllner - 40.0~alpha.1.1-4.20210202gita9d9aee6c +- Build snapshot of current upstream + +* Mon Feb 1 2021 Olivier Fourdan - 40.0~alpha.1.1-3 +- Add build dependency on Xwayland-devel package (from Xwayland standalone) +- Do not explicitly disable initfd support. + +* Tue Jan 26 2021 Fedora Release Engineering - 40.0~alpha.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Thu Jan 14 2021 Florian Müllner - 40.0~alpha.1.1-1 +- Update to 40.alpha.1.1 to adjust for GSettings schema changes in g-s-d + +* Thu Jan 14 2021 Florian Müllner - 40.0~alpha.1-1 +- Update to 40.alpha.1 + +* Wed Dec 02 2020 Florian Müllner - 40.alpha-1 +- Update to 40.alpha + +* Mon Oct 05 2020 Florian Müllner - 3.38.1-1 +- Update to 3.38.1 + +* Mon Sep 28 2020 Peter Robinson - 3.38.0-2 +- Upstream fix for NVidia Jetson devices + +* Mon Sep 14 2020 Florian Müllner - 3.38.0-1 +- Update to 3.38.0 + +* Sat Sep 05 2020 Florian Müllner - 3.37.92-1 +- Update to 3.37.92 + +* Mon Aug 24 2020 Florian Müllner - 3.37.91-1 +- Update to 3.37.91 + +* Tue Aug 11 2020 Florian Müllner - 3.37.90-1 +- Update to 3.37.90 + +* Tue Jul 28 2020 Fedora Release Engineering - 3.37.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 07 2020 Florian Müllner - 3.37.3-1 +- Update to 3.37.3 + +* Wed Jun 03 2020 Florian Müllner - 3.37.2-1 +- Update to 3.37.2 + +* Thu Apr 30 2020 Florian Müllner - 3.37.1-1 +- Update to 3.37.1 + +* Mon Mar 30 2020 Florian Müllner - 3.36.1-1 +- Update to 3.36.1 + +* Tue Mar 24 2020 Adam Williamson - 3.36.0-3 +- Backport all patches to git master for various fixes inc (#1809717) + +* Mon Mar 23 2020 Adam Williamson - 3.36.0-2 +- Backport fix for preedit cursor position bug (#1812449) + +* Sat Mar 07 2020 Florian Müllner - 3.36.0-1 +- Update to 3.36.0 + +* Fri Mar 06 2020 Adam Williamson - 3.35.92-3 +- Backport fix for pop-up menus on secondary heads (Gitlab #1098) + +* Tue Mar 03 2020 Bastien Nocera - 3.35.92-2 ++ mutter-3.35.92-2 +- Fix wayland session not starting up, see https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1103 + +* Sun Mar 01 2020 Florian Müllner - 3.35.92-1 +- Update to 3.35.92 + +* Mon Feb 17 2020 Florian Müllner - 3.35.91-1 +- Update to 3.35.91 + +* Thu Feb 06 2020 Florian Müllner - 3.35.90-1 +- Update to 3.35.90 + +* Wed Jan 29 2020 Fedora Release Engineering - 3.35.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jan 16 2020 Kalev Lember - 3.35.3-2 +- Rebuilt for libgnome-desktop soname bump + +* Sun Jan 05 2020 Florian Müllner - 3.35.3-1 +- Update to 3.35.3 + +* Wed Dec 11 2019 Florian Müllner - 3.35.2-1 +- Update to 3.35.2 + +* Tue Oct 29 2019 Florian Müllner - 3.35.1-3 +- Enable sysprof support + The required dependency was missing from rawhide when the feature + landed, but there's no reason for keeping it disabled nowadays + +* Mon Oct 14 2019 Adam Williamson - 3.35.1-2 +- Update MR #832 backport to fully fix cursor zoom bug (#1749433) + +* Sat Oct 12 2019 Florian Müllner - 3.35.1-1 +- Update to 3.35.1 + +* Sat Oct 12 2019 Adam Williamson - 3.34.1-2 +- Backport multiple fixes for F31 FE/blocker bugs: + MR #832 for #1749433 (also needs change in gnome-shell) + MR #840 for #1760254 + MR #848 for #1751646 and #1759644 + MR #842 for #1758873 + +* Wed Oct 09 2019 Florian Müllner - 3.34.1-1 +- Update to 3.34.1 + +* Sat Sep 28 2019 Kenneth Topp - 3.34.0-5 +- Backport fix for dual special modifier keys bug (#1754867) +- Backport fix that enables core dumps (#1748145) + +* Fri Sep 27 2019 Kenneth Topp - 3.34.0-4 +- Backport a patch to prevent crash during animations +- See upstream issue https://gitlab.gnome.org/GNOME/mutter/issues/815 + +* Thu Sep 12 2019 Kalev Lember - 3.34.0-3 +- Update previous patch to final upstream version + +* Wed Sep 11 2019 Kalev Lember - 3.34.0-2 +- Backport a patch to fix xsettings/ibus-x11 initialization (#1750512) + +* Mon Sep 09 2019 Florian Müllner - 3.34.0-1 +- Update to 3.34.0 + +* Wed Sep 04 2019 Florian Müllner - 3.33.92-1 +- Update to 3.33.92 + +* Tue Sep 03 2019 Ray Strode - 3.33.91-2 +- Fix crash dealing with powersaving + Resolves: #1747845 + +* Wed Aug 21 2019 Florian Müllner - 3.33.91-1 +- Update to 3.33.91 + +* Sat Aug 10 2019 Florian Müllner - 3.33.90-1 +- Update to 3.33.90 + +* Thu Jul 25 2019 Fedora Release Engineering - 3.33.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Sun Jul 21 2019 Kalev Lember - 3.33.4-2 +- Rebuilt for libgnome-desktop soname bump + +* Sat Jul 20 2019 Florian Müllner - 3.33.4-1 +- Update to 3.33.4 + +* Mon Jun 24 2019 Florian Müllner - 3.33.3-1 +- Update to 3.33.3 + +* Wed May 22 2019 Florian Müllner - 3.33.2-1 +- Update to 3.33.2 + +* Tue May 14 2019 Florian Müllner - 3.33.1-1 +- Update to 3.33.1 + +* Wed Apr 17 2019 Florian Müllner - 3.32.1-1 +- Update to 3.32.1 + +* Wed Apr 17 2019 Adam Williamson - 3.32.0-4 +- Backport MR #498 for spinner bug, plus two crasher fixes + Resolves: #1692135 + +* Tue Apr 16 2019 Adam Williamson - 3.32.0-3 +- Rebuild with Meson fix for #1699099 + +* Mon Mar 25 2019 Adam Williamson - 3.32.0-2 +- Backport work-around for hangul text input bug (rhbz#1632981) + +* Tue Mar 12 2019 Florian Müllner - 3.32.0-1 +- Update to 3.32.0 + +* Fri Mar 08 2019 Kalev Lember - 3.31.92-3 +- Backport more inverted colour fixes (#1686649) + +* Wed Mar 06 2019 Kalev Lember - 3.31.92-2 +- Backport a patch to fix inverted colours + +* Tue Mar 05 2019 Florian Müllner - 3.31.92-1 +- Update to 3.31.92 + +* Thu Feb 21 2019 Florian Müllner - 3.31.91-1 +- Update to 3.31.91 + +* Thu Feb 07 2019 Florian Müllner - 3.31.90-1 +- Update to 3.31.90 + +* Fri Feb 01 2019 Fedora Release Engineering - 3.31.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Jan 10 2019 Florian Müllner - 3.31.4-1 +- Update to 3.31.4 + +* Sat Nov 17 2018 Kalev Lember - 3.31.2-2 +- Remove libtool .la files from private libs (#1622944) + +* Wed Nov 14 2018 Florian Müllner - 3.31.2-1 +- Update to 3.31.2 + +* Mon Oct 22 2018 Jonas Ådahl - 3.30.1-5 +- Backport work-around for hangul text input bug (rhbz#1632981) + +* Sat Oct 20 2018 Jonas Ådahl - 3.30.1-4 +- Backport a couple of memory leak fixes (rhbz#1641254) + +* Thu Oct 11 2018 Jonas Ådahl - 3.30.1-3 +- Fix disabled monitor when laptop lid is closed (rhbz#1638444) + +* Thu Oct 11 2018 David Herrmann - 3.30.1-2 +- Reduce 'dbus-x11' dependency to 'dbus'. The xinit script are no longer the + canonical way to start dbus, but the 'dbus' package is nowadays required to + provide a user and system bus to its dependents. + +* Mon Oct 08 2018 Florian Müllner - 3.30.1-1 +- Update to 3.30.1 + +* Wed Oct 03 2018 Adam Williamson - 3.30.0-3 +- Backport fix for #1630943 from upstream master + +* Thu Sep 06 2018 Mateusz Mikuła - 3.30.0-2 +- Enable EGLDevice support + +* Tue Sep 04 2018 Florian Müllner - 3.30.0-1 +- Update to 3.30.0 + +* Wed Aug 29 2018 Florian Müllner - 3.29.92-1 +- Update to 3.29.92 + +* Mon Aug 20 2018 Florian Müllner - 3.29.91-1 +- Update to 3.29.91 + +* Wed Aug 01 2018 Jan Grulich - 3.29.90-2 +- Update libpipewire requirements + +* Wed Aug 01 2018 Florian Müllner - 3.29.90-1 +- Update to 3.29.90 + +* Tue Jul 24 2018 Adam Williamson - 3.29.4-2 +- Backport MR#175 to fix 90/270 degree screen rotation + +* Wed Jul 18 2018 Florian Müllner - 3.29.4-1 +- Update to 3.29.4 + +* Fri Jul 13 2018 Fedora Release Engineering - 3.29.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Fri Jun 01 2018 Adam Williamson - 3.29.2-2 +- Backport crasher fix from upstream master (#1585360) + +* Thu May 24 2018 Florian Müllner - 3.29.2-1 +- Update to 3.29.2 + +* Wed Apr 25 2018 Florian Müllner - 3.29.1-1 +- Update to 3.29.1 + +* Fri Apr 13 2018 Florian Müllner - 3.28.1-1 +- Update to 3.28.1 + +* Mon Mar 12 2018 Florian Müllner - 3.28.0-1 +- Update to 3.28.0 + +* Mon Mar 05 2018 Florian Müllner - 3.27.92-1 +- Update to 3.27.92 + +* Wed Feb 28 2018 Adam Williamson - 3.27.91-2 +- Backport MR#36 to fix RHBZ #1547691 (GGO #2), mouse issues + +* Wed Feb 21 2018 Florian Müllner - 3.27.91-1 +- Update to 3.27.91 + +* Tue Feb 13 2018 Björn Esser - 3.27.1-4 +- Rebuild against newer gnome-desktop3 package +- Add patch for adjustments to pipewire 0.1.8 API + +* Thu Feb 08 2018 Fedora Release Engineering - 3.27.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Jan 06 2018 Igor Gnatenko - 3.27.1-2 +- Remove obsolete scriptlets + +* Mon Oct 30 2017 Florian Müllner - 3.27.1-1 +- Include 32-bit build fixes + +* Tue Oct 17 2017 Florian Müllner - 3.27.1-1 +- Update to 3.27.1 + +* Fri Oct 06 2017 Florian Müllner - 3.26.1-2 +- Fix screencasts + +* Wed Oct 04 2017 Florian Müllner - 3.26.1-1 +- Update to 3.26.1 + +* Thu Sep 21 2017 Florian Müllner - 3.26.0-5 +- Adjust to pipewire API break + +* Wed Sep 20 2017 Florian Müllner - 3.26.0-5 +- Enable tablet support + +* Tue Sep 12 2017 Adam Williamson - 3.26.0-4 +- Also backport BGO #787570 fix from upstream + +* Tue Sep 12 2017 Adam Williamson - 3.26.0-3 +- Backport upstream fixes for crasher bug BGO #787568 + +* Tue Sep 12 2017 Florian Müllner - 3.26.0-2 +- Enable remote desktop support + +* Tue Sep 12 2017 Florian Müllner - 3.26.0-1 +- Update to 3.26.0 + +* Thu Sep 07 2017 Florian Müllner - 3.25.92-1 +- Update to 3.25.92 + +* Thu Aug 24 2017 Bastien Nocera - 3.25.91-2 ++ mutter-3.25.91-2 +- Fix inverted red and blue channels with newer Mesa + +* Tue Aug 22 2017 Florian Müllner - 3.25.91-1 +- Update to 3.25.91 + +* Thu Aug 10 2017 Florian Müllner - 3.25.90-1 +- Update to 3.25.90 + +* Thu Aug 03 2017 Fedora Release Engineering - 3.25.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.25.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 19 2017 Florian Müllner - 3.25.4-1 +- Update to 3.25.4 + +* Wed Jun 21 2017 Florian Müllner - 3.25.3-1 +- Update to 3.25.3 + +* Wed May 24 2017 Florian Müllner - 3.25.2-1 +- Update to 3.25.2 + +* Thu May 18 2017 Florian Müllner - 3.25.1-2 +- Fix copy+paste of UTF8 strings between X11 and wayland + +* Thu Apr 27 2017 Florian Müllner - 3.25.1-1 +- Update to 3.25.1 + +* Tue Apr 11 2017 Florian Müllner - 3.24.1-1 +- Update to 3.24.1 + +* Mon Mar 20 2017 Florian Müllner - 3.24.0-1 +- Update to 3.24.0 + +* Tue Mar 14 2017 Florian Müllner - 3.23.92-1 +- Update to 3.23.92 + +* Fri Mar 10 2017 Florian Müllner - 3.23.91-4 +- Apply startup-notification hack again + +* Tue Mar 07 2017 Adam Williamson - 3.23.91-3 +- Backport more color fixes, should really fix BGO #779234, RHBZ #1428559 + +* Thu Mar 02 2017 Adam Williamson - 3.23.91-2 +- Backport fix for a color issue in 3.23.91 (BGO #779234, RHBZ #1428559) + +* Wed Mar 01 2017 Florian Müllner - 3.23.91-1 +- Update to 3.23.91 + +* Thu Feb 16 2017 Florian Müllner - 3.23.90-1 +- Update to 3.23.90 + +* Fri Feb 10 2017 Fedora Release Engineering - 3.23.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Dec 15 2016 Florian Müllner - 3.23.3-1 +- Update to 3.23.3 + +* Fri Dec 02 2016 Florian Müllner - 3.23.2-2 +- Fix build error on 32-bit platforms + +* Thu Nov 24 2016 Kevin Fenzi - 3.23.2-2 +- Some fixes to get building. Still needs patch1 rebased. + +* Wed Nov 23 2016 Florian Müllner - 3.23.2-1 +- Update to 3.23.2 + +* Tue Nov 8 2016 Matthias Clasen - 3.23.1-2 +- Fix 1376471 + +* Sun Oct 30 2016 Florian Müllner - 3.23.1-1 +- Update to 3.23.1 + +* Tue Oct 18 2016 Kalev Lember - 3.22.1-3 +- Backport a fix to make gnome-screenshot --area work + +* Tue Oct 11 2016 Adam Jackson - 3.22.1-2 +- Prefer eglGetPlatformDisplay() to eglGetDisplay() + +* Tue Oct 11 2016 Florian Müllner - 3.22.1-1 +- Update to 3.22.1 + +* Wed Sep 28 2016 Florian Müllner - 3.22.0-2 +- Include fix for crash on VT switch + +* Mon Sep 19 2016 Florian Müllner - 3.22.0-1 +- Update to 3.22.0 + +* Tue Sep 13 2016 Florian Müllner - 3.21.92-1 +- Update to 3.21.92 + +* Thu Sep 08 2016 Kalev Lember - 3.21.91-2 +- wayland/cursor-role: Increase buffer use count on construction (#1373372) + +* Tue Aug 30 2016 Florian Müllner - 3.21.91-1 +- Update to 3.21.91 + +* Mon Aug 29 2016 Kalev Lember - 3.21.90-3 +- clutter/evdev: Fix absolute pointer motion events (#1369492) + +* Sat Aug 20 2016 Kalev Lember - 3.21.90-2 +- Update minimum dep versions + +* Fri Aug 19 2016 Florian Müllner - 3.21.90-1 +- Update to 3.21.90 + +* Wed Jul 20 2016 Florian Müllner - 3.21.4-1 +- Update to 3.21.4 +- Drop downstream patch +- Fix build error on 32-bit + +* Tue Jun 21 2016 Florian Müllner - 3.21.3-1 +- Update to 3.21.3 + +* Fri May 27 2016 Florian Müllner - 3.21.2-1 +- Update to 3.21.2 + +* Fri Apr 29 2016 Florian Müllner - 3.21.1-1 +- Update to 3.21.1 + +* Wed Apr 13 2016 Florian Müllner - 3.20.1-1 +- Update to 3.20.1 + +* Tue Mar 22 2016 Florian Müllner - 3.20.0-1 +- Update to 3.20.0 + +* Wed Mar 16 2016 Florian Müllner - 3.19.92-1 +- Update to 3.19.92 + +* Thu Mar 03 2016 Florian Müllner - 3.19.91-2 +- Include fix for invalid cursor wl_buffer access + +* Thu Mar 03 2016 Florian Müllner - 3.19.91-1 +- Update to 3.19.91 + +* Fri Feb 19 2016 Florian Müllner - 3.19.90-1 +- Update to 3.19.90 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.19.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 21 2016 Florian Müllner - 3.19.4-1 +- Update to 3.19.4 + +* Thu Dec 17 2015 Florian Müllner - 3.19.3-1 +- Update to 3.19.3 + +* Wed Nov 25 2015 Florian Müllner - 3.19.2-1 +- Update to 3.19.2 + +* Tue Nov 10 2015 Ray Strode 3.19.1-5.20151110git049f1556d +- Update to git snapshot + +* Thu Oct 29 2015 Florian Müllner - 3.19.1-1 +- Update to 3.19.1 + +* Wed Oct 21 2015 Ray Strode 3.18.1-4 +- Force the cursor visible on vt switches after setting + the crtc to workaround that qxl bug from before in a + different situation + Related: #1273247 + +* Wed Oct 21 2015 Kalev Lember - 3.18.1-3 +- Backport a fix for a common Wayland crash (#1266486) + +* Thu Oct 15 2015 Kalev Lember - 3.18.1-2 +- Bump gnome-shell conflicts version + +* Thu Oct 15 2015 Florian Müllner - 3.18.1-1 +- Update to 3.18.1 + +* Mon Sep 21 2015 Florian Müllner - 3.18.0-1 +- Update to 3.18.0 + +* Wed Sep 16 2015 Florian Müllner - 3.17.92-1 +- Update to 3.17.92 + +* Thu Sep 03 2015 Florian Müllner - 3.17.91-1 +- Update to 3.17.91 + +* Thu Sep 03 2015 Ray Strode 3.17.90-2 +- Add workaround for qxl cursor visibility wonkiness that we + did for f22 + Related: #1200901 + +* Thu Aug 20 2015 Florian Müllner - 3.17.90-1 +- Update to 3.17.90 + +* Thu Jul 23 2015 Florian Müllner - 3.17.4-1 +- Update to 3.17.4 + +* Wed Jul 22 2015 David King - 3.17.3-2 +- Bump for new gnome-desktop3 + +* Thu Jul 02 2015 Florian Müllner - 3.17.3-1 +- Update to 3.17.3 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.17.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed May 27 2015 Florian Müllner - 3.17.2-1 +- Update to 3.17.2 + +* Thu Apr 30 2015 Florian Müllner - 3.17.1-1 +- Update to 3.17.1 + +* Thu Apr 16 2015 Kalev Lember - 3.16.1.1-2 +- Bump gnome-shell conflicts version + +* Wed Apr 15 2015 Rui Matos - 3.16.1.1-1 +- Update to 3.16.1.1 + +* Tue Apr 14 2015 Florian Müllner - 3.16.1-1 +- Update to 3.16.1 + +* Mon Mar 23 2015 Florian Müllner - 3.16.0-1 +- Update to 3.16.0 + +* Tue Mar 17 2015 Kalev Lember - 3.15.92-2 +- Update minimum dep versions +- Use license macro for the COPYING file + +* Tue Mar 17 2015 Florian Müllner - 3.15.92-1 +- Update to 3.15.92 + +* Tue Mar 10 2015 Peter Hutterer - 3.15.91-2 +- Rebuild for libinput soname bump + +* Wed Mar 04 2015 Florian Müllner - 3.15.91-1 +- Update to 3.15.91 + +* Fri Feb 20 2015 Florian Müllner - 3.15.90-1 +- Update to 3.15.90 + +* Mon Feb 02 2015 Adam Williamson - 3.15.4-2 +- backport ad90b7dd to fix BGO #743412 / RHBZ #1185811 + +* Wed Jan 21 2015 Florian Müllner - 3.15.4-1 +- Update to 3.15.4 + +* Mon Jan 19 2015 Peter Hutterer 3.15.3-3 +- Rebuild for libinput soname bump + +* Mon Jan 12 2015 Ray Strode 3.15.3-2 +- Add specific BuildRequires for wayland bits, so we don't + get wayland support by happenstance. +- Add BuildRequires for autogoo since ./autogen.sh is run as part of + the build process + +* Fri Dec 19 2014 Florian Müllner - 3.15.3-1 +- Revert unsatisfiable wayland requirement + +* Fri Dec 19 2014 Florian Müllner - 3.15.3-1 +- Update to 3.15.3 + +* Thu Nov 27 2014 Florian Müllner - 3.15.2-1 +- Update to 3.15.2 + +* Wed Nov 12 2014 Vadim Rutkovsky - 3.15.1-2 +- Build installed tests + +* Thu Oct 30 2014 Florian Müllner - 3.15.1-1 +- Update to 3.15.1 + +* Tue Oct 21 2014 Florian Müllner - 3.14.1-2 +- Fix regression in handling raise-on-click option (rhbz#1151918) + +* Tue Oct 14 2014 Florian Müllner - 3.14.1-1 +- Update to 3.14.1 + +* Fri Oct 03 2014 Adam Williamson - 3.14.0-3 +- backport fix for BGO #737233 / RHBZ #1145952 (desktop right click broken) + +* Mon Sep 22 2014 Kalev Lember - 3.14.0-2 +- Bump gnome-shell conflicts version + +* Mon Sep 22 2014 Florian Müllner - 3.14.0-1 +- Update to 3.14.0 + +* Wed Sep 17 2014 Florian Müllner - 3.13.92-1 +- Update to 3.13.92 + +* Fri Sep 12 2014 Peter Hutterer - 3.13.91-2 +- Rebuild for libinput soname bump + +* Wed Sep 03 2014 Florian Müllner - 3.31.91-1 +- Update to 3.13.91, drop downstream patches + +* Tue Aug 26 2014 Adel Gadllah - 3.13.90-4 +- Apply fix for RH #1133166 + +* Mon Aug 25 2014 Hans de Goede - 3.13.90-3 +- Add a patch from upstream fixing gnome-shell crashing non stop on + multi monitor setups (rhbz#1103221) + +* Fri Aug 22 2014 Kevin Fenzi 3.13.90-2 +- Rebuild for new wayland + +* Wed Aug 20 2014 Florian Müllner - 3.13.90-1 +- Update to 3.13.90 + +* Mon Aug 18 2014 Kalev Lember - 3.13.4-3 +- Rebuilt for upower 0.99.1 soname bump + +* Sun Aug 17 2014 Fedora Release Engineering - 3.13.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Jul 23 2014 Florian Müllner - 3.13.4-1 +- Update to 3.13.4 + +* Tue Jul 22 2014 Kalev Lember - 3.13.3-2 +- Rebuilt for gobject-introspection 1.41.4 + +* Fri Jun 27 2014 Florian Müllner - 3.13.3-1 +- New gobject-introspection has been built, drop the last patch again + +* Wed Jun 25 2014 Florian Müllner - 3.13.3-1 +- Revert annotation updates until we get a new gobject-introspection build + +* Wed Jun 25 2014 Florian Müllner - 3.13.3-1 +- Update to 3.13.1 + +* Wed Jun 11 2014 Florian Müllner - 3.13.2-2 +- Backport fix for legacy fullscreen check + +* Sat Jun 07 2014 Fedora Release Engineering - 3.13.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue May 27 2014 Florian Müllner - 3.13.2-1 +- Update to 3.13.2, drop upstreamed patches + +* Thu May 8 2014 Matthias Clasen - 3.13.1-5 +- Fix shrinking terminals + +* Wed May 07 2014 Kalev Lember - 3.13.1-4 +- Backport an upstream fix for a Wayland session crash + +* Wed May 07 2014 Kalev Lember - 3.13.1-3 +- Install mutter-launch as setuid root + +* Thu May 01 2014 Kalev Lember - 3.13.1-2 +- Obsolete mutter-wayland + +* Wed Apr 30 2014 Florian Müllner - 3.13.1-1 +- Update to 3.13.1 + +* Tue Apr 15 2014 Florian Müllner - 3.12.1-1 +- Update to 3.12.1 + +* Sat Apr 05 2014 Kalev Lember - 3.12.0-2 +- Update dep versions + +* Tue Mar 25 2014 Florian Müllner - 3.12.0-1 +- Update to 3.12.0 + +* Wed Mar 19 2014 Florian Müllner - 3.11.92-1 +- Update to 3.11.92 + +* Thu Mar 06 2014 Florian Müllner - 3.11.91-1 +- Update to 3.11.91 + +* Thu Feb 20 2014 Kalev Lember - 3.11.90-2 +- Rebuilt for cogl soname bump + +* Wed Feb 19 2014 Florian Müllner - 3.11.90-1 +- Update to 3.11.90 + +* Wed Feb 19 2014 Richard Hughes - 3.11.5-4 +- Rebuilt for gnome-desktop soname bump + +* Mon Feb 10 2014 Peter Hutterer - 3.11.5-3 +- Rebuild for libevdev soname bump + +* Wed Feb 05 2014 Richard Hughes - 3.11.5-2 +- Rebuilt for cogl soname bump + +* Wed Feb 05 2014 Florian Müllner - 3.11.5-1 +- Update to 3.11.5 + +* Wed Jan 15 2014 Florian Müllner - 3.11.4-1 +- Update to 3.11.4 + +* Fri Dec 20 2013 Florian Müllner - 3.11.3-1 +- Update to 3.11.3 + +* Wed Nov 13 2013 Florian Müllner - 3.11.2-1 +- Update to 3.11.2 + +* Wed Oct 30 2013 Florian Müllner - 3.11.1-1 +- Update to 3.11.1 + +* Tue Oct 15 2013 Florian Müllner - 3.10.1.1-1 +- Update to 3.10.1.1 + +* Mon Oct 14 2013 Florian Müllner - 3.10.1-1 +- Update to 3.10.1 + +* Wed Sep 25 2013 Florian Müllner - 3.10.0.1-1 +- Update to 3.10.0.1 + +* Mon Sep 23 2013 Florian Müllner - 3.10.0-1 +- Update to 3.10.0 + +* Tue Sep 17 2013 Kalev Lember - 3.9.92-2 +- Update the description and URL +- Tighten -devel subpackage deps with _isa +- Use the make_install macro + +* Mon Sep 16 2013 Florian Müllner - 3.9.92-1 +- Update to 3.9.92 + +* Tue Sep 03 2013 Kalev Lember - 3.9.91-2 +- Rebuilt for libgnome-desktop soname bump + +* Tue Sep 03 2013 Florian Müllner - 3.9.91-1 +- Update to 3.9.91 + +* Thu Aug 22 2013 Florian Müllner - 3.9.90-1 +- Update to 3.9.90 + +* Fri Aug 09 2013 Kalev Lember - 3.9.5-2 +- Rebuilt for cogl 1.15.4 soname bump + +* Tue Jul 30 2013 Florian Müllner - 3.9.5-1 +- Update to 3.9.5 + +* Wed Jul 10 2013 Florian Müllner - 3.9.4-1 +- Update to 3.9.4 + +* Tue Jun 18 2013 Florian Müllner - 3.9.3-1 +- Update to 3.9.3 + +* Tue May 28 2013 Florian Müllner - 3.9.2-1 +- Update to 3.9.2 + +* Wed May 01 2013 Florian Müllner - 3.9.1-1 +- Update to 3.9.1 + +* Tue Apr 23 2013 Florian Müllner - 3.8.1-1 +- Update to 3.8.1 + +* Tue Mar 26 2013 Florian Müllner - 3.8.0-1 +- Update to 3.8.0 + +* Tue Mar 19 2013 Florian Müllner - 3.7.92-1 +- Update to 3.7.92 + +* Mon Mar 04 2013 Florian Müllner - 3.7.91-1 +- Update to 3.7.91 + +* Wed Feb 20 2013 Florian Müllner - 3.7.90-1 +- Update to 3.7.90 + +* Tue Feb 05 2013 Florian Müllner - 3.7.5-1 +- Update to 3.7.5 + +* Fri Jan 25 2013 Peter Robinson 3.7.4-2 +- Rebuild for new cogl + +* Tue Jan 15 2013 Florian Müllner - 3.7.4-1 +- Update to 3.7.4 + +* Tue Dec 18 2012 Florian Müllner - 3.7.3-1 +- Update to 3.7.3 + +* Mon Nov 19 2012 Florian Müllner - 3.7.2-1 +- Update to 3.7.2 + +* Fri Nov 09 2012 Kalev Lember - 3.7.1-1 +- Update to 3.7.1 + +* Mon Oct 15 2012 Florian Müllner - 3.6.1-1 +- Update to 3.6.1 + +* Tue Sep 25 2012 Florian Müllner - 3.6.0-1 +- Update to 3.6.0 + +* Wed Sep 19 2012 Florian Müllner - 3.5.92-1 +- Update to 3.5.92 + +* Tue Sep 04 2012 Debarshi Ray - 3.5.91-2 +- Rebuild against new cogl + +* Tue Sep 04 2012 Debarshi Ray - 3.5.91-1 +- Update to 3.5.91 + +* Tue Aug 28 2012 Matthias Clasen - 3.5.90-2 +- Rebuild against new cogl/clutter + +* Tue Aug 21 2012 Richard Hughes - 3.5.90-1 +- Update to 3.5.90 + +* Tue Aug 07 2012 Richard Hughes - 3.5.5-1 +- Update to 3.5.5 + +* Fri Jul 27 2012 Fedora Release Engineering - 3.5.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 17 2012 Richard Hughes - 3.5.4-1 +- Update to 3.5.4 + +* Tue Jun 26 2012 Matthias Clasen - 3.5.3-1 +- Update to 3.5.3 + +* Fri Jun 8 2012 Matthias Clasen - 3.5.2-3 +- Make resize grip area larger + +* Thu Jun 07 2012 Matthias Clasen - 3.5.2-2 +- Don't check for Xinerama anymore - it is now mandatory + +* Thu Jun 07 2012 Richard Hughes - 3.5.2-1 +- Update to 3.5.2 +- Remove upstreamed patches + +* Wed May 09 2012 Adam Jackson 3.4.1-3 +- mutter-never-slice-shape-mask.patch, mutter-use-cogl-texrect-api.patch: + Fix window texturing on hardware without ARB_texture_non_power_of_two + (#813648) + +* Wed Apr 18 2012 Kalev Lember - 3.4.1-2 +- Silence glib-compile-schemas scriplets + +* Wed Apr 18 2012 Kalev Lember - 3.4.1-1 +- Update to 3.4.1 +- Conflict with gnome-shell versions older than 3.4.1 + +* Tue Mar 27 2012 Richard Hughes - 3.4.0-1 +- Update to 3.4.0 + +* Wed Mar 21 2012 Kalev Lember - 3.3.92-1 +- Update to 3.3.92 + +* Sat Mar 10 2012 Matthias Clasen - 3.3.90-2 +- Rebuild against new cogl + +* Sat Feb 25 2012 Matthias Clasen - 3.3.90-1 +- Update to 3.3.90 + +* Tue Feb 7 2012 Matthias Clasen - 3.3.5-1 +- Update to 3.3.5 + +* Fri Jan 20 2012 Matthias Clasen - 3.3.4-1 +- Update to 3.3.4 + +* Thu Jan 19 2012 Matthias Clasen - 3.3.3-2 +- Rebuild against new cogl + +* Thu Jan 5 2012 Matthias Clasen - 3.3.3-1 +- Update to 3.3.3 + +* Wed Nov 23 2011 Matthias Clasen - 3.3.2-2 +- Rebuild against new clutter + +* Tue Nov 22 2011 Matthias Clasen - 3.3.2-1 +- Update to 3.3.2 + +* Wed Oct 26 2011 Fedora Release Engineering - 3.2.1-2 +- Rebuilt for glibc bug#747377 + +* Wed Oct 19 2011 Matthias Clasen - 3.2.1-1 +- Update to 3.2.1 + +* Mon Sep 26 2011 Owen Taylor - 3.2.0-1 +- Update to 3.2.0 + +* Tue Sep 20 2011 Matthias Clasen - 3.1.92-1 +- Update to 3.1.92 + +* Wed Sep 14 2011 Owen Taylor - 3.1.91.1-1 +- Update to 3.1.91.1 + +* Wed Aug 31 2011 Matthias Clasen - 3.1.90.1-1 +- Update to 3.1.90.1 + +* Wed Jul 27 2011 Matthias Clasen - 3.1.4-1 +- Update to 3.1.4 + +* Wed Jul 27 2011 Matthias Clasen - 3.1.3.1-3 +- Rebuild + +* Mon Jul 4 2011 Peter Robinson - 3.1.3.1-2 +- rebuild against new clutter/cogl + +* Mon Jul 04 2011 Adam Williamson - 3.1.3.1-1 +- Update to 3.1.3.1 + +* Thu Jun 30 2011 Owen Taylor - 3.1.3-1 +- Update to 3.1.3 + +* Wed May 25 2011 Owen Taylor - 3.0.2.1-1 +- Update to 3.0.2.1 + +* Fri Apr 29 2011 Matthias Clasen - 3.0.1-3 +- Actually apply the patch for #700276 + +* Thu Apr 28 2011 Matthias Clasen - 3.0.1-2 +- Make session saving of gnome-shell work + +* Mon Apr 25 2011 Owen Taylor - 3.0.1-1 +- Update to 3.0.1 + +* Mon Apr 4 2011 Owen Taylor - 3.0.0-1 +- Update to 3.0.0 + +* Mon Mar 28 2011 Matthias Clasen - 2.91.93-1 +- Update to 2.91.93 + +* Wed Mar 23 2011 Matthias Clasen - 2.91.92-1 +- Update to 2.91.92 + +* Mon Mar 7 2011 Owen Taylor - 2.91.91-1 +- Update to 2.91.91 + +* Tue Mar 1 2011 Matthias Clasen - 2.91.90-2 +- Build against libcanberra, to enable AccessX feedback features + +* Tue Feb 22 2011 Matthias Clasen - 2.91.90-1 +- Update to 2.91.90 + +* Thu Feb 10 2011 Matthias Clasen - 2.91.6-4 +- Rebuild against newer gtk + +* Tue Feb 08 2011 Fedora Release Engineering - 2.91.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Feb 2 2011 Matthias Clasen - 2.91.6-2 +- Rebuild against newer gtk + +* Tue Feb 1 2011 Owen Taylor - 2.91.6-1 +- Update to 2.91.6 + +* Tue Jan 11 2011 Matthias Clasen - 2.91.5-1 +- Update to 2.91.5 + +* Fri Jan 7 2011 Matthias Clasen - 2.91.4-1 +- Update to 2.91.4 + +* Fri Dec 3 2010 Matthias Clasen - 2.91.3-2 +- Rebuild against new gtk +- Drop no longer needed %%clean etc + +* Mon Nov 29 2010 Owen Taylor - 2.91.3-1 +- Update to 2.91.3 + +* Tue Nov 9 2010 Owen Taylor - 2.91.2-1 +- Update to 2.91.2 + +* Tue Nov 2 2010 Matthias Clasen - 2.91.1-2 +- Rebuild against newer gtk3 + +* Fri Oct 29 2010 Owen Taylor - 2.91.1-1 +- Update to 2.91.1 + +* Mon Oct 4 2010 Owen Taylor - 2.91.0-1 +- Update to 2.91.0 + +* Wed Sep 22 2010 Matthias Clasen - 2.31.5-4 +- Rebuild against newer gobject-introspection + +* Wed Jul 14 2010 Colin Walters - 2.31.5-3 +- Rebuild for new gobject-introspection + +* Tue Jul 13 2010 Adel Gadllah - 2.31.5-2 +- Build against gtk3 + +* Mon Jul 12 2010 Colin Walters - 2.31.5-1 +- New upstream version + +* Mon Jul 12 2010 Colin Walters - 2.31.2-5 +- Rebuild against new gobject-introspection + +* Tue Jul 6 2010 Colin Walters - 2.31.2-4 +- Changes to support snapshot builds + +* Fri Jun 25 2010 Colin Walters - 2.31.2-3 +- drop gir-repository-devel dep + +* Wed May 26 2010 Adam Miller - 2.31.2-2 +- removed "--with-clutter" as configure is claiming it to be an unknown option + +* Wed May 26 2010 Adam Miller - 2.31.2-1 +- New upstream 2.31.2 release + +* Thu Mar 25 2010 Peter Robinson 2.29.1-1 +- New upstream 2.29.1 release + +* Wed Mar 17 2010 Peter Robinson 2.29.0-1 +- New upstream 2.29.0 release + +* Tue Feb 16 2010 Adam Jackson 2.28.1-0.2 +- mutter-2.28.1-add-needed.patch: Fix FTBFS from --no-add-needed + +* Thu Feb 4 2010 Peter Robinson 2.28.1-0.1 +- Move to git snapshot + +* Wed Oct 7 2009 Owen Taylor - 2.28.0-1 +- Update to 2.28.0 + +* Tue Sep 15 2009 Owen Taylor - 2.27.5-1 +- Update to 2.27.5 + +* Fri Sep 4 2009 Owen Taylor - 2.27.4-1 +- Remove workaround for #520209 +- Update to 2.27.4 + +* Sat Aug 29 2009 Owen Taylor - 2.27.3-3 +- Fix %%preun GConf script to properly be for package removal + +* Fri Aug 28 2009 Owen Taylor - 2.27.3-2 +- Add a workaround for Red Hat bug #520209 + +* Fri Aug 28 2009 Owen Taylor - 2.27.3-1 +- Update to 2.27.3, remove mutter-metawindow.patch + +* Fri Aug 21 2009 Peter Robinson 2.27.2-2 +- Add upstream patch needed by latest mutter-moblin + +* Tue Aug 11 2009 Peter Robinson 2.27.2-1 +- New upstream 2.27.2 release. Drop upstreamed patches. + +* Wed Jul 29 2009 Peter Robinson 2.27.1-5 +- Add upstream patches for clutter 1.0 + +* Wed Jul 29 2009 Peter Robinson 2.27.1-4 +- Add patch to fix mutter --replace + +* Sat Jul 25 2009 Fedora Release Engineering - 2.27.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Sat Jul 18 2009 Peter Robinson 2.27.1-2 +- Updates from review request + +* Fri Jul 17 2009 Peter Robinson 2.27.1-1 +- Update to official 2.27.1 and review updates + +* Thu Jun 18 2009 Peter Robinson 2.27.0-0.2 +- Updates from initial reviews + +* Thu Jun 18 2009 Peter Robinson 2.27.0-0.1 +- Initial packaging