[gtk+] Fix problems with DND on some X servers



commit 266866e82c1460c268435cf8a6faf466b65727e8
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jan 3 10:51:13 2012 -0500

    Fix problems with DND on some X servers
    
    When the X server does not support the shape extension (as some
    vnc implementations seem to), our DND code was always seeing
    an empty input shape, so drops always missed their target.
    
    http://bugzilla.gnome.org/show_bug.cgi?id=620240

 gdk/x11/gdkdnd-x11.c    |   13 +++++++++----
 gdk/x11/gdkwindow-x11.c |   23 +++++++++++++++--------
 2 files changed, 24 insertions(+), 12 deletions(-)
---
diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c
index 80467fa..62e351c 100644
--- a/gdk/x11/gdkdnd-x11.c
+++ b/gdk/x11/gdkdnd-x11.c
@@ -662,11 +662,16 @@ is_pointer_within_shape (GdkDisplay    *display,
       GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
       cairo_region_t *input_shape;
 
-      child->shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay,
-                                                 child->xid, ShapeBounding);
+      child->shape = NULL;
+      if (gdk_display_supports_shapes (display))
+        child->shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay,
+                                                   child->xid, ShapeBounding);
 #ifdef ShapeInput
-      input_shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay,
-                                                child->xid, ShapeInput);
+      input_shape = NULL;
+      if (gdk_display_supports_input_shapes (display))
+        input_shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay,
+                                                  child->xid, ShapeInput);
+
       if (child->shape && input_shape)
         {
           cairo_region_intersect (child->shape, input_shape);
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 6613801..7773fd7 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -3890,17 +3890,24 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay,
   shape = NULL;
   rn = 0;
 
-  xrl = XShapeGetRectangles (xdisplay,
-			     window,
-			     shape_type, &rn, &ord);
+  /* Note that XShapeGetRectangles returns NULL in two situations:
+   * - the server doesn't support the SHAPE extension
+   * - the shape is empty
+   *
+   * Since we can't discriminate these here, we always return
+   * an empty shape. It is the callers responsibility to check
+   * whether the server supports the SHAPE extensions beforehand.
+   */
+  xrl = XShapeGetRectangles (xdisplay, window, shape_type, &rn, &ord);
 
-  if (xrl == NULL || rn == 0)
+  if (rn == 0)
     return cairo_region_create (); /* Empty */
 
   if (ord != YXBanded)
     {
       /* This really shouldn't happen with any xserver, as they
-	 generally convert regions to YXBanded internally */
+       * generally convert regions to YXBanded internally
+       */
       g_warning ("non YXBanded shape masks not supported");
       XFree (xrl);
       return NULL;
@@ -3915,10 +3922,10 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay,
       rl[i].height = xrl[i].height;
     }
   XFree (xrl);
-  
+
   shape = cairo_region_create_rectangles (rl, rn);
   g_free (rl);
-  
+
   return shape;
 }
 
@@ -3940,7 +3947,7 @@ gdk_x11_window_get_input_shape (GdkWindow *window)
 {
 #if defined(ShapeInput)
   if (!GDK_WINDOW_DESTROYED (window) &&
-      gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
+      gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
     return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
                                        GDK_WINDOW_XID (window),
                                        ShapeInput);



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