dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Desktop Window Tranparency Not Rendering Correctly

Open imgurbot12 opened this issue 11 months ago • 9 comments

Problem

Dioxus fails to rerender properly when transparency is enabled in desktop mode, leaving the old material underneath the new frame.

Steps To Reproduce

use dioxus::prelude::*;

const STYLES: &'static str = r#"
    #body {
        display: flex;
    }
    p {
        font-size: 100px;
    }
"#;

const IPSUM: &'static str = r#"
    Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.
"#;

const BACON: &'static str = r#"
    Bacon ipsum dolor amet jowl pig pork meatball pork belly.
    Beef ribs buffalo hamburger burgdoggen. Pig pancetta pastrami
    shoulder fatback bacon kevin ham hock doner sirloin prosciutto
    t-bone meatloaf. Sausage swine flank pork, spare ribs pork loin
    ribeye beef ribs hamburger. Tongue pork chuck, biltong spare ribs
    pig jerky salami frankfurter flank drumstick leberkas pork chop
    pastrami jowl. Buffalo cupim alcatra tongue prosciutto, pork chop
    short ribs pancetta meatloaf corned beef chicken flank sirloin
    spare ribs. Boudin meatball andouille tenderloin meatloaf.
"#;

fn gui() -> Element {
    let mut scene = use_signal(|| false);

    let content = if scene.with(|b| *b) { IPSUM } else { BACON };

    rsx! {
        style { "{STYLES}" }
        div {
            id: "body",
            onclick: move |_| {
                let value = scene.with(|b| *b);
                scene.set(!value);
            },
            p { "{content}" }
        }
    }
}

fn main() {
    let window = dioxus_desktop::WindowBuilder::default()
        .with_decorations(false)
        .with_transparent(true);
    let config = dioxus_desktop::Config::default().with_window(window);

    LaunchBuilder::desktop().with_cfg(config).launch(gui);
}

Screenshots

Image

Environment:

  • Dioxus version: 0.6.3
  • Rust version: rustc 1.85.0 (4d91de4e4 2025-02-17)
  • OS info: EndeavourOS (Hyprland v0.47.1)
  • App platform: Desktop

Questionnaire

I'm interested in fixing this myself but don't know where to start.

imgurbot12 avatar Mar 03 '25 20:03 imgurbot12

Unsure if this is the same issue but it could be related to https://github.com/DioxusLabs/dioxus/issues/3727

imgurbot12 avatar Mar 18 '25 03:03 imgurbot12

If you are interested in working on this, I would check if transparency works when changing the browser content in wry which is the system webview library dioxus uses.

I can reproduce this issue on macos as well which makes me think this isn't an issue with the webview itself. On macos, the outline only changes depending on if the window is focused or not:

https://github.com/user-attachments/assets/5a228ce4-3db5-4869-9cc2-093fa68d3c7e

ealmloff avatar Mar 18 '25 21:03 ealmloff

Interesting, appreciate the follow up thanks. I'll see if I can reproduce in wry by itself and report back.

imgurbot12 avatar Mar 18 '25 21:03 imgurbot12

After testing the issue does occur with wry alone, even on the latest version. So this does appear to be an issue with wry. I've posted an issue there as well thanks.

https://github.com/tauri-apps/wry/issues/1524

imgurbot12 avatar Mar 19 '25 07:03 imgurbot12

One thing I do find odd however is this issue also seems to occur with wry v0.28 by itself which is what dioxus 0.4.3 uses but I did not have this issue with transparency when using dioxus 0.4.3 but its a problem for both dioxus 0.5.x and 0.6.x, so I'm not sure whats changed there either.

imgurbot12 avatar Mar 19 '25 07:03 imgurbot12

@ealmloff would you be willing to confirm that the wry example I posted in the wry issue has transparency issues for you on MacOS as well please?

I've realized that the issue is not occurring for me when running Sway rather than Hyprland on linux which are both wayland systems. I'm curious if this can be attributed to some configuration related in wry that's just conditional or if this is perhaps a DE issue.

imgurbot12 avatar Mar 21 '25 05:03 imgurbot12

@ealmloff would you be willing to confirm that the wry example I posted in the wry issue has transparency issues for you on MacOS as well please?

I can reproduce an issue in dioxus desktop using wry on mac, but I can't reproduce the issue with wry when changing the HTML content. The original reproduction in the issue doesn't compile on mac, so I modified it to change the content every second and use the normal webview build method:

// tao = "0.32.8"
// wry = "0.50.5"
use tao::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};
use wry::WebViewBuilder;

static HTML1: &'static str = r#"
<html><body><div style="font-size: 100px">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.
</div></body></html>

"#;
static HTML2: &'static str = r#"
<html><body><div style="font-size: 100px">
    Bacon ipsum dolor amet jowl pig pork meatball pork belly.
    Beef ribs buffalo hamburger burgdoggen. Pig pancetta pastrami
    shoulder fatback bacon kevin ham hock doner sirloin prosciutto
    t-bone meatloaf. Sausage swine flank pork, spare ribs pork loin
    ribeye beef ribs hamburger. Tongue pork chuck, biltong spare ribs
    pig jerky salami frankfurter flank drumstick leberkas pork chop
    pastrami jowl. Buffalo cupim alcatra tongue prosciutto, pork chop
    short ribs pancetta meatloaf corned beef chicken flank sirloin
    spare ribs. Boudin meatball andouille tenderloin meatloaf.
</div></body></html>
"#;

fn main() -> wry::Result<()> {
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new()
        .with_decorations(false)
        .with_transparent(false)
        .build(&event_loop)
        .unwrap();

    let builder = WebViewBuilder::new()
        .with_html(HTML1)
        .with_transparent(true);

    let _webview = {
        builder.build(&window).unwrap()
    };

    let mut switch = false;
    let mut last_switched = std::time::Instant::now();
    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Poll;

        if last_switched.elapsed().as_secs() > 1 {
            last_switched = std::time::Instant::now();
            switch = !switch;
            let content = if switch { HTML1 } else { HTML2 };
            _webview
                .load_html(content)
                .expect("failed to update content");
        }

        if let Event::WindowEvent {
            event: WindowEvent::CloseRequested,
            ..
        } = event
        {
            *control_flow = ControlFlow::Exit
        }
    });
}

ealmloff avatar Mar 21 '25 13:03 ealmloff

Greatly appreciate it thanks! 🙏 That leaves me with even more questions lol. Did you happen to run the latest version of wry which is 0.50.5 or 0.45.0 which is whats tagged to dioxus v0.6.3?

If you ran 0.45.0 and its working, that seems to imply the issue is with dioxus perhaps? And yet the issue for me still occurs with wry alone within Hyprland. So odd.

imgurbot12 avatar Mar 21 '25 19:03 imgurbot12

Greatly appreciate it thanks! 🙏 That leaves me with even more questions lol. Did you happen to run the latest version of wry which is 0.50.5 or 0.45.0 which is whats tagged to dioxus v0.6.3?

If you ran 0.45.0 and its working, that seems to imply the issue is with dioxus perhaps? And yet the issue for me still occurs with wry alone within Hyprland. So odd.

I tested with 0.50.5, but it also works if I modify it to use 0.45.0:

// tao = "0.32.8"
// wry = "0.45.0"
use tao::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};
use wry::WebViewBuilder;

static HTML1: &'static str = r#"
<html><body><div style="font-size: 100px">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.
</div></body></html>

"#;
static HTML2: &'static str = r#"
<html><body><div style="font-size: 100px">
    Bacon ipsum dolor amet jowl pig pork meatball pork belly.
    Beef ribs buffalo hamburger burgdoggen. Pig pancetta pastrami
    shoulder fatback bacon kevin ham hock doner sirloin prosciutto
    t-bone meatloaf. Sausage swine flank pork, spare ribs pork loin
    ribeye beef ribs hamburger. Tongue pork chuck, biltong spare ribs
    pig jerky salami frankfurter flank drumstick leberkas pork chop
    pastrami jowl. Buffalo cupim alcatra tongue prosciutto, pork chop
    short ribs pancetta meatloaf corned beef chicken flank sirloin
    spare ribs. Boudin meatball andouille tenderloin meatloaf.
</div></body></html>
"#;

fn main() -> wry::Result<()> {
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new()
        .with_decorations(false)
        .with_transparent(false)
        .build(&event_loop)
        .unwrap();

    let builder = WebViewBuilder::new(&window)
        .with_html(HTML1)
        .with_transparent(true);

    let _webview = {
        builder.build().unwrap()
    };

    let mut switch = false;
    let mut last_switched = std::time::Instant::now();
    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Poll;

        if last_switched.elapsed().as_secs() > 1 {
            last_switched = std::time::Instant::now();
            switch = !switch;
            let content = if switch { HTML1 } else { HTML2 };
            _webview
                .load_html(content)
                .expect("failed to update content");
        }

        if let Event::WindowEvent {
            event: WindowEvent::CloseRequested,
            ..
        } = event
        {
            *control_flow = ControlFlow::Exit
        }
    });
}

If you ran 0.45.0 and its working, that seems to imply the issue is with dioxus perhaps? And yet the issue for me still occurs with wry alone within Hyprland. So odd.

There might be a general bug with gtk rendering on linux and a more specific case dioxus is triggering for macos

ealmloff avatar Mar 21 '25 20:03 ealmloff