-
Notifications
You must be signed in to change notification settings - Fork 36
Add some macOS support #143
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: main
Are you sure you want to change the base?
Conversation
Note: This will enforce window transparency implying a borderless
window. Vice versa, if window decorations are to be drawn, the window
cannot be transparent. This seems to be required on some platforms,
at least on macOS [1]. See further down to the implications of this
change.
Until now, window transparency is set on the project level through
`display/window/size/transparent`. However, since the application starts
in non-borderless mode, Godot (on macOS) will reset this window flag to
non-transparent. Since, all subsequent calls to
`set_background_transparency` only set the inherited `transparent_bg`
property of the root Window/Viewport but not re-enable said window
manager flag, the application will remain non-transparent. Thus,
enabling window transparency won't work at all on these platforms, even
when the option to hide window decorations is enabled and the UI
elements are disabled using Esc.
In order to fix this, window transparency must be tied to hiding window
decorations. This limitation leads to some UX considerations due to
necessary behavior changes.
Currently, the following combinations are possible
| Win Transp | Deco Hidden | UI Hidden |
|------------|-------------|-----------|
| -/x | - | - |
| -/x | - | x |
| -/x | x | x |
On some platforms (such as macOS) where window decorations *must* be
hidden when the background is transparent and vice-versa, we'd need to
get rid of all combinations of the window being transparent while the
decorations are not hidden:
| Win Transp | Deco Hidden | UI Hidden |
|------------|-------------|-----------|
| - | - | - |
| - | - | x |
| -/x | x | x |
This would have the forced effect that pressing Esc whilst having
everything hidden would not only show the UI and decorations, but also
make the window intransparent again.
It is however possible to implement a new mode where the window remains
transparent (and thus window decorations aren't shown) but the UI can be
shown:
| Win Transp | Deco Hidden | UI Hidden |
|------------|-------------|-----------|
| - | - | - |
| - | - | x |
| -/x | x | x |
| x | x | - |
This new mode would mean decoupling the logic of hiding decorations only
when the other UI elements are hidden as well. There's also the
possibility of adding an option where the window is shown/intransparent
and the UI elements are shown, but the decorations are hidden.
| Win Transp | Deco Hidden | UI Hidden |
|------------|-------------|-----------|
| - | - | - |
| - | - | x |
| -/x | x | x |
| -/x | x | - |
I don't see merit in this mode however, really. Thus, I've decided to
implement the following logic and settings:
* Esc remains as a toggle for UI hidden/non hidden, it does not affect window decorations anymore
* There's a drop down to show all, hide scenary only (i.e., disable window transparency) or both scenary and window decorations
Since any enabling of the window decoration will disable the window
transparency hint, this hint must be set dynamically rather than through
the project settings. So I've re-added the functionality from the commented code in a new function `set_window_transparency`
```patch
-# DisplayServer.window_set_flag(
-# DisplayServer.WINDOW_FLAG_TRANSPARENT, true,
-# DisplayServer.MAIN_WINDOW_ID)
+ get_tree().get_root().set_flag(Window.FLAG_TRANSPARENT, hide_window_elements > 1)
```
I've also moved the logic setting the Viewport's background there, since
it belongs logically to setting the Window's transparency anyway and on
newer Godot this is already implied by having the Window's transparency
flag set [2].
```
-# get_viewport().transparent_bg = true
-# get_tree().root.transparent_bg = true
- get_tree().get_root().set_transparent_background(true) # Needed for compatibility mode.
+ if (ProjectSettings.get_setting("rendering/renderer/rendering_method") == "compatibility"):
+ # Newer renderer automatically sets the Viewport's transparent_bg property
+ # if the windows transparent flag is set.
+ get_tree().get_root().set_transparent_background(hide_window_elements > 1)
```
[1]: https://github.com/godotengine/godot/blob/4.4/platform/macos/display_server_macos.mm#L2653
[2]: godotengine/godot#87856
If global menus are available and used, the menubar is moved outside the window and doesn't require a background.
No need to have this in 3D
| Settings -> Window... -> Transparent background | ||
|
|
||
| Should work with OBS Xcomposite capture. | ||
| Should work with OBS (Linux Xcomposite/macOS Screen Capture/...) capture. |
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.
"Capture capture" ?
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.
Heh, true. I just added the OBS capture source name which includes "Capture" already. OBS is a bit inconsistent here: On Linux it just displays "Window Capture (Xcomposite)". On macOS it displays the OS as well "macOS Screen Capture" and doesn't say "Window Capture", even if you set it up to capture just a Window.
Either way, it'd be probably clearer if this bit read:
- "Should work with OBS (Linux: Xcomposite, macOS: Screen Capture, ...)
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.
Please note, obs on Linux also can use pipewire to capture windows on wayland. This is how I've been streaming and I can confirm it works
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 just simplify it and say "OBS window/screen capture (Linux/macOS)", at least if you're implying that transparent window capture doesn't work on Windows – that I don't know. It it works on all three major OSes, then the part in brackets can be left out entirely.
|
This breaks functionality on Windows and Linux, by not allowing window decorations with a transparent window, which is my primary way of using this software. |
ExpiredPopsicle
left a comment
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.
Separate transparency and window decoration settings must be maintained for Linux and Windows. Otherwise this breaks my own usage.
Hey, nice work!! :3
Thanks to Godot basically everything works OOTB on macOS :-)
However there's one small issue with a limitation on macOS that window transparency doesn't work with enabled window decorations. This means I had to change some logic to allow for window transparency on that platform w/o special-casing too much: I've decoupled the UI hiding toggle from the window decoration hiding logic and instead shoved the latter into a drop-down menu, together with hiding the background. Now, Esc only shows/hides UI elements other than window decorations and background. I've added my rationale for that in the first commit.
Another small change that only affects macOS however, is to hide/remove the black stripe behind the MenuBar, because for global menus that's not necessary. In theory, one could think about actually not hiding the MenuBar at all (even with Esc) on such platforms I guess, but I didn't manage that w/o screwing up the UI.
I've shoved a small misc. and a documentation fix into this PR as well.