Re: Bug in dragging from GtkListItem




Elliot Lee <sopwith@redhat.com> writes:

>   This message is in MIME format.  The first part should be readable text,
>   while the remaining parts are likely unreadable without MIME-aware tools.
>   Send mail to mime@docserver.cac.washington.edu for more info.
> 
> ---1345349078-2089841823-915554737=:20942
> Content-Type: TEXT/PLAIN; charset=US-ASCII
> 
> When dragging from a GtkListItem source to another widget in the same app,
> the GtkList keeps an event grab or something, so that moving the mouse
> anywhere in the app changes the current list item, and clicking the first
> time does not work as expected.
> 
> The attached patch (which applies to
> gnome-libs/gnome-hello/gnome-hello-5-dnd.c - sorry, no gtk-only one, but
> the idea is pretty simple and easy to reproduce) demonstrates the problem.

Thanks for the bug report.

The problem is that when the user release the button
from a drag, gtkdnd.c fakes a button release on the
source widget to convince it to release any grabs
it has. But GtkList expects the button release to
propagate to the GtkList widget, so it wasn't noticing
the event sent to the button widget.

The following is a half-fix - you'll notice that the list 
item is selected after the button release which is a bit 
odd, though better. That problem occurs because of the way 
GtkList expects propagation to occur. I'll have to think a 
bit more on how to fix that.

Regards,
                                        Owen

Index: gtkdnd.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdnd.c,v
retrieving revision 1.21
diff -u -r1.21 gtkdnd.c
--- gtkdnd.c	1998/12/24 17:46:57	1.21
+++ gtkdnd.c	1999/01/05 23:19:38
@@ -2459,19 +2460,31 @@
 
   gtk_grab_remove (widget);
 
+  /* Send on a release pair to the the original 
+   * widget to convince it to release its grab. We need to
+   * call gtk_propagate_event() here, instead of 
+   * gtk_widget_event() because widget like GtkList may
+   * expect propagation.
+   */
+
   send_event.button.type = GDK_BUTTON_RELEASE;
   send_event.button.window = source_widget->window;
+  send_event.button.send_event = TRUE;
+  send_event.button.time = event->time;
   send_event.button.x = 0;
   send_event.button.y = 0;
+  send_event.button.pressure = 0.;
+  send_event.button.xtilt = 0.;
+  send_event.button.ytilt = 0.;
   send_event.button.state = event->state;
   send_event.button.button = event->button;
-  
-  send_event.button.time = event->time;
+  send_event.button.source = GDK_SOURCE_PEN;
+  send_event.button.deviceid = GDK_CORE_POINTER;
+  send_event.button.x_root = 0;
+  send_event.button.y_root = 0;
 
-  /* Send on the button release to the original widget to
-   * convince it to release its grab
-   */
-  gtk_widget_event (source_widget, &send_event);
+  gtk_propagate_event (source_widget, &send_event);
+
   gtk_widget_unref (source_widget);
   
   return TRUE;
Index: gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.101
diff -u -r1.101 gtkmain.c
--- gtkmain.c	1998/12/31 04:43:36	1.101
+++ gtkmain.c	1999/01/05 23:19:38
@@ -85,8 +85,6 @@
 static void  gtk_quit_destroy		 (GtkQuitFunction    *quitf);
 static gint  gtk_invoke_key_snoopers	 (GtkWidget	     *grab_widget,
 					  GdkEvent	     *event);
-static void  gtk_propagate_event	 (GtkWidget	     *widget,
-					  GdkEvent	     *event);
 
 static void     gtk_destroy_closure      (gpointer            data);
 static gboolean gtk_invoke_idle_timeout  (gpointer            data);
@@ -1196,7 +1194,7 @@
     }
 }
 
-static void
+void
 gtk_propagate_event (GtkWidget *widget,
 		     GdkEvent  *event)
 {
Index: gtkmain.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.h,v
retrieving revision 1.22
diff -u -r1.22 gtkmain.h
--- gtkmain.h	1998/12/20 05:47:26	1.22
+++ gtkmain.h	1999/01/05 23:19:38
@@ -139,6 +139,11 @@
 GtkWidget* gtk_get_event_widget	   (GdkEvent	   *event);
 
 
+/* Private routines internal to GTK+ 
+ */
+void       gtk_propagate_event     (GtkWidget         *widget,
+				    GdkEvent          *event);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */



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