[gtk/master.win32: 8/8] GDK-Win32: Use SetProcessDpiAwarenessContext() where available
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/master.win32: 8/8] GDK-Win32: Use SetProcessDpiAwarenessContext() where available
- Date: Fri, 31 Jul 2020 15:20:42 +0000 (UTC)
commit 20388f83f58e9d9b7e798c07be3b731a7891201b
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Wed Dec 4 18:41:05 2019 +0800
GDK-Win32: Use SetProcessDpiAwarenessContext() where available
This allows us to use DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 for the
DPI awareness mode, which will help us to better support use cases with
multiple monitors. This is actualy a more advaned version of the
current PROCESS_PER_MONITOR_DPI_AWARE via using SetProcessDpiAwareness().
Note that this is not enabled by default, but also enabled via using
GDK_WIN32_PER_MONITOR_HIDPI, as in the PROCESS_PER_MONITOR_DPI_AWARE
case.
Note also, that appliation compatibility settings and DPI-awareness
manifests takes precedence over this API call, as before.
gdk/win32/gdkdisplay-win32.c | 75 +++++++++++++++++++++++++++++++++++++++++---
gdk/win32/gdkdisplay-win32.h | 32 ++++++++++++++++++-
2 files changed, 101 insertions(+), 6 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index a1c0b26e0b..788d03870b 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -698,6 +698,9 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
gboolean check_for_dpi_awareness = FALSE;
gboolean have_hpi_disable_envvar = FALSE;
+ HMODULE user32;
+ user32 = GetModuleHandleW (L"user32.dll");
+
enum dpi_aware_status {
DPI_STATUS_PENDING,
DPI_STATUS_SUCCESS,
@@ -709,6 +712,17 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
{
/* If we are on Windows 8.1 or later, cache up functions from shcore.dll, by all means */
display->have_at_least_win81 = TRUE;
+
+ if (user32 != NULL)
+ {
+ display->user32_dpi_funcs.setPDAC =
+ (funcSPDAC) GetProcAddress (user32, "SetProcessDpiAwarenessContext");
+ display->user32_dpi_funcs.getTDAC =
+ (funcGTDAC) GetProcAddress (user32, "GetThreadDpiAwarenessContext");
+ display->user32_dpi_funcs.areDACEqual =
+ (funcADACE) GetProcAddress (user32, "AreDpiAwarenessContextsEqual");
+ }
+
display->shcore_funcs.hshcore = LoadLibraryW (L"shcore.dll");
if (display->shcore_funcs.hshcore != NULL)
@@ -728,10 +742,8 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
else
{
/* Windows Vista through 8: use functions from user32.dll directly */
- HMODULE user32;
display->have_at_least_win81 = FALSE;
- user32 = GetModuleHandleW (L"user32.dll");
if (user32 != NULL)
{
@@ -748,7 +760,42 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
if (display->have_at_least_win81)
{
/* then make the GDK-using app DPI-aware */
- if (display->shcore_funcs.setDpiAwareFunc != NULL)
+ if (display->user32_dpi_funcs.setPDAC != NULL)
+ {
+ HANDLE hidpi_mode_ctx;
+ GdkWin32ProcessDpiAwareness hidpi_mode;
+
+ /* TODO: See how per-monitor DPI awareness is done by the Wayland backend */
+ if (g_getenv ("GDK_WIN32_PER_MONITOR_HIDPI") != NULL)
+ {
+ hidpi_mode_ctx = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2;
+ hidpi_mode = PROCESS_PER_MONITOR_DPI_AWARE;
+ }
+ else
+ {
+ hidpi_mode_ctx = DPI_AWARENESS_CONTEXT_SYSTEM_AWARE;
+ hidpi_mode = PROCESS_SYSTEM_DPI_AWARE;
+ }
+
+ if (display->user32_dpi_funcs.setPDAC (hidpi_mode_ctx))
+ {
+ display->dpi_aware_type = hidpi_mode;
+ status = DPI_STATUS_SUCCESS;
+ }
+ else
+ {
+ DWORD err = GetLastError ();
+
+ if (err == ERROR_ACCESS_DENIED)
+ check_for_dpi_awareness = TRUE;
+ else
+ {
+ display->dpi_aware_type = PROCESS_DPI_UNAWARE;
+ status = DPI_STATUS_FAILED;
+ }
+ }
+ }
+ else if (display->shcore_funcs.setDpiAwareFunc != NULL)
{
GdkWin32ProcessDpiAwareness hidpi_mode;
@@ -819,7 +866,25 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
{
if (display->have_at_least_win81)
{
- if (display->shcore_funcs.getDpiAwareFunc != NULL)
+ if (display->user32_dpi_funcs.getTDAC != NULL &&
+ display->user32_dpi_funcs.areDACEqual != NULL)
+ {
+ HANDLE dpi_aware_ctx = display->user32_dpi_funcs.getTDAC ();
+ if (display->user32_dpi_funcs.areDACEqual (dpi_aware_ctx,
+ DPI_AWARENESS_CONTEXT_UNAWARE))
+ /* This means the DPI awareness setting was forcefully disabled */
+ status = DPI_STATUS_DISABLED;
+ else
+ {
+ status = DPI_STATUS_SUCCESS;
+ if (display->user32_dpi_funcs.areDACEqual (dpi_aware_ctx,
+ DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
+ display->dpi_aware_type = PROCESS_SYSTEM_DPI_AWARE;
+ else
+ display->dpi_aware_type = PROCESS_PER_MONITOR_DPI_AWARE_V2;
+ }
+ }
+ else if (display->shcore_funcs.getDpiAwareFunc != NULL)
{
display->shcore_funcs.getDpiAwareFunc (NULL, &display->dpi_aware_type);
@@ -862,7 +927,7 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
/* The user setting or application manifest trumps over GDK_WIN32_DISABLE_HIDPI */
g_print ("Note: GDK_WIN32_DISABLE_HIDPI is ignored due to preset\n"
" DPI awareness settings in user settings or application\n"
- " manifest, DPI awareness is still enabled.");
+ " manifest, DPI awareness is still enabled.\n");
}
}
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index b9bfaeb2e1..46a80def2e 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -33,9 +33,24 @@
typedef enum _GdkWin32ProcessDpiAwareness {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
- PROCESS_PER_MONITOR_DPI_AWARE = 2
+ PROCESS_PER_MONITOR_DPI_AWARE = 2,
+ PROCESS_PER_MONITOR_DPI_AWARE_V2 = 3, /* Newer HiDPI type for Windows 10 1607+ */
} GdkWin32ProcessDpiAwareness;
+/* From https://docs.microsoft.com/en-US/windows/win32/hidpi/dpi-awareness-context */
+/* DPI_AWARENESS_CONTEXT is declared by DEFINE_HANDLE */
+#ifndef DPI_AWARENESS_CONTEXT_UNAWARE
+#define DPI_AWARENESS_CONTEXT_UNAWARE (HANDLE)-1
+#endif
+
+#ifndef DPI_AWARENESS_CONTEXT_SYSTEM_AWARE
+#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE (HANDLE)-2
+#endif
+
+#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
+#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (HANDLE)-4
+#endif
+
typedef enum _GdkWin32MonitorDpiType {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
@@ -63,10 +78,25 @@ typedef struct _GdkWin32ShcoreFuncs
typedef BOOL (WINAPI *funcSetProcessDPIAware) (void);
typedef BOOL (WINAPI *funcIsProcessDPIAware) (void);
+/*
+ * funcSPDAC is SetProcessDpiAwarenessContext() and
+ * funcGTDAC is GetThreadDpiAwarenessContext() and
+ * funcADACE is AreDpiAwarenessContextsEqual() provided by user32.dll, on
+ * Windows 10 Creator Edition and later.
+ * Treat HANDLE as void*, for convenience, since DPI_AWARENESS_CONTEXT is
+ * declared using DEFINE_HANDLE.
+ */
+typedef BOOL (WINAPI *funcSPDAC) (void *);
+typedef HANDLE (WINAPI *funcGTDAC) (void);
+typedef BOOL (WINAPI *funcADACE) (void *, void *);
+
typedef struct _GdkWin32User32DPIFuncs
{
funcSetProcessDPIAware setDpiAwareFunc;
funcIsProcessDPIAware isDpiAwareFunc;
+ funcSPDAC setPDAC;
+ funcGTDAC getTDAC;
+ funcADACE areDACEqual;
} GdkWin32User32DPIFuncs;
/* Detect running architecture */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]