[goocanvas/goocanvas-2.0] Fix stuck grab bug #711709
- From: Damon Chaplin <damon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goocanvas/goocanvas-2.0] Fix stuck grab bug #711709
- Date: Wed, 30 Aug 2017 10:24:45 +0000 (UTC)
commit 9ad26d107dfa4c690d4364a389dc4e47a471c1ff
Author: Damon Chaplin <Damon A Chaplin gmail com>
Date: Wed Aug 30 11:22:37 2017 +0100
Fix stuck grab bug #711709
2017-08-30 Damon Chaplin <damon gnome org>
* src/goocanvas.c: If we receive a LEAVE_NOTIFY event with a mode of
GDK_CROSSING_GRAB or GDK_CROSSING_GTK_GRAB we finish any passive grab
we have underway. Hopefully fixes #711709
* demo/mv-simple-demo.c (on_rect_button_press):
* demo/simple-demo.c (on_rect_button_press): show a dialog to test
the grab bug fix above.
.gitignore | 1 +
ChangeLog | 10 +++++++
demo/mv-simple-demo.c | 17 +++++++++--
demo/simple-demo.c | 17 +++++++++--
src/goocanvas.c | 73 +++++++++++++++++++++++++++++-------------------
5 files changed, 83 insertions(+), 35 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 74b5531..2635757 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@ Makefile.in
/install-sh
/libtool
/ltmain.sh
+/m4
/missing
/mkinstalldirs
/py-compile
diff --git a/ChangeLog b/ChangeLog
index 9a8d576..0a022af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-08-30 Damon Chaplin <damon gnome org>
+
+ * src/goocanvas.c: If we receive a LEAVE_NOTIFY event with a mode of
+ GDK_CROSSING_GRAB or GDK_CROSSING_GTK_GRAB we finish any passive grab
+ we have underway. Hopefully fixes #711709
+
+ * demo/mv-simple-demo.c (on_rect_button_press):
+ * demo/simple-demo.c (on_rect_button_press): show a dialog to test
+ the grab bug fix above.
+
2017-08-29 Damon Chaplin <damon gnome org>
* src/goocanvas.c:
diff --git a/demo/mv-simple-demo.c b/demo/mv-simple-demo.c
index 74c1b34..39c5edd 100644
--- a/demo/mv-simple-demo.c
+++ b/demo/mv-simple-demo.c
@@ -72,15 +72,26 @@ main (int argc, char *argv[])
}
-/* This handles button presses in item views. We simply output a message to
- the console. */
+/* The signal handler for the rectangle item. We show a dialog here. */
static gboolean
on_rect_button_press (GooCanvasItem *item,
GooCanvasItem *target,
GdkEventButton *event,
gpointer data)
{
- g_print ("rect item received button press event\n");
+ GooCanvas *canvas;
+ GtkWidget *window, *dialog;
+
+ canvas = goo_canvas_item_get_canvas (item);
+ window = gtk_widget_get_toplevel (GTK_WIDGET (canvas));
+ dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ "rect item received button press event");
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
return TRUE;
}
diff --git a/demo/simple-demo.c b/demo/simple-demo.c
index 0cb64d5..3da3d62 100644
--- a/demo/simple-demo.c
+++ b/demo/simple-demo.c
@@ -68,15 +68,26 @@ main (int argc, char *argv[])
}
-/* This handles button presses in item views. We simply output a message to
- the console. */
+/* The signal handler for the rectangle item. We show a dialog here. */
static gboolean
on_rect_button_press (GooCanvasItem *item,
GooCanvasItem *target,
GdkEventButton *event,
gpointer data)
{
- g_print ("rect item received button press event\n");
+ GooCanvas *canvas;
+ GtkWidget *window, *dialog;
+
+ canvas = goo_canvas_item_get_canvas (item);
+ window = gtk_widget_get_toplevel (GTK_WIDGET (canvas));
+ dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ "rect item received button press event");
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
return TRUE;
}
diff --git a/src/goocanvas.c b/src/goocanvas.c
index 180d1fa..a7d7a21 100644
--- a/src/goocanvas.c
+++ b/src/goocanvas.c
@@ -122,6 +122,7 @@ struct _GooCanvasPrivate {
gint static_window_x, static_window_y;
GdkRGBA background_color;
guint background_color_set : 1;
+ guint pointer_grab_is_implicit : 1;
};
@@ -3209,17 +3210,51 @@ update_pointer_item (GooCanvas *canvas,
}
+static void
+goo_canvas_finish_pointer_grab (GooCanvas *canvas,
+ GdkEvent *event)
+{
+ /* We set the pointer item back to the item it was in before the
+ grab, so we'll synthesize enter/leave notify events as appropriate. */
+ if (canvas->pointer_grab_initial_item
+ && ITEM_IS_VALID (canvas->pointer_grab_initial_item))
+ set_item_pointer (&canvas->pointer_item,
+ canvas->pointer_grab_initial_item);
+ else
+ set_item_pointer (&canvas->pointer_item, NULL);
+
+ set_item_pointer (&canvas->pointer_grab_item, NULL);
+ set_item_pointer (&canvas->pointer_grab_initial_item, NULL);
+
+ update_pointer_item (canvas, event);
+}
+
+
static gboolean
goo_canvas_crossing (GtkWidget *widget,
GdkEventCrossing *event)
{
GooCanvas *canvas = GOO_CANVAS (widget);
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
if (event->window != canvas->canvas_window)
return FALSE;
- /* This will result in synthesizing focus_in/out events as appropriate. */
- update_pointer_item (canvas, (GdkEvent*) event);
+ /* If the pointer has left the canvas window due to a grab, then finish any
+ implicit pointer grab we have underway. */
+ if (event->type == GDK_LEAVE_NOTIFY
+ && (event->mode == GDK_CROSSING_GRAB
+ || event->mode == GDK_CROSSING_GTK_GRAB)
+ && canvas->pointer_grab_item
+ && priv->pointer_grab_is_implicit)
+ {
+ goo_canvas_finish_pointer_grab (canvas, (GdkEvent*) event);
+ }
+ else
+ {
+ /* This will result in synthesizing focus_in/out events as appropriate. */
+ update_pointer_item (canvas, (GdkEvent*) event);
+ }
return FALSE;
}
@@ -3251,6 +3286,7 @@ goo_canvas_button_press (GtkWidget *widget,
GdkEventButton *event)
{
GooCanvas *canvas = GOO_CANVAS (widget);
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
GdkDevice *device = gdk_event_get_device ((GdkEvent*) event);
GdkDisplay *display;
@@ -3270,6 +3306,7 @@ goo_canvas_button_press (GtkWidget *widget,
set_item_pointer (&canvas->pointer_grab_item,
canvas->pointer_item);
canvas->pointer_grab_button = event->button;
+ priv->pointer_grab_is_implicit = TRUE;
}
return emit_pointer_event (canvas, "button_press_event", (GdkEvent*) event);
@@ -3299,19 +3336,7 @@ goo_canvas_button_release (GtkWidget *widget,
&& event->button == canvas->pointer_grab_button
&& !gdk_display_device_is_grabbed (display, device))
{
- /* We set the pointer item back to the item it was in before the
- grab, so we'll synthesize enter/leave notify events as appropriate. */
- if (canvas->pointer_grab_initial_item
- && ITEM_IS_VALID (canvas->pointer_grab_initial_item))
- set_item_pointer (&canvas->pointer_item,
- canvas->pointer_grab_initial_item);
- else
- set_item_pointer (&canvas->pointer_item, NULL);
-
- set_item_pointer (&canvas->pointer_grab_item, NULL);
- set_item_pointer (&canvas->pointer_grab_initial_item, NULL);
-
- update_pointer_item (canvas, (GdkEvent*) event);
+ goo_canvas_finish_pointer_grab (canvas, (GdkEvent*) event);
}
return retval;
@@ -3534,6 +3559,7 @@ goo_canvas_pointer_grab (GooCanvas *canvas,
GdkCursor *cursor,
guint32 time)
{
+ GooCanvasPrivate *priv = GOO_CANVAS_GET_PRIVATE (canvas);
GdkGrabStatus status = GDK_GRAB_SUCCESS;
GdkDisplay *display;
@@ -3570,6 +3596,7 @@ goo_canvas_pointer_grab (GooCanvas *canvas,
canvas->pointer_item);
set_item_pointer (&canvas->pointer_grab_item,
item);
+ priv->pointer_grab_is_implicit = FALSE;
}
return status;
@@ -3610,20 +3637,8 @@ goo_canvas_pointer_ungrab (GooCanvas *canvas,
gdk_display_pointer_ungrab (display, time);
#endif
- /* We set the pointer item back to the item it was in before the
- grab, so we'll synthesize enter/leave notify events as appropriate. */
- if (canvas->pointer_grab_initial_item
- && ITEM_IS_VALID (canvas->pointer_grab_initial_item))
- set_item_pointer (&canvas->pointer_item,
- canvas->pointer_grab_initial_item);
- else
- set_item_pointer (&canvas->pointer_item, NULL);
-
- set_item_pointer (&canvas->pointer_grab_item, NULL);
- set_item_pointer (&canvas->pointer_grab_initial_item, NULL);
-
- update_pointer_item (canvas, NULL);
- }
+ goo_canvas_finish_pointer_grab (canvas, NULL);
+}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]