On Tue, 7 Jul 2026 22:53:45 GMT, Martin Fox <[email protected]> wrote:

>> This PR enables translucent window backdrops for JavaFX stages on macOS and 
>> Windows 11. Since we’re reliant on the operating system for these effects 
>> (they typically require real-time blurring of the desktop) I needed to flesh 
>> out a fairly complete prototype to sort out the API. I will start a 
>> discussion about the API on the mailing list.
>> 
>> There’s a crude manual test for trying out the different backdrop materials.
>> 
>>      java @build/run.args -Djavafx.enablePreview=true 
>> tests/manual/stage/BackdropTest.java
>> 
>> You’ll want to drag the windows around to avoid having them overlap each 
>> other since they’re all created in the center of the screen. For windows 
>> without title bars you can click anywhere on the background to drag the 
>> window except for TRANSPARENT stages on Windows which are a bit tricker to 
>> get a hold of; try to click on a text label.
>> 
>> If you create an UNDECORATED stage on Windows the backdrop won’t be 
>> translucent initially. This can be corrected by changing the stage’s color 
>> scheme. This is an OS bug that I haven’t found a workaround for.
>> 
>> The changes on Windows 11 are minimal since we’re just invoking an OS 
>> feature by calling DwmSetWindowAttribute. I did need to make two small 
>> changes to the D3D9 Prism code to ensure that the swap chain and back buffer 
>> support an alpha channel so JavaFX can composite its content on top of the 
>> backdrop. This is the same way the old UNIFIED stage style worked before it 
>> became unreliable (see 
>> [JDK-8154847](https://bugs.openjdk.org/browse/JDK-8154847)).
>> 
>> On macOS I moved the GlassHostView so it’s now a permanent part of the 
>> NSWindow. For some time the host view has been a remnant left over from an 
>> older approach to implementing fullscreen. Now it serves as a common parent 
>> for the NSVisualEffectView that provides the backdrop and the GlassView3D 
>> that contains the JavaFX content. Making it the permanent contentView of the 
>> NSWindow simplifies some code.
>> 
>> To validate the API I did prototype this for Windows 10 (thanks @mstr2!). 
>> Well, I prototyped this using DirectComposition so it should work on Win10 
>> but I can't test Win10 myself. Using DirectComposition is much more involved 
>> so I shelved that implementation for now but it does inform the API. It’s 
>> the reason the backdrop needs to be specified before the Java window is 
>> shown and the platform window created.
>> 
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the 
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> Martin Fox has updated the pull request with a new target base due to a merge 
> or a rebase. The pull request now contains 16 commits:
> 
>  - Merge remote-tracking branch 'upstream/master' into osbackdrop
>  - Remove duplicate Mac backdrop styles, add HUD on Mac
>  - Removing unused imports, duplicate comments and code
>  - Merge remote-tracking branch 'upstream/master' into osbackdrop
>  - Distinguishing between the backdrop style and the actual stage-specific 
> backdrop.
>  - Merge remote-tracking branch 'upstream/master' into osbackdrop
>  - Merge remote-tracking branch 'upstream/master' into osbackdrop
>  - New version of StageBackdrop API, separated into standard and platform 
> variants
>    
>    commit dee190390d147e9032a734ab0abaab752e308c76
>    Author: Martin Fox <[email protected]>
>    Date:   Wed May 20 06:18:23 2026 -0700
>    
>        More minor cleanup
>    
>    commit 457c7eb99affd42f67dedb2c760fa639a88943b9
>    Author: Martin Fox <[email protected]>
>    Date:   Tue May 19 19:33:15 2026 -0700
>    
>        Cleaning up imports, comments, etc.
>    
>    commit 947a5e3598fd0e1b8f69747314405519a8a8794d
>    Author: Martin Fox <[email protected]>
>    Date:   Tue May 19 16:16:23 2026 -0700
>    
>        Disabling macOS 26 Liquid Glass effect
>    
>    commit 9c3d0389f3687504411fc840ecb878ebe9608e36
>    Author: Martin Fox <[email protected]>
>    Date:   Tue May 19 16:14:19 2026 -0700
>    
>        Backdrop options are now dynamic and set on the stage.
>    
>    commit 7d61c2b9bc15a7bdc7c79b0ddde651678404f065
>    Author: Martin Fox <[email protected]>
>    Date:   Tue May 19 11:15:09 2026 -0700
>    
>        Added options query and simplified Windows implementation
>    
>    commit c1514f348f9e1d9d3761aec9786dda25e12fa588
>    Author: Martin Fox <[email protected]>
>    Date:   Mon May 18 12:07:40 2026 -0700
>    
>        Revamped StageBackdrop API, splitting standard and platform backdrops 
> and adding options
>    
>    commit 608cfa631967470bdbfc02a5b30e55ab3c932d32
>    Merge: 551c9ec336 7110a0940d
>    Author: Martin Fox <[email protected]>
>    Date:   Thu May 14 07:08:44 2026 -0700
>    
>        Merge branch 'osbackdrop' into osbackdrop_dev
>    
>    commit 551c9ec336d9e6d3f90e37b278dc17df9a9bca03
>    Author: Martin Fox <[email protected]>
>    Date:   Wed Apr 8 08:51:49 2026 -0700
>    
>        Cleanup.
>    
>    commit c2e8ec8afc4df2dbd529470761b500e4d670bbeb
>    Author: Martin Fox <[email protected]...

I think the main point of tension in the API is that we have two seemingly 
different forms of backdrops:
1. Constant backdrops: `WINDOW` and `PARTIAL`, which are exposed as static 
fields.
2. Configurable backdrops, which include dynamic parameters that can change at 
runtime.

Your solution is to split off the "class" of the backdrop from the 
configuration object: `StageBackdropStyle` is the "class", and `StageBackdrop` 
is an object that can hold dynamic parameters. However, the way you've designed 
this -- call `initBackdropStyle()` and then a configuration object is created 
for you that you can access with another API -- that's not a pattern that is 
used anywhere else in JavaFX (that I know of).

I think there shouldn't be two API elements to configure a single aspect about 
the `Stage`, it should be a single API element. Instead, move the complexity 
from `Stage` to `StageBackdrop`.

Here are two other ideas how you could achieve that:
1. Have a separate `ConfigurableStageBackdrop` interface that enables you to 
set dynamic options. This is not implemented by the `WINDOW` and `PARTIAL` 
constants, which is why they can be constants in the first place:
    ```java
    public sealed interface StageBackdrop permits StandardStageBackdrop, 
ConfigurableStageBackdrop {
        StageBackdrop WINDOW = StandardStageBackdrop.WINDOW;
        StageBackdrop PARTIAL = StandardStageBackdrop.PARTIAL;
        
        static StageBackdrop of(String name);
        static ConfigurableStageBackdrop ofConfigurable(String name);
    }

    public interface ConfigurableStageBackdrop extends StageBackdrop {
        void setOption(String key, Object value);
    }
    ```

2. If you expect that we might add options to the predefined constants, then 
that's a strong argument that these shouldn't be constants in the first place, 
and that _all_ backdrops should be able to carry options:
    ```java
    public final class StageBackdrop { // maybe implement Map<String, Object>
        private StageBackdrop();

        public static StageBackdrop newWindowStyle();
        public static StageBackdrop newPartialStyle();
        public static StageBackdrop newPlatformStyle(String styleName, 
Supplier<StageBackdrop> fallback);

        public StageBackdrop setOption(String key, Object value);
    }
    ```
    In this example, the API forces callers to provide a fallback backdrop in 
case the named backdrop is not available. This ensures that developers don't 
need to worry about `null`:
    ```java
    var backdrop = StageBackdrop.newPlatformStyle("macOS.ClearGlass", 
StageBackdrop::newWindowStyle)
                                .setOption("TintColor", Color.RED);
    // backdrop is not null
    ```


Looking forward, we'll want to also support translucent backdrops on Linux at 
some point in the future. With GTK4/Wayland, we could use 
[ext-background-effect-v1](https://wayland.app/protocols/ext-background-effect-v1#ext_background_effect_surface_v1:request:set_blur_region)
 to achieve that, which says: "The blur algorithm is subject to compositor 
policies."
I'm bringing this up because platform implementations might not only allow 
developers to use _more_ types of backdrops, but also come with restrictions 
that allow no choice at all: In this case, there would be no difference between 
`WINDOW` and `PARTIAL` on Linux. Maybe this means our API should only have a 
single default backdrop, and for all other backdrops, you'd use 
platform-specific names? In this case, a potential API could be reduced to just:

public final class StageBackdrop { // maybe implement Map<String, Object>
    private StageBackdrop();

    public static StageBackdrop newDefaultStyle();
    public static StageBackdrop newPlatformStyle(String styleName); // if not 
available, returns default style

    public StageBackdrop setOption(String key, Object value);
}



Another aspect we should consider is the interaction with 
`Scene.Preferences.reducedTransparency`: This preference can be toggled at 
runtime, potentially by users of the application. Should it have an effect on a 
potential translucent window background?


> I want to proceed with the CSR but am having difficulty creating the 
> specification diff files. Perhaps I'm overlooking something obvious or my 
> Google-Fu is weak today but I can't find clear instructions on how to create 
> API diffs. Any pointers would be appreciated.

The diffs are 
[here](https://github.com/openjdk/jfx/pull/2048#issuecomment-3781001757).

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

PR Comment: https://git.openjdk.org/jfx/pull/2048#issuecomment-4921252001

Reply via email to