Preflight checklist
Describe the bug
HTML / Webview-based plugins (in this case, the bug happens with de.perdoctus.streamdeck.homeassistant.sdPlugin) randomly stop responding or updating after the system or Stream Deck is left idle for a while. Button presses stop executing actions.
Possible Cause / Details
I believe I've narrowed the bug to the following:
In src-tauri/src/plugins/mod.rs, OpenDeck spawns HTML plugins in a hidden window (.visible(false)):
let window = tauri::WebviewWindowBuilder::new(APP_HANDLE.get().unwrap(), plugin_uuid.replace('.', "_"), tauri::WebviewUrl::External(url.parse()?))
.title(manifest.name)
.visible(false)
.build()?;
On Linux, OpenDeck uses webkit2gtk-4.1.
Just like WKWebView on macOS, modern WebKitGTK aggressively suspends JavaScript execution, throttles the event loop, and freezes timers (setInterval / setTimeout) for windows that are invisible / hidden.
In src-tauri/src/plugins/mod.rs, code was implemented to prevent this exact scenario, but it currently only works on mac:
// On macOS, hidden WKWebView windows suspend JavaScript after ~7s.
// Periodically eval a no-op to keep them alive.
#[cfg(target_os = "macos")]
tokio::spawn(async {
use tauri::Manager;
let app = APP_HANDLE.get().unwrap();
loop {
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
let instances = INSTANCES.lock().await;
for (uuid, _) in instances.iter().filter(|(_, instance)| matches!(instance, PluginInstance::Webview)) {
if let Some(window) = app.get_webview_window(&uuid.replace('.', "_")) {
let _ = window.eval("void(0);");
}
}
}
});
Linux suspends the hidden webview after an idle period. Then this happens:
- The remote service (e.g. Home Assistant) sends WebSocket heartbeat pings.
- The suspended WebKitGTK webview fails to reply with PONG within the server's timeout
- The server drops the connection:
WARNING (MainThread) [homeassistant.components.websocket_api.http.connection]: Disconnected: Received error message during command phase: No PONG received after 27.5 seconds
- When the plugin catches the disconnect and attempts to schedule a reconnection using setTimeout(), the timer never fires because the background webview is throttled.
- The actions remain permanently unresponsive until OpenDeck is restarted.
Proposed Fix
Let Linux use the same workaround as mac does:
#[cfg(any(target_os = "macos", target_os = "linux"))]
tokio::spawn(async {
...
});
Steps to reproduce
- Run OpenDeck on Linux with an HTML plugin that uses a persistent WebSocket connection (e.g., Home Assistant de.perdoctus.streamdeck.homeassistant.sdPlugin).
- Configure buttons connected to entities.
- Leave the device idle for a while.
- Attempt to press a button or wait for a state update. The plugin is disconnected and does not respond.
Environment & Hardware
• OpenDeck version: 2.14.0-1 (Installed via AUR)
• Hardware: Elgato Stream Deck Mini (0fd9:0063)
• OS: CachyOS Linux (Kernel 7.2.3, Arch-based)
• WebKitGTK: webkit2gtk-4.1 2.52.6-1
• Affected Plugin: de.perdoctus.streamdeck.homeassistant.sdPlugin (v3.8.4.66)
Preflight checklist
Describe the bug
HTML / Webview-based plugins (in this case, the bug happens with
de.perdoctus.streamdeck.homeassistant.sdPlugin) randomly stop responding or updating after the system or Stream Deck is left idle for a while. Button presses stop executing actions.Possible Cause / Details
I believe I've narrowed the bug to the following:
In
src-tauri/src/plugins/mod.rs, OpenDeck spawns HTML plugins in a hidden window (.visible(false)):On Linux, OpenDeck uses webkit2gtk-4.1.
Just like WKWebView on macOS, modern WebKitGTK aggressively suspends JavaScript execution, throttles the event loop, and freezes timers (setInterval / setTimeout) for windows that are invisible / hidden.
In src-tauri/src/plugins/mod.rs, code was implemented to prevent this exact scenario, but it currently only works on mac:
Linux suspends the hidden webview after an idle period. Then this happens:
WARNING (MainThread) [homeassistant.components.websocket_api.http.connection]: Disconnected: Received error message during command phase: No PONG received after 27.5 secondsProposed Fix
Let Linux use the same workaround as mac does:
Steps to reproduce
Environment & Hardware
• OpenDeck version: 2.14.0-1 (Installed via AUR)
• Hardware: Elgato Stream Deck Mini (0fd9:0063)
• OS: CachyOS Linux (Kernel 7.2.3, Arch-based)
• WebKitGTK: webkit2gtk-4.1 2.52.6-1
• Affected Plugin: de.perdoctus.streamdeck.homeassistant.sdPlugin (v3.8.4.66)