# HG changeset patch # User Luke Schierer # Date 1093305383 0 # Node ID 19fd43d52d18618390044ed23d925ff8486f265d # Parent 595a2fb511b91ad14296c8d8ba03877a08f1aac8 [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 diff -r 595a2fb511b9 -r 19fd43d52d18 plugins/gestures/stroke-draw.c --- 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; diff -r 595a2fb511b9 -r 19fd43d52d18 plugins/gestures/stroke.c --- a/plugins/gestures/stroke.c Mon Aug 23 23:10:21 2004 +0000 +++ b/plugins/gestures/stroke.c Mon Aug 23 23:56:23 2004 +0000 @@ -190,6 +190,8 @@ gint delx, dely; float ix, iy; + g_return_if_fail( metrics != NULL ); + #if 0 printf ("%d:%d ", x, y); fflush (stdout); #endif