Don't steal focus from other windows on GTK

Before, it was possible for the canvas to steal the
focus if the cursor was only moved over it and not
clicked. Now, the canvas will only take the focus if
the frame is active.

Fixes https://gitlab.com/kicad/code/kicad/issues/7233
This commit is contained in:
Ian McInerney 2021-04-03 00:04:33 +01:00
parent d7a95e2af4
commit 8ea18c0639
5 changed files with 43 additions and 16 deletions

View File

@ -48,6 +48,8 @@
#include <widgets/infobar.h>
#include <kiplatform/ui.h>
#ifdef PROFILE
#include <profile.h>
#endif /* PROFILE */
@ -488,14 +490,10 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
void EDA_DRAW_PANEL_GAL::OnEvent( wxEvent& aEvent )
{
bool shouldSetFocus = m_lostFocus && m_stealsFocus && !KIUI::IsInputControlFocused()
&& !KIUI::IsModalDialogFocused();
#if defined( _WIN32 )
// Ensure we are the active foreground window before we attempt to steal focus
// mouse events are generated on Win32 regardless if window is active
shouldSetFocus = shouldSetFocus && ( m_edaFrame->GetHWND() == GetForegroundWindow() );
#endif
bool shouldSetFocus = m_lostFocus && m_stealsFocus
&& !KIUI::IsInputControlFocused() // Don't steal from input controls
&& !KIUI::IsModalDialogFocused() // Don't steal from dialogs
&& KIPLATFORM::UI::IsWindowActive( m_edaFrame ); // Don't steal from other windows
if( shouldSetFocus )
SetFocus();
@ -511,14 +509,10 @@ void EDA_DRAW_PANEL_GAL::OnEvent( wxEvent& aEvent )
void EDA_DRAW_PANEL_GAL::onEnter( wxMouseEvent& aEvent )
{
bool shouldSetFocus =
m_stealsFocus && !KIUI::IsInputControlFocused() && !KIUI::IsModalDialogFocused();
#if defined( _WIN32 )
// Ensure we are the active foreground window before we attempt to steal focus
// mouse events are generated on Win32 regardless if window is active
shouldSetFocus = shouldSetFocus && ( m_edaFrame->GetHWND() == GetForegroundWindow() );
#endif
bool shouldSetFocus = m_stealsFocus
&& !KIUI::IsInputControlFocused() // Don't steal from input controls
&& !KIUI::IsModalDialogFocused() // Don't steal from dialogs
&& KIPLATFORM::UI::IsWindowActive( m_edaFrame ); // Don't steal from other windows
// Getting focus is necessary in order to receive key events properly
if( shouldSetFocus )

View File

@ -47,6 +47,18 @@ void KIPLATFORM::UI::ForceFocus( wxWindow* aWindow )
}
bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow )
{
GtkWindow* window = GTK_WINDOW( aWindow->GetHandle() );
if( window )
return gtk_window_is_active( window );
// We shouldn't really ever reach this point
return false;
}
void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow )
{
// Not needed on this platform

View File

@ -47,6 +47,14 @@ namespace KIPLATFORM
*/
void ForceFocus( wxWindow* aWindow );
/**
* Check to see if the given window is the currently active window (e.g. the window
* in the foreground the user is interacting with).
*
* @param aWindow is the window to check
*/
bool IsWindowActive( wxWindow* aWindow );
/**
* Move a window's parent to be the top-level window and force the window to be on top.
*

View File

@ -71,6 +71,12 @@ void KIPLATFORM::UI::ForceFocus( wxWindow* aWindow )
}
bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow )
{
return ( aWindow->GetHWND() == GetForegroundWindow() );
}
void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow )
{
// Not needed on this platform

View File

@ -42,6 +42,13 @@ void KIPLATFORM::UI::ForceFocus( wxWindow* aWindow )
}
bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow )
{
// Just always return true
return true;
}
void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow )
{
wxTopLevelWindow* parent =