From ce90336dffdeb8ae1efdae9842574f12bbad90d5 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 21 Jan 2018 20:41:52 +0100 Subject: [PATCH] Fixing popup windows with a modal dialog as parent When having a certain creation sequence, these popup windows were not focused correctly, see https://github.com/wxWidgets/wxWidgets/pull/672 , commit d2265136e359df4d14054860a68bbc7f4910279d , revert this change if problems arise to see whether this is a recursion --- include/wx/osx/cocoa/private.h | 4 +++ src/osx/cocoa/nonownedwnd.mm | 62 ++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index db182e4479..07402e06d1 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -288,6 +288,10 @@ protected : CGWindowLevel m_macWindowLevel; WXWindow m_macWindow; void * m_macFullScreenData ; + +private: + void SetUpForModalParent(); + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxNonOwnedWindowCocoaImpl); }; diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index 735ed8f5e4..9291601699 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -733,31 +733,9 @@ long style, long extraStyle, const wxString& WXUNUSED(name) ) [[m_macWindow standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; } - // If the parent is modal, windows with wxFRAME_FLOAT_ON_PARENT style need - // to be in NSModalPanelWindowLevel and not NSFloatingWindowLevel to stay - // above the parent. - wxDialog * const parentDialog = parent == NULL ? NULL : wxDynamicCast(parent->MacGetTopLevelWindow(), wxDialog); - if (parentDialog && parentDialog->IsModal()) - { - if (level == NSFloatingWindowLevel) - { - level = NSModalPanelWindowLevel; - } - - // Cocoa's modal loop does not process other windows by default, but - // don't call this on normal window levels so nested modal dialogs will - // still behave modally. - if (level != NSNormalWindowLevel) - { - if ([m_macWindow isKindOfClass:[NSPanel class]]) - { - [(NSPanel*)m_macWindow setWorksWhenModal:YES]; - } - } - } - - [m_macWindow setLevel:level]; m_macWindowLevel = level; + SetUpForModalParent(); + [m_macWindow setLevel:m_macWindowLevel]; [m_macWindow setDelegate:controller]; @@ -791,8 +769,41 @@ void wxNonOwnedWindowCocoaImpl::Lower() [m_macWindow orderWindow:NSWindowBelow relativeTo:0]; } +void wxNonOwnedWindowCocoaImpl::SetUpForModalParent() +{ + wxNonOwnedWindow* wxpeer = GetWXPeer(); + if (wxpeer) + { + // If the parent is modal, windows with wxFRAME_FLOAT_ON_PARENT style need + // to be in NSModalPanelWindowLevel and not NSFloatingWindowLevel to stay + // above the parent. + wxDialog* const parentDialog = wxDynamicCast(wxGetTopLevelParent(wxpeer->GetParent()), wxDialog); + if (parentDialog && parentDialog->IsModal()) + { + if (m_macWindowLevel == NSFloatingWindowLevel) + { + m_macWindowLevel = NSModalPanelWindowLevel; + if ([m_macWindow level] == NSFloatingWindowLevel) + [m_macWindow setLevel:m_macWindowLevel]; + } + + // Cocoa's modal loop does not process other windows by default, but + // don't call this on normal window levels so nested modal dialogs will + // still behave modally. + if (m_macWindowLevel != NSNormalWindowLevel) + { + if ([m_macWindow isKindOfClass:[NSPanel class]]) + { + [(NSPanel*)m_macWindow setWorksWhenModal:YES]; + } + } + } + } +} + void wxNonOwnedWindowCocoaImpl::ShowWithoutActivating() { + SetUpForModalParent(); [m_macWindow orderFront:nil]; [[m_macWindow contentView] setNeedsDisplay: YES]; } @@ -826,7 +837,8 @@ bool wxNonOwnedWindowCocoaImpl::Show(bool show) } } - if (!(wxpeer->GetWindowStyle() & wxFRAME_TOOL_WINDOW)) + SetUpForModalParent(); + if (!(wxpeer->GetWindowStyle() & wxFRAME_TOOL_WINDOW)) [m_macWindow makeKeyAndOrderFront:nil]; else [m_macWindow orderFront:nil];