From 49d1af20231aa804ced834013b594457382d6202 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Tue, 12 Sep 2023 19:03:18 +0200 Subject: [PATCH] display: Deal with destroying windows in pointer rest callback Take a reference to the window to make sure the MetaFocusData->window pointer is not pointing to a freed object. Also make sure that the window that we want to focus is not currently unmanaging. Part-of: --- src/core/display.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 67b210ac7..e9c5388e7 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3812,6 +3812,13 @@ typedef struct int pointer_y; } MetaFocusData; +static void +meta_focus_data_free (MetaFocusData *focus_data) +{ + g_clear_object (&focus_data->window); + g_free (focus_data); +} + static void focus_mouse_mode (MetaDisplay *display, MetaWindow *window, @@ -3866,6 +3873,9 @@ focus_on_pointer_rest_callback (gpointer data) graphene_point_t point; uint32_t timestamp_ms; + if (window && window->unmanaging) + goto out; + if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) goto out; @@ -3906,10 +3916,13 @@ queue_pointer_rest_callback (MetaDisplay *display, focus_data = g_new (MetaFocusData, 1); focus_data->display = display; - focus_data->window = window; + focus_data->window = NULL; focus_data->pointer_x = pointer_x; focus_data->pointer_y = pointer_y; + if (window) + focus_data->window = g_object_ref (window); + g_clear_handle_id (&display->focus_timeout_id, g_source_remove); display->focus_timeout_id = @@ -3917,7 +3930,7 @@ queue_pointer_rest_callback (MetaDisplay *display, FOCUS_TIMEOUT_DELAY, focus_on_pointer_rest_callback, focus_data, - g_free); + (GDestroyNotify) meta_focus_data_free); g_source_set_name_by_id (display->focus_timeout_id, "[mutter] focus_on_pointer_rest_callback"); }