[gthumb] time selector: fixed pointer and keyboard grab
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] time selector: fixed pointer and keyboard grab
- Date: Sat, 9 Nov 2013 20:13:08 +0000 (UTC)
commit 0b2b92e5c14e49f8040035117e5b9f60177a4004
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Nov 9 19:29:51 2013 +0100
time selector: fixed pointer and keyboard grab
gthumb/gth-time-selector.c | 157 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 141 insertions(+), 16 deletions(-)
---
diff --git a/gthumb/gth-time-selector.c b/gthumb/gth-time-selector.c
index 4f7c142..4b7c619 100644
--- a/gthumb/gth-time-selector.c
+++ b/gthumb/gth-time-selector.c
@@ -50,6 +50,8 @@ struct _GthTimeSelectorPrivate
gboolean use_time;
gboolean optional_time;
gulong day_selected_event;
+ GdkDevice *grab_pointer;
+ GdkDevice *grab_keyboard;
};
@@ -74,15 +76,36 @@ gth_time_selector_finalize (GObject *object)
static void
+_gth_time_selector_ungrab_devices (GthTimeSelector *self,
+ guint32 time);
+
+
+static void
+gth_time_selector_unmap (GtkWidget *widget)
+{
+ GthTimeSelector *self;
+
+ self = GTH_TIME_SELECTOR (widget);
+ _gth_time_selector_ungrab_devices (self, GDK_CURRENT_TIME);
+
+ GTK_WIDGET_CLASS (gth_time_selector_parent_class)->unmap (widget);
+}
+
+
+static void
gth_time_selector_class_init (GthTimeSelectorClass *class)
{
- GObjectClass *object_class;
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
g_type_class_add_private (class, sizeof (GthTimeSelectorPrivate));
object_class = (GObjectClass*) class;
object_class->finalize = gth_time_selector_finalize;
+ widget_class = (GtkWidgetClass *) class;
+ widget_class->unmap = gth_time_selector_unmap;
+
gth_time_selector_signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (class),
@@ -101,23 +124,94 @@ gth_time_selector_init (GthTimeSelector *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TIME_SELECTOR, GthTimeSelectorPrivate);
self->priv->date_time = gth_datetime_new ();
self->priv->use_time = TRUE;
+ self->priv->grab_pointer = NULL;
+ self->priv->grab_keyboard = NULL;
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
}
static void
+_gth_time_selector_ungrab_devices (GthTimeSelector *self,
+ guint32 time)
+{
+ if (self->priv->grab_pointer != NULL) {
+ gdk_device_ungrab (self->priv->grab_pointer, time);
+ gtk_device_grab_remove (self->priv->calendar_popup, self->priv->grab_pointer);
+ self->priv->grab_pointer = NULL;
+ }
+
+ if (self->priv->grab_keyboard != NULL) {
+ gdk_device_ungrab (self->priv->grab_keyboard, time);
+ self->priv->grab_keyboard = NULL;
+ }
+}
+
+
+static gboolean
+_gth_time_selector_grab_broken_event (GtkWidget *widget,
+ GdkEventGrabBroken *event,
+ gpointer user_data)
+{
+ GthTimeSelector *self = user_data;
+
+ if (event->grab_window == NULL)
+ _gth_time_selector_ungrab_devices (self, GDK_CURRENT_TIME);
+
+ return TRUE;
+}
+
+
+static void
hide_calendar_popup (GthTimeSelector *self)
{
- gtk_grab_remove (self->priv->calendar_popup);
- gdk_device_ungrab (gdk_device_manager_get_client_pointer (gdk_display_get_device_manager
(gdk_window_get_display (gtk_widget_get_window (self->priv->calendar_popup)))),
- GDK_CURRENT_TIME);
- gtk_widget_hide (self->priv->calendar_popup);
+ _gth_time_selector_ungrab_devices (self, GDK_CURRENT_TIME);
+ gtk_widget_hide (self->priv->calendar_popup);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->calendar_button), FALSE);
}
+static gboolean
+_gth_time_selector_grab_devices (GdkWindow *window,
+ GdkDevice *keyboard,
+ GdkDevice *pointer,
+ GdkCursor *cursor,
+ guint32 time)
+{
+ if (keyboard != NULL) {
+ if (gdk_device_grab (keyboard,
+ window,
+ GDK_OWNERSHIP_APPLICATION,
+ TRUE,
+ (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK),
+ NULL,
+ time) != GDK_GRAB_SUCCESS)
+ {
+ return FALSE;
+ }
+ }
+
+ if (pointer != NULL) {
+ if (gdk_device_grab (pointer,
+ window,
+ GDK_OWNERSHIP_APPLICATION,
+ TRUE,
+ GDK_ALL_EVENTS_MASK,
+ cursor,
+ time) != GDK_GRAB_SUCCESS)
+ {
+ if (keyboard != NULL)
+ gdk_device_ungrab (keyboard, time);
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
static void
show_calendar_popup (GthTimeSelector *self)
{
@@ -129,6 +223,9 @@ show_calendar_popup (GthTimeSelector *self)
GdkScreen *screen;
gint monitor_num;
cairo_rectangle_int_t monitor;
+ GdkDevice *device;
+ GdkDevice *pointer;
+ GdkDevice *keyboard;
gtk_widget_get_preferred_size (self->priv->popup_box, &popup_req, NULL);
@@ -156,18 +253,46 @@ show_calendar_popup (GthTimeSelector *self)
gtk_window_move (GTK_WINDOW (self->priv->calendar_popup), x, y);
gtk_widget_show (self->priv->calendar_popup);
- gtk_grab_add (self->priv->calendar_popup);
- gdk_device_grab (gdk_device_manager_get_client_pointer (gdk_display_get_device_manager
(gdk_window_get_display (gtk_widget_get_window (self->priv->calendar_popup)))),
- gtk_widget_get_window (self->priv->calendar_popup),
- GDK_OWNERSHIP_WINDOW,
- TRUE,
- (GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON_MOTION_MASK),
- NULL,
- GDK_CURRENT_TIME);
+ device = gtk_get_current_event_device ();
+ if (device == NULL) {
+ GdkDeviceManager *device_manager;
+ GdkDisplay *display;
+ GList *devices;
+
+ display = gtk_widget_get_display (GTK_WIDGET (self));
+ device_manager = gdk_display_get_device_manager (display);
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+ device = devices->data;
+
+ g_list_free (devices);
+ }
+
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) {
+ keyboard = device;
+ pointer = gdk_device_get_associated_device (device);
+ }
+ else {
+ pointer = device;
+ keyboard = gdk_device_get_associated_device (device);
+ }
+
gtk_widget_grab_focus (self->priv->calendar);
+
+ if (_gth_time_selector_grab_devices (gtk_widget_get_window (self->priv->calendar_popup),
+ keyboard,
+ pointer,
+ NULL,
+ GDK_CURRENT_TIME))
+ {
+ self->priv->grab_pointer = pointer;
+ self->priv->grab_keyboard = keyboard;
+ gtk_device_grab_add (self->priv->calendar_popup, self->priv->grab_pointer, TRUE);
+
+ g_signal_connect (self,
+ "grab-broken-event",
+ G_CALLBACK (_gth_time_selector_grab_broken_event),
+ self);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]