From 8b90073c83b55a18dcdfc9ab363f71f02bda6e38 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 29 Dec 2019 01:40:28 +0100 Subject: [PATCH] Send kill focus events to modal dialogs earlier in wxGTK Ensure that the dialog is still alive when it gets the kill focus event for its child which had focus just before the dialog was closed (or any other events generated by this child when it detects that it's losing focus, such as wxEVT_SPINCTRL) by resetting focus when the dialog is being hidden and not when it's being destroyed. This makes the events order more consistent with wxMSW but also, most importantly, safer, as wxEVT_KILL_FOCUS handlers could previously easily reference the fields of an already half-destroyed wxDialog-derived object by the time they were run during wxTopLevelWindowGTK destructor execution. Closes #18145. --- src/gtk/toplevel.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 1d307883cb..4faea74c25 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -1080,6 +1080,16 @@ bool wxTopLevelWindowGTK::Show( bool show ) if (change && !show) { + // Generate wxEVT_KILL_FOCUS for the currently focused control + // immediately (i.e. without waiting until the window is destroyed and + // doing it from its dtor), as it could be too late to execute the + // handler for this event, or other events triggered by receiving it, + // by then because the wxTLW will have been half-destroyed by then. + if (GTK_IS_WINDOW(m_widget)) + { + gtk_window_set_focus( GTK_WINDOW(m_widget), NULL ); + } + // make sure window has a non-default position, so when it is shown // again, it won't be repositioned by WM as if it were a new window // Note that this must be done _after_ the window is hidden.