[gtk+] GDK W32: Apply HiDPI scale properly to monitors



commit 3c9b667d3ed2b931df31da0351a09e871057a9ad
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date:   Fri Feb 17 15:59:32 2017 +0000

    GDK W32: Apply HiDPI scale properly to monitors
    
    Previously HiDPI scale was retrieved and applied too late in the initialization
    process to affect monitor size and monitor workarea size, but the code that
    initializes these sizes *did* try to use the scale, even though it was always
    getting scale=1.
    
    To fix this, move the too-late code into monitor enumeration routine.
    This also fixes a probable semantic bug where width and height were divided
    by scale, again.
    
    Now monitor and workarea should be in application pixels (i.e. divided by scale),
    as intended.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=778835

 gdk/win32/gdkdisplay-win32.c |   36 --------------------------------
 gdk/win32/gdkmonitor-win32.c |   46 +++++++++++++++++++++++++++++++++++------
 2 files changed, 39 insertions(+), 43 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index ddc6767..a4b40da 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -199,42 +199,6 @@ _gdk_win32_display_init_monitors (GdkWin32Display *win32_display)
       g_ptr_array_insert (win32_display->monitors, 0, primary_to_move);
       changed = TRUE;
     }
-
-  for (i = 0; i < win32_display->monitors->len; i++)
-    {
-      GdkMonitor *monitor;
-      GdkWin32Monitor *win32_monitor;
-
-      monitor = GDK_MONITOR (g_ptr_array_index (win32_display->monitors, i));
-
-      if (win32_display->has_fixed_scale)
-        gdk_monitor_set_scale_factor (monitor, win32_display->window_scale);
-      else
-        {
-          /* First acquire the scale using the current screen */
-          GdkRectangle workarea;
-          POINT pt;
-          guint scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL);
-
-          gdk_monitor_get_workarea (monitor, &workarea);
-          workarea.x -= _gdk_offset_x;
-          workarea.y -= _gdk_offset_y;
-          workarea.x += workarea.width / scale;
-          workarea.y += workarea.height / scale;
-          pt.x = workarea.x;
-          pt.y = workarea.y;
-
-          /* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */
-          if (win32_display->have_at_least_win81)
-            {
-              HMONITOR hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
-              scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, hmonitor, NULL, NULL);
-            }
-
-          gdk_monitor_set_scale_factor (monitor, scale);
-        }
-    }
-
   return changed;
 }
 
diff --git a/gdk/win32/gdkmonitor-win32.c b/gdk/win32/gdkmonitor-win32.c
index ea58cb5..56b4a84 100644
--- a/gdk/win32/gdkmonitor-win32.c
+++ b/gdk/win32/gdkmonitor-win32.c
@@ -33,6 +33,8 @@
 
 #include "config.h"
 
+#include "gdkprivate-win32.h"
+#include "gdkdisplay-win32.h"
 #include "gdkmonitor-win32.h"
 
 #include <glib.h>
@@ -681,7 +683,43 @@ enum_monitor (HMONITOR hmonitor,
           /* This is the reason this function exists. This data is not available
            * via other functions.
            */
-          scale = gdk_monitor_get_scale_factor (mon);
+          rect.x = monitor_info.rcWork.left;
+          rect.y = monitor_info.rcWork.top;
+          rect.width = (monitor_info.rcWork.right - monitor_info.rcWork.left);
+          rect.height = (monitor_info.rcWork.bottom - monitor_info.rcWork.top);
+          /* This is temporary, scale will be applied below */
+          w32mon->work_rect = rect;
+
+          if (data->display->has_fixed_scale)
+            scale = data->display->window_scale;
+          else
+            {
+              /* First acquire the scale using the current screen */
+              scale = _gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL, NULL);
+
+              /* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */
+              if (data->display->have_at_least_win81)
+                {
+                  HMONITOR hmonitor;
+                  POINT pt;
+
+                  /* Not subtracting _gdk_offset_x and _gdk_offset_y because they will only
+                   * be added later on, in _gdk_win32_display_get_monitor_list().
+                   */
+                  pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
+                  pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
+                  hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
+                  scale = _gdk_win32_display_get_monitor_scale_factor (data->display, hmonitor, NULL, NULL);
+                }
+            }
+
+          gdk_monitor_set_scale_factor (mon, scale);
+          /* Now apply the scale to the work rectangle */
+          w32mon->work_rect.x /= scale;
+          w32mon->work_rect.y /= scale;
+          w32mon->work_rect.width /= scale;
+          w32mon->work_rect.height /= scale;
+
           rect.x = monitor_info.rcMonitor.left / scale;
           rect.y = monitor_info.rcMonitor.top / scale;
           rect.width = (monitor_info.rcMonitor.right - monitor_info.rcMonitor.left) / scale;
@@ -689,12 +727,6 @@ enum_monitor (HMONITOR hmonitor,
           gdk_monitor_set_position (mon, rect.x, rect.y);
           gdk_monitor_set_size (mon, rect.width, rect.height);
 
-          rect.x = monitor_info.rcWork.left / scale;
-          rect.y = monitor_info.rcWork.top / scale;
-          rect.width = (monitor_info.rcWork.right - monitor_info.rcWork.left) / scale;
-          rect.height = (monitor_info.rcWork.bottom - monitor_info.rcWork.top) / scale;
-          w32mon->work_rect = rect;
-
           if (monitor_info.dwFlags & MONITORINFOF_PRIMARY && i != 0)
             {
               /* Put primary monitor at index 0, just in case somebody needs


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]