From cc1db59a5be2fd1c8418df5e3432f0ced37329ba Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 27 May 2022 02:26:26 +0100 Subject: [PATCH] Start updating pugl, WIP Signed-off-by: falkTX --- dgl/src/Window.cpp | 19 +- dgl/src/WindowPrivateData.cpp | 105 ++++---- dgl/src/WindowPrivateData.hpp | 7 +- dgl/src/pugl-upstream | 2 +- dgl/src/pugl.cpp | 352 ++++++++++----------------- dgl/src/pugl.hpp | 93 +++---- distrho/src/DistrhoUIPrivateData.hpp | 4 +- pugl-updates-notes.txt | 9 + 8 files changed, 242 insertions(+), 349 deletions(-) create mode 100644 pugl-updates-notes.txt diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index e77790e0..5ac3d8a7 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2021 Filipe Coelho + * Copyright (C) 2012-2022 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -189,7 +189,7 @@ void Window::setOffsetY(const int y) void Window::setOffset(const int x, const int y) { - puglSetWindowOffset(pData->view, x, y); + puglSetPosition(pData->view, x, y); } void Window::setOffset(const Point& offset) @@ -289,7 +289,7 @@ void Window::setSize(uint width, uint height) } else { - puglSetWindowSize(pData->view, width, height); + puglSetSizeAndDefault(pData->view, width, height); } } @@ -326,10 +326,7 @@ bool Window::setClipboard(const char* const mimeType, const void* const data, co const void* Window::getClipboard(const char*& mimeType, size_t& dataSize) { - DISTRHO_SAFE_ASSERT_RETURN(!pData->ignoreEvents, nullptr); - pData->ignoreEvents = true; - const void* const clipboard = puglGetClipboard(pData->view, &mimeType, &dataSize); - pData->ignoreEvents = false; + const void* const clipboard = nullptr; // puglGetClipboard(pData->view, &mimeType, &dataSize); return clipboard; } @@ -400,10 +397,10 @@ void Window::repaint(const Rectangle& rect) noexcept return; PuglRect prect = { - static_cast(rect.getX()), - static_cast(rect.getY()), - static_cast(rect.getWidth()), - static_cast(rect.getHeight()), + static_cast(rect.getX()), + static_cast(rect.getY()), + static_cast(rect.getWidth()), + static_cast(rect.getHeight()), }; if (pData->autoScaling) { diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index b1bfc7c5..54a13673 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -52,39 +52,63 @@ START_NAMESPACE_DGL // ----------------------------------------------------------------------- -static double getDesktopScaleFactor(const PuglView* const view) +static double getScaleFactorFromParent(const PuglView* const view) { // allow custom scale for testing if (const char* const scale = getenv("DPF_SCALE_FACTOR")) return std::max(1.0, std::atof(scale)); if (view != nullptr) - return puglGetDesktopScaleFactor(view); + return puglGetScaleFactorFromParent(view); return 1.0; } +static PuglView* puglNewViewWithTransientParent(PuglWorld* const world, PuglView* const transientParentView) +{ + DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, nullptr); + + if (PuglView* const view = puglNewView(world)) + { + puglSetTransientParent(view, puglGetNativeWindow(transientParentView)); + return view; + } + + return nullptr; +} + +static PuglView* puglNewViewWithParentWindow(PuglWorld* const world, const uintptr_t parentWindowHandle) +{ + DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, nullptr); + + if (PuglView* const view = puglNewView(world)) + { + puglSetParentWindow(view, parentWindowHandle); + return view; + } + + return nullptr; +} + // ----------------------------------------------------------------------- Window::PrivateData::PrivateData(Application& a, Window* const s) : app(a), appData(a.pData), self(s), - view(puglNewView(appData->world)), - transientParentView(nullptr), + view(appData->world != nullptr ? puglNewView(appData->world) : nullptr), topLevelWidgets(), isClosed(true), isVisible(false), isEmbed(false), usesSizeRequest(false), - scaleFactor(getDesktopScaleFactor(view)), + scaleFactor(getScaleFactorFromParent(view)), autoScaling(false), autoScaleFactor(1.0), minWidth(0), minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - ignoreEvents(false), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED fileBrowserHandle(nullptr), @@ -98,8 +122,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c : app(a), appData(a.pData), self(s), - view(puglNewView(appData->world)), - transientParentView(ppData->view), + view(puglNewViewWithTransientParent(appData->world, ppData->view)), topLevelWidgets(), isClosed(true), isVisible(false), @@ -112,15 +135,12 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - ignoreEvents(false), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED fileBrowserHandle(nullptr), #endif modal(ppData) { - puglSetTransientFor(view, puglGetNativeWindow(transientParentView)); - initPre(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); } @@ -130,30 +150,25 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, : app(a), appData(a.pData), self(s), - view(puglNewView(appData->world)), - transientParentView(nullptr), + view(puglNewViewWithParentWindow(appData->world, parentWindowHandle)), topLevelWidgets(), isClosed(parentWindowHandle == 0), isVisible(parentWindowHandle != 0), isEmbed(parentWindowHandle != 0), usesSizeRequest(false), - scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), + scaleFactor(scale != 0.0 ? scale : getScaleFactorFromParent(view)), autoScaling(false), autoScaleFactor(1.0), minWidth(0), minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - ignoreEvents(false), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED fileBrowserHandle(nullptr), #endif modal() { - if (isEmbed) - puglSetParentWindow(view, parentWindowHandle); - initPre(DEFAULT_WIDTH, DEFAULT_HEIGHT, resizable); } @@ -164,21 +179,19 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, : app(a), appData(a.pData), self(s), - view(appData->world != nullptr ? puglNewView(appData->world) : nullptr), - transientParentView(nullptr), + view(puglNewViewWithParentWindow(appData->world, parentWindowHandle)), topLevelWidgets(), isClosed(parentWindowHandle == 0), isVisible(parentWindowHandle != 0 && view != nullptr), isEmbed(parentWindowHandle != 0), usesSizeRequest(isVST3), - scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), + scaleFactor(scale != 0.0 ? scale : getScaleFactorFromParent(view)), autoScaling(false), autoScaleFactor(1.0), minWidth(0), minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - ignoreEvents(false), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED fileBrowserHandle(nullptr), @@ -230,11 +243,11 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo } puglSetMatchingBackendForCurrentBuild(view); + puglSetHandle(view, this); - puglClearMinSize(view); - puglSetWindowSize(view, width, height); + // FIXME? + // puglClearMinSize(view); - puglSetHandle(view, this); puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); #if DGL_USE_RGBA @@ -249,6 +262,9 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo #endif // PUGL_SAMPLES ?? puglSetEventFunc(view, puglEventCallback); + + // setting default size triggers system-level calls, do it last + puglSetSizeHint(view, PUGL_DEFAULT_SIZE, width, height); } bool Window::PrivateData::initPost() @@ -314,8 +330,8 @@ void Window::PrivateData::show() appData->oneWindowShown(); // FIXME - PuglRect rect = puglGetFrame(view); - puglSetWindowSize(view, static_cast(rect.width), static_cast(rect.height)); +// PuglRect rect = puglGetFrame(view); +// puglSetWindowSize(view, static_cast(rect.width), static_cast(rect.height)); #if defined(DISTRHO_OS_WINDOWS) puglWin32ShowCentered(view); @@ -378,11 +394,7 @@ void Window::PrivateData::focus() if (! isEmbed) puglRaiseWindow(view); -#if defined(HAVE_X11) && !defined(DISTRHO_OS_MAC) && !defined(DISTRHO_OS_WINDOWS) - puglX11GrabFocus(view); -#else puglGrabFocus(view); -#endif } // ----------------------------------------------------------------------- @@ -393,10 +405,7 @@ void Window::PrivateData::setResizable(const bool resizable) DGL_DBG("Window setResizable called\n"); - puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); -#ifdef DISTRHO_OS_WINDOWS - puglWin32SetWindowResizable(view, resizable); -#endif + puglSetResizable(view, resizable); } // ----------------------------------------------------------------------- @@ -795,8 +804,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< View must be drawn, a #PuglEventExpose case PUGL_EXPOSE: - if (pData->ignoreEvents) - break; // unused x, y, width, height (double) pData->onPuglExpose(); break; @@ -810,8 +817,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu case PUGL_FOCUS_IN: ///< Keyboard focus left view, a #PuglEventFocus case PUGL_FOCUS_OUT: - if (pData->ignoreEvents) - break; pData->onPuglFocus(event->type == PUGL_FOCUS_IN, static_cast(event->focus.mode)); break; @@ -821,8 +826,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Key released, a #PuglEventKey case PUGL_KEY_RELEASE: { - if (pData->ignoreEvents) - break; // unused x, y, xRoot, yRoot (double) Widget::KeyboardEvent ev; ev.mod = event->key.state; @@ -846,8 +849,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Character entered, a #PuglEventText case PUGL_TEXT: { - if (pData->ignoreEvents) - break; // unused x, y, xRoot, yRoot (double) Widget::CharacterInputEvent ev; ev.mod = event->text.state; @@ -872,13 +873,11 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Mouse button released, a #PuglEventButton case PUGL_BUTTON_RELEASE: { - if (pData->ignoreEvents) - break; Widget::MouseEvent ev; ev.mod = event->button.state; ev.flags = event->button.flags; ev.time = static_cast(event->button.time * 1000.0 + 0.5); - ev.button = event->button.button; + ev.button = event->button.button + 1; ev.press = event->type == PUGL_BUTTON_PRESS; ev.pos = Point(event->button.x, event->button.y); ev.absolutePos = ev.pos; @@ -889,8 +888,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Pointer moved, a #PuglEventMotion case PUGL_MOTION: { - if (pData->ignoreEvents) - break; Widget::MotionEvent ev; ev.mod = event->motion.state; ev.flags = event->motion.flags; @@ -904,8 +901,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Scrolled, a #PuglEventScroll case PUGL_SCROLL: { - if (pData->ignoreEvents) - break; Widget::ScrollEvent ev; ev.mod = event->scroll.state; ev.flags = event->scroll.flags; @@ -924,8 +919,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Timer triggered, a #PuglEventTimer case PUGL_TIMER: - if (pData->ignoreEvents) - break; if (IdleCallback* const idleCallback = reinterpret_cast(event->timer.id)) idleCallback->idleCallback(); break; @@ -937,6 +930,14 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< Recursive loop left, a #PuglEventLoopLeave case PUGL_LOOP_LEAVE: break; + + ///< Data offered from clipboard, a #PuglDataOfferEvent + case PUGL_DATA_OFFER: + break; + + ///< Data available from clipboard, a #PuglDataEvent + case PUGL_DATA: + break; } return PUGL_SUCCESS; diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp index 36d2ce43..6cb8a4d6 100644 --- a/dgl/src/WindowPrivateData.hpp +++ b/dgl/src/WindowPrivateData.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2021 Filipe Coelho + * Copyright (C) 2012-2022 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -45,7 +45,7 @@ struct Window::PrivateData : IdleCallback { PuglView* view; /** Pugl view instance of the transient parent window. */ - PuglView* const transientParentView; +// PuglView* const transientParentView; /** Reserved space for graphics context. */ mutable uint8_t graphicsContext[sizeof(void*)]; @@ -80,9 +80,6 @@ struct Window::PrivateData : IdleCallback { /** Whether to ignore idle callback requests, useful for temporary windows. */ bool ignoreIdleCallbacks; - /** Whether to ignore pugl events (except create and destroy), used for puglGetClipboard. */ - bool ignoreEvents; - /** Render to a picture file when non-null, automatically free+unset after saving. */ char* filenameToRenderInto; diff --git a/dgl/src/pugl-upstream b/dgl/src/pugl-upstream index b1d9703e..9691a681 160000 --- a/dgl/src/pugl-upstream +++ b/dgl/src/pugl-upstream @@ -1 +1 @@ -Subproject commit b1d9703ecbdb0a033fe0b9acdf58b90f7d81a8e5 +Subproject commit 9691a6810283ffd5a99b1cc974fc638e80f94979 diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp index ae99221c..3f697d3d 100644 --- a/dgl/src/pugl.cpp +++ b/dgl/src/pugl.cpp @@ -16,10 +16,24 @@ #include "pugl.hpp" +// -------------------------------------------------------------------------------------------------------------------- +// include base headers + +#ifdef DGL_CAIRO +# include +#endif +#ifdef DGL_OPENGL +# include "../OpenGL-include.hpp" +#endif +#ifdef DGL_VULKAN +# include +#endif + /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ #include #include #include +#include #include #include @@ -57,9 +71,10 @@ # endif #else # include +# include # include # include -# include +// # include # include # include # include @@ -68,7 +83,7 @@ # include # ifdef HAVE_XCURSOR # include -# include +// # include # endif # ifdef HAVE_XRANDR # include @@ -78,15 +93,12 @@ # include # endif # ifdef DGL_CAIRO -# include # include # endif # ifdef DGL_OPENGL -# include # include # endif # ifdef DGL_VULKAN -# include # include # endif #endif @@ -101,6 +113,8 @@ #ifndef DISTRHO_OS_MAC START_NAMESPACE_DGL +#else +USE_NAMESPACE_DGL #endif // -------------------------------------------------------------------------------------------------------------------- @@ -113,9 +127,6 @@ START_NAMESPACE_DGL # define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView) # define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow) # endif -# ifndef __MAC_10_9 -# define NSModalResponseOK NSOKButton -# endif # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdeprecated-declarations" # import "pugl-upstream/src/mac.m" @@ -159,7 +170,7 @@ START_NAMESPACE_DGL #include "pugl-upstream/src/implementation.c" // -------------------------------------------------------------------------------------------------------------------- -// expose backend enter +// DGL specific, expose backend enter bool puglBackendEnter(PuglView* const view) { @@ -167,109 +178,39 @@ bool puglBackendEnter(PuglView* const view) } // -------------------------------------------------------------------------------------------------------------------- -// expose backend leave - -void puglBackendLeave(PuglView* const view) -{ - view->backend->leave(view, nullptr); -} - -// -------------------------------------------------------------------------------------------------------------------- -// clear minimum size to 0 - -void puglClearMinSize(PuglView* const view) -{ - view->minWidth = 0; - view->minHeight = 0; -} - -// -------------------------------------------------------------------------------------------------------------------- -// missing in pugl, directly returns transient parent +// DGL specific, expose backend leave -PuglNativeView puglGetTransientParent(const PuglView* const view) +bool puglBackendLeave(PuglView* const view) { - return view->transientParent; + return view->backend->leave(view, nullptr) == PUGL_SUCCESS; } // -------------------------------------------------------------------------------------------------------------------- -// missing in pugl, directly returns title char* pointer +// DGL specific, assigns backend that matches current DGL build -const char* puglGetWindowTitle(const PuglView* const view) +void puglSetMatchingBackendForCurrentBuild(PuglView* const view) { - return view->title; +#ifdef DGL_CAIRO + puglSetBackend(view, puglCairoBackend()); +#endif +#ifdef DGL_OPENGL + puglSetBackend(view, puglGlBackend()); +#endif +#ifdef DGL_VULKAN + puglSetBackend(view, puglVulkanBackend()); +#endif + if (view->backend == nullptr) + puglSetBackend(view, puglStubBackend()); } // -------------------------------------------------------------------------------------------------------------------- -// get global scale factor - -double puglGetDesktopScaleFactor(const PuglView* const view) -{ -#if defined(DISTRHO_OS_MAC) - if (NSWindow* const window = view->impl->window ? view->impl->window - : [view->impl->wrapperView window]) - return [window screen].backingScaleFactor; - return [NSScreen mainScreen].backingScaleFactor; -#elif defined(DISTRHO_OS_WINDOWS) - if (const HMODULE Shcore = LoadLibraryA("Shcore.dll")) - { - typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*); - typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*); - -# if defined(__GNUC__) && (__GNUC__ >= 9) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcast-function-type" -# endif - const PFN_GetProcessDpiAwareness GetProcessDpiAwareness - = (PFN_GetProcessDpiAwareness)GetProcAddress(Shcore, "GetProcessDpiAwareness"); - const PFN_GetScaleFactorForMonitor GetScaleFactorForMonitor - = (PFN_GetScaleFactorForMonitor)GetProcAddress(Shcore, "GetScaleFactorForMonitor"); -# if defined(__GNUC__) && (__GNUC__ >= 9) -# pragma GCC diagnostic pop -# endif - - DWORD dpiAware = 0; - if (GetProcessDpiAwareness && GetScaleFactorForMonitor - && GetProcessDpiAwareness(NULL, &dpiAware) == 0 && dpiAware != 0) - { - const HMONITOR hMon = MonitorFromWindow(view->impl->hwnd, MONITOR_DEFAULTTOPRIMARY); - - DWORD scaleFactor = 0; - if (GetScaleFactorForMonitor(hMon, &scaleFactor) == 0 && scaleFactor != 0) - { - FreeLibrary(Shcore); - return static_cast(scaleFactor) / 100.0; - } - } - - FreeLibrary(Shcore); - } -#elif defined(HAVE_X11) - XrmInitialize(); - - if (char* const rms = XResourceManagerString(view->world->impl->display)) - { - if (const XrmDatabase sdb = XrmGetStringDatabase(rms)) - { - char* type = nullptr; - XrmValue ret; - - if (XrmGetResource(sdb, "Xft.dpi", "String", &type, &ret) - && ret.addr != nullptr - && type != nullptr - && std::strncmp("String", type, 6) == 0) - { - if (const double dpi = std::atof(ret.addr)) - return dpi / 96; - } - } - } -#else - // unused - (void)view; -#endif +// clear minimum size to 0 - return 1.0; -} +// void puglClearMinSize(PuglView* const view) +// { +// view->sizeHints[PUGL_MIN_SIZE].width = 0; +// view->sizeHints[PUGL_MIN_SIZE].height = 0; +// } // -------------------------------------------------------------------------------------------------------------------- // bring view window into the foreground, aka "raise" window @@ -284,48 +225,55 @@ void puglRaiseWindow(PuglView* const view) SetForegroundWindow(view->impl->hwnd); SetActiveWindow(view->impl->hwnd); #else - XRaiseWindow(view->impl->display, view->impl->win); + XRaiseWindow(view->world->impl->display, view->impl->win); #endif } // -------------------------------------------------------------------------------------------------------------------- -// set backend that matches current build +// get scale factor from parent window if possible, fallback to puglGetScaleFactor -void puglSetMatchingBackendForCurrentBuild(PuglView* const view) +double puglGetScaleFactorFromParent(const PuglView* const view) { -#ifdef DGL_CAIRO - puglSetBackend(view, puglCairoBackend()); -#endif -#ifdef DGL_OPENGL - puglSetBackend(view, puglGlBackend()); -#endif -#ifdef DGL_VULKAN - puglSetBackend(view, puglVulkanBackend()); + const PuglNativeView parent = view->parent ? view->parent : view->transientParent ? view->transientParent : 0; +#if defined(DISTRHO_OS_MAC) + NSWindow* const window = parent != 0 ? [(NSView*)parent window] + : view->impl->window ? view->impl->window : [view->impl->wrapperView window]); + NSScreen* const screen = window != nullptr ? [window screen] : [NSScreen mainScreen]; + return [screen backingScaleFactor]; +#elif defined(DISTRHO_OS_WINDOWS) + const HWND hwnd = parent != 0 ? (HWND)parent : view->impl->hwnd; + return puglWinGetViewScaleFactor(hwnd); +#else + return puglGetScaleFactor(view); + // unused + (void)parent; #endif - if (view->backend == nullptr) - puglSetBackend(view, puglStubBackend()); } // -------------------------------------------------------------------------------------------------------------------- -// Combine puglSetMinSize and puglSetAspectRatio +// Combined puglSetSizeHint using PUGL_MIN_SIZE and PUGL_FIXED_ASPECT PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, const uint height, const bool aspect) { - view->minWidth = (int)width; - view->minHeight = (int)height; - - if (aspect) { - view->minAspectX = (int)width; - view->minAspectY = (int)height; - view->maxAspectX = (int)width; - view->maxAspectY = (int)height; + view->sizeHints[PUGL_MIN_SIZE].width = width; + view->sizeHints[PUGL_MIN_SIZE].height = height; + + if (aspect) + { + view->sizeHints[PUGL_FIXED_ASPECT].width = width; + view->sizeHints[PUGL_FIXED_ASPECT].height = height; } #if defined(DISTRHO_OS_MAC) - puglSetMinSize(view, width, height); + if (view->impl->window) + { + PuglStatus status; + + if ((status = updateSizeHint(view, PUGL_MIN_SIZE)) != PUGL_SUCCESS) + return status; - if (aspect) { - puglSetAspectRatio(view, width, height, width, height); + if (aspect && (status = updateSizeHint(view, PUGL_FIXED_ASPECT)) != PUGL_SUCCESS) + return status; } #elif defined(DISTRHO_OS_WINDOWS) // nothing @@ -333,92 +281,90 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co if (const PuglStatus status = updateSizeHints(view)) return status; - XFlush(view->impl->display); + XFlush(view->world->impl->display); #endif return PUGL_SUCCESS; } // -------------------------------------------------------------------------------------------------------------------- -// set window offset without changing size +// set view as resizable (or not) during runtime -PuglStatus puglSetWindowOffset(PuglView* const view, const int x, const int y) +void puglSetResizable(PuglView* const view, const bool resizable) { - // TODO custom setFrame version - PuglRect rect = puglGetFrame(view); - rect.x = x; - rect.y = y; - return puglSetFrame(view, rect); + puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); + +#if defined(DISTRHO_OS_MAC) + if (PuglWindow* const window = view->impl->window) + { + const uint style = (NSClosableWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask) + | (resizable ? NSResizableWindowMask : 0x0); + [window setStyleMask:style]; + } + // FIXME use [view setAutoresizingMask:NSViewNotSizable] ? +#elif defined(DISTRHO_OS_WINDOWS) + if (const HWND hwnd = view->impl->hwnd) + { + const uint winFlags = resizable ? GetWindowLong(hwnd, GWL_STYLE) | (WS_SIZEBOX | WS_MAXIMIZEBOX) + : GetWindowLong(hwnd, GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX); + SetWindowLong(hwnd, GWL_STYLE, winFlags); + } +#else + updateSizeHints(view); +#endif } // -------------------------------------------------------------------------------------------------------------------- -// set window size with default size and without changing frame x/y position +// set window size while also changing default -PuglStatus puglSetWindowSize(PuglView* const view, const uint width, const uint height) +PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height) { - view->defaultWidth = width; - view->defaultHeight = height; - view->frame.width = width; - view->frame.height = height; + if (width > INT16_MAX || height > INT16_MAX) + return PUGL_BAD_PARAMETER; + + view->sizeHints[PUGL_DEFAULT_SIZE].width = view->frame.width = static_cast(width); + view->sizeHints[PUGL_DEFAULT_SIZE].height = view->frame.height = static_cast(height); #if defined(DISTRHO_OS_MAC) - // replace setFrame with setFrameSize + // mostly matches upstream pugl, simplified PuglInternals* const impl = view->impl; const PuglRect frame = view->frame; const NSRect framePx = rectToNsRect(frame); const NSRect framePt = nsRectToPoints(view, framePx); - if (impl->window) + if (PuglWindow* const window = view->impl->window) { - // Resize window to fit new content rect const NSRect screenPt = rectToScreen(viewScreen(view), framePt); - const NSRect winFrame = [impl->window frameRectForContentRect:screenPt]; - - [impl->window setFrame:winFrame display:NO]; + const NSRect winFrame = [window frameRectForContentRect:screenPt]; + [window setFrame:winFrame display:NO]; } - // Resize views const NSSize sizePx = NSMakeSize(frame.width, frame.height); const NSSize sizePt = [impl->drawView convertSizeFromBacking:sizePx]; - - [impl->wrapperView setFrameSize:(impl->window ? sizePt : framePt.size)]; + [impl->wrapperView setFrameSize:sizePt]; [impl->drawView setFrameSize:sizePt]; #elif defined(DISTRHO_OS_WINDOWS) - // matches upstream pugl, except we add SWP_NOMOVE flag - if (view->impl->hwnd) + // matches upstream pugl, except we re-enter context after resize + if (const HWND hwnd = view->impl->hwnd) { - const PuglRect frame = view->frame; - - RECT rect = { (long)frame.x, - (long)frame.y, - (long)frame.x + (long)frame.width, - (long)frame.y + (long)frame.height }; + const RECT rect = adjustedWindowRect(view, view->frame.x, view->frame.y, + static_cast(width), static_cast(height)); - AdjustWindowRectEx(&rect, puglWinGetWindowFlags(view), FALSE, puglWinGetWindowExFlags(view)); - - if (SetWindowPos(view->impl->hwnd, - HWND_TOP, - rect.left, - rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER)) - { - // make sure to return context back to ourselves - view->backend->enter(view, nullptr); - return PUGL_SUCCESS; - } + if (!SetWindowPos(hwnd, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE)) + return PUGL_UNKNOWN_ERROR; - return PUGL_UNKNOWN_ERROR; + // make sure to return context back to ourselves + puglBackendEnter(view); } #else - // matches upstream pugl, except we use XResizeWindow instead of XMoveResizeWindow - if (view->impl->win) + // matches upstream pugl, all in one + if (const Window window = view->impl->win) { - Display* const display = view->impl->display; + Display* const display = view->world->impl->display; - if (! XResizeWindow(display, view->impl->win, width, height)) + if (! XResizeWindow(display, window, width, height)) return PUGL_UNKNOWN_ERROR; if (const PuglStatus status = updateSizeHints(view)) @@ -456,6 +402,10 @@ void puglFallbackOnResize(PuglView* const view) glViewport(0, 0, static_cast(view->frame.width), static_cast(view->frame.height)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); +#else + return; + // unused + (void)view; #endif } @@ -603,67 +553,33 @@ void puglWin32ShowCentered(PuglView* const view) SetFocus(impl->hwnd); } -// -------------------------------------------------------------------------------------------------------------------- -// win32 specific, set or unset WS_SIZEBOX style flag - -void puglWin32SetWindowResizable(PuglView* const view, const bool resizable) -{ - PuglInternals* impl = view->impl; - DISTRHO_SAFE_ASSERT_RETURN(impl->hwnd != nullptr,); - - const int winFlags = resizable ? GetWindowLong(impl->hwnd, GWL_STYLE) | WS_SIZEBOX - : GetWindowLong(impl->hwnd, GWL_STYLE) & ~WS_SIZEBOX; - SetWindowLong(impl->hwnd, GWL_STYLE, winFlags); -} - // -------------------------------------------------------------------------------------------------------------------- #elif defined(HAVE_X11) -// -------------------------------------------------------------------------------------------------------------------- -// X11 specific, safer way to grab focus - -PuglStatus puglX11GrabFocus(const PuglView* const view) -{ - const PuglInternals* const impl = view->impl; - - XWindowAttributes wa; - std::memset(&wa, 0, sizeof(wa)); - - DISTRHO_SAFE_ASSERT_RETURN(XGetWindowAttributes(impl->display, impl->win, &wa), PUGL_UNKNOWN_ERROR); - - if (wa.map_state == IsViewable) - { - XRaiseWindow(impl->display, impl->win); - XSetInputFocus(impl->display, impl->win, RevertToPointerRoot, CurrentTime); - XSync(impl->display, False); - } - - return PUGL_SUCCESS; -} - // -------------------------------------------------------------------------------------------------------------------- // X11 specific, set dialog window type and pid hints void puglX11SetWindowTypeAndPID(const PuglView* const view, const bool isStandalone) { - const PuglInternals* const impl = view->impl; + const PuglInternals* const impl = view->impl; + Display* const display = view->world->impl->display; const pid_t pid = getpid(); - const Atom _nwp = XInternAtom(impl->display, "_NET_WM_PID", False); - XChangeProperty(impl->display, impl->win, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1); + const Atom _nwp = XInternAtom(display, "_NET_WM_PID", False); + XChangeProperty(display, impl->win, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1); - const Atom _wt = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE", False); + const Atom _wt = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); Atom _wts[2]; int numAtoms = 0; if (! isStandalone) - _wts[numAtoms++] = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE_DIALOG", False); + _wts[numAtoms++] = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); - _wts[numAtoms++] = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE_NORMAL", False); + _wts[numAtoms++] = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False); - XChangeProperty(impl->display, impl->win, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, numAtoms); + XChangeProperty(display, impl->win, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, numAtoms); } // -------------------------------------------------------------------------------------------------------------------- diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp index 30613ea6..7ebbc736 100644 --- a/dgl/src/pugl.hpp +++ b/dgl/src/pugl.hpp @@ -19,7 +19,7 @@ #include "../Base.hpp" -/* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ +/* we will include all header files used in pugl.h in their C++ friendly form, then pugl stuff in custom namespace */ #include #ifdef DISTRHO_PROPER_CPP11_SUPPORT # include @@ -29,75 +29,58 @@ # include #endif +// hidden api #define PUGL_API #define PUGL_DISABLE_DEPRECATED +#define PUGL_NO_INCLUDE_GL_H #define PUGL_NO_INCLUDE_GLU_H +// do not set extern "C" +// #define __cplusplus_backup __cplusplus +// #undef __cplusplus + +// give warning if defined as something else +// #define PUGL_BEGIN_DECLS +// #define PUGL_END_DECLS + // -------------------------------------------------------------------------------------------------------------------- -#ifndef DISTRHO_OS_MAC START_NAMESPACE_DGL -#else -USE_NAMESPACE_DGL -#endif #include "pugl-upstream/include/pugl/pugl.h" -// -------------------------------------------------------------------------------------------------------------------- - -PUGL_BEGIN_DECLS +// DGL specific, expose backend enter +bool puglBackendEnter(PuglView* view); -// expose backend enter -PUGL_API bool -puglBackendEnter(PuglView* view); +// DGL specific, expose backend leave +bool puglBackendLeave(PuglView* view); -// expose backend leave -PUGL_API void -puglBackendLeave(PuglView* view); +// DGL specific, assigns backend that matches current DGL build +void puglSetMatchingBackendForCurrentBuild(PuglView* view); // clear minimum size to 0 -PUGL_API void -puglClearMinSize(PuglView* view); - -// missing in pugl, directly returns transient parent -PUGL_API PuglNativeView -puglGetTransientParent(const PuglView* view); - -// missing in pugl, directly returns title char* pointer -PUGL_API const char* -puglGetWindowTitle(const PuglView* view); - -// get global scale factor -PUGL_API double -puglGetDesktopScaleFactor(const PuglView* view); +void puglClearMinSize(PuglView* view); // bring view window into the foreground, aka "raise" window -PUGL_API void -puglRaiseWindow(PuglView* view); +void puglRaiseWindow(PuglView* view); -// DGL specific, assigns backend that matches current DGL build -PUGL_API void -puglSetMatchingBackendForCurrentBuild(PuglView* view); +// get scale factor from parent window if possible, fallback to puglGetScaleFactor +double puglGetScaleFactorFromParent(const PuglView* view); -// Combine puglSetMinSize and puglSetAspectRatio -PUGL_API PuglStatus -puglSetGeometryConstraints(PuglView* view, uint width, uint height, bool aspect); +// combined puglSetSizeHint using PUGL_MIN_SIZE, PUGL_MIN_ASPECT and PUGL_MAX_ASPECT +PuglStatus puglSetGeometryConstraints(PuglView* view, uint width, uint height, bool aspect); -// set window offset without changing size -PUGL_API PuglStatus -puglSetWindowOffset(PuglView* view, int x, int y); +// set view as resizable (or not) during runtime +void puglSetResizable(PuglView* view, bool resizable); -// set window size with default size and without changing frame x/y position -PUGL_API PuglStatus -puglSetWindowSize(PuglView* view, uint width, uint height); +// set window size while also changing default +PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height); // DGL specific, build-specific drawing prepare -PUGL_API void -puglOnDisplayPrepare(PuglView* view); +void puglOnDisplayPrepare(PuglView* view); // DGL specific, build-specific fallback resize -PUGL_API void -puglFallbackOnResize(PuglView* view); +void puglFallbackOnResize(PuglView* view); #if defined(DISTRHO_OS_MAC) @@ -127,28 +110,18 @@ puglWin32RestoreWindow(PuglView* view); PUGL_API void puglWin32ShowCentered(PuglView* view); -// win32 specific, set or unset WS_SIZEBOX style flag -PUGL_API void -puglWin32SetWindowResizable(PuglView* view, bool resizable); - #elif defined(HAVE_X11) -// X11 specific, safer way to grab focus -PUGL_API PuglStatus -puglX11GrabFocus(const PuglView* view); - // X11 specific, set dialog window type and pid hints -PUGL_API void -puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone); +void puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone); #endif -PUGL_END_DECLS - // -------------------------------------------------------------------------------------------------------------------- -#ifndef DISTRHO_OS_MAC END_NAMESPACE_DGL -#endif + +// #define __cplusplus __cplusplus_backup +// #undef __cplusplus_backup #endif // DGL_PUGL_HPP_INCLUDED diff --git a/distrho/src/DistrhoUIPrivateData.hpp b/distrho/src/DistrhoUIPrivateData.hpp index ce031e12..c0985344 100644 --- a/distrho/src/DistrhoUIPrivateData.hpp +++ b/distrho/src/DistrhoUIPrivateData.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2021 Filipe Coelho + * Copyright (C) 2012-2022 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -234,7 +234,7 @@ public: #ifdef DISTRHO_PLUGIN_TARGET_VST3 void setSizeForVST3(const uint width, const uint height) { - puglSetWindowSize(pData->view, width, height); + puglSetSizeAndDefault(pData->view, width, height); } #endif diff --git a/pugl-updates-notes.txt b/pugl-updates-notes.txt new file mode 100644 index 00000000..3430c529 --- /dev/null +++ b/pugl-updates-notes.txt @@ -0,0 +1,9 @@ + +puglClearMinSize needed? +clipboard todo + +puglSetWindowSize was used on first show, still needed? + +pugl namespace details finalized + +window starts centered for screen or parent finalized