@@ -408,6 +408,8 @@ protected: | |||||
This method is not used for embed windows, and not even made available in DISTRHO_NAMESPACE::UI. | 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. | 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. | 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(); | virtual bool onClose(); | ||||
@@ -286,15 +286,6 @@ void Window::PrivateData::show() | |||||
DGL_DBG("Window show called\n"); | 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) | if (isClosed) | ||||
{ | { | ||||
isClosed = false; | isClosed = false; | ||||
@@ -337,14 +328,6 @@ void Window::PrivateData::hide() | |||||
DGL_DBG("Window hide called\n"); | 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) | if (modal.enabled) | ||||
stopModal(); | stopModal(); | ||||
@@ -577,6 +560,10 @@ void Window::PrivateData::startModal() | |||||
modal.parent->show(); | modal.parent->show(); | ||||
show(); | show(); | ||||
#ifdef DISTRHO_OS_MAC | |||||
puglMacOSAddChildWindow(modal.parent->view, view); | |||||
#endif | |||||
DGL_DBG("Ok\n"); | DGL_DBG("Ok\n"); | ||||
} | } | ||||
@@ -593,26 +580,20 @@ void Window::PrivateData::stopModal() | |||||
if (modal.parent->modal.child != this) | if (modal.parent->modal.child != this) | ||||
return; | return; | ||||
#ifdef DISTRHO_OS_MAC | |||||
puglMacOSRemoveChildWindow(modal.parent->view, view); | |||||
#endif | |||||
// stop parent from giving focus to us, so it behaves like normal | // stop parent from giving focus to us, so it behaves like normal | ||||
modal.parent->modal.child = nullptr; | 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"); | DGL_DBG("Ok\n"); | ||||
} | } | ||||
@@ -700,10 +681,11 @@ void Window::PrivateData::onPuglClose() | |||||
{ | { | ||||
DGL_DBG("PUGL: onClose\n"); | 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) | if (modal.child != nullptr) | ||||
return modal.child->focus(); | return modal.child->focus(); | ||||
@@ -711,14 +693,15 @@ void Window::PrivateData::onPuglClose() | |||||
if (! self->onClose()) | if (! self->onClose()) | ||||
return; | return; | ||||
} | } | ||||
#endif | |||||
if (modal.enabled) | if (modal.enabled) | ||||
stopModal(); | stopModal(); | ||||
if (PrivateData* const child = modal.child) | |||||
if (modal.child != nullptr) | |||||
{ | { | ||||
modal.child->close(); | |||||
modal.child = nullptr; | modal.child = nullptr; | ||||
child->close(); | |||||
} | } | ||||
close(); | close(); | ||||
@@ -398,6 +398,55 @@ void puglFallbackOnResize(PuglView* const view) | |||||
} | } | ||||
#ifdef DISTRHO_OS_MAC | #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 | // macOS specific, setup file browser dialog | ||||
@@ -438,15 +487,6 @@ bool puglMacOSFilePanelOpen(PuglView* const view, | |||||
return true; | return true; | ||||
} | } | ||||
// -------------------------------------------------------------------------------------------------------------------- | |||||
// macOS specific, allow standalone window to gain focus | |||||
void puglMacOSActivateApp() | |||||
{ | |||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; | |||||
[NSApp activateIgnoringOtherApps:YES]; | |||||
} | |||||
#endif | #endif | ||||
#ifdef DISTRHO_OS_WINDOWS | #ifdef DISTRHO_OS_WINDOWS | ||||
@@ -96,13 +96,21 @@ PUGL_API void | |||||
puglFallbackOnResize(PuglView* view); | puglFallbackOnResize(PuglView* view); | ||||
#ifdef DISTRHO_OS_MAC | #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 | // macOS specific, allow standalone window to gain focus | ||||
PUGL_API void | PUGL_API void | ||||
puglMacOSActivateApp(); | 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 | #endif | ||||
#ifdef DISTRHO_OS_WINDOWS | #ifdef DISTRHO_OS_WINDOWS | ||||