From ed42c58732865c237537ffe234ba47de2f27638f Mon Sep 17 00:00:00 2001 From: Clover <32724585+ushiocheng@users.noreply.github.com> Date: Sat, 10 Oct 2026 02:57:31 -0700 Subject: [PATCH] fix(plugins): realize the Linux editor window before embedding The editor window is built hidden, and GTK only creates the native window on realize, so window_handle() returned "the underlying window handle is not available" and no plugin editor could open on Linux. Co-Authored-By: Claude Opus 5.5 --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 3 +++ src-tauri/src/audio/plugins/editor.rs | 14 ++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index ec092546..4a19681d 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -6242,6 +6242,7 @@ dependencies = [ "freedesktop-desktop-entry", "freedesktop-icons", "futures-util", + "gtk", "hound", "libc", "libpulse-binding", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5e2e5400..58c91d0f 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -120,6 +120,9 @@ dirs = "5" # check falls back to webpki-roots. macOS/Windows keep the platform verifier. webpki-roots = "0.26" rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] } +# Plugin editor windows are realized by hand before a plugin view is parented +# into them; same gtk that tauri already links. +gtk = "0.18" [target.'cfg(unix)'.dependencies] # Fatal-signal crash persistence; Linux VST3 hosting also uses dlopen and poll. diff --git a/src-tauri/src/audio/plugins/editor.rs b/src-tauri/src/audio/plugins/editor.rs index 325df1e9..02e80fce 100644 --- a/src-tauri/src/audio/plugins/editor.rs +++ b/src-tauri/src/audio/plugins/editor.rs @@ -150,6 +150,20 @@ pub fn open(node_id: &str, title: &str) -> Result<(), String> { .unwrap() .insert(node_id.to_string(), window.clone()); + // GTK creates the native window on realize, which a hidden window has not + // been through; without it there is no handle to parent the plugin view to. + #[cfg(target_os = "linux")] + { + use gtk::prelude::WidgetExt; + match window.gtk_window() { + Ok(gtk_window) => gtk_window.realize(), + Err(e) => { + close_window(node_id); + return Err(format!("editor window for {node_id}: {e}")); + } + } + } + let embedded = match super::registry::for_node(node_id) { Some(host) => host.embed_editor(node_id, &window), None => Err(format!("{node_id}: no plugin is running on this node")),