Compare commits

...

4 Commits

Author SHA1 Message Date
Matthias Clasen
e07f3d6e64 spin button: Listen for ::cancel on gestures
Otherwise, we keep spinning when we should stop.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1861
2019-05-02 19:15:37 +00:00
Matthias Clasen
b844778b5b widget: Update controllers responsiveness
Make controllers unresponsive when their
widget is insensitive. This is the expected
behavior.
2019-05-02 19:15:37 +00:00
Matthias Clasen
fca0f649a0 gesture: Chain up in filter_event
This is the right thing to do.
We want to exclude more events.
2019-05-02 19:15:37 +00:00
Matthias Clasen
da034390f2 event controller: Add a ::responsive property
This lets us 'mute' controllers, for example
when widgets are insensitive. For now, we make
this property readonly and only let GTK itself
update it.
2019-05-02 19:15:37 +00:00
7 changed files with 104 additions and 2 deletions

View File

@@ -6514,6 +6514,7 @@ GtkEventController
GtkPropagationPhase
gtk_event_controller_get_propagation_phase
gtk_event_controller_set_propagation_phase
gtk_event_controller_get_responsive
gtk_event_controller_handle_event
gtk_event_controller_get_widget
gtk_event_controller_reset

View File

@@ -43,6 +43,7 @@ typedef struct _GtkEventControllerPrivate GtkEventControllerPrivate;
enum {
PROP_WIDGET = 1,
PROP_PROPAGATION_PHASE,
PROP_RESPONSIVE,
LAST_PROP
};
@@ -52,6 +53,7 @@ struct _GtkEventControllerPrivate
{
GtkWidget *widget;
GtkPropagationPhase phase;
gboolean responsive;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkEventController, gtk_event_controller, G_TYPE_OBJECT)
@@ -63,6 +65,7 @@ gtk_event_controller_set_widget (GtkEventController *self,
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
priv->widget = widget;
priv->responsive = gtk_widget_get_sensitive (widget);
}
static void
@@ -71,6 +74,16 @@ gtk_event_controller_unset_widget (GtkEventController *self)
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
priv->widget = NULL;
priv->responsive = TRUE;
}
static gboolean
gtk_event_controller_filter_event_default (GtkEventController *self,
const GdkEvent *event)
{
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
return !priv->responsive;
}
static gboolean
@@ -116,6 +129,9 @@ gtk_event_controller_get_property (GObject *object,
case PROP_PROPAGATION_PHASE:
g_value_set_enum (value, priv->phase);
break;
case PROP_RESPONSIVE:
g_value_set_enum (value, priv->responsive);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -128,7 +144,7 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
klass->set_widget = gtk_event_controller_set_widget;
klass->unset_widget = gtk_event_controller_unset_widget;
klass->filter_event = gtk_event_controller_handle_event_default;
klass->filter_event = gtk_event_controller_filter_event_default;
klass->handle_event = gtk_event_controller_handle_event_default;
object_class->set_property = gtk_event_controller_set_property;
@@ -158,6 +174,21 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
GTK_PHASE_BUBBLE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkEventController:responsive:
*
* Whether the controller handles events.
*
* GTK sets event controllers to be not responsive
* when the widget they are attached to becomes insensitive.
*/
properties[PROP_RESPONSIVE] =
g_param_spec_boolean ("responsive",
P_("Responsive"),
P_("Whether the controller is reponsive"),
TRUE,
GTK_PARAM_READABLE);
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
@@ -168,6 +199,7 @@ gtk_event_controller_init (GtkEventController *controller)
priv = gtk_event_controller_get_instance_private (controller);
priv->phase = GTK_PHASE_BUBBLE;
priv->responsive = TRUE;
}
/**
@@ -299,3 +331,44 @@ gtk_event_controller_set_propagation_phase (GtkEventController *controller,
g_object_notify_by_pspec (G_OBJECT (controller), properties[PROP_PROPAGATION_PHASE]);
}
void
gtk_event_controller_set_responsive (GtkEventController *controller,
gboolean responsive)
{
GtkEventControllerPrivate *priv;
g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
priv = gtk_event_controller_get_instance_private (controller);
if (priv->responsive == responsive)
return;
priv->responsive = responsive;
if (!responsive)
gtk_event_controller_reset (controller);
g_object_notify_by_pspec (G_OBJECT (controller), properties[PROP_RESPONSIVE]);
}
/**
* gtk_event_controller_get_responsive:
* @controller: a #GtkEventController
*
* Returns whether the controller is currently responsive.
*
* Returns: %TRUE if @controller is responsive
*/
gboolean
gtk_event_controller_get_responsive (GtkEventController *controller)
{
GtkEventControllerPrivate *priv;
g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), TRUE);
priv = gtk_event_controller_get_instance_private (controller);
return priv->responsive;
}

View File

@@ -59,6 +59,9 @@ GDK_AVAILABLE_IN_ALL
void gtk_event_controller_set_propagation_phase (GtkEventController *controller,
GtkPropagationPhase phase);
GDK_AVAILABLE_IN_ALL
gboolean gtk_event_controller_get_responsive (GtkEventController *controller);
G_END_DECLS
#endif /* __GTK_EVENT_CONTROLLER_H__ */

View File

@@ -48,4 +48,8 @@ struct _GtkEventControllerClass
gpointer padding[10];
};
void
gtk_event_controller_set_responsive (GtkEventController *controller,
gboolean responsive);
#endif /* __GTK_EVENT_CONTROLLER_PRIVATE_H__ */

View File

@@ -628,7 +628,10 @@ gtk_gesture_filter_event (GtkEventController *controller,
* subclasses which punch the holes in for the events
* they can possibly handle.
*/
return EVENT_IS_TOUCHPAD_GESTURE (event);
if (EVENT_IS_TOUCHPAD_GESTURE (event))
return FALSE;
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_parent_class)->filter_event (controller, event);
}
static gboolean

View File

@@ -809,6 +809,14 @@ button_released_cb (GtkGestureMultiPress *gesture,
}
}
static void
button_cancel_cb (GtkGesture *gesture,
GdkEventSequence *sequence,
GtkSpinButton *spin_button)
{
gtk_spin_button_stop_spinning (spin_button);
}
static void
key_controller_key_released (GtkEventControllerKey *key,
guint keyval,
@@ -886,6 +894,7 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
GTK_PHASE_CAPTURE);
g_signal_connect (gesture, "pressed", G_CALLBACK (button_pressed_cb), spin_button);
g_signal_connect (gesture, "released", G_CALLBACK (button_released_cb), spin_button);
g_signal_connect (gesture, "cancel", G_CALLBACK (button_cancel_cb), spin_button);
gtk_widget_add_controller (GTK_WIDGET (priv->down_button), GTK_EVENT_CONTROLLER (gesture));
priv->up_button = gtk_button_new ();
@@ -902,6 +911,7 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
GTK_PHASE_CAPTURE);
g_signal_connect (gesture, "pressed", G_CALLBACK (button_pressed_cb), spin_button);
g_signal_connect (gesture, "released", G_CALLBACK (button_released_cb), spin_button);
g_signal_connect (gesture, "cancel", G_CALLBACK (button_cancel_cb), spin_button);
gtk_widget_add_controller (GTK_WIDGET (priv->up_button), GTK_EVENT_CONTROLLER (gesture));
gtk_spin_button_set_adjustment (spin_button, NULL);

View File

@@ -6363,6 +6363,7 @@ gtk_widget_set_sensitive (GtkWidget *widget,
gboolean sensitive)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GList *l;
g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -6373,6 +6374,13 @@ gtk_widget_set_sensitive (GtkWidget *widget,
priv->sensitive = sensitive;
for (l = priv->event_controllers; l; l = l->next)
{
GtkEventController *controller = l->data;
gtk_event_controller_set_responsive (controller, sensitive);
}
if (priv->parent == NULL
|| gtk_widget_is_sensitive (priv->parent))
{