Deal with formal release of upstream library
[pspp] / lib / gtk-contrib / gtkxpaned.c
index e5382f3c3e6710489260aecd28bfaebdc280835c..06f642a24e02a59f2e961a5f7ec3125a6e75717b 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 
+ **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
  **      10        20        30        40        50        60        70        80
  **
  **  library for GtkXPaned-widget, a 2x2 grid-like variation of GtkPaned of gtk+
@@ -54,7 +54,9 @@ enum ChildProperties
   {
     CHILD_PROP_0,
     CHILD_PROP_RESIZE,
-    CHILD_PROP_SHRINK
+    CHILD_PROP_SHRINK,
+    CHILD_PROP_LEFT_ATTACH,
+    CHILD_PROP_TOP_ATTACH
   };
 
 enum WidgetSignals
@@ -72,19 +74,66 @@ static void gtk_xpaned_class_init (GtkXPanedClass * klass);
 
 static void gtk_xpaned_init (GtkXPaned * xpaned);
 
-static void gtk_xpaned_size_request (GtkWidget * widget,
-                                     GtkRequisition * requisition);
-
 static void
 gtk_xpaned_get_preferred_width (GtkWidget *widget,
-                               gint      *minimal_width,
-                               gint      *natural_width)
+                                gint      *minimal_width,
+                                gint      *natural_width)
 {
-  GtkRequisition requisition;
+  GtkXPaned *xpaned = GTK_XPANED (widget);
+  gint tl[2], tr[2], bl[2], br[2];
+  gint overhead;
+  gint w[2];
+  int i;
+
+  if (xpaned->top_left_child
+      && gtk_widget_get_visible (xpaned->top_left_child))
+    gtk_widget_get_preferred_width (xpaned->top_left_child, &tl[0], &tl[1]);
+  else
+    tl[0] = tl[1] = 0;
+
+  if (xpaned->top_right_child
+      && gtk_widget_get_visible (xpaned->top_right_child))
+    gtk_widget_get_preferred_width (xpaned->top_right_child, &tr[0], &tr[1]);
+  else
+    tr[0] = tr[1] = 0;
+
+  if (xpaned->bottom_left_child
+      && gtk_widget_get_visible (xpaned->bottom_left_child))
+    gtk_widget_get_preferred_width (xpaned->bottom_left_child, &bl[0], &bl[1]);
+  else
+    bl[0] = bl[1] = 0;
+
+  if (xpaned->bottom_right_child
+      && gtk_widget_get_visible (xpaned->bottom_right_child))
+    gtk_widget_get_preferred_width (xpaned->bottom_right_child,
+                                    &br[0], &br[1]);
+  else
+    br[0] = br[1] = 0;
+
+  /* add 2 times the set border-width to the GtkXPaneds requisition */
+  overhead = gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
+
+  /* also add the handle "thickness" to GtkXPaned's width requisition */
+  if (xpaned->top_left_child
+      && gtk_widget_get_visible (xpaned->top_left_child)
+      && xpaned->top_right_child
+      && gtk_widget_get_visible (xpaned->top_right_child)
+      && xpaned->bottom_left_child
+      && gtk_widget_get_visible (xpaned->bottom_left_child)
+      && xpaned->bottom_right_child
+      && gtk_widget_get_visible (xpaned->bottom_right_child))
+    {
+      gint handle_size;
+
+      gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+      overhead += handle_size;
+    }
 
-  gtk_xpaned_size_request (widget, &requisition);
+  for (i = 0; i < 2; i++)
+    w[i] = (br[i] ? br[i] : MAX (tl[i] + tr[i], bl[i])) + overhead;
 
-  *minimal_width = *natural_width = requisition.width;
+  *minimal_width = w[0];
+  *natural_width = w[1];
 }
 
 static void
@@ -92,11 +141,62 @@ gtk_xpaned_get_preferred_height (GtkWidget *widget,
                                 gint      *minimal_height,
                                 gint      *natural_height)
 {
-  GtkRequisition requisition;
+  GtkXPaned *xpaned = GTK_XPANED (widget);
+  gint tl[2], tr[2], bl[2], br[2];
+  gint overhead;
+  gint h[2];
+  int i;
 
-  gtk_xpaned_size_request (widget, &requisition);
+  if (xpaned->top_left_child
+      && gtk_widget_get_visible (xpaned->top_left_child))
+    gtk_widget_get_preferred_height (xpaned->top_left_child, &tl[0], &tl[1]);
+  else
+    tl[0] = tl[1] = 0;
 
-  *minimal_height = *natural_height = requisition.height;
+  if (xpaned->top_right_child
+      && gtk_widget_get_visible (xpaned->top_right_child))
+    gtk_widget_get_preferred_height (xpaned->top_right_child, &tr[0], &tr[1]);
+  else
+    tr[0] = tr[1] = 0;
+
+  if (xpaned->bottom_left_child
+      && gtk_widget_get_visible (xpaned->bottom_left_child))
+    gtk_widget_get_preferred_height (xpaned->bottom_left_child,
+                                     &bl[0], &bl[1]);
+  else
+    bl[0] = bl[1] = 0;
+
+  if (xpaned->bottom_right_child
+      && gtk_widget_get_visible (xpaned->bottom_right_child))
+    gtk_widget_get_preferred_height (xpaned->bottom_right_child,
+                                    &br[0], &br[1]);
+  else
+    br[0] = br[1] = 0;
+
+  /* add 2 times the set border-width to the GtkXPaneds requisition */
+  overhead = gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
+
+  /* also add the handle "thickness" to GtkXPaned's height-requisition */
+  if (xpaned->top_left_child
+      && gtk_widget_get_visible (xpaned->top_left_child)
+      && xpaned->top_right_child
+      && gtk_widget_get_visible (xpaned->top_right_child)
+      && xpaned->bottom_left_child
+      && gtk_widget_get_visible (xpaned->bottom_left_child)
+      && xpaned->bottom_right_child
+      && gtk_widget_get_visible (xpaned->bottom_right_child))
+    {
+      gint handle_size;
+
+      gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
+      overhead += handle_size;
+    }
+
+  for (i = 0; i < 2; i++)
+    h[i] = (br[i] ? br[i] : bl[i] + MAX (tl[i], tr[i])) + overhead;
+
+  *minimal_height = h[0];
+  *natural_height = h[1];
 }
 
 static void gtk_xpaned_size_allocate (GtkWidget * widget,
@@ -428,13 +528,36 @@ gtk_xpaned_class_init (GtkXPanedClass * class)
                                                      G_MAXINT,
                                                      G_PARAM_READABLE));
 
+
+  gtk_container_class_install_child_property (container_class,
+                                              CHILD_PROP_LEFT_ATTACH,
+                                              g_param_spec_int ("left-attach",
+                                                               "Left Attach",
+                                                               "The column number to which the  left side of the widget should be attached",
+                                                               0, 1,
+                                                               0,
+                                                               G_PARAM_READWRITE));
+
+
+
+  gtk_container_class_install_child_property (container_class,
+                                              CHILD_PROP_TOP_ATTACH,
+                                              g_param_spec_int ("top-attach",
+                                                               "Top Attach",
+                                                               "The row number to which the  top side of the widget should be attached",
+                                                               0, 1,
+                                                               0,
+                                                               G_PARAM_READWRITE));
+
+
+  
   /**
    * GtkPaned:resize:
    *
-   * The "resize" child property determines whether the child expands and 
+   * The "resize" child property determines whether the child expands and
    * shrinks along with the paned widget.
-   * 
-   * Since: 2.4 
+   *
+   * Since: 2.4
    */
   gtk_container_class_install_child_property (container_class,
                                               CHILD_PROP_RESIZE,
@@ -447,10 +570,10 @@ gtk_xpaned_class_init (GtkXPanedClass * class)
   /**
    * GtkPaned:shrink:
    *
-   * The "shrink" child property determines whether the child can be made 
+   * The "shrink" child property determines whether the child can be made
    * smaller than its requisition.
-   * 
-   * Since: 2.4 
+   *
+   * Since: 2.4
    */
   gtk_container_class_install_child_property (container_class,
                                               CHILD_PROP_SHRINK,
@@ -690,75 +813,6 @@ gtk_xpaned_init (GtkXPaned * xpaned)
   xpaned->drag_pos.y = -1;
 }
 
-static void
-gtk_xpaned_size_request (GtkWidget * widget, GtkRequisition * requisition)
-{
-  GtkXPaned *xpaned = GTK_XPANED (widget);
-  GtkRequisition child_requisition;
-
-  requisition->width = 0;
-  requisition->height = 0;
-
-  if (xpaned->top_left_child
-      && gtk_widget_get_visible (xpaned->top_left_child))
-    {
-      gtk_widget_size_request (xpaned->top_left_child, &child_requisition);
-
-      requisition->width = child_requisition.width;
-      requisition->height = child_requisition.height;
-    }
-
-  if (xpaned->top_right_child
-      && gtk_widget_get_visible (xpaned->top_right_child))
-    {
-      gtk_widget_size_request (xpaned->top_right_child, &child_requisition);
-
-      requisition->width += child_requisition.width;
-      requisition->height =
-        MAX (requisition->height, child_requisition.height);
-    }
-
-  if (xpaned->bottom_left_child
-      && gtk_widget_get_visible (xpaned->bottom_left_child))
-    {
-      gtk_widget_size_request (xpaned->bottom_left_child, &child_requisition);
-
-      requisition->width = MAX (requisition->width, child_requisition.width);
-      requisition->height += child_requisition.height;
-    }
-
-  if (xpaned->bottom_right_child
-      && gtk_widget_get_visible (xpaned->bottom_right_child))
-    {
-      gtk_widget_size_request (xpaned->bottom_right_child,
-                               &child_requisition);
-
-      requisition->width = child_requisition.width;
-      requisition->height = child_requisition.height;
-    }
-
-  /* add 2 times the set border-width to the GtkXPaneds requisition */
-  requisition->width += gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
-  requisition->height += gtk_container_get_border_width (GTK_CONTAINER (xpaned)) * 2;
-
-  /* also add the handle "thickness" to GtkXPaneds width- and height-requisitions */
-  if (xpaned->top_left_child
-      && gtk_widget_get_visible (xpaned->top_left_child)
-      && xpaned->top_right_child
-      && gtk_widget_get_visible (xpaned->top_right_child)
-      && xpaned->bottom_left_child
-      && gtk_widget_get_visible (xpaned->bottom_left_child)
-      && xpaned->bottom_right_child
-      && gtk_widget_get_visible (xpaned->bottom_right_child))
-    {
-      gint handle_size;
-
-      gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
-      requisition->width += handle_size;
-      requisition->height += handle_size;
-    }
-}
-
 void
 gtk_xpaned_compute_position (GtkXPaned * xpaned,
                              const GtkAllocation * allocation,
@@ -783,6 +837,12 @@ gtk_xpaned_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
   GtkRequisition bottom_right_child_requisition;
   gint handle_size;
 
+  g_print ("Allocate %p %p %p %p\n",
+          xpaned->top_left_child,
+          xpaned->top_right_child,
+          xpaned->bottom_left_child,
+          xpaned->bottom_right_child);
+  
   /* determine size of handle(s) */
   gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
 
@@ -798,14 +858,14 @@ gtk_xpaned_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
       && gtk_widget_get_visible (xpaned->bottom_right_child))
     {
       /* what sizes do the children want to be at least at */
-      gtk_widget_get_child_requisition (xpaned->top_left_child,
-                                        &top_left_child_requisition);
-      gtk_widget_get_child_requisition (xpaned->top_right_child,
-                                        &top_right_child_requisition);
-      gtk_widget_get_child_requisition (xpaned->bottom_left_child,
-                                        &bottom_left_child_requisition);
-      gtk_widget_get_child_requisition (xpaned->bottom_right_child,
-                                        &bottom_right_child_requisition);
+      gtk_widget_get_preferred_size (xpaned->top_left_child,
+                                     &top_left_child_requisition, NULL);
+      gtk_widget_get_preferred_size (xpaned->top_right_child,
+                                     &top_right_child_requisition, NULL);
+      gtk_widget_get_preferred_size (xpaned->bottom_left_child,
+                                     &bottom_left_child_requisition, NULL);
+      gtk_widget_get_preferred_size (xpaned->bottom_right_child,
+                                     &bottom_right_child_requisition, NULL);
 
       /* determine the total requisition-sum of all requisitions of borders,
        * handles, children etc. */
@@ -1017,73 +1077,109 @@ gtk_xpaned_set_child_property (GtkContainer * container,
                                const GValue * value, GParamSpec * pspec)
 {
   GtkXPaned *xpaned = GTK_XPANED (container);
-  gboolean old_value = FALSE;
-  gboolean new_value = FALSE;
 
   g_assert (child == xpaned->top_left_child ||
             child == xpaned->top_right_child ||
             child == xpaned->bottom_left_child ||
             child == xpaned->bottom_right_child);
 
-  new_value = g_value_get_boolean (value);
-
+  gint attach = g_value_get_int (value);
   switch (property_id)
     {
+    case CHILD_PROP_LEFT_ATTACH:
+      g_object_ref (child);
+      gtk_widget_unparent (child);
+      if (attach == 0)
+      {
+       if (child == xpaned->top_right_child)
+         xpaned->top_left_child = child;
+       else if (child == xpaned->bottom_right_child)
+         xpaned->bottom_left_child = child;
+      }
+      else
+      {
+       if (child == xpaned->top_left_child)
+         xpaned->top_right_child = child;
+       else if (child == xpaned->bottom_left_child)
+         xpaned->bottom_right_child = child;
+      }
+      gtk_widget_set_parent (child, GTK_WIDGET (xpaned));
+      g_object_unref (child);
+      break;
+    case CHILD_PROP_TOP_ATTACH:
+      g_object_ref (child);
+      gtk_widget_unparent (child);
+      if (attach == 0)
+       {
+         if (child == xpaned->bottom_right_child)
+           xpaned->top_right_child = child;
+         else if (child == xpaned->bottom_left_child)
+           xpaned->top_left_child = child;
+       }
+      else
+       {
+         if (child == xpaned->top_left_child)
+           xpaned->bottom_left_child = child;
+         else if (child == xpaned->top_right_child)
+           xpaned->bottom_right_child = child;
+       }
+      gtk_widget_set_parent (child, GTK_WIDGET (xpaned));
+      g_object_unref (child);
+      break;
     case CHILD_PROP_RESIZE:
-      if (child == xpaned->top_left_child)
-        {
-          old_value = xpaned->top_left_child_resize;
-          xpaned->top_left_child_resize = new_value;
-        }
-      else if (child == xpaned->top_right_child)
-        {
-          old_value = xpaned->top_right_child_resize;
-          xpaned->top_right_child_resize = new_value;
-        }
-      else if (child == xpaned->bottom_left_child)
-        {
-          old_value = xpaned->bottom_left_child_resize;
-          xpaned->bottom_left_child_resize = new_value;
-        }
-      else if (child == xpaned->bottom_right_child)
-        {
-          old_value = xpaned->bottom_right_child_resize;
-          xpaned->bottom_right_child_resize = new_value;
-        }
+      {
+       gboolean  new_value = TRUE;
+       
+       if (child == xpaned->top_left_child)
+         {
+           xpaned->top_left_child_resize = new_value;
+         }
+       else if (child == xpaned->top_right_child)
+         {
+           xpaned->top_right_child_resize = new_value;
+         }
+       else if (child == xpaned->bottom_left_child)
+         {
+           xpaned->bottom_left_child_resize = new_value;
+         }
+       else if (child == xpaned->bottom_right_child)
+         {
+           xpaned->bottom_right_child_resize = new_value;
+         }
+      }
       break;
-
+      
     case CHILD_PROP_SHRINK:
-      if (child == xpaned->top_left_child)
-        {
-          old_value = xpaned->top_left_child_shrink;
-          xpaned->top_left_child_shrink = new_value;
-        }
-      else if (child == xpaned->top_right_child)
-        {
-          old_value = xpaned->top_right_child_shrink;
-          xpaned->top_right_child_shrink = new_value;
-        }
-      else if (child == xpaned->bottom_left_child)
-        {
-          old_value = xpaned->bottom_left_child_shrink;
-          xpaned->bottom_left_child_shrink = new_value;
-        }
-      else if (child == xpaned->bottom_right_child)
-        {
-          old_value = xpaned->bottom_right_child_shrink;
-          xpaned->bottom_right_child_shrink = new_value;
-        }
+      {
+       gboolean  new_value = FALSE;
+       
+       if (child == xpaned->top_left_child)
+         {
+           xpaned->top_left_child_shrink = new_value;
+         }
+       else if (child == xpaned->top_right_child)
+         {
+           xpaned->top_right_child_shrink = new_value;
+         }
+       else if (child == xpaned->bottom_left_child)
+         {
+           xpaned->bottom_left_child_shrink = new_value;
+         }
+       else if (child == xpaned->bottom_right_child)
+         {
+           xpaned->bottom_right_child_shrink = new_value;
+         }
+      }
       break;
 
     default:
       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container,
                                                     property_id, pspec);
-      old_value = -1;           /* quiet gcc */
       break;
     }
 
-  if (old_value != new_value)
-    gtk_widget_queue_resize (GTK_WIDGET (container));
+  gtk_widget_queue_resize (GTK_WIDGET (container));
+  gtk_widget_queue_draw (GTK_WIDGET (container));
 }
 
 static void
@@ -1101,6 +1197,26 @@ gtk_xpaned_get_child_property (GtkContainer * container,
 
   switch (property_id)
     {
+    case CHILD_PROP_TOP_ATTACH:
+      if (child == xpaned->top_left_child)
+       g_value_set_int (value, 0);
+      if (child == xpaned->top_right_child)
+       g_value_set_int (value, 0);
+      if (child == xpaned->bottom_left_child)
+       g_value_set_int (value, 1);
+      if (child == xpaned->bottom_right_child)
+       g_value_set_int (value, 1);
+      break;
+    case CHILD_PROP_LEFT_ATTACH:
+      if (child == xpaned->top_left_child)
+       g_value_set_int (value, 0);
+      if (child == xpaned->bottom_left_child)
+       g_value_set_int (value, 0);
+      if (child == xpaned->top_right_child)
+       g_value_set_int (value, 1);
+      if (child == xpaned->bottom_right_child)
+       g_value_set_int (value, 1);
+      break;
     case CHILD_PROP_RESIZE:
       if (child == xpaned->top_left_child)
         g_value_set_boolean (value, xpaned->top_left_child_resize);
@@ -1282,18 +1398,11 @@ gtk_xpaned_realize (GtkWidget * widget)
   gdk_window_set_user_data (xpaned->handle_south, xpaned);
   gdk_window_set_user_data (xpaned->handle_middle, xpaned);
 
-  gdk_cursor_unref (attributes_east.cursor);
-  gdk_cursor_unref (attributes_west.cursor);
-  gdk_cursor_unref (attributes_north.cursor);
-  gdk_cursor_unref (attributes_south.cursor);
-  gdk_cursor_unref (attributes_middle.cursor);
-
-  {
-  GtkStyle *style = gtk_widget_get_style (widget);
-  style = gtk_style_attach (style, gtk_widget_get_window (widget));
-  gtk_widget_set_style (widget, style);
-  }
-  
+  g_object_unref (attributes_east.cursor);
+  g_object_unref (attributes_west.cursor);
+  g_object_unref (attributes_north.cursor);
+  g_object_unref (attributes_south.cursor);
+  g_object_unref (attributes_middle.cursor);
 
   if (xpaned->top_left_child
       && gtk_widget_get_visible (xpaned->top_left_child)
@@ -1413,44 +1522,18 @@ gtk_xpaned_draw (GtkWidget * widget, cairo_t *cr)
       && xpaned->bottom_right_child
       && gtk_widget_get_visible (xpaned->bottom_right_child))
     {
-      GtkStateType state;
+      GtkStyleContext *context;
 
-      if (gtk_widget_is_focus (widget))
-        state = GTK_STATE_SELECTED;
-      else if (xpaned->handle_prelit)
-        state = GTK_STATE_PRELIGHT;
-      else
-        state = gtk_widget_get_state (widget);
-
-      gtk_paint_handle (gtk_widget_get_style (widget),
-                        cr,
-                        state,
-                        GTK_SHADOW_NONE,
-                        widget,
-                        "paned",
-                        xpaned->handle_pos_east.x - handle_size - 256 / 2,
-                        xpaned->handle_pos_west.y + 1,
-                        256 + handle_size, handle_size - 2,
-                        /*xpaned->handle_pos_west.x,
-                          xpaned->handle_pos_west.y + 1,
-                          xpaned->handle_pos_west.width + handle_size + xpaned->handle_pos_east.width,
-                          handle_size - 2, */
-                        GTK_ORIENTATION_HORIZONTAL);
-
-      gtk_paint_handle (gtk_widget_get_style (widget),
-                        cr,
-                        state,
-                        GTK_SHADOW_NONE,
-                        widget,
-                        "paned",
-                        xpaned->handle_pos_north.x + 1,
-                        xpaned->handle_pos_south.y - handle_size - 256 / 2,
-                        handle_size - 2, 256 + handle_size,
-                        /*xpaned->handle_pos_north.x + 1,
-                          xpaned->handle_pos_north.y,
-                          handle_size - 2,
-                          xpaned->handle_pos_north.height + handle_size + xpaned->handle_pos_south.height, */
-                        GTK_ORIENTATION_VERTICAL);
+      context = gtk_widget_get_style_context (widget);
+      gtk_render_handle (context, cr,
+                         xpaned->handle_pos_east.x - handle_size - 256 / 2,
+                         xpaned->handle_pos_west.y + 1,
+                         256 + handle_size, handle_size - 2);
+
+      gtk_render_handle (context, cr,
+                         xpaned->handle_pos_north.x + 1,
+                         xpaned->handle_pos_south.y - handle_size - 256 / 2,
+                         handle_size - 2, 256 + handle_size);
     }
 
   /* Chain up to draw children */
@@ -1472,12 +1555,23 @@ static void
 update_drag (GtkXPaned * xpaned)
 {
   GdkPoint pos;
+  GtkWidget *widget = GTK_WIDGET (xpaned);
   gint handle_size;
   GtkRequisition size;
   GtkAllocation allocation;
-  gtk_widget_get_allocation (GTK_WIDGET (xpaned), &allocation);
 
-  gtk_widget_get_pointer (GTK_WIDGET (xpaned), &pos.x, &pos.y);
+  gtk_widget_get_allocation (widget, &allocation);
+
+  gdk_window_get_device_position (gtk_widget_get_window (widget),
+                                  gdk_device_manager_get_client_pointer (
+                                    gdk_display_get_device_manager (
+                                      gtk_widget_get_display (widget))),
+                                  &pos.x, &pos.y, NULL);
+  if (!gtk_widget_get_has_window (widget))
+    {
+      pos.x -= allocation.x;
+      pos.y -= allocation.y;
+    }
 
   if (xpaned->in_drag_vert)
     {
@@ -1485,8 +1579,7 @@ update_drag (GtkXPaned * xpaned)
 
       if (is_rtl (xpaned))
         {
-          gtk_widget_style_get (GTK_WIDGET (xpaned),
-                                "handle-size", &handle_size, NULL);
+          gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
 
           size.height = allocation.height - pos.y - handle_size;
         }
@@ -1510,8 +1603,7 @@ update_drag (GtkXPaned * xpaned)
 
       if (is_rtl (xpaned))
         {
-          gtk_widget_style_get (GTK_WIDGET (xpaned),
-                                "handle-size", &handle_size, NULL);
+          gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
 
           size.width = allocation.width - pos.x - handle_size;
         }
@@ -1536,8 +1628,7 @@ update_drag (GtkXPaned * xpaned)
 
       if (is_rtl (xpaned))
         {
-          gtk_widget_style_get (GTK_WIDGET (xpaned),
-                                "handle-size", &handle_size, NULL);
+          gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
 
           size.width = allocation.width - pos.x - handle_size;
           size.height = allocation.height - pos.y - handle_size;
@@ -1672,6 +1763,22 @@ gtk_xpaned_focus (GtkWidget * widget, GtkDirectionType direction)
   return retval;
 }
 
+static void
+gtk_xpaned_button_press_grab (GdkWindow *handle, GdkEventButton *event)
+{
+  /* We need a server grab here, not gtk_grab_add(), since
+   * we don't want to pass events on to the widget's children */
+  gdk_device_grab (event->device, handle,
+                   GDK_OWNERSHIP_NONE,
+                   FALSE,
+                   (GDK_POINTER_MOTION_HINT_MASK
+                    | GDK_BUTTON1_MOTION_MASK
+                    | GDK_BUTTON_RELEASE_MASK
+                    | GDK_ENTER_NOTIFY_MASK
+                    | GDK_LEAVE_NOTIFY_MASK),
+                   NULL, event->time);
+}
+
 static gboolean
 gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
 {
@@ -1693,20 +1800,7 @@ gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
       event->window == xpaned->handle_middle && event->button == 1)
     {
       xpaned->in_drag_vert_and_horiz = TRUE;
-
-      /* We need a server grab here, not gtk_grab_add(), since
-       * we don't want to pass events on to the widget's children */
-      if (gdk_pointer_grab (xpaned->handle_middle,
-                            FALSE,
-                            GDK_POINTER_MOTION_HINT_MASK
-                            | GDK_BUTTON1_MOTION_MASK
-                            | GDK_BUTTON_RELEASE_MASK
-                            | GDK_ENTER_NOTIFY_MASK
-                            | GDK_LEAVE_NOTIFY_MASK,
-                            NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
-        {
-        }
-
+      gtk_xpaned_button_press_grab (xpaned->handle_middle, event);
       xpaned->drag_pos.x = event->x;
       xpaned->drag_pos.y = event->y;
 
@@ -1720,20 +1814,7 @@ gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
            event->window != xpaned->handle_middle && event->button == 1)
     {
       xpaned->in_drag_vert = TRUE;
-
-      /* We need a server grab here, not gtk_grab_add(), since
-       * we don't want to pass events on to the widget's children */
-      if (gdk_pointer_grab (xpaned->handle_east,
-                            FALSE,
-                            GDK_POINTER_MOTION_HINT_MASK
-                            | GDK_BUTTON1_MOTION_MASK
-                            | GDK_BUTTON_RELEASE_MASK
-                            | GDK_ENTER_NOTIFY_MASK
-                            | GDK_LEAVE_NOTIFY_MASK,
-                            NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
-        {
-        }
-
+      gtk_xpaned_button_press_grab (xpaned->handle_east, event);
       xpaned->drag_pos.y = event->y;
 
       return TRUE;
@@ -1746,20 +1827,7 @@ gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
            event->window != xpaned->handle_middle && event->button == 1)
     {
       xpaned->in_drag_vert = TRUE;
-
-      /* We need a server grab here, not gtk_grab_add(), since
-       * we don't want to pass events on to the widget's children */
-      if (gdk_pointer_grab (xpaned->handle_west,
-                            FALSE,
-                            GDK_POINTER_MOTION_HINT_MASK
-                            | GDK_BUTTON1_MOTION_MASK
-                            | GDK_BUTTON_RELEASE_MASK
-                            | GDK_ENTER_NOTIFY_MASK
-                            | GDK_LEAVE_NOTIFY_MASK,
-                            NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
-        {
-        }
-
+      gtk_xpaned_button_press_grab (xpaned->handle_west, event);
       xpaned->drag_pos.y = event->y;
 
       return TRUE;
@@ -1772,20 +1840,7 @@ gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
            event->window != xpaned->handle_middle && event->button == 1)
     {
       xpaned->in_drag_horiz = TRUE;
-
-      /* We need a server grab here, not gtk_grab_add(), since
-       * we don't want to pass events on to the widget's children */
-      if (gdk_pointer_grab (xpaned->handle_north,
-                            FALSE,
-                            GDK_POINTER_MOTION_HINT_MASK
-                            | GDK_BUTTON1_MOTION_MASK
-                            | GDK_BUTTON_RELEASE_MASK
-                            | GDK_ENTER_NOTIFY_MASK
-                            | GDK_LEAVE_NOTIFY_MASK,
-                            NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
-        {
-        }
-
+      gtk_xpaned_button_press_grab (xpaned->handle_north, event);
       xpaned->drag_pos.x = event->x;
 
       return TRUE;
@@ -1798,20 +1853,7 @@ gtk_xpaned_button_press (GtkWidget * widget, GdkEventButton * event)
            event->window != xpaned->handle_middle && event->button == 1)
     {
       xpaned->in_drag_horiz = TRUE;
-
-      /* We need a server grab here, not gtk_grab_add(), since
-       * we don't want to pass events on to the widget's children */
-      if (gdk_pointer_grab (xpaned->handle_south,
-                            FALSE,
-                            GDK_POINTER_MOTION_HINT_MASK
-                            | GDK_BUTTON1_MOTION_MASK
-                            | GDK_BUTTON_RELEASE_MASK
-                            | GDK_ENTER_NOTIFY_MASK
-                            | GDK_LEAVE_NOTIFY_MASK,
-                            NULL, NULL, event->time) == GDK_GRAB_SUCCESS)
-        {
-        }
-
+      gtk_xpaned_button_press_grab (xpaned->handle_south, event);
       xpaned->drag_pos.x = event->x;
 
       return TRUE;
@@ -1829,8 +1871,7 @@ gtk_xpaned_button_release (GtkWidget * widget, GdkEventButton * event)
       xpaned->in_drag_vert = FALSE;
       xpaned->drag_pos.y = -1;
       xpaned->position_set = TRUE;
-      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
-                                  event->time);
+      gdk_device_ungrab (event->device, event->time);
       return TRUE;
     }
   else if (xpaned->in_drag_horiz && (event->button == 1))
@@ -1838,8 +1879,7 @@ gtk_xpaned_button_release (GtkWidget * widget, GdkEventButton * event)
       xpaned->in_drag_horiz = FALSE;
       xpaned->drag_pos.x = -1;
       xpaned->position_set = TRUE;
-      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
-                                  event->time);
+      gdk_device_ungrab (event->device, event->time);
       return TRUE;
     }
   else if (xpaned->in_drag_vert_and_horiz && (event->button == 1))
@@ -1848,8 +1888,7 @@ gtk_xpaned_button_release (GtkWidget * widget, GdkEventButton * event)
       xpaned->drag_pos.x = -1;
       xpaned->drag_pos.y = -1;
       xpaned->position_set = TRUE;
-      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
-                                  event->time);
+      gdk_device_ungrab (event->device, event->time);
       return TRUE;
     }
 
@@ -2062,9 +2101,9 @@ gtk_xpaned_forall (GtkContainer * container,
 /**
  * gtk_xpaned_get_position_x:
  * @paned: a #GtkXPaned widget
- * 
+ *
  * Obtains the x-position of the divider.
- * 
+ *
  * Return value: x-position of the divider
  **/
 gint
@@ -2078,9 +2117,9 @@ gtk_xpaned_get_position_x (GtkXPaned * xpaned)
 /**
  * gtk_xpaned_get_position_y:
  * @paned: a #GtkXPaned widget
- * 
+ *
  * Obtains the y-position of the divider.
- * 
+ *
  * Return value: y-position of the divider
  **/
 gint
@@ -2096,7 +2135,7 @@ gtk_xpaned_get_position_y (GtkXPaned * xpaned)
  * @paned: a #GtkXPaned widget
  * @xposition: pixel x-position of divider, a negative values
  *                        of a component mean that the position is unset.
- * 
+ *
  * Sets the x-position of the divider between the four panes.
  **/
 void
@@ -2145,7 +2184,7 @@ gtk_xpaned_set_position_x (GtkXPaned * xpaned, gint xposition)
  * @paned: a #GtkXPaned widget
  * @yposition: pixel y-position of divider, a negative values
  *                        of a component mean that the position is unset.
- * 
+ *
  * Sets the y-position of the divider between the four panes.
  **/
 void
@@ -2220,9 +2259,9 @@ gtk_xpaned_fetch_unmaximized_y (GtkXPaned * xpaned)
 /**
  * gtk_xpaned_get_top_left_child:
  * @xpaned: a #GtkXPaned widget
- * 
+ *
  * Obtains the top-left child of the xpaned widget.
- * 
+ *
  * Return value: top-left child, or %NULL if it is not set.
  *
  * Since: 2.4
@@ -2238,9 +2277,9 @@ gtk_xpaned_get_top_left_child (GtkXPaned * xpaned)
 /**
  * gtk_xpaned_get_top_right_child:
  * @xpaned: a #GtkXPaned widget
- * 
+ *
  * Obtains the top-right child of the xpaned widget.
- * 
+ *
  * Return value: top-right child, or %NULL if it is not set.
  *
  * Since: 2.4
@@ -2256,9 +2295,9 @@ gtk_xpaned_get_top_right_child (GtkXPaned * xpaned)
 /**
  * gtk_xpaned_get_bottom_left_child:
  * @xpaned: a #GtkXPaned widget
- * 
+ *
  * Obtains the bottom-left child of the xpaned widget.
- * 
+ *
  * Return value: bottom-left child, or %NULL if it is not set.
  *
  * Since: 2.4
@@ -2274,9 +2313,9 @@ gtk_xpaned_get_bottom_left_child (GtkXPaned * xpaned)
 /**
  * gtk_xpaned_get_bottom_right_child:
  * @xpaned: a #GtkXPaned widget
- * 
+ *
  * Obtains the bottom-right child of the xpaned widget.
- * 
+ *
  * Return value: bottom-right child, or %NULL if it is not set.
  *
  * Since: 2.4