From 9f95e86e760220e0df0c1e72fe87a82a4d5f9c45 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Apr 2019 18:13:27 +0200 Subject: [PATCH] Fix apparent activation loss after hiding previous popup Commit 58d4b0e209dad0e6ced56585e74102ab09c930df introduced a regression: if a previous popup still existed when the new one was shown, dismissing the second popup would result in the owner window losing its "active" appearance. This was due to the fact that ::GetActiveWindow() still returned the former popup when it was about to be dismissed, so it was too early to call it in WM_NCACTIVATE handler. Do it now in DismissOnDeactivate() itself which is both simpler and more correct. --- include/wx/popupwin.h | 2 +- src/msw/popupwin.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/wx/popupwin.h b/include/wx/popupwin.h index 6735d2593c..dfde0635ad 100644 --- a/include/wx/popupwin.h +++ b/include/wx/popupwin.h @@ -152,7 +152,7 @@ public: WXLPARAM lParam) wxOVERRIDE; private: - void DismissOnDeactivate(WXHWND hwndActive); + void DismissOnDeactivate(); wxDECLARE_DYNAMIC_CLASS(wxPopupTransientWindow); wxDECLARE_NO_COPY_CLASS(wxPopupTransientWindow); diff --git a/src/msw/popupwin.cpp b/src/msw/popupwin.cpp index ab6cdf6b9c..c3f42860f9 100644 --- a/src/msw/popupwin.cpp +++ b/src/msw/popupwin.cpp @@ -192,7 +192,7 @@ void wxPopupTransientWindow::Dismiss() Hide(); } -void wxPopupTransientWindow::DismissOnDeactivate(WXHWND hwndActive) +void wxPopupTransientWindow::DismissOnDeactivate() { // Hide the window automatically when it loses activation. Dismiss(); @@ -203,7 +203,7 @@ void wxPopupTransientWindow::DismissOnDeactivate(WXHWND hwndActive) wxWindow* const owner = MSWGetOwner(); if ( owner ) { - if ( hwndActive != GetHwndOf(owner) ) + if ( ::GetActiveWindow() != GetHwndOf(owner) ) { ::SendMessage(GetHwndOf(owner), WM_NCACTIVATE, FALSE, 0); } @@ -218,18 +218,17 @@ wxPopupTransientWindow::MSWHandleMessage(WXLRESULT *result, { switch ( message ) { - case WM_NCACTIVATE: - if ( !wParam ) + case WM_ACTIVATE: + if ( wParam == WA_INACTIVE ) { // We need to dismiss this window, however doing it directly // from here seems to confuse ::ShowWindow(), which ends up // calling this handler, and may result in losing activation // entirely, so postpone it slightly. // - // Note that we do use the currently active window, just in - // case it changes between now and the next idle event. - CallAfter(&wxPopupTransientWindow::DismissOnDeactivate, - ::GetActiveWindow()); + // Also note that the active window hasn't changed yet, so we + // postpone calling it until DismissOnDeactivate() is executed. + CallAfter(&wxPopupTransientWindow::DismissOnDeactivate); } break; }