aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2012-11-30 23:39:03 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-12-01 00:30:10 +0800
commit2ce2f8c27698e6122c6a2687f710a18bb4ca602b (patch)
treec6e835126b3802f66e4ff6a8b5f480cb397eb487 /calendar
parentab3f65a15e1b6fe5bdf488e6e879899e283ccc43 (diff)
downloadgsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.tar
gsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.tar.gz
gsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.tar.bz2
gsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.tar.lz
gsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.tar.xz
gsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.tar.zst
gsoc2013-evolution-2ce2f8c27698e6122c6a2687f710a18bb4ca602b.zip
Avoid gdk_keyboard_grab/ungrab() and gdk_pointer_grab/ungrab().
Use gdk_device_grab() and gdk_device_ungrab() instead. In some cases this requires stashing the grabbed device so it can be ungrabbed outside of an GdkEvent handler.
Diffstat (limited to 'calendar')
-rw-r--r--calendar/gui/e-calendar-view.c71
-rw-r--r--calendar/gui/e-day-view-time-item.c29
-rw-r--r--calendar/gui/e-day-view.c44
-rw-r--r--calendar/gui/e-day-view.h3
4 files changed, 132 insertions, 15 deletions
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index bbf890af59..9c21a18739 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -76,6 +76,10 @@ struct _ECalendarViewPrivate {
GtkTargetList *copy_target_list;
GtkTargetList *paste_target_list;
+
+ /* All keyboard devices are grabbed
+ * while a tooltip window is shown. */
+ GQueue grabbed_keyboards;
};
enum {
@@ -353,6 +357,13 @@ calendar_view_dispose (GObject *object)
priv->selected_cut_list = NULL;
}
+ while (!g_queue_is_empty (&priv->grabbed_keyboards)) {
+ GdkDevice *keyboard;
+ keyboard = g_queue_pop_head (&priv->grabbed_keyboards);
+ gdk_device_ungrab (keyboard, GDK_CURRENT_TIME);
+ g_object_unref (keyboard);
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object);
}
@@ -1833,15 +1844,25 @@ e_calendar_view_modify_and_send (ECalendarView *cal_view,
static gboolean
tooltip_grab (GtkWidget *tooltip,
- GdkEventKey *event,
+ GdkEvent *key_event,
ECalendarView *view)
{
- GtkWidget *widget = (GtkWidget *) g_object_get_data (G_OBJECT (view), "tooltip-window");
+ GtkWidget *widget;
+ GdkDevice *keyboard;
+ guint32 event_time;
- if (!widget)
+ widget = g_object_get_data (G_OBJECT (view), "tooltip-window");
+ if (widget == NULL)
return TRUE;
- gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ event_time = gdk_event_get_time (key_event);
+
+ while (!g_queue_is_empty (&view->priv->grabbed_keyboards)) {
+ keyboard = g_queue_pop_head (&view->priv->grabbed_keyboards);
+ gdk_device_ungrab (keyboard, event_time);
+ g_object_unref (keyboard);
+ }
+
gtk_widget_destroy (widget);
g_object_set_data (G_OBJECT (view), "tooltip-window", NULL);
@@ -1927,10 +1948,14 @@ e_calendar_view_get_tooltips (const ECalendarViewEventData *data)
GtkStyle *style = gtk_widget_get_default_style ();
GtkWidget *widget;
GdkWindow *window;
+ GdkDisplay *display;
+ GdkDeviceManager *device_manager;
+ GQueue *grabbed_keyboards;
ECalComponent *newcomp = e_cal_component_new ();
icaltimezone *zone, *default_zone;
ECalModel *model;
ECalClient *client = NULL;
+ GList *list, *link;
gboolean free_text = FALSE;
/* This function is a timeout callback. */
@@ -2099,8 +2124,44 @@ e_calendar_view_get_tooltips (const ECalendarViewEventData *data)
e_calendar_view_move_tip (pevent->tooltip, pevent->x +16, pevent->y + 16);
+ /* Grab all keyboard devices. A key press from
+ * any of them will dismiss the tooltip window. */
+
window = gtk_widget_get_window (pevent->tooltip);
- gdk_keyboard_grab (window, FALSE, GDK_CURRENT_TIME);
+ display = gdk_window_get_display (window);
+ device_manager = gdk_display_get_device_manager (display);
+
+ grabbed_keyboards = &data->cal_view->priv->grabbed_keyboards;
+ g_warn_if_fail (g_queue_is_empty (grabbed_keyboards));
+
+ list = gdk_device_manager_list_devices (
+ device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ GdkDevice *device = GDK_DEVICE (link->data);
+ GdkGrabStatus grab_status;
+
+ if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
+ continue;
+
+ grab_status = gdk_device_grab (
+ device,
+ window,
+ GDK_OWNERSHIP_NONE,
+ FALSE,
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK,
+ NULL,
+ GDK_CURRENT_TIME);
+
+ if (grab_status == GDK_GRAB_SUCCESS)
+ g_queue_push_tail (
+ grabbed_keyboards,
+ g_object_ref (device));
+ }
+
+ g_list_free (list);
+
g_signal_connect (
pevent->tooltip, "key-press-event",
G_CALLBACK (tooltip_grab), data->cal_view);
diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c
index 3a8284be03..f337aa06e1 100644
--- a/calendar/gui/e-day-view-time-item.c
+++ b/calendar/gui/e-day-view-time-item.c
@@ -908,6 +908,9 @@ e_day_view_time_item_on_button_press (EDayViewTimeItem *time_item,
GdkWindow *window;
EDayView *day_view;
GnomeCanvas *canvas;
+ GdkGrabStatus grab_status;
+ GdkDevice *event_device;
+ guint32 event_time;
gint row;
day_view = e_day_view_time_item_get_day_view (time_item);
@@ -927,10 +930,20 @@ e_day_view_time_item_on_button_press (EDayViewTimeItem *time_item,
window = gtk_layout_get_bin_window (GTK_LAYOUT (canvas));
- if (gdk_pointer_grab (window, FALSE,
- GDK_POINTER_MOTION_MASK
- | GDK_BUTTON_RELEASE_MASK,
- NULL, NULL, event->button.time) == 0) {
+ event_device = gdk_event_get_device (event);
+ event_time = gdk_event_get_time (event);
+
+ grab_status = gdk_device_grab (
+ event_device,
+ window,
+ GDK_OWNERSHIP_NONE,
+ FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL,
+ event_time);
+
+ if (grab_status == GDK_GRAB_SUCCESS) {
e_day_view_start_selection (day_view, -1, row);
time_item->priv->dragging_selection = TRUE;
}
@@ -946,7 +959,13 @@ e_day_view_time_item_on_button_release (EDayViewTimeItem *time_item,
g_return_if_fail (day_view != NULL);
if (time_item->priv->dragging_selection) {
- gdk_pointer_ungrab (event->button.time);
+ GdkDevice *event_device;
+ guint32 event_time;
+
+ event_device = gdk_event_get_device (event);
+ event_time = gdk_event_get_time (event);
+ gdk_device_ungrab (event_device, event_time);
+
e_day_view_finish_selection (day_view);
e_day_view_stop_auto_scroll (day_view);
}
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 0f0448d3df..db4557cbff 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -1394,6 +1394,14 @@ e_day_view_dispose (GObject *object)
}
}
+ if (day_view->grabbed_pointer != NULL) {
+ gdk_device_ungrab (
+ day_view->grabbed_pointer,
+ GDK_CURRENT_TIME);
+ g_object_unref (day_view->grabbed_pointer);
+ day_view->grabbed_pointer = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_day_view_parent_class)->dispose (object);
}
@@ -3184,6 +3192,9 @@ e_day_view_on_top_canvas_button_press (GtkWidget *widget,
event_time);
if (grab_status == GDK_GRAB_SUCCESS) {
+ g_warn_if_fail (day_view->grabbed_pointer == NULL);
+ day_view->grabbed_pointer = g_object_ref (event_device);
+
if (event_time - day_view->bc_event_time > 250)
e_day_view_get_selected_time_range (
E_CALENDAR_VIEW (day_view),
@@ -3345,6 +3356,9 @@ e_day_view_on_main_canvas_button_press (GtkWidget *widget,
event_time);
if (grab_status == GDK_GRAB_SUCCESS) {
+ g_warn_if_fail (day_view->grabbed_pointer == NULL);
+ day_view->grabbed_pointer = g_object_ref (event_device);
+
if (event_time - day_view->bc_event_time > 250)
e_day_view_get_selected_time_range (
E_CALENDAR_VIEW (day_view),
@@ -3618,6 +3632,9 @@ e_day_view_on_long_event_click (EDayView *day_view,
event_time);
if (grab_status == GDK_GRAB_SUCCESS) {
+ g_warn_if_fail (day_view->grabbed_pointer == NULL);
+ day_view->grabbed_pointer = g_object_ref (event_device);
+
day_view->resize_event_day = E_DAY_VIEW_LONG_EVENT;
day_view->resize_event_num = event_num;
day_view->resize_drag_pos = pos;
@@ -3717,6 +3734,9 @@ e_day_view_on_event_click (EDayView *day_view,
event_time);
if (grab_status == GDK_GRAB_SUCCESS) {
+ g_warn_if_fail (day_view->grabbed_pointer == NULL);
+ day_view->grabbed_pointer = g_object_ref (event_device);
+
day_view->resize_event_day = day;
day_view->resize_event_num = event_num;
day_view->resize_drag_pos = pos;
@@ -3907,11 +3927,15 @@ e_day_view_on_top_canvas_button_release (GtkWidget *widget,
event_device = gdk_event_get_device (button_event);
event_time = gdk_event_get_time (button_event);
+ if (day_view->grabbed_pointer == event_device) {
+ gdk_device_ungrab (day_view->grabbed_pointer, event_time);
+ g_object_unref (day_view->grabbed_pointer);
+ day_view->grabbed_pointer = NULL;
+ }
+
if (day_view->selection_is_being_dragged) {
- gdk_device_ungrab (event_device, event_time);
e_day_view_finish_selection (day_view);
} else if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE) {
- gdk_device_ungrab (event_device, event_time);
e_day_view_finish_long_event_resize (day_view);
} else if (day_view->pressed_event_day != -1) {
e_day_view_start_editing_event (
@@ -3937,12 +3961,16 @@ e_day_view_on_main_canvas_button_release (GtkWidget *widget,
event_device = gdk_event_get_device (button_event);
event_time = gdk_event_get_time (button_event);
+ if (day_view->grabbed_pointer == event_device) {
+ gdk_device_ungrab (day_view->grabbed_pointer, event_time);
+ g_object_unref (day_view->grabbed_pointer);
+ day_view->grabbed_pointer = NULL;
+ }
+
if (day_view->selection_is_being_dragged) {
- gdk_device_ungrab (event_device, event_time);
e_day_view_finish_selection (day_view);
e_day_view_stop_auto_scroll (day_view);
} else if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE) {
- gdk_device_ungrab (event_device, event_time);
e_day_view_finish_resize (day_view);
e_day_view_stop_auto_scroll (day_view);
} else if (day_view->pressed_event_day != -1) {
@@ -5403,7 +5431,13 @@ e_day_view_do_key_press (GtkWidget *widget,
/* The Escape key aborts a resize operation. */
if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE) {
if (keyval == GDK_KEY_Escape) {
- gdk_pointer_ungrab (event->time);
+ if (day_view->grabbed_pointer != NULL) {
+ gdk_device_ungrab (
+ day_view->grabbed_pointer,
+ event->time);
+ g_object_unref (day_view->grabbed_pointer);
+ day_view->grabbed_pointer = NULL;
+ }
e_day_view_abort_resize (day_view);
}
return FALSE;
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index 9f43a1ad78..5bf8974b69 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -459,6 +459,9 @@ struct _EDayView {
GnomeCanvasItem *drag_bar_item;
GnomeCanvasItem *drag_item;
+ /* Grabbed pointer device while dragging. */
+ GdkDevice *grabbed_pointer;
+
/* "am" and "pm" in the current locale, and their widths. */
gchar *am_string;
gchar *pm_string;