wxMSW: Restore window focus after wxExecute
If wxExecute() is called without the wxEXEC_NODISABLE flag, it disables all toplevel windows and then creates a helper dummy window. This moves focus to the helper window and when it's destroyed, back to the first(?) of the re-enabled application windows, thus loosing original focus. Remember previously focused window instead and try to restore focus to it. This still results in some flicker, but is better than completely changing focus and e.g. even changing the currently active window without user's input.
This commit is contained in:
parent
ea8cb7a24a
commit
a352e95a30
@ -51,6 +51,7 @@
|
||||
#include "wx/thread.h"
|
||||
#include "wx/scopeguard.h"
|
||||
#include "wx/vector.h"
|
||||
#include "wx/weakref.h"
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/dc.h"
|
||||
@ -137,13 +138,15 @@ LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
// AfterChildWaitLoop()
|
||||
struct ChildWaitLoopData
|
||||
{
|
||||
ChildWaitLoopData(wxWindowDisabler *wd_, wxWindow *winActive_)
|
||||
ChildWaitLoopData(wxWindowDisabler *wd_, wxWindow *focused_, wxWindow *winActive_)
|
||||
{
|
||||
wd = wd_;
|
||||
focused = focused_;
|
||||
winActive = winActive_;
|
||||
}
|
||||
|
||||
wxWindowDisabler *wd;
|
||||
wxWeakRef<wxWindow> focused;
|
||||
wxWindow *winActive;
|
||||
};
|
||||
|
||||
@ -167,6 +170,8 @@ void *wxGUIAppTraits::BeforeChildWaitLoop()
|
||||
*/
|
||||
wxBeginBusyCursor();
|
||||
|
||||
wxWindow* const focus = wxWindow::FindFocus();
|
||||
|
||||
// first disable all existing windows
|
||||
wxWindowDisabler *wd = new wxWindowDisabler;
|
||||
|
||||
@ -183,7 +188,7 @@ void *wxGUIAppTraits::BeforeChildWaitLoop()
|
||||
);
|
||||
winActive->Show();
|
||||
|
||||
return new ChildWaitLoopData(wd, winActive);
|
||||
return new ChildWaitLoopData(wd, focus, winActive);
|
||||
}
|
||||
|
||||
void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
|
||||
@ -194,6 +199,9 @@ void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
|
||||
|
||||
delete data->wd;
|
||||
|
||||
if ( data->focused )
|
||||
data->focused->SetFocus();
|
||||
|
||||
// finally delete the dummy dialog and, as wd has been already destroyed
|
||||
// and the other windows reenabled, the activation is going to return to
|
||||
// the window which had had it before
|
||||
|
Loading…
Reference in New Issue
Block a user