diff plugins/gestures/stroke-draw.c @ 9843:19fd43d52d18

[gaim-migrate @ 10721] " I didn't notice this bug had been closed until I went looking for it again. :) I have been able to crash Gaim 0.82cvs using the method described in the bug. It looks like there was a patch to the gestures plugin to catch a case where it catches the release of a non-gestures button and the gesture is active. It seems as though there is a way to confuse GDK (or the gestures plugin) into missing the button release event for the gestures button by sending it a bunch of events at the same time (chord-clicking all 3 buttons of the mouse at once). This patch traps when other buttons are clicked after a gesture is active and cancels the gesture. I don't know if it's the Right Fix(tm), but it does keep it from crashing on my system. I also trapped a place or two where it would actually segfault in Gaim; the button trap is more of a fix to keep the gesture from "sticking". If the gesture sticks and we trap the null data pointers, Gaim still crashes with a badDrawable X error. The error was 'BadDrawable (invalid Pixmap or Window parameter)'. (Details: serial 5520 error_code 9 request_code 66 minor_code 0) " --Dave (kat) West committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Mon, 23 Aug 2004 23:56:23 +0000
parents e0535ba0d667
children b23e6f9c4d2e
line wrap: on
line diff
--- a/plugins/gestures/stroke-draw.c	Mon Aug 23 23:10:21 2004 +0000
+++ b/plugins/gestures/stroke-draw.c	Mon Aug 23 23:56:23 2004 +0000
@@ -57,6 +57,8 @@
   gint x, y;
   struct gstroke_metrics *metrics;
 
+  g_return_if_fail( widget != NULL );
+
   gtk_widget_get_pointer (widget, &x, &y);
 
   if (last_mouse_position.invalid)
@@ -95,12 +97,34 @@
 static gint
 gstroke_timeout (gpointer data)
 {
+  g_return_val_if_fail(data != NULL, FALSE);
   GtkWidget *widget = GTK_WIDGET (data);
   record_stroke_segment (widget);
 
   return TRUE;
 }
 
+static void gstroke_cancel(GdkEvent *event) 
+{
+	last_mouse_position.invalid = TRUE;
+
+	if (timer_id > 0)
+	    g_source_remove (timer_id);
+
+	timer_id = 0;
+
+	if( event != NULL )
+		gdk_pointer_ungrab (event->button.time);
+
+
+	if (gstroke_draw_strokes() && gstroke_disp != NULL) {
+	    /* get rid of the invisible stroke window */
+	    XUnmapWindow (gstroke_disp, gstroke_window);
+	    XFlush (gstroke_disp);
+	}
+
+}
+
 static gint
 process_event (GtkWidget *widget, GdkEvent *event, gpointer data G_GNUC_UNUSED)
 {
@@ -109,8 +133,15 @@
 
   switch (event->type) {
     case GDK_BUTTON_PRESS:
-      if (event->button.button != gstroke_get_mouse_button())
-        break;
+		if (event->button.button != gstroke_get_mouse_button()) {
+			/* Similar to the bug below catch when any other button is
+			 * clicked after the middle button is clicked (but possibly
+			 * not released)
+			 */
+			gstroke_cancel(event);	
+			original_widget = NULL;
+			break;
+		}
 
       original_widget = widget; /* remeber the widget where
                                    the stroke started */
@@ -133,25 +164,11 @@
       if ((event->button.button != gstroke_get_mouse_button())
 	  || (original_widget == NULL)) {
 
-		  /* Nice bug when you hold down one button and press another. */
-		  /* We'll just cancel the gesture instead. */
-		  last_mouse_position.invalid = TRUE;
-		  original_widget = NULL;
-
-		  if (timer_id > 0)
-			  g_source_remove (timer_id);
-
-		  gdk_pointer_ungrab (event->button.time);
-		  timer_id = 0;
-
-		  if (gstroke_draw_strokes() && gstroke_disp != NULL) {
-			  /* get rid of the invisible stroke window */
-			  XUnmapWindow (gstroke_disp, gstroke_window);
-			  XFlush (gstroke_disp);
-		  }
-
-		  break;
-	  
+		/* Nice bug when you hold down one button and press another. */
+		/* We'll just cancel the gesture instead. */
+		gstroke_cancel(event);
+		original_widget = NULL;
+		break;
 	  }
 
       last_mouse_position.invalid = TRUE;