Fix event blocker on GTK
We block events when a modal window is active. But detecting when the modal window is closed is harder on GTK than just counting modal closes because the modal flag can sometimes be unset before the wxEVT_SHOW event fires. Instead, we track the stack of modal windows opened and close the window and subsequent windows when the object pointer matches Fixes https://gitlab.com/kicad/code/kicad/issues/13372
This commit is contained in:
parent
cbfbd3a0de
commit
fa91d906d0
|
@ -123,7 +123,6 @@ PGM_BASE::PGM_BASE()
|
||||||
m_locale = nullptr;
|
m_locale = nullptr;
|
||||||
m_Printing = false;
|
m_Printing = false;
|
||||||
m_Quitting = false;
|
m_Quitting = false;
|
||||||
m_ModalDialogCount = 0;
|
|
||||||
m_argcUtf8 = 0;
|
m_argcUtf8 = 0;
|
||||||
m_argvUtf8 = nullptr;
|
m_argvUtf8 = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -215,8 +215,25 @@ struct APP_SINGLE_TOP : public wxApp
|
||||||
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
||||||
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
||||||
|
|
||||||
if( dialog && dialog->IsModal() )
|
std::vector<void*>& dlgs = Pgm().m_ModalDialogs;
|
||||||
Pgm().m_ModalDialogCount += event.IsShown() ? 1 : -1;
|
|
||||||
|
if( dialog )
|
||||||
|
{
|
||||||
|
if( event.IsShown() && dialog->IsModal() )
|
||||||
|
{
|
||||||
|
dlgs.push_back( dialog );
|
||||||
|
}
|
||||||
|
// Under GTK, sometimes the modal flag is cleared before hiding
|
||||||
|
else if( !event.IsShown() )
|
||||||
|
{
|
||||||
|
// If we close the expected dialog, remove it from our stack
|
||||||
|
if( dlgs.back() == dialog )
|
||||||
|
dlgs.pop_back();
|
||||||
|
// If an out-of-order, remove all dialogs added after the closed one
|
||||||
|
else if( auto it = std::find( dlgs.begin(), dlgs.end(), dialog ) ; it != dlgs.end() )
|
||||||
|
dlgs.erase( it, dlgs.end() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Event_Skip;
|
return Event_Skip;
|
||||||
|
|
|
@ -314,7 +314,7 @@ bool KIUI::IsInputControlEditable( wxWindow* aFocus )
|
||||||
|
|
||||||
bool KIUI::IsModalDialogFocused()
|
bool KIUI::IsModalDialogFocused()
|
||||||
{
|
{
|
||||||
return Pgm().m_ModalDialogCount > 0;
|
return !Pgm().m_ModalDialogs.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -350,4 +350,4 @@ void KIUI::Disable( wxWindow* aWindow )
|
||||||
for( wxWindow* child : aWindow->GetChildren() )
|
for( wxWindow* child : aWindow->GetChildren() )
|
||||||
Disable( child );
|
Disable( child );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define PGM_BASE_H_
|
#define PGM_BASE_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <search_stack.h>
|
#include <search_stack.h>
|
||||||
#include <settings/environment.h>
|
#include <settings/environment.h>
|
||||||
|
@ -302,7 +303,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool m_Printing;
|
bool m_Printing;
|
||||||
|
|
||||||
int m_ModalDialogCount;
|
std::vector<void*> m_ModalDialogs;
|
||||||
|
|
||||||
bool m_Quitting;
|
bool m_Quitting;
|
||||||
|
|
||||||
|
|
|
@ -476,8 +476,25 @@ struct APP_KICAD : public wxApp
|
||||||
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
||||||
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
||||||
|
|
||||||
if( dialog && dialog->IsModal() )
|
std::vector<void*>& dlgs = Pgm().m_ModalDialogs;
|
||||||
Pgm().m_ModalDialogCount += event.IsShown() ? 1 : -1;
|
|
||||||
|
if( dialog )
|
||||||
|
{
|
||||||
|
if( event.IsShown() && dialog->IsModal() )
|
||||||
|
{
|
||||||
|
dlgs.push_back( dialog );
|
||||||
|
}
|
||||||
|
// Under GTK, sometimes the modal flag is cleared before hiding
|
||||||
|
else if( !event.IsShown() )
|
||||||
|
{
|
||||||
|
// If we close the expected dialog, remove it from our stack
|
||||||
|
if( dlgs.back() == dialog )
|
||||||
|
dlgs.pop_back();
|
||||||
|
// If an out-of-order, remove all dialogs added after the closed one
|
||||||
|
else if( auto it = std::find( dlgs.begin(), dlgs.end(), dialog ) ; it != dlgs.end() )
|
||||||
|
dlgs.erase( it, dlgs.end() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Event_Skip;
|
return Event_Skip;
|
||||||
|
|
|
@ -503,8 +503,25 @@ struct APP_KICAD_CLI : public wxAppConsole
|
||||||
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
||||||
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
||||||
|
|
||||||
if( dialog && dialog->IsModal() )
|
std::vector<void*>& dlgs = Pgm().m_ModalDialogs;
|
||||||
Pgm().m_ModalDialogCount += event.IsShown() ? 1 : -1;
|
|
||||||
|
if( dialog )
|
||||||
|
{
|
||||||
|
if( event.IsShown() && dialog->IsModal() )
|
||||||
|
{
|
||||||
|
dlgs.push_back( dialog );
|
||||||
|
}
|
||||||
|
// Under GTK, sometimes the modal flag is cleared before hiding
|
||||||
|
else if( !event.IsShown() )
|
||||||
|
{
|
||||||
|
// If we close the expected dialog, remove it from our stack
|
||||||
|
if( dlgs.back() == dialog )
|
||||||
|
dlgs.pop_back();
|
||||||
|
// If an out-of-order, remove all dialogs added after the closed one
|
||||||
|
else if( auto it = std::find( dlgs.begin(), dlgs.end(), dialog ) ; it != dlgs.end() )
|
||||||
|
dlgs.erase( it, dlgs.end() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Event_Skip;
|
return Event_Skip;
|
||||||
|
|
Loading…
Reference in New Issue