diff options
-rw-r--r-- | widgets/misc/e-canvas.c | 68 | ||||
-rw-r--r-- | widgets/misc/e-canvas.h | 61 | ||||
-rw-r--r-- | widgets/table/e-table-item.c | 35 | ||||
-rw-r--r-- | widgets/table/e-table-item.h | 1 | ||||
-rw-r--r-- | widgets/text/e-text.c | 15 |
5 files changed, 149 insertions, 31 deletions
diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index 378bc31e56..e5b0b78bcd 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -24,6 +24,8 @@ #include <gtk/gtksignal.h> #include "e-canvas.h" #include "gal/util/e-util.h" +#include <X11/Xlib.h> +#include <gtk/gtkmain.h> static void e_canvas_init (ECanvas *card); static void e_canvas_destroy (GtkObject *object); @@ -1082,3 +1084,69 @@ void e_canvas_hide_tooltip (ECanvas *canvas) canvas->tooltip_window = NULL; } } + + +static gboolean +grab_cancelled_check (gpointer data) +{ + ECanvas *canvas = data; + + if (gtk_grab_get_current ()) { + gnome_canvas_item_ungrab(GNOME_CANVAS (canvas)->grabbed_item, canvas->grab_cancelled_time); + if (canvas->grab_cancelled_cb) { + canvas->grab_cancelled_cb (canvas, + GNOME_CANVAS (canvas)->grabbed_item, + canvas->grab_cancelled_data); + } + canvas->grab_cancelled_cb = NULL; + canvas->grab_cancelled_check_id = 0; + canvas->grab_cancelled_time = 0; + canvas->grab_cancelled_data = NULL; + return FALSE; + } + return TRUE; +} + +int +e_canvas_item_grab (ECanvas *canvas, + GnomeCanvasItem *item, + guint event_mask, + GdkCursor *cursor, + guint32 etime, + ECanvasItemGrabCancelled cancelled_cb, + gpointer cancelled_data) +{ + if (gtk_grab_get_current ()) { + return AlreadyGrabbed; + } else { + int ret_val = gnome_canvas_item_grab (item, event_mask, cursor, etime); + if (ret_val == GrabSuccess) { + canvas->grab_cancelled_cb = cancelled_cb; + canvas->grab_cancelled_check_id = + g_timeout_add_full (G_PRIORITY_LOW, + 100, + grab_cancelled_check, + canvas, + NULL); + canvas->grab_cancelled_time = etime; + canvas->grab_cancelled_data = cancelled_data; + } + + return ret_val; + } +} + +void +e_canvas_item_ungrab (ECanvas *canvas, + GnomeCanvasItem *item, + guint32 etime) +{ + if (canvas->grab_cancelled_check_id) { + g_source_remove (canvas->grab_cancelled_check_id); + canvas->grab_cancelled_cb = NULL; + canvas->grab_cancelled_check_id = 0; + canvas->grab_cancelled_time = 0; + canvas->grab_cancelled_data = NULL; + gnome_canvas_item_ungrab (item, etime); + } +} diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index ee25a4b6bf..fb0d7398e7 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -74,6 +74,8 @@ typedef struct { gpointer id; } ECanvasSelectionInfo; +typedef void (*ECanvasItemGrabCancelled) (ECanvas *canvas, GnomeCanvasItem *item, gpointer data); + struct _ECanvas { GnomeCanvas parent; @@ -90,6 +92,11 @@ struct _ECanvas /* Input context for dead key support */ GdkIC *ic; GdkICAttr *ic_attr; + + ECanvasItemGrabCancelled grab_cancelled_cb; + guint grab_cancelled_check_id; + guint32 grab_cancelled_time; + gpointer grab_cancelled_data; }; struct _ECanvasClass @@ -99,30 +106,48 @@ struct _ECanvasClass }; -GtkType e_canvas_get_type (void); -GtkWidget *e_canvas_new (void); +GtkType e_canvas_get_type (void); +GtkWidget *e_canvas_new (void); /* Used to send all of the keystroke events to a specific item as well as * GDK_FOCUS_CHANGE events. */ -void e_canvas_item_grab_focus (GnomeCanvasItem *item, gboolean widget_too); - -void e_canvas_item_request_reflow (GnomeCanvasItem *item); -void e_canvas_item_request_parent_reflow (GnomeCanvasItem *item); -void e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, ECanvasItemReflowFunc func); - -void e_canvas_item_set_selection_callback (GnomeCanvasItem *item, ECanvasItemSelectionFunc func); -void e_canvas_item_set_selection_compare_callback (GnomeCanvasItem *item, ECanvasItemSelectionCompareFunc func); - -void e_canvas_item_set_cursor (GnomeCanvasItem *item, gpointer id); -void e_canvas_item_add_selection (GnomeCanvasItem *item, gpointer id); -void e_canvas_item_remove_selection (GnomeCanvasItem *item, gpointer id); +void e_canvas_item_grab_focus (GnomeCanvasItem *item, + gboolean widget_too); +void e_canvas_item_request_reflow (GnomeCanvasItem *item); +void e_canvas_item_request_parent_reflow (GnomeCanvasItem *item); +void e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, + ECanvasItemReflowFunc func); +void e_canvas_item_set_selection_callback (GnomeCanvasItem *item, + ECanvasItemSelectionFunc func); +void e_canvas_item_set_selection_compare_callback (GnomeCanvasItem *item, + ECanvasItemSelectionCompareFunc func); +void e_canvas_item_set_cursor (GnomeCanvasItem *item, + gpointer id); +void e_canvas_item_add_selection (GnomeCanvasItem *item, + gpointer id); +void e_canvas_item_remove_selection (GnomeCanvasItem *item, + gpointer id); + +int e_canvas_item_grab (ECanvas *canvas, + GnomeCanvasItem *item, + guint event_mask, + GdkCursor *cursor, + guint32 etime, + ECanvasItemGrabCancelled cancelled, + gpointer cancelled_data); +void e_canvas_item_ungrab (ECanvas *canvas, + GnomeCanvasItem *item, + guint32 etime); /* Not implemented yet. */ -void e_canvas_item_set_cursor_end (GnomeCanvasItem *item, gpointer id); - -void e_canvas_popup_tooltip (ECanvas *canvas, GtkWidget *widget, int x, int y); -void e_canvas_hide_tooltip (ECanvas *canvas); +void e_canvas_item_set_cursor_end (GnomeCanvasItem *item, + gpointer id); +void e_canvas_popup_tooltip (ECanvas *canvas, + GtkWidget *widget, + int x, + int y); +void e_canvas_hide_tooltip (ECanvas *canvas); #ifdef __cplusplus } diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index d92a174f45..80b557251a 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -30,6 +30,8 @@ #include "e-table-item.h" +#include <X11/Xlib.h> + #include <math.h> #include <stdio.h> #include <gtk/gtksignal.h> @@ -168,6 +170,14 @@ view_to_model_col(ETableItem *eti, int col) return ecol ? ecol->col_idx : -1; } +static void +grab_cancelled (ECanvas *canvas, GnomeCanvasItem *item, gpointer data) +{ + ETableItem *eti = data; + + eti->grab_cancelled = TRUE; +} + inline static void eti_grab (ETableItem *eti, guint32 time) { @@ -175,10 +185,14 @@ eti_grab (ETableItem *eti, guint32 time) d(g_print ("%s: time: %d\n", __FUNCTION__, time)); if (eti->grabbed_count == 0) { eti->gtk_grabbed = FALSE; - if (!gnome_canvas_item_grab(item, - GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK - | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK, - NULL, time)) { + eti->grab_cancelled = FALSE; + if (e_canvas_item_grab(E_CANVAS (item->canvas), + item, + GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK + | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK, + NULL, time, + grab_cancelled, + eti) != GrabSuccess) { d(g_print ("%s: gtk_grab_add\n", __FUNCTION__)); gtk_grab_add (GTK_WIDGET (item->canvas)); eti->gtk_grabbed = TRUE; @@ -194,11 +208,16 @@ eti_ungrab (ETableItem *eti, guint32 time) d(g_print ("%s: time: %d\n", __FUNCTION__, time)); eti->grabbed_count --; if (eti->grabbed_count == 0) { - if (eti->gtk_grabbed) { - d(g_print ("%s: gtk_grab_remove\n", __FUNCTION__)); - gtk_grab_remove (GTK_WIDGET (item->canvas)); + if (eti->grab_cancelled) { + eti->grab_cancelled = FALSE; + } else { + if (eti->gtk_grabbed) { + d(g_print ("%s: gtk_grab_remove\n", __FUNCTION__)); + gtk_grab_remove (GTK_WIDGET (item->canvas)); + eti->gtk_grabbed = FALSE; + } + gnome_canvas_item_ungrab(item, time); } - gnome_canvas_item_ungrab(item, time); } } diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index 793379b837..f1f055f1a1 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -114,6 +114,7 @@ typedef struct { guint gtk_grabbed : 1; guint queue_show_cursor : 1; + guint grab_cancelled : 1; int frozen_count; diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index 66c4eb85b6..1808477f65 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -3716,14 +3716,19 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp text->select_by_word = command->value; break; case E_TEP_GRAB: - gnome_canvas_item_grab (GNOME_CANVAS_ITEM(text), - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - text->i_cursor, - command->time); + e_canvas_item_grab (E_CANVAS (GNOME_CANVAS_ITEM(text)->canvas), + GNOME_CANVAS_ITEM(text), + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + text->i_cursor, + command->time, + NULL, + NULL); scroll = FALSE; break; case E_TEP_UNGRAB: - gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM(text), command->time); + e_canvas_item_ungrab (E_CANVAS (GNOME_CANVAS_ITEM(text)->canvas), + GNOME_CANVAS_ITEM(text), + command->time); scroll = FALSE; break; case E_TEP_CAPS: |