From e5a3cf5a369d4ef1431904e7552ed209c0bde6c9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 6 Nov 2011 16:22:09 +0100 Subject: [PATCH] scrolledwindow: Don't use p-a-h for the "let event go through" timeout Just use a timeout there, the press-and-hold feedback is undesirable here. --- gtk/gtkscrolledwindow.c | 143 +++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 74 deletions(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index fa9fd09a93..3e48fc987e 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -177,7 +177,7 @@ struct _GtkScrolledWindowPrivate guint button_press_id; guint motion_notify_id; guint button_release_id; - guint press_and_hold_id; + guint release_timeout_id; MotionEventList motion_events; GtkTimeline *deceleration_timeline; gdouble dx; @@ -236,11 +236,6 @@ static gboolean gtk_scrolled_window_scroll_event (GtkWidget *widge GdkEventScroll *event); static gboolean gtk_scrolled_window_button_press_event (GtkWidget *widget, GdkEvent *event); -static gboolean gtk_scrolled_window_press_and_hold (GtkWidget *widget, - GdkDevice *device, - GtkPressAndHoldAction action, - gint x, - gint y); static gboolean gtk_scrolled_window_focus (GtkWidget *widget, GtkDirectionType direction); static void gtk_scrolled_window_add (GtkContainer *container, @@ -1144,10 +1139,6 @@ gtk_scrolled_window_set_kinetic_scrolling (GtkScrolledWindow *scrolled_window, g_signal_connect (scrolled_window, "captured-event", G_CALLBACK (gtk_scrolled_window_button_press_event), NULL); - priv->press_and_hold_id = - g_signal_connect (scrolled_window, "press-and-hold", - G_CALLBACK (gtk_scrolled_window_press_and_hold), - NULL); /* Hide the scrollbars */ gtk_scrolled_window_auto_hide_scrollbars_start (scrolled_window, @@ -1185,10 +1176,10 @@ gtk_scrolled_window_set_kinetic_scrolling (GtkScrolledWindow *scrolled_window, g_signal_handler_disconnect (scrolled_window, priv->button_release_id); priv->button_release_id = 0; } - if (priv->press_and_hold_id > 0) + if (priv->release_timeout_id) { - g_signal_handler_disconnect (scrolled_window, priv->press_and_hold_id); - priv->press_and_hold_id = 0; + g_source_remove (priv->release_timeout_id); + priv->release_timeout_id = 0; } motion_event_list_clear (&priv->motion_events); if (priv->event_window) @@ -1268,10 +1259,10 @@ gtk_scrolled_window_destroy (GtkWidget *widget) g_signal_handler_disconnect (widget, priv->button_release_id); priv->button_release_id = 0; } - if (priv->press_and_hold_id > 0) + if (priv->release_timeout_id) { - g_signal_handler_disconnect (widget, priv->press_and_hold_id); - priv->press_and_hold_id = 0; + g_source_remove (priv->release_timeout_id); + priv->release_timeout_id = 0; } if (priv->button_press_event) @@ -2836,62 +2827,45 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window, } static gboolean -gtk_scrolled_window_press_and_hold (GtkWidget *widget, - GdkDevice *device, - GtkPressAndHoldAction action, - gint x, - gint y) +gtk_scrolled_window_release_captured_events (GtkScrolledWindow *scrolled_window) { - GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget); GtkScrolledWindowPrivate *priv = scrolled_window->priv; + GdkDevice *device; - switch (action) + /* Cancel the scrolling and send the button press + * event to the child widget + */ + if (!priv->button_press_event) + return FALSE; + + device = gdk_event_get_device (priv->button_press_event); + gdk_device_ungrab (device, GDK_CURRENT_TIME); + gtk_device_grab_remove (GTK_WIDGET (scrolled_window), device); + + if (priv->motion_notify_id > 0) { - case GTK_PRESS_AND_HOLD_QUERY: - return !priv->in_drag; - case GTK_PRESS_AND_HOLD_TRIGGER: - /* Cancel the scrolling and send the button press - * event to the child widget - */ - if (!priv->button_press_event || - device != gdk_event_get_device (priv->button_press_event)) - return FALSE; - - gdk_device_ungrab (device, GDK_CURRENT_TIME); - gtk_device_grab_remove (widget, device); - - if (priv->motion_notify_id > 0) - { - g_signal_handler_disconnect (scrolled_window, priv->motion_notify_id); - priv->motion_notify_id = 0; - } - if (priv->button_release_id > 0) - { - g_signal_handler_disconnect (scrolled_window, priv->button_release_id); - priv->button_release_id = 0; - } - - /* We are going to synthesize the button press event so that - * it can be handled by child widget, but we don't want to - * handle it, so block both button-press and and press-and-hold - * during this button press - */ - g_signal_handler_block (scrolled_window, priv->button_press_id); - g_signal_handler_block (scrolled_window, priv->press_and_hold_id); - - gtk_main_do_event (priv->button_press_event); - - g_signal_handler_unblock (scrolled_window, priv->button_press_id); - g_signal_handler_unblock (scrolled_window, priv->press_and_hold_id); - gdk_event_free (priv->button_press_event); - priv->button_press_event = NULL; - break; - case GTK_PRESS_AND_HOLD_CANCEL: - default: - break; + g_signal_handler_disconnect (scrolled_window, priv->motion_notify_id); + priv->motion_notify_id = 0; + } + if (priv->button_release_id > 0) + { + g_signal_handler_disconnect (scrolled_window, priv->button_release_id); + priv->button_release_id = 0; } - /* Doesn't really matter in this case */ + /* We are going to synthesize the button press event so that + * it can be handled by child widget, but we don't want to + * handle it, so block both button-press and and press-and-hold + * during this button press + */ + g_signal_handler_block (scrolled_window, priv->button_press_id); + + gtk_main_do_event (priv->button_press_event); + + g_signal_handler_unblock (scrolled_window, priv->button_press_id); + gdk_event_free (priv->button_press_event); + priv->button_press_event = NULL; + return FALSE; } @@ -2932,6 +2906,11 @@ gtk_scrolled_window_button_release_event (GtkWidget *widget, g_signal_handler_disconnect (widget, priv->button_release_id); priv->button_release_id = 0; } + if (priv->release_timeout_id) + { + g_source_remove (priv->release_timeout_id); + priv->release_timeout_id = 0; + } if (!priv->in_drag) { @@ -3007,7 +2986,14 @@ gtk_scrolled_window_motion_notify_event (GtkWidget *widget, { motion = motion_event_list_first (&priv->motion_events); if (gtk_drag_check_threshold (widget, motion->x, motion->y, event->x_root, event->y_root)) - priv->in_drag = TRUE; + { + if (priv->release_timeout_id) + { + g_source_remove (priv->release_timeout_id); + priv->release_timeout_id = 0; + } + priv->in_drag = TRUE; + } else return FALSE; } @@ -3045,7 +3031,7 @@ gtk_scrolled_window_motion_notify_event (GtkWidget *widget, motion->y = event->y_root; g_get_current_time (&motion->time); - return TRUE; + return FALSE; } static gboolean @@ -3061,6 +3047,7 @@ gtk_scrolled_window_button_press_event (GtkWidget *widget, GdkEventButton *event; GdkDevice *device, *source_device; GdkInputSource source; + guint timeout; if (_event->type != GDK_BUTTON_PRESS) return FALSE; @@ -3121,14 +3108,22 @@ gtk_scrolled_window_button_press_event (GtkWidget *widget, priv->deceleration_timeline = NULL; } + g_object_get (gtk_widget_get_settings (GTK_WIDGET (widget)), + "gtk-press-and-hold-timeout", &timeout, + NULL); + priv->motion_notify_id = - g_signal_connect (widget, "captured-event", - G_CALLBACK (gtk_scrolled_window_motion_notify_event), - NULL); + g_signal_connect (widget, "captured-event", + G_CALLBACK (gtk_scrolled_window_motion_notify_event), + NULL); priv->button_release_id = - g_signal_connect (widget, "captured-event", - G_CALLBACK (gtk_scrolled_window_button_release_event), - NULL); + g_signal_connect (widget, "captured-event", + G_CALLBACK (gtk_scrolled_window_button_release_event), + NULL); + priv->release_timeout_id = + gdk_threads_add_timeout (timeout, + (GSourceFunc) gtk_scrolled_window_release_captured_events, + scrolled_window); gtk_scrolled_window_auto_hide_scrollbars_stop (scrolled_window); if (priv->vscrollbar_visible && !gtk_widget_get_visible (priv->vscrollbar))