From 0cde65839cdfc66b7338bc6b160b9018f1784a7c Mon Sep 17 00:00:00 2001 From: jess Date: Sat, 25 Apr 2026 14:39:10 -0700 Subject: [PATCH] diagnose failure to stash or restore layer states across sessions on flatpak --- src/app.rs | 18 ++++++++++++++++++ src/ffi.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 167363f..e7c5004 100644 --- a/src/app.rs +++ b/src/app.rs @@ -264,8 +264,21 @@ impl App { } crate::ipc::Event::OpenDocuments(paths) => { if let Some(pcb) = paths.into_iter().next() { + let canonical = pcb + .canonicalize() + .ok() + .map(|p| p.display().to_string()) + .unwrap_or_else(|| "".to_string()); let hash = crate::paths::project_hash(&pcb); let state_path = crate::paths::state_path(&hash); + tracing::info!( + pcb_raw = %pcb.display(), + pcb_canonical = %canonical, + project_hash = %hash, + state_path = %state_path.display(), + state_exists = state_path.exists(), + "open document: resolving project state" + ); self.current_project = Some(ProjectContext { project_hash: hash, kicad_pcb_path: pcb, @@ -274,6 +287,11 @@ impl App { self.has_pruned_orphans = false; match crate::layers::persistence::load(&state_path) { Ok(tree) => { + tracing::info!( + state_path = %state_path.display(), + layer_count = tree.layers.len(), + "loaded layer tree from disk" + ); self.layer_tree = tree; self.rebuild_panel_content(); } diff --git a/src/ffi.rs b/src/ffi.rs index 38088d7..2d35dc7 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -618,13 +618,23 @@ fn persist_if_due(app: &mut App) { return; } let state_path = paths::state_path(&project.project_hash); + let layer_count = app.layer_tree.layers.len(); match crate::layers::persistence::save(&app.layer_tree, &state_path) { Ok(()) => { + tracing::debug!( + state_path = %state_path.display(), + layer_count, + "saved layer tree" + ); app.dirty = false; app.last_save = Some(std::time::Instant::now()); } Err(e) => { - tracing::warn!("layer state save failed: {e}"); + tracing::warn!( + state_path = %state_path.display(), + layer_count, + "layer state save failed: {e}" + ); app.last_save = Some(std::time::Instant::now()); } } @@ -671,10 +681,28 @@ pub fn init_native_shell(plugin_root: Option<&std::path::Path>) -> anyhow::Resul paths::create_dirs_if_missing()?; let _ = init_logging_file_only(); dump_invocation_context_file_only(); + probe_data_dir_writable(); crate::ui::colors::init(plugin_root); Ok(()) } +fn probe_data_dir_writable() { + let dir = paths::data_dir(); + let probe = dir.join(".write-probe"); + match std::fs::write(&probe, b"ok") { + Ok(()) => { + let _ = std::fs::remove_file(&probe); + tracing::info!(data_dir = %dir.display(), "data dir is writable"); + } + Err(e) => { + tracing::error!( + data_dir = %dir.display(), + "data dir NOT writable: {e} — state and logs won't persist; check flatpak --filesystem=home" + ); + } + } +} + fn init_logging_file_only() -> anyhow::Result<()> { use tracing_subscriber::{fmt, prelude::*, EnvFilter}; let filter = EnvFilter::try_from_default_env()