[gtk+] win32: handle WM_DISPLAYCHANGE globally



commit 8606e57910fb3ea4c66448702ee7e3bb73f3c29d
Author: Paolo Borelli <pborelli gnome org>
Date:   Thu Oct 29 17:20:54 2015 +0100

    win32: handle WM_DISPLAYCHANGE globally
    
    Instead of handling WM_DISPLAYCHANGE on every GdkWindow, only handle
    it on an ad-hoc hidden window we create when opening the display.
    This has two reasons:
    1) we want emit the display::size-changed signal even if there are no
       gtk windows currently open
    2) we want to emit the signal just once and not once for every window
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757324

 gdk/win32/gdkdisplay-win32.c |   84 +++++++++++++++++++++++++++++++++++++++++-
 gdk/win32/gdkdisplay-win32.h |    2 +
 gdk/win32/gdkevents-win32.c  |   12 ------
 3 files changed, 84 insertions(+), 14 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index 0a47970..b1e6f01 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -26,6 +26,8 @@
 #include "gdkwin32window.h"
 #include "gdkwin32.h"
 
+static int debug_indent = 0;
+
 /**
  * gdk_win32_display_set_cursor_theme:
  * @display: (type GdkWin32Display): a #GdkDisplay
@@ -242,6 +244,81 @@ _gdk_monitor_init (void)
     }
 }
 
+static LRESULT CALLBACK
+inner_display_change_window_procedure (HWND   hwnd,
+                                       UINT   message,
+                                       WPARAM wparam,
+                                       LPARAM lparam)
+{
+  switch (message)
+    {
+    case WM_DESTROY:
+      {
+        PostQuitMessage (0);
+        return 0;
+      }
+    case WM_DISPLAYCHANGE:
+      {
+        _gdk_monitor_init ();
+        _gdk_root_window_size_init ();
+        g_signal_emit_by_name (_gdk_screen, "size_changed");
+
+        return 0;
+      }
+    default:
+      /* Otherwise call DefWindowProcW(). */
+      GDK_NOTE (EVENTS, g_print (" DefWindowProcW"));
+      return DefWindowProc (hwnd, message, wparam, lparam);
+    }
+}
+
+static LRESULT CALLBACK
+display_change_window_procedure (HWND   hwnd,
+                                 UINT   message,
+                                 WPARAM wparam,
+                                 LPARAM lparam)
+{
+  LRESULT retval;
+
+  GDK_NOTE (EVENTS, g_print ("%s%*s%s %p",
+                            (debug_indent > 0 ? "\n" : ""),
+                            debug_indent, "",
+                            _gdk_win32_message_to_string (message), hwnd));
+  debug_indent += 2;
+  retval = inner_display_change_window_procedure (hwnd, message, wparam, lparam);
+  debug_indent -= 2;
+
+  GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "%s", (gint64) retval, (debug_indent == 0 ? "\n" : 
"")));
+
+  return retval;
+}
+
+/* Use a hidden window to be notified about display changes */
+static void
+register_display_change_notification (GdkDisplay *display)
+{
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
+  WNDCLASS wclass = { 0, };
+  ATOM klass;
+
+  wclass.lpszClassName = "GdkDisplayChange";
+  wclass.lpfnWndProc = display_change_window_procedure;
+  wclass.hInstance = _gdk_app_hmodule;
+
+  klass = RegisterClass (&wclass);
+  if (klass)
+    {
+      display_win32->hwnd = CreateWindow (MAKEINTRESOURCE (klass),
+                                          NULL, WS_POPUP,
+                                          0, 0, 0, 0, NULL, NULL,
+                                          _gdk_app_hmodule, NULL);
+      if (!display_win32->hwnd)
+        {
+          UnregisterClass (MAKEINTRESOURCE (klass), _gdk_app_hmodule);
+        }
+    }
+}
+
 GdkDisplay *
 _gdk_win32_display_open (const gchar *display_name)
 {
@@ -276,6 +353,8 @@ _gdk_win32_display_open (const gchar *display_name)
   /* Precalculate display name */
   (void) gdk_display_get_name (_gdk_display);
 
+  register_display_change_notification (_gdk_display);
+
   g_signal_emit_by_name (_gdk_display, "opened");
 
   GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
@@ -376,7 +455,6 @@ gdk_win32_display_supports_selection_notification (GdkDisplay *display)
 }
 
 static HWND _hwnd_next_viewer = NULL;
-static int debug_indent = 0;
 
 /*
  * maybe this should be integrated with the default message loop - or maybe not ;-)
@@ -619,7 +697,6 @@ gdk_win32_display_flush (GdkDisplay * display)
   GdiFlush ();
 }
 
-
 static void
 gdk_win32_display_sync (GdkDisplay * display)
 {
@@ -631,6 +708,9 @@ gdk_win32_display_sync (GdkDisplay * display)
 static void
 gdk_win32_display_dispose (GObject *object)
 {
+  GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (object);
+
+  g_clear_pointer(&display_win32->hwnd, (GDestroyNotify)DestroyWindow);
 }
 
 static void
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 585d958..8cb0861 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -31,6 +31,8 @@ struct _GdkWin32Display
   int cursor_theme_size;
   GHashTable *cursor_cache;
 
+  HWND hwnd;
+
   /* WGL/OpenGL Items */
   guint have_wgl : 1;
   guint gl_version;
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 0390a1e..2ce139f 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1611,14 +1611,6 @@ sync_timer_proc (HWND     hwnd,
   KillTimer (hwnd, sync_timer);
 }
 
-static void
-handle_display_change (void)
-{
-  _gdk_monitor_init ();
-  _gdk_root_window_size_init ();
-  g_signal_emit_by_name (_gdk_screen, "size_changed");
-}
-
 static gboolean
 handle_nchittest (HWND hwnd,
                   GdkWindow *window,
@@ -3202,10 +3194,6 @@ gdk_event_translate (MSG  *msg,
       return_val = TRUE;
       break;
 
-    case WM_DISPLAYCHANGE:
-      handle_display_change ();
-      break;
-
     case WM_DWMCOMPOSITIONCHANGED:
       _gdk_win32_window_enable_transparency (window);
       break;


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