mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 09:00:42 -05:00
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.
This commit is contained in:
parent
064788cbc9
commit
a6f95bc8cd
@ -64,6 +64,13 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_gpu_poll_hardware (MetaGpu *gpu)
|
||||||
|
{
|
||||||
|
if (META_GPU_GET_CLASS (gpu)->poll_hardware)
|
||||||
|
META_GPU_GET_CLASS (gpu)->poll_hardware (gpu);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_gpu_read_current (MetaGpu *gpu,
|
meta_gpu_read_current (MetaGpu *gpu,
|
||||||
GError **error)
|
GError **error)
|
||||||
|
@ -35,12 +35,14 @@ struct _MetaGpuClass
|
|||||||
|
|
||||||
gboolean (* read_current) (MetaGpu *gpu,
|
gboolean (* read_current) (MetaGpu *gpu,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
void (* poll_hardware) (MetaGpu *gpu);
|
||||||
};
|
};
|
||||||
|
|
||||||
int meta_gpu_get_kms_fd (MetaGpu *gpu);
|
int meta_gpu_get_kms_fd (MetaGpu *gpu);
|
||||||
|
|
||||||
const char * meta_gpu_get_kms_file_path (MetaGpu *gpu);
|
const char * meta_gpu_get_kms_file_path (MetaGpu *gpu);
|
||||||
|
|
||||||
|
void meta_gpu_poll_hardware (MetaGpu *gpu);
|
||||||
gboolean meta_gpu_read_current (MetaGpu *gpu,
|
gboolean meta_gpu_read_current (MetaGpu *gpu,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ struct _MetaGpuXrandr
|
|||||||
|
|
||||||
int max_screen_width;
|
int max_screen_width;
|
||||||
int max_screen_height;
|
int max_screen_height;
|
||||||
|
|
||||||
|
gboolean need_hardware_poll;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU)
|
G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU)
|
||||||
@ -81,6 +83,14 @@ get_xmode_name (XRRModeInfo *xmode)
|
|||||||
return g_strdup_printf ("%dx%d", width, height);
|
return g_strdup_printf ("%dx%d", width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
|
||||||
|
{
|
||||||
|
MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
|
||||||
|
|
||||||
|
gpu_xrandr->need_hardware_poll = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_gpu_xrandr_read_current (MetaGpu *gpu,
|
meta_gpu_xrandr_read_current (MetaGpu *gpu,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -148,8 +158,18 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
|
|||||||
monitor_manager->screen_width = WidthOfScreen (screen);
|
monitor_manager->screen_width = WidthOfScreen (screen);
|
||||||
monitor_manager->screen_height = HeightOfScreen (screen);
|
monitor_manager->screen_height = HeightOfScreen (screen);
|
||||||
|
|
||||||
|
if (gpu_xrandr->need_hardware_poll)
|
||||||
|
{
|
||||||
|
resources = XRRGetScreenResources (xdisplay,
|
||||||
|
DefaultRootWindow (xdisplay));
|
||||||
|
gpu_xrandr->need_hardware_poll = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
resources = XRRGetScreenResourcesCurrent (xdisplay,
|
resources = XRRGetScreenResourcesCurrent (xdisplay,
|
||||||
DefaultRootWindow (xdisplay));
|
DefaultRootWindow (xdisplay));
|
||||||
|
}
|
||||||
|
|
||||||
if (!resources)
|
if (!resources)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
@ -282,6 +302,7 @@ meta_gpu_xrandr_finalize (GObject *object)
|
|||||||
static void
|
static void
|
||||||
meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr)
|
meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr)
|
||||||
{
|
{
|
||||||
|
gpu_xrandr->need_hardware_poll = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -293,4 +314,5 @@ meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass)
|
|||||||
object_class->finalize = meta_gpu_xrandr_finalize;
|
object_class->finalize = meta_gpu_xrandr_finalize;
|
||||||
|
|
||||||
gpu_class->read_current = meta_gpu_xrandr_read_current;
|
gpu_class->read_current = meta_gpu_xrandr_read_current;
|
||||||
|
gpu_class->poll_hardware = meta_gpu_xrandr_poll_hardware;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,10 @@ struct _MetaMonitorManagerXrandr
|
|||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
int rr_event_base;
|
int rr_event_base;
|
||||||
int rr_error_base;
|
int rr_error_base;
|
||||||
|
|
||||||
|
guint logind_watch_id;
|
||||||
|
guint logind_signal_sub_id;
|
||||||
|
|
||||||
gboolean has_randr15;
|
gboolean has_randr15;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -95,6 +99,8 @@ typedef struct _MetaMonitorXrandrData
|
|||||||
GQuark quark_meta_monitor_xrandr_data;
|
GQuark quark_meta_monitor_xrandr_data;
|
||||||
#endif /* HAVE_RANDR15 */
|
#endif /* HAVE_RANDR15 */
|
||||||
|
|
||||||
|
static void meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr);
|
||||||
|
|
||||||
Display *
|
Display *
|
||||||
meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr)
|
meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr)
|
||||||
{
|
{
|
||||||
@ -966,6 +972,62 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager
|
|||||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
meta_gpu_poll_hardware (manager_xrandr->gpu);
|
||||||
|
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
|
static void
|
||||||
meta_monitor_manager_xrandr_constructed (GObject *object)
|
meta_monitor_manager_xrandr_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
@ -1024,12 +1086,23 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
|
|||||||
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
|
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
|
||||||
g_free (manager_xrandr->supported_scales);
|
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);
|
G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
||||||
{
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1076,9 +1149,8 @@ is_xvnc (MetaMonitorManager *manager)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static void
|
||||||
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
|
||||||
XEvent *event)
|
|
||||||
{
|
{
|
||||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
||||||
MetaGpuXrandr *gpu_xrandr;
|
MetaGpuXrandr *gpu_xrandr;
|
||||||
@ -1087,11 +1159,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
|||||||
gboolean is_our_configuration;
|
gboolean is_our_configuration;
|
||||||
unsigned int timestamp;
|
unsigned int timestamp;
|
||||||
|
|
||||||
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
XRRUpdateConfiguration (event);
|
|
||||||
|
|
||||||
meta_monitor_manager_read_current_state (manager);
|
meta_monitor_manager_read_current_state (manager);
|
||||||
|
|
||||||
gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
|
gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
|
||||||
@ -1126,6 +1193,19 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
|||||||
|
|
||||||
meta_monitor_manager_xrandr_rebuild_derived (manager, config);
|
meta_monitor_manager_xrandr_rebuild_derived (manager, config);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
|
||||||
|
XEvent *event)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
XRRUpdateConfiguration (event);
|
||||||
|
|
||||||
|
meta_monitor_manager_xrandr_update (manager_xrandr);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user