1) a buggy implementation coupled with lack of specification creates a certain 
expectation
2) bug gets fixed
3) people complain because the feature now works as it should?

I think (and this is my personal opinion, in the absence of a formal 
specification) that this works as expected now.  The statement " Nowhere did we 
**actualy** override -fx-text-fill " is not technically correct since this 
color depends on -fx-base.

And I would not want to change how it works currently because this is the only 
way (short of overwriting the whole modena.css styleshseet) for an application 
to effect a system-wide change like reacting to changes in the user preferences 
or the platform theme.

-andy



From: John Hendrikx <john.hendr...@gmail.com>
Date: Tuesday, July 9, 2024 at 10:45
To: Andy Goryachev <andy.goryac...@oracle.com>, openjfx-dev 
<openjfx-dev@openjdk.org>
Subject: Re: [External] : Re: CSS Lookups and their origins (possible 
regression)

Well, it is coming as a surprise to many. With the fix for the CSS caching bug 
since JavaFX 21, this "normal" behavior is becoming much more obvious.

Let me repeat one more time:

If I have a Label, and I manually set its text fill with a setter to YELLOW. In 
JavaFX 17, when I now add a stylesheet that is empty aside from `-fx-base: 
WHITE`, the label's text fill stays YELLOW.

Now do this in JavaFX 21.  As soon as you add the stylesheet with `-fx-base: 
WHITE` in it, the set value to YELLOW is overridden, even though technically 
this value for -fx-text-fill is defined by Modena (which should not be 
overriding set values).  Nowhere did we **actualy** override -fx-text-fill, yet 
the CSS subsystem now sees **all** values defined by Modena that are somehow 
linked to -fx-base as defined directly by the developer...

The reason this didn't happen in JavaFX prior to 21 is because there was a bug 
where a CSS value was not fully calculated if the property it encountered was 
overridden via a set value. That was a bug however as cache entries are shared 
amongst similar styled nodes, and so not calculating it fully could have 
effects on other nodes that shared that cache entry but did NOT have a property 
set directly.  Now that this bug is fixed, this problem is odd behavior is 
popping up where simply specifying -fx-base in an empty stylesheet is somehow 
overriding a programmatically set text fill.  Users are confused by this, as 
nowhere in their stylesheet do they themselves override text fill.

This entire mechanism is not specified by CSS, but is unique to FX.  The most 
similar mechanism in CSS (see Michael's answer) says the priority of a style 
should not be changed when it is using a reference.

--John
On 09/07/2024 17:43, Andy Goryachev wrote:

> all styles used in Modena that rely on -fx-base directly or indirectly 
> suddenly have a higher priority

I think it works as designed (and as expected).

-andy



From: John Hendrikx <john.hendr...@gmail.com><mailto:john.hendr...@gmail.com>
Date: Tuesday, July 9, 2024 at 08:25
To: Andy Goryachev 
<andy.goryac...@oracle.com><mailto:andy.goryac...@oracle.com>, openjfx-dev 
<openjfx-dev@openjdk.org><mailto:openjfx-dev@openjdk.org>
Subject: [External] : Re: CSS Lookups and their origins (possible regression)

It's not that you can't use -fx-base, but that as it is currently that all 
styles used in Modena that rely on -fx-base directly or indirectly suddenly 
have a higher priority (above setters) even though you didn't specifically 
specify them in your own stylesheet.  All such styles are being elevated from 
USER_AGENT to AUTHOR level (which is above USER level which is used for 
setters).

--John
On 09/07/2024 17:03, Andy Goryachev wrote:
I've used this feature in the past to change the colors in all the controls, so 
to me this is the expected behavior.

So in your case (if I got it right), you need to set the direct style on the 
label (.setStyle("-fx-text-fill:yellow")) instead of setting the text fill 
programmatically.  Right?

-andy




From: openjfx-dev 
<openjfx-dev-r...@openjdk.org><mailto:openjfx-dev-r...@openjdk.org> on behalf 
of John Hendrikx <john.hendr...@gmail.com><mailto:john.hendr...@gmail.com>
Date: Monday, July 8, 2024 at 17:11
To: openjfx-dev <openjfx-dev@openjdk.org><mailto:openjfx-dev@openjdk.org>
Subject: Re: CSS Lookups and their origins (possible regression)

I realized I worded the TLDR poorly.

Let me try again:

TLDR; should styles which use references (like -fx-base used in Modena) become 
AUTHOR level styles if -fx-base is specified in an AUTHOR stylesheet?  The act 
of simply specifying -fx-base in your own AUTHOR stylesheet elevates hundreds 
of styles from Modena to AUTHOR level, as if you specified them directly...

--John
On 09/07/2024 02:07, John Hendrikx wrote:

Hi List,

TLDR; should a CSS reference like -fx-base convert all styles that use this 
value (or derive from it) become AUTHOR level styles (higher priority than 
setters) ?

Long version:

In JavaFX 21, I did a fix (see #1072) to solve a problem where a CSS value 
could be reset on an unrelated control.

This happened when the CSS engine encountered a stylable that is overridden by 
the user (with a setter), and decided NOT to proceed with the full CSS value 
calculation (as it could not override the user setting if that CSS value had 
lower priority).  However, not proceeding with the calculation meant that a 
"SKIP" was stored in a shared cache which was incorrect.  This is because when 
this "SKIP" is later encountered for an unrelated control (the cache entries 
are shared for controls with the same styles at the same level), they could get 
their values reset because they were assumed to be unstyled.

However, this fix has exposed what seems to be a deeper bug or perhaps an 
unfortunate default:

JavaFX has a special feature where you can refer to certain other styles by 
using a reference (which is resolved, recursively, to a final value).  This 
does not seem to be a CSS standard, but is a feature only FX has.

It works by saying something like:

    -fx-base: RED;

And then using it like this:

    -fx-text-fill: -fx-base;

This feature works accross stylesheets of different origins, so an AUTHOR 
stylesheet can specify -fx-base, and when a USER_AGENT refers to -fx-base, the 
value comes from the AUTHOR stylesheet.

JavaFX then changes the origin of the style to the highest priority encountered 
while resolving the reference.  This means that Modena can specify 
"-fx-text-fill: -fx-base", and when "-fx-base" is then part of the AUTHOR style 
sheet, that ALL Modena styles that use -fx-base will be considered AUTHOR level 
styles, as per this comment:

// The origin of this parsed value is the greatest of

// any of the resolved reference. If a resolved reference

// comes from an inline style, for example, then the value

// calculated from the resolved lookup should have inline

// as its origin. Otherwise, an inline style could be

// stored in shared cache.

I feel that this is a really unfortunate choice.  The style after all was 
specified by Modena, only its value came from another (higher priority) style 
sheet.  I think a more logical choice would have been to not change the 
priority at all, unless a "-fx-text-fill" is explicitly made part of the AUTHOR 
stylesheet.

A consequence of this (and which is much more visible after the fix) is that 
creating a Label with a setTextFill(Color.YELLOW) in its constructor will only 
result in a yellow text fill if the AUTHOR stylesheet did not override any of 
the Modena colors involved in calculating the Modena -fx-text-fill default.  
Overriding -fx-base in any way will result in the text fill of the label to be 
overridden (as the reference came from an AUTHOR stylesheet, which trumps a 
setter which is of a lower style origin).

The comment also alludes to a potential problem.  If an inline style would 
specify "-fx-base", but would be treated as if it came from Modena (USER_AGENT 
level), then this value could get stored in the cache as everything except 
INLINE styles can be cached.  However, I feel that the changing of style origin 
level was then probably done to solve a CACHING problem, instead of what made 
logical sense for users.  If we agree that a resolved reference should not 
change the style origin level, then this would need to be addressed, by perhaps 
marking such a calculated value as uncacheable, instead of overloading the 
meaning of style origin.

I'd like to hear your thoughts, and also how to proceed.  JavaFX versions 
before 21 seemingly allowed overriding reference without much consequence 
because if the user overrode the value manually, the cache entry would be set 
to "SKIP".  Now that this is no longer the case, JavaFX more aggressively 
overrides user set values if they happen to use a referenced value.  See code 
below.

--John

.root {

-fx-base: #ff0000;

}

package app;

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.paint.Color;

import javafx.stage.Stage;

public class TestApp extends Application {

public static void main(String[] args) {

launch(args);

}

@Override

public void start(Stage primaryStage) {

Scene scene = new Scene(new MyLabel());

// See the difference with/without -fx-base in the stylesheet

scene.getStylesheets().add(TestApp.class.getResource("/style.css").toExternalForm());

primaryStage.setScene(scene);

primaryStage.show();

}

}

class MyLabel extends Label {

public MyLabel() {

setTextFill(Color.YELLOW);

setText("Hello world");

}

}


Reply via email to