Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -1,3 +1,3 @@ | |||
| [submodule "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(); | |||
| /** | |||
| 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(); | |||
| /** | |||
| @@ -144,8 +164,6 @@ END_NAMESPACE_DGL | |||
| static Window& withTransientParentWindow(Window& transientParentWindow); | |||
| void show(); | |||
| void hide(); | |||
| void exec(bool lockWait = false); | |||
| void focus(); | |||
| @@ -156,11 +174,6 @@ END_NAMESPACE_DGL | |||
| bool openFileBrowser(const FileBrowserOptions& options); | |||
| #endif | |||
| bool isEmbed() const noexcept; | |||
| bool isVisible() const noexcept; | |||
| void setVisible(bool visible); | |||
| bool isResizable() const noexcept; | |||
| void setResizable(bool resizable); | |||
| @@ -28,6 +28,7 @@ Application::PrivateData::PrivateData(const bool standalone) | |||
| standalone ? PUGL_WORLD_THREADS : 0x0)), | |||
| isStandalone(standalone), | |||
| isQuitting(false), | |||
| isStarting(true), | |||
| visibleWindows(0), | |||
| windows(), | |||
| idleCallbacks() | |||
| @@ -36,14 +37,11 @@ Application::PrivateData::PrivateData(const bool standalone) | |||
| puglSetWorldHandle(world, this); | |||
| puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); | |||
| // puglSetLogLevel(world, PUGL_LOG_LEVEL_DEBUG); | |||
| } | |||
| Application::PrivateData::~PrivateData() | |||
| { | |||
| DISTRHO_SAFE_ASSERT(isQuitting); | |||
| DISTRHO_SAFE_ASSERT(isStarting || isQuitting); | |||
| DISTRHO_SAFE_ASSERT(visibleWindows == 0); | |||
| windows.clear(); | |||
| @@ -57,21 +55,23 @@ Application::PrivateData::~PrivateData() | |||
| void Application::PrivateData::oneWindowShown() noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||
| if (++visibleWindows == 1) | |||
| { | |||
| 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,); | |||
| if (--visibleWindows == 0) | |||
| isQuitting = true; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void Application::PrivateData::idle(const uint timeoutInMs) | |||
| { | |||
| if (world != nullptr) | |||
| @@ -92,6 +92,8 @@ void Application::PrivateData::idle(const uint timeoutInMs) | |||
| void Application::PrivateData::quit() | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(isStandalone,); | |||
| isQuitting = true; | |||
| #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. */ | |||
| 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. | |||
| If 0->1, application is starting. If 1->0, application is quitting/stopping. */ | |||
| 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; | |||
| /** List of idle callbacks for this application. Run after all windows `idle`. */ | |||
| /** List of idle callbacks for this application. */ | |||
| std::list<IdleCallback*> idleCallbacks; | |||
| /** Constructor and destructor */ | |||
| PrivateData(const bool standalone); | |||
| ~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 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); | |||
| /** 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(); | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | |||
| @@ -37,27 +37,32 @@ Window::~Window() | |||
| 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 | |||
| void Window::exec(bool lockWait) | |||
| { | |||
| @@ -89,21 +94,6 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept | |||
| 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 | |||
| { | |||
| 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) | |||
| : appData(a), | |||
| 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) | |||
| : appData(a), | |||
| self(s), | |||
| view(puglNewView(appData->world)) | |||
| view(puglNewView(appData->world)), | |||
| isClosed(true), | |||
| isVisible(false), | |||
| isEmbed(false) | |||
| { | |||
| init(false); | |||
| puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | |||
| init(true); | |||
| } | |||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, | |||
| const uintptr_t parentWindowHandle, const double scaling, const bool resizable) | |||
| : appData(a), | |||
| self(s), | |||
| view(puglNewView(appData->world)) | |||
| view(puglNewView(appData->world)), | |||
| isClosed(parentWindowHandle == 0), | |||
| isVisible(parentWindowHandle != 0), | |||
| isEmbed(parentWindowHandle != 0) | |||
| { | |||
| // TODO view parent | |||
| init(resizable); | |||
| if (isEmbed) | |||
| { | |||
| appData->oneWindowShown(); | |||
| puglSetParentWindow(view, parentWindowHandle); | |||
| puglShow(view); | |||
| } | |||
| } | |||
| Window::PrivateData::~PrivateData() | |||
| { | |||
| if (isEmbed) | |||
| { | |||
| puglHide(view); | |||
| appData->oneWindowClosed(); | |||
| isClosed = true; | |||
| isVisible = false; | |||
| } | |||
| appData->idleCallbacks.remove(this); | |||
| appData->windows.remove(self); | |||
| @@ -95,28 +119,102 @@ void Window::PrivateData::init(const bool resizable) | |||
| // DGL_DBG("Success!\n"); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| void Window::PrivateData::close() | |||
| { | |||
| /* | |||
| DGL_DBG("Window close\n"); | |||
| // DGL_DBG("Window close\n"); | |||
| if (fUsingEmbed) | |||
| if (isEmbed || isClosed) | |||
| return; | |||
| isClosed = true; | |||
| 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() | |||
| { | |||
| // #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 | |||
| # include "pugl-upstream/src/haiku.cpp" | |||
| #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" | |||
| #elif defined(DISTRHO_OS_WINDOWS) | |||
| # 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) | |||
| { | |||
| 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 | |||
| printModifiers(const uint32_t mods) | |||
| { | |||
| @@ -18,7 +18,6 @@ | |||
| #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED | |||
| #include "../Window.hpp" | |||
| // #include "ApplicationPrivateData.hpp" | |||
| #include "pugl.hpp" | |||
| @@ -41,6 +40,16 @@ struct Window::PrivateData : IdleCallback { | |||
| /** Pugl view instance. */ | |||
| 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. */ | |||
| PrivateData(AppData* appData, Window* self); | |||
| @@ -58,13 +67,15 @@ struct Window::PrivateData : IdleCallback { | |||
| /** Hide window and notify application of a window close event. | |||
| * 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. | |||
| */ | |||
| void close(); | |||
| void setVisible(bool visible); | |||
| void idleCallback() override; | |||
| 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) | |||
| #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) | |||
| #else | |||
| # include "pugl-upstream/src/x11.c" | |||
| @@ -35,7 +35,7 @@ TARGETS = $(TESTS:%=../build/tests/%) | |||
| TARGETS += $(WTESTS:Window.%=../build/tests/Window.%) | |||
| 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 $*" | |||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||
| @echo "Running test for $*" | |||
| # $(SILENT) | |||
| $@ | |||
| $(SILENT) $@ | |||
| # gdb -ex run | |||
| ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | |||
| @@ -39,6 +39,7 @@ int main() | |||
| { | |||
| Application app(true); | |||
| Window win(app); | |||
| app.idle(); | |||
| } | |||
| // TODO | |||