On Sun, 20 Oct 2024 01:23:01 GMT, Michael Strauß <mstra...@openjdk.org> wrote:

>> This PR is a new take on a highly requested feature: JavaFX controls in the 
>> header bar (see also #594 for an earlier iteration).
>> 
>> This is a feature with many possible ways to skin the cat, and it has taken 
>> quite a bit of effort to come up with a good user model. In contrast to the 
>> previous iteration, the focus has shifted from providing an entirely 
>> undecorated window to providing a window with a user-configurable header bar.
>> 
>> The customizable header bar is a new layout container: 
>> `javafx.scene.layout.HeaderBar`. It has three areas that accept child nodes: 
>> leading, center, and trailing.  `HeaderBar` also automatically adjusts for 
>> the placement of the default window buttons (minimize, maximize, close) on 
>> the left or right side of the window.
>> 
>> The customizable header bar is combined with a new `EXTENDED` stage style, 
>> which extends the client area into the header bar area. The new extended 
>> stage style is supported on Windows, macOS, and Linux. For platforms that 
>> don't support this stage style, it automatically downgrades to `DECORATED`.
>> 
>> This is how it looks like on each of the three operating systems:
>> 
>> ![extendedwindow](https://github.com/user-attachments/assets/9d798af6-09f4-4337-8210-6eae91079d3a)
>> 
>> The window buttons (minimize, maximize, close) are provided by JavaFX, not 
>> by the application developer. This makes it easier to get basic window 
>> functionality without recreating the entirety of the window controls for all 
>> platforms.
>> 
>> ## Usage
>> This is a minimal example that uses a custom header bar with a `TextField` 
>> in the center area. `HeaderBar` is usually placed in the top area of a 
>> `BorderPane` root container:
>> 
>> public class MyApp extends Application {
>>     @Override
>>     public void start(Stage stage) {
>>         var headerBar = new HeaderBar();
>>         headerBar.setCenter(new TextField());
>> 
>>         var root = new BorderPane();
>>         root.setTop(headerBar);
>> 
>>         stage.setScene(new Scene(root));
>>         stage.initStyle(StageStyle.EXTENDED);
>>         stage.show();
>>     }
>> }
>> 
>> To learn more about the details of the API, refer to the documentation of 
>> `StageStyle.EXTENDED` and `HeaderBar`.
>> 
>> ## Platform integration
>> The implementation varies per platform, and ranges from pretty easy to quite 
>> involved:
>> 1. **macOS**: The window buttons are provided by macOS, we just leave an 
>> empty area where the window buttons will appear. The client area is extended 
>> to cover the entire window by setting the `NSW...
>
> Michael Strauß has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   revert unintended change

I would advise all commenters to look at the proposal which is presented, 
understand the trade-offs being made, and only then criticize the design 
decisions and offer suggestions.

This feature is designed in a particular way because it needs to work on _all_ 
supported platforms (not just the one you happen to like most). Here are the 
main design decisions that I made along the way:

### Multi-platform
Since JavaFX is a multi-plattform framework, this feature _must_ work out of 
the box on all supported platforms. It is a non-starter to require application 
developers to add platform-specific code to their applications if they want to 
use this feature.

This rules out things like requiring developers to add JavaFX shadows to their 
application because Linux doesn't provide the shadows for us. If we require 
JavaFX shadows, we must do that without intervention of application developers. 
We also shouldn't add platform-specific configuration switches.

### Ease of use
It must be easy to use. In particular, this means that default window 
interactions must work reliably and feel at home on the OS. If possible, we 
will use platform-native window buttons instead of crafting our own bespoke 
versions (the macOS implementation does just that).

If you look at many examples of applications that extend the client area into 
the title bar, you will notice that most good examples don't re-invent window 
buttons in their totality, but either use platform-native buttons or at least 
use lookalike-versions of the platform buttons.

Window buttons require quite a bit of effort to get it just right. It's way 
more effort than just throwing a bunch of buttons in the window corner and 
calling it a day. Window buttons need to interact with the OS in very specific 
ways to enable features like snap layouts (on Windows). Again, please 
understand the design constraints before offering alternatives.

### Customizability
It is an explicit non-goal of this PR to offer a way to customize the window 
buttons. That's because at least on macOS, there is simply no way to do that 
with the OS-native buttons. If we allowed for customization only for Windows 
and Linux, but not for macOS, we would again run into the problem of falling 
short of our multi-platform compatibility goal.

In addition to that, most application developers will not want to customize the 
window buttons. Just look at the examples of applications that have already 
been posted, and you'll notice that window buttons are not gratuitously 
different, they at least try to feel at home on the target OS.

Shifting all of the implementation burden for window buttons to application 
developers is the wrong framing for this feature. We're not trying to build a 
feature that mainly caters to the few applications with crazy custom user 
interfaces, we're trying to build a feature for the 99%.

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

PR Comment: https://git.openjdk.org/jfx/pull/1605#issuecomment-2429579311

Reply via email to