Skip to content

Commit 9f8037c

Browse files
authored
fix(core): clear window surface for transparent windows (#8633)
* 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
1 parent e0b38d7 commit 9f8037c

3 files changed

Lines changed: 91 additions & 6 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'tauri': 'patch:bug'
3+
'tauri-runtime-wry': 'patch'
4+
---
5+
6+
On Windows, fix decorated window not transparent initially until resized.

core/tauri-runtime-wry/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rust-version = { workspace = true }
1414

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

2424
[target."cfg(windows)".dependencies]
2525
webview2-com = "0.28"
26+
softbuffer = "0.4"
2627

2728
[target."cfg(windows)".dependencies.windows]
2829
version = "0.52"

core/tauri-runtime-wry/src/lib.rs

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,13 +1678,17 @@ pub struct WindowWrapper {
16781678
label: String,
16791679
inner: Option<WindowHandle>,
16801680
window_event_listeners: WindowEventListeners,
1681+
is_window_transparent: bool,
1682+
#[cfg(windows)]
1683+
surface: Option<softbuffer::Surface<Arc<Window>, Arc<Window>>>,
16811684
}
16821685

16831686
impl fmt::Debug for WindowWrapper {
16841687
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16851688
f.debug_struct("WindowWrapper")
16861689
.field("label", &self.label)
16871690
.field("inner", &self.inner)
1691+
.field("is_window_transparent", &self.is_window_transparent)
16881692
.finish()
16891693
}
16901694
}
@@ -2470,20 +2474,40 @@ fn handle_user_message<T: UserEvent>(
24702474
},
24712475
Message::CreateWindow(window_id, handler, sender) => {
24722476
let (label, builder) = handler();
2477+
let is_window_transparent = builder.window.transparent;
24732478
if let Ok(window) = builder.build(event_loop) {
24742479
webview_id_map.insert(window.id(), window_id);
24752480

2476-
let w = Arc::new(window);
2481+
let window = Arc::new(window);
2482+
2483+
#[cfg(windows)]
2484+
let surface = if is_window_transparent {
2485+
if let Ok(context) = softbuffer::Context::new(window.clone()) {
2486+
if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) {
2487+
clear_window_surface(&window, &mut surface);
2488+
Some(surface)
2489+
} else {
2490+
None
2491+
}
2492+
} else {
2493+
None
2494+
}
2495+
} else {
2496+
None
2497+
};
24772498

24782499
windows.borrow_mut().insert(
24792500
window_id,
24802501
WindowWrapper {
24812502
label,
2482-
inner: Some(WindowHandle::Window(w.clone())),
2503+
inner: Some(WindowHandle::Window(window.clone())),
24832504
window_event_listeners: Default::default(),
2505+
is_window_transparent,
2506+
#[cfg(windows)]
2507+
surface,
24842508
},
24852509
);
2486-
sender.send(Ok(Arc::downgrade(&w))).unwrap();
2510+
sender.send(Ok(Arc::downgrade(&window))).unwrap();
24872511
} else {
24882512
sender.send(Err(Error::CreateWindow)).unwrap();
24892513
}
@@ -2533,8 +2557,23 @@ fn handle_event_loop<T: UserEvent>(
25332557
callback(RunEvent::Exit);
25342558
}
25352559

2536-
#[cfg(feature = "tracing")]
2560+
#[cfg(any(feature = "tracing", windows))]
25372561
Event::RedrawRequested(id) => {
2562+
#[cfg(windows)]
2563+
if let Some(window_id) = webview_id_map.get(&id) {
2564+
let mut windows_ref = windows.borrow_mut();
2565+
if let Some(window) = windows_ref.get_mut(&window_id) {
2566+
if window.is_window_transparent {
2567+
if let Some(surface) = &mut window.surface {
2568+
if let Some(window) = &window.inner {
2569+
clear_window_surface(&window, surface)
2570+
}
2571+
}
2572+
}
2573+
}
2574+
}
2575+
2576+
#[cfg(feature = "tracing")]
25382577
active_tracing_spans.remove_window_draw(id);
25392578
}
25402579

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

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

3065+
let window = Arc::new(window);
3066+
#[cfg(windows)]
3067+
let surface = if is_window_transparent {
3068+
if let Ok(context) = softbuffer::Context::new(window.clone()) {
3069+
if let Ok(mut surface) = softbuffer::Surface::new(&context, window.clone()) {
3070+
clear_window_surface(&window, &mut surface);
3071+
Some(surface)
3072+
} else {
3073+
None
3074+
}
3075+
} else {
3076+
None
3077+
}
3078+
} else {
3079+
None
3080+
};
3081+
30243082
Ok(WindowWrapper {
30253083
label,
30263084
inner: Some(WindowHandle::Webview {
3027-
window: Arc::new(window),
3085+
window,
30283086
inner: Rc::new(webview),
30293087
context_store: web_context_store.clone(),
30303088
context_key: if automation_enabled {
@@ -3034,6 +3092,9 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
30343092
},
30353093
}),
30363094
window_event_listeners,
3095+
is_window_transparent,
3096+
#[cfg(windows)]
3097+
surface,
30373098
})
30383099
}
30393100

@@ -3057,3 +3118,20 @@ fn create_ipc_handler<T: UserEvent>(
30573118
);
30583119
})
30593120
}
3121+
3122+
#[cfg(windows)]
3123+
fn clear_window_surface(
3124+
window: &Window,
3125+
surface: &mut softbuffer::Surface<Arc<Window>, Arc<Window>>,
3126+
) {
3127+
let size = window.inner_size();
3128+
if let (Some(width), Some(height)) = (
3129+
std::num::NonZeroU32::new(size.width),
3130+
std::num::NonZeroU32::new(size.height),
3131+
) {
3132+
surface.resize(width, height).unwrap();
3133+
let mut buffer = surface.buffer_mut().unwrap();
3134+
buffer.fill(0);
3135+
let _ = buffer.present();
3136+
}
3137+
}

0 commit comments

Comments
 (0)