Skip to content

Commit

Permalink
fix(core): clear window surface for transparent windows (#8633)
Browse files Browse the repository at this point in the history
* fix(core): clear window surface for transparent windows

closes #8632

this may conflict with `tauri-egui` rendering to the surface so we may need to add an option to disable internal rendering

* fix build
  • Loading branch information
amrbashir committed Jan 18, 2024
1 parent e0b38d7 commit 9f8037c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changes/tauri-decorated-transparent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'tauri': 'patch:bug'
'tauri-runtime-wry': 'patch'
---

On Windows, fix decorated window not transparent initially until resized.
3 changes: 2 additions & 1 deletion core/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version = { workspace = true }

[dependencies]
wry = { version = "0.35.2", default-features = false, features = [ "file-drop", "protocol", "os-webview" ] }
tao = { version = "0.24", default-features = false, features = [ "rwh_05" ] }
tao = { version = "0.24", default-features = false, features = [ "rwh_05", "rwh_06" ] }
tauri-runtime = { version = "1.0.0-alpha.8", path = "../tauri-runtime" }
tauri-utils = { version = "2.0.0-alpha.13", path = "../tauri-utils" }
raw-window-handle = "0.5"
Expand All @@ -23,6 +23,7 @@ tracing = { version = "0.1", optional = true }

[target."cfg(windows)".dependencies]
webview2-com = "0.28"
softbuffer = "0.4"

[target."cfg(windows)".dependencies.windows]
version = "0.52"
Expand Down
88 changes: 83 additions & 5 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1678,13 +1678,17 @@ pub struct WindowWrapper {
label: String,
inner: Option<WindowHandle>,
window_event_listeners: WindowEventListeners,
is_window_transparent: bool,
#[cfg(windows)]
surface: Option<softbuffer::Surface<Arc<Window>, Arc<Window>>>,
}

impl fmt::Debug for WindowWrapper {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WindowWrapper")
.field("label", &self.label)
.field("inner", &self.inner)
.field("is_window_transparent", &self.is_window_transparent)
.finish()
}
}
Expand Down Expand Up @@ -2470,20 +2474,40 @@ fn handle_user_message<T: UserEvent>(
},
Message::CreateWindow(window_id, handler, sender) => {
let (label, builder) = handler();
let is_window_transparent = builder.window.transparent;
if let Ok(window) = builder.build(event_loop) {
webview_id_map.insert(window.id(), window_id);

let w = Arc::new(window);
let window = Arc::new(window);

#[cfg(windows)]
let surface = if is_window_transparent {
if let Ok(context) = softbuffer::Context::new(window.clone()) {
if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) {
clear_window_surface(&window, &mut surface);
Some(surface)
} else {
None
}
} else {
None
}
} else {
None
};

windows.borrow_mut().insert(
window_id,
WindowWrapper {
label,
inner: Some(WindowHandle::Window(w.clone())),
inner: Some(WindowHandle::Window(window.clone())),
window_event_listeners: Default::default(),
is_window_transparent,
#[cfg(windows)]
surface,
},
);
sender.send(Ok(Arc::downgrade(&w))).unwrap();
sender.send(Ok(Arc::downgrade(&window))).unwrap();
} else {
sender.send(Err(Error::CreateWindow)).unwrap();
}
Expand Down Expand Up @@ -2533,8 +2557,23 @@ fn handle_event_loop<T: UserEvent>(
callback(RunEvent::Exit);
}

#[cfg(feature = "tracing")]
#[cfg(any(feature = "tracing", windows))]
Event::RedrawRequested(id) => {
#[cfg(windows)]
if let Some(window_id) = webview_id_map.get(&id) {
let mut windows_ref = windows.borrow_mut();
if let Some(window) = windows_ref.get_mut(&window_id) {
if window.is_window_transparent {
if let Some(surface) = &mut window.surface {
if let Some(window) = &window.inner {
clear_window_surface(&window, surface)
}
}
}
}
}

#[cfg(feature = "tracing")]
active_tracing_spans.remove_window_draw(id);
}

Expand Down Expand Up @@ -2685,6 +2724,8 @@ fn on_close_requested<'a, T: UserEvent>(
fn on_window_close(window_id: WebviewId, windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>) {
if let Some(window_wrapper) = windows.borrow_mut().get_mut(&window_id) {
window_wrapper.inner = None;
#[cfg(windows)]
window_wrapper.surface.take();
}
}

Expand Down Expand Up @@ -3021,10 +3062,27 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
.unwrap();
}

let window = Arc::new(window);
#[cfg(windows)]
let surface = if is_window_transparent {
if let Ok(context) = softbuffer::Context::new(window.clone()) {
if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) {
clear_window_surface(&window, &mut surface);
Some(surface)
} else {
None
}
} else {
None
}
} else {
None
};

Ok(WindowWrapper {
label,
inner: Some(WindowHandle::Webview {
window: Arc::new(window),
window,
inner: Rc::new(webview),
context_store: web_context_store.clone(),
context_key: if automation_enabled {
Expand All @@ -3034,6 +3092,9 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
},
}),
window_event_listeners,
is_window_transparent,
#[cfg(windows)]
surface,
})
}

Expand All @@ -3057,3 +3118,20 @@ fn create_ipc_handler<T: UserEvent>(
);
})
}

#[cfg(windows)]
fn clear_window_surface(
window: &Window,
surface: &mut softbuffer::Surface<Arc<Window>, Arc<Window>>,
) {
let size = window.inner_size();
if let (Some(width), Some(height)) = (
std::num::NonZeroU32::new(size.width),
std::num::NonZeroU32::new(size.height),
) {
surface.resize(width, height).unwrap();
let mut buffer = surface.buffer_mut().unwrap();
buffer.fill(0);
let _ = buffer.present();
}
}

0 comments on commit 9f8037c

Please sign in to comment.