Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -1,3 +1,3 @@ | |||||
| [submodule "dgl/src/pugl-upstream"] | [submodule "dgl/src/pugl-upstream"] | ||||
| path = dgl/src/pugl-upstream | path = dgl/src/pugl-upstream | ||||
| url = https://github.com/lv2/pugl.git | |||||
| url = https://github.com/DISTRHO/pugl.git | |||||
| @@ -63,6 +63,26 @@ public: | |||||
| */ | */ | ||||
| virtual ~Window(); | virtual ~Window(); | ||||
| /** | |||||
| Whether this Window is embed into another (usually not DGL-controlled) Window. | |||||
| */ | |||||
| bool isEmbed() const noexcept; | |||||
| bool isVisible() const noexcept; | |||||
| void setVisible(bool visible); | |||||
| inline void show() { setVisible(true); } | |||||
| inline void hide() { setVisible(true); } | |||||
| /** | |||||
| Hide window and notify application of a window close event. | |||||
| The application event-loop will stop when all windows have been closed. | |||||
| For standalone windows only, has no effect if window is embed. | |||||
| @see isEmbed() | |||||
| @note It is possible to hide the window while not stopping the event-loop. | |||||
| A closed window is always hidden, but the reverse is not always true. | |||||
| */ | |||||
| void close(); | void close(); | ||||
| /** | /** | ||||
| @@ -144,8 +164,6 @@ END_NAMESPACE_DGL | |||||
| static Window& withTransientParentWindow(Window& transientParentWindow); | static Window& withTransientParentWindow(Window& transientParentWindow); | ||||
| void show(); | |||||
| void hide(); | |||||
| void exec(bool lockWait = false); | void exec(bool lockWait = false); | ||||
| void focus(); | void focus(); | ||||
| @@ -156,11 +174,6 @@ END_NAMESPACE_DGL | |||||
| bool openFileBrowser(const FileBrowserOptions& options); | bool openFileBrowser(const FileBrowserOptions& options); | ||||
| #endif | #endif | ||||
| bool isEmbed() const noexcept; | |||||
| bool isVisible() const noexcept; | |||||
| void setVisible(bool visible); | |||||
| bool isResizable() const noexcept; | bool isResizable() const noexcept; | ||||
| void setResizable(bool resizable); | void setResizable(bool resizable); | ||||
| @@ -28,6 +28,7 @@ Application::PrivateData::PrivateData(const bool standalone) | |||||
| standalone ? PUGL_WORLD_THREADS : 0x0)), | standalone ? PUGL_WORLD_THREADS : 0x0)), | ||||
| isStandalone(standalone), | isStandalone(standalone), | ||||
| isQuitting(false), | isQuitting(false), | ||||
| isStarting(true), | |||||
| visibleWindows(0), | visibleWindows(0), | ||||
| windows(), | windows(), | ||||
| idleCallbacks() | idleCallbacks() | ||||
| @@ -36,14 +37,11 @@ Application::PrivateData::PrivateData(const bool standalone) | |||||
| puglSetWorldHandle(world, this); | puglSetWorldHandle(world, this); | ||||
| puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); | puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); | ||||
| // puglSetLogLevel(world, PUGL_LOG_LEVEL_DEBUG); | |||||
| } | } | ||||
| Application::PrivateData::~PrivateData() | Application::PrivateData::~PrivateData() | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT(isQuitting); | |||||
| DISTRHO_SAFE_ASSERT(isStarting || isQuitting); | |||||
| DISTRHO_SAFE_ASSERT(visibleWindows == 0); | DISTRHO_SAFE_ASSERT(visibleWindows == 0); | ||||
| windows.clear(); | windows.clear(); | ||||
| @@ -57,21 +55,23 @@ Application::PrivateData::~PrivateData() | |||||
| void Application::PrivateData::oneWindowShown() noexcept | void Application::PrivateData::oneWindowShown() noexcept | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||||
| if (++visibleWindows == 1) | if (++visibleWindows == 1) | ||||
| { | |||||
| isQuitting = false; | isQuitting = false; | ||||
| isStarting = false; | |||||
| } | |||||
| } | } | ||||
| void Application::PrivateData::oneWindowHidden() noexcept | |||||
| void Application::PrivateData::oneWindowClosed() noexcept | |||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(visibleWindows != 0,); | DISTRHO_SAFE_ASSERT_RETURN(visibleWindows != 0,); | ||||
| if (--visibleWindows == 0) | if (--visibleWindows == 0) | ||||
| isQuitting = true; | isQuitting = true; | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| void Application::PrivateData::idle(const uint timeoutInMs) | void Application::PrivateData::idle(const uint timeoutInMs) | ||||
| { | { | ||||
| if (world != nullptr) | if (world != nullptr) | ||||
| @@ -92,6 +92,8 @@ void Application::PrivateData::idle(const uint timeoutInMs) | |||||
| void Application::PrivateData::quit() | void Application::PrivateData::quit() | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||||
| isQuitting = true; | isQuitting = true; | ||||
| #ifndef DPF_TEST_APPLICATION_CPP | #ifndef DPF_TEST_APPLICATION_CPP | ||||
| @@ -39,31 +39,38 @@ struct Application::PrivateData { | |||||
| /** Whether the applicating is about to quit, or already stopped. Defaults to false. */ | /** Whether the applicating is about to quit, or already stopped. Defaults to false. */ | ||||
| bool isQuitting; | bool isQuitting; | ||||
| /** Whether the applicating is starting up, that is, no windows have been made visible yet. Defaults to true. */ | |||||
| bool isStarting; | |||||
| /** Counter of visible windows, only used in standalone mode. | /** Counter of visible windows, only used in standalone mode. | ||||
| If 0->1, application is starting. If 1->0, application is quitting/stopping. */ | If 0->1, application is starting. If 1->0, application is quitting/stopping. */ | ||||
| uint visibleWindows; | uint visibleWindows; | ||||
| /** List of windows for this application. Used as a way to call each window `idle`. */ | |||||
| /** List of windows for this application. Only used during `close`. */ | |||||
| std::list<Window*> windows; | std::list<Window*> windows; | ||||
| /** List of idle callbacks for this application. Run after all windows `idle`. */ | |||||
| /** List of idle callbacks for this application. */ | |||||
| std::list<IdleCallback*> idleCallbacks; | std::list<IdleCallback*> idleCallbacks; | ||||
| /** Constructor and destructor */ | /** Constructor and destructor */ | ||||
| PrivateData(const bool standalone); | PrivateData(const bool standalone); | ||||
| ~PrivateData(); | ~PrivateData(); | ||||
| /** Flag one window shown or hidden status, which modifies @a visibleWindows. | |||||
| For standalone mode only. | |||||
| Modifies @a isQuitting under certain conditions */ | |||||
| /** Flag one window as shown, which increments @a visibleWindows. | |||||
| Sets @a isQuitting and @a isStarting as false if this is the first window. | |||||
| For standalone mode only. */ | |||||
| void oneWindowShown() noexcept; | void oneWindowShown() noexcept; | ||||
| void oneWindowHidden() noexcept; | |||||
| /** Run Pugl world update for @a timeoutInMs, and then the idle functions for each window and idle callback, | |||||
| in order of registration. */ | |||||
| /** Flag one window as closed, which decrements @a visibleWindows. | |||||
| Sets @a isQuitting as true if this is the last window. | |||||
| For standalone mode only. */ | |||||
| void oneWindowClosed() noexcept; | |||||
| /** Run Pugl world update for @a timeoutInMs, and then each idle callback in order of registration. */ | |||||
| void idle(const uint timeoutInMs); | void idle(const uint timeoutInMs); | ||||
| /** Set flag indicating application is quitting, and closes all windows in reverse order of registration. */ | |||||
| /** Set flag indicating application is quitting, and close all windows in reverse order of registration. | |||||
| For standalone mode only. */ | |||||
| void quit(); | void quit(); | ||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | ||||
| @@ -37,27 +37,32 @@ Window::~Window() | |||||
| delete pData; | delete pData; | ||||
| } | } | ||||
| void Window::close() | |||||
| bool Window::isEmbed() const noexcept | |||||
| { | { | ||||
| pData->close(); | |||||
| return pData->isEmbed; | |||||
| } | } | ||||
| uintptr_t Window::getNativeWindowHandle() const noexcept | |||||
| bool Window::isVisible() const noexcept | |||||
| { | { | ||||
| return puglGetNativeWindow(pData->view); | |||||
| return pData->isVisible; | |||||
| } | } | ||||
| #if 0 | |||||
| void Window::show() | |||||
| void Window::setVisible(const bool visible) | |||||
| { | { | ||||
| pData->setVisible(true); | |||||
| pData->setVisible(visible); | |||||
| } | } | ||||
| void Window::hide() | |||||
| void Window::close() | |||||
| { | |||||
| pData->close(); | |||||
| } | |||||
| uintptr_t Window::getNativeWindowHandle() const noexcept | |||||
| { | { | ||||
| pData->setVisible(false); | |||||
| return puglGetNativeWindow(pData->view); | |||||
| } | } | ||||
| #if 0 | |||||
| #if 0 | #if 0 | ||||
| void Window::exec(bool lockWait) | void Window::exec(bool lockWait) | ||||
| { | { | ||||
| @@ -89,21 +94,6 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept | |||||
| puglPostRedisplayRect(pData->fView, prect); | puglPostRedisplayRect(pData->fView, prect); | ||||
| } | } | ||||
| bool Window::isEmbed() const noexcept | |||||
| { | |||||
| return pData->fUsingEmbed; | |||||
| } | |||||
| bool Window::isVisible() const noexcept | |||||
| { | |||||
| return pData->fVisible; | |||||
| } | |||||
| void Window::setVisible(const bool visible) | |||||
| { | |||||
| pData->setVisible(visible); | |||||
| } | |||||
| bool Window::isResizable() const noexcept | bool Window::isResizable() const noexcept | ||||
| { | { | ||||
| return puglGetViewHint(pData->fView, PUGL_RESIZABLE) == PUGL_TRUE; | return puglGetViewHint(pData->fView, PUGL_RESIZABLE) == PUGL_TRUE; | ||||
| @@ -26,32 +26,56 @@ START_NAMESPACE_DGL | |||||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s) | Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s) | ||||
| : appData(a), | : appData(a), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)) | |||||
| view(puglNewView(appData->world)), | |||||
| isClosed(true), | |||||
| isVisible(false), | |||||
| isEmbed(false) | |||||
| { | { | ||||
| init(true); | |||||
| init(false); | |||||
| } | } | ||||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, Window& transientWindow) | Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, Window& transientWindow) | ||||
| : appData(a), | : appData(a), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)) | |||||
| view(puglNewView(appData->world)), | |||||
| isClosed(true), | |||||
| isVisible(false), | |||||
| isEmbed(false) | |||||
| { | { | ||||
| init(false); | |||||
| puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | ||||
| init(true); | |||||
| } | } | ||||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, | Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, | ||||
| const uintptr_t parentWindowHandle, const double scaling, const bool resizable) | const uintptr_t parentWindowHandle, const double scaling, const bool resizable) | ||||
| : appData(a), | : appData(a), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)) | |||||
| view(puglNewView(appData->world)), | |||||
| isClosed(parentWindowHandle == 0), | |||||
| isVisible(parentWindowHandle != 0), | |||||
| isEmbed(parentWindowHandle != 0) | |||||
| { | { | ||||
| // TODO view parent | |||||
| init(resizable); | init(resizable); | ||||
| if (isEmbed) | |||||
| { | |||||
| appData->oneWindowShown(); | |||||
| puglSetParentWindow(view, parentWindowHandle); | |||||
| puglShow(view); | |||||
| } | |||||
| } | } | ||||
| Window::PrivateData::~PrivateData() | Window::PrivateData::~PrivateData() | ||||
| { | { | ||||
| if (isEmbed) | |||||
| { | |||||
| puglHide(view); | |||||
| appData->oneWindowClosed(); | |||||
| isClosed = true; | |||||
| isVisible = false; | |||||
| } | |||||
| appData->idleCallbacks.remove(this); | appData->idleCallbacks.remove(this); | ||||
| appData->windows.remove(self); | appData->windows.remove(self); | ||||
| @@ -95,28 +119,102 @@ void Window::PrivateData::init(const bool resizable) | |||||
| // DGL_DBG("Success!\n"); | // DGL_DBG("Success!\n"); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::close() | void Window::PrivateData::close() | ||||
| { | { | ||||
| /* | |||||
| DGL_DBG("Window close\n"); | |||||
| // DGL_DBG("Window close\n"); | |||||
| if (fUsingEmbed) | |||||
| if (isEmbed || isClosed) | |||||
| return; | return; | ||||
| isClosed = true; | |||||
| setVisible(false); | setVisible(false); | ||||
| appData->oneWindowClosed(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::setVisible(const bool visible) | |||||
| { | |||||
| if (isVisible == visible) | |||||
| { | |||||
| // DGL_DBG("Window setVisible matches current state, ignoring request\n"); | |||||
| return; | |||||
| } | |||||
| if (isEmbed) | |||||
| { | |||||
| // DGL_DBG("Window setVisible cannot be called when embedded\n"); | |||||
| return; | |||||
| } | |||||
| // DGL_DBG("Window setVisible called\n"); | |||||
| isVisible = visible; | |||||
| if (visible) | |||||
| { | |||||
| // #if 0 && defined(DISTRHO_OS_MAC) | |||||
| // if (mWindow != nullptr) | |||||
| // { | |||||
| // if (mParentWindow != nullptr) | |||||
| // [mParentWindow addChildWindow:mWindow | |||||
| // ordered:NSWindowAbove]; | |||||
| // } | |||||
| // #endif | |||||
| if (! fFirstInit) | |||||
| if (isClosed) | |||||
| { | |||||
| puglRealize(view); | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglWin32ShowWindowCentered(view); | |||||
| #else | |||||
| puglShow(view); | |||||
| #endif | |||||
| appData->oneWindowShown(); | |||||
| isClosed = false; | |||||
| } | |||||
| else | |||||
| { | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglWin32RestoreWindow(view); | |||||
| #else | |||||
| puglShow(view); | |||||
| #endif | |||||
| } | |||||
| } | |||||
| else | |||||
| { | { | ||||
| fAppData->oneWindowHidden(); | |||||
| fFirstInit = true; | |||||
| // #if 0 && defined(DISTRHO_OS_MAC) | |||||
| // if (mWindow != nullptr) | |||||
| // { | |||||
| // if (mParentWindow != nullptr) | |||||
| // [mParentWindow removeChildWindow:mWindow]; | |||||
| // } | |||||
| // #endif | |||||
| puglHide(view); | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| } | } | ||||
| */ | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::idleCallback() | void Window::PrivateData::idleCallback() | ||||
| { | { | ||||
| // #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) | |||||
| // if (fSelectedFile.isNotEmpty()) | |||||
| // { | |||||
| // char* const buffer = fSelectedFile.getAndReleaseBuffer(); | |||||
| // fView->fileSelectedFunc(fView, buffer); | |||||
| // std::free(buffer); | |||||
| // } | |||||
| // #endif | |||||
| // | |||||
| // if (fModal.enabled && fModal.parent != nullptr) | |||||
| // fModal.parent->windowSpecificIdle(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -156,8 +254,6 @@ extern "C" { | |||||
| # define DGL_DEBUG_EVENTS | # define DGL_DEBUG_EVENTS | ||||
| # include "pugl-upstream/src/haiku.cpp" | # include "pugl-upstream/src/haiku.cpp" | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| # define PuglWindow DISTRHO_JOIN_MACRO(PuglWindow, DGL_NAMESPACE) | |||||
| # define PuglOpenGLView DISTRHO_JOIN_MACRO(PuglOpenGLView, DGL_NAMESPACE) | |||||
| # include "pugl-upstream/src/mac.m" | # include "pugl-upstream/src/mac.m" | ||||
| #elif defined(DISTRHO_OS_WINDOWS) | #elif defined(DISTRHO_OS_WINDOWS) | ||||
| # include "ppugl-upstream/src/win.c" | # include "ppugl-upstream/src/win.c" | ||||
| @@ -214,189 +310,6 @@ struct Fallback { | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| Window::PrivateData::PrivateData(Application::PrivateData* const appData, Window* const self) | |||||
| : fAppData(appData), | |||||
| fSelf(self), | |||||
| fView(puglNewView(appData->world)), | |||||
| fFirstInit(true), | |||||
| fVisible(false), | |||||
| fUsingEmbed(false), | |||||
| fScaling(1.0), | |||||
| fAutoScaling(1.0), | |||||
| fWidgets(), | |||||
| fModal() | |||||
| { | |||||
| DGL_DBG("Creating window without parent..."); DGL_DBGF; | |||||
| init(); | |||||
| } | |||||
| #ifndef DPF_TEST_WINDOW_CPP | |||||
| Window::PrivateData::PrivateData(Application::PrivateData* const appData, Window* const self, Window& transientWindow) | |||||
| : fAppData(appData), | |||||
| fSelf(self), | |||||
| fView(puglNewView(appData->world)), | |||||
| fFirstInit(true), | |||||
| fVisible(false), | |||||
| fUsingEmbed(false), | |||||
| fScaling(1.0), | |||||
| fAutoScaling(1.0), | |||||
| fWidgets(), | |||||
| fModal(transientWindow.pData) | |||||
| { | |||||
| DGL_DBG("Creating window with parent..."); DGL_DBGF; | |||||
| init(); | |||||
| puglSetTransientFor(fView, transientWindow.getNativeWindowHandle()); | |||||
| } | |||||
| #endif | |||||
| Window::PrivateData::PrivateData(Application::PrivateData* const appData, Window* const self, | |||||
| const uintptr_t parentWindowHandle, | |||||
| const double scaling, | |||||
| const bool resizable) | |||||
| : fAppData(appData), | |||||
| fSelf(self), | |||||
| fView(puglNewView(appData->world)), | |||||
| fFirstInit(true), | |||||
| fVisible(parentWindowHandle != 0), | |||||
| fUsingEmbed(parentWindowHandle != 0), | |||||
| fScaling(scaling), | |||||
| fAutoScaling(1.0), | |||||
| fWidgets(), | |||||
| fModal() | |||||
| { | |||||
| if (fUsingEmbed) | |||||
| { | |||||
| DGL_DBG("Creating embedded window..."); DGL_DBGF; | |||||
| puglSetParentWindow(fView, parentWindowHandle); | |||||
| } | |||||
| else | |||||
| { | |||||
| DGL_DBG("Creating window without parent..."); DGL_DBGF; | |||||
| } | |||||
| init(resizable); | |||||
| if (fUsingEmbed) | |||||
| { | |||||
| DGL_DBG("NOTE: Embed window is always visible and non-resizable\n"); | |||||
| // puglShowWindow(fView); | |||||
| // fAppData->oneWindowShown(); | |||||
| // fFirstInit = false; | |||||
| } | |||||
| } | |||||
| Window::PrivateData::~PrivateData() | |||||
| { | |||||
| DGL_DBG("Destroying window..."); DGL_DBGF; | |||||
| #if 0 | |||||
| if (fModal.enabled) | |||||
| { | |||||
| exec_fini(); | |||||
| close(); | |||||
| } | |||||
| #endif | |||||
| fWidgets.clear(); | |||||
| if (fUsingEmbed) | |||||
| { | |||||
| // puglHideWindow(fView); | |||||
| // fAppData->oneWindowHidden(); | |||||
| } | |||||
| if (fSelf != nullptr) | |||||
| fAppData->windows.remove(fSelf); | |||||
| #if defined(DISTRHO_OS_MAC) && !defined(DGL_FILE_BROWSER_DISABLED) | |||||
| if (fOpenFilePanel) | |||||
| { | |||||
| [fOpenFilePanel release]; | |||||
| fOpenFilePanel = nullptr; | |||||
| } | |||||
| if (fFilePanelDelegate) | |||||
| { | |||||
| [fFilePanelDelegate release]; | |||||
| fFilePanelDelegate = nullptr; | |||||
| } | |||||
| #endif | |||||
| if (fView != nullptr) | |||||
| puglFreeView(fView); | |||||
| DGL_DBG("Success!\n"); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::setVisible(const bool visible) | |||||
| { | |||||
| if (fVisible == visible) | |||||
| { | |||||
| DGL_DBG("Window setVisible matches current state, ignoring request\n"); | |||||
| return; | |||||
| } | |||||
| if (fUsingEmbed) | |||||
| { | |||||
| DGL_DBG("Window setVisible cannot be called when embedded\n"); | |||||
| return; | |||||
| } | |||||
| DGL_DBG("Window setVisible called\n"); | |||||
| fVisible = visible; | |||||
| if (visible) | |||||
| { | |||||
| #if 0 && defined(DISTRHO_OS_MAC) | |||||
| if (mWindow != nullptr) | |||||
| { | |||||
| if (mParentWindow != nullptr) | |||||
| [mParentWindow addChildWindow:mWindow | |||||
| ordered:NSWindowAbove]; | |||||
| } | |||||
| #endif | |||||
| if (fFirstInit) | |||||
| { | |||||
| puglRealize(fView); | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglShowWindowCentered(fView); | |||||
| #else | |||||
| puglShow(fView); | |||||
| #endif | |||||
| fAppData->oneWindowShown(); | |||||
| fFirstInit = false; | |||||
| } | |||||
| else | |||||
| { | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglWin32RestoreWindow(fView); | |||||
| #else | |||||
| puglShow(fView); | |||||
| #endif | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| #if 0 && defined(DISTRHO_OS_MAC) | |||||
| if (mWindow != nullptr) | |||||
| { | |||||
| if (mParentWindow != nullptr) | |||||
| [mParentWindow removeChildWindow:mWindow]; | |||||
| } | |||||
| #endif | |||||
| puglHide(fView); | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| } | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::addWidget(Widget* const widget) | void Window::PrivateData::addWidget(Widget* const widget) | ||||
| { | { | ||||
| fWidgets.push_back(widget); | fWidgets.push_back(widget); | ||||
| @@ -486,23 +399,6 @@ void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev) | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::windowSpecificIdle() | |||||
| { | |||||
| #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) | |||||
| if (fSelectedFile.isNotEmpty()) | |||||
| { | |||||
| char* const buffer = fSelectedFile.getAndReleaseBuffer(); | |||||
| fView->fileSelectedFunc(fView, buffer); | |||||
| std::free(buffer); | |||||
| } | |||||
| #endif | |||||
| if (fModal.enabled && fModal.parent != nullptr) | |||||
| fModal.parent->windowSpecificIdle(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| static inline int | static inline int | ||||
| printModifiers(const uint32_t mods) | printModifiers(const uint32_t mods) | ||||
| { | { | ||||
| @@ -18,7 +18,6 @@ | |||||
| #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | ||||
| #include "../Window.hpp" | #include "../Window.hpp" | ||||
| // #include "ApplicationPrivateData.hpp" | |||||
| #include "pugl.hpp" | #include "pugl.hpp" | ||||
| @@ -41,6 +40,16 @@ struct Window::PrivateData : IdleCallback { | |||||
| /** Pugl view instance. */ | /** Pugl view instance. */ | ||||
| PuglView* const view; | PuglView* const view; | ||||
| /** Whether this Window is closed (not visible or counted in the Application it is tied to). | |||||
| Defaults to true unless embed (embed windows are never closed). */ | |||||
| bool isClosed; | |||||
| /** Whether this Window is currently visible/mapped. Defaults to false. */ | |||||
| bool isVisible; | |||||
| /** Whether this Window is embed into another (usually not DGL-controlled) Window. */ | |||||
| const bool isEmbed; | |||||
| /** Constructor for a regular, standalone window. */ | /** Constructor for a regular, standalone window. */ | ||||
| PrivateData(AppData* appData, Window* self); | PrivateData(AppData* appData, Window* self); | ||||
| @@ -58,13 +67,15 @@ struct Window::PrivateData : IdleCallback { | |||||
| /** Hide window and notify application of a window close event. | /** Hide window and notify application of a window close event. | ||||
| * Does nothing if window is embed (that is, not standalone). | * Does nothing if window is embed (that is, not standalone). | ||||
| * The application event-loop will stop if all windows have been closed. | |||||
| * The application event-loop will stop when all windows have been closed. | |||||
| * | * | ||||
| * @note It is possible to hide the window while not stopping event-loop. | |||||
| * @note It is possible to hide the window while not stopping the event-loop. | |||||
| * A closed window is always hidden, but the reverse is not always true. | * A closed window is always hidden, but the reverse is not always true. | ||||
| */ | */ | ||||
| void close(); | void close(); | ||||
| void setVisible(bool visible); | |||||
| void idleCallback() override; | void idleCallback() override; | ||||
| static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | ||||
| @@ -1 +1 @@ | |||||
| Subproject commit 2d3100e47eee6a8bf2209ee19157de6d23dd1c55 | |||||
| Subproject commit 5a3a1309ad6432d72cdb7f37e3e36383dd6ba372 | |||||
| @@ -67,6 +67,8 @@ START_NAMESPACE_DGL | |||||
| #if defined(DISTRHO_OS_HAIKU) | #if defined(DISTRHO_OS_HAIKU) | ||||
| #elif defined(DISTRHO_OS_MAC) | #elif defined(DISTRHO_OS_MAC) | ||||
| # define PuglWindow DISTRHO_JOIN_MACRO(PuglWindow, DGL_NAMESPACE) | |||||
| # define PuglOpenGLView DISTRHO_JOIN_MACRO(PuglOpenGLView, DGL_NAMESPACE) | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | #elif defined(DISTRHO_OS_WINDOWS) | ||||
| #else | #else | ||||
| # include "pugl-upstream/src/x11.c" | # include "pugl-upstream/src/x11.c" | ||||
| @@ -35,7 +35,7 @@ TARGETS = $(TESTS:%=../build/tests/%) | |||||
| TARGETS += $(WTESTS:Window.%=../build/tests/Window.%) | TARGETS += $(WTESTS:Window.%=../build/tests/Window.%) | ||||
| OBJS = $(TESTS:%=../build/tests/%.cpp.o) | OBJS = $(TESTS:%=../build/tests/%.cpp.o) | ||||
| OBJS += $(WTESTS:Window.%=../build/tests/Window.%.cpp.o) | |||||
| OBJS += $(WTESTS:Window.%=../build/tests/Window.cpp.%.o) | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -68,8 +68,7 @@ all: $(TARGETS) | |||||
| @echo "Linking $*" | @echo "Linking $*" | ||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | ||||
| @echo "Running test for $*" | @echo "Running test for $*" | ||||
| # $(SILENT) | |||||
| $@ | |||||
| $(SILENT) $@ | |||||
| # gdb -ex run | # gdb -ex run | ||||
| ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | ||||
| @@ -39,6 +39,7 @@ int main() | |||||
| { | { | ||||
| Application app(true); | Application app(true); | ||||
| Window win(app); | Window win(app); | ||||
| app.idle(); | |||||
| } | } | ||||
| // TODO | // TODO | ||||