[gtk+/gtk-3-8] x11: keep track of the screen pixel size by calculating the bounding box of monitors



commit a20e7634b617aae051e522ec84a0dda2a1f09095
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Nov 22 18:33:02 2013 +0100

    x11: keep track of the screen pixel size by calculating the bounding box of monitors
    
    This is so we always have the latest information given by XRandR (or other), and not
    rely on Core protocol information that might not have been updated yet.
    
    This is specially visible when a monitor is connected (less frequent) or disconnected
    (much more frequent), callbacks on GdkScreen::monitors-changed that call
    gdk_screen_get_width/height() could get the screen size previous to the monitor
    rearrangement.
    
    So in order to fix this, keep track of the latest monitors information, and calculate
    the bounding box in order to know the screen size.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=715029

 gdk/x11/gdkscreen-x11.c |   41 ++++++++++++++++++++++++++++++++++-------
 gdk/x11/gdkscreen-x11.h |    3 +++
 2 files changed, 37 insertions(+), 7 deletions(-)
---
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
index 8d3a490..bf4811b 100644
--- a/gdk/x11/gdkscreen-x11.c
+++ b/gdk/x11/gdkscreen-x11.c
@@ -96,13 +96,13 @@ gdk_x11_screen_get_display (GdkScreen *screen)
 static gint
 gdk_x11_screen_get_width (GdkScreen *screen)
 {
-  return WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen);
+  return GDK_X11_SCREEN (screen)->width;
 }
 
 static gint
 gdk_x11_screen_get_height (GdkScreen *screen)
 {
-  return HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen);
+  return GDK_X11_SCREEN (screen)->height;
 }
 
 static gint
@@ -895,8 +895,8 @@ _gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
                                    gint      *right)
 {
   GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
-  gint          top_most_pos = HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen);
-  gint          left_most_pos = WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen);
+  gint          top_most_pos = x11_screen->height;
+  gint          left_most_pos = x11_screen->width;
   gint          bottom_most_pos = 0;
   gint          right_most_pos = 0;
   gint          monitor_num;
@@ -1025,6 +1025,30 @@ init_multihead (GdkScreen *screen)
                         HeightOfScreen (x11_screen->xscreen));
 }
 
+static void
+update_bounding_box (GdkScreen *screen)
+{
+  GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+  gint i, x1, y1, x2, y2;
+
+  x1 = y1 = G_MAXINT;
+  x2 = y2 = G_MININT;
+
+  for (i = 0; i < x11_screen->n_monitors; i++)
+    {
+      GdkX11Monitor *monitor;
+
+      monitor = &x11_screen->monitors[i];
+      x1 = MIN (x1, monitor->geometry.x);
+      y1 = MIN (y1, monitor->geometry.y);
+      x2 = MAX (x2, monitor->geometry.x + monitor->geometry.width);
+      y2 = MAX (y2, monitor->geometry.y + monitor->geometry.height);
+    }
+
+  x11_screen->width = x2 - x1;
+  x11_screen->height = y2 - y1;
+}
+
 GdkScreen *
 _gdk_x11_screen_new (GdkDisplay *display,
                     gint        screen_number) 
@@ -1050,7 +1074,8 @@ _gdk_x11_screen_new (GdkDisplay *display,
   
   _gdk_x11_screen_init_visuals (screen);
   _gdk_x11_screen_init_root_window (screen);
-  
+  update_bounding_box (screen);
+
   return screen;
 }
 
@@ -1122,11 +1147,13 @@ process_monitors_change (GdkScreen *screen)
                       x11_screen->monitors, x11_screen->n_monitors) ||
     x11_screen->primary_monitor != primary_monitor;
 
-
   free_monitors (monitors, n_monitors);
 
   if (changed)
-    g_signal_emit_by_name (screen, "monitors-changed");
+    {
+      update_bounding_box (screen);
+      g_signal_emit_by_name (screen, "monitors-changed");
+    }
 }
 
 void
diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h
index 5c88a1a..fd05a88 100644
--- a/gdk/x11/gdkscreen-x11.h
+++ b/gdk/x11/gdkscreen-x11.h
@@ -47,6 +47,9 @@ struct _GdkX11Screen
   GdkX11Monitor *monitors;
   gint primary_monitor;
 
+  gint width;
+  gint height;
+
   /* Xft resources for the display, used for default values for
    * the Xft/ XSETTINGS
    */


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