From f4d07caa38e51d09ee73bab20334a6b5c28952d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 24 Aug 2018 12:54:50 +0200 Subject: [PATCH 1/2] window: Pass flag to meta_window_update_monitor() instead of bool The bool determines whether the call was directly from a user operation or not. To add more state into the call without having to add more boolenas, change the boolean to a flag (so far with 'none' and 'user-op' as possible values). No functional changes were made. https://gitlab.gnome.org/GNOME/mutter/issues/192 --- src/core/window-private.h | 14 ++++++++++---- src/core/window.c | 24 ++++++++++++++++-------- src/wayland/meta-wayland-shell-surface.c | 2 +- src/wayland/meta-window-wayland.c | 8 ++++---- src/x11/window-x11.c | 6 +++--- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 8eb462be345..b11511f4482 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -121,6 +121,12 @@ typedef enum META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 1 << 5, } MetaPlacementConstraintAdjustment; +typedef enum _MetaWindowUpdateMonitorFlags +{ + META_WINDOW_UPDATE_MONITOR_FLAGS_NONE = 0, + META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP = 1 << 0, +} MetaWindowUpdateMonitorFlags; + typedef struct _MetaPlacementRule { MetaRectangle anchor_rect; @@ -548,8 +554,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, - gboolean user_op); + void (*update_main_monitor) (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags); void (*main_monitor_changed) (MetaWindow *window, const MetaLogicalMonitor *old); void (*force_restore_shortcuts) (MetaWindow *window, @@ -766,8 +772,8 @@ void meta_window_activate_full (MetaWindow *window, MetaLogicalMonitor * meta_window_calculate_main_logical_monitor (MetaWindow *window); MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window); -void meta_window_update_monitor (MetaWindow *window, - gboolean user_op); +void meta_window_update_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags); void meta_window_set_urgent (MetaWindow *window, gboolean urgent); diff --git a/src/core/window.c b/src/core/window.c index e32366838af..bd752d95b74 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3825,7 +3825,8 @@ meta_window_update_for_monitors_changed (MetaWindow *window) if (window->override_redirect || window->type == META_WINDOW_DESKTOP) { - meta_window_update_monitor (window, FALSE); + meta_window_update_monitor (window, + META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); return; } @@ -3860,19 +3861,20 @@ meta_window_update_for_monitors_changed (MetaWindow *window) } else { - meta_window_update_monitor (window, FALSE); + meta_window_update_monitor (window, + META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); } } void -meta_window_update_monitor (MetaWindow *window, - gboolean user_op) +meta_window_update_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags) { MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; const MetaLogicalMonitor *old; old = window->monitor; - META_WINDOW_GET_CLASS (window)->update_main_monitor (window, user_op); + META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags); if (old != window->monitor) { meta_window_on_all_workspaces_changed (window); @@ -3886,7 +3888,8 @@ meta_window_update_monitor (MetaWindow *window, * That should be handled by explicitly moving the window before changing the * workspace. */ - if (meta_prefs_get_workspaces_only_on_primary () && user_op && + if (meta_prefs_get_workspaces_only_on_primary () && + flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP && meta_window_is_on_primary_monitor (window) && workspace_manager->active_workspace != window->workspace) meta_window_change_workspace (window, workspace_manager->active_workspace); @@ -3930,6 +3933,7 @@ meta_window_move_resize_internal (MetaWindow *window, MetaRectangle constrained_rect; MetaMoveResizeResultFlags result = 0; gboolean moved_or_resized = FALSE; + MetaWindowUpdateMonitorFlags update_monitor_flags; g_return_if_fail (!window->override_redirect); @@ -4030,13 +4034,17 @@ meta_window_move_resize_internal (MetaWindow *window, did_placement); } + update_monitor_flags = META_WINDOW_UPDATE_MONITOR_FLAGS_NONE; + if (flags & META_MOVE_RESIZE_USER_ACTION) + update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP; + if (window->monitor) { guint old_output_winsys_id; old_output_winsys_id = window->monitor->winsys_id; - meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION); + meta_window_update_monitor (window, update_monitor_flags); if (old_output_winsys_id != window->monitor->winsys_id && flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION) @@ -4044,7 +4052,7 @@ meta_window_move_resize_internal (MetaWindow *window, } else { - meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION); + meta_window_update_monitor (window, update_monitor_flags); } if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds) diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c index 88bfc21a5d3..50dbb9bcd20 100644 --- a/src/wayland/meta-wayland-shell-surface.c +++ b/src/wayland/meta-wayland-shell-surface.c @@ -91,7 +91,7 @@ meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface, meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_set_window (surface, window); - meta_window_update_monitor (window, FALSE); + meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); } void diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index 601ea1b2049..57459323161 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -371,8 +371,8 @@ scale_rect_size (MetaRectangle *rect, } static void -meta_window_wayland_update_main_monitor (MetaWindow *window, - gboolean user_op) +meta_window_wayland_update_main_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags) { MetaBackend *backend = meta_get_backend (); MetaMonitorManager *monitor_manager = @@ -392,7 +392,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); + meta_window_update_monitor (window, flags); window->monitor = toplevel_window->monitor; return; } @@ -413,7 +413,7 @@ meta_window_wayland_update_main_monitor (MetaWindow *window, return; } - if (!user_op) + if (flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP) { window->monitor = to; return; diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 2418e626279..b2b2c9cb302 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -1501,8 +1501,8 @@ meta_window_x11_update_icon (MetaWindow *window, } static void -meta_window_x11_update_main_monitor (MetaWindow *window, - gboolean user_op) +meta_window_x11_update_main_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags) { window->monitor = meta_window_calculate_main_logical_monitor (window); } @@ -3339,7 +3339,7 @@ meta_window_x11_configure_notify (MetaWindow *window, priv->client_rect = window->rect; window->buffer_rect = window->rect; - meta_window_update_monitor (window, FALSE); + meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); /* Whether an override-redirect window is considered fullscreen depends * on its geometry. -- GitLab From 8d3e053059cd202e740076caedfc8e3ac149066a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 24 Aug 2018 12:56:31 +0200 Subject: [PATCH 2/2] window: Force update monitor on hot plugs Commit a3da4b8d5bd217c0262fd9361036877d155a300f changed updating of window monitors to always use take affect when it was done from a non-user operation. This could cause feed back loops when a non-user driven operation would trigger the changing of a monitor, which itself would trigger changing of the monitor again due to a window scale change. The reason for the change, was that when the window monitor changed due to a hot plug, if it didn't actually change, eventually the window monitor pointer would be pointing to freed memory. Instead of force updating the monitor on all non-user operations, just do it on hot plugs. This allows for the feedback loop preventing logic to still do what its supposed to do, without risking dangling pointers on hot plugs. Related: https://gitlab.gnome.org/GNOME/mutter/issues/189 Closes: https://gitlab.gnome.org/GNOME/mutter/issues/192 --- src/core/window-private.h | 1 + src/core/window.c | 4 ++-- src/wayland/meta-window-wayland.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index b11511f4482..76c454417e3 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -125,6 +125,7 @@ typedef enum _MetaWindowUpdateMonitorFlags { META_WINDOW_UPDATE_MONITOR_FLAGS_NONE = 0, META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP = 1 << 0, + META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE = 1 << 1, } MetaWindowUpdateMonitorFlags; typedef struct _MetaPlacementRule diff --git a/src/core/window.c b/src/core/window.c index bd752d95b74..f8b0e0128d5 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3826,7 +3826,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window) if (window->override_redirect || window->type == META_WINDOW_DESKTOP) { meta_window_update_monitor (window, - META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); + META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE); return; } @@ -3862,7 +3862,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window) else { meta_window_update_monitor (window, - META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); + META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE); } } diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index 57459323161..f73f3e1040b 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -413,7 +413,7 @@ meta_window_wayland_update_main_monitor (MetaWindow *window, return; } - if (flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP) + if (flags & META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE) { window->monitor = to; return; -- GitLab