st/widget: Fix applying :insensitive to initially unreactive widgets

We are applying the :insensitive pseudo class to unreactive widgets,
or at least we are supposed to. As we currently only update the style
on notify, we don't apply it to initially unreactive widgets.

This was covered up partially until recently when Clutter started to
use G_PARAM_EXPLICIT_NOTIFY. Before that, the notify handler would run
when explicitly setting :reactive to FALSE at construction time.

Make sure we always apply the pseudo class correctly by updating it
after construct properties have been set.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3685

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1648>
This commit is contained in:
Florian Müllner 2021-02-07 23:21:55 +01:00
parent d75b64b88f
commit 473e77e2c5
2 changed files with 21 additions and 4 deletions

View File

@ -142,6 +142,15 @@ static gboolean st_widget_real_navigate_focus (StWidget *widget,
static AtkObject * st_widget_get_accessible (ClutterActor *actor); static AtkObject * st_widget_get_accessible (ClutterActor *actor);
static gboolean st_widget_has_accessible (ClutterActor *actor); static gboolean st_widget_has_accessible (ClutterActor *actor);
static void
st_widget_update_insensitive (StWidget *widget)
{
if (clutter_actor_get_reactive (CLUTTER_ACTOR (widget)))
st_widget_remove_style_pseudo_class (widget, "insensitive");
else
st_widget_add_style_pseudo_class (widget, "insensitive");
}
static void static void
st_widget_set_property (GObject *gobject, st_widget_set_property (GObject *gobject,
guint prop_id, guint prop_id,
@ -247,6 +256,14 @@ st_widget_get_property (GObject *gobject,
} }
} }
static void
st_widget_constructed (GObject *gobject)
{
G_OBJECT_CLASS (st_widget_parent_class)->constructed (gobject);
st_widget_update_insensitive (ST_WIDGET (gobject));
}
static void static void
st_widget_remove_transition (StWidget *widget) st_widget_remove_transition (StWidget *widget)
{ {
@ -840,6 +857,7 @@ st_widget_class_init (StWidgetClass *klass)
gobject_class->set_property = st_widget_set_property; gobject_class->set_property = st_widget_set_property;
gobject_class->get_property = st_widget_get_property; gobject_class->get_property = st_widget_get_property;
gobject_class->constructed = st_widget_constructed;
gobject_class->dispose = st_widget_dispose; gobject_class->dispose = st_widget_dispose;
gobject_class->finalize = st_widget_finalize; gobject_class->finalize = st_widget_finalize;
@ -1471,10 +1489,7 @@ st_widget_reactive_notify (StWidget *widget,
{ {
StWidgetPrivate *priv = st_widget_get_instance_private (widget); StWidgetPrivate *priv = st_widget_get_instance_private (widget);
if (clutter_actor_get_reactive (CLUTTER_ACTOR (widget))) st_widget_update_insensitive (widget);
st_widget_remove_style_pseudo_class (widget, "insensitive");
else
st_widget_add_style_pseudo_class (widget, "insensitive");
if (priv->track_hover) if (priv->track_hover)
st_widget_sync_hover(widget); st_widget_sync_hover(widget);

View File

@ -465,6 +465,8 @@ test_pseudo_class (void)
/* Test the StWidget add/remove pseudo_class interfaces */ /* Test the StWidget add/remove pseudo_class interfaces */
label = st_label_new ("foo"); label = st_label_new ("foo");
/* Make reactive, so we don't get the automatic :insensitive style */
clutter_actor_set_reactive (CLUTTER_ACTOR (label), TRUE);
clutter_actor_add_child (stage, CLUTTER_ACTOR (label)); clutter_actor_add_child (stage, CLUTTER_ACTOR (label));
labelNode = st_widget_get_theme_node (label); labelNode = st_widget_get_theme_node (label);