|
|
1c7749 |
From 849902beff553de41dd3940b17672ef98f687be5 Mon Sep 17 00:00:00 2001
|
|
|
1c7749 |
From: Rui Matos <tiagomatos@gmail.com>
|
|
|
1c7749 |
Date: Mon, 4 Jun 2018 16:35:04 -0400
|
|
|
1c7749 |
Subject: [PATCH] monitor-manager-xrandr: Force an update when resuming from
|
|
|
1c7749 |
suspend
|
|
|
1c7749 |
|
|
|
1c7749 |
The stack below us isn't as reliable as we'd like and in some cases
|
|
|
1c7749 |
doesn't generate RRScreenChangeNotify events when e.g. resuming a
|
|
|
1c7749 |
laptop on a dock, meaning that we'd miss newly attached outputs.
|
|
|
1c7749 |
---
|
|
|
1c7749 |
src/backends/meta-gpu.c | 7 ++
|
|
|
1c7749 |
src/backends/meta-gpu.h | 4 +
|
|
|
1c7749 |
src/backends/x11/meta-gpu-xrandr.c | 26 ++++-
|
|
|
1c7749 |
.../x11/meta-monitor-manager-xrandr.c | 96 +++++++++++++++++--
|
|
|
1c7749 |
4 files changed, 123 insertions(+), 10 deletions(-)
|
|
|
1c7749 |
|
|
|
1c7749 |
diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c
|
|
|
1c7749 |
index 3577391e5..946f72387 100644
|
|
|
1c7749 |
--- a/src/backends/meta-gpu.c
|
|
|
1c7749 |
+++ b/src/backends/meta-gpu.c
|
|
|
1c7749 |
@@ -64,6 +64,13 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
|
|
|
1c7749 |
return FALSE;
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
+void
|
|
|
1c7749 |
+meta_gpu_poll_hardware (MetaGpu *gpu)
|
|
|
1c7749 |
+{
|
|
|
1c7749 |
+ if (META_GPU_GET_CLASS (gpu)->poll_hardware)
|
|
|
1c7749 |
+ META_GPU_GET_CLASS (gpu)->poll_hardware (gpu);
|
|
|
1c7749 |
+}
|
|
|
1c7749 |
+
|
|
|
1c7749 |
gboolean
|
|
|
1c7749 |
meta_gpu_read_current (MetaGpu *gpu,
|
|
|
1c7749 |
GError **error)
|
|
|
1c7749 |
diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h
|
|
|
1c7749 |
index 701acdc97..a2fd061f7 100644
|
|
|
1c7749 |
--- a/src/backends/meta-gpu.h
|
|
|
1c7749 |
+++ b/src/backends/meta-gpu.h
|
|
|
1c7749 |
@@ -36,8 +36,12 @@ struct _MetaGpuClass
|
|
|
1c7749 |
|
|
|
1c7749 |
gboolean (* read_current) (MetaGpu *gpu,
|
|
|
1c7749 |
GError **error);
|
|
|
1c7749 |
+ void (* poll_hardware) (MetaGpu *gpu);
|
|
|
1c7749 |
};
|
|
|
1c7749 |
|
|
|
1c7749 |
+META_EXPORT_TEST
|
|
|
1c7749 |
+void meta_gpu_poll_hardware (MetaGpu *gpu);
|
|
|
1c7749 |
+
|
|
|
1c7749 |
META_EXPORT_TEST
|
|
|
1c7749 |
gboolean meta_gpu_read_current (MetaGpu *gpu,
|
|
|
1c7749 |
GError **error);
|
|
|
1c7749 |
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
|
|
|
1c7749 |
index 3e8a7318d..90b33d486 100644
|
|
|
1c7749 |
--- a/src/backends/x11/meta-gpu-xrandr.c
|
|
|
1c7749 |
+++ b/src/backends/x11/meta-gpu-xrandr.c
|
|
|
1c7749 |
@@ -44,6 +44,8 @@ struct _MetaGpuXrandr
|
|
|
1c7749 |
|
|
|
1c7749 |
int max_screen_width;
|
|
|
1c7749 |
int max_screen_height;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ gboolean need_hardware_poll;
|
|
|
1c7749 |
};
|
|
|
1c7749 |
|
|
|
1c7749 |
G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU)
|
|
|
1c7749 |
@@ -81,6 +83,14 @@ get_xmode_name (XRRModeInfo *xmode)
|
|
|
1c7749 |
return g_strdup_printf ("%dx%d", width, height);
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
+static void
|
|
|
1c7749 |
+meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
|
|
|
1c7749 |
+{
|
|
|
1c7749 |
+ MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ gpu_xrandr->need_hardware_poll = TRUE;
|
|
|
1c7749 |
+}
|
|
|
1c7749 |
+
|
|
|
1c7749 |
static gboolean
|
|
|
1c7749 |
meta_gpu_xrandr_read_current (MetaGpu *gpu,
|
|
|
1c7749 |
GError **error)
|
|
|
1c7749 |
@@ -116,8 +126,18 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
|
|
|
1c7749 |
monitor_manager->screen_width = WidthOfScreen (screen);
|
|
|
1c7749 |
monitor_manager->screen_height = HeightOfScreen (screen);
|
|
|
1c7749 |
|
|
|
1c7749 |
- resources = XRRGetScreenResourcesCurrent (xdisplay,
|
|
|
1c7749 |
- DefaultRootWindow (xdisplay));
|
|
|
1c7749 |
+ if (gpu_xrandr->need_hardware_poll)
|
|
|
1c7749 |
+ {
|
|
|
1c7749 |
+ resources = XRRGetScreenResources (xdisplay,
|
|
|
1c7749 |
+ DefaultRootWindow (xdisplay));
|
|
|
1c7749 |
+ gpu_xrandr->need_hardware_poll = FALSE;
|
|
|
1c7749 |
+ }
|
|
|
1c7749 |
+ else
|
|
|
1c7749 |
+ {
|
|
|
1c7749 |
+ resources = XRRGetScreenResourcesCurrent (xdisplay,
|
|
|
1c7749 |
+ DefaultRootWindow (xdisplay));
|
|
|
1c7749 |
+ }
|
|
|
1c7749 |
+
|
|
|
1c7749 |
if (!resources)
|
|
|
1c7749 |
{
|
|
|
1c7749 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
|
1c7749 |
@@ -250,6 +270,7 @@ meta_gpu_xrandr_finalize (GObject *object)
|
|
|
1c7749 |
static void
|
|
|
1c7749 |
meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr)
|
|
|
1c7749 |
{
|
|
|
1c7749 |
+ gpu_xrandr->need_hardware_poll = TRUE;
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
static void
|
|
|
1c7749 |
@@ -261,4 +282,5 @@ meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass)
|
|
|
1c7749 |
object_class->finalize = meta_gpu_xrandr_finalize;
|
|
|
1c7749 |
|
|
|
1c7749 |
gpu_class->read_current = meta_gpu_xrandr_read_current;
|
|
|
1c7749 |
+ gpu_class->poll_hardware = meta_gpu_xrandr_poll_hardware;
|
|
|
1c7749 |
}
|
|
|
1c7749 |
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
1c7749 |
index 448e51fae..d60f00325 100644
|
|
|
1c7749 |
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
1c7749 |
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
|
|
|
1c7749 |
@@ -71,6 +71,10 @@ struct _MetaMonitorManagerXrandr
|
|
|
1c7749 |
Display *xdisplay;
|
|
|
1c7749 |
int rr_event_base;
|
|
|
1c7749 |
int rr_error_base;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ guint logind_watch_id;
|
|
|
1c7749 |
+ guint logind_signal_sub_id;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
gboolean has_randr15;
|
|
|
1c7749 |
|
|
|
1c7749 |
/*
|
|
|
1c7749 |
@@ -102,6 +106,8 @@ typedef struct _MetaMonitorXrandrData
|
|
|
1c7749 |
|
|
|
1c7749 |
GQuark quark_meta_monitor_xrandr_data;
|
|
|
1c7749 |
|
|
|
1c7749 |
+static void meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr);
|
|
|
1c7749 |
+
|
|
|
1c7749 |
Display *
|
|
|
1c7749 |
meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
1c7749 |
{
|
|
|
1c7749 |
@@ -1016,6 +1022,62 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager
|
|
|
1c7749 |
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
+static void
|
|
|
1c7749 |
+logind_signal_handler (GDBusConnection *connection,
|
|
|
1c7749 |
+ const gchar *sender_name,
|
|
|
1c7749 |
+ const gchar *object_path,
|
|
|
1c7749 |
+ const gchar *interface_name,
|
|
|
1c7749 |
+ const gchar *signal_name,
|
|
|
1c7749 |
+ GVariant *parameters,
|
|
|
1c7749 |
+ gpointer user_data)
|
|
|
1c7749 |
+{
|
|
|
1c7749 |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
1c7749 |
+ gboolean suspending;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ if (!g_str_equal (signal_name, "PrepareForSleep"))
|
|
|
1c7749 |
+ return;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ g_variant_get (parameters, "(b)", &suspending);
|
|
|
1c7749 |
+ if (!suspending)
|
|
|
1c7749 |
+ {
|
|
|
1c7749 |
+ meta_gpu_poll_hardware (manager_xrandr->gpu);
|
|
|
1c7749 |
+ meta_monitor_manager_xrandr_update (manager_xrandr);
|
|
|
1c7749 |
+ }
|
|
|
1c7749 |
+}
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+static void
|
|
|
1c7749 |
+logind_appeared (GDBusConnection *connection,
|
|
|
1c7749 |
+ const gchar *name,
|
|
|
1c7749 |
+ const gchar *name_owner,
|
|
|
1c7749 |
+ gpointer user_data)
|
|
|
1c7749 |
+{
|
|
|
1c7749 |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection,
|
|
|
1c7749 |
+ "org.freedesktop.login1",
|
|
|
1c7749 |
+ "org.freedesktop.login1.Manager",
|
|
|
1c7749 |
+ "PrepareForSleep",
|
|
|
1c7749 |
+ "/org/freedesktop/login1",
|
|
|
1c7749 |
+ NULL,
|
|
|
1c7749 |
+ G_DBUS_SIGNAL_FLAGS_NONE,
|
|
|
1c7749 |
+ logind_signal_handler,
|
|
|
1c7749 |
+ manager_xrandr,
|
|
|
1c7749 |
+ NULL);
|
|
|
1c7749 |
+}
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+static void
|
|
|
1c7749 |
+logind_vanished (GDBusConnection *connection,
|
|
|
1c7749 |
+ const gchar *name,
|
|
|
1c7749 |
+ gpointer user_data)
|
|
|
1c7749 |
+{
|
|
|
1c7749 |
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ if (connection && manager_xrandr->logind_signal_sub_id > 0)
|
|
|
1c7749 |
+ g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id);
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ manager_xrandr->logind_signal_sub_id = 0;
|
|
|
1c7749 |
+}
|
|
|
1c7749 |
+
|
|
|
1c7749 |
static void
|
|
|
1c7749 |
meta_monitor_manager_xrandr_constructed (GObject *object)
|
|
|
1c7749 |
{
|
|
|
1c7749 |
@@ -1072,12 +1134,23 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
|
|
|
1c7749 |
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
|
|
|
1c7749 |
g_free (manager_xrandr->supported_scales);
|
|
|
1c7749 |
|
|
|
1c7749 |
+ if (manager_xrandr->logind_watch_id > 0)
|
|
|
1c7749 |
+ g_bus_unwatch_name (manager_xrandr->logind_watch_id);
|
|
|
1c7749 |
+ manager_xrandr->logind_watch_id = 0;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
static void
|
|
|
1c7749 |
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
1c7749 |
{
|
|
|
1c7749 |
+ manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
|
|
|
1c7749 |
+ "org.freedesktop.login1",
|
|
|
1c7749 |
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
|
|
|
1c7749 |
+ logind_appeared,
|
|
|
1c7749 |
+ logind_vanished,
|
|
|
1c7749 |
+ manager_xrandr,
|
|
|
1c7749 |
+ NULL);
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
static void
|
|
|
1c7749 |
@@ -1123,9 +1196,8 @@ is_xvnc (MetaMonitorManager *manager)
|
|
|
1c7749 |
return FALSE;
|
|
|
1c7749 |
}
|
|
|
1c7749 |
|
|
|
1c7749 |
-gboolean
|
|
|
1c7749 |
-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
|
|
1c7749 |
- XEvent *event)
|
|
|
1c7749 |
+static void
|
|
|
1c7749 |
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
|
|
|
1c7749 |
{
|
|
|
1c7749 |
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
|
|
1c7749 |
MetaGpuXrandr *gpu_xrandr;
|
|
|
1c7749 |
@@ -1134,11 +1206,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
|
|
1c7749 |
gboolean is_our_configuration;
|
|
|
1c7749 |
unsigned int timestamp;
|
|
|
1c7749 |
|
|
|
1c7749 |
- if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
|
|
1c7749 |
- return FALSE;
|
|
|
1c7749 |
-
|
|
|
1c7749 |
- XRRUpdateConfiguration (event);
|
|
|
1c7749 |
-
|
|
|
1c7749 |
meta_monitor_manager_read_current_state (manager);
|
|
|
1c7749 |
|
|
|
1c7749 |
gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
|
|
|
1c7749 |
@@ -1173,6 +1240,19 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
|
|
1c7749 |
|
|
|
1c7749 |
meta_monitor_manager_xrandr_rebuild_derived (manager, config);
|
|
|
1c7749 |
}
|
|
|
1c7749 |
+}
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+gboolean
|
|
|
1c7749 |
+meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
|
|
1c7749 |
+ XEvent *event)
|
|
|
1c7749 |
+{
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
|
|
1c7749 |
+ return FALSE;
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ XRRUpdateConfiguration (event);
|
|
|
1c7749 |
+
|
|
|
1c7749 |
+ meta_monitor_manager_xrandr_update (manager_xrandr);
|
|
|
1c7749 |
|
|
|
1c7749 |
return TRUE;
|
|
|
1c7749 |
}
|
|
|
1c7749 |
--
|
|
|
1c7749 |
2.21.0
|
|
|
1c7749 |
|