commit 9b8827b4f32da407974ad3b2a1d078ac1bf0e65e Author: CentOS Sources Date: Tue Nov 15 01:27:52 2022 -0500 import mutter-40.9-9.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56b1812 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mutter-40.9.tar.xz diff --git a/.mutter.metadata b/.mutter.metadata new file mode 100644 index 0000000..4e26344 --- /dev/null +++ b/.mutter.metadata @@ -0,0 +1 @@ +f9b20f8330ecdb76fc887c4a99c03b406e26fd66 SOURCES/mutter-40.9.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..d847397 --- /dev/null +++ b/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch @@ -0,0 +1,35 @@ +From 9d0ded3178777cd6afcdd5fff7b6f0f39a0d5236 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 85aded9a6..e749ab6b9 100644 +--- a/src/backends/native/meta-kms-device.c ++++ b/src/backends/native/meta-kms-device.c +@@ -253,6 +253,7 @@ is_atomic_allowed (const char *driver_name) + "vboxvideo", + "nvidia-drm", + "virtio_gpu", ++ "tegra", + NULL, + }; + +-- +2.32.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-backends-Move-MetaKeyboardA11yFlags-to-a-public-head.patch b/SOURCES/0001-backends-Move-MetaKeyboardA11yFlags-to-a-public-head.patch new file mode 100644 index 0000000..7af82f1 --- /dev/null +++ b/SOURCES/0001-backends-Move-MetaKeyboardA11yFlags-to-a-public-head.patch @@ -0,0 +1,144 @@ +From 651f5e0c6a33d9ac32c2a16735a026153a2ddf38 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 14 Jun 2022 16:31:43 +0200 +Subject: [PATCH] backends: Move MetaKeyboardA11yFlags to a public header + +The MetaKeyboardA11yFlags are used by gnome-shell to show a dialog +whenever a keyboard accessibility feature is switched using the +keyboard. + +Unfortunately, commit c3acaeb25 renamed the Clutter flag to Meta and +moved them to a private header. As a result, gnome-shell do not show any +dialog anymore when a keyboard accessibility feature is activated. + +Move the MetaKeyboardA11yFlags definition to a public header so that +gnome-shell can use it. + +Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2306 +Fixes: c3acaeb25 - backends: Move keyboard a11y into backends +Part-of: +--- + src/backends/meta-input-settings-private.h | 19 +------ + src/meta/meson.build | 1 + + src/meta/meta-enums.h | 62 ++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 18 deletions(-) + create mode 100644 src/meta/meta-enums.h + +diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h +index 42ee0e0e6..5ef54ee84 100644 +--- a/src/backends/meta-input-settings-private.h ++++ b/src/backends/meta-input-settings-private.h +@@ -31,29 +31,12 @@ + #include "backends/meta-backend-types.h" + #include "clutter/clutter.h" + #include "meta/display.h" ++#include "meta/meta-enums.h" + + #define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ()) + G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings, + META, INPUT_SETTINGS, GObject) + +-typedef enum +-{ +- META_A11Y_KEYBOARD_ENABLED = 1 << 0, +- META_A11Y_TIMEOUT_ENABLED = 1 << 1, +- META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2, +- META_A11Y_SLOW_KEYS_ENABLED = 1 << 3, +- META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4, +- META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5, +- META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6, +- META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7, +- META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8, +- META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9, +- META_A11Y_STICKY_KEYS_ENABLED = 1 << 10, +- META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11, +- META_A11Y_STICKY_KEYS_BEEP = 1 << 12, +- META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13, +-} MetaKeyboardA11yFlags; +- + /** + * MetaKbdA11ySettings: + * +diff --git a/src/meta/meson.build b/src/meta/meson.build +index a096ee4dd..4a67abb25 100644 +--- a/src/meta/meson.build ++++ b/src/meta/meson.build +@@ -17,6 +17,7 @@ mutter_public_headers = [ + 'meta-close-dialog.h', + 'meta-cursor-tracker.h', + 'meta-dnd.h', ++ 'meta-enums.h', + 'meta-idle-monitor.h', + 'meta-inhibit-shortcuts-dialog.h', + 'meta-launch-context.h', +diff --git a/src/meta/meta-enums.h b/src/meta/meta-enums.h +new file mode 100644 +index 000000000..e59ebaf72 +--- /dev/null ++++ b/src/meta/meta-enums.h +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2016-2021 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, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++ * 02111-1307, USA. ++ * ++ */ ++ ++#ifndef META_ENUMS_H ++#define META_ENUMS_H ++ ++/** ++ * MetaKeyboardA11yFlags: ++ * @META_A11Y_KEYBOARD_ENABLED: ++ * @META_A11Y_TIMEOUT_ENABLED: ++ * @META_A11Y_MOUSE_KEYS_ENABLED: ++ * @META_A11Y_SLOW_KEYS_ENABLED: ++ * @META_A11Y_SLOW_KEYS_BEEP_PRESS: ++ * @META_A11Y_SLOW_KEYS_BEEP_ACCEPT: ++ * @META_A11Y_SLOW_KEYS_BEEP_REJECT: ++ * @META_A11Y_BOUNCE_KEYS_ENABLED: ++ * @META_A11Y_BOUNCE_KEYS_BEEP_REJECT: ++ * @META_A11Y_TOGGLE_KEYS_ENABLED: ++ * @META_A11Y_STICKY_KEYS_ENABLED: ++ * @META_A11Y_STICKY_KEYS_TWO_KEY_OFF: ++ * @META_A11Y_STICKY_KEYS_BEEP: ++ * @META_A11Y_FEATURE_STATE_CHANGE_BEEP: ++ * ++ * Keyboard accessibility features. ++ * ++ */ ++typedef enum ++{ ++ META_A11Y_KEYBOARD_ENABLED = 1 << 0, ++ META_A11Y_TIMEOUT_ENABLED = 1 << 1, ++ META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2, ++ META_A11Y_SLOW_KEYS_ENABLED = 1 << 3, ++ META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4, ++ META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5, ++ META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6, ++ META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7, ++ META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8, ++ META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9, ++ META_A11Y_STICKY_KEYS_ENABLED = 1 << 10, ++ META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11, ++ META_A11Y_STICKY_KEYS_BEEP = 1 << 12, ++ META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13, ++} MetaKeyboardA11yFlags; ++ ++#endif /* META_ENUMS_H */ +-- +2.36.1 + diff --git a/SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch b/SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch new file mode 100644 index 0000000..1099461 --- /dev/null +++ b/SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch @@ -0,0 +1,260 @@ +From a1f33bdac95ba4fd0599f164ef893c05d8be123b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 6 Oct 2021 15:31:30 -0400 +Subject: [PATCH] backends/x11: Fix key repeat of on-screen keyboard for second + level keysyms + +Certains keys (such as ~ and |) are in the keyboard map behind the +second shift level. This means in order for them to be input, the +shift key needs to be held down by the user. + +The GNOME Shell on-screen keyboard presents these keys separately on +a page of keys that has no shift key. Instead, it relies on mutter +to set a shift latch before the key event is emitted. A shift latch +is a virtual press of the shift key that automatically gets released +after the next key press (in our case the ~ or | key). + +The problem is using a shift latch doesn't work very well in the face +of key repeat. The latch is automatically released after the first +press, and subsequent repeats of that press no longer have shift +latched to them. + +This commit fixes the problem by using a shift lock instead of a shift +latch. A shift lock is never implicitly released, so it remains +in place for the duration of key repeat. +--- + src/backends/x11/meta-keymap-x11.c | 12 ++++++------ + src/backends/x11/meta-keymap-x11.h | 6 +++--- + src/backends/x11/meta-virtual-input-device-x11.c | 4 ++-- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c +index da5d064e7..1192cc387 100644 +--- a/src/backends/x11/meta-keymap-x11.c ++++ b/src/backends/x11/meta-keymap-x11.c +@@ -829,85 +829,85 @@ meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11, + g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval); + return FALSE; + } + + if (!meta_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval)) + { + g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval); + return FALSE; + } + + g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval)); + g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out)); + + return TRUE; + } + + void + meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11, + uint32_t keycode) + { + g_return_if_fail (META_IS_KEYMAP_X11 (keymap_x11)); + + if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) || + g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1) + return; + + g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)); + } + + void +-meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11, +- uint32_t level, +- gboolean enable) ++meta_keymap_x11_lock_modifiers (MetaKeymapX11 *keymap_x11, ++ uint32_t level, ++ gboolean enable) + { + uint32_t modifiers[] = { + 0, + ShiftMask, + keymap_x11->level3_shift_mask, + keymap_x11->level3_shift_mask | ShiftMask, + }; + uint32_t value = 0; + + if (!keymap_x11->use_xkb) + return; + + level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1); + + if (enable) + value = modifiers[level]; + else + value = 0; + +- XkbLatchModifiers (clutter_x11_get_default_display (), +- XkbUseCoreKbd, modifiers[level], +- value); ++ XkbLockModifiers (clutter_x11_get_default_display (), ++ XkbUseCoreKbd, modifiers[level], ++ value); + } + + static uint32_t + meta_keymap_x11_get_current_group (MetaKeymapX11 *keymap_x11) + { + XkbStateRec state_rec; + + if (keymap_x11->current_group >= 0) + return keymap_x11->current_group; + + XkbGetState (clutter_x11_get_default_display (), + XkbUseCoreKbd, &state_rec); + return XkbStateGroup (&state_rec); + } + + gboolean + meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11, + uint32_t keyval, + uint32_t *keycode_out, + uint32_t *level_out) + { + ClutterKeymapKey *keys; + int i, n_keys, group; + gboolean found = FALSE; + + g_return_val_if_fail (keycode_out != NULL, FALSE); + g_return_val_if_fail (level_out != NULL, FALSE); + + group = meta_keymap_x11_get_current_group (keymap_x11); + +diff --git a/src/backends/x11/meta-keymap-x11.h b/src/backends/x11/meta-keymap-x11.h +index 67a5f8eb9..2f93acdbc 100644 +--- a/src/backends/x11/meta-keymap-x11.h ++++ b/src/backends/x11/meta-keymap-x11.h +@@ -17,45 +17,45 @@ + * Author: Emmanuele Bassi + */ + + #ifndef META_KEYMAP_X11_H + #define META_KEYMAP_X11_H + + #include + #include + + #include "clutter/clutter.h" + + G_BEGIN_DECLS + + #define META_TYPE_KEYMAP_X11 (meta_keymap_x11_get_type ()) + G_DECLARE_FINAL_TYPE (MetaKeymapX11, meta_keymap_x11, + META, KEYMAP_X11, ClutterKeymap) + + int meta_keymap_x11_get_key_group (MetaKeymapX11 *keymap, + ClutterModifierType state); + int meta_keymap_x11_translate_key_state (MetaKeymapX11 *keymap, + guint hardware_keycode, + ClutterModifierType *modifier_state_p, + ClutterModifierType *mods_p); + gboolean meta_keymap_x11_get_is_modifier (MetaKeymapX11 *keymap, + int keycode); + + gboolean meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11, + guint keyval, + guint *keycode_out, + guint *level_out); +-void meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11, +- uint32_t level, +- gboolean enable); ++void meta_keymap_x11_lock_modifiers (MetaKeymapX11 *keymap_x11, ++ uint32_t level, ++ gboolean enable); + gboolean meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11, + guint keyval, + guint *keycode_out); + void meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11, + guint keycode); + + gboolean meta_keymap_x11_handle_event (MetaKeymapX11 *keymap_x11, + XEvent *xevent); + + G_END_DECLS + + #endif /* META_KEYMAP_X11_H */ +diff --git a/src/backends/x11/meta-virtual-input-device-x11.c b/src/backends/x11/meta-virtual-input-device-x11.c +index fe6040859..1a5cdfc2e 100644 +--- a/src/backends/x11/meta-virtual-input-device-x11.c ++++ b/src/backends/x11/meta-virtual-input-device-x11.c +@@ -159,71 +159,71 @@ meta_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_dev + ClutterKeyState key_state) + { + XTestFakeKeyEvent (clutter_x11_get_default_display (), + key + 8, key_state == CLUTTER_KEY_STATE_PRESSED, 0); + } + + static void + meta_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t keyval, + ClutterKeyState key_state) + { + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + MetaKeymapX11 *keymap = META_KEYMAP_X11 (clutter_seat_get_keymap (seat)); + uint32_t keycode, level; + + if (!meta_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level)) + { + level = 0; + + if (!meta_keymap_x11_reserve_keycode (keymap, keyval, &keycode)) + { + g_warning ("No keycode found for keyval %x in current group", keyval); + return; + } + } + + if (!meta_keymap_x11_get_is_modifier (keymap, keycode) && + key_state == CLUTTER_KEY_STATE_PRESSED) +- meta_keymap_x11_latch_modifiers (keymap, level, TRUE); ++ meta_keymap_x11_lock_modifiers (keymap, level, TRUE); + + XTestFakeKeyEvent (clutter_x11_get_default_display (), + (KeyCode) keycode, + key_state == CLUTTER_KEY_STATE_PRESSED, 0); + + + if (key_state == CLUTTER_KEY_STATE_RELEASED) + { + if (!meta_keymap_x11_get_is_modifier (keymap, keycode)) +- meta_keymap_x11_latch_modifiers (keymap, level, FALSE); ++ meta_keymap_x11_lock_modifiers (keymap, level, FALSE); + meta_keymap_x11_release_keycode_if_needed (keymap, keycode); + } + } + + static void + meta_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot, + double x, + double y) + { + g_warning ("Virtual touch motion not implemented under X11"); + } + + static void + meta_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot, + double x, + double y) + { + g_warning ("Virtual touch motion not implemented under X11"); + } + + static void + meta_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot) + { + g_warning ("Virtual touch motion not implemented under X11"); +-- +2.33.1 + diff --git a/SOURCES/0001-clutter-Make-ClutterClickAction-independent-of-click.patch b/SOURCES/0001-clutter-Make-ClutterClickAction-independent-of-click.patch new file mode 100644 index 0000000..35af59d --- /dev/null +++ b/SOURCES/0001-clutter-Make-ClutterClickAction-independent-of-click.patch @@ -0,0 +1,38 @@ +From 28030178d7682ce5be03cb7273365ab628065871 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Mon, 27 Sep 2021 20:37:30 +0200 +Subject: [PATCH] clutter: Make ClutterClickAction independent of click count + +This will trigger for every button press/release that is obtained, +regardless of the click count. + +Part-of: +--- + clutter/clutter/clutter-click-action.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/clutter/clutter/clutter-click-action.c b/clutter/clutter/clutter-click-action.c +index 45d87e809..266b6da92 100644 +--- a/clutter/clutter/clutter-click-action.c ++++ b/clutter/clutter/clutter-click-action.c +@@ -306,9 +306,6 @@ on_event (ClutterActor *actor, + case CLUTTER_TOUCH_BEGIN: + has_button = FALSE; + case CLUTTER_BUTTON_PRESS: +- if (has_button && clutter_event_get_click_count (event) != 1) +- return CLUTTER_EVENT_PROPAGATE; +- + if (priv->is_held) + return CLUTTER_EVENT_STOP; + +@@ -386,7 +383,6 @@ on_captured_event (ClutterActor *stage, + return CLUTTER_EVENT_STOP; + + if ((has_button && clutter_event_get_button (event) != priv->press_button) || +- (has_button && clutter_event_get_click_count (event) != 1) || + clutter_event_get_device (event) != priv->press_device || + clutter_event_get_event_sequence (event) != priv->press_sequence) + return CLUTTER_EVENT_PROPAGATE; +-- +2.35.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-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch b/SOURCES/0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch new file mode 100644 index 0000000..24a5bcd --- /dev/null +++ b/SOURCES/0001-events-Pass-CurrentTime-to-XIAllowEvents-when-unfree.patch @@ -0,0 +1,26 @@ +From 65ffd7e4df42cd62633f93107644f87208881578 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Thu, 14 Apr 2022 18:07:41 +0200 +Subject: [PATCH] events: Pass CurrentTime to XIAllowEvents() when unfreezing + pointer + +--- + src/core/events.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/events.c b/src/core/events.c +index 0dc3a73222..dd9b4ec981 100644 +--- a/src/core/events.c ++++ b/src/core/events.c +@@ -205,7 +205,7 @@ maybe_unfreeze_pointer_events (MetaBackend *backend, + } + + xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); +- XIAllowEvents (xdisplay, device_id, event_mode, event->button.time); ++ XIAllowEvents (xdisplay, device_id, event_mode, CurrentTime); + } + + static gboolean +-- +2.34.1 + diff --git a/SOURCES/0001-kms-Allow-passing-framebuffer-damage-metadata.patch b/SOURCES/0001-kms-Allow-passing-framebuffer-damage-metadata.patch new file mode 100644 index 0000000..6143687 --- /dev/null +++ b/SOURCES/0001-kms-Allow-passing-framebuffer-damage-metadata.patch @@ -0,0 +1,193 @@ +From af0460d0cedd5a66b2110ab2a99e67c647e7b6fb Mon Sep 17 00:00:00 2001 +From: Piotr Lopatka +Date: Fri, 3 Sep 2021 19:39:12 +0100 +Subject: [PATCH 1/2] kms: Allow passing framebuffer damage metadata + +This commit adds support to atomic KMS backend for optional plane property +prop_fb_damage_clips. Some drivers (e.g. EVDI) take advantage of this +property and process only updated regions of the screen instead of +processing the full frame. This can save system resources. + +Part-of: +--- + .../native/meta-kms-impl-device-atomic.c | 28 +++++++++++++++ + src/backends/native/meta-kms-plane-private.h | 1 + + src/backends/native/meta-kms-plane.c | 5 +++ + src/backends/native/meta-kms-update-private.h | 7 ++++ + src/backends/native/meta-kms-update.c | 35 +++++++++++++++++++ + src/backends/native/meta-kms-update.h | 4 +++ + 6 files changed, 80 insertions(+) + +diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c +index 8e41207ee14..674a24902bd 100644 +--- a/src/backends/native/meta-kms-impl-device-atomic.c ++++ b/src/backends/native/meta-kms-impl-device-atomic.c +@@ -416,6 +416,8 @@ process_plane_assignment (MetaKmsImplDevice *impl_device, + MetaKmsPlaneAssignment *plane_assignment = update_entry; + MetaKmsPlane *plane = plane_assignment->plane; + MetaDrmBuffer *buffer; ++ MetaKmsFbDamage *fb_damage; ++ uint32_t prop_id; + + buffer = plane_assignment->buffer; + +@@ -539,6 +541,32 @@ process_plane_assignment (MetaKmsImplDevice *impl_device, + return FALSE; + } + ++ fb_damage = plane_assignment->fb_damage; ++ if (fb_damage && ++ meta_kms_plane_get_prop_id (plane, ++ META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID)) ++ { ++ meta_topic (META_DEBUG_KMS, ++ "[atomic] Setting %d damage clips on %u", ++ fb_damage->n_rects, ++ meta_kms_plane_get_id (plane)); ++ ++ prop_id = store_new_blob (impl_device, ++ blob_ids, ++ fb_damage->rects, ++ fb_damage->n_rects * ++ sizeof (struct drm_mode_rect), ++ error); ++ if (!prop_id) ++ return FALSE; ++ ++ if (!add_plane_property (impl_device, ++ plane, req, ++ META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID, ++ prop_id, ++ error)) ++ return FALSE; ++ } + return TRUE; + } + +diff --git a/src/backends/native/meta-kms-plane-private.h b/src/backends/native/meta-kms-plane-private.h +index 92f9cfcc9aa..f735c8da8f6 100644 +--- a/src/backends/native/meta-kms-plane-private.h ++++ b/src/backends/native/meta-kms-plane-private.h +@@ -41,6 +41,7 @@ typedef enum _MetaKmsPlaneProp + META_KMS_PLANE_PROP_CRTC_H, + META_KMS_PLANE_PROP_FB_ID, + META_KMS_PLANE_PROP_CRTC_ID, ++ META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID, + META_KMS_PLANE_N_PROPS + } MetaKmsPlaneProp; + +diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c +index 73fab7d8f80..3cb58764ff3 100644 +--- a/src/backends/native/meta-kms-plane.c ++++ b/src/backends/native/meta-kms-plane.c +@@ -446,6 +446,11 @@ init_properties (MetaKmsPlane *plane, + .name = "CRTC_ID", + .type = DRM_MODE_PROP_OBJECT, + }, ++ [META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID] = ++ { ++ .name = "FB_DAMAGE_CLIPS", ++ .type = DRM_MODE_PROP_BLOB, ++ }, + } + }; + +diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h +index 22491ece2d5..c89622d09a5 100644 +--- a/src/backends/native/meta-kms-update-private.h ++++ b/src/backends/native/meta-kms-update-private.h +@@ -34,6 +34,12 @@ typedef struct _MetaKmsFeedback + GError *error; + } MetaKmsFeedback; + ++typedef struct _MetaKmsFbDamage ++{ ++ struct drm_mode_rect *rects; ++ int n_rects; ++} MetaKmsFbDamage; ++ + typedef struct _MetaKmsPlaneAssignment + { + MetaKmsUpdate *update; +@@ -43,6 +49,7 @@ typedef struct _MetaKmsPlaneAssignment + MetaFixed16Rectangle src_rect; + MetaRectangle dst_rect; + MetaKmsAssignPlaneFlag flags; ++ MetaKmsFbDamage *fb_damage; + + uint64_t rotation; + +diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c +index be6eaefcc2c..71e5b423fb7 100644 +--- a/src/backends/native/meta-kms-update.c ++++ b/src/backends/native/meta-kms-update.c +@@ -129,9 +129,17 @@ meta_kms_feedback_get_error (const MetaKmsFeedback *feedback) + return feedback->error; + } + ++static void ++meta_kms_fb_damage_free (MetaKmsFbDamage *fb_damage) ++{ ++ g_free (fb_damage->rects); ++ g_free (fb_damage); ++} ++ + static void + meta_kms_plane_assignment_free (MetaKmsPlaneAssignment *plane_assignment) + { ++ g_clear_pointer (&plane_assignment->fb_damage, meta_kms_fb_damage_free); + g_free (plane_assignment); + } + +@@ -456,6 +464,33 @@ meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update, + update->custom_page_flip = custom_page_flip; + } + ++void ++meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment, ++ const int *rectangles, ++ int n_rectangles) ++{ ++ MetaKmsFbDamage *fb_damage; ++ struct drm_mode_rect *mode_rects; ++ int i; ++ ++ mode_rects = g_new0 (struct drm_mode_rect, n_rectangles); ++ for (i = 0; i < n_rectangles; ++i) ++ { ++ mode_rects[i].x1 = rectangles[i * 4]; ++ mode_rects[i].y1 = rectangles[i * 4 + 1]; ++ mode_rects[i].x2 = mode_rects[i].x1 + rectangles[i * 4 + 2]; ++ mode_rects[i].y2 = mode_rects[i].y1 + rectangles[i * 4 + 3]; ++ } ++ ++ fb_damage = g_new0 (MetaKmsFbDamage, 1); ++ *fb_damage = (MetaKmsFbDamage) { ++ .rects = mode_rects, ++ .n_rects = n_rectangles, ++ }; ++ ++ plane_assignment->fb_damage = fb_damage; ++} ++ + void + meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment, + uint64_t rotation) +diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h +index 4a6a8bb4373..e63b6d8711d 100644 +--- a/src/backends/native/meta-kms-update.h ++++ b/src/backends/native/meta-kms-update.h +@@ -115,6 +115,10 @@ void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update, + const uint16_t *green, + const uint16_t *blue); + ++void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment, ++ const int *rectangles, ++ int n_rectangles); ++ + MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + MetaKmsPlane *plane, +-- +2.36.1 + diff --git a/SOURCES/0001-kms-crtc-Add-function-meta_kms_crtc_has_gamma.patch b/SOURCES/0001-kms-crtc-Add-function-meta_kms_crtc_has_gamma.patch new file mode 100644 index 0000000..5774e45 --- /dev/null +++ b/SOURCES/0001-kms-crtc-Add-function-meta_kms_crtc_has_gamma.patch @@ -0,0 +1,46 @@ +From de3188fcc6863b8a6e3d2443a00cf3b00f6f26ff Mon Sep 17 00:00:00 2001 +From: Daniel van Vugt +Date: Tue, 12 Apr 2022 18:34:58 +0800 +Subject: [PATCH 1/2] kms/crtc: Add function meta_kms_crtc_has_gamma + +Part-of: +--- + src/backends/native/meta-kms-crtc.c | 7 +++++++ + src/backends/native/meta-kms-crtc.h | 3 +++ + 2 files changed, 10 insertions(+) + +diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c +index 51d040b44..24f5a2d74 100644 +--- a/src/backends/native/meta-kms-crtc.c ++++ b/src/backends/native/meta-kms-crtc.c +@@ -92,6 +92,13 @@ meta_kms_crtc_is_active (MetaKmsCrtc *crtc) + return crtc->current_state.is_active; + } + ++ ++gboolean ++meta_kms_crtc_has_gamma (MetaKmsCrtc *crtc) ++{ ++ return !!meta_kms_crtc_get_prop_id (crtc, META_KMS_CRTC_PROP_GAMMA_LUT); ++} ++ + static void + read_gamma_state (MetaKmsCrtc *crtc, + MetaKmsImplDevice *impl_device, +diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h +index 406ca3ac1..cbaeaa280 100644 +--- a/src/backends/native/meta-kms-crtc.h ++++ b/src/backends/native/meta-kms-crtc.h +@@ -66,6 +66,9 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc); + + int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc); + ++ ++gboolean meta_kms_crtc_has_gamma (MetaKmsCrtc *crtc); ++ + gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc); + + void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma); +-- +2.35.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-monitor-manager-Add-NightLightSupported-property-to-.patch b/SOURCES/0001-monitor-manager-Add-NightLightSupported-property-to-.patch new file mode 100644 index 0000000..9c8ec52 --- /dev/null +++ b/SOURCES/0001-monitor-manager-Add-NightLightSupported-property-to-.patch @@ -0,0 +1,218 @@ +From f21c8614daeb70a021c128b97c000a92652cf6f8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Thu, 24 Feb 2022 12:32:27 +0100 +Subject: [PATCH] monitor-manager: Add NightLightSupported property to + DisplayConfig + +This checks whether it's possible to set a CRTC GAMMA_LUT, which is what +is necessary to implement night light. +--- + src/backends/meta-monitor-manager.c | 76 ++++++++++++++++--- + .../native/meta-monitor-manager-native.c | 25 ++++-- + .../x11/meta-monitor-manager-xrandr.c | 9 ++- + src/org.gnome.Mutter.DisplayConfig.xml | 7 ++ + 4 files changed, 99 insertions(+), 18 deletions(-) + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index 75146950c3..0f30b3de25 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -952,6 +952,59 @@ update_panel_orientation_managed (MetaMonitorManager *manager) + handle_orientation_change (orientation_manager, manager); + } + ++static void ++meta_monitor_manager_get_crtc_gamma (MetaMonitorManager *manager, ++ MetaCrtc *crtc, ++ size_t *size, ++ unsigned short **red, ++ unsigned short **green, ++ unsigned short **blue) ++{ ++ MetaMonitorManagerClass *klass = META_MONITOR_MANAGER_GET_CLASS (manager); ++ ++ if (klass->get_crtc_gamma) ++ { ++ klass->get_crtc_gamma (manager, crtc, size, red, green, blue); ++ } ++ else ++ { ++ if (size) ++ *size = 0; ++ if (red) ++ *red = NULL; ++ if (green) ++ *green = NULL; ++ if (blue) ++ *blue = NULL; ++ } ++} ++ ++static gboolean ++is_night_light_supported (MetaMonitorManager *manager) ++{ ++ GList *l; ++ ++ for (l = meta_backend_get_gpus (manager->backend); l; l = l->next) ++ { ++ MetaGpu *gpu = l->data; ++ GList *l_crtc; ++ ++ for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next) ++ { ++ MetaCrtc *crtc = l_crtc->data; ++ size_t gamma_lut_size; ++ ++ meta_monitor_manager_get_crtc_gamma (manager, crtc, ++ &gamma_lut_size, ++ NULL, NULL, NULL); ++ if (gamma_lut_size > 0) ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ + void + meta_monitor_manager_setup (MetaMonitorManager *manager) + { +@@ -967,7 +1020,6 @@ meta_monitor_manager_setup (MetaMonitorManager *manager) + meta_dbus_display_config_set_apply_monitors_config_allowed (manager->display_config, + policy->enable_dbus); + +- + meta_monitor_manager_read_current_state (manager); + + meta_monitor_manager_ensure_initial_config (manager); +@@ -2445,7 +2497,6 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton, + guint crtc_id, + MetaMonitorManager *manager) + { +- MetaMonitorManagerClass *klass; + GList *combined_crtcs; + MetaCrtc *crtc; + gsize size; +@@ -2476,14 +2527,8 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton, + crtc = g_list_nth_data (combined_crtcs, crtc_id); + g_list_free (combined_crtcs); + +- klass = META_MONITOR_MANAGER_GET_CLASS (manager); +- if (klass->get_crtc_gamma) +- klass->get_crtc_gamma (manager, crtc, &size, &red, &green, &blue); +- else +- { +- size = 0; +- red = green = blue = NULL; +- } ++ meta_monitor_manager_get_crtc_gamma (manager, crtc, ++ &size, &red, &green, &blue); + + red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short)); + green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short)); +@@ -3078,6 +3123,16 @@ meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager, + return manager_class->is_transform_handled (manager, crtc, transform); + } + ++static void ++update_night_light_supported (MetaMonitorManager *manager) ++{ ++ gboolean night_light_supported; ++ ++ night_light_supported = is_night_light_supported (manager); ++ meta_dbus_display_config_set_night_light_supported (manager->display_config, ++ night_light_supported); ++} ++ + static void + meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager) + { +@@ -3098,6 +3153,7 @@ meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager) + } + + rebuild_monitors (manager); ++ update_night_light_supported (manager); + } + + void +diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c +index fd5e7784ff..37a50f1d6f 100644 +--- a/src/backends/native/meta-monitor-manager-native.c ++++ b/src/backends/native/meta-monitor-manager-native.c +@@ -381,15 +381,30 @@ meta_monitor_manager_native_get_crtc_gamma (MetaMonitorManager *manager, + MetaKmsCrtc *kms_crtc; + const MetaKmsCrtcState *crtc_state; + +- g_return_if_fail (META_IS_CRTC_KMS (crtc)); ++ if (!META_IS_CRTC_KMS (crtc)) ++ { ++ if (size) ++ *size = 0; ++ if (red) ++ *red = NULL; ++ if (green) ++ *green = NULL; ++ if (blue) ++ *blue = NULL; ++ return; ++ } + + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + crtc_state = meta_kms_crtc_get_current_state (kms_crtc); + +- *size = crtc_state->gamma.size; +- *red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red); +- *green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green); +- *blue = g_memdup2 (crtc_state->gamma.blue, *size * sizeof **blue); ++ if (size) ++ *size = crtc_state->gamma.size; ++ if (red) ++ *red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red); ++ if (green) ++ *green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green); ++ if (blue) ++ *blue = g_memdup2 (crtc_state->gamma.blue, *size * sizeof **blue); + } + + static char * +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 98eb080b6b..865f4e5800 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -707,9 +707,12 @@ meta_monitor_manager_xrandr_get_crtc_gamma (MetaMonitorManager *manager, + (XID) meta_crtc_get_id (crtc)); + + *size = gamma->size; +- *red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size); +- *green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size); +- *blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size); ++ if (red) ++ *red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size); ++ if (green) ++ *green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size); ++ if (blue) ++ *blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size); + + XRRFreeGamma (gamma); + } +diff --git a/src/org.gnome.Mutter.DisplayConfig.xml b/src/org.gnome.Mutter.DisplayConfig.xml +index c6859c2c09..5f85c5e271 100644 +--- a/src/org.gnome.Mutter.DisplayConfig.xml ++++ b/src/org.gnome.Mutter.DisplayConfig.xml +@@ -297,6 +297,13 @@ + --> + + ++ ++ ++ + + + ++ ++ ++ +