@@ -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 | |||