fix: reload the panel for browser keys only after its first page load

This commit is contained in:
tiennm99 committed 2026-10-21 15:44:00 +07:00
1 parent 388305de04
commit 9c7ade8ea3
3 files changed
+41 -11

No files matched your search

@@ -92,7 +92,7 @@ dismisses it.
- The row labels ("5h", "7d") are not in `PanelPayload`; the page reads them once from the existing `get_strings` command, so the payload contract stays as planned.
- The pure page helpers live in `ui/panel-view.js` instead of `ui/panel.js`, because `panel.js` reads `window.__TAURI__` on import and cannot run under `node --test`.
- Tauri does not expose wry's `with_browser_accelerator_keys`, so `platform::windows::disable_browser_accelerator_keys` sets `AreBrowserAcceleratorKeysEnabled` through `with_webview` and reloads the page once at startup, because the setting applies from the next navigation. The `keydown` handler covers the same keys on every platform.
- Tauri does not expose wry's `with_browser_accelerator_keys`, so `platform::windows::disable_browser_accelerator_keys` sets `AreBrowserAcceleratorKeysEnabled` through `with_webview` and reloads the page once, because the setting applies from the next navigation. A page-load hook on the panel runs this after the first `panel.html` load finishes, so the reload cannot replace the initial navigation; still to check on Windows hardware that the panel draws its payload after startup. The `keydown` handler covers the same keys on every platform.
- `bubble_click` is an async command, so the toggle is queued to the main thread instead of running inside the webview's IPC callback. Toggles and refreshes both run on the main thread, which keeps a refresh from drawing a provider the panel no longer shows.
- The panel background colour is set from the theme before every show, and the payload is emitted before `show()`, against a white or stale flash.
- `shadow(false)` is kept until the Windows screenshot comparison says otherwise.
+36 -8
View File
@@ -130,7 +130,7 @@ fn background(is_dark: bool) -> Color {
/// Create the hidden panel window. Called once at startup.
pub fn create(app: &AppHandle, is_dark: bool) -> tauri::Result<()> {
let window = WebviewWindowBuilder::new(app, PANEL_LABEL, WebviewUrl::App("panel.html".into()))
let builder = WebviewWindowBuilder::new(app, PANEL_LABEL, WebviewUrl::App("panel.html".into()))
.title(TITLE)
.decorations(false)
.always_on_top(true)
@@ -140,15 +140,46 @@ pub fn create(app: &AppHandle, is_dark: bool) -> tauri::Result<()> {
.shadow(false)
.visible(false)
.background_color(background(is_dark))
.inner_size(f64::from(PANEL_W_LOGICAL), f64::from(PANEL_H_LOGICAL))
.build()?;
.inner_size(f64::from(PANEL_W_LOGICAL), f64::from(PANEL_H_LOGICAL));
#[cfg(windows)]
let builder = builder.on_page_load(disable_browser_keys_after_first_load());
let window = builder.build()?;
prepare_native(app, &window);
log::info!("{PANEL_LABEL} created");
Ok(())
}
/// Windows: drop the panel from Alt-Tab and turn off the browser keys of
/// its webview, on the window's own (main) thread, before the first show.
/// Windows: a page-load hook that turns off the webview's browser keys
/// once `panel.html` has finished its first load. The setting only applies
/// from the next navigation, so it comes with a reload; waiting for the
/// first load keeps that reload from racing the initial navigation, and the
/// flag keeps the reload's own load from repeating it. The work leaves the
/// navigation callback through another thread, which queues it on the main
/// thread for after the callback returns.
#[cfg(windows)]
fn disable_browser_keys_after_first_load(
) -> impl Fn(WebviewWindow, tauri::webview::PageLoadPayload<'_>) + Send + Sync + 'static {
use std::sync::atomic::{AtomicBool, Ordering};
use tauri::webview::PageLoadEvent;
let done = AtomicBool::new(false);
move |window, payload| {
if payload.event() != PageLoadEvent::Finished
|| payload.url().scheme() == "about"
|| done.swap(true, Ordering::SeqCst)
{
return;
}
std::thread::spawn(move || {
if let Err(err) = platform::windows::disable_browser_accelerator_keys(&window) {
log::warn!("{PANEL_LABEL} keeps the browser accelerator keys: {err}");
}
});
}
}
/// Windows: drop the panel from Alt-Tab, on the window's own (main)
/// thread, before the first show.
#[cfg(windows)]
fn prepare_native(app: &AppHandle, window: &WebviewWindow) {
let window = window.clone();
@@ -156,9 +187,6 @@ fn prepare_native(app: &AppHandle, window: &WebviewWindow) {
if let Err(err) = platform::windows::apply_toolwindow(&window) {
log::warn!("{PANEL_LABEL} may show in Alt-Tab: {err}");
}
if let Err(err) = platform::windows::disable_browser_accelerator_keys(&window) {
log::warn!("{PANEL_LABEL} keeps the browser accelerator keys: {err}");
}
});
if let Err(err) = queued {
log::warn!("panel set-up could not reach the main thread: {err}");
+4 -2
View File
@@ -254,8 +254,10 @@ pub fn round_corners(window: &tauri::WebviewWindow) -> io::Result<()> {
/// Turn off WebView2's browser accelerator keys (F5, Ctrl+R, Ctrl+P,
/// Ctrl+F, zoom, F12 and the like) for `window`'s webview, then reload it,
/// because the setting applies from the next navigation. Runs on the main
/// thread; a failure inside the webview is logged there.
/// because the setting applies from the next navigation. Call it only after
/// the first navigation has finished, or the reload can replace that
/// navigation. The work runs on the main thread; a failure inside the
/// webview is logged there.
pub fn disable_browser_accelerator_keys(window: &tauri::WebviewWindow) -> io::Result<()> {
let label = window.label().to_string();
window