|
|
e47e58 |
From ed7cad0561b79e68ddd91f0e12042087199676ea Mon Sep 17 00:00:00 2001
|
|
|
67f8b7 |
From: Rui Matos <tiagomatos@gmail.com>
|
|
|
67f8b7 |
Date: Sun, 25 Oct 2015 16:14:58 +0100
|
|
|
e47e58 |
Subject: [PATCH 3/8] monitor-manager-xrandr: Force an update when resuming
|
|
|
e47e58 |
from suspend
|
|
|
67f8b7 |
|
|
|
67f8b7 |
The stack below us isn't as reliable as we'd like and in some cases
|
|
|
67f8b7 |
doesn't generate RRScreenChangeNotify events when e.g. resuming a
|
|
|
67f8b7 |
laptop on a dock, meaning that we'd miss newly attached outputs.
|
|
|
67f8b7 |
---
|
|
|
e47e58 |
src/backends/x11/meta-monitor-manager-xrandr.c | 188 ++++++++++++++++++-------
|
|
|
e47e58 |
1 file changed, 137 insertions(+), 51 deletions(-)
|
|
|
67f8b7 |
|
|
|
67f8b7 |
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
e47e58 |
index 8d1bdfb69..d451fcccc 100644
|
|
|
67f8b7 |
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
67f8b7 |
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
e47e58 |
@@ -61,6 +61,11 @@ struct _MetaMonitorManagerXrandr
|
|
|
67f8b7 |
XRRScreenResources *resources;
|
|
|
67f8b7 |
int rr_event_base;
|
|
|
67f8b7 |
int rr_error_base;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ guint logind_watch_id;
|
|
|
67f8b7 |
+ guint logind_signal_sub_id;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ gboolean need_hardware_poll;
|
|
|
67f8b7 |
gboolean has_randr15;
|
|
|
67f8b7 |
|
|
|
e47e58 |
xcb_timestamp_t last_xrandr_set_timestamp;
|
|
|
e47e58 |
@@ -787,8 +792,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
|
|
67f8b7 |
manager->screen_width = WidthOfScreen (screen);
|
|
|
67f8b7 |
manager->screen_height = HeightOfScreen (screen);
|
|
|
67f8b7 |
|
|
|
67f8b7 |
- resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay,
|
|
|
67f8b7 |
- DefaultRootWindow (manager_xrandr->xdisplay));
|
|
|
67f8b7 |
+ if (manager_xrandr->need_hardware_poll)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ resources = XRRGetScreenResources (manager_xrandr->xdisplay,
|
|
|
67f8b7 |
+ DefaultRootWindow (manager_xrandr->xdisplay));
|
|
|
67f8b7 |
+ manager_xrandr->need_hardware_poll = FALSE;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else
|
|
|
67f8b7 |
+ resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay,
|
|
|
67f8b7 |
+ DefaultRootWindow (manager_xrandr->xdisplay));
|
|
|
67f8b7 |
if (!resources)
|
|
|
67f8b7 |
return;
|
|
|
67f8b7 |
|
|
|
e47e58 |
@@ -1910,6 +1922,115 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager
|
|
|
e47e58 |
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+static gboolean
|
|
|
67f8b7 |
+is_xvnc (MetaMonitorManager *manager)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ unsigned int i;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ for (i = 0; i < manager->n_outputs; ++i)
|
|
|
67f8b7 |
+ if (g_str_has_prefix (manager->outputs[i].name, "VNC-"))
|
|
|
67f8b7 |
+ return TRUE;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ return FALSE;
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+static void
|
|
|
67f8b7 |
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
|
|
e47e58 |
+ gboolean is_hotplug;
|
|
|
e47e58 |
+ gboolean is_our_configuration;
|
|
|
67f8b7 |
+ unsigned int timestamp;
|
|
|
67f8b7 |
+
|
|
|
e47e58 |
+ meta_monitor_manager_read_current_state (manager);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ timestamp = manager_xrandr->resources->timestamp;
|
|
|
67f8b7 |
+ if (is_xvnc (manager))
|
|
|
67f8b7 |
+ timestamp += 100;
|
|
|
67f8b7 |
+
|
|
|
e47e58 |
+ is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp);
|
|
|
e47e58 |
+ is_our_configuration = (manager_xrandr->resources->timestamp ==
|
|
|
e47e58 |
+ manager_xrandr->last_xrandr_set_timestamp);
|
|
|
e47e58 |
+ if (is_hotplug)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ meta_monitor_manager_on_hotplug (manager);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else
|
|
|
67f8b7 |
+ {
|
|
|
e47e58 |
+ MetaMonitorsConfig *config;
|
|
|
e47e58 |
+
|
|
|
e47e58 |
+ if (is_our_configuration)
|
|
|
e47e58 |
+ {
|
|
|
e47e58 |
+ MetaMonitorConfigManager *config_manager =
|
|
|
e47e58 |
+ meta_monitor_manager_get_config_manager (manager);
|
|
|
e47e58 |
+
|
|
|
e47e58 |
+ config = meta_monitor_config_manager_get_current (config_manager);
|
|
|
e47e58 |
+ }
|
|
|
e47e58 |
+ else
|
|
|
e47e58 |
+ {
|
|
|
e47e58 |
+ config = NULL;
|
|
|
e47e58 |
+ }
|
|
|
e47e58 |
+
|
|
|
e47e58 |
+ meta_monitor_manager_rebuild_derived (manager, config);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+static void
|
|
|
67f8b7 |
+logind_signal_handler (GDBusConnection *connection,
|
|
|
67f8b7 |
+ const gchar *sender_name,
|
|
|
67f8b7 |
+ const gchar *object_path,
|
|
|
67f8b7 |
+ const gchar *interface_name,
|
|
|
67f8b7 |
+ const gchar *signal_name,
|
|
|
67f8b7 |
+ GVariant *parameters,
|
|
|
67f8b7 |
+ gpointer user_data)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
67f8b7 |
+ gboolean suspending;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (!g_str_equal (signal_name, "PrepareForSleep"))
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ g_variant_get (parameters, "(b)", &suspending);
|
|
|
67f8b7 |
+ if (!suspending)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ manager_xrandr->need_hardware_poll = TRUE;
|
|
|
67f8b7 |
+ meta_monitor_manager_xrandr_update (manager_xrandr);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+static void
|
|
|
67f8b7 |
+logind_appeared (GDBusConnection *connection,
|
|
|
67f8b7 |
+ const gchar *name,
|
|
|
67f8b7 |
+ const gchar *name_owner,
|
|
|
67f8b7 |
+ gpointer user_data)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection,
|
|
|
67f8b7 |
+ "org.freedesktop.login1",
|
|
|
67f8b7 |
+ "org.freedesktop.login1.Manager",
|
|
|
67f8b7 |
+ "PrepareForSleep",
|
|
|
67f8b7 |
+ "/org/freedesktop/login1",
|
|
|
67f8b7 |
+ NULL,
|
|
|
67f8b7 |
+ G_DBUS_SIGNAL_FLAGS_NONE,
|
|
|
67f8b7 |
+ logind_signal_handler,
|
|
|
67f8b7 |
+ manager_xrandr,
|
|
|
67f8b7 |
+ NULL);
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+static void
|
|
|
67f8b7 |
+logind_vanished (GDBusConnection *connection,
|
|
|
67f8b7 |
+ const gchar *name,
|
|
|
67f8b7 |
+ gpointer user_data)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (connection && manager_xrandr->logind_signal_sub_id > 0)
|
|
|
67f8b7 |
+ g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ manager_xrandr->logind_signal_sub_id = 0;
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
static void
|
|
|
67f8b7 |
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
67f8b7 |
{
|
|
|
e47e58 |
@@ -1948,6 +2069,15 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
67f8b7 |
meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
|
|
|
67f8b7 |
#endif
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
|
|
|
67f8b7 |
+ "org.freedesktop.login1",
|
|
|
67f8b7 |
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
|
|
|
67f8b7 |
+ logind_appeared,
|
|
|
67f8b7 |
+ logind_vanished,
|
|
|
67f8b7 |
+ manager_xrandr,
|
|
|
67f8b7 |
+ NULL);
|
|
|
67f8b7 |
+ manager_xrandr->need_hardware_poll = TRUE;
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
|
|
|
67f8b7 |
static void
|
|
|
e47e58 |
@@ -1962,6 +2092,10 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
|
|
|
e47e58 |
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
|
|
|
e47e58 |
g_free (manager_xrandr->supported_scales);
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (manager_xrandr->logind_watch_id > 0)
|
|
|
67f8b7 |
+ g_bus_unwatch_name (manager_xrandr->logind_watch_id);
|
|
|
67f8b7 |
+ manager_xrandr->logind_watch_id = 0;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
|
|
|
e47e58 |
@@ -1996,64 +2130,16 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
|
|
|
e47e58 |
g_quark_from_static_string ("-meta-monitor-xrandr-data");
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
|
|
|
67f8b7 |
-static gboolean
|
|
|
67f8b7 |
-is_xvnc (MetaMonitorManager *manager)
|
|
|
67f8b7 |
-{
|
|
|
67f8b7 |
- unsigned int i;
|
|
|
67f8b7 |
-
|
|
|
67f8b7 |
- for (i = 0; i < manager->n_outputs; ++i)
|
|
|
67f8b7 |
- if (g_str_has_prefix (manager->outputs[i].name, "VNC-"))
|
|
|
67f8b7 |
- return TRUE;
|
|
|
67f8b7 |
-
|
|
|
67f8b7 |
- return FALSE;
|
|
|
67f8b7 |
-}
|
|
|
67f8b7 |
-
|
|
|
67f8b7 |
gboolean
|
|
|
67f8b7 |
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
|
|
67f8b7 |
XEvent *event)
|
|
|
67f8b7 |
{
|
|
|
67f8b7 |
- MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
|
|
e47e58 |
- gboolean is_hotplug;
|
|
|
e47e58 |
- gboolean is_our_configuration;
|
|
|
67f8b7 |
- unsigned int timestamp;
|
|
|
67f8b7 |
-
|
|
|
67f8b7 |
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
|
|
67f8b7 |
return FALSE;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
XRRUpdateConfiguration (event);
|
|
|
67f8b7 |
|
|
|
e47e58 |
- meta_monitor_manager_read_current_state (manager);
|
|
|
e47e58 |
-
|
|
|
67f8b7 |
-
|
|
|
67f8b7 |
- timestamp = manager_xrandr->resources->timestamp;
|
|
|
67f8b7 |
- if (is_xvnc (manager))
|
|
|
67f8b7 |
- timestamp += 100;
|
|
|
67f8b7 |
-
|
|
|
e47e58 |
- is_hotplug = (timestamp < manager_xrandr->resources->configTimestamp);
|
|
|
e47e58 |
- is_our_configuration = (manager_xrandr->resources->timestamp ==
|
|
|
e47e58 |
- manager_xrandr->last_xrandr_set_timestamp);
|
|
|
e47e58 |
- if (is_hotplug)
|
|
|
67f8b7 |
- {
|
|
|
67f8b7 |
- meta_monitor_manager_on_hotplug (manager);
|
|
|
67f8b7 |
- }
|
|
|
67f8b7 |
- else
|
|
|
67f8b7 |
- {
|
|
|
e47e58 |
- MetaMonitorsConfig *config;
|
|
|
e47e58 |
-
|
|
|
e47e58 |
- if (is_our_configuration)
|
|
|
e47e58 |
- {
|
|
|
e47e58 |
- MetaMonitorConfigManager *config_manager =
|
|
|
e47e58 |
- meta_monitor_manager_get_config_manager (manager);
|
|
|
e47e58 |
-
|
|
|
e47e58 |
- config = meta_monitor_config_manager_get_current (config_manager);
|
|
|
e47e58 |
- }
|
|
|
e47e58 |
- else
|
|
|
e47e58 |
- {
|
|
|
e47e58 |
- config = NULL;
|
|
|
e47e58 |
- }
|
|
|
e47e58 |
-
|
|
|
e47e58 |
- meta_monitor_manager_xrandr_rebuild_derived (manager, config);
|
|
|
67f8b7 |
- }
|
|
|
67f8b7 |
+ meta_monitor_manager_xrandr_update (manager_xrandr);
|
|
|
67f8b7 |
|
|
|
67f8b7 |
return TRUE;
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
--
|
|
|
e47e58 |
2.14.2
|
|
|
67f8b7 |
|