From d52ad1054d509bbe02809b7f5a9471e95727ef08 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 29 Nov 2012 16:33:41 -0500 Subject: Add a GdkDevice parameter to gnome_canvas_item_grab(). GnomeCanvas will stash the GdkDevice and reuse it in the subsequent gnome_canvas_item_ungrab() call. --- addressbook/gui/widgets/e-minicard.c | 25 ++- calendar/gui/e-meeting-time-sel-item.c | 21 ++- libgnomecanvas/gnome-canvas.c | 44 +++-- libgnomecanvas/gnome-canvas.h | 6 +- widgets/misc/e-calendar-item.c | 48 +++-- widgets/misc/e-canvas.c | 12 +- widgets/misc/e-canvas.h | 1 + widgets/table/e-table-header-item.c | 70 ++++--- widgets/table/e-table-item.c | 327 ++++++++++++++++++++++----------- widgets/text/e-reflow.c | 1 + widgets/text/e-text.c | 1 + 11 files changed, 382 insertions(+), 174 deletions(-) diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c index 4e0df4c42f..b0dae34b69 100644 --- a/addressbook/gui/widgets/e-minicard.c +++ b/addressbook/gui/widgets/e-minicard.c @@ -580,17 +580,28 @@ e_minicard_event (GnomeCanvasItem *item, case GDK_BUTTON_PRESS: { if (1 <= event->button.button && event->button.button <= 2) { gint ret_val = e_minicard_selected (e_minicard, event); - GdkEventMask mask = ((1 << (4 + event->button.button)) | - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK); + GdkGrabStatus grab_status; + GdkDevice *event_device; + guint32 event_time; e_canvas_item_grab_focus (item, TRUE); - if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (e_minicard), - mask, NULL, event->button.time)) { + event_device = gdk_event_get_device (event); + event_time = gdk_event_get_time (event); + + grab_status = gnome_canvas_item_grab ( + GNOME_CANVAS_ITEM (e_minicard), + (1 << (4 + event->button.button)) | + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, + event_device, + event_time); + + if (grab_status != GDK_GRAB_SUCCESS) return FALSE; - } + gtk_grab_add (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas)); e_minicard->button_x = event->button.x; e_minicard->button_y = event->button.y; diff --git a/calendar/gui/e-meeting-time-sel-item.c b/calendar/gui/e-meeting-time-sel-item.c index 52558e4f31..a15f25a6ef 100644 --- a/calendar/gui/e-meeting-time-sel-item.c +++ b/calendar/gui/e-meeting-time-sel-item.c @@ -843,11 +843,22 @@ e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item, mts_item, x, y); if (position != E_MEETING_TIME_SELECTOR_POS_NONE) { - if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (mts_item), - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - mts_item->resize_cursor, - event->button.time) == 0 /*Success */) { + GdkGrabStatus grab_status; + GdkDevice *event_device; + guint32 event_time; + + event_device = gdk_event_get_device (event); + event_time = gdk_event_get_time (event); + + grab_status = gnome_canvas_item_grab ( + GNOME_CANVAS_ITEM (mts_item), + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK, + mts_item->resize_cursor, + event_device, + event_time); + + if (grab_status == GDK_GRAB_SUCCESS) { mts->dragging_position = position; return TRUE; } diff --git a/libgnomecanvas/gnome-canvas.c b/libgnomecanvas/gnome-canvas.c index 10f2da53ae..99aa679f3c 100644 --- a/libgnomecanvas/gnome-canvas.c +++ b/libgnomecanvas/gnome-canvas.c @@ -312,7 +312,11 @@ gnome_canvas_item_dispose (GObject *object) if (item->canvas && item == item->canvas->grabbed_item) { item->canvas->grabbed_item = NULL; - gdk_pointer_ungrab (GDK_CURRENT_TIME); + + gdk_device_ungrab ( + item->canvas->grabbed_device, GDK_CURRENT_TIME); + g_object_unref (item->canvas->grabbed_device); + item->canvas->grabbed_device = NULL; } if (item->canvas && item == item->canvas->focused_item) @@ -816,23 +820,25 @@ gnome_canvas_item_hide (GnomeCanvasItem *item) * @item: A canvas item. * @event_mask: Mask of events that will be sent to this item. * @cursor: If non-NULL, the cursor that will be used while the grab is active. - * @etime: The timestamp required for grabbing the mouse, or GDK_CURRENT_TIME. + * @device: The pointer device to grab. + * @etime: The timestamp required for grabbing @device, or GDK_CURRENT_TIME. * * Specifies that all events that match the specified event mask should be sent - * to the specified item, and also grabs the mouse by calling - * gdk_pointer_grab(). The event mask is also used when grabbing the pointer. - * If @cursor is not NULL, then that cursor is used while the grab is active. - * The @etime parameter is the timestamp required for grabbing the mouse. + * to the specified item, and also grabs @device by calling gdk_device_grab(). + * The event mask is also used when grabbing the @device. If @cursor is not + * NULL, then that cursor is used while the grab is active. The @etime + * parameter is the timestamp required for grabbing the @device. * * Return value: If an item was already grabbed, it returns * %GDK_GRAB_ALREADY_GRABBED. If the specified item was hidden by calling * gnome_canvas_item_hide(), then it returns %GDK_GRAB_NOT_VIEWABLE. Else, - * it returns the result of calling gdk_pointer_grab(). + * it returns the result of calling gdk_device_grab(). **/ gint gnome_canvas_item_grab (GnomeCanvasItem *item, guint event_mask, GdkCursor *cursor, + GdkDevice *device, guint32 etime) { GtkLayout *layout; @@ -844,6 +850,8 @@ gnome_canvas_item_grab (GnomeCanvasItem *item, g_return_val_if_fail ( gtk_widget_get_mapped (GTK_WIDGET (item->canvas)), GDK_GRAB_NOT_VIEWABLE); + g_return_val_if_fail ( + GDK_IS_DEVICE (device), GDK_GRAB_NOT_VIEWABLE); if (item->canvas->grabbed_item) return GDK_GRAB_ALREADY_GRABBED; @@ -854,14 +862,15 @@ gnome_canvas_item_grab (GnomeCanvasItem *item, layout = GTK_LAYOUT (item->canvas); bin_window = gtk_layout_get_bin_window (layout); - retval = gdk_pointer_grab ( - bin_window, FALSE, event_mask, - NULL, cursor, etime); + retval = gdk_device_grab ( + device, bin_window, GDK_OWNERSHIP_NONE, + FALSE, event_mask, cursor, etime); if (retval != GDK_GRAB_SUCCESS) return retval; item->canvas->grabbed_item = item; + item->canvas->grabbed_device = g_object_ref (device); item->canvas->grabbed_event_mask = event_mask; item->canvas->current_item = item; /* So that events go to the grabbed item */ @@ -887,7 +896,11 @@ gnome_canvas_item_ungrab (GnomeCanvasItem *item, item->canvas->grabbed_item = NULL; - gdk_pointer_ungrab (etime); + g_return_if_fail (item->canvas->grabbed_device != NULL); + gdk_device_ungrab (item->canvas->grabbed_device, etime); + + g_object_unref (item->canvas->grabbed_device); + item->canvas->grabbed_device = NULL; } void @@ -1927,11 +1940,14 @@ remove_idle (GnomeCanvas *canvas) static void shutdown_transients (GnomeCanvas *canvas) { - if (canvas->grabbed_item) { - canvas->grabbed_item = NULL; - gdk_pointer_ungrab (GDK_CURRENT_TIME); + if (canvas->grabbed_device != NULL) { + gdk_device_ungrab (canvas->grabbed_device, GDK_CURRENT_TIME); + g_object_unref (canvas->grabbed_device); + canvas->grabbed_device = NULL; } + canvas->grabbed_item = NULL; + remove_idle (canvas); } diff --git a/libgnomecanvas/gnome-canvas.h b/libgnomecanvas/gnome-canvas.h index 603ebfebc3..2c2befbf2f 100644 --- a/libgnomecanvas/gnome-canvas.h +++ b/libgnomecanvas/gnome-canvas.h @@ -245,7 +245,8 @@ void gnome_canvas_item_hide (GnomeCanvasItem *item); * XGrabPointer(). */ gint gnome_canvas_item_grab (GnomeCanvasItem *item, guint event_mask, - GdkCursor *cursor, guint32 etime); + GdkCursor *cursor, GdkDevice *device, + guint32 etime); /* Ungrabs the mouse -- the specified item must be the same that was passed to * gnome_canvas_item_grab(). Time is a proper X event time parameter. @@ -362,6 +363,9 @@ struct _GnomeCanvas { /* Item that holds a pointer grab, or NULL if none */ GnomeCanvasItem *grabbed_item; + /* The grabbed device for grabbed_item. */ + GdkDevice *grabbed_device; + /* If non-NULL, the currently focused item */ GnomeCanvasItem *focused_item; diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c index 1b1a72281d..414311bb2b 100644 --- a/widgets/misc/e-calendar-item.c +++ b/widgets/misc/e-calendar-item.c @@ -2228,45 +2228,61 @@ e_calendar_item_get_day_style (ECalendarItem *calitem, static gboolean e_calendar_item_button_press (ECalendarItem *calitem, - GdkEvent *event) + GdkEvent *button_event) { + GdkGrabStatus grab_status; + GdkDevice *event_device; + guint event_button = 0; + guint32 event_time; + gdouble event_x_win = 0; + gdouble event_y_win = 0; gint month_offset, day, add_days = 0; gboolean all_week, round_up_end = FALSE, round_down_start = FALSE; - if (event->button.button == 4) + gdk_event_get_button (button_event, &event_button); + gdk_event_get_coords (button_event, &event_x_win, &event_y_win); + event_device = gdk_event_get_device (button_event); + event_time = gdk_event_get_time (button_event); + + if (event_button == 4) e_calendar_item_set_first_month ( calitem, calitem->year, calitem->month - 1); - else if (event->button.button == 5) + else if (event_button == 5) e_calendar_item_set_first_month ( calitem, calitem->year, calitem->month + 1); if (!e_calendar_item_convert_position_to_day (calitem, - event->button.x, - event->button.y, + event_x_win, + event_y_win, TRUE, &month_offset, &day, &all_week)) return FALSE; - if (event->button.button == 3 && day == -1 + if (event_button == 3 && day == -1 && e_calendar_item_get_display_popup (calitem)) { e_calendar_item_show_popup_menu ( - calitem, event, month_offset); + calitem, button_event, month_offset); return TRUE; } - if (event->button.button != 1 || day == -1) + if (event_button != 1 || day == -1) return FALSE; if (calitem->max_days_selected < 1) return TRUE; - if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (calitem), - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - NULL, event->button.time) != 0) + grab_status = gnome_canvas_item_grab ( + GNOME_CANVAS_ITEM (calitem), + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, + event_device, + event_time); + + if (grab_status != GDK_GRAB_SUCCESS) return FALSE; if (all_week && calitem->keep_wdays_on_weeknum_click) { @@ -2341,9 +2357,13 @@ e_calendar_item_button_press (ECalendarItem *calitem, static gboolean e_calendar_item_button_release (ECalendarItem *calitem, - GdkEvent *event) + GdkEvent *button_event) { - e_calendar_item_stop_selecting (calitem, event->button.time); + guint32 event_time; + + event_time = gdk_event_get_time (button_event); + e_calendar_item_stop_selecting (calitem, event_time); + return FALSE; } diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c index e2e9ddd0cc..3ffc105867 100644 --- a/widgets/misc/e-canvas.c +++ b/widgets/misc/e-canvas.c @@ -835,21 +835,23 @@ e_canvas_item_grab (ECanvas *canvas, GnomeCanvasItem *item, guint event_mask, GdkCursor *cursor, + GdkDevice *device, guint32 etime, ECanvasItemGrabCancelled cancelled_cb, gpointer cancelled_data) { - gint ret_val; + GdkGrabStatus grab_status; g_return_val_if_fail (E_IS_CANVAS (canvas), -1); g_return_val_if_fail (GNOME_IS_CANVAS_ITEM (item), -1); + g_return_val_if_fail (GDK_IS_DEVICE (device), -1); if (gtk_grab_get_current ()) return GDK_GRAB_ALREADY_GRABBED; - ret_val = gnome_canvas_item_grab ( - item, event_mask, cursor, etime); - if (ret_val == GDK_GRAB_SUCCESS) { + grab_status = gnome_canvas_item_grab ( + item, event_mask, cursor, device, etime); + if (grab_status == GDK_GRAB_SUCCESS) { canvas->grab_cancelled_cb = cancelled_cb; canvas->grab_cancelled_check_id = g_timeout_add_full ( G_PRIORITY_LOW, 100, @@ -858,7 +860,7 @@ e_canvas_item_grab (ECanvas *canvas, canvas->grab_cancelled_data = cancelled_data; } - return ret_val; + return grab_status; } void diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h index 72a2e47f54..c5f2087cd0 100644 --- a/widgets/misc/e-canvas.h +++ b/widgets/misc/e-canvas.h @@ -124,6 +124,7 @@ gint e_canvas_item_grab (ECanvas *canvas, GnomeCanvasItem *item, guint event_mask, GdkCursor *cursor, + GdkDevice *device, guint32 etime, ECanvasItemGrabCancelled cancelled, gpointer cancelled_data); diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c index 8bec92fa10..44d3979e1c 100644 --- a/widgets/table/e-table-header-item.c +++ b/widgets/table/e-table-header-item.c @@ -1878,7 +1878,7 @@ ethi_change_sort_state (ETableHeaderItem *ethi, */ static gint ethi_event (GnomeCanvasItem *item, - GdkEvent *e) + GdkEvent *event) { ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item); GnomeCanvas *canvas = item->canvas; @@ -1886,10 +1886,25 @@ ethi_event (GnomeCanvasItem *item, const gboolean resizing = ETHI_RESIZING (ethi); gint x, y, start, col; gint was_maybe_drag = 0; + GdkModifierType event_state = 0; + guint event_button = 0; + guint event_keyval = 0; + gdouble event_x_win = 0; + gdouble event_y_win = 0; + guint32 event_time; - switch (e->type) { + /* Don't fetch the device here. GnomeCanvas frequently emits + * synthesized events, and calling gdk_event_get_device() on them + * will trigger a runtime warning. Fetch the device where needed. */ + gdk_event_get_button (event, &event_button); + gdk_event_get_coords (event, &event_x_win, &event_y_win); + gdk_event_get_keyval (event, &event_keyval); + gdk_event_get_state (event, &event_state); + event_time = gdk_event_get_time (event); + + switch (event->type) { case GDK_ENTER_NOTIFY: - convert (canvas, e->crossing.x, e->crossing.y, &x, &y); + convert (canvas, event_x_win, event_y_win, &x, &y); set_cursor (ethi, x); break; @@ -1900,20 +1915,25 @@ ethi_event (GnomeCanvasItem *item, case GDK_MOTION_NOTIFY: - convert (canvas, e->motion.x, e->motion.y, &x, &y); + convert (canvas, event_x_win, event_y_win, &x, &y); if (resizing) { gint new_width; if (ethi->resize_guide == NULL) { + GdkDevice *event_device; + /* Quick hack until I actually bind the views */ ethi->resize_guide = GINT_TO_POINTER (1); + event_device = gdk_event_get_device (event); + gnome_canvas_item_grab ( item, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, ethi->resize_cursor, - e->button.time); + event_device, + event_time); } new_width = x - ethi->resize_start_pos; @@ -1921,20 +1941,20 @@ ethi_event (GnomeCanvasItem *item, e_table_header_set_size (ethi->eth, ethi->resize_col, new_width); gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (ethi)); - } else if (ethi_maybe_start_drag (ethi, &e->motion)) { - ethi_start_drag (ethi, e); + } else if (ethi_maybe_start_drag (ethi, &event->motion)) { + ethi_start_drag (ethi, event); } else set_cursor (ethi, x); break; case GDK_BUTTON_PRESS: - if (e->button.button > 3) + if (event_button > 3) return FALSE; - convert (canvas, e->button.x, e->button.y, &x, &y); + convert (canvas, event_x_win, event_y_win, &x, &y); if (is_pointer_on_division (ethi, x, &start, &col) && - e->button.button == 1) { + event_button == 1) { ETableCol *ecol; /* @@ -1957,18 +1977,18 @@ ethi_event (GnomeCanvasItem *item, else if (ethi->tree) e_tree_freeze_state_change (ethi->tree); } else { - if (e->button.button == 1) { - ethi->click_x = e->button.x; - ethi->click_y = e->button.y; + if (event_button == 1) { + ethi->click_x = event_x_win; + ethi->click_y = event_y_win; ethi->maybe_drag = TRUE; is_pointer_on_division (ethi, x, &start, &col); ethi->selected_col = col; if (gtk_widget_get_can_focus (GTK_WIDGET (item->canvas))) e_canvas_item_grab_focus (item, TRUE); - } else if (e->button.button == 3) { - ethi_header_context_menu (ethi, e); + } else if (event_button == 3) { + ethi_header_context_menu (ethi, event); } else - ethi_button_pressed (ethi, e); + ethi_button_pressed (ethi, event); } break; @@ -1976,7 +1996,7 @@ ethi_event (GnomeCanvasItem *item, if (!resizing) break; - if (e->button.button != 1) + if (event_button != 1) break; else { gint width = 0; @@ -2005,18 +2025,18 @@ ethi_event (GnomeCanvasItem *item, } else if (was_maybe_drag && ethi->sort_info) { ETableCol *ecol; - col = ethi_find_col_by_x (ethi, e->button.x); + col = ethi_find_col_by_x (ethi, event_x_win); ecol = e_table_header_get_column (ethi->eth, col); ethi_change_sort_state (ethi, ecol); } if (needs_ungrab) - gnome_canvas_item_ungrab (item, e->button.time); + gnome_canvas_item_ungrab (item, event_time); break; } case GDK_KEY_PRESS: - if ((e->key.keyval == GDK_KEY_F10) && (e->key.state & GDK_SHIFT_MASK)) { + if ((event_keyval == GDK_KEY_F10) && (event_state & GDK_SHIFT_MASK)) { EthiHeaderInfo *info = g_new (EthiHeaderInfo, 1); ETableCol *ecol; GtkMenu *popup; @@ -2042,13 +2062,13 @@ ethi_event (GnomeCanvasItem *item, GTK_MENU (popup), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME); - } else if (e->key.keyval == GDK_KEY_space) { + } else if (event_keyval == GDK_KEY_space) { ETableCol *ecol; ecol = e_table_header_get_column (ethi->eth, ethi->selected_col); ethi_change_sort_state (ethi, ecol); - } else if ((e->key.keyval == GDK_KEY_Right) || - (e->key.keyval == GDK_KEY_KP_Right)) { + } else if ((event_keyval == GDK_KEY_Right) || + (event_keyval == GDK_KEY_KP_Right)) { ETableCol *ecol; if ((ethi->selected_col < 0) || @@ -2058,8 +2078,8 @@ ethi_event (GnomeCanvasItem *item, ethi->selected_col++; ecol = e_table_header_get_column (ethi->eth, ethi->selected_col); ethi_change_sort_state (ethi, ecol); - } else if ((e->key.keyval == GDK_KEY_Left) || - (e->key.keyval == GDK_KEY_KP_Left)) { + } else if ((event_keyval == GDK_KEY_Left) || + (event_keyval == GDK_KEY_KP_Left)) { ETableCol *ecol; if ((ethi->selected_col <= 0) || diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index 1cb81f00dc..ddf7d0ac62 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -237,20 +237,32 @@ grab_cancelled (ECanvas *canvas, inline static void eti_grab (ETableItem *eti, + GdkDevice *device, guint32 time) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti); d (g_print ("%s: time: %d\n", __FUNCTION__, time)); if (eti->grabbed_count == 0) { + GdkGrabStatus grab_status; + eti->gtk_grabbed = FALSE; 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) != GDK_GRAB_SUCCESS) { + + grab_status = 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, + device, time, + grab_cancelled, + eti); + + if (grab_status != GDK_GRAB_SUCCESS) { d (g_print ("%s: gtk_grab_add\n", __FUNCTION__)); gtk_grab_add (GTK_WIDGET (item->canvas)); eti->gtk_grabbed = TRUE; @@ -2298,7 +2310,6 @@ static gint eti_e_cell_event (ETableItem *item, ECellView *ecell_view, GdkEvent *event, - gint time, gint model_col, gint view_col, gint row, @@ -2307,18 +2318,31 @@ eti_e_cell_event (ETableItem *item, ECellActions actions = 0; gint ret_val; - ret_val = e_cell_event (ecell_view, event, model_col, view_col, row, flags, &actions); + ret_val = e_cell_event ( + ecell_view, event, model_col, view_col, row, flags, &actions); if (actions & E_CELL_GRAB) { + GdkDevice *event_device; + guint32 event_time; + d (g_print ("%s: eti_grab\n", __FUNCTION__)); - eti_grab (item, time); + + event_device = gdk_event_get_device (event); + event_time = gdk_event_get_time (event); + eti_grab (item, event_device, event_time); + item->grabbed_col = view_col; item->grabbed_row = row; } if (actions & E_CELL_UNGRAB) { + guint32 event_time; + d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - eti_ungrab (item, time); + + event_time = gdk_event_get_time (event); + eti_ungrab (item, event_time); + item->grabbed_col = -1; item->grabbed_row = -1; } @@ -2329,10 +2353,19 @@ eti_e_cell_event (ETableItem *item, /* FIXME: cursor */ static gint eti_event (GnomeCanvasItem *item, - GdkEvent *e) + GdkEvent *event) { ETableItem *eti = E_TABLE_ITEM (item); ECellView *ecell_view; + GdkModifierType event_state = 0; + GdkEvent *event_copy; + guint event_button = 0; + guint event_keyval = 0; + gdouble event_x_item = 0; + gdouble event_y_item = 0; + gdouble event_x_win = 0; + gdouble event_y_win = 0; + guint32 event_time; gboolean return_val = TRUE; #if d(!)0 gboolean leave = FALSE; @@ -2341,37 +2374,48 @@ eti_event (GnomeCanvasItem *item, if (!eti->header) return FALSE; - switch (e->type) { + /* Don't fetch the device here. GnomeCanvas frequently emits + * synthesized events, and calling gdk_event_get_device() on them + * will trigger a runtime warning. Fetch the device where needed. */ + gdk_event_get_button (event, &event_button); + gdk_event_get_coords (event, &event_x_win, &event_y_win); + gdk_event_get_keyval (event, &event_keyval); + gdk_event_get_state (event, &event_state); + event_time = gdk_event_get_time (event); + + switch (event->type) { case GDK_BUTTON_PRESS: { gdouble x1, y1; - gdouble realx, realy; - GdkEventButton button; gint col, row; gint cursor_row, cursor_col; gint new_cursor_row, new_cursor_col; ECellFlags flags = 0; - d (g_print ("%s: GDK_BUTTON_PRESS received, button %d\n", __FUNCTION__, e->button.button)); + d (g_print ("%s: GDK_BUTTON_PRESS received, button %d\n", __FUNCTION__, event_button)); - switch (e->button.button) { + switch (event_button) { case 1: /* Fall through. */ case 2: e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (eti), TRUE); - gnome_canvas_item_w2i (item, &e->button.x, &e->button.y); - realx = e->button.x; - realy = e->button.y; + event_x_item = event_x_win; + event_y_item = event_y_win; - if (!find_cell (eti, realx, realy, &col, &row, &x1, &y1)) { + gnome_canvas_item_w2i ( + item, &event_x_item, &event_y_item); + + if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) { if (eti_editing (eti)) e_table_item_leave_edit_(eti); return TRUE; } ecell_view = eti->cell_views[col]; - button = *(GdkEventButton *) e; - button.x = x1; - button.y = y1; + + /* Clone the event and alter its position. */ + event_copy = gdk_event_copy (event); + event_copy->button.x = x1; + event_copy->button.y = y1; g_object_get ( eti->selection, @@ -2385,13 +2429,21 @@ eti_event (GnomeCanvasItem *item, flags = 0; } - return_val = eti_e_cell_event (eti, ecell_view, (GdkEvent *) &button, button.time, view_to_model_col (eti, col), col, row, flags); - if (return_val) + return_val = eti_e_cell_event ( + eti, ecell_view, event_copy, + view_to_model_col (eti, col), + col, row, flags); + if (return_val) { + gdk_event_free (event_copy); return TRUE; + } g_signal_emit ( eti, eti_signals[CLICK], 0, - row, view_to_model_col (eti, col), &button, &return_val); + row, view_to_model_col (eti, col), + event_copy, &return_val); + + gdk_event_free (event_copy); if (return_val) { eti->click_count = 0; @@ -2405,7 +2457,11 @@ eti_event (GnomeCanvasItem *item, NULL); eti->maybe_did_something = - e_selection_model_maybe_do_something (E_SELECTION_MODEL (eti->selection), view_to_model_row (eti, row), view_to_model_col (eti, col), button.state); + e_selection_model_maybe_do_something ( + E_SELECTION_MODEL (eti->selection), + view_to_model_row (eti, row), + view_to_model_col (eti, col), + event_state); g_object_get ( eti->selection, "cursor_row", &new_cursor_row, @@ -2428,39 +2484,64 @@ eti_event (GnomeCanvasItem *item, if (eti_editing (eti)) { return_val = eti_e_cell_event ( - eti, ecell_view, (GdkEvent *) &button, button.time, - view_to_model_col (eti, col), col, row, E_CELL_EDITING | E_CELL_CURSOR); + eti, ecell_view, event, + view_to_model_col (eti, col), + col, row, + E_CELL_EDITING | + E_CELL_CURSOR); if (return_val) return TRUE; } } - if (e->button.button == 1) { + if (event_button == 1) { + GdkDevice *event_device; + return_val = TRUE; + event_device = gdk_event_get_device (event); + eti->maybe_in_drag = TRUE; eti->drag_row = new_cursor_row; eti->drag_col = new_cursor_col; - eti->drag_x = realx; - eti->drag_y = realy; - eti->drag_state = e->button.state; + eti->drag_x = event_x_item; + eti->drag_y = event_y_item; + eti->drag_state = event_state; eti->grabbed = TRUE; d (g_print ("%s: eti_grab\n", __FUNCTION__)); - eti_grab (eti, e->button.time); + eti_grab (eti, event_device, event_time); } break; case 3: e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (eti), TRUE); - gnome_canvas_item_w2i (item, &e->button.x, &e->button.y); - if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1)) + + event_x_item = event_x_win; + event_y_item = event_y_win; + + gnome_canvas_item_w2i ( + item, &event_x_item, &event_y_item); + + if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) return TRUE; - e_selection_model_right_click_down (E_SELECTION_MODEL (eti->selection), view_to_model_row (eti, row), view_to_model_col (eti, col), 0); + e_selection_model_right_click_down ( + E_SELECTION_MODEL (eti->selection), + view_to_model_row (eti, row), + view_to_model_col (eti, col), 0); + + /* Clone the event and alter its position. */ + event_copy = gdk_event_copy (event); + event_copy->button.x = event_x_item; + event_copy->button.y = event_y_item; g_signal_emit ( eti, eti_signals[RIGHT_CLICK], 0, - row, view_to_model_col (eti, col), e, &return_val); + row, view_to_model_col (eti, col), + event, &return_val); + + gdk_event_free (event_copy); + if (!return_val) e_selection_model_right_click_up (E_SELECTION_MODEL (eti->selection)); break; @@ -2477,14 +2558,14 @@ eti_event (GnomeCanvasItem *item, gint col, row; gint cursor_row, cursor_col; - d (g_print ("%s: GDK_BUTTON_RELEASE received, button %d\n", __FUNCTION__, e->button.button)); + d (g_print ("%s: GDK_BUTTON_RELEASE received, button %d\n", __FUNCTION__, event_button)); if (eti->grabbed_count > 0) { d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - eti_ungrab (eti, e->button.time); + eti_ungrab (eti, event_time); } - if (e->button.button == 1) { + if (event_button == 1) { if (eti->maybe_in_drag) { eti->maybe_in_drag = FALSE; if (!eti->maybe_did_something) @@ -2495,21 +2576,28 @@ eti_event (GnomeCanvasItem *item, } } - switch (e->button.button) { + switch (event_button) { case 1: /* Fall through. */ case 2: - gnome_canvas_item_w2i (item, &e->button.x, &e->button.y); + event_x_item = event_x_win; + event_y_item = event_y_win; + + gnome_canvas_item_w2i ( + item, &event_x_item, &event_y_item); #if d(!)0 { - gboolean cell_found = find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1); + gboolean cell_found = find_cell ( + eti, event_x_item, event_y_item, + &col, &row, &x1, &y1); g_print ( - "%s: find_cell(%f, %f) = %s(%d, %d, %f, %f)\n", __FUNCTION__, e->button.x, e->button.y, + "%s: find_cell(%f, %f) = %s(%d, %d, %f, %f)\n", + __FUNCTION__, event_x_item, event_y_item, cell_found?"true":"false", col, row, x1, y1); } #endif - if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1)) + if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) return TRUE; g_object_get ( @@ -2520,20 +2608,24 @@ eti_event (GnomeCanvasItem *item, if (eti_editing (eti) && cursor_row == view_to_model_row (eti, row) && cursor_col == view_to_model_col (eti, col)) { - d (g_print ("%s: GDK_BUTTON_RELEASE received, button %d, line: %d\n", __FUNCTION__, e->button.button, __LINE__)) + d (g_print ("%s: GDK_BUTTON_RELEASE received, button %d, line: %d\n", __FUNCTION__, event_button, __LINE__)) ; ecell_view = eti->cell_views[col]; - /* - * Adjust the event positions - */ - e->button.x = x1; - e->button.y = y1; + /* Clone the event and alter its position. */ + event_copy = gdk_event_copy (event); + event_copy->button.x = x1; + event_copy->button.y = y1; return_val = eti_e_cell_event ( - eti, ecell_view, e, e->button.time, - view_to_model_col (eti, col), col, row, E_CELL_EDITING | E_CELL_CURSOR); + eti, ecell_view, event_copy, + view_to_model_col (eti, col), + col, row, + E_CELL_EDITING | + E_CELL_CURSOR); + + gdk_event_free (event_copy); } break; case 3: @@ -2554,7 +2646,7 @@ eti_event (GnomeCanvasItem *item, gdouble x1, y1; #endif - d (g_print ("%s: GDK_2BUTTON_PRESS received, button %d\n", __FUNCTION__, e->button.button)); + d (g_print ("%s: GDK_2BUTTON_PRESS received, button %d\n", __FUNCTION__, event_button)); /* * click_count is so that if you click on two @@ -2563,12 +2655,11 @@ eti_event (GnomeCanvasItem *item, if (eti->click_count >= 2) { - gnome_canvas_item_w2i (item, &e->button.x, &e->button.y); + event_x_item = event_x_win; + event_y_item = event_y_win; -#if 0 - if (!find_cell (eti, e->button.x, e->button.y, ¤t_col, ¤t_row, &x1, &y1)) - return TRUE; -#endif + gnome_canvas_item_w2i ( + item, &event_x_item, &event_y_item); g_object_get ( eti->selection, @@ -2576,10 +2667,18 @@ eti_event (GnomeCanvasItem *item, "cursor_col", &model_col, NULL); - e->button.x -= e_table_header_col_diff (eti->header, 0, model_to_view_col (eti, model_col)); - e->button.y -= e_table_item_row_diff (eti, 0, model_to_view_row (eti, model_row)); - - if (e->button.button == 1) { + /* Clone the event and alter its position. */ + event_copy = gdk_event_copy (event); + event_copy->button.x = event_x_item - + e_table_header_col_diff ( + eti->header, 0, + model_to_view_col (eti, model_col)); + event_copy->button.y = event_y_item - + e_table_item_row_diff ( + eti, 0, + model_to_view_row (eti, model_row)); + + if (event_button == 1) { if (eti->maybe_in_drag) { eti->maybe_in_drag = FALSE; if (!eti->maybe_did_something) @@ -2595,14 +2694,16 @@ eti_event (GnomeCanvasItem *item, if (eti->grabbed_count > 0) { d (g_print ("%s: eti_ungrab\n", __FUNCTION__)); - eti_ungrab (eti, e->button.time); + eti_ungrab (eti, event_time); } if (model_row != -1 && model_col != -1) { g_signal_emit ( eti, eti_signals[DOUBLE_CLICK], 0, - model_row, model_col, e); + model_row, model_col, event_copy); } + + gdk_event_free (event_copy); } break; } @@ -2611,17 +2712,31 @@ eti_event (GnomeCanvasItem *item, gdouble x1, y1; gint cursor_col, cursor_row; - gnome_canvas_item_w2i (item, &e->motion.x, &e->motion.y); + event_x_item = event_x_win; + event_y_item = event_y_win; + + gnome_canvas_item_w2i (item, &event_x_item, &event_y_item); if (eti->maybe_in_drag) { - if (abs (e->motion.x - eti->drag_x) >= 3 || - abs (e->motion.y - eti->drag_y) >= 3) { + if (abs (event_x_item - eti->drag_x) >= 3 || + abs (event_y_item - eti->drag_y) >= 3) { gboolean drag_handled; eti->maybe_in_drag = 0; + + /* Clone the event and + * alter its position. */ + event_copy = gdk_event_copy (event); + event_copy->motion.x = event_x_item; + event_copy->motion.y = event_y_item; + g_signal_emit ( eti, eti_signals[START_DRAG], 0, - eti->drag_row, eti->drag_col, e, &drag_handled); + eti->drag_row, eti->drag_col, + event_copy, &drag_handled); + + gdk_event_free (event_copy); + if (drag_handled) eti->in_drag = 1; else @@ -2629,16 +2744,16 @@ eti_event (GnomeCanvasItem *item, } } - if (!find_cell (eti, e->motion.x, e->motion.y, &col, &row, &x1, &y1)) + if (!find_cell (eti, event_x_item, event_y_item, &col, &row, &x1, &y1)) return TRUE; if (eti->motion_row != -1 && eti->motion_col != -1 && (row != eti->motion_row || col != eti->motion_col)) { GdkEvent *cross = gdk_event_new (GDK_LEAVE_NOTIFY); - cross->crossing.time = e->motion.time; + cross->crossing.time = event_time; return_val = eti_e_cell_event ( eti, eti->cell_views[eti->motion_col], - cross, cross->crossing.time, + cross, view_to_model_col (eti, eti->motion_col), eti->motion_col, eti->motion_row, 0); } @@ -2659,15 +2774,17 @@ eti_event (GnomeCanvasItem *item, ecell_view = eti->cell_views[col]; - /* - * Adjust the event positions - */ - e->motion.x = x1; - e->motion.y = y1; + /* Clone the event and alter its position. */ + event_copy = gdk_event_copy (event); + event_copy->motion.x = x1; + event_copy->motion.y = y1; return_val = eti_e_cell_event ( - eti, ecell_view, e, e->motion.time, + eti, ecell_view, event_copy, view_to_model_col (eti, col), col, row, flags); + + gdk_event_free (event_copy); + break; } @@ -2688,7 +2805,7 @@ eti_event (GnomeCanvasItem *item, eti->in_key_press = TRUE; - switch (e->key.keyval) { + switch (event_keyval) { case GDK_KEY_Left: case GDK_KEY_KP_Left: if (eti_editing (eti)) { @@ -2698,7 +2815,8 @@ eti_event (GnomeCanvasItem *item, g_signal_emit ( eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), cursor_col, e, &return_val); + model_to_view_row (eti, cursor_row), + cursor_col, event, &return_val); if ((!return_val) && (atk_get_root () || eti->cursor_mode != E_CURSOR_LINE) && cursor_col != view_to_model_col (eti, 0)) @@ -2715,7 +2833,8 @@ eti_event (GnomeCanvasItem *item, g_signal_emit ( eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), cursor_col, e, &return_val); + model_to_view_row (eti, cursor_row), + cursor_col, event, &return_val); if ((!return_val) && (atk_get_root () || eti->cursor_mode != E_CURSOR_LINE) && cursor_col != view_to_model_col (eti, eti->cols - 1)) @@ -2727,15 +2846,15 @@ eti_event (GnomeCanvasItem *item, case GDK_KEY_KP_Up: case GDK_KEY_Down: case GDK_KEY_KP_Down: - if ((e->key.state & GDK_MOD1_MASK) - && ((e->key.keyval == GDK_KEY_Down) || (e->key.keyval == GDK_KEY_KP_Down))) { + if ((event_state & GDK_MOD1_MASK) + && ((event_keyval == GDK_KEY_Down) || (event_keyval == GDK_KEY_KP_Down))) { gint view_col = model_to_view_col (eti, cursor_col); if ((view_col >= 0) && (view_col < eti->cols)) - if (eti_e_cell_event (eti, eti->cell_views[view_col], e, ((GdkEventKey *) e)->time, cursor_col, view_col, model_to_view_row (eti, cursor_row), E_CELL_CURSOR)) + if (eti_e_cell_event (eti, eti->cell_views[view_col], event, cursor_col, view_col, model_to_view_row (eti, cursor_row), E_CELL_CURSOR)) return TRUE; } else - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e); + return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); break; case GDK_KEY_Home: case GDK_KEY_KP_Home: @@ -2748,7 +2867,7 @@ eti_event (GnomeCanvasItem *item, eti_cursor_move (eti, model_to_view_row (eti, cursor_row), 0); return_val = TRUE; } else - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e); + return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); break; case GDK_KEY_End: case GDK_KEY_KP_End: @@ -2761,17 +2880,17 @@ eti_event (GnomeCanvasItem *item, eti_cursor_move (eti, model_to_view_row (eti, cursor_row), eti->cols - 1); return_val = TRUE; } else - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e); + return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); break; case GDK_KEY_Tab: case GDK_KEY_KP_Tab: case GDK_KEY_ISO_Left_Tab: - if ((e->key.state & GDK_CONTROL_MASK) != 0) { + if ((event_state & GDK_CONTROL_MASK) != 0) { return_val = FALSE; break; } if (eti->cursor_mode == E_CURSOR_SPREADSHEET) { - if ((e->key.state & GDK_SHIFT_MASK) != 0) { + if ((event_state & GDK_SHIFT_MASK) != 0) { /* shift tab */ if (cursor_col != view_to_model_col (eti, 0)) eti_cursor_move_left (eti); @@ -2811,7 +2930,7 @@ eti_event (GnomeCanvasItem *item, if (eti_editing (eti)) { ecell_view = eti->cell_views[eti->editing_col]; return_val = eti_e_cell_event ( - eti, ecell_view, e, e->key.time, + eti, ecell_view, event, view_to_model_col (eti, eti->editing_col), eti->editing_col, eti->editing_row, E_CELL_EDITING | E_CELL_CURSOR | E_CELL_PREEDIT); if (!return_val) @@ -2819,9 +2938,10 @@ eti_event (GnomeCanvasItem *item, } g_signal_emit ( eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), cursor_col, e, &return_val); + model_to_view_row (eti, cursor_row), + cursor_col, event, &return_val); if (!return_val) - return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e); + return_val = e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); break; default: @@ -2830,7 +2950,7 @@ eti_event (GnomeCanvasItem *item, } if (!handled) { - switch (e->key.keyval) { + switch (event_keyval) { case GDK_KEY_Scroll_Lock: case GDK_KEY_Sys_Req: case GDK_KEY_Shift_L: @@ -2862,17 +2982,18 @@ eti_event (GnomeCanvasItem *item, if (!eti_editing (eti)) { g_signal_emit ( eti, eti_signals[KEY_PRESS], 0, - model_to_view_row (eti, cursor_row), cursor_col, e, &return_val); + model_to_view_row (eti, cursor_row), + cursor_col, event, &return_val); if (!return_val) - e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e); + e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); } else { ecell_view = eti->cell_views[eti->editing_col]; return_val = eti_e_cell_event ( - eti, ecell_view, e, e->key.time, + eti, ecell_view, event, view_to_model_col (eti, eti->editing_col), eti->editing_col, eti->editing_row, E_CELL_EDITING | E_CELL_CURSOR); if (!return_val) - e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e); + e_selection_model_key_press (E_SELECTION_MODEL (eti->selection), (GdkEventKey *) event); } break; } @@ -2884,7 +3005,7 @@ eti_event (GnomeCanvasItem *item, case GDK_KEY_RELEASE: { gint cursor_row, cursor_col; - d (g_print ("%s: GDK_KEY_RELEASE received, keyval: %d\n", __FUNCTION__, (gint) e->key.keyval)); + d (g_print ("%s: GDK_KEY_RELEASE received, keyval: %d\n", __FUNCTION__, (gint) event_keyval)); g_object_get ( eti->selection, @@ -2898,7 +3019,7 @@ eti_event (GnomeCanvasItem *item, if (eti_editing (eti)) { ecell_view = eti->cell_views[eti->editing_col]; return_val = eti_e_cell_event ( - eti, ecell_view, e, e->key.time, + eti, ecell_view, event, view_to_model_col (eti, eti->editing_col), eti->editing_col, eti->editing_row, E_CELL_EDITING | E_CELL_CURSOR); } @@ -2912,7 +3033,7 @@ eti_event (GnomeCanvasItem *item, if (eti->motion_row != -1 && eti->motion_col != -1) return_val = eti_e_cell_event ( eti, eti->cell_views[eti->motion_col], - e, e->crossing.time, + event, view_to_model_col (eti, eti->motion_col), eti->motion_col, eti->motion_row, 0); eti->motion_row = -1; @@ -2922,7 +3043,7 @@ eti_event (GnomeCanvasItem *item, case GDK_FOCUS_CHANGE: d (g_print ("%s: GDK_FOCUS_CHANGE received, %s\n", __FUNCTION__, e->focus_change.in ? "in": "out")); - if (e->focus_change.in) { + if (event->focus_change.in) { if (eti->save_row != -1 && eti->save_col != -1 && !eti_editing (eti) && diff --git a/widgets/text/e-reflow.c b/widgets/text/e-reflow.c index 1c3b0da4fe..e8304e4b38 100644 --- a/widgets/text/e-reflow.c +++ b/widgets/text/e-reflow.c @@ -1058,6 +1058,7 @@ e_reflow_event (GnomeCanvasItem *item, item, GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, reflow->arrow_cursor, + button->device, button->time); reflow->previous_temp_column_width = -1; diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index da10bb02f9..f75c4ca8b9 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -2772,6 +2772,7 @@ e_text_command (ETextEventProcessor *tep, GNOME_CANVAS_ITEM (text), GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, text->i_cursor, + command->device, command->time, NULL, NULL); -- cgit v1.2.3