After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 621140 - [StyleTransition] Improve style changes during transitions
[StyleTransition] Improve style changes during transitions
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2010-06-09 19:19 UTC by Florian Müllner
Modified: 2010-06-10 02:33 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[StyleTransition] Improve style changes during transitions (3.56 KB, patch)
2010-06-09 19:19 UTC, Florian Müllner
none Details | Review
[StyleTransition] Improve style changes during transitions (3.50 KB, patch)
2010-06-09 19:20 UTC, Florian Müllner
committed Details | Review

Description Florian Müllner 2010-06-09 19:19:43 UTC
When changing back to the previous style, we correctly reverse the transition. All other style changes during transitions will result in canceling the transition - mainly because supporting transitions from intermediate states is hard.

This behavior is fine if the style change is actually triggered by some event (button press, hover change etc.).

Unfortunately, a simple snippet like this:

widget.style_class = 'foo';
widget.add_pseudo_class(':bar');

will trigger two style changes - not a big deal in case of "normal" changes, but in combination with transitions the result can be pretty surprising.

The W3C's proposal for CSS transitions[1] is not very helpful here either:

"Since this specification does not define what property changes are considered simultaneous, authors should be aware that changing any of the transition properties a small amount of time after making a change that might transition can result in behavior that varies between implementations, since the changes might be considered simultaneous in some implementations but not others."

As an implementor, we need to define what changes we want to consider simultaneous (e.g. the snippet above). Some thoughts from Owen on the topic:

<owen> fmuellner: first stab is that it should be "return to the main loop" - if you add a style in a button press, and then change it in the next button release then that should not be simultaneous, but if within a button press you add a style and change it to another style that should be simultaneous and trigger a transition
 fmuellner: now, next question is how you implement that, since you don't actually return to the GLib main loop between the button press and the release if they are both in the queue
<owen> fmuellner: second idea, completely different is that if we haven't yet done any frames of the first animation, instead of cancelling and not animating, we do the second animation
<owen> because the whole reason for not animating is that once we get to an intermediate state we can't animate to the end state, but we aren't yet *in* an intermediate state



[1] http://www.w3.org/TR/css3-transitions/#starting
Comment 1 Florian Müllner 2010-06-09 19:19:47 UTC
Created attachment 163225 [details] [review]
[StyleTransition] Improve style changes during transitions

Our behavior of reversing the animation when the widget's style
changes back to the previous one is sound. On the other hand, when
there's a change to a new style while a transition is active, we
simply cancel the ongoing transition. Updating the transition
correctly so that the new one starts from an intermediate state
is hard.
Nevertheless, if the style changes before any time of the transition
has elapsed, we should do better than the current behavior.
Comment 2 Florian Müllner 2010-06-09 19:20:52 UTC
Created attachment 163226 [details] [review]
[StyleTransition] Improve style changes during transitions

Our behavior of reversing the animation when the widget's style
changes back to the previous one is sound. On the other hand, when
there's a change to a new style while a transition is active, we
simply cancel the ongoing transition. Updating the transition
correctly so that the new one starts from an intermediate state
is hard.
Nevertheless, if the style changes before any time of the transition
has elapsed, we should do better than the current behavior.
Comment 3 Florian Müllner 2010-06-09 19:30:52 UTC
Two variations of Owen's second proposal:

 (1) when interrupting transition A=>B, we replace it
     with B=>C
 (2) when interrupting transition A=>B, we replace it
     with A=>C

The second variant makes a little more sense to me - note that the search entry (which is the only case we currently have of a widget uses both a plethora of style classes and transitions) looks worse with both patches.

I think it still make sense to look into Owen's first suggestion as well ...
Comment 4 Owen Taylor 2010-06-09 20:57:43 UTC
(In reply to comment #3)
> Two variations of Owen's second proposal:
> 
>  (1) when interrupting transition A=>B, we replace it
>      with B=>C
>  (2) when interrupting transition A=>B, we replace it
>      with A=>C
> 
> The second variant makes a little more sense to me - note that the search entry
> (which is the only case we currently have of a widget uses both a plethora of
> style classes and transitions) looks worse with both patches.

I definitely meant (2) here - the whole point is that if we haven't made any progress from A => B then the user will never know we started down that path. Can you describe how the entry looks worse than current with this approach?
Comment 5 Florian Müllner 2010-06-09 21:33:13 UTC
Comment on attachment 163225 [details] [review]
[StyleTransition] Improve style changes during transitions

(In reply to comment #4)
> Can you describe how the entry looks worse than current with this approach?

There is now a transition between :focus and :indeterminate (hitting escape when typing / clicking outside the entry after activating) - the transition itself is okay-ish, but moving the pointer inside the entry during the transition jumps straight to :hover which looks a little out of place (especially towards the end of the animation).

It's not exactly awful, the wrong transition we do currently just feels more consistent to me (yeah, the irony ...) - there is _always_ a transition between "normal" and "hover" and _never_ for "focus"; of course, I would feel much better if that behavior wasn't the more-or-less accidental result of some unrelated style changes ...
Comment 6 Owen Taylor 2010-06-10 00:15:05 UTC
(In reply to comment #5)
> (From update of attachment 163225 [details] [review])
> (In reply to comment #4)
> > Can you describe how the entry looks worse than current with this approach?
> 
> There is now a transition between :focus and :indeterminate (hitting escape
> when typing / clicking outside the entry after activating) - the transition
> itself is okay-ish, but moving the pointer inside the entry during the
> transition jumps straight to :hover which looks a little out of place
> (especially towards the end of the animation).
> 
> It's not exactly awful, the wrong transition we do currently just feels more
> consistent to me (yeah, the irony ...) - there is _always_ a transition between
> "normal" and "hover" and _never_ for "focus"; of course, I would feel much
> better if that behavior wasn't the more-or-less accidental result of some
> unrelated style changes ...

OK, that sounds a little bit annoying, but expected. In my opinion, if we want to do better we need to do one or the other of:

 - Implement a way of doing state-transition specifications

 - Implement full transition continuity by "pausing" old transitions and
   keeping more layers.

They are both distinctly possible programming tasks, but I think in terms of moving the shell forward to GNOME 3.0 they probably are a lot of work for the gain. Maybe we should wait and see if people who haven't been spending a lot of time staring at the details of the entry transitions complain... :-) (Up to you what you find fun to work on, of course!)
Comment 7 Owen Taylor 2010-06-10 00:18:05 UTC
Review of attachment 163226 [details] [review]:

Looks good to me. 

(There's some annoying inefficiency in allocating new theme nodes for every change but not using the intermediate theme nodes, but all the actual "hard work" of the theme node - computing the borders and background, creating Cogl resources, etc, is lazy; I think just allocating a theme node is going to be fine.)
Comment 8 Florian Müllner 2010-06-10 02:05:48 UTC
(In reply to comment #6)
> OK, that sounds a little bit annoying, but expected. In my opinion, if we want
> to do better we need to do one or the other of:
> 
>  - Implement a way of doing state-transition specifications
> 
>  - Implement full transition continuity by "pausing" old transitions and
>    keeping more layers.

I disagree about the "one or the other" part - the first adds more control to the CSS (e.g. when to do transitions), the second improves the transitions itself (e.g. how to do transitions)


> They are both distinctly possible programming tasks, but I think in terms of
> moving the shell forward to GNOME 3.0 they probably are a lot of work for the
> gain.

+1


> Maybe we should wait and see if people who haven't been spending a lot of
> time staring at the details of the entry transitions complain... :-)

Yup, sounds like a plan - even if people complain, we can still try to tweak the CSS to get to the least annoying look - it won't be perfect, but "good enough" ain't that bad either :)
Comment 9 Florian Müllner 2010-06-10 02:33:29 UTC
Attachment 163226 [details] pushed as 49919ac - [StyleTransition] Improve style changes during transitions

(In reply to comment #7)
> (There's some annoying inefficiency in allocating new theme nodes for every
> change but not using the intermediate theme nodes, but all the actual "hard
> work" of the theme node - computing the borders and background, creating Cogl
> resources, etc, is lazy; I think just allocating a theme node is going to be
> fine.)

Yes, but it's not actually related to transitions, is it? The same applies for style changes without transitions, if a style is replaced before it's first painted. Not that this does make it any better of course ...

If we created the theme node itself lazily, we would have to cache the style information in StWidget itself (id, class, inline style, ...) - I don't think there's much more room for improvement beside object construction itself.