Browse Source

Fixup for modal windows, tested on macOS

tags/v1.5
falkTX 3 years ago
parent
commit
a2d2c0b1c6
4 changed files with 85 additions and 52 deletions
  1. +2
    -0
      dpf/dgl/Window.hpp
  2. +22
    -39
      dpf/dgl/src/WindowPrivateData.cpp
  3. +49
    -9
      dpf/dgl/src/pugl.cpp
  4. +12
    -4
      dpf/dgl/src/pugl.hpp

+ 2
- 0
dpf/dgl/Window.hpp View File

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




+ 22
- 39
dpf/dgl/src/WindowPrivateData.cpp View File

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


+ 49
- 9
dpf/dgl/src/pugl.cpp View File

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


+ 12
- 4
dpf/dgl/src/pugl.hpp View File

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


Loading…
Cancel
Save