diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2012-11-30 23:39:03 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2012-12-01 00:30:10 +0800 |
commit | 2ce2f8c27698e6122c6a2687f710a18bb4ca602b (patch) | |
tree | c6e835126b3802f66e4ff6a8b5f480cb397eb487 /calendar/gui/e-calendar-view.c | |
parent | ab3f65a15e1b6fe5bdf488e6e879899e283ccc43 (diff) | |
download | gsoc2013-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/gui/e-calendar-view.c')
-rw-r--r-- | calendar/gui/e-calendar-view.c | 71 |
1 files changed, 66 insertions, 5 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); |