[gtk+/xi2] GtkRange: Use device GTK+ grabs.



commit 5d9bff39bf40d825ef6708c131b8f551d03a504e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Mar 9 18:20:25 2010 +0100

    GtkRange: Use device GTK+ grabs.

 gtk/gtkrange.c |   68 ++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 54 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 3ab498e..6d0875b 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -122,6 +122,8 @@ struct _GtkRangeLayout
   gint *mark_pos;
   gint n_marks;
   gboolean recalc_marks;
+
+  GdkDevice *grab_device;
 };
 
 
@@ -2014,16 +2016,28 @@ gtk_range_expose (GtkWidget      *widget,
 
 static void
 range_grab_add (GtkRange      *range,
+                GdkDevice     *device,
                 MouseLocation  location,
                 gint           button)
 {
-  /* we don't actually gtk_grab, since a button is down */
+  GtkRangeLayout *layout = range->layout;
+
+  if (device == layout->grab_device)
+    return;
+
+  if (layout->grab_device != NULL)
+    {
+      g_warning ("GtkRange already had a grab device, releasing device grab");
+      gtk_device_grab_remove (GTK_WIDGET (range), layout->grab_device);
+    }
+
+  /* we don't actually gdk_grab, since a button is down */
+  gtk_device_grab_add (GTK_WIDGET (range), device, TRUE);
 
-  gtk_grab_add (GTK_WIDGET (range));
-  
   range->layout->grab_location = location;
   range->layout->grab_button = button;
-  
+  range->layout->grab_device = device;
+
   if (gtk_range_update_mouse_location (range))
     gtk_widget_queue_draw (GTK_WIDGET (range));
 }
@@ -2031,10 +2045,16 @@ range_grab_add (GtkRange      *range,
 static void
 range_grab_remove (GtkRange *range)
 {
+  GtkRangeLayout *layout = range->layout;
   MouseLocation location;
 
-  gtk_grab_remove (GTK_WIDGET (range));
- 
+  if (layout->grab_device)
+    {
+      gtk_device_grab_remove (GTK_WIDGET (range),
+                              layout->grab_device);
+      layout->grab_device = NULL;
+    }
+
   location = range->layout->grab_location; 
   range->layout->grab_location = MOUSE_OUTSIDE;
   range->layout->grab_button = 0;
@@ -2159,9 +2179,15 @@ static gboolean
 gtk_range_key_press (GtkWidget   *widget,
 		     GdkEventKey *event)
 {
+  GdkDevice *device;
   GtkRange *range = GTK_RANGE (widget);
+  GtkRangeLayout *layout = range->layout;
+
+  device = gdk_event_get_device ((GdkEvent *) event);
+  device = gdk_device_get_associated_device (device);
 
-  if (event->keyval == GDK_Escape &&
+  if (device == layout->grab_device &&
+      event->keyval == GDK_Escape &&
       range->layout->grab_location != MOUSE_OUTSIDE)
     {
       stop_scrolling (range);
@@ -2181,6 +2207,7 @@ gtk_range_button_press (GtkWidget      *widget,
 			GdkEventButton *event)
 {
   GtkRange *range = GTK_RANGE (widget);
+  GdkDevice *device;
   
   if (!GTK_WIDGET_HAS_FOCUS (widget))
     gtk_widget_grab_focus (widget);
@@ -2189,8 +2216,10 @@ gtk_range_button_press (GtkWidget      *widget,
   if (range->layout->grab_location != MOUSE_OUTSIDE)
     return FALSE;
 
+  device = gdk_event_get_device ((GdkEvent *) event);
   range->layout->mouse_x = event->x;
   range->layout->mouse_y = event->y;
+
   if (gtk_range_update_mouse_location (range))
     gtk_widget_queue_draw (widget);
     
@@ -2207,7 +2236,7 @@ gtk_range_button_press (GtkWidget      *widget,
                                     event->y : event->x);
       
       range->trough_click_forward = click_value > range->adjustment->value;
-      range_grab_add (range, MOUSE_TROUGH, event->button);
+      range_grab_add (range, device, MOUSE_TROUGH, event->button);
       
       scroll = range_get_scroll_for_grab (range);
       
@@ -2224,7 +2253,7 @@ gtk_range_button_press (GtkWidget      *widget,
       GdkRectangle *stepper_area;
       GtkScrollType scroll;
       
-      range_grab_add (range, range->layout->mouse_location, event->button);
+      range_grab_add (range, device, range->layout->mouse_location, event->button);
 
       stepper_area = get_area (range, range->layout->mouse_location);
       gtk_widget_queue_draw_area (widget,
@@ -2291,7 +2320,7 @@ gtk_range_button_press (GtkWidget      *widget,
           range->slide_initial_coordinate = event->x;
         }
 
-      range_grab_add (range, MOUSE_SLIDER, event->button);
+      range_grab_add (range, device, MOUSE_SLIDER, event->button);
 
       gtk_widget_style_get (widget, "activate-slider", &activate_slider, NULL);
 
@@ -2368,8 +2397,12 @@ gtk_range_grab_broken (GtkWidget          *widget,
 		       GdkEventGrabBroken *event)
 {
   GtkRange *range = GTK_RANGE (widget);
+  GdkDevice *device;
 
-  if (range->layout->grab_location != MOUSE_OUTSIDE)
+  device = gdk_event_get_device ((GdkEvent *) event);
+
+  if (device == range->layout->grab_device &&
+      range->layout->grab_location != MOUSE_OUTSIDE)
     {
       if (range->layout->grab_location == MOUSE_SLIDER)
 	update_slider_position (range, range->layout->mouse_x, range->layout->mouse_y);
@@ -2387,6 +2420,7 @@ gtk_range_button_release (GtkWidget      *widget,
 			  GdkEventButton *event)
 {
   GtkRange *range = GTK_RANGE (widget);
+  GdkDevice *device;
 
   if (event->window == range->event_window)
     {
@@ -2401,8 +2435,11 @@ gtk_range_button_release (GtkWidget      *widget,
                                       &range->layout->mouse_y,
                                       NULL);
     }
-  
-  if (range->layout->grab_button == event->button)
+
+  device = gdk_event_get_device ((GdkEvent *) event);
+
+  if (range->layout->grab_device == device &&
+      range->layout->grab_button == event->button)
     {
       if (range->layout->grab_location == MOUSE_SLIDER)
         update_slider_position (range, range->layout->mouse_x, range->layout->mouse_y);
@@ -2534,7 +2571,10 @@ static void
 gtk_range_grab_notify (GtkWidget *widget,
 		       gboolean   was_grabbed)
 {
-  if (!was_grabbed)
+  GtkRangeLayout *layout = GTK_RANGE (widget)->layout;
+
+  if (layout->grab_device &&
+      gtk_widget_device_is_shadowed (widget, layout->grab_device))
     stop_scrolling (GTK_RANGE (widget));
 }
 



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