jfx icon indicating copy to clipboard operation
jfx copied to clipboard

8369836: Update HeaderBar API

Open mstr2 opened this issue 2 months ago • 15 comments

The HeaderBar control currently has three areas: leading, center, and trailing. Additionally, there's leftSystemInset and rightSystemInset, which are not RTL adjusted. I've come to the understanding that there is no particularly good reason for this, because every time you would want to use this information for layout purposes, it should also be adjusted for RTL.

With this in mind, there are three changes for the HeaderBar control:

  1. Rename leading to left, and trailing to right, which aligns the terminology with BorderPane.
  2. Adjust leftSystemInset and rightSystemInset for RTL.
  3. Make leftSystemInset, rightSystemInset, and minSystemHeight attached properties for Stage.

With this change, the HeaderBar control is more semantically consistent and easier to use, and the renamed left and right areas now show its close relationship with BorderPane.

/csr /reviewers 2


Progress

  • [x] Change must not contain extraneous whitespace
  • [x] Commit message must refer to an issue
  • [ ] Change requires a CSR request matching fixVersion jfx26 to be approved (needs to be created)
  • [ ] Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1936/head:pull/1936
$ git checkout pull/1936

Update a local copy of the PR:
$ git checkout pull/1936
$ git pull https://git.openjdk.org/jfx.git pull/1936/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 1936

View PR using the GUI difftool:
$ git pr show -t 1936

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1936.diff

Using Webrev

Link to Webrev Comment

mstr2 avatar Oct 14 '25 14:10 mstr2

:wave: Welcome back mstrauss! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

bridgekeeper[bot] avatar Oct 14 '25 14:10 bridgekeeper[bot]

❗ This change is not yet ready to be integrated. See the Progress checklist in the description for automated requirements.

openjdk[bot] avatar Oct 14 '25 14:10 openjdk[bot]

@mstr2 has indicated that a compatibility and specification (CSR) request is needed for this pull request.

@mstr2 this pull request must refer to an issue in JBS to be able to link it to a CSR request. To refer this pull request to an issue in JBS, please update the title of this pull request to just the issue ID.

openjdk[bot] avatar Oct 14 '25 14:10 openjdk[bot]

@mstr2 The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

openjdk[bot] avatar Oct 14 '25 14:10 openjdk[bot]

Mailing list message from Andy Goryachev on openjfx-dev:

Can you clarify what you mean by "aligning with" BorderPane?

Does it mean we are trying to propagate somewhat misleading terminology that was used by the BorderPane (setLeft() in RTL mode results in the added node on the right side, so it should really be named something like setLeading() instead of setLeft()).

Thanks, -andy

From: openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of Michael Strau? <mstrauss at openjdk.org> Date: Tuesday, October 14, 2025 at 09:40 To: openjfx-dev at openjdk.org <openjfx-dev at openjdk.org> Subject: RFR: 8369836: Update HeaderBar API

The `HeaderBar` control currently has three areas: `leading`, `center`, and `trailing`. Additionally, there's `leftSystemInset` and `rightSystemInset`, which are not RTL adjusted. I've come to the understanding that there is no particularly good reason for this, because every time you would want to use this information for layout purposes, it should also be adjusted for RTL.

With this in mind, there are two changes for the `HeaderBar` control: 1. Rename `leading` to `left`, and `trailing` to `right`, which aligns the terminology with `BorderPane`. 2. Adjust `leftSystemInset` and `rightSystemInset` for RTL.

With this change, the `HeaderBar` control is more semantically consistent and easier to use, and the renamed `left` and `right` areas now show its close relationship with `BorderPane`.

-------------

Commit messages: - Update HeaderBar API

Changes: https://git.openjdk.org/jfx/pull/1936/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1936&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8369836 Stats: 212 lines in 3 files changed: 14 ins; 56 del; 142 mod Patch: https://git.openjdk.org/jfx/pull/1936.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1936/head:pull/1936

PR: https://git.openjdk.org/jfx/pull/1936 -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20251014/cb6293e4/attachment-0001.htm>

mlbridge[bot] avatar Oct 14 '25 16:10 mlbridge[bot]

Mailing list message from Michael Strauß on openjfx-dev:

Yes, exactly. "Left" and "right" is used in several places in JavaFX (BorderPane, AnchorPane, Insets) to effectively mean "leading" and "trailing". HeaderBar is different, because it uses "left", "right", as well as "leading" and "trailing" with a different definition than the other controls (leading and trailing are RTL adjusted, while left and right are not). My proposal is to just accept that "left" and "right" are JavaFX terminology for RTL-adjusted leading and trailing areas.

On Tue, Oct 14, 2025 at 6:52?PM Andy Goryachev <andy.goryachev at oracle.com> wrote:

Can you clarify what you mean by "aligning with" BorderPane?

Does it mean we are trying to propagate somewhat misleading terminology that was used by the BorderPane (setLeft() in RTL mode results in the added node on the right side, so it should really be named something like setLeading() instead of setLeft()).

Thanks, -andy

mlbridge[bot] avatar Oct 14 '25 17:10 mlbridge[bot]

Mailing list message from Andy Goryachev on openjfx-dev:

I would rather clarify the incorrect labels in the existing components. We obviously cannot change setLeft() - perhaps we should add explanation to the corresponding javadoc explaining RTL behavior. I would like to avoid making the same mistake going forward.

-andy

From: Michael Strau? <michaelstrau2 at gmail.com> Date: Tuesday, October 14, 2025 at 10:02 To: Andy Goryachev <andy.goryachev at oracle.com> Cc: Michael Strau? <mstrauss at openjdk.org>, openjfx-dev at openjdk.org <openjfx-dev at openjdk.org> Subject: [External] : Re: RFR: 8369836: Update HeaderBar API

Yes, exactly. "Left" and "right" is used in several places in JavaFX (BorderPane, AnchorPane, Insets) to effectively mean "leading" and "trailing". HeaderBar is different, because it uses "left", "right", as well as "leading" and "trailing" with a different definition than the other controls (leading and trailing are RTL adjusted, while left and right are not). My proposal is to just accept that "left" and "right" are JavaFX terminology for RTL-adjusted leading and trailing areas.

On Tue, Oct 14, 2025 at 6:52?PM Andy Goryachev <andy.goryachev at oracle.com> wrote:

Can you clarify what you mean by "aligning with" BorderPane?

Does it mean we are trying to propagate somewhat misleading terminology that was used by the BorderPane (setLeft() in RTL mode results in the added node on the right side, so it should really be named something like setLeading() instead of setLeft()).

Thanks, -andy

-------------- next part -------------- An HTML attachment was scrubbed... URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20251014/46137efc/attachment-0001.htm>

mlbridge[bot] avatar Oct 14 '25 17:10 mlbridge[bot]

Mailing list message from Michael Strauß on openjfx-dev:

Considering that the "left" and "right" terminology is deeply entrenched in JavaFX, I see no advantage in trying to fight it. However, I agree that we should clearly define what left and right means in the context of RTL layouts, which is a bit different from the usual dictionary definition of left and right.

On Tue, Oct 14, 2025 at 7:08?PM Andy Goryachev <andy.goryachev at oracle.com> wrote:

I would rather clarify the incorrect labels in the existing components. We obviously cannot change setLeft() - perhaps we should add explanation to the corresponding javadoc explaining RTL behavior. I would like to avoid making the same mistake going forward.

-andy

mlbridge[bot] avatar Oct 14 '25 17:10 mlbridge[bot]

Reviewers: @andy-goryachev-oracle @kevinrushforth

kevinrushforth avatar Oct 15 '25 17:10 kevinrushforth

Considering that the "left" and "right" terminology is deeply entrenched in JavaFX, I see no advantage in trying to fight it. However, I agree that we should clearly define what left and right means in the context of RTL layouts, which is a bit different from the usual dictionary definition of left and right.

I think this is a good choice from a consistency point of view.

kevinrushforth avatar Oct 15 '25 17:10 kevinrushforth

There's another thing that I think will improve the HeaderBarAPI:

The leftSystemInset, rightSystemInset, and minSystemHeight properties shouldn't be normal properties, but attached properties for Stage. If you think about it, these aren't really properties of HeaderBar, but properties of Stage that are used in the context of HeaderBar.

We already have an attached property of this kind: HeaderBar.getPrefButtonHeight(Stage). Having the other three properties defined similarly makes the API more consistent.

It should be noted that this will be the first instance of an observable attached property in JavaFX. So while regular attached properties have a getter/setter pair like this...

class HBox {
    static Insets getMargin(Node);
    static void setMargin(Node, Insets);
}

...an observable attached property will have an observable property getter:

class HeaderBar {
    static ReadOnlyObjectProperty<Dimension2D> leftSystemInsetProperty(Stage);
    static Dimension2D getLeftSystemInset(Stage);
}

The form of the property getter shouldn't be controversial, as it follows the existing getter/setter form for attached properties.

What needs to be clarified, however, is what getBean() and getName() should return for an attached observable property. Since an attached property is a part of the object it is attached to, the getBean() method should return that object. In our example, this means HeaderBar.leftSystemInsetProperty(myStage).getBean() == myStage.

For the getName() method, the usual convention is to return the lowerCamelCase name of the property. However, since an attached property is not declared on the object's class to which it is attached, the name shouldn't claim that it is. I propose a naming convention of the form DeclaringType.myProperty, that is, the property name is qualified with the declaring type. In our example, the name of the property would be "HeaderBar.leftSystemInset" (instead of just "leftSystemInset").

mstr2 avatar Oct 17 '25 02:10 mstr2

@mstr2 are there any plans to look at this: IMG_20251204_153610

On Linux Min 22.2 with Cinnamon I get a rectangular window no matter what. I also tried setting the root's background color and radius, as well as the scene's fill to TRANSPARENT but nothing works.

One thing I'm curious about is why it was implemented this way. I mean, if the native decorations are just rendered on top of JavaFX nodes, then why I'm not able to set the scene's fill to TRANSPARENT and let the developer handle the rest.

Edit: btw this is quite the issue because I can't achieve a consistent look across the various systems. The only solution is to use a TRANSPARENT Stage and make my own window buttons, losing a ton of features though (resize, drag, snap assistants, etc.)

palexdev avatar Dec 04 '25 14:12 palexdev

@palexdev In the case of linux, the decorations are a JavaFX overlay, the window manager (at least mutter) will not draw over the window.

tsayao avatar Dec 04 '25 17:12 tsayao

On Linux Min 22.2 with Cinnamon I get a rectangular window no matter what. I also tried setting the root's background color and radius, as well as the scene's fill to TRANSPARENT but nothing works.

One thing I'm curious about is why it was implemented this way. I mean, if the native decorations are just rendered on top of JavaFX nodes, then why I'm not able to set the scene's fill to TRANSPARENT and let the developer handle the rest.

The USP of an extended stage is: give me native window decorations (borders, drop shadows, animations, etc.) but don't give me the native title bar. As it turns out, this is surprisingly hard to do with GTK: we either get all of the decorations, or almost none of them. We can't tell GTK to just give us a native-looking window without the title bar, we can only get a completely undecorated window. We didn't forget the rounded corners, it's just a non-trivial thing to achieve.

Could we have implemented this feature in a way where you'll basically get a transparent window, and then have the application be responsible for drawing decorations and drop shadows? Maybe. But that would be a different feature, we want the native-looking windows without applications trying (and failing) to recreate their look-and-feel. In addition to that, such an approach would also lead to applications looking like they're stuck in time when a future OS version changes the styling of native window decorations.

@tsayao recently posted an email to the mailing list with some thoughts on how the Linux situation could be improved.

Edit: btw this is quite the issue because I can't achieve a consistent look across the various systems. The only solution is to use a TRANSPARENT Stage and make my own window buttons, losing a ton of features though (resize, drag, snap assistants, etc.)

Using a transparent stage has even more downsides, as you'll not only lose all of the things you mentioned, but also window animations (on Windows) and drop shadows.

mstr2 avatar Dec 08 '25 23:12 mstr2