Open mgalos999 opened 1 year ago
Ok I think I have a fix, but I'm not sure if it will really do the job.
I think you just have to insert this in src/platform_impl/windows.rs
if self.contains(WindowFlags::TRANSPARENT) {
style_ex |= WS_EX_LAYERED;
}
Note you won't want to use the WS_EX_TRANSPARENT
style since that doesn't actually make the window transparent, it just makes mouse clicks passthrough
thanks for the report. It should work fine when actually drawing something onto the window surface, which the examples don't do. With the changes from the PR the screens windows will be completely invisible for me, no matter what I draw on it.
It should work fine when actually drawing something onto the window surface
However this would be an overhead for apps that don't need to draw the window surface, for example when using Webview2.
Transparency used to work out of the box for undecorated windows before https://github.com/rust-windowing/winit/pull/1933 . I really don't know what caused the regression or if it can be fixed but it is the reason why I kept TAO (the winit fork for WRY) using subclasses.
This could also be a blocker for us to migrate back to using winit directly.
Edit: Seems it is indeed #2419 not #1933, I thought it was #1933 because at the time I was testing it along with #1891 which is similar to #2419
I might be not understand how transparency works on windows, but aren't you required to provide a buffer with alpha value in the end?
Is it just blending with black background now if you draw into subview(not sure how that called on windows, but that's my understanding of what happens). You might just clear it with fully transparent color it or do something like.
Webview2 works a bit differently. I don't remember the correct term for it but it is a sort of a child window which has its own window surface. So in order to have transparency, we would need to draw the window surface which is just a bit annoying since we don't need to draw the window surface for any other purpose.
This could also be a blocker for us to migrate back to using winit directly.
Also this was an overstatement from me, I think I wanted to say it will be a minor setback.
In general if you don't feel the root window with something it could contain random data leading to graphical artifacts. Conveniently some GPU drivers do clear the buffer with zeros for you, so you have some sort of initialized thingy, but it's not always the case and on linux users can disable that for example leading you to blending with random data.
I'm not an expert here, but you should always explicitly initialize the buffers you blend against.
Window transparency is broken on Macos as well. This is a regression as it works if I use winit legacy (0.19.5) after some tweaks to make the compiler happy
I'm not sure what are you talking about, transparency works just fine on all the available backends, only example is broken, nothing more. Real code with e.g. OpenGL is not affected.
The transparent example also does not work on macos.
I dug a little bit, and I believe the bug is with the platform_impl/window.rs where the code is using the setOpaque method of NSWindow. As far as I can tell, this method is deprecated and no longer exists, and the NSWindow API created using objc2 crate is out of date. Because of the way message passing works in objective-C, it just fails silently. Does anyone know how to set a transparent background in NSWindow in modern AppKit? I tried adding the API for alphaValue, and it worked, but I think alphaValue affects the whole window and not just the background.
I'm not sure what are you talking about, transparency works just fine on all the available backends, only example is broken, nothing more. Real code with e.g. OpenGL is not affected.
You mean that using with_transparent will not work but using openGL on the context directly will? Can you provide an example, please?
idk, just run https://github.com/rust-windowing/glutin example from here, it's transparent. There's also alacritty which uses Opaque
hints and has transparency. Also, softbuffer, which we're using for examples don't support transparency at all as of now...
setOpaque
definitely exists, it's just documented as opaque
due to how Objective-C renames property setters.
Because of the way message passing works in objective-C, it just fails silently.
Nope, that would've thrown an error. It only does that if the receiver/window is NULL.
@ericguedespinto Do you have a minimal reproducible example for the MacOS behavior? If yes, could you open a new issue for that? If not, could you try out https://github.com/rust-windowing/winit/pull/3048 ?
are any workarounds available? Transparency also is not working for me as well.
having the same issue here, reported to RioTerm as well: https://github.com/raphamorim/rio/issues/361
idk, just run https://github.com/rust-windowing/glutin example from here, it's transparent. There's also alacritty which uses
Opaque
hints and has transparency. Also, softbuffer, which we're using for examples don't support transparency at all as of now...
Could you provide some more guidance?
can confirm the glutin example works for me
from their readme:
git clone https://github.com/rust-windowing/glutin
cd glutin
cargo run --example window
can correctly see my web browser through the transparent window
Edition Windows 10 Pro
Version 22H2
Installed on 2020-11-03
OS build 19045.4291
Experience Windows Feature Experience Pack 1000.19056.1000.0
Quite right, I forgot versioning information, doubling down:
~\src\glutin> cargo run --example window
warning: unused import: `std::mem`
--> C:\Users\raggi\src\glutin\target\debug\build\glutin_wgl_sys-580181e13c8eaeb7\out/wgl_bindings.rs:3:21
|
3 | pub use std::mem;
| ^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: `glutin_wgl_sys` (lib) generated 1 warning (run `cargo fix --lib -p glutin_wgl_sys`
to apply 1 suggestion)
Finished dev [unoptimized + debuginfo] target(s) in 2.01s
Running `target\debug\examples\window.exe`
Picked a config with 16 samples
Running on NVIDIA GeForce RTX 4090/PCIe/SSE2
OpenGL Version 3.3.0 NVIDIA 551.86
Shaders version on 3.30 NVIDIA via Cg compiler
OS Name: Microsoft Windows 11 Pro
OS Version: 10.0.22631 N/A Build 22631
~\src\glutin> rustc --version
rustc 1.77.2 (25ef9e3d8 2024-04-09)
~\src\glutin> g log --oneline -n1
9228126 (HEAD -> master, origin/master, origin/HEAD) ci: add typos
Also to confirm, here's transparency effects from native composited windows:
You might have to check your NVIDIA driver settings in case some presentation compatibility has been set. The WSI parts of OpenGL and Vulkan are unfortunately not great. Using DXGI/DirectComposition should give more control.
Is there any solution at present?
This has been fixed? Just set the alpha channel of color DARK_GRAY
and it's working for me.
Tested with v0.30.5 on Windows11:
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::{Window, WindowId};
#[path = "util/fill.rs"]
mod fill;
#[derive(Default)]
struct State {
window: Option<Window>,
}
impl ApplicationHandler for State {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let attributes = Window::default_attributes().with_transparent(true);
self.window = Some(event_loop.create_window(attributes).unwrap());
}
fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
_window_id: WindowId,
event: WindowEvent,
) {
let window = self.window.as_ref().unwrap();
match event {
WindowEvent::CloseRequested => event_loop.exit(),
WindowEvent::RedrawRequested => {
fill::fill_window(&window);
},
_ => (),
}
}
}
fn main() {
let event_loop = EventLoop::new().unwrap();
let mut state = State::default();
let _ = event_loop.run_app(&mut state);
}
Screenshot:
When I run
cargo run --example transparent
instead of a transparent window I just get a white window with no decorations.It seems the problem was introduced in this PR: https://github.com/rust-windowing/winit/pull/2419 If I revert to a commit before that PR was merged, then I see no GUI window showing up at all which I believe is the intended result (I see the icon in the taskbar and it appears in the alt+tab window list).
When I run the transparent example on the latest commit I just get a white window (with the expected icon in the taskbar)
I am running Windows 10.