summaryrefslogtreecommitdiff
path: root/gdk/win32/gdkmonitor-win32.c
diff options
context:
space:
mode:
authorРуслан Ижбулатов <lrn1986@gmail.com>2017-01-20 10:23:00 +0000
committerРуслан Ижбулатов <lrn1986@gmail.com>2017-12-02 10:38:23 +0000
commit58ba4d6a3e0bda764ad7ae9aeede39627ec6deb1 (patch)
treeff2898c6aad30dda604d00f8a1abf702806d8428 /gdk/win32/gdkmonitor-win32.c
parentf7ae36739ad054f029c27d766197d167ea970c87 (diff)
downloadgtk+-58ba4d6a3e0bda764ad7ae9aeede39627ec6deb1.tar.gz
GDK W32: Ensure that we use made-up monitors when there are none
Previously GDK only made up monitors when it initially found none. Now it also makes up monitors when it initially finds some, but later fails to get their informatin in a normal way and finally prunes them out, being left with zero monitors. Having zero-length monitor array is unexpected and causes a number of critical warnings and some critical functionality (such as displaying drop-down menus) fails in such cases. Ideally, there might be such a way to interrogate W32 API that produces the information about non-real (but active) monitors out of it so that it isn't necessary for us to make stuff up. However, this code is already complicated, and i am not prepared to dig W32 API to find a way to do this. This fixes the issues people had when they accessed a Windows desktop via RDP. https://bugzilla.gnome.org/show_bug.cgi?id=777527
Diffstat (limited to 'gdk/win32/gdkmonitor-win32.c')
-rw-r--r--gdk/win32/gdkmonitor-win32.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/gdk/win32/gdkmonitor-win32.c b/gdk/win32/gdkmonitor-win32.c
index 1686eb59be..ea58cb5fc5 100644
--- a/gdk/win32/gdkmonitor-win32.c
+++ b/gdk/win32/gdkmonitor-win32.c
@@ -722,6 +722,25 @@ enum_monitor (HMONITOR hmonitor,
return TRUE;
}
+static void
+prune_monitors (EnumMonitorData *data)
+{
+ gint i;
+
+ for (i = 0; i < data->monitors->len; i++)
+ {
+ GdkWin32Monitor *m;
+
+ m = g_ptr_array_index (data->monitors, i);
+
+ if (m->remove)
+ {
+ g_ptr_array_remove_index (data->monitors, i);
+ continue;
+ }
+ }
+}
+
GPtrArray *
_gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
{
@@ -743,6 +762,18 @@ _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &data);
+ prune_monitors (&data);
+
+ if (data.monitors->len == 0 && data.have_monitor_devices)
+ {
+ /* We thought we had monitors, but enumeration eventually failed, and
+ * we have none. Try again, this time making stuff up as we go.
+ */
+ data.have_monitor_devices = FALSE;
+ EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &data);
+ prune_monitors (&data);
+ }
+
_gdk_offset_x = G_MININT;
_gdk_offset_y = G_MININT;
@@ -753,12 +784,6 @@ _gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
m = g_ptr_array_index (data.monitors, i);
- if (m->remove)
- {
- g_ptr_array_remove_index (data.monitors, i);
- continue;
- }
-
/* Calculate offset */
gdk_monitor_get_geometry (GDK_MONITOR (m), &rect);
_gdk_offset_x = MAX (_gdk_offset_x, -rect.x);