diff options
Diffstat (limited to 'src/file_registry.rs')
| -rw-r--r-- | src/file_registry.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/file_registry.rs b/src/file_registry.rs new file mode 100644 index 0000000..25aba3f --- /dev/null +++ b/src/file_registry.rs @@ -0,0 +1,52 @@ +//! Manages tracking of open files and window controllers. +//! +//! GTK is single-threaded, so thread-local storage is safe here. + +use std::cell::RefCell; +use std::path::PathBuf; + +use relm4::component::Controller; +use relm4::gtk; + +use crate::AppModel; + +thread_local! { + /// Keeps window controllers alive for the lifetime of each window. + static WINDOW_CONTROLLERS: RefCell<Vec<Controller<AppModel>>> = const { RefCell::new(Vec::new()) }; + + /// Tracks which files are currently open to prevent duplicate windows. + static OPEN_FILES: RefCell<Vec<(PathBuf, gtk::Window)>> = const { RefCell::new(Vec::new()) }; +} + +/// Stores a window controller to keep it alive. +pub fn store_controller(controller: Controller<AppModel>) { + WINDOW_CONTROLLERS.with_borrow_mut(|controllers| { + controllers.push(controller); + }); +} + +/// Returns the window that has the given file open, if any. +pub fn find_window_for_file(path: &PathBuf) -> Option<gtk::Window> { + OPEN_FILES.with_borrow(|files| { + files + .iter() + .find(|(file_path, _)| file_path == path) + .map(|(_, window)| window.clone()) + }) +} + +/// Registers a file as being open in the given window. +pub fn register_file(path: &PathBuf, window: >k::Window) { + OPEN_FILES.with_borrow_mut(|files| { + if !files.iter().any(|(file_path, _)| file_path == path) { + files.push((path.clone(), window.clone())); + } + }); +} + +/// Unregisters a file when its window is closed. +pub fn unregister_file(path: &PathBuf) { + OPEN_FILES.with_borrow_mut(|files| { + files.retain(|(file_path, _)| file_path != path); + }); +} |