Skip to content

Webview/HTML plugins suspend on Linux causing WebSocket timeouts & frozen actions #445

Description

@pauverblom

Preflight checklist

  • I have searched the existing issues and believe this will not be a duplicate of any existing issue.
  • I understand that if this issue is about support for non-Elgato or non-Tacto hardware, it will be closed without explanation, as per issue Statement regarding device support #38, and that it should be raised in the repository of the plugin that provides support for the hardware.
  • I will provide the OpenDeck log file and the log files of plugins involved, where applicable.
  • I will provide my operating system information and method of installation, as well as any steps I have taken to troubleshoot the issue.
  • I certify that I am using the latest available version of OpenDeck, and that I will provide enough information to reproduce the issue.

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:

  1. The remote service (e.g. Home Assistant) sends WebSocket heartbeat pings.
  2. The suspended WebKitGTK webview fails to reply with PONG within the server's timeout
  3. 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
  4. When the plugin catches the disconnect and attempts to schedule a reconnection using setTimeout(), the timer never fires because the background webview is throttled.
  5. 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

  1. Run OpenDeck on Linux with an HTML plugin that uses a persistent WebSocket connection (e.g., Home Assistant de.perdoctus.streamdeck.homeassistant.sdPlugin).
  2. Configure buttons connected to entities.
  3. Leave the device idle for a while.
  4. 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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions