mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-21 01:32:03 +03:00
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
This commit is contained in:
parent
e0b38d7434
commit
9f8037c288
6
.changes/tauri-decorated-transparent.md
Normal file
6
.changes/tauri-decorated-transparent.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
'tauri': 'patch:bug'
|
||||||
|
'tauri-runtime-wry': 'patch'
|
||||||
|
---
|
||||||
|
|
||||||
|
On Windows, fix decorated window not transparent initially until resized.
|
@ -14,7 +14,7 @@ rust-version = { workspace = true }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wry = { version = "0.35.2", default-features = false, features = [ "file-drop", "protocol", "os-webview" ] }
|
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-runtime = { version = "1.0.0-alpha.8", path = "../tauri-runtime" }
|
||||||
tauri-utils = { version = "2.0.0-alpha.13", path = "../tauri-utils" }
|
tauri-utils = { version = "2.0.0-alpha.13", path = "../tauri-utils" }
|
||||||
raw-window-handle = "0.5"
|
raw-window-handle = "0.5"
|
||||||
@ -23,6 +23,7 @@ tracing = { version = "0.1", optional = true }
|
|||||||
|
|
||||||
[target."cfg(windows)".dependencies]
|
[target."cfg(windows)".dependencies]
|
||||||
webview2-com = "0.28"
|
webview2-com = "0.28"
|
||||||
|
softbuffer = "0.4"
|
||||||
|
|
||||||
[target."cfg(windows)".dependencies.windows]
|
[target."cfg(windows)".dependencies.windows]
|
||||||
version = "0.52"
|
version = "0.52"
|
||||||
|
@ -1678,6 +1678,9 @@ pub struct WindowWrapper {
|
|||||||
label: String,
|
label: String,
|
||||||
inner: Option<WindowHandle>,
|
inner: Option<WindowHandle>,
|
||||||
window_event_listeners: WindowEventListeners,
|
window_event_listeners: WindowEventListeners,
|
||||||
|
is_window_transparent: bool,
|
||||||
|
#[cfg(windows)]
|
||||||
|
surface: Option<softbuffer::Surface<Arc<Window>, Arc<Window>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for WindowWrapper {
|
impl fmt::Debug for WindowWrapper {
|
||||||
@ -1685,6 +1688,7 @@ impl fmt::Debug for WindowWrapper {
|
|||||||
f.debug_struct("WindowWrapper")
|
f.debug_struct("WindowWrapper")
|
||||||
.field("label", &self.label)
|
.field("label", &self.label)
|
||||||
.field("inner", &self.inner)
|
.field("inner", &self.inner)
|
||||||
|
.field("is_window_transparent", &self.is_window_transparent)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2470,20 +2474,40 @@ fn handle_user_message<T: UserEvent>(
|
|||||||
},
|
},
|
||||||
Message::CreateWindow(window_id, handler, sender) => {
|
Message::CreateWindow(window_id, handler, sender) => {
|
||||||
let (label, builder) = handler();
|
let (label, builder) = handler();
|
||||||
|
let is_window_transparent = builder.window.transparent;
|
||||||
if let Ok(window) = builder.build(event_loop) {
|
if let Ok(window) = builder.build(event_loop) {
|
||||||
webview_id_map.insert(window.id(), window_id);
|
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(
|
windows.borrow_mut().insert(
|
||||||
window_id,
|
window_id,
|
||||||
WindowWrapper {
|
WindowWrapper {
|
||||||
label,
|
label,
|
||||||
inner: Some(WindowHandle::Window(w.clone())),
|
inner: Some(WindowHandle::Window(window.clone())),
|
||||||
window_event_listeners: Default::default(),
|
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 {
|
} else {
|
||||||
sender.send(Err(Error::CreateWindow)).unwrap();
|
sender.send(Err(Error::CreateWindow)).unwrap();
|
||||||
}
|
}
|
||||||
@ -2533,8 +2557,23 @@ fn handle_event_loop<T: UserEvent>(
|
|||||||
callback(RunEvent::Exit);
|
callback(RunEvent::Exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(any(feature = "tracing", windows))]
|
||||||
Event::RedrawRequested(id) => {
|
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);
|
active_tracing_spans.remove_window_draw(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2685,6 +2724,8 @@ fn on_close_requested<'a, T: UserEvent>(
|
|||||||
fn on_window_close(window_id: WebviewId, windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>) {
|
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) {
|
if let Some(window_wrapper) = windows.borrow_mut().get_mut(&window_id) {
|
||||||
window_wrapper.inner = None;
|
window_wrapper.inner = None;
|
||||||
|
#[cfg(windows)]
|
||||||
|
window_wrapper.surface.take();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3021,10 +3062,27 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
|
|||||||
.unwrap();
|
.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 {
|
Ok(WindowWrapper {
|
||||||
label,
|
label,
|
||||||
inner: Some(WindowHandle::Webview {
|
inner: Some(WindowHandle::Webview {
|
||||||
window: Arc::new(window),
|
window,
|
||||||
inner: Rc::new(webview),
|
inner: Rc::new(webview),
|
||||||
context_store: web_context_store.clone(),
|
context_store: web_context_store.clone(),
|
||||||
context_key: if automation_enabled {
|
context_key: if automation_enabled {
|
||||||
@ -3034,6 +3092,9 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
window_event_listeners,
|
window_event_listeners,
|
||||||
|
is_window_transparent,
|
||||||
|
#[cfg(windows)]
|
||||||
|
surface,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user