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