rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.55k stars 876 forks source link

macOS: fix opacity handling #3722

Closed kchibisov closed 2 weeks ago

kchibisov commented 3 weeks ago

Not using NSColor::clearColor() results in Quartz thinking that the window is not transparent at all, which results in artifacts.

However, not setting the windowBackgroundColor in Window::set_transparent results in border not properly rendered.

Fixes: 94664ff6876cd (Don't set the background color)

--

This is kind of a revert, given that https://github.com/alacritty/alacritty/pull/7965 not really doing anything and the window is not really tranparent as it should (it kind of is, but the value is different to what it should be and Quartz glitches behind the window with damage tracking).

Though, Quartz seems to generally glitch with e.g. shadows if you reload opacity with these changes as well. Maybe we should do something completely different, but I only care to fix the regression.

kchibisov commented 3 weeks ago

I mean, that breaks not only alacritty, but basically everything that wants to put something transparent on screen, like glutin example, etc, etc.

kchibisov commented 3 weeks ago

I'd also note, that it won't align with how all platforms work in winit, so not setting proper transparency sounds like we're not trying to do reliable cross platform behavior.

kchibisov commented 2 weeks ago

And indeed for all of them, the correct behaviour is to set the background color to clearColor, setOpaque didn't seem to even do anything (!).

setOpaque is a hint for compositor and nothing more, IIRC. Which means that handling it reduces the load on the compositor, but that's about it. It doesn't actually check whether something is opaque/not.

Also noting for the future: -[NSWindow setAlphaValue:] is similar to what we're doing here, but distinct in that it sets the opacity of the entire window, including decorations / title bar, and this cannot be "overridden" by rendering something with full opacity.

This is not desired in most cases, because it makes the text transparent as well. So should just leave it.