[gthumb] image overview: fixed pointer grub
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] image overview: fixed pointer grub
- Date: Sat, 9 Nov 2013 20:13:13 +0000 (UTC)
commit 60c7ea0395b9db6b8a0f7d8a185137af8e8aebf0
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Nov 9 19:30:26 2013 +0100
image overview: fixed pointer grub
gthumb/gth-image-overview.c | 155 ++++++++++++++++++++++++++++++++++++++-----
1 files changed, 139 insertions(+), 16 deletions(-)
---
diff --git a/gthumb/gth-image-overview.c b/gthumb/gth-image-overview.c
index 9ee328b..39ddc05 100644
--- a/gthumb/gth-image-overview.c
+++ b/gthumb/gth-image-overview.c
@@ -59,6 +59,8 @@ struct _GthImageOverviewPrivate {
gulong hadj_changed_id;
gboolean scrolling_active;
gboolean update_preview;
+ GdkDevice *grab_pointer;
+ GdkDevice *grab_keyboard;
};
@@ -366,7 +368,9 @@ gth_image_overview_realize (GtkWidget *widget)
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK
| GDK_BUTTON_MOTION_MASK
- | GDK_SCROLL_MASK);
+ | GDK_SCROLL_MASK
+ | GDK_KEY_PRESS_MASK
+ | GDK_KEY_RELEASE_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
gtk_widget_register_window (widget, window);
@@ -376,6 +380,23 @@ gth_image_overview_realize (GtkWidget *widget)
static void
+_gth_image_overview_ungrab_devices (GthImageOverview *self,
+ guint32 time);
+
+
+static void
+gth_image_overview_unmap (GtkWidget *widget)
+{
+ GthImageOverview *self;
+
+ self = GTH_IMAGE_OVERVIEW (widget);
+ _gth_image_overview_ungrab_devices (self, GDK_CURRENT_TIME);
+
+ GTK_WIDGET_CLASS (gth_image_overview_parent_class)->unmap (widget);
+}
+
+
+static void
gth_image_overview_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
@@ -597,6 +618,7 @@ gth_image_overview_class_init (GthImageOverviewClass *klass)
widget_class = (GtkWidgetClass *) klass;
widget_class->realize = gth_image_overview_realize;
+ widget_class->unmap = gth_image_overview_unmap;
widget_class->size_allocate = gth_image_overview_size_allocate;
widget_class->draw = gth_image_overview_draw;
widget_class->button_press_event = gth_image_overview_button_press_event;
@@ -652,6 +674,11 @@ gth_image_overview_init (GthImageOverview *self)
self->priv->hadj_changed_id = 0;
self->priv->scrolling_active = FALSE;
self->priv->update_preview = TRUE;
+ self->priv->grab_pointer = NULL;
+ self->priv->grab_keyboard = NULL;
+
+ gtk_widget_set_has_window (GTK_WIDGET (self), TRUE);
+ gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
g_signal_connect (self, "notify::visible", G_CALLBACK (notify_visible_cb), NULL);
@@ -699,6 +726,78 @@ gth_image_overview_get_visible_area (GthImageOverview *self,
}
+static gboolean
+_gth_image_overview_grab_devices (GthImageOverview *self,
+ GdkDevice *keyboard,
+ GdkDevice *pointer,
+ GdkCursor *cursor,
+ guint32 time)
+{
+ if (keyboard != NULL) {
+ if (gdk_device_grab (keyboard,
+ gtk_widget_get_window (GTK_WIDGET (self)),
+ GDK_OWNERSHIP_WINDOW,
+ FALSE,
+ (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK),
+ NULL,
+ time) != GDK_GRAB_SUCCESS)
+ {
+ return FALSE;
+ }
+ }
+
+ if (pointer != NULL) {
+ if (gdk_device_grab (pointer,
+ gtk_widget_get_window (GTK_WIDGET (self)),
+ GDK_OWNERSHIP_WINDOW,
+ FALSE,
+ (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK),
+ cursor,
+ time) != GDK_GRAB_SUCCESS)
+ {
+ if (keyboard != NULL)
+ gdk_device_ungrab (keyboard, time);
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static void
+_gth_image_overview_ungrab_devices (GthImageOverview *self,
+ guint32 time)
+{
+ if (self->priv->grab_pointer != NULL) {
+ gdk_device_ungrab (self->priv->grab_pointer, time);
+ gtk_device_grab_remove (GTK_WIDGET (self), 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;
+ }
+
+ self->priv->scrolling_active = FALSE;
+}
+
+
+static gboolean
+_gth_image_overview_grab_broken_event (GtkWidget *widget,
+ GdkEventGrabBroken *event,
+ gpointer user_data)
+{
+ GthImageOverview *self = user_data;
+
+ if (event->grab_window == NULL)
+ _gth_image_overview_ungrab_devices (self, GDK_CURRENT_TIME);
+
+ return TRUE;
+}
+
+
void
gth_image_overview_activate_scrolling (GthImageOverview *self,
gboolean active,
@@ -706,30 +805,54 @@ gth_image_overview_activate_scrolling (GthImageOverview *self,
{
g_return_if_fail (event != NULL);
+ if (! gtk_widget_get_realized (GTK_WIDGET (self)))
+ return;
+
if (active && ! self->priv->scrolling_active) {
+ GdkDevice *device;
+ GdkDevice *pointer;
+ GdkDevice *keyboard;
GdkCursor *cursor;
- gtk_widget_realize (GTK_WIDGET (self));
- gtk_grab_add (GTK_WIDGET (self));
+ if ((self->priv->grab_pointer != NULL) || (self->priv->grab_keyboard != NULL))
+ return;
+
+ gtk_widget_grab_focus (GTK_WIDGET (self));
/* capture mouse events */
+ device = gdk_event_get_device ((GdkEvent *) event);
+ 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);
+ }
+
cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET
(self->priv->viewer)), GDK_FLEUR);
- gdk_device_grab (gdk_event_get_device ((GdkEvent *) event),
- gtk_widget_get_window (GTK_WIDGET (self)),
- GDK_OWNERSHIP_WINDOW,
- FALSE,
- GDK_ALL_EVENTS_MASK,
- cursor,
- event->time);
- g_object_unref (cursor);
- gtk_widget_grab_focus (GTK_WIDGET (self));
- }
- else if (! active && self->priv->scrolling_active) {
- gdk_device_ungrab (gdk_event_get_device ((GdkEvent *) event), event->time);
- gtk_grab_remove (GTK_WIDGET (self));
+ if (_gth_image_overview_grab_devices (self,
+ keyboard,
+ pointer,
+ cursor,
+ event->time))
+ {
+ self->priv->grab_pointer = pointer;
+ self->priv->grab_keyboard = keyboard;
+ gtk_device_grab_add (GTK_WIDGET (self), self->priv->grab_pointer, TRUE);
+
+ g_signal_connect (self,
+ "grab-broken-event",
+ G_CALLBACK (_gth_image_overview_grab_broken_event),
+ self);
+ }
+
+ g_object_unref (cursor);
}
+ else if (! active && self->priv->scrolling_active)
+ _gth_image_overview_ungrab_devices (self, event->time);
self->priv->scrolling_active = active;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]