wxWidgets and KiCad fixes for quasi-modal dialogs.
OSX activates windows before telling the application, so there's no good way to implement wxWidgets window enable/disable. This patch keeps the quasi-modal dialog and its parent windows order in the z-list fixed, and re-activates the quasi-modal dialog whenever the OS activates the parent window.
This commit is contained in:
parent
41f5c754e5
commit
786312b103
|
@ -112,30 +112,21 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
|
|||
}
|
||||
|
||||
|
||||
DIALOG_SHIM* findQuasiModalDialog( wxWindowList& aList )
|
||||
{
|
||||
for( wxWindowList::iterator iter = aList.begin(); iter != aList.end(); ++iter )
|
||||
{
|
||||
DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( *iter );
|
||||
if( dlg && dlg->IsQuasiModal() )
|
||||
return dlg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
|
||||
{
|
||||
DIALOG_SHIM* dlg = NULL;
|
||||
wxWindowList list = GetChildren();
|
||||
|
||||
// Quasi modal dialogs create issues (crashes) when closing Kicad.
|
||||
// I am guessing they are delete too late, when deleting main frames.
|
||||
// AFAIK, only these DIALOG_SHIM dialogs create such issues.
|
||||
// The policy is do not allow closing Kicad if a Quasi modal dialog is open.
|
||||
// (Anyway, closing without prompting the user is certainly bad,
|
||||
// because an edit is in preogress)
|
||||
// Therefore, iterate through the child list to find at least
|
||||
// a DIALOG_SHIM opened in quasi modal mode
|
||||
for( wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter )
|
||||
{
|
||||
if( (dlg = dynamic_cast<DIALOG_SHIM*> (*iter) ) != NULL )
|
||||
{
|
||||
if( dlg->IsQuasiModal() )
|
||||
break;
|
||||
else
|
||||
dlg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DIALOG_SHIM* dlg = findQuasiModalDialog( GetChildren() );
|
||||
if( dlg )
|
||||
{
|
||||
// Happens when a quasi modal dialog is currently open.
|
||||
|
@ -184,6 +175,13 @@ EDA_BASE_FRAME::~EDA_BASE_FRAME()
|
|||
|
||||
bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent )
|
||||
{
|
||||
if( !IsEnabled() && IsActive() )
|
||||
{
|
||||
DIALOG_SHIM* dlg = findQuasiModalDialog( GetChildren() );
|
||||
if( dlg )
|
||||
dlg->Raise();
|
||||
}
|
||||
|
||||
if( !wxFrame::ProcessEvent( aEvent ) )
|
||||
return false;
|
||||
|
||||
|
|
|
@ -565,6 +565,13 @@ int DIALOG_SHIM::ShowQuasiModal()
|
|||
// quasi-modal: disable only my "optimal" parent
|
||||
m_qmodal_parent_disabler = new WDO_ENABLE_DISABLE( parent );
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// 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 quasi-modal will be pushed in front of the disabled
|
||||
// window when it is raised.
|
||||
ReparentQuasiModal();
|
||||
#endif
|
||||
Show( true );
|
||||
|
||||
m_qmodal_showing = true;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
From 0cc169ec53f5eb50e6f1e77c2f73f4631561d574 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Young <jeff@rokeby.ie>
|
||||
Date: Tue, 9 Jan 2018 12:04:20 +0000
|
||||
Subject: [PATCH 1/1] Backport OSX disabled-window fixes from master.
|
||||
|
||||
Also adds ReparentQuasiModal() which is required for Kicad
|
||||
quasi-modal dialogs.
|
||||
---
|
||||
src/osx/cocoa/dialog.mm | 12 ++++++++++++
|
||||
src/osx/cocoa/window.mm | 13 ++++++++++++-
|
||||
2 files changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/osx/cocoa/dialog.mm b/src/osx/cocoa/dialog.mm
|
||||
index 8b1e48f1b4..c6b508013e 100644
|
||||
--- a/src/osx/cocoa/dialog.mm
|
||||
+++ b/src/osx/cocoa/dialog.mm
|
||||
@@ -44,3 +44,15 @@
|
||||
[NSApp endSheet: GetWXWindow()];
|
||||
[GetWXWindow() orderOut:GetWXWindow()];
|
||||
}
|
||||
+
|
||||
+void wxDialog::ReparentQuasiModal()
|
||||
+{
|
||||
+ wxTopLevelWindow* parent = static_cast<wxTopLevelWindow*>(wxGetTopLevelParent(GetParent()));
|
||||
+
|
||||
+ wxASSERT_MSG(parent, "QuasiModal dialogs require a parent.");
|
||||
+
|
||||
+ NSWindow* parentWindow = parent->GetWXWindow();
|
||||
+ NSWindow* theWindow = GetWXWindow();
|
||||
+
|
||||
+ [parentWindow addChildWindow:theWindow ordered:NSWindowAbove];
|
||||
+}
|
||||
diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm
|
||||
index ede8ebf778..2366d65d6b 100644
|
||||
--- a/src/osx/cocoa/window.mm
|
||||
+++ b/src/osx/cocoa/window.mm
|
||||
@@ -863,6 +863,15 @@ - (BOOL) canBecomeKeyView
|
||||
return NO;
|
||||
}
|
||||
|
||||
+- (NSView *)hitTest:(NSPoint)aPoint;
|
||||
+{
|
||||
+ wxWidgetCocoaImpl* viewimpl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
|
||||
+ if ( viewimpl && viewimpl->GetWXPeer() && !viewimpl->GetWXPeer()->IsEnabled() )
|
||||
+ return nil;
|
||||
+
|
||||
+ return [super hitTest:aPoint];
|
||||
+}
|
||||
+
|
||||
@end // wxNSView
|
||||
|
||||
// We need to adopt NSTextInputClient protocol in order to interpretKeyEvents: to work.
|
||||
@@ -985,7 +994,9 @@ void wxOSX_mouseEvent(NSView* self, SEL _cmd, NSEvent *event)
|
||||
if (impl == NULL)
|
||||
return;
|
||||
|
||||
- impl->mouseEvent(event, self, _cmd);
|
||||
+ // We shouldn't let disabled windows get mouse events.
|
||||
+ if (impl->GetWXPeer()->IsEnabled())
|
||||
+ impl->mouseEvent(event, self, _cmd);
|
||||
}
|
||||
|
||||
void wxOSX_cursorUpdate(NSView* self, SEL _cmd, NSEvent *event)
|
||||
--
|
||||
2.14.3 (Apple Git-98)
|
||||
|
Loading…
Reference in New Issue