aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/misc/e-canvas.c68
-rw-r--r--widgets/misc/e-canvas.h61
-rw-r--r--widgets/table/e-table-item.c35
-rw-r--r--widgets/table/e-table-item.h1
-rw-r--r--widgets/text/e-text.c15
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: