From 31d51186e237eaff67ee298828f80516e8dfd2ff Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 27 Oct 2017 17:49:13 +0200 Subject: [PATCH] Fix crash when reparenting the focused window to another TLW If the window stored as m_winLastFocused in one TLW was reparented to another one and then destroyed, this pointer to it wasn't updated and became dangling. Fix this by using a safe weak reference instead of raw pointer for m_winLastFocused. This ensures that it can never be used when it becomes invalid. Closes #17980. --- docs/changes.txt | 1 + include/wx/msw/toplevel.h | 4 +++- src/msw/toplevel.cpp | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 40ed527a0a..91a0a3c018 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -214,6 +214,7 @@ wxMSW: - Fix updating radio groups when non-radio item is inserted to wxMenu. - Fix autoselecting the contents of wxTextCtrl with wxWANTS_CHARS style. - Implement SetIcon(), SetPosition(), GetPosition() for native wxProgressDialog. +- Fix crash when reparenting the currently focused window to another TLW. wxOSX: diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index f464e92eca..42c667b9a2 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -11,6 +11,8 @@ #ifndef _WX_MSW_TOPLEVEL_H_ #define _WX_MSW_TOPLEVEL_H_ +#include "wx/weakref.h" + // ---------------------------------------------------------------------------- // wxTopLevelWindowMSW // ---------------------------------------------------------------------------- @@ -176,7 +178,7 @@ protected: // The last focused child: we remember it when we're deactivated and // restore focus to it when we're activated (this is done here) or restored // from iconic state (done by wxFrame). - wxWindow *m_winLastFocused; + wxWindowRef m_winLastFocused; private: diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index ba880caae6..2b815c74f6 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -102,8 +102,6 @@ void wxTopLevelWindowMSW::Init() m_fsIsMaximized = false; m_fsIsShowing = false; - m_winLastFocused = NULL; - m_menuSystem = NULL; } @@ -1195,7 +1193,9 @@ void wxTopLevelWindowMSW::DoRestoreLastFocus() parent = this; } - wxSetFocusToChild(parent, &m_winLastFocused); + wxWindow* winPtr = m_winLastFocused; + wxSetFocusToChild(parent, &winPtr); + m_winLastFocused = winPtr; } void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event)