Skip to content

Commit 5fd356e

Browse files
committed
pr: saving at exit or kill, on window removal
1 parent 9709ddb commit 5fd356e

File tree

1 file changed

+40
-18
lines changed

1 file changed

+40
-18
lines changed

anyrun/src/main.rs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ struct RuntimeData {
184184
error_label: String,
185185
config_dir: String,
186186
state_dir: Option<String>,
187+
last_input: Option<String>,
187188
}
188189

189190
#[derive(Deserialize, Serialize)]
@@ -253,6 +254,7 @@ impl RuntimeData {
253254
error_label,
254255
config_dir,
255256
state_dir,
257+
last_input: None,
256258
}
257259
}
258260

@@ -265,19 +267,19 @@ impl RuntimeData {
265267
if !self.config.persist_state {
266268
return Ok(());
267269
}
268-
270+
269271
let state = PersistentState {
270272
timestamp: SystemTime::now()
271273
.duration_since(UNIX_EPOCH)
272274
.unwrap()
273275
.as_secs(),
274276
text: text.to_string(),
275277
};
276-
278+
277279
fs::write(self.state_file(), ron::ser::to_string_pretty(&state, ron::ser::PrettyConfig::default())
278280
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?)
279281
}
280-
282+
281283
fn load_state(&self) -> io::Result<Option<String>> {
282284
if !self.config.persist_state {
283285
return Ok(None);
@@ -310,13 +312,24 @@ impl RuntimeData {
310312
if !self.config.persist_state {
311313
return Ok(());
312314
}
313-
315+
314316
match fs::remove_file(self.state_file()) {
315317
Ok(()) => Ok(()),
316318
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()), // File doesn't exist = already cleared
317319
Err(e) => Err(e),
318320
}
319321
}
322+
323+
fn persist_state(&self) -> io::Result<()> {
324+
if !self.config.persist_state {
325+
return Ok(());
326+
}
327+
328+
match &self.last_input {
329+
Some(text) => self.save_state(text),
330+
None => self.clear_state(),
331+
}
332+
}
320333
}
321334

322335
/// The naming scheme for CSS styling
@@ -565,20 +578,35 @@ fn activate(app: &gtk::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
565578
.name(style_names::ENTRY)
566579
.build();
567580

568-
// Update last_input, save state and refresh matches when text changes
581+
// Refresh the matches when text input changes
569582
let runtime_data_clone = runtime_data.clone();
570583
entry.connect_changed(move |entry| {
571584
let text = entry.text().to_string();
572-
if let Err(e) = runtime_data_clone.borrow().save_state(&text) {
573-
eprintln!("Failed to save state: {}", e);
585+
586+
refresh_matches(text.clone(), runtime_data_clone.clone());
587+
588+
let runtime_data_update = runtime_data_clone.clone();
589+
590+
// idle_add_local_once is needed to avoid borrow conflicts with the entry widget
591+
glib::idle_add_local_once(move || {
592+
runtime_data_update.borrow_mut().last_input = Some(text);
593+
});
594+
});
595+
596+
597+
// Persist state when window is removed
598+
let runtime_data_clone = runtime_data.clone();
599+
window.connect_delete_event(move |_, _| {
600+
if let Err(e) = runtime_data_clone.borrow().persist_state() {
601+
eprintln!("Failed to handle state persistence on shutdown: {}", e);
574602
}
575-
refresh_matches(text, runtime_data_clone.clone());
603+
Inhibit(false)
576604
});
577605

578606
// Handle other key presses for selection control and all other things that may be needed
579607
let entry_clone = entry.clone();
580608
let runtime_data_clone = runtime_data.clone();
581-
609+
582610
window.connect_key_press_event(move |window, event| {
583611
use gdk::keys::constants;
584612
match event.keyval() {
@@ -688,9 +716,7 @@ fn activate(app: &gtk::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
688716
(*selected_match.data::<Match>("match").unwrap().as_ptr()).clone()
689717
}) {
690718
HandleResult::Close => {
691-
if let Err(e) = _runtime_data_clone.clear_state() {
692-
eprintln!("Failed to clear state: {}", e);
693-
}
719+
_runtime_data_clone.last_input = None;
694720
window.close();
695721
Inhibit(true)
696722
}
@@ -706,19 +732,15 @@ fn activate(app: &gtk::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
706732
}
707733
HandleResult::Copy(bytes) => {
708734
_runtime_data_clone.post_run_action = PostRunAction::Copy(bytes.into());
709-
if let Err(e) = _runtime_data_clone.clear_state() {
710-
eprintln!("Failed to clear state: {}", e);
711-
}
735+
_runtime_data_clone.last_input = None;
712736
window.close();
713737
Inhibit(true)
714738
}
715739
HandleResult::Stdout(bytes) => {
716740
if let Err(why) = io::stdout().lock().write_all(&bytes) {
717741
eprintln!("Error outputting content to stdout: {}", why);
718742
}
719-
if let Err(e) = _runtime_data_clone.clear_state() {
720-
eprintln!("Failed to clear state: {}", e);
721-
}
743+
_runtime_data_clone.last_input = None;
722744
window.close();
723745
Inhibit(true)
724746
}

0 commit comments

Comments
 (0)