HumbleUI / JWM

Cross-platform window management and OS integration library for Java
Apache License 2.0
552 stars 44 forks source link

macOS titlebar options #181

Closed mworzala closed 2 years ago

mworzala commented 2 years ago

Implements titlebar customization as outlined in #75 for macOS.

Missing user drag regions Missing some javadocs

Some behaviors:

What is the policy on what goes in WindowMac vs existing only in JNI methods?

mworzala commented 2 years ago

I am still able to drag the window near the top when using a full size content area.

This has to do with title visibility. If the title is invisible you cannot drag anywhere. If the title is visible, then you can drag anywhere at or above the title height. The subtitle is not included (eg you cannot drag over the subtitle)

tonsky commented 2 years ago

Thank you for your quick PR! I merged it with minor change: I renamed constants in WindowMacTitlebarStyle to match macOS names.

I also added two ways to test this. First is Cmd+T, it switches titlebar of current window. Second is Cmd+N, each new window will be created with new titlebar style (there are 7 total, see PanelScreens.java).

These are different codepaths and we need them both to work. But I feel like the experience of changing window style on the fly is not that important. Most of the time you set the style before creating window (what Cmd+N tests).

I also realized that setTitle(null) is not such a great idea because title is used in e.g. Expose. I guess we’ll need another way of adding traffic light to titleless window. I am also happy to only allowing this when titlebar is hidden (makes little sense in all other cases).

Couple of other issues:

I have some experience trying to tame traffic light. I think what Electron does is the most reliable way. IIRC it puts default buttons into its own View and then positions that container in main window. Positioning individual buttons won’t work. Another crucial (and very obscure) detail is that container that contains those buttons must respond to some selectors, otherwise it will behave weird. See https://stackoverflow.com/a/30417372/142655

I would greatly appreciate help with any of that.

mworzala commented 2 years ago

If you have experience I will let you tackle the traffic light positioning, this is my first time trying to modify them and I am not surprised I missed something.

Is there any reason we cannot treat window.setTitlebarVisible(false) as simply full size content view + hide title + hide traffic lights instead of actually removing NSWindowStyleMaskTitled? (which as you mentioned causes weird behavior and it removes corner rounding on the window)

This does create some potentially weird cases where you could do something like

window.setTitlebarVisible(false);
window.setFullSizeContentView(false);

and then the titlebar would come back. Of course this could be solved by ignoring any calls to full size content view while the titlebar is gone.

because title is used in e.g. Expose

I am not sure what this means. I also do not have a better idea for getting rid of the title than WindowMac#setTitleVisible(boolean), but it still has an exclusivity issue with invisible titlebar.

Both the Window#focus() and lack of keyboard input with invisible titlebar appear to be caused by this. Looks like a simple fix, however, it would also be fixed by my previous comment regarding not actually removing the titled style.

tonsky commented 2 years ago

If you have experience I will let you tackle the traffic light positioning, this is my first time trying to modify them and I am not surprised I missed something.

Got it https://github.com/HumbleUI/JWM/issues/183

Is there any reason we cannot treat window.setTitlebarVisible(false) as simply full size content view + hide title + hide traffic lights instead of actually removing NSWindowStyleMaskTitled?

That’s what we probably should do, yes. Is there a NSWindow method to hide window title instead of setting it to empty string? I am worried about latter, because window should keep its title, it should just be invisible. If yes, I am happy.

Just to clarify: we keep window.setTitlebarVisible(false); in Java API (because it’s cross-platform) but under-the-hood it will hide title, traffic light and make full sized content view, right?

mworzala commented 2 years ago

Is there a NSWindow method to hide window title instead of setting it to empty string

Its possible I'm misunderstanding, but there is the titleVisibility property which can be used to hide the titlebar (without touching the underlying string). I am not sure how it works internally.

Just to clarify: we keep window.setTitlebarVisible(false); in Java API (because it’s cross-platform) but under-the-hood it will hide title, traffic light and make full sized content view, right?

Yep this is what I was thinking, I can work on this.

tonsky commented 2 years ago

titleVisibility

Sounds like just what we need!