From a2d2c0b1c6b503322b36faa040fed4febe141bed Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 17 Aug 2021 19:15:24 +0100 Subject: [PATCH] Fixup for modal windows, tested on macOS --- dpf/dgl/Window.hpp | 2 + dpf/dgl/src/WindowPrivateData.cpp | 61 +++++++++++-------------------- dpf/dgl/src/pugl.cpp | 58 ++++++++++++++++++++++++----- dpf/dgl/src/pugl.hpp | 16 ++++++-- 4 files changed, 85 insertions(+), 52 deletions(-) diff --git a/dpf/dgl/Window.hpp b/dpf/dgl/Window.hpp index e64035e..b5931ec 100644 --- a/dpf/dgl/Window.hpp +++ b/dpf/dgl/Window.hpp @@ -408,6 +408,8 @@ protected: This method is not used for embed windows, and not even made available in DISTRHO_NAMESPACE::UI. For embed windows, closing is handled by the host/parent process and we have no control over it. As such, a close action on embed windows will always succeed and cannot be cancelled. + + NOTE: This currently does not work under macOS. */ virtual bool onClose(); diff --git a/dpf/dgl/src/WindowPrivateData.cpp b/dpf/dgl/src/WindowPrivateData.cpp index 95cdf40..9dd7a8c 100644 --- a/dpf/dgl/src/WindowPrivateData.cpp +++ b/dpf/dgl/src/WindowPrivateData.cpp @@ -286,15 +286,6 @@ void Window::PrivateData::show() DGL_DBG("Window show called\n"); -#if 0 && defined(DISTRHO_OS_MAC) -// if (mWindow != nullptr) -// { -// if (mParentWindow != nullptr) -// [mParentWindow addChildWindow:mWindow -// ordered:NSWindowAbove]; -// } -#endif - if (isClosed) { isClosed = false; @@ -337,14 +328,6 @@ void Window::PrivateData::hide() DGL_DBG("Window hide called\n"); -#if 0 && defined(DISTRHO_OS_MAC) -// if (mWindow != nullptr) -// { -// if (mParentWindow != nullptr) -// [mParentWindow removeChildWindow:mWindow]; -// } -#endif - if (modal.enabled) stopModal(); @@ -577,6 +560,10 @@ void Window::PrivateData::startModal() modal.parent->show(); show(); +#ifdef DISTRHO_OS_MAC + puglMacOSAddChildWindow(modal.parent->view, view); +#endif + DGL_DBG("Ok\n"); } @@ -593,26 +580,20 @@ void Window::PrivateData::stopModal() if (modal.parent->modal.child != this) return; +#ifdef DISTRHO_OS_MAC + puglMacOSRemoveChildWindow(modal.parent->view, view); +#endif + // stop parent from giving focus to us, so it behaves like normal modal.parent->modal.child = nullptr; - // the mouse position probably changed since the modal appeared, - // so send a mouse motion event to the modal's parent window -#if 0 -#if defined(DISTRHO_OS_HAIKU) - // TODO -#elif defined(DISTRHO_OS_MAC) - // TODO -#elif defined(DISTRHO_OS_WINDOWS) - // TODO -#else - int i, wx, wy; - uint u; - ::Window w; - if (XQueryPointer(fModal.parent->xDisplay, fModal.parent->xWindow, &w, &w, &i, &i, &wx, &wy, &u) == True) - fModal.parent->onPuglMotion(wx, wy); -#endif -#endif + // refocus main window after closing child + if (! modal.parent->isClosed) + { + const Widget::MotionEvent ev; + modal.parent->onPuglMotion(ev); + modal.parent->focus(); + } DGL_DBG("Ok\n"); } @@ -700,10 +681,11 @@ void Window::PrivateData::onPuglClose() { DGL_DBG("PUGL: onClose\n"); - // if we have a parent or running as standalone we can prevent closing in certain conditions - if (modal.parent != nullptr || appData->isStandalone) +#ifndef DISTRHO_OS_MAC + // if we are running as standalone we can prevent closing in certain conditions + if (appData->isStandalone) { - // parent gives focus to us as modal, prevent closing + // a child window is active, gives focus to it if (modal.child != nullptr) return modal.child->focus(); @@ -711,14 +693,15 @@ void Window::PrivateData::onPuglClose() if (! self->onClose()) return; } +#endif if (modal.enabled) stopModal(); - if (PrivateData* const child = modal.child) + if (modal.child != nullptr) { + modal.child->close(); modal.child = nullptr; - child->close(); } close(); diff --git a/dpf/dgl/src/pugl.cpp b/dpf/dgl/src/pugl.cpp index 860edaa..560c978 100644 --- a/dpf/dgl/src/pugl.cpp +++ b/dpf/dgl/src/pugl.cpp @@ -398,6 +398,55 @@ void puglFallbackOnResize(PuglView* const view) } #ifdef DISTRHO_OS_MAC +// -------------------------------------------------------------------------------------------------------------------- +// macOS specific, allow standalone window to gain focus + +void puglMacOSActivateApp() +{ + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp activateIgnoringOtherApps:YES]; +} + +// -------------------------------------------------------------------------------------------------------------------- +// macOS specific, add another view's window as child + +PuglStatus +puglMacOSAddChildWindow(PuglView* view, PuglView* child) +{ + if (NSWindow* const viewWindow = view->impl->window ? view->impl->window + : [view->impl->wrapperView window]) + { + if (NSWindow* const childWindow = child->impl->window ? child->impl->window + : [child->impl->wrapperView window]) + { + [viewWindow addChildWindow:childWindow ordered:NSWindowAbove]; + return PUGL_SUCCESS; + } + } + + return PUGL_FAILURE; +} + +// -------------------------------------------------------------------------------------------------------------------- +// macOS specific, remove another view's window as child + +PuglStatus +puglMacOSRemoveChildWindow(PuglView* view, PuglView* child) +{ + if (NSWindow* const viewWindow = view->impl->window ? view->impl->window + : [view->impl->wrapperView window]) + { + if (NSWindow* const childWindow = child->impl->window ? child->impl->window + : [child->impl->wrapperView window]) + { + [viewWindow removeChildWindow:childWindow]; + return PUGL_SUCCESS; + } + } + + return PUGL_FAILURE; +} + // -------------------------------------------------------------------------------------------------------------------- // macOS specific, setup file browser dialog @@ -438,15 +487,6 @@ bool puglMacOSFilePanelOpen(PuglView* const view, return true; } - -// -------------------------------------------------------------------------------------------------------------------- -// macOS specific, allow standalone window to gain focus - -void puglMacOSActivateApp() -{ - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [NSApp activateIgnoringOtherApps:YES]; -} #endif #ifdef DISTRHO_OS_WINDOWS diff --git a/dpf/dgl/src/pugl.hpp b/dpf/dgl/src/pugl.hpp index dbf4519..e89539a 100644 --- a/dpf/dgl/src/pugl.hpp +++ b/dpf/dgl/src/pugl.hpp @@ -96,13 +96,21 @@ PUGL_API void puglFallbackOnResize(PuglView* view); #ifdef DISTRHO_OS_MAC -// macOS specific, setup file browser dialog -typedef void (*openPanelCallback)(PuglView* view, const char* path); -bool puglMacOSFilePanelOpen(PuglView* view, const char* startDir, const char* title, uint flags, openPanelCallback callback); - // macOS specific, allow standalone window to gain focus PUGL_API void puglMacOSActivateApp(); + +// macOS specific, add another view's window as child +PUGL_API PuglStatus +puglMacOSAddChildWindow(PuglView* view, PuglView* child); + +// macOS specific, remove another view's window as child +PUGL_API PuglStatus +puglMacOSRemoveChildWindow(PuglView* view, PuglView* child); + +// macOS specific, setup file browser dialog +typedef void (*openPanelCallback)(PuglView* view, const char* path); +bool puglMacOSFilePanelOpen(PuglView* view, const char* startDir, const char* title, uint flags, openPanelCallback callback); #endif #ifdef DISTRHO_OS_WINDOWS