]> Pileus Git - ~andy/gtk/commitdiff
Another attempt at getting Xrandr screen size changes right. Actually
authorMatthias Clasen <matthiasc@src.gnome.org>
Tue, 24 Feb 2009 05:09:13 +0000 (05:09 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 24 Feb 2009 05:09:13 +0000 (05:09 +0000)
        * gdk/x11/gdkevents-x11.c:
        * gdk/x11/gdkscreen-x11.[hc]: Another attempt at getting Xrandr
        screen size changes right. Actually handle XRRScreenChangeNotify
        events, and ignore root ConfigureNotify events if we are using
        Xrandr. Only emit size-changed signals if the screen size changed,
        and only emit monitor-changed signals if the monitors changed.

svn path=/trunk/; revision=22398

ChangeLog
gdk/x11/gdkevents-x11.c
gdk/x11/gdkscreen-x11.c
gdk/x11/gdkscreen-x11.h

index d0510fc101b8e136ee2a3cfaa6e01b170db97695..7269be5710de141b6a49fb0a52937c952fa61f09 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-02-24  Matthias Clasen <mclasen@redhat.com>
+
+       * gdk/x11/gdkevents-x11.c:
+       * gdk/x11/gdkscreen-x11.[hc]: Another attempt at getting Xrandr
+       screen size changes right. Actually handle XRRScreenChangeNotify
+       events, and ignore root ConfigureNotify events if we are using
+       Xrandr. Only emit size-changed signals if the screen size changed,
+       and only emit monitor-changed signals if the monitors changed.
+
 2009-02-23  Matthias Clasen <mclasen@redhat.com>
 
        Bug 565199 – Ellipsize text in Places list
index a335feefb6e0ad3cf14c52dffde8f3e8fb0ce44a..096c17005c141cf26122b85dc9b1d0f096e2e5c6 100644 (file)
@@ -2107,10 +2107,11 @@ gdk_event_translate (GdkDisplay *display,
       else
 #endif
 #ifdef HAVE_RANDR
-      if (xevent->type - display_x11->xrandr_event_base == RRNotify)
+      if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify ||
+          xevent->type - display_x11->xrandr_event_base == RRNotify)
        {
           if (screen)
-            _gdk_x11_screen_process_monitors_change (screen);
+            _gdk_x11_screen_size_changed (screen, xevent);
        }
       else
 #endif
index e6478006bfefff9c6b7c4fd6a342e49efd2319fe..0bcb2bcdab45b06b63737d636483a96dec4c31c2 100644 (file)
@@ -1,4 +1,4 @@
-/*
+ /*
  * gdkscreen-x11.c
  * 
  * Copyright 2001 Sun Microsystems Inc. 
@@ -857,33 +857,78 @@ init_xfree_xinerama (GdkScreen *screen)
 }
 
 static void
-deinit_multihead (GdkScreen *screen)
+free_monitors (GdkX11Monitor *monitors,
+               gint           n_monitors)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
   int i;
 
-  for (i = 0; i < screen_x11->n_monitors; ++i)
+  for (i = 0; i < n_monitors; ++i)
     {
-      GdkX11Monitor *monitor = get_monitor (screen, i);
-
-      g_free (monitor->output_name);
-      g_free (monitor->manufacturer);
+      g_free (monitors[i].output_name);
+      g_free (monitors[i].manufacturer);
     }
 
-  g_free (screen_x11->monitors);
+  g_free (monitors);
+}
+
+static void
+deinit_multihead (GdkScreen *screen)
+{
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
+  free_monitors (screen_x11->monitors, screen_x11->n_monitors);
 
   screen_x11->n_monitors = 0;
   screen_x11->monitors = NULL;
 }
 
+static gboolean
+compare_monitor (GdkX11Monitor *m1,
+                 GdkX11Monitor *m2)
+{
+  if (m1->geometry.x != m2->geometry.x ||
+      m1->geometry.y != m2->geometry.y ||
+      m1->geometry.width != m2->geometry.width ||
+      m1->geometry.height != m2->geometry.height)
+    return FALSE;
+
+  if (m1->width_mm != m2->width_mm ||
+      m1->height_mm != m2->height_mm)
+    return FALSE;
+
+  if (g_strcmp0 (m1->output_name, m2->output_name) != 0)
+    return FALSE;
+
+  if (g_strcmp0 (m1->manufacturer, m2->manufacturer) != 0)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+compare_monitors (GdkX11Monitor *monitors1, gint n_monitors1,
+                  GdkX11Monitor *monitors2, gint n_monitors2)
+{
+  gint i;
+
+  if (n_monitors1 != n_monitors2)
+    return FALSE;
+
+  for (i = 0; i < n_monitors1; i++)
+    {
+      if (!compare_monitor (monitors1 + i, monitors2 + i))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
 static void
 init_multihead (GdkScreen *screen)
 {
   GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
   int opcode, firstevent, firsterror;
 
-  deinit_multihead (screen);
-  
   /* There are four different implementations of multihead support: 
    *
    *  1. Fake Xinerama for debugging purposes
@@ -995,18 +1040,49 @@ init_randr_support (GdkScreen * screen)
 #endif
 }
 
+static void
+process_monitors_change (GdkScreen *screen)
+{
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+  gint          n_monitors;
+  GdkX11Monitor        *monitors;
+  gboolean changed;
+
+  n_monitors = screen_x11->n_monitors;
+  monitors = screen_x11->monitors;
+
+  screen_x11->n_monitors = 0;
+  screen_x11->monitors = NULL;
+
+  init_multihead (screen);
+
+  changed = !compare_monitors (monitors, n_monitors,
+                               screen_x11->monitors, screen_x11->n_monitors);
+
+  free_monitors (monitors, n_monitors);
+
+  if (changed)
+    g_signal_emit_by_name (screen, "monitors-changed");
+}
+
 void
 _gdk_x11_screen_size_changed (GdkScreen *screen,
                              XEvent    *event)
 {
   gint width, height;
+  GdkDisplayX11 *display_x11;
+  gboolean monitors_changed;
 
   width = gdk_screen_get_width (screen);
   height = gdk_screen_get_height (screen);
 
 #ifdef HAVE_RANDR
-  if (!XRRUpdateConfiguration (event))
+  display_x11 = GDK_DISPLAY_X11 (gdk_screen_get_display (screen));
+
+  if (display_x11->have_randr13 && event->type == ConfigureNotify)
     return;
+
+  XRRUpdateConfiguration (event);
 #else
   if (event->type == ConfigureNotify)
     {
@@ -1020,21 +1096,11 @@ _gdk_x11_screen_size_changed (GdkScreen *screen,
     return;
 #endif
 
-  if (width == gdk_screen_get_width (screen) && 
-      height == gdk_screen_get_height (screen))
-    return;
-
-  _gdk_x11_screen_process_monitors_change (screen);
-
-  g_signal_emit_by_name (screen, "size-changed");
-}
-
-void
-_gdk_x11_screen_process_monitors_change (GdkScreen *screen)
-{
-  init_multihead (screen);
+  process_monitors_change (screen);
 
-  g_signal_emit_by_name (screen, "monitors-changed");
+  if (width != gdk_screen_get_width (screen) ||
+      height != gdk_screen_get_height (screen))
+    g_signal_emit_by_name (screen, "size-changed");
 }
 
 void
@@ -1061,7 +1127,7 @@ _gdk_x11_screen_process_owner_change (GdkScreen *screen,
        {
          screen_x11->is_composited = composited;
 
-         g_signal_emit_by_name (screen, "composited_changed");
+         g_signal_emit_by_name (screen, "composited-changed");
        }
     }
 #endif
index 4ccc795f5684eac789c7426a00e246ff5925a3a8..8a743f5d849bba9642f7964719b2196f3bd57051 100644 (file)
@@ -125,9 +125,8 @@ GdkScreen * _gdk_x11_screen_new      (GdkDisplay *display,
 void _gdk_x11_screen_window_manager_changed (GdkScreen *screen);
 void _gdk_x11_screen_size_changed           (GdkScreen *screen,
                                             XEvent    *event);
-void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
-                                          XEvent    *event);
-void _gdk_x11_screen_process_monitors_change (GdkScreen *screen);
+void _gdk_x11_screen_process_owner_change   (GdkScreen *screen,
+                                            XEvent    *event);
 
 G_END_DECLS