| @@ -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(); | |||
| @@ -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(); | |||
| @@ -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 | |||
| @@ -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 | |||