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.
This commit is contained in:
Vadim Zeitlin
2019-12-29 01:40:28 +01:00
parent 38cec22d4c
commit 8b90073c83

View File

@@ -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.