From 8a333d6770800f8805a067a1a07c2caefaadcdca Mon Sep 17 00:00:00 2001 From: mesmerize Date: Wed, 4 Nov 2026 21:19:30 -0800 Subject: [PATCH] potentially fixed mac support --- crypto-utils.js | 5 +-- main.js | 3 ++ service-manager.js | 3 ++ src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 5 ++- src-tauri/Info.plist | 2 ++ src-tauri/src/main.rs | 81 +++++++++++++++++++++++++++++++++++++------ 7 files changed, 86 insertions(+), 14 deletions(-) diff --git a/crypto-utils.js b/crypto-utils.js index 5668750..ecf9fa9 100644 --- a/crypto-utils.js +++ b/crypto-utils.js @@ -17,13 +17,14 @@ class CryptoUtils { let key; try { + const isMac = os.platform() === 'darwin'; const machineId = [ - os.hostname(), + isMac ? '' : os.hostname(), os.platform(), os.arch(), os.cpus()[0] ? os.cpus()[0].model : '', process.env.COMPUTERNAME || '', - process.env.USERNAME || '' + process.env.USERNAME || (isMac ? os.userInfo().username : '') ].join('|'); const hash = crypto.createHash('sha256'); diff --git a/main.js b/main.js index 087473b..155301b 100644 --- a/main.js +++ b/main.js @@ -459,5 +459,8 @@ process.on('SIGINT', () => { process.on('SIGTERM', () => { process.exit(0); }); +process.on('SIGHUP', () => { + process.exit(0); +}); start(); diff --git a/service-manager.js b/service-manager.js index abf6c6b..2542b04 100644 --- a/service-manager.js +++ b/service-manager.js @@ -54,6 +54,9 @@ class ServiceManager { const env = { ...process.env, + ...(process.platform === 'darwin' + ? { PATH: [process.env.PATH, '/opt/homebrew/bin', '/usr/local/bin', '/usr/bin', '/bin'].filter(Boolean).join(path.delimiter) } + : {}), PORT: (this.envConfig[name] && this.envConfig[name].PORT) || defaultPorts[name] || process.env.PORT || 3000, TOKEN_SECRET: tokenSecret, ...(this.envConfig[name] || {}), diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9b23b04..7c97693 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4075,6 +4075,7 @@ dependencies = [ name = "vyla-home" version = "1.1.56" dependencies = [ + "libc", "objc2 0.5.2", "serde", "serde_json", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index eb7b45f..de6f9c1 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -17,6 +17,9 @@ window-vibrancy = "0.8" [target.'cfg(target_os = "macos")'.dependencies] objc2 = "0.5" +[target.'cfg(unix)'.dependencies] +libc = "0.2" + [profile.release] opt-level = 3 lto = true @@ -27,4 +30,4 @@ panic = "abort" [profile.dev] opt-level = 0 debug = true -incremental = true +incremental = true \ No newline at end of file diff --git a/src-tauri/Info.plist b/src-tauri/Info.plist index 594d619..638f26f 100644 --- a/src-tauri/Info.plist +++ b/src-tauri/Info.plist @@ -8,6 +8,8 @@ NSAllowsArbitraryLoads + NSAllowsArbitraryLoadsInWebContent + \ No newline at end of file diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b9e8edf..9509b4d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -44,6 +44,8 @@ static WINDOW_COUNTER: std::sync::atomic::AtomicUsize = std::sync::atomic::Atomi static READY_URL: Mutex> = Mutex::new(None); +static APP_LOADED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false); + fn js_log(app: &AppHandle, msg: &str) { debug_log(msg); if let Some(w) = app.get_webview_window("main") { @@ -94,6 +96,17 @@ fn kill_child_process(child: &mut Child) { .creation_flags(CREATE_NO_WINDOW) .output(); } + #[cfg(unix)] + { + let pgid = child.id() as i32; + unsafe { + libc::killpg(pgid, libc::SIGTERM); + } + std::thread::sleep(std::time::Duration::from_millis(400)); + unsafe { + libc::killpg(pgid, libc::SIGKILL); + } + } let _ = child.kill(); let _ = child.wait(); } @@ -580,7 +593,7 @@ fn open_new_window(app: AppHandle, url: String) -> Result<(), String> { fn handle_ready(w: &tauri::WebviewWindow, msg: &BackendMessage) { let url_str = match msg.data.get("url").and_then(|u| u.as_str()) { - Some(u) => u, + Some(u) => u.to_string(), None => return, }; @@ -592,19 +605,36 @@ fn handle_ready(w: &tauri::WebviewWindow, msg: &BackendMessage) { #[cfg(target_os = "macos")] { use objc2::msg_send; - use objc2::runtime::AnyObject; - debug_log("Attempting with_webview on ready event"); - let result = w.with_webview(|webview| unsafe { - debug_log("Inside with_webview closure"); + use objc2::runtime::{AnyObject, Sel}; + use objc2::sel; + let _ = w.with_webview(|webview| unsafe { let wk_webview = webview.inner() as *mut AnyObject; let config: *mut AnyObject = msg_send![wk_webview, configuration]; - let _: () = msg_send![config, setUpgradeKnownHostsToHTTPS: false]; - debug_log("setUpgradeKnownHostsToHTTPS set to false"); + let selector: Sel = sel!(setUpgradeKnownHostsToHTTPS:); + let supported: bool = msg_send![config, respondsToSelector: selector]; + if supported { + let _: () = msg_send![config, setUpgradeKnownHostsToHTTPS: false]; + } }); - debug_log(&format!("with_webview result: {:?}", result)); } - let _ = w.navigate(url_parsed); + APP_LOADED.store(false, std::sync::atomic::Ordering::SeqCst); + let _ = w.navigate(url_parsed.clone()); + + let watcher = w.clone(); + std::thread::spawn(move || { + for attempt in 1..=8 { + std::thread::sleep(std::time::Duration::from_secs(4)); + if APP_LOADED.load(std::sync::atomic::Ordering::SeqCst) { + return; + } + debug_log(&format!("App page not loaded yet, retry {}", attempt)); + let target = serde_json::to_string(&url_str).unwrap_or_default(); + let _ = watcher.eval(&format!("window.location.replace({});", target)); + let _ = watcher.navigate(url_parsed.clone()); + } + debug_log("App page never loaded after retries"); + }); } fn main() { @@ -663,6 +693,9 @@ fn main() { .initialization_script("window.__VYLA_WINDOW_LABEL = 'main';") .on_page_load(move |wv, payload| { if matches!(payload.event(), tauri::webview::PageLoadEvent::Finished) { + if payload.url().host_str() == Some("127.0.0.1") { + APP_LOADED.store(true, std::sync::atomic::Ordering::SeqCst); + } if payload.url().host_str() != Some("127.0.0.1") { let known = READY_URL.lock().ok().and_then(|g| g.clone()); if let Some(u) = known { @@ -726,6 +759,16 @@ fn main() { } }; + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + if let Ok(meta) = std::fs::metadata(&node_bin) { + let mut perms = meta.permissions(); + perms.set_mode(0o755); + let _ = std::fs::set_permissions(&node_bin, perms); + } + } + let vyla_files_str = clean_path(&vyla_files); let mut cmd = Command::new(&node_bin); @@ -746,6 +789,12 @@ fn main() { cmd.creation_flags(CREATE_NO_WINDOW); } + #[cfg(unix)] + { + use std::os::unix::process::CommandExt; + cmd.process_group(0); + } + match cmd.spawn() { Ok(mut child) => { debug_log(&format!( @@ -878,6 +927,16 @@ fn main() { } } }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); + .build(tauri::generate_context!()) + .expect("error while building tauri application") + .run(|app, event| { + if let tauri::RunEvent::Exit = event { + let state: State = app.state(); + if let Ok(mut lock) = state.0.lock() { + if let Some(mut child) = lock.take() { + kill_child_process(&mut child); + } + }; + } + }); }