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