diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 6af56ab4f..6505f7b79 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -1045,6 +1045,7 @@ dependencies = [ "url", "user-idle", "uuid", + "webkit2gtk", "window-vibrancy", "windows-sys 0.61.2", "zeroize", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index dcb432b73..9bde2026f 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -35,6 +35,10 @@ ctrlc = { version = "3", features = ["termination"] } [target.'cfg(target_os = "linux")'.dependencies] keyring = { version = "3.6.3", default-features = false, features = ["sync-secret-service", "vendored"], optional = true } +# Same version tauri links. Needed to reach the native WebKitGTK webview and +# approve UserMedia permission requests — WebKitGTK denies unhandled requests, +# which made getUserMedia() (huddle mic) always fail on Linux. +webkit2gtk = "2.0" # Used directly (alongside tauri-plugin-notification) so we can hold the posting # D-Bus connection open. GNOME 46+ dismisses a notification the moment that # connection is dropped, which the plugin does immediately. Default features diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 9017356ab..2fbad9fd8 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -186,6 +186,42 @@ pub fn run() { .with_state_flags(StateFlags::all() & !StateFlags::VISIBLE) .build(), ) + .plugin( + tauri::plugin::Builder::<_, ()>::new("linux-media-permissions") + .on_webview_ready(|webview| { + // WebKitGTK denies any permission request the embedder + // doesn't handle, so without this getUserMedia() always + // fails on Linux — the huddle mic never connects and the + // huddle tears itself down right after starting. Allow + // media-device requests; everything else keeps the + // default deny. + #[cfg(target_os = "linux")] + { + use webkit2gtk::glib::prelude::*; + use webkit2gtk::{PermissionRequestExt, WebViewExt}; + + let _ = webview.with_webview(|platform_webview| { + platform_webview.inner().connect_permission_request( + |_, request| { + if request + .is::() + || request + .is::() + { + request.allow(); + true + } else { + false + } + }, + ); + }); + } + #[cfg(not(target_os = "linux"))] + let _ = &webview; + }) + .build(), + ) .plugin( tauri::plugin::Builder::<_, ()>::new("initial-window-reveal") .on_webview_ready(|webview| {