Skip to content

Transparent windows in Wayland are opaque #5779

Closed
@Hoverbear

Description

@Hoverbear

Bevy version

0.7.0, 0.8.1 or 0.9.0-dev

[Optional] Relevant system information

Rust:

❯ rustc --version
rustc 1.63.0 (4b91a6ea7 2022-08-08)

Adapter:

2022-08-23T23:51:13.144078Z  INFO bevy_render::renderer: AdapterInfo { name: "AMD RADV NAVI10", vendor: 4098, device: 29471, device_type: DiscreteGpu, backend: Vulkan }

On Arch Linux, using Gnome (in Wayland mode)

image

What you did

From a freshly cloned repository I ran:

cargo run --example transparent_window --features x11, yielding:

image

cargo run --example transparent_window --features wayland, yielding:

image

I attempted to update winit using the dependabot/cargo/winit-0.27.2 branch (#5701) with this patch, but it did not solve it:

Patch
diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs
index b48dd441..b9512340 100644
--- a/crates/bevy_winit/src/lib.rs
+++ b/crates/bevy_winit/src/lib.rs
@@ -4,6 +4,7 @@ mod web_resize;
mod winit_config;
mod winit_windows;

+use winit::window::CursorGrabMode;
pub use winit_config::*;
pub use winit_windows::*;

@@ -138,7 +139,7 @@ fn change_window(
               bevy_window::WindowCommand::SetCursorLockMode { locked } => {
                   let window = winit_windows.get_window(id).unwrap();
                   window
-                        .set_cursor_grab(locked)
+                        .set_cursor_grab(if locked { CursorGrabMode::Locked } else { CursorGrabMode::None })
                       .unwrap_or_else(|e| error!("Unable to un/grab cursor: {}", e));
               }
               bevy_window::WindowCommand::SetCursorVisibility { visible } => {
diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs
index 91550eef..91375f22 100644
--- a/crates/bevy_winit/src/winit_windows.rs
+++ b/crates/bevy_winit/src/winit_windows.rs
@@ -2,7 +2,7 @@ use bevy_math::IVec2;
use bevy_utils::{tracing::warn, HashMap};
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
use raw_window_handle::HasRawWindowHandle;
-use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
+use winit::{dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, window::CursorGrabMode};

#[derive(Debug, Default)]
pub struct WinitWindows {
@@ -156,7 +156,7 @@ impl WinitWindows {
       let winit_window = winit_window_builder.build(event_loop).unwrap();

       if window_descriptor.cursor_locked {
-            match winit_window.set_cursor_grab(true) {
+            match winit_window.set_cursor_grab(CursorGrabMode::Locked) {
               Ok(_) | Err(winit::error::ExternalError::NotSupported(_)) => {}
               Err(err) => Err(err).unwrap(),
           }
@@ -238,7 +238,7 @@ pub fn get_fitting_videomode(
       match abs_diff(a.size().width, width).cmp(&abs_diff(b.size().width, width)) {
           Equal => {
               match abs_diff(a.size().height, height).cmp(&abs_diff(b.size().height, height)) {
-                    Equal => b.refresh_rate().cmp(&a.refresh_rate()),
+                    Equal => b.refresh_rate_millihertz().cmp(&a.refresh_rate_millihertz()),
                   default => default,
               }
           }
@@ -255,7 +255,7 @@ pub fn get_best_videomode(monitor: &winit::monitor::MonitorHandle) -> winit::mon
       use std::cmp::Ordering::*;
       match b.size().width.cmp(&a.size().width) {
           Equal => match b.size().height.cmp(&a.size().height) {
-                Equal => b.refresh_rate().cmp(&a.refresh_rate()),
+                Equal => b.refresh_rate_millihertz().cmp(&a.refresh_rate_millihertz()),
               default => default,
           },
           default => default,

I then attempted to replicate the issue in winit using the latest main, however winit won't draw wayland windows (note) so I couldn't replicate.

The example in winit ran but did not produce a visual window:

winit on  master is 📦 v0.27.2 via 🦀 v1.63.0 
❯ cargo run --example transparent --features wayland
    Blocking waiting for file lock on build directory
    Finished dev [unoptimized + debuginfo] target(s) in 3.91s
     Running `target/debug/examples/transparent`
2022-08-24T00:46:14.093Z TRACE [crossfont::ft::fc::font_set] Number of fonts is 175
2022-08-24T00:46:14.094Z TRACE [crossfont::ft] Got font path="/usr/share/fonts/noto/NotoSans-Regular.ttf", index=0
2022-08-24T00:46:14.094Z DEBUG [crossfont::ft] Loaded Face Face { ft_face: Font Face: Regular, load_flags: TARGET_LIGHT, render_mode: "Normal", lcd_filter: 1 }
NewEvents(Init)
Resumed
NewEvents(WaitCancelled { start: Instant { tv_sec: 4824, tv_nsec: 233335504 }, requested_resume: None })
WindowEvent { window_id: WindowId(WindowId(94012884126464)), event: Focused(false) }
MainEventsCleared
RedrawRequested(WindowId(WindowId(94012884126464)))
RedrawEventsCleared
NewEvents(WaitCancelled { start: Instant { tv_sec: 4831, tv_nsec: 4778737 }, requested_resume: None })
MainEventsCleared
RedrawEventsCleared
NewEvents(WaitCancelled { start: Instant { tv_sec: 4832, tv_nsec: 36637634 }, requested_resume: None })
MainEventsCleared
RedrawEventsCleared

Next I tried glutin as the winit docs recommended instead (note), this seemed to work ok:
image

What went wrong

I was expecting roughly the same output between x11 and Wayland in the example. The wayland feature seems to render the example incorrect, as the window is supposed to be transparent.

Additional information

It's unclear to me what's going on and I'm fairly new to bevy, so I don't really have any idea what's going on!

@benbrittain noted gfx-rs/wgpu#687 (comment) might be relevant, if so that implies gfx-rs/wgpu#2836 may be required to fix this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-WindowingPlatform-agnostic interface layer to run your app inC-BugAn unexpected or incorrect behaviorO-LinuxSpecific to the Linux desktop operating system

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions