T8: Rust open_vst_gui command - floating window + HWND via raw-window-handle

This commit is contained in:
2026-08-11 16:01:22 +07:00
parent 9fc5498999
commit a12c133ba6
5 changed files with 69 additions and 0 deletions
+1
View File
@@ -2873,6 +2873,7 @@ dependencies = [
name = "sonicforge-daw" name = "sonicforge-daw"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"raw-window-handle",
"serde", "serde",
"serde_json", "serde_json",
"tauri", "tauri",
+1
View File
@@ -15,6 +15,7 @@ tauri-build = { version = "2", features = [] }
tauri = { version = "2", features = [] } tauri = { version = "2", features = [] }
tauri-plugin-shell = "2" tauri-plugin-shell = "2"
tauri-plugin-dialog = "2" tauri-plugin-dialog = "2"
raw-window-handle = "0.6"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
+3
View File
@@ -17,6 +17,8 @@ use tauri_plugin_shell::ShellExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Mutex; use std::sync::Mutex;
mod vst_gui;
struct EngineProcess(Mutex<Option<CommandChild>>); struct EngineProcess(Mutex<Option<CommandChild>>);
/// Các vị trí có thể chứa daw_engine, theo thứ tự ưu tiên. /// Các vị trí có thể chứa daw_engine, theo thứ tự ưu tiên.
@@ -73,6 +75,7 @@ pub fn run() {
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.invoke_handler(tauri::generate_handler![vst_gui::open_vst_gui])
.setup(|app| { .setup(|app| {
let res_dir = app let res_dir = app
.path() .path()
+44
View File
@@ -0,0 +1,44 @@
// VST GUI windows (spec vsti_gui): floating child window per (track, plugin).
//
// T8: command `open_vst_gui(plugin_id, track_id)` tao WebviewWindow noi
// label `vst_gui_{track}_{plugin}`, 800x600, always-on-top; mo lai thi focus.
// raw_window_handle() lay HWND (Windows) — T9 se attach native VST3/VST2
// editor vao HWND cua window nay. Chua load plugin GUI (T9), chi placeholder.
use raw_window_handle::HasWindowHandle;
use tauri::{AppHandle, Manager, WebviewUrl, WebviewWindowBuilder};
/// Mo (hoac focus neu da mo) cua so VST GUI cho 1 (track, plugin).
/// Tra ve chuoi trang thai cho JS log — khong throw.
#[tauri::command]
pub fn open_vst_gui(
app: AppHandle,
plugin_id: String,
track_id: String,
) -> Result<String, String> {
let label = format!("vst_gui_{}_{}", track_id, plugin_id);
if let Some(win) = app.get_webview_window(&label) {
win.set_focus().map_err(|e| e.to_string())?;
return Ok(format!("focused: {}", label));
}
let win = WebviewWindowBuilder::new(&app, &label, WebviewUrl::App("vst_gui.html".into()))
.title(format!("VST GUI - {}", plugin_id))
.inner_size(800.0, 600.0)
.always_on_top(true)
.build()
.map_err(|e| e.to_string())?;
let _ = win.set_focus();
// HWND cho native editor attach (T9). Log de verify — chua dung.
match win.window_handle() {
Ok(raw) => {
let raw = raw.as_raw();
#[cfg(target_os = "windows")]
if let raw_window_handle::RawWindowHandle::Win32(h) = raw {
println!("[vst_gui] {} hwnd={:?}", label, h.hwnd);
}
#[cfg(not(target_os = "windows"))]
let _ = raw;
}
Err(e) => println!("[vst_gui] {} raw_window_handle error: {}", label, e),
}
Ok(format!("opened: {}", label))
}
+20
View File
@@ -0,0 +1,20 @@
<!doctype html>
<html lang="vi">
<head>
<meta charset="utf-8">
<title>VST GUI</title>
<style>
body { font-family: system-ui, sans-serif; background: #1a1d24; color: #c8ccd4;
display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
#msg { text-align: center; max-width: 520px; line-height: 1.6; }
code { background: #262b34; padding: 2px 6px; border-radius: 4px; }
</style>
</head>
<body>
<div id="msg">Cửa sổ nổi VST GUI (T8).<br>Plugin editor sẽ được attach vào HWND cửa sổ này ở T9.</div>
<script>
// T8: placeholder — chưa có native editor. JS của DAW gọi invoke('open_vst_gui', ...)
// để mở/focus cửa sổ này. Thông tin (track, plugin) nằm ở title + label window.
</script>
</body>
</html>