[vlc-commits] [Git][videolan/vlc][master] qt: do not assume that the interface window is in the primary monitor in `CSDWin32EventHandler`
Steve Lhomme (@robUx4)
gitlab at videolan.org
Sat Mar 1 15:23:24 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
7e063c67 by Fatih Uzunoglu at 2025-03-01T15:07:54+00:00
qt: do not assume that the interface window is in the primary monitor in `CSDWin32EventHandler`
- `GetSystemMetrics()` function already scales most of the metrics for the
primary monitor [1], evidently because Qt makes the application DPI aware.
- Currently by multiplying the `GetSystemMetrics()` result with
`windowDpi / screenDpi`, we apply the window's DPI which is what is wanted
here.
- If the window is in the primary monitor, there is no problem. If there
are multiple monitors but they share the same DPI, there should also be no
problem. But if there are multiple monitors that have different DPIs, in
that case dragging would be problematic.
- The solution that Windows recommends [2] is using `GetSystemMetricsForDpi`
and `GetDpiForWindow`. Unfortunately these are only available on Windows 10,
so I dynamically load the necessary library and resolve the symbols.
- Handling `WM_DPICHANGED` and calling `SetWindowPos()` should not be
necessary, because Qt already calls it to resize the window according to
the new dpi.
[1] https://learn.microsoft.com/en-us/windows/win32/gdi/multiple-monitor-system-metrics
[2] https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows#updating-existing-applications
- - - - -
1 changed file:
- modules/gui/qt/maininterface/mainctx_win32.cpp
Changes:
=====================================
modules/gui/qt/maininterface/mainctx_win32.cpp
=====================================
@@ -40,10 +40,6 @@
#include <QWindow>
-#ifndef QT_GUI_PRIVATE
-#warning "qplatformnativeinterface.h header is required for MainCtxWin32"
-#endif
-#include <QtGui/qpa/qplatformnativeinterface.h>
#include <dwmapi.h>
#define WM_APPCOMMAND 0x0319
@@ -108,13 +104,10 @@ using namespace vlc::playlist;
namespace {
-HWND WinId( QWindow *windowHandle )
+HWND WinId( const QWindow *window )
{
- if( windowHandle && windowHandle->handle() )
- return static_cast<HWND>(QGuiApplication::platformNativeInterface()->
- nativeResourceForWindow("handle", windowHandle));
- else
- return 0;
+ assert(window);
+ return reinterpret_cast<HWND>(window->winId());
}
class CSDWin32EventHandler : public QObject, public QAbstractNativeEventFilter
@@ -142,26 +135,44 @@ public:
QApplication::instance()->removeNativeEventFilter(this);
}
+ static int getSystemMetricsForDpi(int nIndex, UINT dpi)
+ {
+ typedef int (WINAPI *GetSystemMetricsForDpiFunc)(int, UINT);
+ static GetSystemMetricsForDpiFunc getSystemMetricsForDpi = []() {
+ const auto user32dll = LoadLibraryEx(TEXT("user32.dll"), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ return reinterpret_cast<GetSystemMetricsForDpiFunc>(GetProcAddress(user32dll, "GetSystemMetricsForDpi"));
+ }();
+
+ if (getSystemMetricsForDpi)
+ return getSystemMetricsForDpi(nIndex, dpi);
+
+ return GetSystemMetrics(nIndex);
+ }
+
+ static int getSystemMetricsForWindow(int nIndex, const QWindow* window)
+ {
+ assert(window);
+
+ typedef UINT (WINAPI *GetDpiForWindowFunc)(HWND);
+ static GetDpiForWindowFunc getDpiForWindow = []() {
+ const auto user32dll = LoadLibraryEx(TEXT("user32.dll"), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ return reinterpret_cast<GetDpiForWindowFunc>(GetProcAddress(user32dll, "GetDpiForWindow"));
+ }();
+
+ if (getDpiForWindow)
+ return getSystemMetricsForDpi(nIndex, getDpiForWindow(WinId(window)));
+
+ return GetSystemMetrics(nIndex);
+ }
+
static int resizeBorderWidth(QWindow *window)
{
- // NOTE: When possible, Qt makes the application DPI aware, so `GetSystemMetrics()` would
- // already take the screen DPI into account.
- const int result = GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
- if (result > 0)
- return qRound(static_cast<qreal>(result) * (window->devicePixelRatio() / window->screen()->devicePixelRatio()));
- else
- return qRound(static_cast<qreal>(8) * window->devicePixelRatio());
+ return getSystemMetricsForWindow(SM_CXSIZEFRAME, window) + getSystemMetricsForWindow(SM_CXPADDEDBORDER, window);
}
static int resizeBorderHeight(QWindow *window)
{
- // NOTE: Qt makes the application DPI aware, so `GetSystemMetrics()` would already take
- // already take the screen DPI into account.
- const int result = GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
- if (result > 0)
- return qRound(static_cast<qreal>(result) * (window->devicePixelRatio() / window->screen()->devicePixelRatio()));
- else
- return qRound(static_cast<qreal>(8) * window->devicePixelRatio());
+ return getSystemMetricsForWindow(SM_CYSIZEFRAME, window) + getSystemMetricsForWindow(SM_CXPADDEDBORDER, window);
}
bool nativeEventFilter(const QByteArray &, void *message, qintptr *result) override
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/7e063c673e84ee4fb8e5a2cf859d4a3f9edac11b
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/7e063c673e84ee4fb8e5a2cf859d4a3f9edac11b
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list