From 6767b0897ef77f17429955cf05cd984bb12a4e9f Mon Sep 17 00:00:00 2001 From: guibuilder_pel7x64builder0 Date: Tue, 5 Jun 2018 09:51:32 +0200 Subject: [PATCH] mutter package update Signed-off-by: guibuilder_pel7x64builder0 --- ...01-Revert-build-Require-libgudev-232.patch | 46 + ...tor-changes-in-active-tools-settings.patch | 142 +++ ...serve-XI1-XDevice-throughout-Clutter.patch | 127 +++ ...-x11-Support-synaptics-configuration.patch | 342 ++++++ ...om-pressure-curve-is-a-32-bit-proper.patch | 35 + ...001-build-Lower-automake-requirement.patch | 25 + ...ouchpad-device-property-check-for-Sy.patch | 61 + ...utter-stage-don-t-use-deprecated-api.patch | 217 ++++ ...ement-missing-ClutterInputDevice-pad.patch | 481 ++++++++ ...e-sloppy-focus-while-buttons-are-pre.patch | 43 + ...e-aggressive-in-assuming-X11-backend.patch | 132 +++ ...Consider-external-layout-before-defa.patch | 145 +++ ...xrandr-Force-an-update-when-resuming.patch | 259 +++++ ...xrandr-Work-around-spurious-hotplugs.patch | 63 ++ ...ble-GPU-memory-purge-error-extension.patch | 44 + SOURCES/0001-rhel7-Fix-build-for-el7.patch | 898 +++++++++++++++ ...ot-fail-on-stalled-.X11-unix-entries.patch | 37 + ...scale-monitor-framebuffer-by-default.patch | 25 + ...tor-Special-case-shaped-Java-windows.patch | 35 + ...ayland-Handle-resizing-when-headless.patch | 50 + ...8-Add-support-for-quad-buffer-stereo.patch | 1008 +++++++++++++++++ ...for-plain-old-x-device-configuration.patch | 400 +++++++ ...re-gracefully-with-oversized-windows.patch | 85 ++ SOURCES/fix-session-save-crash.patch | 92 ++ SOURCES/mutter-3.26.0-hybrid-gpus.patch | 12 + ...er-saved-multi-monitor-configuration.patch | 160 +++ SOURCES/startup-notification.patch | 45 + SPECS/mutter.spec | 845 ++++++++++++++ 28 files changed, 5854 insertions(+) create mode 100644 SOURCES/0001-Revert-build-Require-libgudev-232.patch create mode 100644 SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch create mode 100644 SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch create mode 100644 SOURCES/0001-backends-x11-Support-synaptics-configuration.patch create mode 100644 SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch create mode 100644 SOURCES/0001-build-Lower-automake-requirement.patch create mode 100644 SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch create mode 100644 SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch create mode 100644 SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch create mode 100644 SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch create mode 100644 SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch create mode 100644 SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch create mode 100644 SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch create mode 100644 SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch create mode 100644 SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch create mode 100644 SOURCES/0001-rhel7-Fix-build-for-el7.patch create mode 100644 SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch create mode 100644 SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch create mode 100644 SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch create mode 100644 SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch create mode 100644 SOURCES/0008-Add-support-for-quad-buffer-stereo.patch create mode 100644 SOURCES/add-support-for-plain-old-x-device-configuration.patch create mode 100644 SOURCES/deal-more-gracefully-with-oversized-windows.patch create mode 100644 SOURCES/fix-session-save-crash.patch create mode 100644 SOURCES/mutter-3.26.0-hybrid-gpus.patch create mode 100644 SOURCES/remember-saved-multi-monitor-configuration.patch create mode 100644 SOURCES/startup-notification.patch create mode 100644 SPECS/mutter.spec diff --git a/SOURCES/0001-Revert-build-Require-libgudev-232.patch b/SOURCES/0001-Revert-build-Require-libgudev-232.patch new file mode 100644 index 0000000..ec6bf21 --- /dev/null +++ b/SOURCES/0001-Revert-build-Require-libgudev-232.patch @@ -0,0 +1,46 @@ +From 23f4b91105c4fa9fa2231d2e1049728a6383cd65 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Fri, 15 Sep 2017 09:39:18 +0200 +Subject: [PATCH] Revert "build: Require libgudev >= 232" + +This reverts commit 361bf847af82c7dca097302fe64c575079280c9c. +--- + configure.ac | 4 ++-- + src/backends/native/meta-launcher.c | 4 ++++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 805707933..813ca008a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -225,10 +225,10 @@ AC_MSG_CHECKING([gudev]) + if test x$with_gudev = xno ; then + AC_MSG_RESULT([disabled]) + else +- if $PKG_CONFIG --exists "gudev-1.0 >= 232"; then ++ if $PKG_CONFIG --exists gudev-1.0; then + have_gudev=yes + AC_MSG_RESULT(yes) +- MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0 >= 232" ++ MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0" + AC_DEFINE([HAVE_LIBGUDEV], 1, [Building with gudev for device type detection]) + else + AC_MSG_RESULT(no) +diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c +index eb35f88be..90b4b98ba 100644 +--- a/src/backends/native/meta-launcher.c ++++ b/src/backends/native/meta-launcher.c +@@ -49,6 +49,10 @@ + + #define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor" + ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref) ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevEnumerator, g_object_unref) ++ + struct _MetaLauncher + { + Login1Session *session_proxy; +-- +2.13.5 + diff --git a/SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch b/SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch new file mode 100644 index 0000000..444e6ff --- /dev/null +++ b/SOURCES/0001-backends-Monitor-changes-in-active-tools-settings.patch @@ -0,0 +1,142 @@ +From 62f0fb12b1fa946779f0efa406159a355811fdc5 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Mon, 19 Feb 2018 16:50:52 +0100 +Subject: [PATCH] backends: Monitor changes in active tools' settings + +So the changes can be instantly applied while the tool is in proximity. +Before we would just do it on proximity-in, which doesn't provide a +good look&feel while modifying the tool settings in g-c-c. + +https://gitlab.gnome.org/GNOME/mutter/issues/38 + +Closes: #38 +--- + src/backends/meta-input-settings.c | 71 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 68 insertions(+), 3 deletions(-) + +diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c +index 0658755..ec0fc9f 100644 +--- a/src/backends/meta-input-settings.c ++++ b/src/backends/meta-input-settings.c +@@ -41,6 +41,16 @@ static GQuark quark_tool_settings = 0; + + typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate; + typedef struct _DeviceMappingInfo DeviceMappingInfo; ++typedef struct _CurrentToolInfo CurrentToolInfo; ++ ++struct _CurrentToolInfo ++{ ++ MetaInputSettings *input_settings; ++ ClutterInputDevice *device; ++ ClutterInputDeviceTool *tool; ++ GSettings *settings; ++ guint changed_id; ++}; + + struct _DeviceMappingInfo + { +@@ -68,6 +78,8 @@ struct _MetaInputSettingsPrivate + + GHashTable *mappable_devices; + ++ GHashTable *current_tools; ++ + ClutterVirtualInputDevice *virtual_pad_keyboard; + + #ifdef HAVE_LIBWACOM +@@ -144,6 +156,7 @@ meta_input_settings_dispose (GObject *object) + g_clear_object (&priv->keyboard_settings); + g_clear_object (&priv->gsd_settings); + g_clear_pointer (&priv->mappable_devices, g_hash_table_unref); ++ g_clear_pointer (&priv->current_tools, g_hash_table_unref); + + if (priv->monitors_changed_id && priv->monitor_manager) + { +@@ -1510,22 +1523,71 @@ meta_input_settings_device_removed (ClutterDeviceManager *device_manager, + + priv = meta_input_settings_get_instance_private (input_settings); + g_hash_table_remove (priv->mappable_devices, device); ++ g_hash_table_remove (priv->current_tools, device); + + if (g_hash_table_remove (priv->two_finger_devices, device) && + g_hash_table_size (priv->two_finger_devices) == 0) + apply_device_settings (input_settings, NULL); + } + ++static void ++current_tool_changed_cb (GSettings *settings, ++ const char *key, ++ gpointer user_data) ++{ ++ CurrentToolInfo *info = user_data; ++ ++ apply_stylus_settings (info->input_settings, info->device, info->tool); ++} ++ ++static CurrentToolInfo * ++current_tool_info_new (MetaInputSettings *input_settings, ++ ClutterInputDevice *device, ++ ClutterInputDeviceTool *tool) ++{ ++ CurrentToolInfo *info; ++ ++ info = g_new0 (CurrentToolInfo, 1); ++ info->input_settings = input_settings; ++ info->device = device; ++ info->tool = tool; ++ info->settings = lookup_tool_settings (tool, device); ++ info->changed_id = ++ g_signal_connect (info->settings, "changed", ++ G_CALLBACK (current_tool_changed_cb), ++ info); ++ return info; ++} ++ ++static void ++current_tool_info_free (CurrentToolInfo *info) ++{ ++ g_signal_handler_disconnect (info->settings, info->changed_id); ++ g_free (info); ++} ++ + static void + meta_input_settings_tool_changed (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + MetaInputSettings *input_settings) + { +- if (!tool) +- return; ++ MetaInputSettingsPrivate *priv; + +- apply_stylus_settings (input_settings, device, tool); ++ priv = meta_input_settings_get_instance_private (input_settings); ++ ++ if (tool) ++ { ++ CurrentToolInfo *current_tool; ++ ++ current_tool = current_tool_info_new (input_settings, device, tool); ++ g_hash_table_insert (priv->current_tools, device, current_tool); ++ apply_stylus_settings (input_settings, device, tool); ++ } ++ else ++ { ++ g_hash_table_remove (priv->current_tools, device); ++ } + } + + static void +@@ -1616,6 +1678,9 @@ meta_input_settings_init (MetaInputSettings *settings) + priv->mappable_devices = + g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) device_mapping_info_free); + ++ priv->current_tools = ++ g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free); ++ + priv->monitor_manager = g_object_ref (meta_monitor_manager_get ()); + g_signal_connect (priv->monitor_manager, "monitors-changed-internal", + G_CALLBACK (monitors_changed_cb), settings); +-- +2.16.1 + diff --git a/SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch b/SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch new file mode 100644 index 0000000..0a1fc86 --- /dev/null +++ b/SOURCES/0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch @@ -0,0 +1,127 @@ +From bc17d94ef058564c1a1adf28a8696164455fea1b Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 30 Jan 2018 13:07:32 +0100 +Subject: [PATCH] backends/x11: Preserve XI1 XDevice throughout + ClutterInputDevice lifetime + +Opening and closing the device may result into XI2 grabs being cut short, +resulting into pad buttons being rendered ineffective, and other possible +misbehaviors. This is an XInput flaw that fell in the gap between XI1 and +XI2, and has no easy fix. It pays us for mixing both versions, I guess... + +Work this around by keeping the XI1 XDevice attached to the +ClutterInputDevice, this way it will live long enough that this is not +a concern. + +Investigation of this bug was mostly carried by Peter Hutterer, I'm just +the executing hand. + +https://gitlab.gnome.org/GNOME/mutter/issues/7 + +Closes: #7 +--- + src/backends/x11/meta-input-settings-x11.c | 48 ++++++++++++++++++++++++++---- + 1 file changed, 42 insertions(+), 6 deletions(-) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index d1ee37a..7a876ef 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -55,6 +55,46 @@ enum { + SCROLL_METHOD_NUM_FIELDS + }; + ++static void ++device_free_xdevice (gpointer user_data) ++{ ++ MetaDisplay *display = meta_get_display (); ++ MetaBackend *backend = meta_get_backend (); ++ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ XDevice *xdev = user_data; ++ ++ meta_error_trap_push (display); ++ XCloseDevice (xdisplay, xdev); ++ meta_error_trap_pop (display); ++} ++ ++static XDevice * ++device_ensure_xdevice (ClutterInputDevice *device) ++{ ++ MetaDisplay *display = meta_get_display (); ++ MetaBackend *backend = meta_get_backend (); ++ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ int device_id = clutter_input_device_get_device_id (device); ++ XDevice *xdev = NULL; ++ ++ xdev = g_object_get_data (G_OBJECT (device), "meta-input-settings-xdevice"); ++ if (xdev) ++ return xdev; ++ ++ meta_error_trap_push (display); ++ xdev = XOpenDevice (xdisplay, device_id); ++ meta_error_trap_pop (display); ++ ++ if (xdev) ++ { ++ g_object_set_data_full (G_OBJECT (device), ++ "meta-input-settings-xdevice", ++ xdev, (GDestroyNotify) device_free_xdevice); ++ } ++ ++ return xdev; ++} ++ + static void * + get_property (ClutterInputDevice *device, + const gchar *property, +@@ -540,7 +580,6 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings, + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); +- int device_id = clutter_input_device_get_device_id (device); + XDevice *xdev; + + if (!display) +@@ -548,13 +587,12 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings, + + /* Grab the puke bucket! */ + meta_error_trap_push (display); +- xdev = XOpenDevice (xdisplay, device_id); ++ xdev = device_ensure_xdevice (device); + if (xdev) + { + XSetDeviceMode (xdisplay, xdev, + mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE ? + Absolute : Relative); +- XCloseDevice (xdisplay, xdev); + } + + if (meta_error_trap_pop_with_return (display)) +@@ -737,7 +775,6 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *setti + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); +- int device_id = clutter_input_device_get_device_id (device); + XDevice *xdev; + + if (!display) +@@ -745,7 +782,7 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *setti + + /* Grab the puke bucket! */ + meta_error_trap_push (display); +- xdev = XOpenDevice (xdisplay, device_id); ++ xdev = device_ensure_xdevice (device); + if (xdev) + { + guchar map[3] = { +@@ -755,7 +792,6 @@ meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *setti + }; + + XSetDeviceButtonMapping (xdisplay, xdev, map, G_N_ELEMENTS (map)); +- XCloseDevice (xdisplay, xdev); + } + + if (meta_error_trap_pop_with_return (display)) +-- +1.8.3.1 + diff --git a/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch b/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch new file mode 100644 index 0000000..b6f21e1 --- /dev/null +++ b/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch @@ -0,0 +1,342 @@ +From 647de5a802627809486fe760c657b05297470683 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 19 Jan 2017 15:03:41 +0100 +Subject: [PATCH] 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 | 261 +++++++++++++++++++++++++++++ + 1 file changed, 261 insertions(+) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 7a876ef..467a9b7 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -26,6 +26,7 @@ + #include "meta-backend-x11.h" + #include "meta-input-settings-x11.h" + ++#include + #include + #include + #include +@@ -159,6 +160,173 @@ 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 (); ++ MetaBackend *backend = meta_get_backend (); ++ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ XDevice *xdevice; ++ guchar *tap_action, *buttons; ++ guint buttons_capacity = 16, n_buttons; ++ ++ xdevice = device_ensure_xdevice (device); ++ if (!xdevice) ++ return; ++ ++ 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); ++ ++ if (display) ++ meta_error_trap_push (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); ++ ++ if (display && meta_error_trap_pop_with_return (display)) ++ { ++ g_warning ("Could not set synaptics touchpad left-handed for %s", ++ clutter_input_device_get_device_name (device)); ++ } ++} ++ ++static void ++change_synaptics_speed (ClutterInputDevice *device, ++ gdouble speed) ++{ ++ MetaDisplay *display = meta_get_display (); ++ MetaBackend *backend = meta_get_backend (); ++ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); ++ XDevice *xdevice; ++ XPtrFeedbackControl feedback; ++ XFeedbackState *states, *state; ++ int i, num_feedbacks, motion_threshold, numerator, denominator; ++ gfloat motion_acceleration; ++ ++ xdevice = device_ensure_xdevice (device); ++ 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 (display) ++ meta_error_trap_push (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 (display && meta_error_trap_pop_with_return (display)) ++ { ++ g_warning ("Could not set synaptics touchpad acceleration for %s", ++ clutter_input_device_get_device_name (device)); ++ } ++ ++ XFreeFeedbackList (states); ++} ++ + static void + meta_input_settings_x11_set_send_events (MetaInputSettings *settings, + ClutterInputDevice *device, +@@ -167,6 +335,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) +@@ -219,6 +394,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); +@@ -245,6 +426,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); + } +@@ -268,6 +462,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); + } +@@ -290,6 +498,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); + } +@@ -303,6 +532,22 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings, + guchar *current = NULL; + guchar *available = NULL; + ++ if (is_device_synaptics (device)) ++ { ++ current = get_property (device, "Synaptics Edge Scrolling", ++ XA_INTEGER, 8, 3); ++ if (current) ++ { ++ current[0] = !!edge_scroll_enabled; ++ current[1] = !!edge_scroll_enabled; ++ change_property (device, "Synaptics Edge Scrolling", ++ XA_INTEGER, 8, current, 3); ++ meta_XFree (current); ++ } ++ ++ return; ++ } ++ + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_EDGE]) +@@ -332,6 +577,22 @@ meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *set + guchar *current = NULL; + guchar *available = NULL; + ++ if (is_device_synaptics (device)) ++ { ++ current = get_property (device, "Synaptics Two-Finger Scrolling", ++ XA_INTEGER, 8, 2); ++ if (current) ++ { ++ current[0] = !!two_finger_scroll_enabled; ++ current[1] = !!two_finger_scroll_enabled; ++ change_property (device, "Synaptics Two-Finger Scrolling", ++ XA_INTEGER, 8, current, 2); ++ meta_XFree (current); ++ } ++ ++ return; ++ } ++ + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_2FG]) +-- +1.8.3.1 + diff --git a/SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch b/SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch new file mode 100644 index 0000000..f13f593 --- /dev/null +++ b/SOURCES/0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch @@ -0,0 +1,35 @@ +From ac502c921d2e813e6e916a589a07bc58ca4c12e7 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Fri, 9 Feb 2018 11:53:17 +1000 +Subject: [PATCH] backends/x11: wacom pressure curve is a 32-bit property + +The property has been 32 bits since around 2011 and has not changed, mutter +expects it to be 8 bits. The mismatch causes change_property to never +actually change the property. + +https://gitlab.gnome.org/GNOME/mutter/issues/26 + +Closes: #26 +--- + src/backends/x11/meta-input-settings-x11.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 7d1d360a3..9687fb36f 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -813,9 +813,9 @@ meta_input_settings_x11_set_stylus_pressure (MetaInputSettings *settings, + ClutterInputDeviceTool *tool, + const gint32 pressure[4]) + { +- guchar values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] }; ++ guint32 values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] }; + +- change_property (device, "Wacom Pressurecurve", XA_INTEGER, 8, ++ change_property (device, "Wacom Pressurecurve", XA_INTEGER, 32, + &values, G_N_ELEMENTS (values)); + } + +-- +2.16.1 + diff --git a/SOURCES/0001-build-Lower-automake-requirement.patch b/SOURCES/0001-build-Lower-automake-requirement.patch new file mode 100644 index 0000000..f7c7af6 --- /dev/null +++ b/SOURCES/0001-build-Lower-automake-requirement.patch @@ -0,0 +1,25 @@ +From e19b0723e829a102f930af735c9ff6d08ec9232f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 17 Mar 2017 16:44:11 +0100 +Subject: [PATCH] build: Lower automake requirement + +--- + cogl/configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cogl/configure.ac b/cogl/configure.ac +index 3ed761c57..1b259af58 100644 +--- a/cogl/configure.ac ++++ b/cogl/configure.ac +@@ -113,7 +113,7 @@ AC_SUBST([WAYLAND_SERVER_REQ_VERSION], [wayland_server_req_version]) + # want to know if the user specified custom cflags or not. + cflags_set=${CFLAGS+set} + +-AM_INIT_AUTOMAKE([1.14 foreign -Wno-portability no-define no-dist-gzip dist-xz tar-ustar subdir-objects]) ++AM_INIT_AUTOMAKE([1.11 foreign -Wno-portability no-define no-dist-gzip dist-xz tar-ustar]) + AM_SILENT_RULES([yes]) + + AH_BOTTOM([#include "config-custom.h"]) +-- +2.12.0 + diff --git a/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch b/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch new file mode 100644 index 0000000..3ae0f20 --- /dev/null +++ b/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch @@ -0,0 +1,61 @@ +From 424e37231a0930594d4363477e7515e006b3dac1 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 13 Feb 2018 11:44:40 +0100 +Subject: [PATCH] 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. +--- + clutter/clutter/x11/clutter-device-manager-xi2.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c +index d2610cc..fcba55c 100644 +--- a/clutter/clutter/x11/clutter-device-manager-xi2.c ++++ b/clutter/clutter/x11/clutter-device-manager-xi2.c +@@ -267,8 +267,9 @@ is_touch_device (XIAnyClassInfo **classes, + } + + static gboolean +-is_touchpad_device (ClutterBackendX11 *backend_x11, +- XIDeviceInfo *info) ++query_exists_device_property (ClutterBackendX11 *backend_x11, ++ XIDeviceInfo *info, ++ const gchar *property) + { + gulong nitems, bytes_after; + guint32 *data = NULL; +@@ -276,7 +277,7 @@ is_touchpad_device (ClutterBackendX11 *backend_x11, + Atom type; + Atom prop; + +- prop = XInternAtom (backend_x11->xdpy, "libinput Tapping Enabled", True); ++ prop = XInternAtom (backend_x11->xdpy, property, True); + if (prop == None) + return FALSE; + +@@ -298,6 +299,21 @@ is_touchpad_device (ClutterBackendX11 *backend_x11, + } + + static gboolean ++is_touchpad_device (ClutterBackendX11 *backend_x11, ++ XIDeviceInfo *info) ++{ ++ if (query_exists_device_property (backend_x11, info, ++ "libinput Tapping Enabled")) ++ return TRUE; ++ ++ if (query_exists_device_property (backend_x11, info, ++ "Synaptics Off")) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static gboolean + get_device_ids (ClutterBackendX11 *backend_x11, + XIDeviceInfo *info, + gchar **vendor_id, +-- +1.8.3.1 + diff --git a/SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch b/SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch new file mode 100644 index 0000000..d3b0103 --- /dev/null +++ b/SOURCES/0001-clutter-stage-don-t-use-deprecated-api.patch @@ -0,0 +1,217 @@ +From e69a6ac0e44e8d5fd72d7bc60f118044b0407e8f Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 9 Nov 2017 16:18:02 -0500 +Subject: [PATCH] 0001-clutter-stage-don-t-use-deprecated-api.patch + +--- + clutter/clutter/clutter-stage.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c +index 02ab07b..e4f9342 100644 +--- a/clutter/clutter/clutter-stage.c ++++ b/clutter/clutter/clutter-stage.c +@@ -1459,64 +1459,65 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage, + fb_height = view_layout.height * fb_scale; + cogl_push_framebuffer (fb); + + /* needed for when a context switch happens */ + _clutter_stage_maybe_setup_viewport (stage, view); + + /* FIXME: For some reason leaving the cogl clip stack empty causes the + * picking to not work at all, so setting it the whole framebuffer content + * for now. */ + cogl_framebuffer_push_scissor_clip (fb, 0, 0, + view_layout.width * fb_scale, + view_layout.height * fb_scale); + + _clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y); + + if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))) + { + CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1", + (int) dirty_x * fb_scale, + (int) dirty_y * fb_scale); + cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1); + } + + viewport_offset_x = x * fb_scale - dirty_x * fb_scale; + viewport_offset_y = y * fb_scale - dirty_y * fb_scale; + CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f", + priv->viewport[0] * fb_scale - viewport_offset_x, + priv->viewport[1] * fb_scale - viewport_offset_y, + priv->viewport[2] * fb_scale, + priv->viewport[3] * fb_scale); +- cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x, +- priv->viewport[1] * fb_scale - viewport_offset_y, +- priv->viewport[2] * fb_scale, +- priv->viewport[3] * fb_scale); ++ cogl_framebuffer_set_viewport (fb, ++ priv->viewport[0] * fb_scale - viewport_offset_x, ++ priv->viewport[1] * fb_scale - viewport_offset_y, ++ priv->viewport[2] * fb_scale, ++ priv->viewport[3] * fb_scale); + + read_x = dirty_x * fb_scale; + read_y = dirty_y * fb_scale; + + CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d", + x, y, + view_layout.width, view_layout.height, + view_layout.x, view_layout.y, fb_scale); + + cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255); + cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH); + + /* Disable dithering (if any) when doing the painting in pick mode */ + dither_enabled_save = cogl_framebuffer_get_dither_enabled (fb); + cogl_framebuffer_set_dither_enabled (fb, FALSE); + + /* Render the entire scence in pick mode - just single colored silhouette's + * are drawn offscreen (as we never swap buffers) + */ + context->pick_mode = mode; + _clutter_stage_paint_view (stage, view, NULL); + context->pick_mode = CLUTTER_PICK_NONE; + + /* Read the color of the screen co-ords pixel. RGBA_8888_PRE is used + even though we don't care about the alpha component because under + GLES this is the only format that is guaranteed to work so Cogl + will end up having to do a conversion if any other format is + used. The format is requested as pre-multiplied because Cogl + assumes that all pixels in the framebuffer are premultiplied so + it avoids a conversion. */ +@@ -3590,123 +3591,125 @@ calculate_z_translation (float z_near) + * z_2d = --------------------------- + z_near + * sin (0.5°) + */ + + /* We expect the compiler should boil this down to z_near * CONSTANT + * already, but just in case we use precomputed constants + */ + #if 0 + # define A tanf (_DEG_TO_RAD (30.f)) + # define B sinf (_DEG_TO_RAD (120.f)) + # define C cosf (_DEG_TO_RAD (30.5f)) + # define D sinf (_DEG_TO_RAD (.5f)) + #else + # define A 0.57735025882720947265625f + # define B 0.866025388240814208984375f + # define C 0.86162912845611572265625f + # define D 0.00872653536498546600341796875f + #endif + + return z_near + * A * B * C + / D + + z_near; + } + + void + _clutter_stage_maybe_setup_viewport (ClutterStage *stage, + ClutterStageView *view) + { + ClutterStagePrivate *priv = stage->priv; ++ CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view); + + if (clutter_stage_view_is_dirty_viewport (view)) + { + cairo_rectangle_int_t view_layout; + ClutterPerspective perspective; + float fb_scale; + float viewport_offset_x; + float viewport_offset_y; + float z_2d; + + CLUTTER_NOTE (PAINT, + "Setting up the viewport { w:%f, h:%f }", + priv->viewport[2], + priv->viewport[3]); + + fb_scale = clutter_stage_view_get_scale (view); + clutter_stage_view_get_layout (view, &view_layout); + + viewport_offset_x = view_layout.x * fb_scale; + viewport_offset_y = view_layout.y * fb_scale; +- cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x, +- priv->viewport[1] * fb_scale - viewport_offset_y, +- priv->viewport[2] * fb_scale, +- priv->viewport[3] * fb_scale); ++ cogl_framebuffer_set_viewport (fb, ++ priv->viewport[0] * fb_scale - viewport_offset_x, ++ priv->viewport[1] * fb_scale - viewport_offset_y, ++ priv->viewport[2] * fb_scale, ++ priv->viewport[3] * fb_scale); + + perspective = priv->perspective; + + /* Ideally we want to regenerate the perspective matrix whenever + * the size changes but if the user has provided a custom matrix + * then we don't want to override it */ + if (!priv->has_custom_perspective) + { + perspective.aspect = priv->viewport[2] / priv->viewport[3]; + z_2d = calculate_z_translation (perspective.z_near); + + /* NB: z_2d is only enough room for 85% of the stage_height between + * the stage and the z_near plane. For behind the stage plane we + * want a more consistent gap of 10 times the stage_height before + * hitting the far plane so we calculate that relative to the final + * height of the stage plane at the z_2d_distance we got... */ + perspective.z_far = z_2d + + tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f; + + clutter_stage_set_perspective_internal (stage, &perspective); + } + else + z_2d = calculate_z_translation (perspective.z_near); + + cogl_matrix_init_identity (&priv->view); + cogl_matrix_view_2d_in_perspective (&priv->view, + perspective.fovy, + perspective.aspect, + perspective.z_near, + z_2d, + priv->viewport[2], + priv->viewport[3]); + + clutter_stage_view_set_dirty_viewport (view, FALSE); + } + + if (clutter_stage_view_is_dirty_projection (view)) + { +- cogl_set_projection_matrix (&priv->projection); ++ cogl_framebuffer_set_projection_matrix (fb, &priv->projection); + + clutter_stage_view_set_dirty_projection (view, FALSE); + } + } + + #undef _DEG_TO_RAD + + /** + * clutter_stage_ensure_redraw: + * @stage: a #ClutterStage + * + * Ensures that @stage is redrawn + * + * This function should not be called by applications: it is + * used when embedding a #ClutterStage into a toolkit with + * another windowing system, like GTK+. + * + * Since: 1.0 + */ + void + clutter_stage_ensure_redraw (ClutterStage *stage) + { + ClutterMasterClock *master_clock; + ClutterStagePrivate *priv; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + + priv = stage->priv; + + if (!priv->relayout_pending && !priv->redraw_pending) +-- +2.14.3 + diff --git a/SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch b/SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch new file mode 100644 index 0000000..69ca7a4 --- /dev/null +++ b/SOURCES/0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch @@ -0,0 +1,481 @@ +From 1d745a858470b29b44e5b0e308488a477c4526cb Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 22 Feb 2018 17:48:17 +0100 +Subject: [PATCH 1/2] clutter/x11: Implement missing ClutterInputDevice pad + vmethods + +Use libwacom to be able to find out modes, groups and button roles on +pad devices. + +https://gitlab.gnome.org/GNOME/mutter/issues/48 + +Closes: #48 +--- + clutter/clutter/x11/clutter-device-manager-xi2.c | 11 +++ + clutter/clutter/x11/clutter-device-manager-xi2.h | 8 ++ + clutter/clutter/x11/clutter-input-device-xi2.c | 97 ++++++++++++++++++++++++ + clutter/clutter/x11/clutter-input-device-xi2.h | 10 +++ + clutter/configure.ac | 32 +++++++- + 5 files changed, 156 insertions(+), 2 deletions(-) + +diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c +index d2610cc..dee2604 100644 +--- a/clutter/clutter/x11/clutter-device-manager-xi2.c ++++ b/clutter/clutter/x11/clutter-device-manager-xi2.c +@@ -495,11 +495,18 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, + "device-node", node_path, + "n-rings", num_rings, + "n-strips", num_strips, ++ "n-mode-groups", MAX (num_rings, num_strips), + NULL); + + translate_device_classes (backend_x11->xdpy, retval, + info->classes, + info->num_classes); ++ ++#ifdef HAVE_LIBWACOM ++ if (source == CLUTTER_PAD_DEVICE) ++ clutter_input_device_xi2_ensure_wacom_info (retval, manager_xi2->wacom_db); ++#endif ++ + g_free (vendor_id); + g_free (product_id); + +@@ -2063,4 +2070,8 @@ clutter_device_manager_xi2_init (ClutterDeviceManagerXI2 *self) + (GDestroyNotify) g_object_unref); + self->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) g_object_unref); ++ ++#ifdef HAVE_LIBWACOM ++ self->wacom_db = libwacom_database_new (); ++#endif + } +diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.h b/clutter/clutter/x11/clutter-device-manager-xi2.h +index c8e66f9..be25759 100644 +--- a/clutter/clutter/x11/clutter-device-manager-xi2.h ++++ b/clutter/clutter/x11/clutter-device-manager-xi2.h +@@ -26,6 +26,10 @@ + + #include + ++#ifdef HAVE_LIBWACOM ++#include ++#endif ++ + G_BEGIN_DECLS + + #define CLUTTER_TYPE_DEVICE_MANAGER_XI2 (_clutter_device_manager_xi2_get_type ()) +@@ -51,6 +55,10 @@ struct _ClutterDeviceManagerXI2 + GList *slave_devices; + + int opcode; ++ ++#ifdef HAVE_LIBWACOM ++ WacomDeviceDatabase *wacom_db; ++#endif + }; + + struct _ClutterDeviceManagerXI2Class +diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c +index 7fb0e05..2d9b6d2 100644 +--- a/clutter/clutter/x11/clutter-input-device-xi2.c ++++ b/clutter/clutter/x11/clutter-input-device-xi2.c +@@ -45,6 +45,10 @@ struct _ClutterInputDeviceXI2 + + gint device_id; + ClutterInputDeviceTool *current_tool; ++ ++#ifdef HAVE_LIBWACOM ++ WacomDevice *wacom_device; ++#endif + }; + + #define N_BUTTONS 5 +@@ -88,15 +92,94 @@ clutter_input_device_xi2_is_grouped (ClutterInputDevice *device, + } + + static void ++clutter_input_device_xi2_finalize (GObject *object) ++{ ++#ifdef HAVE_LIBWACOM ++ ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (object); ++ ++ if (device_xi2->wacom_device) ++ libwacom_destroy (device_xi2->wacom_device); ++#endif ++ ++ G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object); ++} ++ ++static gint ++clutter_input_device_xi2_get_group_n_modes (ClutterInputDevice *device, ++ gint group) ++{ ++#ifdef HAVE_LIBWACOM ++ ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); ++ ++ if (device_xi2->wacom_device) ++ { ++ if (group == 0) ++ { ++ if (libwacom_has_ring (device_xi2->wacom_device)) ++ return libwacom_get_ring_num_modes (device_xi2->wacom_device); ++ else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 1) ++ return libwacom_get_strips_num_modes (device_xi2->wacom_device); ++ } ++ else if (group == 1) ++ { ++ if (libwacom_has_ring2 (device_xi2->wacom_device)) ++ return libwacom_get_ring2_num_modes (device_xi2->wacom_device); ++ else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 2) ++ return libwacom_get_strips_num_modes (device_xi2->wacom_device); ++ } ++ } ++#endif ++ ++ return -1; ++} ++ ++#ifdef HAVE_LIBWACOM ++static int ++clutter_input_device_xi2_get_button_group (ClutterInputDevice *device, ++ guint button) ++{ ++ ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); ++ ++ if (device_xi2->wacom_device) ++ { ++ if (button >= libwacom_get_num_buttons (device_xi2->wacom_device)) ++ return -1; ++ ++ return libwacom_get_button_led_group (device_xi2->wacom_device, ++ 'A' + button); ++ } ++ else ++ return -1; ++} ++#endif ++ ++static gboolean ++clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device, ++ guint group, ++ guint button) ++{ ++ int button_group = -1; ++ ++#ifdef HAVE_LIBWACOM ++ button_group = clutter_input_device_xi2_get_button_group (device, button); ++#endif ++ ++ return button_group == (int) group; ++} ++ ++static void + clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass) + { + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass); + + gobject_class->constructed = clutter_input_device_xi2_constructed; ++ gobject_class->finalize = clutter_input_device_xi2_finalize; + + device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev; + device_class->is_grouped = clutter_input_device_xi2_is_grouped; ++ device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes; ++ device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button; + } + + static void +@@ -196,3 +279,17 @@ clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device) + ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); + return device_xi2->current_tool; + } ++ ++#ifdef HAVE_LIBWACOM ++void ++clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device, ++ WacomDeviceDatabase *wacom_db) ++{ ++ ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); ++ const gchar *node_path; ++ ++ node_path = clutter_input_device_get_device_node (device); ++ device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path, ++ WFALLBACK_NONE, NULL); ++} ++#endif +diff --git a/clutter/clutter/x11/clutter-input-device-xi2.h b/clutter/clutter/x11/clutter-input-device-xi2.h +index b93684f..e30fb4d 100644 +--- a/clutter/clutter/x11/clutter-input-device-xi2.h ++++ b/clutter/clutter/x11/clutter-input-device-xi2.h +@@ -27,6 +27,10 @@ + #include + #include + ++#ifdef HAVE_LIBWACOM ++#include ++#endif ++ + G_BEGIN_DECLS + + #define CLUTTER_TYPE_INPUT_DEVICE_XI2 (_clutter_input_device_xi2_get_type ()) +@@ -45,6 +49,12 @@ void clutter_input_device_xi2_update_tool (ClutterInputDevice *device, + ClutterInputDeviceTool *tool); + ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device); + ++#ifdef HAVE_LIBWACOM ++void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device, ++ WacomDeviceDatabase *wacom_db); ++ ++#endif ++ + G_END_DECLS + + #endif /* __CLUTTER_INPUT_DEVICE_XI2_H__ */ +diff --git a/clutter/configure.ac b/clutter/configure.ac +index 3c3d0c5..5474fa0 100644 +--- a/clutter/configure.ac ++++ b/clutter/configure.ac +@@ -121,6 +121,7 @@ m4_define([xcomposite_req_version], [0.4]) + m4_define([gdk_req_version], [3.3.18]) + m4_define([libinput_req_version], [1.4.0]) + m4_define([libudev_req_version], [136]) ++m4_define([libwacom_req_version], [0.13]) + + AC_SUBST([GLIB_REQ_VERSION], [glib_req_version]) + AC_SUBST([COGL_REQ_VERSION], [cogl_req_version]) +@@ -133,6 +134,7 @@ AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version]) + AC_SUBST([GDK_REQ_VERSION], [gdk_req_version]) + AC_SUBST([LIBINPUT_REQ_VERSION], [libinput_req_version]) + AC_SUBST([LIBUDEV_REQ_VERSION], [libudev_req_version]) ++AC_SUBST([LIBWACOM_REQ_VERSION], [libwacom_req_version]) + + # Checks for typedefs, structures, and compiler characteristics. + AM_PATH_GLIB_2_0([glib_req_version], +@@ -508,6 +510,32 @@ X11_EXTS=${X11_EXTS#* } + + AC_CACHE_SAVE + ++dnl === Libwacom support for X11 =============================================== ++AC_ARG_WITH(libwacom, ++ AC_HELP_STRING([--without-libwacom], ++ [disable the use of libwacom for advanced tablet management]),, ++ with_libwacom=auto) ++ ++have_libwacom=no ++AC_MSG_CHECKING([libwacom]) ++if test x$with_libwacom = xno ; then ++ AC_MSG_RESULT([disabled]) ++else ++ if $PKG_CONFIG --exists libwacom '>=' $LIBWACOM_REQ_VERSION; then ++ have_libwacom=yes ++ AC_MSG_RESULT(yes) ++ PKG_CHECK_MODULES([LIBWACOM], [libwacom]) ++ AC_SUBST(LIBWACOM_CFLAGS) ++ AC_SUBST(LIBWACOM_LIBS) ++ AC_DEFINE([HAVE_LIBWACOM], 1, [Building with libwacom for advanced tablet management]) ++ else ++ AC_MSG_RESULT(no) ++ if test x$with_libwacom = xyes ; then ++ AC_MSG_ERROR([libwacom forced but not found]) ++ fi ++ fi ++fi ++ + dnl === Enable GDK-Pixbuf in tests ============================================ + + m4_define([pixbuf_default], [yes]) +@@ -679,8 +707,8 @@ AS_IF([test "x$CLUTTER_BASE_PC_FILES_PRIVATE" = "x" && test "x$BACKEND_PC_FILES_ + AC_SUBST(CLUTTER_REQUIRES) + AC_SUBST(CLUTTER_REQUIRES_PRIVATE) + +-CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS" +-CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS" ++CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS $LIBWACOM_CFLAGS" ++CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS $LIBWACOM_LIBS" + AC_SUBST(CLUTTER_CFLAGS) + AC_SUBST(CLUTTER_LIBS) + +-- +1.8.3.1 + + +From f8fa4b8fa13fba9ed484be74fb7fc82499d46261 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 22 Feb 2018 17:50:42 +0100 +Subject: [PATCH 2/2] clutter/x11: Communicate proper group/mode on pad events. + +So we can trigger actions for the right mode. + +https://gitlab.gnome.org/GNOME/mutter/issues/48 + +Closes: #48 +--- + clutter/clutter/x11/clutter-device-manager-xi2.c | 15 +++++- + clutter/clutter/x11/clutter-input-device-xi2.c | 61 ++++++++++++++++++++++++ + clutter/clutter/x11/clutter-input-device-xi2.h | 9 ++++ + 3 files changed, 84 insertions(+), 1 deletion(-) + +diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c +index dee2604..d269a38 100644 +--- a/clutter/clutter/x11/clutter-device-manager-xi2.c ++++ b/clutter/clutter/x11/clutter-device-manager-xi2.c +@@ -1133,7 +1133,7 @@ translate_pad_event (ClutterEvent *event, + ClutterInputDevice *device) + { + gdouble value; +- guint number; ++ guint number, mode = 0; + + if (!translate_pad_axis (device, &xev->valuators, + &event->any.type, +@@ -1147,15 +1147,21 @@ translate_pad_event (ClutterEvent *event, + if (xev->evtype == XI_Motion) + value = -1; + ++#ifdef HAVE_LIBWACOM ++ mode = clutter_input_device_xi2_get_pad_group_mode (device, number); ++#endif ++ + if (event->any.type == CLUTTER_PAD_RING) + { + event->pad_ring.ring_number = number; + event->pad_ring.angle = value; ++ event->pad_ring.mode = mode; + } + else + { + event->pad_strip.strip_number = number; + event->pad_strip.value = value; ++ event->pad_strip.mode = mode; + } + + event->any.time = xev->time; +@@ -1382,6 +1388,13 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, + + /* Pad buttons are 0-indexed */ + event->pad_button.button = xev->detail - 1; ++#ifdef HAVE_LIBWACOM ++ clutter_input_device_xi2_update_pad_state (device, ++ event->pad_button.button, ++ (xi_event->evtype == XI_ButtonPress), ++ &event->pad_button.group, ++ &event->pad_button.mode); ++#endif + clutter_event_set_device (event, device); + clutter_event_set_source_device (event, source_device); + +diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c +index 2d9b6d2..f62ba85 100644 +--- a/clutter/clutter/x11/clutter-input-device-xi2.c ++++ b/clutter/clutter/x11/clutter-input-device-xi2.c +@@ -48,6 +48,7 @@ struct _ClutterInputDeviceXI2 + + #ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; ++ GArray *group_modes; + #endif + }; + +@@ -68,6 +69,15 @@ clutter_input_device_xi2_constructed (GObject *gobject) + + if (G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed) + G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed (gobject); ++ ++#ifdef HAVE_LIBWACOM ++ if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (gobject)) == CLUTTER_PAD_DEVICE) ++ { ++ device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (guint)); ++ g_array_set_size (device_xi2->group_modes, ++ clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (gobject))); ++ } ++#endif + } + + static gboolean +@@ -99,6 +109,8 @@ clutter_input_device_xi2_finalize (GObject *object) + + if (device_xi2->wacom_device) + libwacom_destroy (device_xi2->wacom_device); ++ ++ g_array_unref (device_xi2->group_modes); + #endif + + G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object); +@@ -292,4 +304,53 @@ clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device, + device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path, + WFALLBACK_NONE, NULL); + } ++ ++guint ++clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device, ++ guint group) ++{ ++ ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); ++ ++ if (group >= device_xi2->group_modes->len) ++ return 0; ++ ++ return g_array_index (device_xi2->group_modes, guint, group); ++} ++ ++void ++clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, ++ guint button, ++ guint state, ++ guint *group, ++ guint *mode) ++{ ++ ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); ++ guint button_group, *group_mode; ++ gboolean is_mode_switch = FALSE; ++ ++ button_group = clutter_input_device_xi2_get_button_group (device, button); ++ is_mode_switch = button_group >= 0; ++ ++ /* Assign all non-mode-switch buttons to group 0 so far */ ++ button_group = MAX (0, button_group); ++ ++ if (button_group >= device_xi2->group_modes->len) ++ return; ++ ++ group_mode = &g_array_index (device_xi2->group_modes, guint, button_group); ++ ++ if (is_mode_switch && state) ++ { ++ guint next, n_modes; ++ ++ n_modes = clutter_input_device_get_group_n_modes (device, button_group); ++ next = (*group_mode + 1) % n_modes; ++ *group_mode = next; ++ } ++ ++ if (group) ++ *group = button_group; ++ if (mode) ++ *mode = *group_mode; ++} + #endif +diff --git a/clutter/clutter/x11/clutter-input-device-xi2.h b/clutter/clutter/x11/clutter-input-device-xi2.h +index e30fb4d..2194e1b 100644 +--- a/clutter/clutter/x11/clutter-input-device-xi2.h ++++ b/clutter/clutter/x11/clutter-input-device-xi2.h +@@ -53,6 +53,15 @@ ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInput + void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device, + WacomDeviceDatabase *wacom_db); + ++guint clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device, ++ guint group); ++ ++void clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, ++ guint button, ++ guint state, ++ guint *group, ++ guint *mode); ++ + #endif + + G_END_DECLS +-- +1.8.3.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..4eeb33e --- /dev/null +++ b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch @@ -0,0 +1,43 @@ +From 887537360c3c3b0ae5d0ef0222fad4d0a3bc41c9 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 5/8] 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 49f2569f3..ecb4de53d 100644 +--- a/src/x11/events.c ++++ b/src/x11/events.c +@@ -830,6 +830,16 @@ crossing_serial_is_ignored (MetaDisplay *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 (MetaDisplay *display, + XIEvent *input_event, +@@ -871,6 +881,7 @@ handle_input_xevent (MetaDisplay *display, + * avoid races. + */ + if (window && !crossing_serial_is_ignored (display, serial) && ++ !event_has_button_mask (enter_event) && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + enter_event->detail != XINotifyInferior && +-- +2.14.2 + 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..8fcef03 --- /dev/null +++ b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch @@ -0,0 +1,132 @@ +From 5e3a6efd0e2bbea040e203b996e7d00ab3431cfa 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 079f6a9ef..8e8bc3f77 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -304,108 +304,106 @@ meta_finalize (void) + + #ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + meta_wayland_finalize (); + #endif + } + + static gboolean + on_sigterm (gpointer user_data) + { + meta_quit (EXIT_SUCCESS); + + return G_SOURCE_REMOVE; + } + + #if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) + static gboolean + session_type_is_supported (const char *session_type) + { + return (g_strcmp0 (session_type, "x11") == 0) || + (g_strcmp0 (session_type, "wayland") == 0); + } + + static char * + find_session_type (void) + { + char **sessions = NULL; + 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); + if (ret == 0 && session_id != NULL) + { + ret = sd_session_get_type (session_id, &session_type); + free (session_id); + + if (ret == 0) + { + if (session_type_is_supported (session_type)) + goto out; +- else +- is_tty = g_strcmp0 (session_type, "tty") == 0; ++ + free (session_type); + } + } + else if (sd_uid_get_sessions (getuid (), 1, &sessions) > 0) + { + for (i = 0; sessions[i] != NULL; i++) + { + ret = sd_session_get_type (sessions[i], &session_type); + + if (ret < 0) + continue; + + if (session_type_is_supported (session_type)) + { + g_strfreev (sessions); + goto out; + } + + free (session_type); + } + } + g_strfreev (sessions); + + session_type_env = g_getenv ("XDG_SESSION_TYPE"); + if (session_type_is_supported (session_type_env)) + { + /* The string should be freeable */ + session_type = strdup (session_type_env); + 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; + } + + meta_warning ("Unsupported session type\n"); + meta_exit (META_EXIT_ERROR); + + out: + return session_type; + } + + static gboolean + check_for_wayland_session_type (void) + { + char *session_type; + gboolean is_wayland; + + session_type = find_session_type (); + is_wayland = g_strcmp0 (session_type, "wayland") == 0; + free (session_type); + + return is_wayland; + } + #endif + + /* + * Determine the compositor configuration, i.e. whether to run as a Wayland + * compositor, as well as what backend to use. + * +-- +2.14.3 + diff --git a/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch b/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch new file mode 100644 index 0000000..3a67aa8 --- /dev/null +++ b/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch @@ -0,0 +1,145 @@ +From 679644180338527648d7856640c2021b4f4daf30 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] 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 | 71 ++++++++++++++++++++++++++++++ + src/backends/meta-monitor-config-manager.h | 1 + + src/backends/meta-monitor-manager.c | 19 ++++++++ + 3 files changed, 91 insertions(+) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index cdc9fb775..2fe620767 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -558,6 +558,77 @@ 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; ++ ++ output = meta_monitor_get_main_output (monitor); ++ return create_preferred_logical_monitor_config (monitor_manager, ++ monitor, ++ output->crtc->rect.x, ++ output->crtc->rect.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); ++ ++ 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); ++ ++ logical_monitor_configs = g_list_append (logical_monitor_configs, ++ logical_monitor_config); ++ } ++ return NULL; ++} ++ + 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 b99cdaba2..516909dd7 100644 +--- a/src/backends/meta-monitor-config-manager.h ++++ b/src/backends/meta-monitor-config-manager.h +@@ -87,6 +87,7 @@ gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager, + + MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager); + ++MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager); + MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager); + + MetaMonitorsConfig * meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager); +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index f2ad3f3d0..8b548fd68 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -553,6 +553,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.14.2 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch b/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch new file mode 100644 index 0000000..127f61d --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch @@ -0,0 +1,259 @@ +From ed7cad0561b79e68ddd91f0e12042087199676ea Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Sun, 25 Oct 2015 16:14:58 +0100 +Subject: [PATCH 3/8] 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/x11/meta-monitor-manager-xrandr.c | 188 ++++++++++++++++++------- + 1 file changed, 137 insertions(+), 51 deletions(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index 8d1bdfb69..d451fcccc 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -61,6 +61,11 @@ struct _MetaMonitorManagerXrandr + XRRScreenResources *resources; + int rr_event_base; + int rr_error_base; ++ ++ guint logind_watch_id; ++ guint logind_signal_sub_id; ++ ++ gboolean need_hardware_poll; + gboolean has_randr15; + + xcb_timestamp_t last_xrandr_set_timestamp; +@@ -787,8 +792,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) + manager->screen_width = WidthOfScreen (screen); + manager->screen_height = HeightOfScreen (screen); + +- resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay, +- DefaultRootWindow (manager_xrandr->xdisplay)); ++ if (manager_xrandr->need_hardware_poll) ++ { ++ resources = XRRGetScreenResources (manager_xrandr->xdisplay, ++ DefaultRootWindow (manager_xrandr->xdisplay)); ++ manager_xrandr->need_hardware_poll = FALSE; ++ } ++ else ++ resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay, ++ DefaultRootWindow (manager_xrandr->xdisplay)); + if (!resources) + return; + +@@ -1910,6 +1922,115 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; + } + ++static gboolean ++is_xvnc (MetaMonitorManager *manager) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < manager->n_outputs; ++i) ++ if (g_str_has_prefix (manager->outputs[i].name, "VNC-")) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static void ++meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr) ++{ ++ MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); ++ gboolean is_hotplug; ++ gboolean is_our_configuration; ++ unsigned int timestamp; ++ ++ meta_monitor_manager_read_current_state (manager); ++ ++ timestamp = manager_xrandr->resources->timestamp; ++ if (is_xvnc (manager)) ++ timestamp += 100; ++ ++ is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp); ++ is_our_configuration = (manager_xrandr->resources->timestamp == ++ manager_xrandr->last_xrandr_set_timestamp); ++ if (is_hotplug) ++ { ++ meta_monitor_manager_on_hotplug (manager); ++ } ++ else ++ { ++ MetaMonitorsConfig *config; ++ ++ if (is_our_configuration) ++ { ++ MetaMonitorConfigManager *config_manager = ++ meta_monitor_manager_get_config_manager (manager); ++ ++ config = meta_monitor_config_manager_get_current (config_manager); ++ } ++ else ++ { ++ config = NULL; ++ } ++ ++ meta_monitor_manager_rebuild_derived (manager, config); ++ } ++} ++ ++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) ++ { ++ manager_xrandr->need_hardware_poll = TRUE; ++ 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_init (MetaMonitorManagerXrandr *manager_xrandr) + { +@@ -1948,6 +2069,15 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) + meta_monitor_manager_xrandr_init_monitors (manager_xrandr); + #endif + } ++ ++ 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); ++ manager_xrandr->need_hardware_poll = TRUE; + } + + static void +@@ -1962,6 +2092,10 @@ 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); + } + +@@ -1996,64 +2130,16 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) + g_quark_from_static_string ("-meta-monitor-xrandr-data"); + } + +-static gboolean +-is_xvnc (MetaMonitorManager *manager) +-{ +- unsigned int i; +- +- for (i = 0; i < manager->n_outputs; ++i) +- if (g_str_has_prefix (manager->outputs[i].name, "VNC-")) +- return TRUE; +- +- return FALSE; +-} +- + gboolean + meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, + XEvent *event) + { +- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); +- gboolean is_hotplug; +- 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); +- +- +- timestamp = manager_xrandr->resources->timestamp; +- if (is_xvnc (manager)) +- timestamp += 100; +- +- is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp); +- is_our_configuration = (manager_xrandr->resources->timestamp == +- manager_xrandr->last_xrandr_set_timestamp); +- if (is_hotplug) +- { +- meta_monitor_manager_on_hotplug (manager); +- } +- else +- { +- MetaMonitorsConfig *config; +- +- if (is_our_configuration) +- { +- MetaMonitorConfigManager *config_manager = +- meta_monitor_manager_get_config_manager (manager); +- +- config = meta_monitor_config_manager_get_current (config_manager); +- } +- else +- { +- config = NULL; +- } +- +- meta_monitor_manager_xrandr_rebuild_derived (manager, config); +- } ++ meta_monitor_manager_xrandr_update (manager_xrandr); + + return TRUE; + } +-- +2.14.2 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch new file mode 100644 index 0000000..73e1cd5 --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch @@ -0,0 +1,63 @@ +From 73cae2c78af65cdfd6fa0c8257b4d3ae593f9f74 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Tue, 6 Oct 2015 21:16:18 +0200 +Subject: [PATCH 2/8] 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. +--- + src/backends/x11/meta-monitor-manager-xrandr.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c +index c369d4960..8d1bdfb69 100644 +--- a/src/backends/x11/meta-monitor-manager-xrandr.c ++++ b/src/backends/x11/meta-monitor-manager-xrandr.c +@@ -1909,6 +1909,18 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) + g_quark_from_static_string ("-meta-monitor-xrandr-data"); + } + ++static gboolean ++is_xvnc (MetaMonitorManager *manager) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < manager->n_outputs; ++i) ++ if (g_str_has_prefix (manager->outputs[i].name, "VNC-")) ++ return TRUE; ++ ++ return FALSE; ++} ++ + gboolean + meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, + XEvent *event) +@@ -1916,6 +1928,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + gboolean is_hotplug; + gboolean is_our_configuration; ++ unsigned int timestamp; + + if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) + return FALSE; +@@ -1925,8 +1938,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra + meta_monitor_manager_read_current_state (manager); + + +- is_hotplug = (manager_xrandr->resources->timestamp < +- manager_xrandr->resources->configTimestamp); ++ timestamp = manager_xrandr->resources->timestamp; ++ if (is_xvnc (manager)) ++ timestamp += 100; ++ ++ is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp); + is_our_configuration = (manager_xrandr->resources->timestamp == + manager_xrandr->last_xrandr_set_timestamp); + if (is_hotplug) +-- +2.14.2 + diff --git a/SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch b/SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch new file mode 100644 index 0000000..094910d --- /dev/null +++ b/SOURCES/0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch @@ -0,0 +1,44 @@ +From 4b2d21ff03ed389138fcb9bca778aec02bafcadb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Fri, 2 Feb 2018 14:34:50 +0800 +Subject: [PATCH] renderer/x11: Enable GPU memory purge error extension if + available + +This was done by the clutter X11 backend before prior to introducing +MetaRenderer, but during that work, enabling of said extension was lost. +Let's turn it on again. + +https://bugzilla.gnome.org/show_bug.cgi?id=739178 +--- + src/backends/x11/meta-backend-x11.c | 2 -- + src/backends/x11/meta-renderer-x11.c | 1 + + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c +index 233532435..c7602cc70 100644 +--- a/src/backends/x11/meta-backend-x11.c ++++ b/src/backends/x11/meta-backend-x11.c +@@ -705,8 +705,6 @@ meta_backend_x11_init (MetaBackendX11 *x11) + */ + XInitThreads(); + +- clutter_x11_request_reset_on_video_memory_purge (); +- + /* We do X11 event retrieval ourselves */ + clutter_x11_disable_event_retrieval (); + } +diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c +index 90924e038..003211d85 100644 +--- a/src/backends/x11/meta-renderer-x11.c ++++ b/src/backends/x11/meta-renderer-x11.c +@@ -73,6 +73,7 @@ meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer) + cogl_renderer = cogl_renderer_new (); + cogl_renderer_set_custom_winsys (cogl_renderer, get_x11_cogl_winsys_vtable); + cogl_xlib_renderer_set_foreign_display (cogl_renderer, xdisplay); ++ cogl_xlib_renderer_request_reset_on_video_memory_purge (cogl_renderer, TRUE); + + /* Set up things so that if the INTEL_swap_event extension is not present, + * but the driver is known to have good thread support, we use an extra +-- +2.14.3 + diff --git a/SOURCES/0001-rhel7-Fix-build-for-el7.patch b/SOURCES/0001-rhel7-Fix-build-for-el7.patch new file mode 100644 index 0000000..5b9ac0f --- /dev/null +++ b/SOURCES/0001-rhel7-Fix-build-for-el7.patch @@ -0,0 +1,898 @@ +From 6be34265a67e9ca1e30fe42993d5743b01d3b010 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Fri, 15 Sep 2017 08:55:44 +0100 +Subject: [PATCH] rhel7: Fix build for el7 + +--- + .../evdev/clutter-virtual-input-device-evdev.c | 1 + + clutter/clutter/evdev/linux/input-event-codes.h | 838 +++++++++++++++++++++ + src/backends/native/meta-input-settings-native.c | 2 +- + src/wayland/meta-wayland-tablet-tool.c | 2 +- + 4 files changed, 841 insertions(+), 2 deletions(-) + create mode 100644 clutter/clutter/evdev/linux/input-event-codes.h + +diff --git a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c +index e487708..8443c0a 100644 +--- a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c ++++ b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c +@@ -33,6 +33,7 @@ + #include "evdev/clutter-input-device-evdev.h" + #include "evdev/clutter-seat-evdev.h" + #include "evdev/clutter-virtual-input-device-evdev.h" ++#include "evdev/linux/input-event-codes.h" + + enum + { +diff --git a/clutter/clutter/evdev/linux/input-event-codes.h b/clutter/clutter/evdev/linux/input-event-codes.h +new file mode 100644 +index 0000000..e2b5c75 +--- /dev/null ++++ b/clutter/clutter/evdev/linux/input-event-codes.h +@@ -0,0 +1,838 @@ ++/* ++ * Input event codes ++ * ++ * *** IMPORTANT *** ++ * This file is not only included from C-code but also from devicetree source ++ * files. As such this file MUST only contain comments and defines. ++ * ++ * Copyright (c) 1999-2002 Vojtech Pavlik ++ * Copyright (c) 2015 Hans de Goede ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published by ++ * the Free Software Foundation. ++ */ ++#ifndef _INPUT_EVENT_CODES_H ++#define _INPUT_EVENT_CODES_H ++ ++/* ++ * Device properties and quirks ++ */ ++ ++#define INPUT_PROP_POINTER 0x00 /* needs a pointer */ ++#define INPUT_PROP_DIRECT 0x01 /* direct input devices */ ++#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */ ++#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ ++#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ ++#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ ++#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ ++ ++#define INPUT_PROP_MAX 0x1f ++#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) ++ ++/* ++ * Event types ++ */ ++ ++#define EV_SYN 0x00 ++#define EV_KEY 0x01 ++#define EV_REL 0x02 ++#define EV_ABS 0x03 ++#define EV_MSC 0x04 ++#define EV_SW 0x05 ++#define EV_LED 0x11 ++#define EV_SND 0x12 ++#define EV_REP 0x14 ++#define EV_FF 0x15 ++#define EV_PWR 0x16 ++#define EV_FF_STATUS 0x17 ++#define EV_MAX 0x1f ++#define EV_CNT (EV_MAX+1) ++ ++/* ++ * Synchronization events. ++ */ ++ ++#define SYN_REPORT 0 ++#define SYN_CONFIG 1 ++#define SYN_MT_REPORT 2 ++#define SYN_DROPPED 3 ++#define SYN_MAX 0xf ++#define SYN_CNT (SYN_MAX+1) ++ ++/* ++ * Keys and buttons ++ * ++ * Most of the keys/buttons are modeled after USB HUT 1.12 ++ * (see http://www.usb.org/developers/hidpage). ++ * Abbreviations in the comments: ++ * AC - Application Control ++ * AL - Application Launch Button ++ * SC - System Control ++ */ ++ ++#define KEY_RESERVED 0 ++#define KEY_ESC 1 ++#define KEY_1 2 ++#define KEY_2 3 ++#define KEY_3 4 ++#define KEY_4 5 ++#define KEY_5 6 ++#define KEY_6 7 ++#define KEY_7 8 ++#define KEY_8 9 ++#define KEY_9 10 ++#define KEY_0 11 ++#define KEY_MINUS 12 ++#define KEY_EQUAL 13 ++#define KEY_BACKSPACE 14 ++#define KEY_TAB 15 ++#define KEY_Q 16 ++#define KEY_W 17 ++#define KEY_E 18 ++#define KEY_R 19 ++#define KEY_T 20 ++#define KEY_Y 21 ++#define KEY_U 22 ++#define KEY_I 23 ++#define KEY_O 24 ++#define KEY_P 25 ++#define KEY_LEFTBRACE 26 ++#define KEY_RIGHTBRACE 27 ++#define KEY_ENTER 28 ++#define KEY_LEFTCTRL 29 ++#define KEY_A 30 ++#define KEY_S 31 ++#define KEY_D 32 ++#define KEY_F 33 ++#define KEY_G 34 ++#define KEY_H 35 ++#define KEY_J 36 ++#define KEY_K 37 ++#define KEY_L 38 ++#define KEY_SEMICOLON 39 ++#define KEY_APOSTROPHE 40 ++#define KEY_GRAVE 41 ++#define KEY_LEFTSHIFT 42 ++#define KEY_BACKSLASH 43 ++#define KEY_Z 44 ++#define KEY_X 45 ++#define KEY_C 46 ++#define KEY_V 47 ++#define KEY_B 48 ++#define KEY_N 49 ++#define KEY_M 50 ++#define KEY_COMMA 51 ++#define KEY_DOT 52 ++#define KEY_SLASH 53 ++#define KEY_RIGHTSHIFT 54 ++#define KEY_KPASTERISK 55 ++#define KEY_LEFTALT 56 ++#define KEY_SPACE 57 ++#define KEY_CAPSLOCK 58 ++#define KEY_F1 59 ++#define KEY_F2 60 ++#define KEY_F3 61 ++#define KEY_F4 62 ++#define KEY_F5 63 ++#define KEY_F6 64 ++#define KEY_F7 65 ++#define KEY_F8 66 ++#define KEY_F9 67 ++#define KEY_F10 68 ++#define KEY_NUMLOCK 69 ++#define KEY_SCROLLLOCK 70 ++#define KEY_KP7 71 ++#define KEY_KP8 72 ++#define KEY_KP9 73 ++#define KEY_KPMINUS 74 ++#define KEY_KP4 75 ++#define KEY_KP5 76 ++#define KEY_KP6 77 ++#define KEY_KPPLUS 78 ++#define KEY_KP1 79 ++#define KEY_KP2 80 ++#define KEY_KP3 81 ++#define KEY_KP0 82 ++#define KEY_KPDOT 83 ++ ++#define KEY_ZENKAKUHANKAKU 85 ++#define KEY_102ND 86 ++#define KEY_F11 87 ++#define KEY_F12 88 ++#define KEY_RO 89 ++#define KEY_KATAKANA 90 ++#define KEY_HIRAGANA 91 ++#define KEY_HENKAN 92 ++#define KEY_KATAKANAHIRAGANA 93 ++#define KEY_MUHENKAN 94 ++#define KEY_KPJPCOMMA 95 ++#define KEY_KPENTER 96 ++#define KEY_RIGHTCTRL 97 ++#define KEY_KPSLASH 98 ++#define KEY_SYSRQ 99 ++#define KEY_RIGHTALT 100 ++#define KEY_LINEFEED 101 ++#define KEY_HOME 102 ++#define KEY_UP 103 ++#define KEY_PAGEUP 104 ++#define KEY_LEFT 105 ++#define KEY_RIGHT 106 ++#define KEY_END 107 ++#define KEY_DOWN 108 ++#define KEY_PAGEDOWN 109 ++#define KEY_INSERT 110 ++#define KEY_DELETE 111 ++#define KEY_MACRO 112 ++#define KEY_MUTE 113 ++#define KEY_VOLUMEDOWN 114 ++#define KEY_VOLUMEUP 115 ++#define KEY_POWER 116 /* SC System Power Down */ ++#define KEY_KPEQUAL 117 ++#define KEY_KPPLUSMINUS 118 ++#define KEY_PAUSE 119 ++#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ ++ ++#define KEY_KPCOMMA 121 ++#define KEY_HANGEUL 122 ++#define KEY_HANGUEL KEY_HANGEUL ++#define KEY_HANJA 123 ++#define KEY_YEN 124 ++#define KEY_LEFTMETA 125 ++#define KEY_RIGHTMETA 126 ++#define KEY_COMPOSE 127 ++ ++#define KEY_STOP 128 /* AC Stop */ ++#define KEY_AGAIN 129 ++#define KEY_PROPS 130 /* AC Properties */ ++#define KEY_UNDO 131 /* AC Undo */ ++#define KEY_FRONT 132 ++#define KEY_COPY 133 /* AC Copy */ ++#define KEY_OPEN 134 /* AC Open */ ++#define KEY_PASTE 135 /* AC Paste */ ++#define KEY_FIND 136 /* AC Search */ ++#define KEY_CUT 137 /* AC Cut */ ++#define KEY_HELP 138 /* AL Integrated Help Center */ ++#define KEY_MENU 139 /* Menu (show menu) */ ++#define KEY_CALC 140 /* AL Calculator */ ++#define KEY_SETUP 141 ++#define KEY_SLEEP 142 /* SC System Sleep */ ++#define KEY_WAKEUP 143 /* System Wake Up */ ++#define KEY_FILE 144 /* AL Local Machine Browser */ ++#define KEY_SENDFILE 145 ++#define KEY_DELETEFILE 146 ++#define KEY_XFER 147 ++#define KEY_PROG1 148 ++#define KEY_PROG2 149 ++#define KEY_WWW 150 /* AL Internet Browser */ ++#define KEY_MSDOS 151 ++#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */ ++#define KEY_SCREENLOCK KEY_COFFEE ++#define KEY_ROTATE_DISPLAY 153 /* Display orientation for e.g. tablets */ ++#define KEY_DIRECTION KEY_ROTATE_DISPLAY ++#define KEY_CYCLEWINDOWS 154 ++#define KEY_MAIL 155 ++#define KEY_BOOKMARKS 156 /* AC Bookmarks */ ++#define KEY_COMPUTER 157 ++#define KEY_BACK 158 /* AC Back */ ++#define KEY_FORWARD 159 /* AC Forward */ ++#define KEY_CLOSECD 160 ++#define KEY_EJECTCD 161 ++#define KEY_EJECTCLOSECD 162 ++#define KEY_NEXTSONG 163 ++#define KEY_PLAYPAUSE 164 ++#define KEY_PREVIOUSSONG 165 ++#define KEY_STOPCD 166 ++#define KEY_RECORD 167 ++#define KEY_REWIND 168 ++#define KEY_PHONE 169 /* Media Select Telephone */ ++#define KEY_ISO 170 ++#define KEY_CONFIG 171 /* AL Consumer Control Configuration */ ++#define KEY_HOMEPAGE 172 /* AC Home */ ++#define KEY_REFRESH 173 /* AC Refresh */ ++#define KEY_EXIT 174 /* AC Exit */ ++#define KEY_MOVE 175 ++#define KEY_EDIT 176 ++#define KEY_SCROLLUP 177 ++#define KEY_SCROLLDOWN 178 ++#define KEY_KPLEFTPAREN 179 ++#define KEY_KPRIGHTPAREN 180 ++#define KEY_NEW 181 /* AC New */ ++#define KEY_REDO 182 /* AC Redo/Repeat */ ++ ++#define KEY_F13 183 ++#define KEY_F14 184 ++#define KEY_F15 185 ++#define KEY_F16 186 ++#define KEY_F17 187 ++#define KEY_F18 188 ++#define KEY_F19 189 ++#define KEY_F20 190 ++#define KEY_F21 191 ++#define KEY_F22 192 ++#define KEY_F23 193 ++#define KEY_F24 194 ++ ++#define KEY_PLAYCD 200 ++#define KEY_PAUSECD 201 ++#define KEY_PROG3 202 ++#define KEY_PROG4 203 ++#define KEY_DASHBOARD 204 /* AL Dashboard */ ++#define KEY_SUSPEND 205 ++#define KEY_CLOSE 206 /* AC Close */ ++#define KEY_PLAY 207 ++#define KEY_FASTFORWARD 208 ++#define KEY_BASSBOOST 209 ++#define KEY_PRINT 210 /* AC Print */ ++#define KEY_HP 211 ++#define KEY_CAMERA 212 ++#define KEY_SOUND 213 ++#define KEY_QUESTION 214 ++#define KEY_EMAIL 215 ++#define KEY_CHAT 216 ++#define KEY_SEARCH 217 ++#define KEY_CONNECT 218 ++#define KEY_FINANCE 219 /* AL Checkbook/Finance */ ++#define KEY_SPORT 220 ++#define KEY_SHOP 221 ++#define KEY_ALTERASE 222 ++#define KEY_CANCEL 223 /* AC Cancel */ ++#define KEY_BRIGHTNESSDOWN 224 ++#define KEY_BRIGHTNESSUP 225 ++#define KEY_MEDIA 226 ++ ++#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video ++ outputs (Monitor/LCD/TV-out/etc) */ ++#define KEY_KBDILLUMTOGGLE 228 ++#define KEY_KBDILLUMDOWN 229 ++#define KEY_KBDILLUMUP 230 ++ ++#define KEY_SEND 231 /* AC Send */ ++#define KEY_REPLY 232 /* AC Reply */ ++#define KEY_FORWARDMAIL 233 /* AC Forward Msg */ ++#define KEY_SAVE 234 /* AC Save */ ++#define KEY_DOCUMENTS 235 ++ ++#define KEY_BATTERY 236 ++ ++#define KEY_BLUETOOTH 237 ++#define KEY_WLAN 238 ++#define KEY_UWB 239 ++ ++#define KEY_UNKNOWN 240 ++ ++#define KEY_VIDEO_NEXT 241 /* drive next video source */ ++#define KEY_VIDEO_PREV 242 /* drive previous video source */ ++#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */ ++#define KEY_BRIGHTNESS_AUTO 244 /* Set Auto Brightness: manual ++ brightness control is off, ++ rely on ambient */ ++#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO ++#define KEY_DISPLAY_OFF 245 /* display device to off state */ ++ ++#define KEY_WWAN 246 /* Wireless WAN (LTE, UMTS, GSM, etc.) */ ++#define KEY_WIMAX KEY_WWAN ++#define KEY_RFKILL 247 /* Key that controls all radios */ ++ ++#define KEY_MICMUTE 248 /* Mute / unmute the microphone */ ++ ++/* Code 255 is reserved for special needs of AT keyboard driver */ ++ ++#define BTN_MISC 0x100 ++#define BTN_0 0x100 ++#define BTN_1 0x101 ++#define BTN_2 0x102 ++#define BTN_3 0x103 ++#define BTN_4 0x104 ++#define BTN_5 0x105 ++#define BTN_6 0x106 ++#define BTN_7 0x107 ++#define BTN_8 0x108 ++#define BTN_9 0x109 ++ ++#define BTN_MOUSE 0x110 ++#define BTN_LEFT 0x110 ++#define BTN_RIGHT 0x111 ++#define BTN_MIDDLE 0x112 ++#define BTN_SIDE 0x113 ++#define BTN_EXTRA 0x114 ++#define BTN_FORWARD 0x115 ++#define BTN_BACK 0x116 ++#define BTN_TASK 0x117 ++ ++#define BTN_JOYSTICK 0x120 ++#define BTN_TRIGGER 0x120 ++#define BTN_THUMB 0x121 ++#define BTN_THUMB2 0x122 ++#define BTN_TOP 0x123 ++#define BTN_TOP2 0x124 ++#define BTN_PINKIE 0x125 ++#define BTN_BASE 0x126 ++#define BTN_BASE2 0x127 ++#define BTN_BASE3 0x128 ++#define BTN_BASE4 0x129 ++#define BTN_BASE5 0x12a ++#define BTN_BASE6 0x12b ++#define BTN_DEAD 0x12f ++ ++#define BTN_GAMEPAD 0x130 ++#define BTN_SOUTH 0x130 ++#define BTN_A BTN_SOUTH ++#define BTN_EAST 0x131 ++#define BTN_B BTN_EAST ++#define BTN_C 0x132 ++#define BTN_NORTH 0x133 ++#define BTN_X BTN_NORTH ++#define BTN_WEST 0x134 ++#define BTN_Y BTN_WEST ++#define BTN_Z 0x135 ++#define BTN_TL 0x136 ++#define BTN_TR 0x137 ++#define BTN_TL2 0x138 ++#define BTN_TR2 0x139 ++#define BTN_SELECT 0x13a ++#define BTN_START 0x13b ++#define BTN_MODE 0x13c ++#define BTN_THUMBL 0x13d ++#define BTN_THUMBR 0x13e ++ ++#define BTN_DIGI 0x140 ++#define BTN_TOOL_PEN 0x140 ++#define BTN_TOOL_RUBBER 0x141 ++#define BTN_TOOL_BRUSH 0x142 ++#define BTN_TOOL_PENCIL 0x143 ++#define BTN_TOOL_AIRBRUSH 0x144 ++#define BTN_TOOL_FINGER 0x145 ++#define BTN_TOOL_MOUSE 0x146 ++#define BTN_TOOL_LENS 0x147 ++#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */ ++#define BTN_TOUCH 0x14a ++#define BTN_STYLUS 0x14b ++#define BTN_STYLUS2 0x14c ++#define BTN_TOOL_DOUBLETAP 0x14d ++#define BTN_TOOL_TRIPLETAP 0x14e ++#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */ ++ ++#define BTN_WHEEL 0x150 ++#define BTN_GEAR_DOWN 0x150 ++#define BTN_GEAR_UP 0x151 ++ ++#define KEY_OK 0x160 ++#define KEY_SELECT 0x161 ++#define KEY_GOTO 0x162 ++#define KEY_CLEAR 0x163 ++#define KEY_POWER2 0x164 ++#define KEY_OPTION 0x165 ++#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */ ++#define KEY_TIME 0x167 ++#define KEY_VENDOR 0x168 ++#define KEY_ARCHIVE 0x169 ++#define KEY_PROGRAM 0x16a /* Media Select Program Guide */ ++#define KEY_CHANNEL 0x16b ++#define KEY_FAVORITES 0x16c ++#define KEY_EPG 0x16d ++#define KEY_PVR 0x16e /* Media Select Home */ ++#define KEY_MHP 0x16f ++#define KEY_LANGUAGE 0x170 ++#define KEY_TITLE 0x171 ++#define KEY_SUBTITLE 0x172 ++#define KEY_ANGLE 0x173 ++#define KEY_ZOOM 0x174 ++#define KEY_MODE 0x175 ++#define KEY_KEYBOARD 0x176 ++#define KEY_SCREEN 0x177 ++#define KEY_PC 0x178 /* Media Select Computer */ ++#define KEY_TV 0x179 /* Media Select TV */ ++#define KEY_TV2 0x17a /* Media Select Cable */ ++#define KEY_VCR 0x17b /* Media Select VCR */ ++#define KEY_VCR2 0x17c /* VCR Plus */ ++#define KEY_SAT 0x17d /* Media Select Satellite */ ++#define KEY_SAT2 0x17e ++#define KEY_CD 0x17f /* Media Select CD */ ++#define KEY_TAPE 0x180 /* Media Select Tape */ ++#define KEY_RADIO 0x181 ++#define KEY_TUNER 0x182 /* Media Select Tuner */ ++#define KEY_PLAYER 0x183 ++#define KEY_TEXT 0x184 ++#define KEY_DVD 0x185 /* Media Select DVD */ ++#define KEY_AUX 0x186 ++#define KEY_MP3 0x187 ++#define KEY_AUDIO 0x188 /* AL Audio Browser */ ++#define KEY_VIDEO 0x189 /* AL Movie Browser */ ++#define KEY_DIRECTORY 0x18a ++#define KEY_LIST 0x18b ++#define KEY_MEMO 0x18c /* Media Select Messages */ ++#define KEY_CALENDAR 0x18d ++#define KEY_RED 0x18e ++#define KEY_GREEN 0x18f ++#define KEY_YELLOW 0x190 ++#define KEY_BLUE 0x191 ++#define KEY_CHANNELUP 0x192 /* Channel Increment */ ++#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */ ++#define KEY_FIRST 0x194 ++#define KEY_LAST 0x195 /* Recall Last */ ++#define KEY_AB 0x196 ++#define KEY_NEXT 0x197 ++#define KEY_RESTART 0x198 ++#define KEY_SLOW 0x199 ++#define KEY_SHUFFLE 0x19a ++#define KEY_BREAK 0x19b ++#define KEY_PREVIOUS 0x19c ++#define KEY_DIGITS 0x19d ++#define KEY_TEEN 0x19e ++#define KEY_TWEN 0x19f ++#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */ ++#define KEY_GAMES 0x1a1 /* Media Select Games */ ++#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */ ++#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */ ++#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */ ++#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */ ++#define KEY_EDITOR 0x1a6 /* AL Text Editor */ ++#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */ ++#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */ ++#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */ ++#define KEY_DATABASE 0x1aa /* AL Database App */ ++#define KEY_NEWS 0x1ab /* AL Newsreader */ ++#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */ ++#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */ ++#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */ ++#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */ ++#define KEY_BRIGHTNESS_TOGGLE KEY_DISPLAYTOGGLE ++#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */ ++#define KEY_LOGOFF 0x1b1 /* AL Logoff */ ++ ++#define KEY_DOLLAR 0x1b2 ++#define KEY_EURO 0x1b3 ++ ++#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */ ++#define KEY_FRAMEFORWARD 0x1b5 ++#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */ ++#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */ ++#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ ++#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ ++#define KEY_IMAGES 0x1ba /* AL Image Browser */ ++ ++#define KEY_DEL_EOL 0x1c0 ++#define KEY_DEL_EOS 0x1c1 ++#define KEY_INS_LINE 0x1c2 ++#define KEY_DEL_LINE 0x1c3 ++ ++#define KEY_FN 0x1d0 ++#define KEY_FN_ESC 0x1d1 ++#define KEY_FN_F1 0x1d2 ++#define KEY_FN_F2 0x1d3 ++#define KEY_FN_F3 0x1d4 ++#define KEY_FN_F4 0x1d5 ++#define KEY_FN_F5 0x1d6 ++#define KEY_FN_F6 0x1d7 ++#define KEY_FN_F7 0x1d8 ++#define KEY_FN_F8 0x1d9 ++#define KEY_FN_F9 0x1da ++#define KEY_FN_F10 0x1db ++#define KEY_FN_F11 0x1dc ++#define KEY_FN_F12 0x1dd ++#define KEY_FN_1 0x1de ++#define KEY_FN_2 0x1df ++#define KEY_FN_D 0x1e0 ++#define KEY_FN_E 0x1e1 ++#define KEY_FN_F 0x1e2 ++#define KEY_FN_S 0x1e3 ++#define KEY_FN_B 0x1e4 ++ ++#define KEY_BRL_DOT1 0x1f1 ++#define KEY_BRL_DOT2 0x1f2 ++#define KEY_BRL_DOT3 0x1f3 ++#define KEY_BRL_DOT4 0x1f4 ++#define KEY_BRL_DOT5 0x1f5 ++#define KEY_BRL_DOT6 0x1f6 ++#define KEY_BRL_DOT7 0x1f7 ++#define KEY_BRL_DOT8 0x1f8 ++#define KEY_BRL_DOT9 0x1f9 ++#define KEY_BRL_DOT10 0x1fa ++ ++#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */ ++#define KEY_NUMERIC_1 0x201 /* and other keypads */ ++#define KEY_NUMERIC_2 0x202 ++#define KEY_NUMERIC_3 0x203 ++#define KEY_NUMERIC_4 0x204 ++#define KEY_NUMERIC_5 0x205 ++#define KEY_NUMERIC_6 0x206 ++#define KEY_NUMERIC_7 0x207 ++#define KEY_NUMERIC_8 0x208 ++#define KEY_NUMERIC_9 0x209 ++#define KEY_NUMERIC_STAR 0x20a ++#define KEY_NUMERIC_POUND 0x20b ++#define KEY_NUMERIC_A 0x20c /* Phone key A - HUT Telephony 0xb9 */ ++#define KEY_NUMERIC_B 0x20d ++#define KEY_NUMERIC_C 0x20e ++#define KEY_NUMERIC_D 0x20f ++ ++#define KEY_CAMERA_FOCUS 0x210 ++#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */ ++ ++#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */ ++#define KEY_TOUCHPAD_ON 0x213 ++#define KEY_TOUCHPAD_OFF 0x214 ++ ++#define KEY_CAMERA_ZOOMIN 0x215 ++#define KEY_CAMERA_ZOOMOUT 0x216 ++#define KEY_CAMERA_UP 0x217 ++#define KEY_CAMERA_DOWN 0x218 ++#define KEY_CAMERA_LEFT 0x219 ++#define KEY_CAMERA_RIGHT 0x21a ++ ++#define KEY_ATTENDANT_ON 0x21b ++#define KEY_ATTENDANT_OFF 0x21c ++#define KEY_ATTENDANT_TOGGLE 0x21d /* Attendant call on or off */ ++#define KEY_LIGHTS_TOGGLE 0x21e /* Reading light on or off */ ++ ++#define BTN_DPAD_UP 0x220 ++#define BTN_DPAD_DOWN 0x221 ++#define BTN_DPAD_LEFT 0x222 ++#define BTN_DPAD_RIGHT 0x223 ++ ++#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */ ++ ++#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */ ++#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */ ++#define KEY_JOURNAL 0x242 /* AL Log/Journal/Timecard */ ++#define KEY_CONTROLPANEL 0x243 /* AL Control Panel */ ++#define KEY_APPSELECT 0x244 /* AL Select Task/Application */ ++#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */ ++#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ ++ ++#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ ++#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ ++ ++#define KEY_KBDINPUTASSIST_PREV 0x260 ++#define KEY_KBDINPUTASSIST_NEXT 0x261 ++#define KEY_KBDINPUTASSIST_PREVGROUP 0x262 ++#define KEY_KBDINPUTASSIST_NEXTGROUP 0x263 ++#define KEY_KBDINPUTASSIST_ACCEPT 0x264 ++#define KEY_KBDINPUTASSIST_CANCEL 0x265 ++ ++/* Diagonal movement keys */ ++#define KEY_RIGHT_UP 0x266 ++#define KEY_RIGHT_DOWN 0x267 ++#define KEY_LEFT_UP 0x268 ++#define KEY_LEFT_DOWN 0x269 ++ ++#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */ ++/* Show Top Menu of the Media (e.g. DVD) */ ++#define KEY_MEDIA_TOP_MENU 0x26b ++#define KEY_NUMERIC_11 0x26c ++#define KEY_NUMERIC_12 0x26d ++/* ++ * Toggle Audio Description: refers to an audio service that helps blind and ++ * visually impaired consumers understand the action in a program. Note: in ++ * some countries this is referred to as "Video Description". ++ */ ++#define KEY_AUDIO_DESC 0x26e ++#define KEY_3D_MODE 0x26f ++#define KEY_NEXT_FAVORITE 0x270 ++#define KEY_STOP_RECORD 0x271 ++#define KEY_PAUSE_RECORD 0x272 ++#define KEY_VOD 0x273 /* Video on Demand */ ++#define KEY_UNMUTE 0x274 ++#define KEY_FASTREVERSE 0x275 ++#define KEY_SLOWREVERSE 0x276 ++/* ++ * Control a data application associated with the currently viewed channel, ++ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) ++ */ ++#define KEY_DATA 0x277 ++#define KEY_ONSCREEN_KEYBOARD 0x278 ++ ++#define BTN_TRIGGER_HAPPY 0x2c0 ++#define BTN_TRIGGER_HAPPY1 0x2c0 ++#define BTN_TRIGGER_HAPPY2 0x2c1 ++#define BTN_TRIGGER_HAPPY3 0x2c2 ++#define BTN_TRIGGER_HAPPY4 0x2c3 ++#define BTN_TRIGGER_HAPPY5 0x2c4 ++#define BTN_TRIGGER_HAPPY6 0x2c5 ++#define BTN_TRIGGER_HAPPY7 0x2c6 ++#define BTN_TRIGGER_HAPPY8 0x2c7 ++#define BTN_TRIGGER_HAPPY9 0x2c8 ++#define BTN_TRIGGER_HAPPY10 0x2c9 ++#define BTN_TRIGGER_HAPPY11 0x2ca ++#define BTN_TRIGGER_HAPPY12 0x2cb ++#define BTN_TRIGGER_HAPPY13 0x2cc ++#define BTN_TRIGGER_HAPPY14 0x2cd ++#define BTN_TRIGGER_HAPPY15 0x2ce ++#define BTN_TRIGGER_HAPPY16 0x2cf ++#define BTN_TRIGGER_HAPPY17 0x2d0 ++#define BTN_TRIGGER_HAPPY18 0x2d1 ++#define BTN_TRIGGER_HAPPY19 0x2d2 ++#define BTN_TRIGGER_HAPPY20 0x2d3 ++#define BTN_TRIGGER_HAPPY21 0x2d4 ++#define BTN_TRIGGER_HAPPY22 0x2d5 ++#define BTN_TRIGGER_HAPPY23 0x2d6 ++#define BTN_TRIGGER_HAPPY24 0x2d7 ++#define BTN_TRIGGER_HAPPY25 0x2d8 ++#define BTN_TRIGGER_HAPPY26 0x2d9 ++#define BTN_TRIGGER_HAPPY27 0x2da ++#define BTN_TRIGGER_HAPPY28 0x2db ++#define BTN_TRIGGER_HAPPY29 0x2dc ++#define BTN_TRIGGER_HAPPY30 0x2dd ++#define BTN_TRIGGER_HAPPY31 0x2de ++#define BTN_TRIGGER_HAPPY32 0x2df ++#define BTN_TRIGGER_HAPPY33 0x2e0 ++#define BTN_TRIGGER_HAPPY34 0x2e1 ++#define BTN_TRIGGER_HAPPY35 0x2e2 ++#define BTN_TRIGGER_HAPPY36 0x2e3 ++#define BTN_TRIGGER_HAPPY37 0x2e4 ++#define BTN_TRIGGER_HAPPY38 0x2e5 ++#define BTN_TRIGGER_HAPPY39 0x2e6 ++#define BTN_TRIGGER_HAPPY40 0x2e7 ++ ++/* We avoid low common keys in module aliases so they don't get huge. */ ++#define KEY_MIN_INTERESTING KEY_MUTE ++#define KEY_MAX 0x2ff ++#define KEY_CNT (KEY_MAX+1) ++ ++/* ++ * Relative axes ++ */ ++ ++#define REL_X 0x00 ++#define REL_Y 0x01 ++#define REL_Z 0x02 ++#define REL_RX 0x03 ++#define REL_RY 0x04 ++#define REL_RZ 0x05 ++#define REL_HWHEEL 0x06 ++#define REL_DIAL 0x07 ++#define REL_WHEEL 0x08 ++#define REL_MISC 0x09 ++#define REL_MAX 0x0f ++#define REL_CNT (REL_MAX+1) ++ ++/* ++ * Absolute axes ++ */ ++ ++#define ABS_X 0x00 ++#define ABS_Y 0x01 ++#define ABS_Z 0x02 ++#define ABS_RX 0x03 ++#define ABS_RY 0x04 ++#define ABS_RZ 0x05 ++#define ABS_THROTTLE 0x06 ++#define ABS_RUDDER 0x07 ++#define ABS_WHEEL 0x08 ++#define ABS_GAS 0x09 ++#define ABS_BRAKE 0x0a ++#define ABS_HAT0X 0x10 ++#define ABS_HAT0Y 0x11 ++#define ABS_HAT1X 0x12 ++#define ABS_HAT1Y 0x13 ++#define ABS_HAT2X 0x14 ++#define ABS_HAT2Y 0x15 ++#define ABS_HAT3X 0x16 ++#define ABS_HAT3Y 0x17 ++#define ABS_PRESSURE 0x18 ++#define ABS_DISTANCE 0x19 ++#define ABS_TILT_X 0x1a ++#define ABS_TILT_Y 0x1b ++#define ABS_TOOL_WIDTH 0x1c ++ ++#define ABS_VOLUME 0x20 ++ ++#define ABS_MISC 0x28 ++ ++#define ABS_MT_SLOT 0x2f /* MT slot being modified */ ++#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ ++#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ ++#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */ ++#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */ ++#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */ ++#define ABS_MT_POSITION_X 0x35 /* Center X touch position */ ++#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */ ++#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */ ++#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ ++#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ ++#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ ++#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */ ++#define ABS_MT_TOOL_X 0x3c /* Center X tool position */ ++#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */ ++ ++ ++#define ABS_MAX 0x3f ++#define ABS_CNT (ABS_MAX+1) ++ ++/* ++ * Switch events ++ */ ++ ++#define SW_LID 0x00 /* set = lid shut */ ++#define SW_TABLET_MODE 0x01 /* set = tablet mode */ ++#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */ ++#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any" ++ set = radio enabled */ ++#define SW_RADIO SW_RFKILL_ALL /* deprecated */ ++#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */ ++#define SW_DOCK 0x05 /* set = plugged into dock */ ++#define SW_LINEOUT_INSERT 0x06 /* set = inserted */ ++#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */ ++#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */ ++#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */ ++#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ ++#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ ++#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */ ++#define SW_LINEIN_INSERT 0x0d /* set = inserted */ ++#define SW_MUTE_DEVICE 0x0e /* set = device disabled */ ++#define SW_PEN_INSERTED 0x0f /* set = pen inserted */ ++#define SW_MAX 0x0f ++#define SW_CNT (SW_MAX+1) ++ ++/* ++ * Misc events ++ */ ++ ++#define MSC_SERIAL 0x00 ++#define MSC_PULSELED 0x01 ++#define MSC_GESTURE 0x02 ++#define MSC_RAW 0x03 ++#define MSC_SCAN 0x04 ++#define MSC_TIMESTAMP 0x05 ++#define MSC_MAX 0x07 ++#define MSC_CNT (MSC_MAX+1) ++ ++/* ++ * LEDs ++ */ ++ ++#define LED_NUML 0x00 ++#define LED_CAPSL 0x01 ++#define LED_SCROLLL 0x02 ++#define LED_COMPOSE 0x03 ++#define LED_KANA 0x04 ++#define LED_SLEEP 0x05 ++#define LED_SUSPEND 0x06 ++#define LED_MUTE 0x07 ++#define LED_MISC 0x08 ++#define LED_MAIL 0x09 ++#define LED_CHARGING 0x0a ++#define LED_MAX 0x0f ++#define LED_CNT (LED_MAX+1) ++ ++/* ++ * Autorepeat values ++ */ ++ ++#define REP_DELAY 0x00 ++#define REP_PERIOD 0x01 ++#define REP_MAX 0x01 ++#define REP_CNT (REP_MAX+1) ++ ++/* ++ * Sounds ++ */ ++ ++#define SND_CLICK 0x00 ++#define SND_BELL 0x01 ++#define SND_TONE 0x02 ++#define SND_MAX 0x07 ++#define SND_CNT (SND_MAX+1) ++ ++#endif +diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c +index 8a62bb3..8a5ff5b 100644 +--- a/src/backends/native/meta-input-settings-native.c ++++ b/src/backends/native/meta-input-settings-native.c +@@ -24,7 +24,7 @@ + #include "config.h" + + #include +-#include ++#include + #include + + #include "meta-backend-native.h" +diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c +index 4b57d41..5675f48 100644 +--- a/src/wayland/meta-wayland-tablet-tool.c ++++ b/src/wayland/meta-wayland-tablet-tool.c +@@ -41,7 +41,7 @@ + + #ifdef HAVE_NATIVE_BACKEND + #include "backends/native/meta-backend-native.h" +-#include ++#include + #endif + + #define TABLET_AXIS_MAX 65535 +-- +1.8.3.1 + diff --git a/SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch b/SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch new file mode 100644 index 0000000..d90a588 --- /dev/null +++ b/SOURCES/0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch @@ -0,0 +1,37 @@ +From 9826eae9f091d461bd117c254ba8e255dd084797 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Fri, 2 Feb 2018 16:35:26 +0100 +Subject: [PATCH] wayland: Do not fail on stalled .X11-unix entries + +If for whatever reason, there are stalled files in /tmp/.X11-unix/ the +bind() to the abstract socket will succeed but not the bind() to the +to the UNIX socket. + +This causes gnome-shell/mutter to fail because it cannot start Xwayland +(while it could actually, by using a different display). + +In case of failure to bind to the UNIX socket, try the next display +instead of failing, to avoid stalled entries in /tmp/.X11-unix. + +Closes: https://gitlab.gnome.org/GNOME/mutter/issues/13 +--- + src/wayland/meta-xwayland.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c +index 50cfc7c57..ce21fe5ee 100644 +--- a/src/wayland/meta-xwayland.c ++++ b/src/wayland/meta-xwayland.c +@@ -458,7 +458,8 @@ choose_xdisplay (MetaXWaylandManager *manager) + { + unlink (lock_file); + close (manager->abstract_fd); +- return FALSE; ++ display++; ++ continue; + } + + break; +-- +2.14.3 + diff --git a/SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch b/SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch new file mode 100644 index 0000000..46c940b --- /dev/null +++ b/SOURCES/0001-wayland-enable-scale-monitor-framebuffer-by-default.patch @@ -0,0 +1,25 @@ +From 85968e1d0996b7f3a7453076c88ed6d5e0113369 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Wed, 20 Sep 2017 12:17:23 +0200 +Subject: [PATCH] wayland: enable scale-monitor-framebuffer by default + +--- + data/org.gnome.mutter.gschema.xml.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in +index d926312c8..bec5585bd 100644 +--- a/data/org.gnome.mutter.gschema.xml.in ++++ b/data/org.gnome.mutter.gschema.xml.in +@@ -103,7 +103,7 @@ + + + +- [] ++ ['scale-monitor-framebuffer'] + Enable experimental features + + To enable experimental features, add the feature keyword to the list. +-- +2.13.5 + 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..f20fc6c --- /dev/null +++ b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch @@ -0,0 +1,35 @@ +From 97f5f9bdc1c5cb1a2e02ec04750b5db9a4b4fdf1 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 8/8] 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.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c +index 773e6d09d..ac072997c 100644 +--- a/src/compositor/meta-window-actor.c ++++ b/src/compositor/meta-window-actor.c +@@ -843,6 +843,14 @@ meta_window_actor_has_shadow (MetaWindowActor *self) + if (priv->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 (priv->window->res_name, "sun-awt-X11-XWindowPeer") == 0 && ++ priv->window->shape_region != NULL) ++ return FALSE; ++ + /* + * Generate shadows for all other windows. + */ +-- +2.14.2 + diff --git a/SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch b/SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch new file mode 100644 index 0000000..32756c0 --- /dev/null +++ b/SOURCES/0003-window-wayland-Handle-resizing-when-headless.patch @@ -0,0 +1,50 @@ +From 07e5f7ef29b5567e090221d5da9415e8b84c0ebb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 16 Oct 2017 17:02:51 +0800 +Subject: [PATCH 3/4] window/wayland: Handle resizing when headless + +We tried to get the geometry scale, which may depend on the main +logical monitor assigned to the window. To avoid dereferencing a NULL +logical monitor when headless, instead assume the geometry scale is 1. + +https://bugzilla.gnome.org/show_bug.cgi?id=788764 +--- + src/wayland/meta-window-wayland.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c +index ed6e34b43..f3f0e1688 100644 +--- a/src/wayland/meta-window-wayland.c ++++ b/src/wayland/meta-window-wayland.c +@@ -67,6 +67,8 @@ G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW) + static int + get_window_geometry_scale_for_logical_monitor (MetaLogicalMonitor *logical_monitor) + { ++ g_assert (logical_monitor); ++ + if (meta_is_stage_views_scaled ()) + return 1; + else +@@ -79,8 +81,7 @@ meta_window_wayland_manage (MetaWindow *window) + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + MetaDisplay *display = window->display; + +- wl_window->geometry_scale = +- get_window_geometry_scale_for_logical_monitor (window->monitor); ++ wl_window->geometry_scale = meta_window_wayland_get_geometry_scale (window); + + meta_display_register_wayland_window (display, window); + +@@ -634,6 +635,9 @@ should_do_pending_move (MetaWindowWayland *wl_window, + int + meta_window_wayland_get_geometry_scale (MetaWindow *window) + { ++ if (!window->monitor) ++ return 1; ++ + return get_window_geometry_scale_for_logical_monitor (window->monitor); + } + +-- +2.14.2 + diff --git a/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch b/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch new file mode 100644 index 0000000..82fe332 --- /dev/null +++ b/SOURCES/0008-Add-support-for-quad-buffer-stereo.patch @@ -0,0 +1,1008 @@ +From 7940ea62307044c056c16f1534e3e8e94cc7a352 Mon Sep 17 00:00:00 2001 +From: "Owen W. Taylor" +Date: Thu, 8 May 2014 18:44:15 -0400 +Subject: [PATCH 7/8] 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. +--- + src/Makefile.am | 2 + + src/compositor/compositor-private.h | 9 ++ + src/compositor/compositor.c | 128 ++++++++++++++++++++++ + src/compositor/meta-shaped-texture-private.h | 5 +- + src/compositor/meta-shaped-texture.c | 157 ++++++++++++++++++++------- + src/compositor/meta-surface-actor-wayland.c | 10 +- + src/compositor/meta-surface-actor-x11.c | 56 ++++++++-- + 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 | 153 ++++++++++++++++++++++++++ + src/core/stereo.h | 28 +++++ + src/wayland/meta-wayland-surface.c | 2 +- + 14 files changed, 535 insertions(+), 51 deletions(-) + create mode 100644 src/core/stereo.c + create mode 100644 src/core/stereo.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index 6aef50de8..8c680602c 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -281,6 +281,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \ + core/stack.h \ + core/stack-tracker.c \ + core/stack-tracker.h \ ++ core/stereo.c \ ++ core/stereo.h \ + core/util.c \ + meta/util.h \ + core/util-private.h \ +diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h +index ba58bf175..1c257b5ee 100644 +--- a/src/compositor/compositor-private.h ++++ b/src/compositor/compositor-private.h +@@ -21,6 +21,10 @@ struct _MetaCompositor + gint64 server_time_query_time; + gint64 server_time_offset; + ++ int glx_opcode; ++ guint stereo_tree_ext : 1; ++ guint have_stereo_windows : 1; ++ + guint server_time_is_monotonic_time : 1; + guint no_mipmaps : 1; + +@@ -61,6 +65,11 @@ void meta_end_modal_for_plugin (MetaCompositor *compositor, + gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, + gint64 monotonic_time); + ++gboolean meta_compositor_window_is_stereo (MetaScreen *screen, ++ Window xwindow); ++void meta_compositor_select_stereo_notify (MetaScreen *screen, ++ Window xwindow); ++ + void meta_compositor_flash_window (MetaCompositor *compositor, + MetaWindow *window); + +diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c +index 17e8a55dd..a1bf1a8f8 100644 +--- a/src/compositor/compositor.c ++++ b/src/compositor/compositor.c +@@ -70,6 +70,8 @@ + #include "meta-window-group.h" + #include "window-private.h" /* to check window->hidden */ + #include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */ ++#include "stack-tracker.h" ++#include "stereo.h" + #include "util-private.h" + #include "backends/meta-dnd-private.h" + #include "frame.h" +@@ -482,6 +484,97 @@ redirect_windows (MetaScreen *screen) + } + } + ++#define GLX_STEREO_TREE_EXT 0x20F5 ++#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 ++#define GLX_STEREO_NOTIFY_EXT 0x00000000 ++ ++typedef struct { ++ int type; ++ unsigned long serial; ++ Bool send_event; ++ Display *display; ++ int extension; ++ int evtype; ++ Drawable window; ++ Bool stereo_tree; ++} StereoNotifyEvent; ++ ++static gboolean ++screen_has_stereo_tree_ext (MetaScreen *screen) ++{ ++ MetaDisplay *display = meta_screen_get_display (screen); ++ Display *xdisplay = meta_display_get_xdisplay (display); ++ 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_screen_get_screen_number (screen)); ++ ++ return extensions_string && strstr (extensions_string, "EXT_stereo_tree") != 0; ++} ++ ++#include ++ ++gboolean ++meta_compositor_window_is_stereo (MetaScreen *screen, ++ Window xwindow) ++{ ++ MetaCompositor *compositor = get_compositor_for_screen (screen); ++ MetaDisplay *display = meta_screen_get_display (screen); ++ Display *xdisplay = meta_display_get_xdisplay (display); ++ ++ static int (*query_drawable) (Display *dpy, ++ Drawable draw, ++ int attribute, ++ unsigned int *value); ++ ++ if (compositor->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_select_stereo_notify (MetaScreen *screen, ++ Window xwindow) ++{ ++ MetaCompositor *compositor = get_compositor_for_screen (screen); ++ MetaDisplay *display = meta_screen_get_display (screen); ++ Display *xdisplay = meta_display_get_xdisplay (display); ++ ++ static void (*select_event) (Display *dpy, ++ Drawable draw, ++ unsigned long event_mask); ++ ++ if (compositor->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); ++ } ++} ++ + void + meta_compositor_manage (MetaCompositor *compositor) + { +@@ -490,6 +583,8 @@ meta_compositor_manage (MetaCompositor *compositor) + MetaScreen *screen = display->screen; + MetaBackend *backend = meta_get_backend (); + ++ compositor->stereo_tree_ext = screen_has_stereo_tree_ext (screen); ++ + meta_screen_set_cm_selection (display->screen); + + compositor->stage = meta_backend_get_stage (backend); +@@ -757,6 +852,23 @@ meta_compositor_process_event (MetaCompositor *compositor, + if (window) + process_damage (compositor, (XDamageNotifyEvent *) event, window); + } ++ else if (!meta_is_wayland_compositor () && ++ event->type == GenericEvent && ++ event->xcookie.extension == compositor->glx_opcode) ++ { ++ if (event->xcookie.evtype == GLX_STEREO_NOTIFY_EXT) ++ { ++ StereoNotifyEvent *stereo_event = (StereoNotifyEvent *)(event->xcookie.data); ++ window = meta_display_lookup_x_window (compositor->display, stereo_event->window); ++ ++ if (window != NULL) ++ { ++ MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); ++ meta_window_actor_stereo_notify (window_actor, stereo_event->stereo_tree); ++ meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); ++ } ++ } ++ } + + if (compositor->have_x11_sync_object) + meta_sync_ring_handle_event (event); +@@ -957,6 +1069,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor, + GList *stack) + { + 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 +@@ -1032,6 +1145,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor, + * near the front of the other.) + */ + compositor->windows = g_list_prepend (compositor->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); +@@ -1039,6 +1154,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor, + + sync_actor_stacking (compositor); + ++ meta_stereo_set_have_stereo_windows (stereo_window_count > 0); ++ + compositor->top_window_actor = get_top_visible_window_actor (compositor); + } + +@@ -1237,6 +1354,17 @@ meta_compositor_new (MetaDisplay *display) + meta_post_paint_func, + compositor, + NULL); ++ if (!meta_is_wayland_compositor ()) ++ { ++ Display *xdisplay = meta_display_get_xdisplay (display); ++ int glx_major_opcode, glx_first_event, glx_first_error; ++ ++ if (XQueryExtension (xdisplay, ++ "GLX", ++ &glx_major_opcode, &glx_first_event, &glx_first_error)) ++ compositor->glx_opcode = glx_major_opcode; ++ } ++ + return compositor; + } + +diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h +index 5b3f283c2..189a95312 100644 +--- a/src/compositor/meta-shaped-texture-private.h ++++ b/src/compositor/meta-shaped-texture-private.h +@@ -30,8 +30,9 @@ + #include + + ClutterActor *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 98346c6ae..b89de03a3 100644 +--- a/src/compositor/meta-shaped-texture.c ++++ b/src/compositor/meta-shaped-texture.c +@@ -74,8 +74,10 @@ static guint signals[LAST_SIGNAL]; + struct _MetaShapedTexturePrivate + { + MetaTextureTower *paint_tower; ++ MetaTextureTower *paint_tower_right; + + CoglTexture *texture; ++ CoglTexture *texture_right; + CoglTexture *mask_texture; + CoglSnippet *snippet; + +@@ -129,8 +131,10 @@ meta_shaped_texture_init (MetaShapedTexture *self) + priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self); + + priv->paint_tower = meta_texture_tower_new (); ++ priv->paint_tower_right = NULL; /* demand create */ + + priv->texture = NULL; ++ priv->texture_right = NULL; + priv->mask_texture = NULL; + priv->create_mipmaps = TRUE; + priv->is_y_inverted = TRUE; +@@ -191,11 +195,11 @@ meta_shaped_texture_dispose (GObject *object) + MetaShapedTexture *self = (MetaShapedTexture *) object; + MetaShapedTexturePrivate *priv = self->priv; + +- if (priv->paint_tower) +- meta_texture_tower_free (priv->paint_tower); +- priv->paint_tower = NULL; ++ g_clear_pointer (&priv->paint_tower, meta_texture_tower_free); ++ g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free); + + g_clear_pointer (&priv->texture, cogl_object_unref); ++ g_clear_pointer (&priv->texture_right, cogl_object_unref); + g_clear_pointer (&priv->opaque_region, cairo_region_destroy); + + meta_shaped_texture_set_mask_texture (self, NULL); +@@ -326,8 +330,9 @@ paint_clipped_rectangle (CoglFramebuffer *fb, + } + + static void +-set_cogl_texture (MetaShapedTexture *stex, +- CoglTexture *cogl_tex) ++set_cogl_textures (MetaShapedTexture *stex, ++ CoglTexture *cogl_tex, ++ CoglTexture *cogl_tex_right) + { + MetaShapedTexturePrivate *priv; + guint width, height; +@@ -338,8 +343,11 @@ set_cogl_texture (MetaShapedTexture *stex, + + if (priv->texture) + cogl_object_unref (priv->texture); ++ if (priv->texture_right) ++ cogl_object_unref (priv->texture_right); + + priv->texture = cogl_tex; ++ priv->texture_right = cogl_tex_right; + + if (cogl_tex != NULL) + { +@@ -353,6 +361,9 @@ set_cogl_texture (MetaShapedTexture *stex, + height = 0; + } + ++ if (cogl_tex_right != NULL) ++ cogl_object_ref (cogl_tex_right); ++ + if (priv->tex_width != width || + priv->tex_height != height) + { +@@ -368,52 +379,41 @@ set_cogl_texture (MetaShapedTexture *stex, + * previous buffer. We only queue a redraw in response to surface + * damage. */ + ++ if (cogl_tex_right != NULL) ++ { ++ if (priv->paint_tower_right == NULL) ++ priv->paint_tower_right = meta_texture_tower_new (); ++ } ++ else ++ { ++ g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free); ++ } ++ + if (priv->create_mipmaps) +- meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex); ++ { ++ meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex); ++ ++ if (priv->paint_tower_right) ++ meta_texture_tower_set_base_texture (priv->paint_tower_right, cogl_tex_right); ++ } + } + + static void +-meta_shaped_texture_paint (ClutterActor *actor) ++paint_texture (MetaShapedTexture *stex, ++ CoglTexture *paint_tex) + { +- MetaShapedTexture *stex = (MetaShapedTexture *) actor; ++ ClutterActor *actor = CLUTTER_ACTOR (stex); + MetaShapedTexturePrivate *priv = stex->priv; + guint tex_width, tex_height; + guchar opacity; + CoglContext *ctx; + CoglFramebuffer *fb; +- CoglTexture *paint_tex; + ClutterActorBox alloc; + CoglPipelineFilter filter; + + if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) + return; + +- if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex))) +- clutter_actor_realize (CLUTTER_ACTOR (stex)); +- +- /* 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. +- */ +- if (priv->create_mipmaps) +- paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); +- else +- paint_tex = COGL_TEXTURE (priv->texture); +- +- if (paint_tex == NULL) +- return; +- + tex_width = priv->tex_width; + tex_height = priv->tex_height; + +@@ -574,6 +574,76 @@ meta_shaped_texture_paint (ClutterActor *actor) + } + + static void ++meta_shaped_texture_paint (ClutterActor *actor) ++{ ++ MetaShapedTexture *stex = (MetaShapedTexture *) actor; ++ MetaShapedTexturePrivate *priv = stex->priv; ++ CoglFramebuffer *fb; ++ gboolean stereo; ++ CoglTexture *paint_tex; ++ CoglTexture *paint_tex_right; ++ ++ if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) ++ return; ++ ++ if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex))) ++ clutter_actor_realize (CLUTTER_ACTOR (stex)); ++ ++ /* 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. ++ */ ++ if (priv->create_mipmaps) ++ paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); ++ else ++ paint_tex = COGL_TEXTURE (priv->texture); ++ ++ if (paint_tex == NULL) ++ return; ++ ++ fb = cogl_get_draw_framebuffer (); ++ ++ stereo = priv->texture_right && cogl_framebuffer_get_is_stereo (fb); ++ ++ if (stereo) ++ { ++ if (priv->create_mipmaps) ++ paint_tex_right = meta_texture_tower_get_paint_texture (priv->paint_tower_right); ++ else ++ paint_tex_right = COGL_TEXTURE (priv->texture_right); ++ } ++ else ++ paint_tex_right = NULL; ++ ++ if (paint_tex != NULL) ++ { ++ if (stereo) ++ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_LEFT); ++ paint_texture (stex, paint_tex); ++ if (stereo) ++ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH); ++ } ++ ++ if (paint_tex_right != NULL) ++ { ++ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_RIGHT); ++ paint_texture (stex, paint_tex_right); ++ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH); ++ } ++} ++ ++static void + meta_shaped_texture_get_preferred_width (ClutterActor *self, + gfloat for_height, + gfloat *min_width_p, +@@ -692,6 +762,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, + priv->create_mipmaps = create_mipmaps; + base_texture = create_mipmaps ? priv->texture : NULL; + meta_texture_tower_set_base_texture (priv->paint_tower, base_texture); ++ ++ if (priv->paint_tower_right) ++ { ++ base_texture = create_mipmaps ? priv->texture_right : NULL; ++ meta_texture_tower_set_base_texture (priv->paint_tower_right, base_texture); ++ } + } + } + +@@ -757,6 +833,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, + return FALSE; + + meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); ++ if (priv->paint_tower_right) ++ meta_texture_tower_update_area (priv->paint_tower_right, x, y, width, height); + + unobscured_region = effective_unobscured_region (stex); + if (unobscured_region) +@@ -789,17 +867,18 @@ 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)); + +- 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 551322573..6ca68eb64 100644 +--- a/src/compositor/meta-surface-actor-wayland.c ++++ b/src/compositor/meta-surface-actor-wayland.c +@@ -403,7 +403,7 @@ meta_surface_actor_wayland_dispose (GObject *object) + MetaShapedTexture *stex = + meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + +- meta_shaped_texture_set_texture (stex, NULL); ++ meta_shaped_texture_set_textures (stex, NULL, NULL); + if (priv->surface) + { + g_object_remove_weak_pointer (G_OBJECT (priv->surface), +@@ -462,6 +462,14 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface) + return META_SURFACE_ACTOR (self); + } + ++void ++meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self, ++ CoglTexture *texture) ++{ ++ MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); ++ meta_shaped_texture_set_textures (stex, texture, NULL); ++} ++ + MetaWaylandSurface * + meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self) + { +diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c +index d32aeb68a..52db3808e 100644 +--- a/src/compositor/meta-surface-actor-x11.c ++++ b/src/compositor/meta-surface-actor-x11.c +@@ -31,6 +31,7 @@ + #include + + #include ++#include "compositor-private.h" + #include "window-private.h" + #include "meta-shaped-texture-private.h" + #include "meta-cullable.h" +@@ -43,6 +44,7 @@ struct _MetaSurfaceActorX11Private + MetaDisplay *display; + + CoglTexture *texture; ++ CoglTexture *texture_right; + Pixmap pixmap; + Damage damage; + +@@ -58,6 +60,8 @@ struct _MetaSurfaceActorX11Private + guint size_changed : 1; + + guint unredirected : 1; ++ ++ guint stereo : 1; + }; + typedef struct _MetaSurfaceActorX11Private MetaSurfaceActorX11Private; + +@@ -94,7 +98,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_error_trap_push (display); +@@ -103,6 +107,7 @@ detach_pixmap (MetaSurfaceActorX11 *self) + meta_error_trap_pop (display); + + g_clear_pointer (&priv->texture, cogl_object_unref); ++ g_clear_pointer (&priv->texture_right, cogl_object_unref); + } + + static void +@@ -114,23 +119,35 @@ 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)); + CoglError *error = NULL; +- CoglTexture *texture; ++ CoglTexturePixmapX11 *texture; ++ CoglTexturePixmapX11 *texture_right; + + g_assert (priv->pixmap == None); + priv->pixmap = pixmap; + +- texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->pixmap, FALSE, &error)); ++ if (priv->stereo) ++ texture = cogl_texture_pixmap_x11_new_left (ctx, pixmap, FALSE, &error); ++ else ++ texture = cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, &error); ++ ++ if (priv->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); + cogl_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!\n"); + +- priv->texture = texture; +- meta_shaped_texture_set_texture (stex, texture); ++ priv->texture = COGL_TEXTURE (texture); ++ if (priv->stereo) ++ priv->texture_right = COGL_TEXTURE (texture_right); ++ ++ meta_shaped_texture_set_textures (stex, COGL_TEXTURE (texture), COGL_TEXTURE (texture_right)); + } + + static void +@@ -433,8 +450,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, priv->texture); ++ meta_shaped_texture_set_textures (stex, NULL, NULL); ++ meta_shaped_texture_set_textures (stex, priv->texture, priv->texture_right); + } + + MetaSurfaceActor * +@@ -443,12 +460,17 @@ meta_surface_actor_x11_new (MetaWindow *window) + MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); + MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); + MetaDisplay *display = meta_window_get_display (window); ++ Window xwindow; + + g_assert (!meta_is_wayland_compositor ()); + + priv->window = window; + priv->display = display; + ++ xwindow = meta_window_x11_get_toplevel_xwindow (window); ++ priv->stereo = meta_compositor_window_is_stereo (display->screen, xwindow); ++ meta_compositor_select_stereo_notify (display->screen, xwindow); ++ + g_signal_connect_object (priv->display, "gl-video-memory-purged", + G_CALLBACK (reset_texture), self, G_CONNECT_SWAPPED); + +@@ -479,3 +501,21 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + priv->last_height = height; + meta_shaped_texture_set_fallback_size (stex, width, height); + } ++ ++void ++meta_surface_actor_x11_stereo_notify (MetaSurfaceActorX11 *self, ++ gboolean stereo_tree) ++{ ++ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); ++ ++ priv->stereo = stereo_tree != FALSE; ++ detach_pixmap (self); ++} ++ ++gboolean ++meta_surface_actor_x11_is_stereo (MetaSurfaceActorX11 *self) ++{ ++ MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); ++ ++ return priv->stereo; ++} +diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h +index 0e692ee0f..4b2ecccb1 100644 +--- a/src/compositor/meta-surface-actor-x11.h ++++ b/src/compositor/meta-surface-actor-x11.h +@@ -64,6 +64,11 @@ MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window); + void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height); + ++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 72dcd1451..035d756b2 100644 +--- a/src/compositor/meta-window-actor-private.h ++++ b/src/compositor/meta-window-actor-private.h +@@ -59,4 +59,9 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor, + MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); + void meta_window_actor_update_surface (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 1184cd422..773e6d09d 100644 +--- a/src/compositor/meta-window-actor.c ++++ b/src/compositor/meta-window-actor.c +@@ -2150,3 +2150,25 @@ meta_window_actor_sync_updates_frozen (MetaWindowActor *self) + + meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window)); + } ++ ++void ++meta_window_actor_stereo_notify (MetaWindowActor *self, ++ gboolean stereo_tree) ++{ ++ MetaWindowActorPrivate *priv = self->priv; ++ ++ 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 = self->priv; ++ ++ 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 dc1f1c4f6..2c1160711 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -47,6 +47,7 @@ + #include + #include "util-private.h" + #include "display-private.h" ++#include "stereo.h" + #include + #include "ui.h" + #include +@@ -566,6 +567,9 @@ meta_init (void) + + meta_init_backend (backend_gtype); + ++ if (!meta_is_wayland_compositor ()) ++ meta_stereo_init (); ++ + meta_clutter_init (); + + #ifdef HAVE_WAYLAND +diff --git a/src/core/stereo.c b/src/core/stereo.c +new file mode 100644 +index 000000000..5a232b67c +--- /dev/null ++++ b/src/core/stereo.c +@@ -0,0 +1,153 @@ ++/* -*- 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 ++#include "ui.h" ++#include ++#include "display-private.h" ++#include "stereo.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_display_get_xdisplay (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 000000000..ccd1d702a +--- /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/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c +index 6f9df37da..d353ae5d0 100644 +--- a/src/wayland/meta-wayland-surface.c ++++ b/src/wayland/meta-wayland-surface.c +@@ -789,7 +789,7 @@ apply_pending_state (MetaWaylandSurface *surface, + snippet = meta_wayland_buffer_create_snippet (pending->buffer); + is_y_inverted = meta_wayland_buffer_is_y_inverted (pending->buffer); + +- meta_shaped_texture_set_texture (stex, texture); ++ meta_shaped_texture_set_textures (stex, texture, NULL); + meta_shaped_texture_set_snippet (stex, snippet); + meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted); + g_clear_pointer (&snippet, cogl_object_unref); +-- +2.14.2 + diff --git a/SOURCES/add-support-for-plain-old-x-device-configuration.patch b/SOURCES/add-support-for-plain-old-x-device-configuration.patch new file mode 100644 index 0000000..3198a09 --- /dev/null +++ b/SOURCES/add-support-for-plain-old-x-device-configuration.patch @@ -0,0 +1,400 @@ +From 81986e9b3c16efa170b2bb4fe2af05a30b9386b3 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 9 Oct 2017 18:37:11 +0200 +Subject: [PATCH 1/4] backends/x11: Fix a small memory leak + +Introduced in "backends/x11: Support synaptics configuration". +--- + src/backends/x11/meta-input-settings-x11.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 467a9b7..27995c8 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -222,6 +222,7 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device, + buttons[0] = left_handed ? 3 : 1; + buttons[2] = left_handed ? 1 : 3; + XSetDeviceButtonMapping (xdisplay, xdevice, buttons, n_buttons); ++ g_free (buttons); + + if (display && meta_error_trap_pop_with_return (display)) + { +-- +1.8.3.1 + + +From c3f4dc97cdb4f1b63e43e38daf02e676d207ad37 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 9 Oct 2017 18:39:52 +0200 +Subject: [PATCH 2/4] 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 27995c8..4c2709c 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -621,6 +621,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]) +-- +1.8.3.1 + + +From fd94f5fd842f0f0f9e4a28e69716a30669e2e848 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 9 Oct 2017 18:55:56 +0200 +Subject: [PATCH 3/4] 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 4c2709c..9a85f94 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 + #include "backends/meta-logical-monitor.h" +@@ -44,6 +47,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, +@@ -328,6 +333,107 @@ change_synaptics_speed (ClutterInputDevice *device, + XFreeFeedbackList (states); + } + ++/* 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, "syndaemon"); ++ g_ptr_array_add (args, "-i"); ++ g_ptr_array_add (args, "1.0"); ++ g_ptr_array_add (args, "-t"); ++ g_ptr_array_add (args, "-K"); ++ g_ptr_array_add (args, "-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, +@@ -452,6 +558,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); + } +-- +1.8.3.1 + + +From f5f9195fe23c0af8a498a13ca6bc5521a0c9e6ce Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Tue, 10 Oct 2017 19:07:27 +0200 +Subject: [PATCH 4/4] 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 | 96 +++++++++++++++++++++++------- + 1 file changed, 74 insertions(+), 22 deletions(-) + +diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c +index 9a85f94..cb4eb00 100644 +--- a/src/backends/x11/meta-input-settings-x11.c ++++ b/src/backends/x11/meta-input-settings-x11.c +@@ -179,35 +179,35 @@ 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 (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + XDevice *xdevice; +- guchar *tap_action, *buttons; ++ guchar *buttons; + guint buttons_capacity = 16, n_buttons; + + xdevice = device_ensure_xdevice (device); + if (!xdevice) + return; + +- 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); +- + if (display) + meta_error_trap_push (display); + buttons = g_new (guchar, buttons_capacity); +@@ -231,14 +231,37 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device, + + if (display && meta_error_trap_pop_with_return (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)); + } + } + + 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 (); + MetaBackend *backend = meta_get_backend (); +@@ -333,6 +356,23 @@ change_synaptics_speed (ClutterInputDevice *device, + XFreeFeedbackList (states); + } + ++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 +@@ -501,9 +541,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; + } + +@@ -545,6 +586,11 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings, + g_object_unref (settings); + return; + } ++ else if (!is_device_libinput (device)) ++ { ++ change_x_device_left_handed (device, enabled); ++ return; ++ } + + change_property (device, "libinput Left Handed Enabled", + XA_INTEGER, 8, &value, 1); +@@ -758,6 +804,12 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings, + ClutterInputDevice *device, + guint button) + { ++ if (!is_device_libinput (device)) ++ { ++ change_x_device_scroll_button (device, button); ++ return; ++ } ++ + change_property (device, "libinput Button Scrolling Button", + XA_INTEGER, 32, &button, 1); + } +-- +1.8.3.1 + diff --git a/SOURCES/deal-more-gracefully-with-oversized-windows.patch b/SOURCES/deal-more-gracefully-with-oversized-windows.patch new file mode 100644 index 0000000..477aded --- /dev/null +++ b/SOURCES/deal-more-gracefully-with-oversized-windows.patch @@ -0,0 +1,85 @@ +From 547af942e6a0586208dbc3f158a7ec2c14611ff8 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 1/8] 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 f5360ef9d..3b6203d6b 100644 +--- a/src/core/constraints.c ++++ b/src/core/constraints.c +@@ -106,6 +106,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; + +@@ -196,6 +197,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, +@@ -231,6 +236,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} + }; + +@@ -1674,3 +1680,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.14.2 + diff --git a/SOURCES/fix-session-save-crash.patch b/SOURCES/fix-session-save-crash.patch new file mode 100644 index 0000000..99534ae --- /dev/null +++ b/SOURCES/fix-session-save-crash.patch @@ -0,0 +1,92 @@ +From 0c9cb02111908409285991e4b0f44a4fdcf91eed Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 23 Jan 2018 11:43:09 +0100 +Subject: [PATCH 1/2] session: use initial workspace if no workspace set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Having “on_all_workspaces_requested” FALSE on a window does not imply a +workspace is set. + +If the X11 window is placed on a secondary monitor while workspaces +applies on primary monitor only (“workspaces-only-on-primary” set) then +“on_all_workspaces_requested” is FALSE while “on_all_workspaces“ is TRUE +and the associated workspace is NULL, leading to a crash when saving the +gnome-shell/mutter session. + +So if no workspace is set, use the “initial_workspace” instead to avoid +a NULL pointer dereference. + +https://bugzilla.gnome.org/show_bug.cgi?id=792818 +--- + src/x11/session.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/x11/session.c b/src/x11/session.c +index af64270a6..8b2a89f1c 100644 +--- a/src/x11/session.c ++++ b/src/x11/session.c +@@ -950,7 +950,10 @@ save_state (void) + fputs (" \n", outfile); + } else { + int n; +- n = meta_workspace_index (window->workspace); ++ if (window->workspace) ++ n = meta_workspace_index (window->workspace); ++ else ++ n = window->initial_workspace; + fprintf (outfile, + " \n", n); + } +-- +2.14.3 + + +From e2269448dcebd24f23bb8872590204819abc3ac0 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 29 Jan 2018 16:58:46 +0100 +Subject: [PATCH 2/2] =?UTF-8?q?x11/window:=20Mark=20restored=20workspace?= + =?UTF-8?q?=20as=20=E2=80=9Cset=E2=80=9D?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When a window's workspace is not NULL, on_all_workspace should be FALSE. +Similarly, when on_all_workspace is TRUE, the window workspace should be +NULL. + +This is an assumption in multiple places in the code, including when +setting the workspace state, the window is either added or removed from +all workspaces only if the window's workspace is NULL. + +This rule is initially enforced at creation in _meta_window_shared_new() +when a initial workspace is set. However, when the initial workspace is +set from the session info, the initial workspace is not marked as “set” +which leads to an assertion failure when unmanaging windows, because the +window is not removed from all the workspaces. + +When applying the session info to a window, mark the workspace as “set”. + +https://gitlab.gnome.org/GNOME/mutter/issues/4 + +Closes: #4 +--- + src/x11/window-x11.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c +index 36a5e70a3..9c8ef5d75 100644 +--- a/src/x11/window-x11.c ++++ b/src/x11/window-x11.c +@@ -466,6 +466,7 @@ meta_window_apply_session_info (MetaWindow *window, + MetaWorkspace *workspace = spaces->data; + + meta_window_change_workspace (window, workspace); ++ window->initial_workspace_set = TRUE; + + meta_topic (META_DEBUG_SM, + "Restoring saved window %s to workspace %d\n", +-- +2.14.3 + diff --git a/SOURCES/mutter-3.26.0-hybrid-gpus.patch b/SOURCES/mutter-3.26.0-hybrid-gpus.patch new file mode 100644 index 0000000..e0c314a --- /dev/null +++ b/SOURCES/mutter-3.26.0-hybrid-gpus.patch @@ -0,0 +1,12 @@ +diff -up mutter-3.26.0/src/backends/native/meta-launcher.c.hybrid mutter-3.26.0/src/backends/native/meta-launcher.c +--- mutter-3.26.0/src/backends/native/meta-launcher.c.hybrid 2017-09-18 15:55:56.673262947 +0100 ++++ mutter-3.26.0/src/backends/native/meta-launcher.c 2017-09-18 15:56:21.383167768 +0100 +@@ -363,7 +363,7 @@ get_primary_gpu_path (const gchar *seat_ + guint num_devices; + + num_devices = count_devices_with_connectors (seat_name, devices); +- if (num_devices != 1) ++ if (num_devices > 1) + goto out; + } + diff --git a/SOURCES/remember-saved-multi-monitor-configuration.patch b/SOURCES/remember-saved-multi-monitor-configuration.patch new file mode 100644 index 0000000..f658b0d --- /dev/null +++ b/SOURCES/remember-saved-multi-monitor-configuration.patch @@ -0,0 +1,160 @@ +From 702f204a281c6525da6bfcd2286d70b1ab6eab13 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Fri, 3 Nov 2017 15:58:02 +0800 +Subject: [PATCH 1/4] monitor-config-manager: Don't include closed laptop panel + in config key + +When deriving the list of disabled monitors when creating new monitors +configs, don't include the laptop panel if the lid is currently closed, +as we consider the laptop panel nonexistent when the laptop lid is +closed when it comes to configuration. + +The laptop panel connector(s) will either way be appropriately disabled +anyway, as the field listing disabled monitors in the configuration do +not affect actual CRTC/connector assignments. + +https://bugzilla.gnome.org/show_bug.cgi?id=788915 +--- + src/backends/meta-monitor-config-manager.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index 2fe620767..2a7287778 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -1308,6 +1308,10 @@ meta_monitors_config_new (MetaMonitorManager *monitor_manager, + MetaMonitor *monitor = l->data; + MetaMonitorSpec *monitor_spec; + ++ if (meta_monitor_manager_is_lid_closed (monitor_manager) && ++ meta_monitor_is_laptop_panel (monitor)) ++ continue; ++ + monitor_spec = meta_monitor_get_spec (monitor); + if (meta_logical_monitor_configs_have_monitor (logical_monitor_configs, + monitor_spec)) +-- +2.14.2 + +From 584e2b93d9f28557cfe8a6ff720b4c3e45c458ab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Fri, 3 Nov 2017 16:03:23 +0800 +Subject: [PATCH 2/4] monitor-manager: Compare keys when checking whether a + config is complete + +We only counted configured monitors and whether the config was +applicable (could be assigned), howeverwe didn't include disabled +monitors when comparing. This could caused incorrect configurations to +be applied when trying to use the previous configuration. + +One scenario where this happened was one a system with one laptop +screen and one external monitor that was hot plugged some point after +start up. When the laptop lid was closed, the 'previous configuration' +being the configuration where only the laptop panel was enabled, passed +'is-complete' check as the number of configured monitors were correct, +and the configuration was applicable. + +Avoid this issue by simply comparing the configuration key of the +previous configuration and the configuration key of the current state. +This correctly identifies a laptop panel with the lid closed as +inaccessible, thus doesn't incorrectly revert to the previous +configuration. + +https://bugzilla.gnome.org/show_bug.cgi?id=788915 +--- + src/backends/meta-monitor-config-manager.c | 7 +++--- + src/backends/meta-monitor-config-manager.h | 2 ++ + src/backends/meta-monitor-manager.c | 36 +++++++++--------------------- + 3 files changed, 16 insertions(+), 29 deletions(-) + +diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c +index 2a7287778..bdf863055 100644 +--- a/src/backends/meta-monitor-config-manager.c ++++ b/src/backends/meta-monitor-config-manager.c +@@ -326,8 +326,8 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager, + return TRUE; + } + +-static MetaMonitorsConfigKey * +-create_key_for_current_state (MetaMonitorManager *monitor_manager) ++MetaMonitorsConfigKey * ++meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager) + { + MetaMonitorsConfigKey *config_key; + GList *l; +@@ -369,7 +369,8 @@ meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager + MetaMonitorsConfig *config; + GError *error = NULL; + +- config_key = create_key_for_current_state (monitor_manager); ++ config_key = ++ meta_create_monitors_config_key_for_current_state (monitor_manager); + if (!config_key) + return NULL; + +diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h +index 516909dd7..c36df38e6 100644 +--- a/src/backends/meta-monitor-config-manager.h ++++ b/src/backends/meta-monitor-config-manager.h +@@ -136,6 +136,8 @@ void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor + + void meta_monitor_config_free (MetaMonitorConfig *monitor_config); + ++MetaMonitorsConfigKey * meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager); ++ + gboolean meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs, + MetaMonitorSpec *monitor_spec); + +diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c +index 8b548fd68..eb3612cf0 100644 +--- a/src/backends/meta-monitor-manager.c ++++ b/src/backends/meta-monitor-manager.c +@@ -1551,35 +1551,19 @@ static gboolean + meta_monitor_manager_is_config_complete (MetaMonitorManager *manager, + MetaMonitorsConfig *config) + { +- GList *l; +- unsigned int configured_monitor_count = 0; +- unsigned int expected_monitor_count = 0; +- +- for (l = config->logical_monitor_configs; l; l = l->next) +- { +- MetaLogicalMonitorConfig *logical_monitor_config = l->data; +- GList *k; ++ MetaMonitorsConfigKey *current_state_key; ++ gboolean is_config_complete; + +- for (k = logical_monitor_config->monitor_configs; k; k = k->next) +- configured_monitor_count++; +- } +- +- for (l = manager->monitors; l; l = l->next) +- { +- MetaMonitor *monitor = l->data; ++ current_state_key = ++ meta_create_monitors_config_key_for_current_state (manager); ++ if (!current_state_key) ++ return FALSE; + +- if (meta_monitor_is_laptop_panel (monitor)) +- { +- if (!meta_monitor_manager_is_lid_closed (manager)) +- expected_monitor_count++; +- } +- else +- { +- expected_monitor_count++; +- } +- } ++ is_config_complete = meta_monitors_config_key_equal (current_state_key, ++ config->key); ++ meta_monitors_config_key_free (current_state_key); + +- if (configured_monitor_count != expected_monitor_count) ++ if (!is_config_complete) + return FALSE; + + return meta_monitor_manager_is_config_applicable (manager, config, NULL); +-- +2.14.2 + diff --git a/SOURCES/startup-notification.patch b/SOURCES/startup-notification.patch new file mode 100644 index 0000000..1a4dd0b --- /dev/null +++ b/SOURCES/startup-notification.patch @@ -0,0 +1,45 @@ +From 4ed430b4ef3013c96fa56cdc57b925b42d20ead9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 20 Oct 2016 18:00:04 +0200 +Subject: [PATCH] gtk-shell: Work around non-working startup notifications + +GNOME Shell relies on the MetaScreen::startup-sequence-changed signal, +which is tied to (lib)startup-notification and therefore X11. As a result, +when we remove the startup sequence of a wayland client, GNOME Shell will +not be notified about this until startup-notification's timeout is hit. +As a temporary stop-gap, go through XWayland even for wayland clients, +so that the signal is emitted when expected. + +https://bugzilla.gnome.org/show_bug.cgi?id=768531 +--- + src/wayland/meta-wayland-gtk-shell.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/wayland/meta-wayland-gtk-shell.c b/src/wayland/meta-wayland-gtk-shell.c +index d6e249f..9d1a19e 100644 +--- a/src/wayland/meta-wayland-gtk-shell.c ++++ b/src/wayland/meta-wayland-gtk-shell.c +@@ -219,11 +219,21 @@ gtk_shell_set_startup_id (struct wl_client *client, + struct wl_resource *resource, + const char *startup_id) + { ++#if 0 + MetaDisplay *display; + + display = meta_get_display (); + meta_startup_notification_remove_sequence (display->startup_notification, + startup_id); ++#else ++ /* HACK: MetaScreen::startup-sequence-changed is currently tied to ++ (lib)startup-notification, which means it only works on X11; ++ so for now, always go through XWayland, even for wayland clients */ ++ gdk_x11_display_broadcast_startup_message (gdk_display_get_default (), ++ "remove", ++ "ID", startup_id, ++ NULL); ++#endif + } + + static void +-- +2.9.3 diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec new file mode 100644 index 0000000..af086a5 --- /dev/null +++ b/SPECS/mutter.spec @@ -0,0 +1,845 @@ +%global gtk3_version 3.19.8 +%global glib_version 2.53.2 +%global gsettings_desktop_schemas_version 3.21.4 +%global json_glib_version 0.12.0 +%global libinput_version 1.4 +%global wayland_protocols_version 1.9.0 + +%ifarch s390 s390x +%global disable_wayland --disable-wayland-egl-server --disable-wayland --disable-native-backend +%endif + +Name: mutter +Version: 3.26.2 +Release: 13%{?dist} +Summary: Window and compositing manager based on Clutter + +License: GPLv2+ +#VCS: git:git://git.gnome.org/mutter +URL: http://www.gnome.org +Source0: http://download.gnome.org/sources/%{name}/3.26/%{name}-%{version}.tar.xz + +Patch0: startup-notification.patch + +Patch1: deal-more-gracefully-with-oversized-windows.patch + +Patch2: 0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch +Patch3: 0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch +Patch4: 0001-monitor-manager-Consider-external-layout-before-defa.patch + +Patch5: 0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch +Patch6: 0001-backends-x11-Support-synaptics-configuration.patch + +Patch7: 0001-window-actor-Special-case-shaped-Java-windows.patch + +Patch8: 0001-backends-x11-Preserve-XI1-XDevice-throughout-Clutter.patch +Patch9: 0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch +Patch10: 0001-backends-x11-wacom-pressure-curve-is-a-32-bit-proper.patch + +Patch11: 0001-renderer-x11-Enable-GPU-memory-purge-error-extension.patch +Patch12: 0001-backends-Monitor-changes-in-active-tools-settings.patch +Patch13: 0001-clutter-x11-Implement-missing-ClutterInputDevice-pad.patch + +# http://bugzilla.gnome.org/show_bug.cgi?id=733277 +Patch20: 0008-Add-support-for-quad-buffer-stereo.patch +Patch21: 0001-build-Lower-automake-requirement.patch + +# el7 patches +Patch100: 0001-Revert-build-Require-libgudev-232.patch +Patch101: 0001-rhel7-Fix-build-for-el7.patch +Patch102: mutter-3.26.0-hybrid-gpus.patch +Patch103: 0001-wayland-enable-scale-monitor-framebuffer-by-default.patch +Patch104: add-support-for-plain-old-x-device-configuration.patch +Patch105: remember-saved-multi-monitor-configuration.patch +Patch106: 0003-window-wayland-Handle-resizing-when-headless.patch +Patch107: fix-session-save-crash.patch +Patch108: 0001-wayland-Do-not-fail-on-stalled-.X11-unix-entries.patch +Patch109: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch + +Patch500: 0001-clutter-stage-don-t-use-deprecated-api.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: pam-devel +BuildRequires: upower-devel +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: automake, autoconf, libtool +BuildRequires: pkgconfig(gudev-1.0) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(gbm) +BuildRequires: pkgconfig(wayland-server) + +BuildRequires: json-glib-devel >= %{json_glib_version} +BuildRequires: libgudev1-devel +%ifnarch s390 s390x +BuildRequires: libwayland-server-devel +BuildRequires: libinput-devel >= %{libinput_version} +BuildRequires: wayland-protocols-devel >= %{wayland_protocols_version} +%endif + +Obsoletes: mutter-wayland < 3.13.0 +Obsoletes: mutter-wayland-devel < 3.13.0 + +# Make sure yum updates gnome-shell as well; otherwise we might end up with +# broken gnome-shell installations due to mutter ABI changes. +Conflicts: gnome-shell < 3.21.1 + +Requires: control-center-filesystem +Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas_version} +Requires: gtk3%{?_isa} >= %{gtk3_version} +Requires: startup-notification +Requires: dbus-x11 +Requires: zenity + +Requires: json-glib%{?_isa} >= %{json_glib_version} + +%ifnarch s390 s390x +Requires: libinput%{?_isa} >= %{libinput_version} +%endif + +%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. + +%prep +%autosetup -S git + +%build +autoreconf -f -i +(if ! test -x configure; then NOCONFIGURE=1 ./autogen.sh; fi; + %configure --disable-static %{?disable_wayland} --enable-compile-warnings=maximum --with-libwacom) + +SHOULD_HAVE_DEFINED="HAVE_SM HAVE_RANDR HAVE_STARTUP_NOTIFICATION" + +for I in $SHOULD_HAVE_DEFINED; do + if ! grep -q "define $I" config.h; then + echo "$I was not defined in config.h" + grep "$I" config.h + exit 1 + else + echo "$I was defined as it should have been" + grep "$I" config.h + fi +done + +make %{?_smp_mflags} V=1 + +%install +%make_install + +#Remove libtool archives. +rm -rf %{buildroot}/%{_libdir}/*.la + +%find_lang %{name} + +# Mutter contains a .desktop file so we just need to validate it +desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop + +%post -p /sbin/ldconfig + +%postun +/sbin/ldconfig +if [ $1 -eq 0 ]; then + glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : +fi + +%posttrans +glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : + +%files -f %{name}.lang +%license COPYING +%doc NEWS +%{_bindir}/mutter +%{_datadir}/applications/*.desktop +%{_libdir}/lib*.so.* +%{_libdir}/mutter/ +%{_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* + +%files devel +%{_includedir}/* +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/* + +%changelog +* Fri Feb 23 2018 Carlos Garnacho - 3.26.2-13 +- Fix pad ring/strip modes + Resolves: #1543633 + +* Mon Feb 19 2018 Carlos Garnacho - 3.26.2-12 +- Apply settings on current stylus tools instantly + Resolves: #1543693 + +* Wed Feb 14 2018 Jonas Ådahl - 3.26.2-11 +- Fix GPU memory purge error handling + Resolves: #1542375 + +* Tue Feb 13 2018 Carlos Garnacho - 3.26.2-10 +- Detect CLUTTER_TOUCHPAD_DEVICE on all Synaptics devices + Resolves: #1499788 +- Fix tablet pressure curve configuration not being applied + Resolves: #1543693 + +* Tue Feb 13 2018 Ray Strode - 3.26.2-9 +- Fix VNC sessions + Resolves: #1543073 + +* Wed Feb 07 2018 Carlos Garnacho - 3.26.2-8 +- Avoid XCloseDevice on active XI2 devices + Resolves: #1540790 + +* Wed Feb 07 2018 Florian Müllner - 3.26.2-7 +- Fix crash during session saving + Resolves: #1535080 +- Fix XWayland prevented from starting + Resolves: #1540986 + +* Wed Nov 29 2017 Rui Matos - 3.26.2-6 +- Fix a crash resizing windows while headless + Resolves: #1516408 + +* Wed Nov 29 2017 Rui Matos - 3.26.2-5 +- Fix for certain multi-monitor configurations not being remembered + Resolves: #1516404 + +* Wed Nov 08 2017 Ray Strode - 3.26.2-4 +- Fix crash with screen recorder + Resolves: #1508903 + +* Tue Nov 7 2017 Rui Matos - 3.26.2-3 +- Fix external monitor layout patch to avoid a crash +- Resolves: #1481386 + +* Mon Nov 6 2017 Rui Matos - 3.26.2-2 +- Fix stereo patch to fail gracefully on Xwayland +- Resolves: #1481386 + +* Fri Nov 03 2017 Kalev Lember - 3.26.2-1 +- Update to 3.26.2 +- Resolves: #1481386 + +* Thu Oct 26 2017 Rui Matos - 3.26.1-2 +- Add support for plain old X device configuration + Resolves: #1478397 + +* Fri Oct 06 2017 Florian Müllner - 3.26.1-1 +- Update to 3.26.1 + Resolves: #1481386 + +* Mon Jun 26 2017 Florian Müllner - 3.24.3-11 +- Prevent crash when removing workspace with on-all-workspaces windows + present (like desktop icons) +- Resolves: #1453065 + +* Wed Jun 14 2017 Florian Müllner - 3.24.3-10 +- Keep OR windows stacked on top +- Resolves: #1437203 + +* Thu Jun 08 2017 Florian Müllner - 3.24.3-9 +- Fix crash when a window closes during Alt+Tab +- Resolves: #1438722 + +* Tue May 16 2017 Florian Müllner - 3.24.3-8 +- Special-case shaped java windows to fix OpenJDK's compliance test +- Resolves: #1363784 + +* Fri Apr 28 2017 Florian Müllner - 3.24.3-7 +- Fix cally translation of screen coordinates +- Resolves: #1439194 + +* Fri Mar 17 2017 Florian Müllner - 3.22.3-6 +- Recreate build files after modifying templates with the last patch +- Resolves: #1387025 + +* Thu Mar 16 2017 Owen Taylor - 3.22.3-6 +- Add back quad-buffer stereo patches, rebased to 3.22 +- Resolves: #1387025 + +* Wed Mar 15 2017 Carlos Garnacho - 3.22.3-5 +- Swizzle BGRA buffers to avoid pixel conversions +- Resolves: #1387025 + +* Tue Mar 14 2017 Florian Müllner - 3.22.3-4 +- Don't segfault on early exit +- Resolves: #1369073 + +* Mon Mar 13 2017 Carlos Garnacho - 3.22.3-3 +- Handle synaptics settings +- Resolves: #1387025 + +* Mon Mar 13 2017 Florian Müllner - 3.22.3-2 +- Re-add downstream patches +- Resolves: #1387025 + +* Thu Feb 16 2017 Kalev Lember - 3.22.3-1 +- Update to 3.22.3 +- Resolves: #1387025 + +* Fri Feb 03 2017 Kalev Lember - 3.22.2-1 +- Update to 3.22.2 +- Resolves: #1387025 + +* Fri Sep 16 2016 Florian Müllner - 3.14.4-31 +- Make meta_window_actor_update_visibility() public + Related: #1306670 + +* Mon Aug 29 2016 Owen Taylor - 3.14.4-29 +- Allow clutter to fallback to the classic gl driver since mesa's + software driver doesn't support gl3 + Related: #1361251 + +* Thu Aug 11 2016 Rui Matos - 3.14.4-28 +- Add patch to require clutter to use the gl3 driver + Resolves: #1361251 + +* Mon Jul 18 2016 Rui Matos - 3.14.4-27 +- Require a clutter version that provides all the new APIs + Related: rhbz#1330488 + +* Thu Jun 30 2016 Owen Taylor - 3.14.4-26 +- Turn on newly added "threaded swap wait" functionality in Cogl + so that on NVIDIA cards, frame completion is handled in a proper + non-blocking fashion, fixing bugs with idles not running when + they should. + Resolves: #1305076 + +* Wed Jun 29 2016 Rui Matos - 3.14.4-25 +- Handle video memory purge errors + Resolves: #1330488 + +* Tue Jun 28 2016 Florian Müllner - 3.14.4-24 +- Update translations + Resolves: #1304233 + +* Fri Jun 17 2016 Florian Müllner - 3.14.4-23 +- Track ignored damage + Resolves: #1165840 + +* Thu May 19 2016 Florian Müllner - 3.14.4-22 +- Support external monitor layout configuration + Related: #1290448 + +* Thu May 12 2016 Florian Müllner - 3.14.4-21 +- Ignore window groups for stacking + Resolves: #1167889 + +* Tue May 10 2016 Owen Taylor - 3.14.4-20 +- Rebase and add back stereo support patch that was dropped in + update to 3.14. +- Retain the last active window for seamless restarts. + Resolves: #1305076 + +* Thu Apr 21 2016 Florian Müllner - 3.14.4-19 +- Make Cogl errors non-fatal + Related: #1326372 + +* Wed Apr 20 2016 Carlos Garnacho - 3.14.4-18 +- Fix unredirected windows being transparent to input in sloppy focus + Resolves: #1299616 + +* Mon Oct 26 2015 Rui Matos - 3.14.4-17 +- Fix a crash when plugging monitors + Resolves: #1275215 +- Avoid a critical message when unplugging monitors + Resolves: #1275220 +- Fix monitors remaining undetected on resume from suspend + Resolves: #1219476 + +* Fri Oct 16 2015 Florian Müllner - 3.14.4-16 +- Fix crash during session saving when saving sticky windows + Related: #1272106 + +* Tue Oct 6 2015 Rui Matos - 3.14.4-15 +- Fix integer sign oversight in the previous patch + Related: #1265511 + +* Tue Oct 6 2015 Rui Matos - 3.14.4-14 +- Add a couple of fixes for Xvnc resolution changes + Resolves: #1265511 + +* Thu Oct 01 2015 Florian Müllner - 3.14.4-13 +- Fix a couple more errors in headless mode + Related: #1212702 + +* Fri Sep 04 2015 Florian Müllner - 3.14.4-12 +- Fix maximum potential number of monitors + Resolves: #1260082 + +* Thu Sep 03 2015 Florian Müllner - 3.14.4-11 +- Fix screen flicking issue with propriertary NVidia drivers + Resolves: #1258842 + +* Thu Jul 30 2015 Florian Müllner - 3.14.4-10 +- Fix placement of fullscreen windows + Resolves: #1247718 + +* Fri Jul 24 2015 Florian Müllner - 3.14.4-9 +- Fix some more headless-mode warnings + Related: #1212702 + +* Fri Jul 24 2015 Florian Müllner - 3.14.4-8 +- Fix focus_serial overflow + Resolves: #1236113 + +* Tue Jul 21 2015 Matthias Clasen - 3.14.4-7 +- Fix coverity spotted bugs + Related #1174722 + +* Fri Jul 17 2015 Florian Müllner - 3.14.4-6 +- Fix oversight in headless-mode backport + Resolves: #1212702 + +* Thu Jul 16 2015 Florian Müllner - 3.14.4-5 +- Support headless mode + Resolves: #1212702 + +* Fri Jul 10 2015 Florian Müllner - 3.14.4-4 +- Don't try to focus hidden windows + Related: #1174722 + +* Thu May 21 2015 Florian Müllner - 3.14.4-3 +- support suggested output position + Resolves: rhbz#1166319 + +* Wed May 06 2015 Ray Strode 3.14.4-2 +- rebuild against new gnome-desktop3 + Related: #1174722 + +* Tue Mar 24 2015 Florian Müllner - 3.14.4-1 +- Drop obsolete patches, rebase still relevant one + +* Mon Mar 23 2015 Richard Hughes - 3.14.3-1 +- Update to 3.14.3 +- Resolves: #1174722 + +* Wed Jan 14 2015 Florian Müllner - 3.8.4.16 +- Fix window placement regression + Resolves: rhbz#1153641 + +* Thu Nov 13 2014 Florian Müllner - 3.8.4-15 +- Fix delayed mouse mode + Resolves: rhbz#1149585 + +* Thu Oct 09 2014 Florian Müllner - 3.8.4-14 +- Preserve window placement on monitor changes + Resolves: rhbz#1126754 + +* Thu Oct 09 2014 Florian Müllner - 3.8.4-13 +- Improve handling of vertical monitor layouts + Resolves: rhbz#1108322 + +* Thu Jul 17 2014 Owen Taylor 3.8.4-13 +- Add patches for quadbuffer stereo suppport + Fix a bad performance problem drawing window thumbnails + Resolves: rhbz#861507 + +* Tue Mar 11 2014 Florian Müllner - 3.8.4-10 +- Fix crash when encountering over-sized windows + Resolves: #1027832 + +* Tue Mar 11 2014 Florian Müllner - 3.8.4-10 +- Backport another minor memory leak fix + Resolves: #1067456 + +* Tue Mar 11 2014 Debarshi Ray - 3.8.4-9 +- Do not save pixbuf in user data + Resolves: #1067456 + +* Wed Feb 12 2014 Carlos Garnacho - 3.8.4-8 +- Fix window dragging on touchscreens + Resolves: #1051006 + +* Tue Feb 11 2014 Owen Taylor - 3.8.4-7 +- Add an upstream patch that fixes a bug with left-over window + shadows that show up when we add patches to Clutter to stop + redrawing the entire screen on every window move. + Resolves: rhbz#1063984 + +* Fri Jan 24 2014 Daniel Mach - 3.8.4-6 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 3.8.4-5 +- Mass rebuild 2013-12-27 + +* Thu Nov 28 2013 Florian Müllner - 3.8.4-4 +- Include translation updates + Resolves: rhbz#1030369 + +* Mon Nov 11 2013 Florian Müllner - 3.8.4-3 +- Backport allowing sliced textures for large backgrounds + Resolves: rhbz#1028586 + +* Thu Oct 31 2013 Florian Müllner - 3.8.4-2 +- Backport performance improvements for software rendering from 3.10 + +* Tue Jul 30 2013 Ray Strode 3.8.4-1 +- Update to 3.8.4 + +* Tue Jul 02 2013 Florian Müllner - 3.8.3-2 +- Rebuild with (re-)fixed download URL + +* Fri Jun 07 2013 Florian Müllner - 3.8.3-1 +- Update to 3.8.3 + +* Tue May 14 2013 Florian Müllner - 3.8.2-1 +- Update to 3.8.2 + +* Tue Apr 16 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