Skip to content
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

Transparent example not working #2502

Open
mgalos999 opened this issue Sep 23, 2022 · 26 comments · May be fixed by #2503
Open

Transparent example not working #2502

mgalos999 opened this issue Sep 23, 2022 · 26 comments · May be fixed by #2503
Labels
B - bug Dang, that shouldn't have happened DS - windows

Comments

@mgalos999
Copy link

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:
#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.

@madsmtm madsmtm added B - bug Dang, that shouldn't have happened DS - windows labels Sep 23, 2022
@mgalos999
Copy link
Author

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

@mgalos999 mgalos999 linked a pull request Sep 23, 2022 that will close this issue
@msiglreith
Copy link
Member

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.

@amrbashir
Copy link
Contributor

amrbashir commented Oct 10, 2022

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 #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

@kchibisov
Copy link
Member

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.

@amrbashir
Copy link
Contributor

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.

@kchibisov
Copy link
Member

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.

@ericguedespinto
Copy link

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

@kchibisov
Copy link
Member

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.

@ericguedespinto
Copy link

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.

@ericguedespinto
Copy link

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?

@kchibisov
Copy link
Member

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...

@madsmtm
Copy link
Member

madsmtm commented Aug 4, 2023

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.

@stefnotch
Copy link

stefnotch commented Aug 25, 2023

@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 #3048 ?

@CoryRobertson
Copy link

are any workarounds available? Transparency also is not working for me as well.

@orhun
Copy link

orhun commented Dec 2, 2023

having the same issue here, reported to RioTerm as well: raphamorim/rio#361

@raggi
Copy link
Contributor

raggi commented Apr 14, 2024

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...

image

Could you provide some more guidance?

@TeamDman
Copy link

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

image

Edition	Windows 10 Pro
Version	22H2
Installed on	‎2020-‎11-‎03
OS build	19045.4291
Experience	Windows Feature Experience Pack 1000.19056.1000.0

@raggi
Copy link
Contributor

raggi commented Apr 17, 2024

Quite right, I forgot versioning information, doubling down:

image

~\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:
image

@msiglreith
Copy link
Member

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.

@han1548772930
Copy link

Is there any solution at present?

@Long0x0
Copy link

Long0x0 commented Aug 25, 2024

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:

TheAlan404 added a commit to TheAlan404/winit that referenced this issue Sep 22, 2024
TheAlan404 added a commit to TheAlan404/winit that referenced this issue Sep 22, 2024
TheAlan404 added a commit to TheAlan404/winit that referenced this issue Sep 22, 2024
@TeamDman
Copy link

This has been fixed? Just set the alpha channel of color DARK_GRAY and it's working for me.

Cannot confirm, this transparency example does not work for me.

winit on  HEAD (114512b) [$?] is 📦 v0.30.5 via 🦀 v1.82.0-nightly 
❯ cargo run --example dark_grey
   Compiling dpi v0.1.1 (D:\Repos\rust\winit\dpi)
   Compiling raw-window-handle v0.5.2
   Compiling winit v0.30.5 (D:\Repos\rust\winit)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4.61s
     Running `target\debug\examples\dark_grey.exe`
OS: Windows_NT x64 10.0.19045

image

@kchibisov
Copy link
Member

I'm pretty sure softbuffer doesn't handle alpha channel, but generally has nothing to do with e.g. winit.

Try https://github.com/rust-windowing/glutin/ example, it's transparent by default, if it's not then it's likely something to do with winit.

@TeamDman
Copy link

I'm pretty sure softbuffer doesn't handle alpha channel, but generally has nothing to do with e.g. winit.

Try https://github.com/rust-windowing/glutin/ example, it's transparent by default, if it's not then it's likely something to do with winit.

Can confirm that the glutin example works for me #2502 (comment)

@kchibisov
Copy link
Member

Then it works, since glutin explicitly draws transparent content.

@Long0x0
Copy link

Long0x0 commented Oct 16, 2024

I'm pretty sure softbuffer doesn't handle alpha channel

Weird...
I tried another desktop Windows 10 and a Windows 10 VM, freshly installed Rust and built the example I mentioned above with DARK_GRAY = 0x00181818, both got transparent windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B - bug Dang, that shouldn't have happened DS - windows
Development

Successfully merging a pull request may close this issue.