|
1 | | -use std::{collections::HashMap, time::Duration}; |
| 1 | +use std::{collections::HashMap, path::PathBuf, time::Duration}; |
2 | 2 |
|
3 | 3 | use data::{ |
4 | 4 | AppState, |
@@ -41,6 +41,10 @@ use crate::config_dialogs::{ |
41 | 41 | }; |
42 | 42 | use crate::udev_dialog::UdevDialogMsg; |
43 | 43 |
|
| 44 | +use common::{APP, ORG, QUALIFIER}; |
| 45 | +use directories::ProjectDirs; |
| 46 | +use fslock::LockFile; |
| 47 | + |
44 | 48 | #[macro_use] |
45 | 49 | extern crate log; |
46 | 50 |
|
@@ -69,7 +73,27 @@ impl<H: HardwareBridge> CosmicFlags for Flags<H> { |
69 | 73 | type Args = Vec<String>; |
70 | 74 | } |
71 | 75 |
|
72 | | -pub fn run_ui<H: HardwareBridge + 'static>(app_state: AppState<H>) { |
| 76 | +pub fn run_ui<H: HardwareBridge + 'static>(mut app_state: AppState<H>) { |
| 77 | + // ensure single instance |
| 78 | + let instance_lock_path = if cfg!(debug_assertions) { |
| 79 | + let _ = std::fs::create_dir_all("temp"); |
| 80 | + PathBuf::from("temp").join("app.lock") |
| 81 | + } else { |
| 82 | + let project_dirs = ProjectDirs::from(QUALIFIER, ORG, APP).unwrap(); |
| 83 | + project_dirs.cache_dir().join("app.lock") |
| 84 | + }; |
| 85 | + let mut app_lock = LockFile::open(&instance_lock_path).expect("Failed to open app lock file"); |
| 86 | + if !app_lock.try_lock_with_pid().unwrap_or(false) { |
| 87 | + info!( |
| 88 | + "Another instance is already running. PID can be found in {:?}", |
| 89 | + instance_lock_path |
| 90 | + ); |
| 91 | + if let Err(e) = app_state.bridge.shutdown() { |
| 92 | + error!("shutdown hardware: {e}"); |
| 93 | + } |
| 94 | + return; |
| 95 | + } |
| 96 | + |
73 | 97 | utils::setup_wgpu(); |
74 | 98 |
|
75 | 99 | let settings = cosmic::app::Settings::default() |
|
0 commit comments