From 4afa66fe41f0d82c1d9e025cb87ab0a2a4ca6cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 13 Jul 2017 12:38:02 +0800 Subject: [PATCH] wayland/window: Update toplevel main monitor before non-toplevel When updating the main monitor, make sure to update the toplevel main monitor before trying to use that as the main monitor for non-toplevel windows (such as popups). Without this, when the main monitor is updated as a side effect to monitors being changed (for example due to a hot plug event, or coming back from being suspended) the main monitor pointer may, after 'monitors-changed' has completed, point to freed memory resulting in undefined behaviour. https://bugzilla.gnome.org/show_bug.cgi?id=784867 --- src/core/window-private.h | 3 ++- src/core/window.c | 2 +- src/wayland/meta-window-wayland.c | 4 +++- src/x11/window-x11.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 5c8ed98c0..0b667fb8f 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -531,7 +531,8 @@ struct _MetaWindowClass cairo_surface_t **icon, cairo_surface_t **mini_icon); uint32_t (*get_client_pid) (MetaWindow *window); - void (*update_main_monitor) (MetaWindow *window); + void (*update_main_monitor) (MetaWindow *window, + gboolean user_op); void (*main_monitor_changed) (MetaWindow *window, const MetaLogicalMonitor *old); }; diff --git a/src/core/window.c b/src/core/window.c index 68d5bcb67..fa01e57c1 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3603,7 +3603,7 @@ meta_window_update_monitor (MetaWindow *window, const MetaLogicalMonitor *old; old = window->monitor; - META_WINDOW_GET_CLASS (window)->update_main_monitor (window); + META_WINDOW_GET_CLASS (window)->update_main_monitor (window, user_op); if (old != window->monitor) { meta_window_on_all_workspaces_changed (window); diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index 6ae57d13e..efe299fe3 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -350,7 +350,8 @@ scale_rect_size (MetaRectangle *rect, } static void -meta_window_wayland_update_main_monitor (MetaWindow *window) +meta_window_wayland_update_main_monitor (MetaWindow *window, + gboolean user_op) { MetaBackend *backend = meta_get_backend (); MetaMonitorManager *monitor_manager = @@ -370,6 +371,7 @@ meta_window_wayland_update_main_monitor (MetaWindow *window) toplevel_window = meta_wayland_surface_get_toplevel_window (window->surface); if (toplevel_window != window) { + meta_window_update_monitor (toplevel_window, user_op); window->monitor = toplevel_window->monitor; return; } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index fafa9296d..07f09223e 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -1456,7 +1456,8 @@ meta_window_x11_update_icon (MetaWindow *window, } static void -meta_window_x11_update_main_monitor (MetaWindow *window) +meta_window_x11_update_main_monitor (MetaWindow *window, + gboolean user_op) { window->monitor = meta_window_calculate_main_logical_monitor (window); }