-
Notifications
You must be signed in to change notification settings - Fork 516
8313424: JavaFX controls in the title bar (Preview) #1605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
/reviewers 2 reviewers |
@mstr2 has indicated that a compatibility and specification (CSR) request is needed for this pull request. @mstr2 please create a CSR request for issue JDK-8313424 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
Hey, I'm glad to see this PR, but do you have any ideas for continuing to provide |
Very nice. I'll test on Linux and report back. |
The only difference between the two would be whether the default window buttons are provided. I don't see how a window without default window buttons would be more useful. Even heavily stylized apps like Spotify use window buttons that feel at home on the OS, that doesn't take away from a consistent look and feel. |
A few points observed on Linux:
Added later: Nice cleanup on |
I suggest we convert this PR to Draft and first discuss this in the mailing list. There are so many issues with the proposal that need to be ironed first: CSS support, height limitation (what happens when the app or CSS places too large of the component?), user-defined color/accents/transparency on Windows, to name just a few. This change also may add a significant maintenance burden to the platform, for what I feel is a very small payout. What do you think? |
This has already been discussed at various points in time, and was always received positively. The previous implementation is one of the most-upvoted feature proposals since OpenJFX moved to GitHub.
What about these things? I don't understand the question, but let me try to give some answers nontheless:
Popular demand says otherwise. |
Popular demand is good, but I would like to hear from the tech leads and the maintainers. |
To clarify about height: do all the platforms support arbitrary height? What if size set by the app/CSS exceeds the height supported by the platform? About platform preferences: will it support all the attributes of the window decorations provided by the platform? |
@tsayao Thanks for the comments. I'll have a look at the bugs that you found.
I know that dragging on interactive controls is a thing on Linux, but I don't think that we should be doing that. JavaFX applications are multi-platform apps, which means that their behavior should be consistent across platforms. Stealing mouse interactions on interactive controls is not a thing on Windows and macOS, and this has the potential to cause problems for application developers. If you want, you can declare any node in the header bar to be draggable on all platforms with
I'll have to look into that, but in general an
While that sounds useful at first, I don't think it carries its own weight. Many platforms use different styling for windows that are focused vs. windows that are not. This not only includes the header bar, but many other parts of the user interface as well. I don't think that we should be adding what would essentially be ad-hoc pseudo-classes only to HeaderBar. In addition to that, it is extremely easy for an application to do this by adding a listener to We should definitely not do pseudo-classes for light vs. dark mode. The correct way to solve this problem is with media queries (prefers-color-scheme). |
Mailing list message from quizynox at gmail.com on openjfx-dev: Hello, Thank you so much for your effort! I'm really glad this hasn't been Every modern platform supports this feature: Electron, Tauri, Wails, Qt, Unfortunately, the current UNDECORATED stage implementation lacks two That's why the implementation should be handled on the native side, which It's indeed a complex feature. For that reason, I believe the ??, 22 ???. 2024??. ? 03:24, Michael Strau? <mstrauss at openjdk.org>: -------------- next part -------------- |
Continuing on window attributes. I would like to know what is and is not supported by platform, by feature. For example: Windows
Did I miss anything? |
For the HeaderBar, I would like to see the explanation of different layout options, including the cases when all the information does not fit the window width. Which parts are contracted? How is overflow handled? |
May be I am late to the party, but I would suggest to discuss the JEP first. I would like to see the summary by platform by feature, I would like to see details of the layout, and the description if and how the proposed design responds to user preferences changes dynamically. I would also like to see alternatives. Perhaps the app developers has all the tools already (for example, creating an overlay transparent scene on top of the platform title bar?), or maybe this functionality should be rather implemented in a library. Lastly, there is a concern of adding a huge maintenance burden on the platform. Next time the major OS vendor changes the L&F or adds something to the window decorations, we are on the hook for supporting that. I am not even qualified to access the impact of this feature in the Linux world. There are so many frameworks and opinions - how do you propose to handle that? Is it going to be supported on Wayland? |
Gtk does work on Mac and Windows, maybe we can see how it handles it's HeaderBar, for reference. |
Another aspect is whether this should be a conditional feature. |
I'll eagerly invite you to dissect this PR for its merits, its pros and cons. However, your questions lead me to conclude that you haven't really looked at what I'm proposing. Half of your questions are answered just by looking at the documentation for Let me try to explain
Since there is no non-client title bar, all questions regarding the appearance or accessibility of the |
On #1789 there's a Test utility for Stages called |
created * JDK-8358625 Full screen of a modal Stage breaks the application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recently discovered issues appear unrelated (i.e. present in the master branch).
The latest changes look good.
Good job, Michael!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good, re-approving.
modules/javafx.graphics/src/main/java/com/sun/glass/ui/gtk/WindowManager.java
Outdated
Show resolved
Hide resolved
GdkDisplay* display = gdk_display_get_default(); | ||
if (!display) { | ||
return; | ||
} | ||
|
||
GdkSeat* seat = gdk_display_get_default_seat(display); | ||
GdkDevice* device = gdk_seat_get_pointer(seat); | ||
if (!device) { | ||
return; | ||
} | ||
|
||
gint rx = 0, ry = 0; | ||
gdk_window_get_root_coords(gdk_window, x, y, &rx, &ry); | ||
|
||
GdkEvent* event = (GdkEvent*)gdk_event_new(GDK_BUTTON_PRESS); | ||
GdkEventButton* buttonEvent = (GdkEventButton*)event; | ||
buttonEvent->x_root = rx; | ||
buttonEvent->y_root = ry; | ||
buttonEvent->window = (GdkWindow*)g_object_ref(gdk_window); | ||
buttonEvent->device = (GdkDevice*)g_object_ref(device); | ||
|
||
gdk_window_show_window_menu(gdk_window, event); | ||
gdk_event_free(event); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The seat
concept was introduced in gtk 3.20 and gdk_window_show_window_menu
was in 3.14, and we require 3.8.
I would agree that it's time to bump it up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anything we need to change here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can bump up required Gtk version (with another PR) to 3.20 (it's from 2016, so pretty old), or replace the gdk_window_show_menu
with X11 calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm okay with bumping the required version. It seems like 3.8 was released 12 years ago, and we would be requiring a version that was released 9 years ago. Sounds fair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our production build system is Oracle Linux 8, which has GTK 3.22.
The oldest system I now have access to is Ubuntu 16.04 (yeah, I know...it's probably time to retire it), which has GTK 3.18. I build JavaFX using GCC 14.2 (via a devkit) and compile against a GTK 3.22 header files and library. I'm able to run this PR and use the EXTENDED stage style with a HeaderBar, but when I try to use the context menu it crashes:
java: symbol lookup error: build/sdk/lib/libglassgtk3.so: undefined symbol: gdk_display_get_default_seat
We should make a deliberate decision as to whether or not to bump the minimum. I think bumping the minimum to 3.20 might be reasonable thing to, although I'd want to do it separately from this PR and provide a release note for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth noting is that we only recently upgraded our production build env from Oracle Linux 7, which is now out of support. Bumping the minimum GTK version to 3.20 will preclude running on OL 7 / RHEL 7 at all (RHEL 7 has GTK 3.8, which is why that minimum was chosen). I think this is OK, but is another reason I want to see a separate JBS issue to bump the minimum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think providing a release note that the new extended stage style requires GTK 3.20 sounds reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mis-remembered the GTK version in OL7. I just tried it on an OL 7 VM I still had lying around, and it also has GTK 3.22 and using this PR, the MonkeyTester with EXTENDED stage style and a HeaderBar runs just fine, including the context menu.
I think providing a release note that the new extended stage style requires GTK 3.20 sounds reasonable.
I was more thinking that we would file a new issue to bump the minimum to 3.20 and provide a release note using that bug that JavaFX requires 3.20 as a minimum. If we end up not doing that, then a release note that the extended stage style needs 3.20 would be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can work on the Gtk version bump.
@@ -126,6 +129,7 @@ class WindowContext : public DeletedMemDebug<0xCC> { | |||
virtual void set_title(const char*) = 0; | |||
virtual void set_alpha(double) = 0; | |||
virtual void set_enabled(bool) = 0; | |||
virtual void set_system_minimum_size(int, int) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe set_headerbar_mininum_size()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... but it's not the minimum size of the header bar, it's the minimum size of the window.
It appears that the CSS of the Window icons cannot be overridden; see below example which doesn't apply css.css. What is the proper/expected way to style the window icons; and should there be some documentation on this somewhere in HeaderBar?
css.css (put in same directory as class)
|
The default buttons can't be styled, because their appearance is an unspecified implementation detail of the platform toolkit. These are the reasons for this decision:
If you need to customize the window buttons, the proper way is as follows:
By the way, there's a section in the |
Probably not, try setting |
Yeah, just looking into this which will apply dark or not:
Thanks! |
No, the docs on that are good. Although, nothing stood out to make it obvious that the WindowDecoration.css styles cannot be overridden. Regarding the "dark" + scene fill, there are some good docs in HeaderButtonOverlay, but I don't know if the average developer would venture into there. |
The documentation for that is in I've created a ticket to track this: JDK-8358823 |
Just something to consider regarding this "dark" mode reliance on a Scene's fill property. As far as I know, a Scene's fill property cannot be set via CSS. I have a light and dark theme (two css files), and the user can pick "light" or "dark", for example. A few well-known apps have quite a few themes to choose from, like AtlantaFX-based apps. Other apps allow users to supply custom CSS files, such as JabRef. In order for the window icons to appear correctly, one must programmatically call Scene.setFill(), setting it to something appropriate anytime a user changes theme, at runtime -- it seems to defeat the purpose of stylesheets a little to need to "know" how to set a scene's fill. Would it be more flexible to check the background colour of the HeaderBar instead, and base the isDarkBackground() check off that? Runtime stylesheet changes would also be picked up by HeaderButtonOverlay which would automatically adjust the window icons, and the developer doesn't need to call any code. Let the developer decide the background colour of the HeaderBar (which can be via CSS). Would also cover the case where users might want a dark menu/header bar, but a otherwise "white" scene, or vica-versa. |
Well, don't assume a "documentation problem" based on my comments alone. I hadn't read the docs properly in quite a long time. Thanks for all your work on this, it's looking very nice. |
In the future, separate stylesheets for light and dark modes might not be required. PR #1655 proposes media feature queries that includes a scene-specific property So when we get that feature, we could have the default header buttons adapt to the scene's color scheme instead of its fill color. And instead of swapping out stylesheets to toggle dark mode, you would only toggle the scene's color scheme property.
This would be the most flexible option, but it's also more difficult to implement. Consider the case where you have two header bars side by side (this is a supported configuration). Do we take the average background color of both header bars? Do we pick one of them? (And if so, how? Do we inspect the scene graph under the header buttons?) By the way, the entire point of a preview feature is to encourage constructive feedback, so your experience with the feature and potential ideas on how to improve it are very welcome. |
I am noticing some strange artifacts, whereby the window icons are partially or completely disappearing, or (more often) their styling is not changing on hover. I don't have a screenshot of all three disappearing, but it has happened. I am not doing anything unusual, so this is odd. I know such a "bug" report without a reproducible example, is a pain. But this is just an FYI, that something is happening. No other styling is affected, just these windows icons. I will post more when I know more. Here, my mouse was hovering over X (not in screenshot), note it isn't red: Here, one icon has disappeared: What I appear to be able to reproduce the easiest, is where the three icons are still visible, but styling does not change on hover. All I need to do is click around my app a little bit, loading a few different (unrelated) views, and this "bug" occurs. UPDATE: I think this issue is closely related to #1605 (comment) |
This is a frustrating "issue" in the sense that it's very much timing-related and even window-size specific, as to whether or not it occurs (i.e., the icons disappear). Ultimately, I found that the application in the screenshot was slightly mis-using this method in a ControlsFx's class: https://github.com/controlsfx/controlsfx/blob/4f1da99e4ebc15d8fc8cb44bf5476d39068b2eea/controlsfx/src/main/java/impl/org/controlsfx/ImplUtils.java#L51 ... long story short is that it was trying to, in some rare circumstances, erroneously wrap a DecorationPane in a DecorationPane (which was pointless, there's no reason to do that). A DecorationPane is something ControlsFx wraps root nodes in (usually without the developer knowing) in order to provide some of its functionality. This double wrapping bug, which was seemingly harmless until now, for whatever reason, was causing the display issues on the window icons (and oddly only when the window was a certain size...). When fixed, I can no longer reproduce the disappearing window icons issue. So I don't know if there's a bug worth investigating here or not, these comments are mainly intended as a source of information to others. |
I fell into that trap a number of times ;-) |
This seems like a bug. If developers use an API wrongly, a clearly defined error should result; in this case, window buttons disappear or stop working. This can't be right. Is the software you're talking about open source, or can you reproduce the issue with ControlFx in a standalone app? |
I've narrowed it down to this, which is a much simplified version of what my earlier code + ControlsFX was doing; this consistently reproduces the issue. No third party libs needed.
Note that I see some CSS errors, that weren't being logged before for me (at least not consistently, though I did see them, sometimes -- depending):
|
As it turns out, the CSS engine really wants all styleable nodes to be traceable to a single root node. If that's not the case (as in this PR with the overlay buttons), all kinds of things go wrong. I've fixed this issue by having the scene's root node be the parent of the scene overlay. Note that only the overlay knows that the scene root is its parent, the scene root has no knowledge of that (i.e. the overlay is not a child of the scene root that you can see with With this change, the CSS engine works correctly. As a side effect, it now also picks up stylesheets of the root node. This makes it possible to interfere with the internal stylesheets of the button overlay. In order to reduce the chance of that happening, I've renamed all style classes to have the |
Implementation of
StageStyle.EXTENDED
.Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1605/head:pull/1605
$ git checkout pull/1605
Update a local copy of the PR:
$ git checkout pull/1605
$ git pull https://git.openjdk.org/jfx.git pull/1605/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1605
View PR using the GUI difftool:
$ git pr show -t 1605
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1605.diff
Using Webrev
Link to Webrev Comment