DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 37e6922b315b05e198b7c4ca574cd4e41147056a
parent dbbfef6dc3f827295e3af9941b488075ff9f68f5
Author: falkTX <falktx@falktx.com>
Date:   Fri,  3 Sep 2021 20:14:53 +0100

Set desktop scale factor for external uis if not provided by host

Diffstat:
Mdistrho/src/DistrhoUI.cpp | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 90 insertions(+), 3 deletions(-)

diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp @@ -16,19 +16,106 @@ #include "DistrhoUIPrivateData.hpp" #include "src/WindowPrivateData.hpp" -#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI +#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI +# if defined(DISTRHO_OS_HAIKU) +# elif defined(DISTRHO_OS_MAC) +# define Point CocoaPoint +# define Size CocoaSize +# import <Cocoa/Cocoa.h> +# undef Point +# undef Size +# elif defined(DISTRHO_OS_WINDOWS) +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# else +# include <X11/Xresource.h> +# endif +#else # include "src/TopLevelWidgetPrivateData.hpp" #endif START_NAMESPACE_DISTRHO +#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI /* ------------------------------------------------------------------------------------------------------------ * Static data, see DistrhoUIInternal.hpp */ -#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI uintptr_t g_nextWindowId = 0; double g_nextScaleFactor = 1.0; const char* g_nextBundlePath = nullptr; + +/* ------------------------------------------------------------------------------------------------------------ + * get global scale factor */ + +static double getDesktopScaleFactor() +{ + // allow custom scale for testing + if (const char* const scale = getenv("DPF_SCALE_FACTOR")) + return std::max(1.0, std::atof(scale)); + +#if defined(DISTRHO_OS_MAC) + 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*); + + const PFN_GetProcessDpiAwareness GetProcessDpiAwareness + = (PFN_GetProcessDpiAwareness)GetProcAddress(Shcore, "GetProcessDpiAwareness"); + const PFN_GetScaleFactorForMonitor GetScaleFactorForMonitor + = (PFN_GetScaleFactorForMonitor)GetProcAddress(Shcore, "GetScaleFactorForMonitor"); + + DWORD dpiAware = 0; + if (GetProcessDpiAwareness && GetScaleFactorForMonitor + && GetProcessDpiAwareness(NULL, &dpiAware) == 0 && dpiAware != 0) + { + // TODO replace with something else + const HMONITOR hMon = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY); + + DWORD scaleFactor = 0; + if (GetScaleFactorForMonitor(hMon, &scaleFactor) == 0 && scaleFactor != 0) + { + FreeLibrary(Shcore); + return static_cast<double>(scaleFactor) / 100.0; + } + } + + FreeLibrary(Shcore); + } +#elif defined(HAVE_X11) + ::Display* const display = XOpenDisplay(nullptr); + DISTRHO_SAFE_ASSERT_RETURN(display != nullptr, 1.0); + + 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)) + { + XCloseDisplay(display); + return dpi / 96; + } + } + } + } + + XCloseDisplay(display); +#endif + + return 1.0; +} + #endif /* ------------------------------------------------------------------------------------------------------------ @@ -50,7 +137,7 @@ UI::PrivateData::createNextWindow(UI* const ui, const uint width, const uint hei ewData.parentWindowHandle = pData->winId; ewData.width = width; ewData.height = height; - ewData.scaleFactor = pData->scaleFactor; + ewData.scaleFactor = pData->scaleFactor != 0.0 ? pData->scaleFactor : getDesktopScaleFactor(); ewData.title = DISTRHO_PLUGIN_NAME; ewData.isStandalone = DISTRHO_UI_IS_STANDALONE; return ewData;