From 3ad92bc8db1e02ec5c7fc06cfe59a10fd755f087 Mon Sep 17 00:00:00 2001 From: Andrej Valek Date: Sun, 27 Oct 2024 16:37:47 +0000 Subject: [PATCH] ShowModal: override method in DIALOG_SHIM All DIALOG_SHIM dialogues which should be modal, has a problem on OSX that parent could be lost. So call ReparentModal to fix this before calling the base ShowModal method. This should fix the problem when modal window has been hidden when windows were switched. Fixes: https://gitlab.com/kicad/code/kicad/-/issues/3765 Fixes: https://gitlab.com/kicad/code/kicad/-/issues/17460 --- common/dialog_shim.cpp | 13 ++++++++++++- include/dialog_shim.h | 2 ++ libs/kiplatform/include/kiplatform/ui.h | 2 +- libs/kiplatform/port/wxgtk/ui.cpp | 2 +- libs/kiplatform/port/wxmsw/ui.cpp | 2 +- libs/kiplatform/port/wxosx/ui.mm | 4 ++-- pcbnew/footprint_chooser_frame.cpp | 2 +- pcbnew/tools/pcb_viewer_tools.cpp | 2 +- 8 files changed, 21 insertions(+), 8 deletions(-) diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index b6337d81c5..87340ec3ef 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -471,6 +471,17 @@ void DIALOG_SHIM::ClearModify() SetTitle( GetTitle().AfterFirst( '*' ) ); } +int DIALOG_SHIM::ShowModal() +{ + // Apple in its infinite wisdom will raise a disabled window before even passing + // us the event, so we have no way to stop it. Instead, we must set an order on + // the windows so that the modal will be pushed in front of the disabled + // window when it is raised. + KIPLATFORM::UI::ReparentModal( this ); + + // Call the base class ShowModal() method + return wxDialog::ShowModal(); +} /* Quasi-Modal Mode Explained: @@ -527,7 +538,7 @@ int DIALOG_SHIM::ShowQuasiModal() // us the event, so we have no way to stop it. Instead, we must set an order on // the windows so that the quasi-modal will be pushed in front of the disabled // window when it is raised. - KIPLATFORM::UI::ReparentQuasiModal( this ); + KIPLATFORM::UI::ReparentModal( this ); Show( true ); diff --git a/include/dialog_shim.h b/include/dialog_shim.h index 1cc2ca1b02..2233a67c6a 100644 --- a/include/dialog_shim.h +++ b/include/dialog_shim.h @@ -104,6 +104,8 @@ public: m_initialFocusTarget = aWindow; } + int ShowModal() override; + int ShowQuasiModal(); // disable only the parent window, otherwise modal. void EndQuasiModal( int retCode ); // End quasi-modal mode diff --git a/libs/kiplatform/include/kiplatform/ui.h b/libs/kiplatform/include/kiplatform/ui.h index 7e9e0510bf..4ee0fad941 100644 --- a/libs/kiplatform/include/kiplatform/ui.h +++ b/libs/kiplatform/include/kiplatform/ui.h @@ -69,7 +69,7 @@ namespace KIPLATFORM * * @param aWindow is the window to reparent */ - void ReparentQuasiModal( wxNonOwnedWindow* aWindow ); + void ReparentModal( wxNonOwnedWindow* aWindow ); /* * An ugly hack to fix an issue on OSX: cmd+c closes the dialog instead of copying the diff --git a/libs/kiplatform/port/wxgtk/ui.cpp b/libs/kiplatform/port/wxgtk/ui.cpp index c3c0e15a21..53cd21feee 100644 --- a/libs/kiplatform/port/wxgtk/ui.cpp +++ b/libs/kiplatform/port/wxgtk/ui.cpp @@ -85,7 +85,7 @@ bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow ) } -void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow ) +void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow ) { // Not needed on this platform } diff --git a/libs/kiplatform/port/wxmsw/ui.cpp b/libs/kiplatform/port/wxmsw/ui.cpp index b3f45ddcb2..e039d0b709 100644 --- a/libs/kiplatform/port/wxmsw/ui.cpp +++ b/libs/kiplatform/port/wxmsw/ui.cpp @@ -90,7 +90,7 @@ bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow ) } -void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow ) +void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow ) { // Not needed on this platform } diff --git a/libs/kiplatform/port/wxosx/ui.mm b/libs/kiplatform/port/wxosx/ui.mm index 6ff859d34b..370b714856 100644 --- a/libs/kiplatform/port/wxosx/ui.mm +++ b/libs/kiplatform/port/wxosx/ui.mm @@ -76,12 +76,12 @@ bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow ) } -void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow ) +void KIPLATFORM::UI::ReparentModal( wxNonOwnedWindow* aWindow ) { wxTopLevelWindow* parent = static_cast( wxGetTopLevelParent( aWindow->GetParent() ) ); - wxASSERT_MSG(parent, wxT( "QuasiModal windows require a parent.") ); + wxASSERT_MSG(parent, wxT( "Modal windows require a parent.") ); NSWindow* parentWindow = parent->GetWXWindow(); NSWindow* theWindow = aWindow->GetWXWindow(); diff --git a/pcbnew/footprint_chooser_frame.cpp b/pcbnew/footprint_chooser_frame.cpp index 8744c6fe1e..b12a041672 100644 --- a/pcbnew/footprint_chooser_frame.cpp +++ b/pcbnew/footprint_chooser_frame.cpp @@ -257,7 +257,7 @@ void FOOTPRINT_CHOOSER_FRAME::Show3DViewerFrame() EDA_3D_VIEWER_FRAME* draw3DFrame = CreateAndShow3D_Frame(); // A stronger version of Raise() which promotes the window to its parent's level. - KIPLATFORM::UI::ReparentQuasiModal( draw3DFrame ); + KIPLATFORM::UI::ReparentModal( draw3DFrame ); // And load or update the current board (if needed) if( do_reload_board ) diff --git a/pcbnew/tools/pcb_viewer_tools.cpp b/pcbnew/tools/pcb_viewer_tools.cpp index 97ef5e45b7..039fc9cb10 100644 --- a/pcbnew/tools/pcb_viewer_tools.cpp +++ b/pcbnew/tools/pcb_viewer_tools.cpp @@ -80,7 +80,7 @@ int PCB_VIEWER_TOOLS::Show3DViewer( const TOOL_EVENT& aEvent ) || frame()->IsType( FRAME_FOOTPRINT_WIZARD ) ) { // A stronger version of Raise() which promotes the window to its parent's level. - KIPLATFORM::UI::ReparentQuasiModal( draw3DFrame ); + KIPLATFORM::UI::ReparentModal( draw3DFrame ); } // And load or update the current board (if needed)