diff -ur gtk+-0d30ad2/gdk/win32/gdkdisplay-win32.c gtk+-0d30ad2.orig/gdk/win32/gdkdisplay-win32.c
--- gtk+-0d30ad2/gdk/win32/gdkdisplay-win32.c	2016-07-04 16:19:31.678128300 +0000
+++ gtk+-0d30ad2.orig/gdk/win32/gdkdisplay-win32.c	2016-07-02 12:31:43.285304200 +0000
@@ -193,6 +193,43 @@
       changed = TRUE;
     }
 
+  for (i = 0; i < win32_display->monitors->len; i++)
+    {
+      GdkMonitor *m;
+      GdkWin32Monitor *w32_m;
+
+      m = GDK_MONITOR (g_ptr_array_index (win32_display->monitors, i));
+      w32_m = GDK_WIN32_MONITOR (m);
+
+      if (win32_display->fixed_window_scale)
+        gdk_monitor_set_scale_factor (m, win32_display->window_scale);
+      else
+        {
+          HMONITOR hmonitor;
+          GdkRectangle workarea;
+          POINT pt;
+          UINT dpix, dpiy;
+
+          gdk_monitor_get_workarea (m, &workarea);
+          workarea.x -= _gdk_offset_x;
+          workarea.y -= _gdk_offset_y;
+          workarea.x += workarea.width / 2;
+          workarea.y += workarea.height / 2;
+          pt.x = workarea.x;
+          pt.y = workarea.y;
+
+          hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
+
+          if (_gdk_win32_display_get_monitor_scale_factor (win32_display,
+                                                           hmonitor,
+                                                           NULL,
+                                                           &dpix, &dpiy))
+            {
+              gdk_monitor_set_scale_factor (m, dpix / 96 < 1 ? 1 : dpix / 96);
+            }
+        }
+    }
+
   return changed;
 }
 
@@ -949,11 +986,24 @@
 static void
 gdk_win32_display_init (GdkWin32Display *display)
 {
+  const char *scale_str;
+
   display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
 
   if (g_getenv ("GDK_WIN32_DISABLE_HIDPI") == NULL)
     _gdk_win32_enable_hidpi (display);
 
+  scale_str = g_getenv ("GDK_SCALE");
+  if (scale_str)
+    {
+      display->fixed_window_scale = TRUE;
+      display->window_scale = atol (scale_str);
+      if (display->window_scale == 0)
+        display->window_scale = 1;
+    }
+  else
+    display->window_scale = 1;
+
   _gdk_win32_display_init_cursors (display);
 }
 
diff -ur gtk+-0d30ad2/gdk/win32/gdkdisplay-win32.h gtk+-0d30ad2.orig/gdk/win32/gdkdisplay-win32.h
--- gtk+-0d30ad2/gdk/win32/gdkdisplay-win32.h	2016-07-04 16:19:31.676128200 +0000
+++ gtk+-0d30ad2.orig/gdk/win32/gdkdisplay-win32.h	2016-07-02 12:31:53.161869100 +0000
@@ -83,6 +83,8 @@
   GdkWin32ProcessDpiAwareness dpi_aware_type;
   guint have_at_least_win81 : 1;
   GdkWin32ShcoreFuncs shcore_funcs;
+  glong window_scale;
+  gboolean fixed_window_scale;
 };
 
 struct _GdkWin32DisplayClass
@@ -94,4 +96,10 @@
 
 GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
 
+gboolean   _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
+                                                        HMONITOR         hmonitor,
+                                                        HWND             hwnd,
+                                                        UINT            *dpix,
+                                                        UINT            *dpiy);
+
 #endif /* __GDK_DISPLAY__WIN32_H__ */
diff -ur gtk+-0d30ad2/gdk/win32/gdkwindow-win32.c gtk+-0d30ad2.orig/gdk/win32/gdkwindow-win32.c
--- gtk+-0d30ad2/gdk/win32/gdkwindow-win32.c	2016-07-04 16:19:31.708130100 +0000
+++ gtk+-0d30ad2.orig/gdk/win32/gdkwindow-win32.c	2016-07-02 14:12:15.745174300 +0000
@@ -6098,6 +6098,8 @@
 
       impl->cache_surface = new_cache;
 
+      cairo_surface_set_device_scale (new_cache, impl->window_scale, impl->window_scale);
+
       if (impl->cairo_surface)
         cairo_surface_destroy (impl->cairo_surface);
 
@@ -6113,6 +6115,7 @@
       impl->cairo_surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
       impl->dib_width = width;
       impl->dib_height = height;
+      cairo_surface_set_device_scale (impl->cairo_surface, impl->window_scale, impl->window_scale);
 
       cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
 				   impl, gdk_win32_cairo_surface_destroy);
@@ -6270,6 +6273,44 @@
   impl->margins_y = top + bottom;
 }
 
+gboolean
+_gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
+                                             HMONITOR         hmonitor,
+                                             HWND             hwnd,
+                                             UINT            *dpix,
+                                             UINT            *dpiy)
+{
+  gboolean is_scale_acquired;
+
+  if (win32_display->have_at_least_win81)
+    {
+      /* Use GetDpiForMonitor() for Windows 8.1+ */
+      if (win32_display->shcore_funcs.hshcore != NULL &&
+          win32_display->shcore_funcs.getDpiForMonitorFunc != NULL)
+        {
+          if (win32_display->shcore_funcs.getDpiForMonitorFunc (hmonitor,
+                                                                MDT_EFFECTIVE_DPI,
+                                                                dpix,
+                                                                dpiy) == S_OK)
+            {
+              is_scale_acquired = TRUE;
+            }
+        }
+    }
+  else
+    {
+      /* Go back to GetDeviceCaps() for Windows 8 and earler */
+      HDC hdc = GetDC (hwnd);
+      *dpix = GetDeviceCaps (hdc, LOGPIXELSX);
+      *dpiy = GetDeviceCaps (hdc, LOGPIXELSY);
+      ReleaseDC (hwnd, hdc);
+
+      is_scale_acquired = TRUE;
+    }
+
+  return is_scale_acquired;
+}
+
 gint
 _gdk_win32_window_get_scale_factor (GdkWindow *window)
 {
@@ -6283,6 +6283,11 @@
   g_return_val_if_fail (display != NULL, 1);
   win32_display = GDK_WIN32_DISPLAY (display);
 
+  if (win32_display->fixed_window_scale)
+  {
+    return impl->window_scale = win32_display->window_scale;
+  }
+
   if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
   {
     if (!win32_display->have_at_least_win81)
@@ -6290,36 +6331,16 @@
 
   if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
   {
-    is_scale_acquired = FALSE;
+    HMONITOR hmonitor;
 
-    if (win32_display->have_at_least_win81)
-      {
-        /* Use GetDpiForMonitor() for Windows 8.1+ */
-        if (win32_display->shcore_funcs.hshcore != NULL &&
-            win32_display->shcore_funcs.getDpiForMonitorFunc != NULL)
-          {
-            HMONITOR hmonitor = MonitorFromWindow (GDK_WINDOW_HWND (window),
-                                                   MONITOR_DEFAULTTONEAREST);
-
-            if (win32_display->shcore_funcs.getDpiForMonitorFunc (hmonitor,
-                                                                  MDT_EFFECTIVE_DPI,
-                                                                  &dpix,
-                                                                  &dpiy) == S_OK)
-              {
-                is_scale_acquired = TRUE;
-              }
-          }
-      }
-    else
-      {
-        /* Go back to GetDeviceCaps() for Windows 8 and earler */
-        HDC hdc = GetDC (GDK_WINDOW_HWND (window));
-        dpix = GetDeviceCaps (hdc, LOGPIXELSX);
-        dpiy = GetDeviceCaps (hdc, LOGPIXELSY);
-        ReleaseDC (GDK_WINDOW_HWND (window), hdc);
+    is_scale_acquired = FALSE;
+    hmonitor = MonitorFromWindow (GDK_WINDOW_HWND (window),
+                                  MONITOR_DEFAULTTONEAREST);
 
-        is_scale_acquired = TRUE;
-      }
+    is_scale_acquired = _gdk_win32_display_get_monitor_scale_factor (win32_display,
+                                                                     hmonitor,
+                                                                     GDK_WINDOW_HWND (window),
+                                                                     &dpix, &dpiy);
 
     if (is_scale_acquired)
       {
diff -ur gtk+-0d30ad2/gdk/win32/gdkwindow-win32.c.orig gtk+-0d30ad2.orig/gdk/win32/gdkwindow-win32.c.orig
--- gtk+-0d30ad2/gdk/win32/gdkwindow-win32.c.orig	2016-07-04 16:19:31.645126500 +0000
+++ gtk+-0d30ad2.orig/gdk/win32/gdkwindow-win32.c.orig	2016-07-01 21:33:41.244530500 +0000
@@ -6285,9 +6285,7 @@
 
   if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
   {
-    is_scale_acquired = FALSE;
-
-    if (win32_display->have_at_least_win81)
+    if (!win32_display->have_at_least_win81)
       {
         /* Use GetDpiForMonitor() for Windows 8.1+ */
         if (win32_display->shcore_funcs.hshcore != NULL &&
