From 3a59cc5ab6284b6f7defc0be3d7934d8843c4bf7 Mon Sep 17 00:00:00 2001 From: jess Date: Thu, 23 Apr 2026 08:27:23 -0700 Subject: [PATCH] gagaddji3.0 --- src/bin/layers_shell.rs | 11 +++++---- src/ffi.rs | 49 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/bin/layers_shell.rs b/src/bin/layers_shell.rs index 15c4184..e89e220 100644 --- a/src/bin/layers_shell.rs +++ b/src/bin/layers_shell.rs @@ -17,10 +17,13 @@ const MIN_LOGICAL_SIZE: (u32, u32) = (380, 220); fn main() { let plugin_root = discover_plugin_root(); - if let Err(e) = layers::ffi::init_native_shell(plugin_root.as_deref()) { - eprintln!("layers: init_native_shell failed: {e}"); - std::process::exit(2); - } + // Tracing goes to a file; stderr is a deadlock risk when launched by KiCad. + let _ = layers::ffi::init_native_shell(plugin_root.as_deref()); + + std::panic::set_hook(Box::new(|info| { + tracing::error!("panic: {info}"); + })); + tracing::info!( plugin_root = ?plugin_root, "layers shell: starting native event loop", diff --git a/src/ffi.rs b/src/ffi.rs index 6da16fc..38088d7 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -2,6 +2,7 @@ use std::ffi::c_void; use std::io::Write as _; +#[cfg(target_os = "macos")] use std::ptr::NonNull; use iced_graphics::{Shell as GShell, Viewport}; @@ -664,15 +665,57 @@ fn dump_invocation_context() { } /// Native-shell setup used by non-FFI entry points (winit binary on Windows / Linux). -/// Creates log + state dirs, initialises file-based tracing, preloads colours. +/// Creates log + state dirs, initialises file-only tracing (stderr is a broken pipe when +/// launched as a KiCad subprocess — writing blocks the UI thread), preloads colours. pub fn init_native_shell(plugin_root: Option<&std::path::Path>) -> anyhow::Result<()> { paths::create_dirs_if_missing()?; - let _ = init_logging(); - dump_invocation_context(); + let _ = init_logging_file_only(); + dump_invocation_context_file_only(); crate::ui::colors::init(plugin_root); Ok(()) } +fn init_logging_file_only() -> anyhow::Result<()> { + use tracing_subscriber::{fmt, prelude::*, EnvFilter}; + let filter = EnvFilter::try_from_default_env() + .unwrap_or_else(|_| EnvFilter::new("warn,layers=debug,iced=info,wgpu=warn,wgpu_core=warn,wgpu_hal=warn,naga=warn")); + + let file_appender = tracing_appender::rolling::daily(paths::log_dir(), "layers-trace"); + let (non_blocking, guard) = tracing_appender::non_blocking(file_appender); + Box::leak(Box::new(guard)); + + let _ = tracing_subscriber::registry() + .with(filter) + .with(fmt::layer().with_writer(non_blocking).with_ansi(false)) + .try_init(); + Ok(()) +} + +fn dump_invocation_context_file_only() { + let argv: Vec = std::env::args().collect(); + let cwd = std::env::current_dir() + .map(|p| p.display().to_string()) + .unwrap_or_else(|_| "".to_string()); + let socket = std::env::var("KICAD_API_SOCKET").unwrap_or_else(|_| "".to_string()); + let token_preview = match std::env::var("KICAD_API_TOKEN") { + Ok(t) if t.len() > 8 => format!("{}\u{2026}", &t[..8]), + Ok(t) => format!("{t}\u{2026}"), + Err(_) => "".to_string(), + }; + let ts = chrono::Utc::now().to_rfc3339(); + if let Ok(mut f) = std::fs::OpenOptions::new() + .append(true) + .create(true) + .open(paths::log_path()) + { + let _ = writeln!(f, "--- layers invocation {ts} ---"); + let _ = writeln!(f, "layers: argv={argv:?}"); + let _ = writeln!(f, "layers: cwd={cwd}"); + let _ = writeln!(f, "layers: KICAD_API_SOCKET={socket}"); + let _ = writeln!(f, "layers: KICAD_API_TOKEN={token_preview}"); + } +} + #[cfg(feature = "debug")] fn init_logging() -> anyhow::Result<()> { use tracing_subscriber::{fmt, prelude::*, EnvFilter};