From 2005b4430fa91a89da35e39b356317a72cf86cf0 Mon Sep 17 00:00:00 2001 From: RenaKunisaki Date: Mon, 16 May 2016 15:09:59 -0400 Subject: [PATCH 1/2] Fix window focus detection on Linux On Linux, the FindFocus method from wx simply doesn't work, it would on some environment report that dolphin has the focus while it doesn't have it. This is why an alternative method has to be used which is to set a focus flag whenever the render frame gets activated. --- Source/Core/DolphinWX/Frame.cpp | 63 ++++++---------------------- Source/Core/DolphinWX/Frame.h | 3 +- Source/Core/DolphinWX/FrameTools.cpp | 4 +- 3 files changed, 15 insertions(+), 55 deletions(-) diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index 5978dfc49d..c0e09ebdfb 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -504,18 +504,25 @@ void CFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) // Events void CFrame::OnActive(wxActivateEvent& event) { + m_bHasFocus = (event.GetActive() && event.GetEventObject() == m_RenderFrame); if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE) { - if (event.GetActive() && event.GetEventObject() == m_RenderFrame) + if (m_bHasFocus) { if (SConfig::GetInstance().bRenderToMain) m_RenderParent->SetFocus(); + if (SConfig::GetInstance().m_PauseOnFocusLost && Core::GetState() == Core::CORE_PAUSE) + DoPause(); + if (SConfig::GetInstance().bHideCursor && Core::GetState() == Core::CORE_RUN) m_RenderParent->SetCursor(wxCURSOR_BLANK); } else { + if (SConfig::GetInstance().m_PauseOnFocusLost && Core::GetState() == Core::CORE_RUN) + DoPause(); + if (SConfig::GetInstance().bHideCursor) m_RenderParent->SetCursor(wxNullCursor); } @@ -769,27 +776,11 @@ bool CFrame::RendererHasFocus() { if (m_RenderParent == nullptr) return false; -#ifdef _WIN32 - HWND window = GetForegroundWindow(); - if (window == nullptr) - return false; - - if (m_RenderFrame->GetHWND() == window) - return true; -#else - wxWindow* window = wxWindow::FindFocus(); - if (window == nullptr) - return false; - // Why these different cases? - if (m_RenderParent == window || m_RenderParent == window->GetParent() || - m_RenderParent->GetParent() == window->GetParent()) - { - return true; - } -#endif - return false; + return m_bRendererHasFocus; } +// Returns true any time any one of our UI windows +// has the focus, including any dialogs or other windows. bool CFrame::UIHasFocus() { // UIHasFocus should return true any time any one of our UI @@ -799,8 +790,7 @@ bool CFrame::UIHasFocus() // focus. If it's not one of our windows, then it will return // null. - wxWindow* focusWindow = wxWindow::FindFocus(); - return (focusWindow != nullptr); + return m_bHasFocus; } void CFrame::OnGameListCtrlItemActivated(wxListEvent& WXUNUSED(event)) @@ -1139,35 +1129,6 @@ void CFrame::OnMouse(wxMouseEvent& event) event.Skip(); } -void CFrame::OnFocusChange(wxFocusEvent& event) -{ - if (SConfig::GetInstance().m_PauseOnFocusLost && Core::IsRunningAndStarted()) - { - if (RendererHasFocus()) - { - if (Core::GetState() == Core::CORE_PAUSE) - { - Core::SetState(Core::CORE_RUN); - if (SConfig::GetInstance().bHideCursor) - m_RenderParent->SetCursor(wxCURSOR_BLANK); - } - } - else - { - if (Core::GetState() == Core::CORE_RUN) - { - Core::SetState(Core::CORE_PAUSE); - if (SConfig::GetInstance().bHideCursor) - m_RenderParent->SetCursor(wxNullCursor); - Core::UpdateTitle(); - } - } - UpdateGUI(); - } - - event.Skip(); -} - void CFrame::DoFullscreen(bool enable_fullscreen) { if (g_Config.bExclusiveMode && Core::GetState() == Core::CORE_PAUSE) diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h index 883b2db9f4..8bf27c1620 100644 --- a/Source/Core/DolphinWX/Frame.h +++ b/Source/Core/DolphinWX/Frame.h @@ -158,6 +158,7 @@ private: bool m_bNoDocking = false; bool m_bGameLoading = false; bool m_bClosing = false; + bool m_bHasFocus = false; bool m_confirmStop = false; bool m_tried_graceful_shutdown = false; int m_saveSlot = 1; @@ -306,8 +307,6 @@ private: void OnKeyDown(wxKeyEvent& event); // Keyboard void OnMouse(wxMouseEvent& event); // Mouse - void OnFocusChange(wxFocusEvent& event); - void OnHostMessage(wxCommandEvent& event); void OnMemcard(wxCommandEvent& event); // Misc diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index a4e3a0ae52..fb85d22cc4 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -733,8 +733,6 @@ void CFrame::StartGame(const std::string& filename) wxTheApp->Bind(wxEVT_MIDDLE_DOWN, &CFrame::OnMouse, this); wxTheApp->Bind(wxEVT_MIDDLE_UP, &CFrame::OnMouse, this); wxTheApp->Bind(wxEVT_MOTION, &CFrame::OnMouse, this); - wxTheApp->Bind(wxEVT_SET_FOCUS, &CFrame::OnFocusChange, this); - wxTheApp->Bind(wxEVT_KILL_FOCUS, &CFrame::OnFocusChange, this); m_RenderParent->Bind(wxEVT_SIZE, &CFrame::OnRenderParentResize, this); } } @@ -926,6 +924,8 @@ void CFrame::OnStopped() m_RenderFrame->SetWindowStyle(m_RenderFrame->GetWindowStyle() & ~wxSTAY_ON_TOP); } m_RenderParent = nullptr; + m_bRendererHasFocus = false; + m_RenderFrame = nullptr; // Clean framerate indications from the status bar. GetStatusBar()->SetStatusText(" ", 0); From ee201455a8810803a9966b951815143786a0767d Mon Sep 17 00:00:00 2001 From: aldelaro5 Date: Thu, 27 Oct 2016 21:50:09 -0400 Subject: [PATCH 2/2] Move UiHasFocus into DolphinApp Using a wxEVT_ACTIVATE_APP event. --- Source/Core/DolphinWX/Frame.cpp | 18 ++---------------- Source/Core/DolphinWX/Frame.h | 3 +-- Source/Core/DolphinWX/Main.cpp | 8 +++++++- Source/Core/DolphinWX/Main.h | 3 +++ 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index c0e09ebdfb..a07586ad9c 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -504,10 +504,10 @@ void CFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) // Events void CFrame::OnActive(wxActivateEvent& event) { - m_bHasFocus = (event.GetActive() && event.GetEventObject() == m_RenderFrame); + m_bRendererHasFocus = (event.GetActive() && event.GetEventObject() == m_RenderFrame); if (Core::GetState() == Core::CORE_RUN || Core::GetState() == Core::CORE_PAUSE) { - if (m_bHasFocus) + if (m_bRendererHasFocus) { if (SConfig::GetInstance().bRenderToMain) m_RenderParent->SetFocus(); @@ -779,20 +779,6 @@ bool CFrame::RendererHasFocus() return m_bRendererHasFocus; } -// Returns true any time any one of our UI windows -// has the focus, including any dialogs or other windows. -bool CFrame::UIHasFocus() -{ - // UIHasFocus should return true any time any one of our UI - // windows has the focus, including any dialogs or other windows. - // - // wxWindow::FindFocus() returns the current wxWindow which has - // focus. If it's not one of our windows, then it will return - // null. - - return m_bHasFocus; -} - void CFrame::OnGameListCtrlItemActivated(wxListEvent& WXUNUSED(event)) { // Show all platforms and regions if... diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h index 8bf27c1620..99358f4de3 100644 --- a/Source/Core/DolphinWX/Frame.h +++ b/Source/Core/DolphinWX/Frame.h @@ -101,7 +101,6 @@ public: void OnRenderParentClose(wxCloseEvent& event); void OnRenderParentMove(wxMoveEvent& event); bool RendererHasFocus(); - bool UIHasFocus(); bool RendererIsFullscreen(); void DoFullscreen(bool bF); void ToggleDisplayMode(bool bFullscreen); @@ -158,7 +157,7 @@ private: bool m_bNoDocking = false; bool m_bGameLoading = false; bool m_bClosing = false; - bool m_bHasFocus = false; + bool m_bRendererHasFocus = false; bool m_confirmStop = false; bool m_tried_graceful_shutdown = false; int m_saveSlot = 1; diff --git a/Source/Core/DolphinWX/Main.cpp b/Source/Core/DolphinWX/Main.cpp index bdf6ada482..6620275cfa 100644 --- a/Source/Core/DolphinWX/Main.cpp +++ b/Source/Core/DolphinWX/Main.cpp @@ -84,6 +84,7 @@ bool DolphinApp::OnInit() Bind(wxEVT_QUERY_END_SESSION, &DolphinApp::OnEndSession, this); Bind(wxEVT_END_SESSION, &DolphinApp::OnEndSession, this); Bind(wxEVT_IDLE, &DolphinApp::OnIdle, this); + Bind(wxEVT_ACTIVATE_APP, &DolphinApp::OnActivate, this); // Register message box and translation handlers RegisterMsgAlertHandler(&wxMsgAlert); @@ -256,6 +257,11 @@ void DolphinApp::AfterInit() } } +void DolphinApp::OnActivate(wxActivateEvent& ev) +{ + m_is_active = ev.GetActive(); +} + void DolphinApp::InitLanguageSupport() { std::string language_code; @@ -500,7 +506,7 @@ void Host_SetWiiMoteConnectionState(int _State) bool Host_UIHasFocus() { - return main_frame->UIHasFocus(); + return wxGetApp().IsActiveThreadsafe(); } bool Host_RendererHasFocus() diff --git a/Source/Core/DolphinWX/Main.h b/Source/Core/DolphinWX/Main.h index 803ee3baa9..e1bfd8df25 100644 --- a/Source/Core/DolphinWX/Main.h +++ b/Source/Core/DolphinWX/Main.h @@ -16,6 +16,7 @@ extern CFrame* main_frame; class DolphinApp : public wxApp { public: + bool IsActiveThreadsafe() const { return m_is_active; } CFrame* GetCFrame(); private: @@ -33,10 +34,12 @@ private: void OnEndSession(wxCloseEvent& event); void InitLanguageSupport(); void AfterInit(); + void OnActivate(wxActivateEvent& ev); void OnIdle(wxIdleEvent&); bool m_batch_mode = false; bool m_confirm_stop = false; + bool m_is_active = true; bool m_load_file = false; bool m_play_movie = false; bool m_use_debugger = false;