benfry / processing4

Processing 4.x releases for Java 17
https://processing.org
Other
1.35k stars 237 forks source link

Implement dark mode for window title frame on Windows and Linux #699

Open Perverance opened 1 year ago

Perverance commented 1 year ago
## Description Hi all! I'm not sure if this is the right place. In short, I'd like to see an option to change the windows title frame color to a dark or custom one. As far I know, themes cannot change the default white color of the window title, it seems to be the only element which color cannot be changed. I'd like to have an option to change it to match the OS dark mode, but I'm not sure how hard could it be to implement it. Thank you! <3

Current Behavior

I don't find this option, the

Your Environment

RichardDL99 commented 1 year ago

Just to confirm, I changed all the colours in theme.txt to yellow, and the run window title is still white.

mglst commented 1 year ago

I have taken a look at this. Of relevance is the FlatLaf macOS page, which has been the guide for the experimentation which follows.

Dark Window Title Bar - Unsuccessful Attempt

My first thought was to attempt to use a dark window title bar. The section titled "Appearance of window title bars" gives instructions for this. Seemingly, using System.setProperty( "apple.awt.application.appearance", "system" ); (or replacing "system" with "NSAppearanceNameAqua" or "NSAppearanceNameDarkAqua") should do this.

However, I did not have any success. My attempted modification added the suggested line in processing.app.platform.MacPlatform, just after line 65 which already sets system properties pertaining to Look & Feel: System.setProperty("apple.laf.useScreenMenuBar", "true");. The FlatLaf pages does have as a note "must be set on main thread and before AWT/Swing is initialized; setting it on AWT thread does not work"; but my understanding is that this should be the case. Indeed, when processing is launched, processing.app.ui.Splash is the start point, which in turn invokes processing.app.Base; first an instance of Base is instantiated, and the constructor for Base has Platform.initBase(this); which should in turn call initBase(base); on MacPlatform, which is precisely where I set the relevant system properties. One Base is initialised, its main method can be invoked, which queues up createAndShowGUI, which calls Platform.setLookAndFeel();, which calls DefaultPlatform's setLookAndFeel();, which deals with FlatLightLaf. Nevertheless, I have not managed to get it to work and I do not understand why.

tl:dr; I tried to make the title bar dark by adding System.setProperty("apple.awt.application.appearance", "NSAppearanceNameDarkAqua"); to app/src/processing/app/platform/MacPlatform.java on line 66 and it did not work.

Transparent title bar - Some Success

A further section in the FlatLaf guide mentions transparent title bars, so I tried to implement that. In processing.app.ui.Editor I added getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true ); to the end of the updateTitle method. I don't believe this is where it should be placed, but it worked well enough for testing purposes. Also I skipped checking for SystemInfo.isMacFullWindowContentSupported unlike what the guide instructs. This modification on its own made no difference unfortunately, and I do not know why.

However, enabling full window content in conjunction with making the title bar transparent did lead to a change! This involved having the additional frame.getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );.

Using the bottom-left dark theme, here is what a Processing window usually looks like:

Screenshot 2023-07-18 at 02 20 42

And both full window content and a transparent title bar on my current experimental build:

Screenshot 2023-07-18 at 02 20 02

This seems quite promising to me, and I hope you will agree! That being said, there are two immediate issues that I see with this:

There may be multiple ways of fixing the first issue. The one which seems the least disruptive to me is to shift the entire UI down as if full window content were not enable; after all the sole reason I enabled it was because it seemingly was necessary to make the transparent title bar work. That being said, I think there is a definite point to made about maximising the usage of vertical screen space. I have often found myself wishing that I could fit more lines of code into the Processing editor, and have been frustrated that the top and bottom UI elements take up much of it.

For the second point about the title being illegible, this should be fairly easy to fix. That being said, perhaps there are accessibility reasons to want to want to maintain macOS default UI elements such as the title bar. Perhaps pushing simply for a dark mode title bar after all is better.

This is the progress I have made so far on this issue. I have published my changes in a fork.

benfry commented 1 year ago

Thanks for looking into it! The trick is that apple.awt.application.appearance has to be set before AWT (any GUI) is initialized. Earliest possible is just before the splash screen is invoked, but a simpler option is to add it to Info.plist in the macOS .app package. That change is now here: https://github.com/processing/processing4/commit/b1b8d3b4548098354829c2dcc1f2b89f639c26a9 so it resolves the problem for macOS and will be available in the next release (4.2.1 or 4.3).

Now changing the issue title to be specific to Windows and Linux since it's now resolved for macOS.