|
|
2c033f |
From 0a205c86df3422c4918d225c29adc0a06bc4e2d5 Mon Sep 17 00:00:00 2001
|
|
|
2c033f |
From: Rui Matos <tiagomatos@gmail.com>
|
|
|
2c033f |
Date: Sun, 25 Oct 2015 16:14:58 +0100
|
|
|
2c033f |
Subject: [PATCH 4/4] monitor-manager-xrandr: Force an update when resuming
|
|
|
2c033f |
from suspend
|
|
|
2c033f |
|
|
|
2c033f |
The stack below us isn't as reliable as we'd like and in some cases
|
|
|
2c033f |
doesn't generate RRScreenChangeNotify events when e.g. resuming a
|
|
|
2c033f |
laptop on a dock, meaning that we'd miss newly attached outputs.
|
|
|
2c033f |
---
|
|
|
2c033f |
src/backends/x11/meta-monitor-manager-xrandr.c | 215 +++++++++++++++++--------
|
|
|
2c033f |
1 file changed, 151 insertions(+), 64 deletions(-)
|
|
|
2c033f |
|
|
|
2c033f |
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
2c033f |
index 9a64bb2..d2a5df2 100644
|
|
|
2c033f |
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
2c033f |
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
2c033f |
@@ -59,6 +59,11 @@ struct _MetaMonitorManagerXrandr
|
|
|
2c033f |
XRRScreenResources *resources;
|
|
|
2c033f |
int rr_event_base;
|
|
|
2c033f |
int rr_error_base;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ guint logind_watch_id;
|
|
|
2c033f |
+ guint logind_signal_sub_id;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ gboolean need_hardware_poll;
|
|
|
2c033f |
};
|
|
|
2c033f |
|
|
|
2c033f |
struct _MetaMonitorManagerXrandrClass
|
|
|
2c033f |
@@ -506,8 +511,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
|
|
2c033f |
manager->screen_width = WidthOfScreen (screen);
|
|
|
2c033f |
manager->screen_height = HeightOfScreen (screen);
|
|
|
2c033f |
|
|
|
2c033f |
- resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay,
|
|
|
2c033f |
- DefaultRootWindow (manager_xrandr->xdisplay));
|
|
|
2c033f |
+ if (manager_xrandr->need_hardware_poll)
|
|
|
2c033f |
+ {
|
|
|
2c033f |
+ resources = XRRGetScreenResources (manager_xrandr->xdisplay,
|
|
|
2c033f |
+ DefaultRootWindow (manager_xrandr->xdisplay));
|
|
|
2c033f |
+ manager_xrandr->need_hardware_poll = FALSE;
|
|
|
2c033f |
+ }
|
|
|
2c033f |
+ else
|
|
|
2c033f |
+ resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay,
|
|
|
2c033f |
+ DefaultRootWindow (manager_xrandr->xdisplay));
|
|
|
2c033f |
if (!resources)
|
|
|
2c033f |
return;
|
|
|
2c033f |
|
|
|
2c033f |
@@ -1083,60 +1095,6 @@ meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager)
|
|
|
2c033f |
meta_monitor_manager_rebuild_derived (manager);
|
|
|
2c033f |
}
|
|
|
2c033f |
|
|
|
2c033f |
-static void
|
|
|
2c033f |
-meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
2c033f |
-{
|
|
|
2c033f |
- MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
|
|
2c033f |
-
|
|
|
2c033f |
- manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend);
|
|
|
2c033f |
-
|
|
|
2c033f |
- if (!XRRQueryExtension (manager_xrandr->xdisplay,
|
|
|
2c033f |
- &manager_xrandr->rr_event_base,
|
|
|
2c033f |
- &manager_xrandr->rr_error_base))
|
|
|
2c033f |
- {
|
|
|
2c033f |
- return;
|
|
|
2c033f |
- }
|
|
|
2c033f |
- else
|
|
|
2c033f |
- {
|
|
|
2c033f |
- /* We only use ScreenChangeNotify, but GDK uses the others,
|
|
|
2c033f |
- and we don't want to step on its toes */
|
|
|
2c033f |
- XRRSelectInput (manager_xrandr->xdisplay,
|
|
|
2c033f |
- DefaultRootWindow (manager_xrandr->xdisplay),
|
|
|
2c033f |
- RRScreenChangeNotifyMask
|
|
|
2c033f |
- | RRCrtcChangeNotifyMask
|
|
|
2c033f |
- | RROutputPropertyNotifyMask);
|
|
|
2c033f |
- }
|
|
|
2c033f |
-}
|
|
|
2c033f |
-
|
|
|
2c033f |
-static void
|
|
|
2c033f |
-meta_monitor_manager_xrandr_finalize (GObject *object)
|
|
|
2c033f |
-{
|
|
|
2c033f |
- MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object);
|
|
|
2c033f |
-
|
|
|
2c033f |
- if (manager_xrandr->resources)
|
|
|
2c033f |
- XRRFreeScreenResources (manager_xrandr->resources);
|
|
|
2c033f |
- manager_xrandr->resources = NULL;
|
|
|
2c033f |
-
|
|
|
2c033f |
- G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
|
|
|
2c033f |
-}
|
|
|
2c033f |
-
|
|
|
2c033f |
-static void
|
|
|
2c033f |
-meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
|
|
|
2c033f |
-{
|
|
|
2c033f |
- MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
|
|
|
2c033f |
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
2c033f |
-
|
|
|
2c033f |
- object_class->finalize = meta_monitor_manager_xrandr_finalize;
|
|
|
2c033f |
-
|
|
|
2c033f |
- manager_class->read_current = meta_monitor_manager_xrandr_read_current;
|
|
|
2c033f |
- manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
|
|
|
2c033f |
- manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration;
|
|
|
2c033f |
- manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;
|
|
|
2c033f |
- manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
|
|
|
2c033f |
- manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
|
|
|
2c033f |
- manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
|
|
|
2c033f |
-}
|
|
|
2c033f |
-
|
|
|
2c033f |
static gboolean
|
|
|
2c033f |
is_xvnc (MetaMonitorManager *manager)
|
|
|
2c033f |
{
|
|
|
2c033f |
@@ -1149,9 +1107,8 @@ is_xvnc (MetaMonitorManager *manager)
|
|
|
2c033f |
return FALSE;
|
|
|
2c033f |
}
|
|
|
2c033f |
|
|
|
2c033f |
-gboolean
|
|
|
2c033f |
-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
|
|
2c033f |
- XEvent *event)
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
2c033f |
{
|
|
|
2c033f |
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
|
|
2c033f |
MetaOutput *old_outputs;
|
|
|
2c033f |
@@ -1162,11 +1119,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
|
|
2c033f |
gboolean applied_config = FALSE;
|
|
|
2c033f |
unsigned int timestamp;
|
|
|
2c033f |
|
|
|
2c033f |
- if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
|
|
2c033f |
- return FALSE;
|
|
|
2c033f |
-
|
|
|
2c033f |
- XRRUpdateConfiguration (event);
|
|
|
2c033f |
-
|
|
|
2c033f |
/* Save the old structures, so they stay valid during the update */
|
|
|
2c033f |
old_outputs = manager->outputs;
|
|
|
2c033f |
n_old_outputs = manager->n_outputs;
|
|
|
2c033f |
@@ -1210,6 +1162,141 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
|
|
2c033f |
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
|
|
|
2c033f |
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
|
|
|
2c033f |
g_free (old_crtcs);
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+logind_signal_handler (GDBusConnection *connection,
|
|
|
2c033f |
+ const gchar *sender_name,
|
|
|
2c033f |
+ const gchar *object_path,
|
|
|
2c033f |
+ const gchar *interface_name,
|
|
|
2c033f |
+ const gchar *signal_name,
|
|
|
2c033f |
+ GVariant *parameters,
|
|
|
2c033f |
+ gpointer user_data)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
2c033f |
+ gboolean suspending;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ if (!g_str_equal (signal_name, "PrepareForSleep"))
|
|
|
2c033f |
+ return;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ g_variant_get (parameters, "(b)", &suspending);
|
|
|
2c033f |
+ if (!suspending)
|
|
|
2c033f |
+ {
|
|
|
2c033f |
+ manager_xrandr->need_hardware_poll = TRUE;
|
|
|
2c033f |
+ meta_monitor_manager_xrandr_update (manager_xrandr);
|
|
|
2c033f |
+ }
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+logind_appeared (GDBusConnection *connection,
|
|
|
2c033f |
+ const gchar *name,
|
|
|
2c033f |
+ const gchar *name_owner,
|
|
|
2c033f |
+ gpointer user_data)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection,
|
|
|
2c033f |
+ "org.freedesktop.login1",
|
|
|
2c033f |
+ "org.freedesktop.login1.Manager",
|
|
|
2c033f |
+ "PrepareForSleep",
|
|
|
2c033f |
+ "/org/freedesktop/login1",
|
|
|
2c033f |
+ NULL,
|
|
|
2c033f |
+ G_DBUS_SIGNAL_FLAGS_NONE,
|
|
|
2c033f |
+ logind_signal_handler,
|
|
|
2c033f |
+ manager_xrandr,
|
|
|
2c033f |
+ NULL);
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+logind_vanished (GDBusConnection *connection,
|
|
|
2c033f |
+ const gchar *name,
|
|
|
2c033f |
+ gpointer user_data)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ if (connection && manager_xrandr->logind_signal_sub_id > 0)
|
|
|
2c033f |
+ g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id);
|
|
|
2c033f |
+
|
|
|
2c033f |
+ manager_xrandr->logind_signal_sub_id = 0;
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
|
|
2c033f |
+
|
|
|
2c033f |
+ manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend);
|
|
|
2c033f |
+
|
|
|
2c033f |
+ if (!XRRQueryExtension (manager_xrandr->xdisplay,
|
|
|
2c033f |
+ &manager_xrandr->rr_event_base,
|
|
|
2c033f |
+ &manager_xrandr->rr_error_base))
|
|
|
2c033f |
+ {
|
|
|
2c033f |
+ return;
|
|
|
2c033f |
+ }
|
|
|
2c033f |
+ else
|
|
|
2c033f |
+ {
|
|
|
2c033f |
+ /* We only use ScreenChangeNotify, but GDK uses the others,
|
|
|
2c033f |
+ and we don't want to step on its toes */
|
|
|
2c033f |
+ XRRSelectInput (manager_xrandr->xdisplay,
|
|
|
2c033f |
+ DefaultRootWindow (manager_xrandr->xdisplay),
|
|
|
2c033f |
+ RRScreenChangeNotifyMask
|
|
|
2c033f |
+ | RRCrtcChangeNotifyMask
|
|
|
2c033f |
+ | RROutputPropertyNotifyMask);
|
|
|
2c033f |
+ }
|
|
|
2c033f |
+
|
|
|
2c033f |
+ manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
|
|
|
2c033f |
+ "org.freedesktop.login1",
|
|
|
2c033f |
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
|
|
|
2c033f |
+ logind_appeared,
|
|
|
2c033f |
+ logind_vanished,
|
|
|
2c033f |
+ manager_xrandr,
|
|
|
2c033f |
+ NULL);
|
|
|
2c033f |
+ manager_xrandr->need_hardware_poll = TRUE;
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+meta_monitor_manager_xrandr_finalize (GObject *object)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object);
|
|
|
2c033f |
+
|
|
|
2c033f |
+ if (manager_xrandr->resources)
|
|
|
2c033f |
+ XRRFreeScreenResources (manager_xrandr->resources);
|
|
|
2c033f |
+ manager_xrandr->resources = NULL;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ if (manager_xrandr->logind_watch_id > 0)
|
|
|
2c033f |
+ g_bus_unwatch_name (manager_xrandr->logind_watch_id);
|
|
|
2c033f |
+ manager_xrandr->logind_watch_id = 0;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+static void
|
|
|
2c033f |
+meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
|
|
|
2c033f |
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
2c033f |
+
|
|
|
2c033f |
+ object_class->finalize = meta_monitor_manager_xrandr_finalize;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ manager_class->read_current = meta_monitor_manager_xrandr_read_current;
|
|
|
2c033f |
+ manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
|
|
|
2c033f |
+ manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration;
|
|
|
2c033f |
+ manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;
|
|
|
2c033f |
+ manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
|
|
|
2c033f |
+ manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
|
|
|
2c033f |
+ manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
|
|
|
2c033f |
+}
|
|
|
2c033f |
+
|
|
|
2c033f |
+gboolean
|
|
|
2c033f |
+meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
|
|
2c033f |
+ XEvent *event)
|
|
|
2c033f |
+{
|
|
|
2c033f |
+ if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
|
|
2c033f |
+ return FALSE;
|
|
|
2c033f |
+
|
|
|
2c033f |
+ XRRUpdateConfiguration (event);
|
|
|
2c033f |
+
|
|
|
2c033f |
+ meta_monitor_manager_xrandr_update (manager_xrandr);
|
|
|
2c033f |
|
|
|
2c033f |
return TRUE;
|
|
|
2c033f |
}
|
|
|
2c033f |
--
|
|
|
2c033f |
2.5.0
|
|
|
2c033f |
|