Skip to content

Commit 321b7fd

Browse files
committed
pr: saving at exit or kill, on window removal
1 parent b989bca commit 321b7fd

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
@@ -185,6 +185,7 @@ struct RuntimeData {
185185
error_label: String,
186186
config_dir: String,
187187
state_dir: Option<String>,
188+
last_input: Option<String>,
188189
}
189190

190191
#[derive(Deserialize, Serialize)]
@@ -254,6 +255,7 @@ impl RuntimeData {
254255
error_label,
255256
config_dir,
256257
state_dir,
258+
last_input: None,
257259
}
258260
}
259261

@@ -266,19 +268,19 @@ impl RuntimeData {
266268
if !self.config.persist_state {
267269
return Ok(());
268270
}
269-
271+
270272
let state = PersistentState {
271273
timestamp: SystemTime::now()
272274
.duration_since(UNIX_EPOCH)
273275
.unwrap()
274276
.as_secs(),
275277
text: text.to_string(),
276278
};
277-
279+
278280
fs::write(self.state_file(), ron::ser::to_string_pretty(&state, ron::ser::PrettyConfig::default())
279281
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?)
280282
}
281-
283+
282284
fn load_state(&self) -> io::Result<Option<String>> {
283285
if !self.config.persist_state {
284286
return Ok(None);
@@ -311,13 +313,24 @@ impl RuntimeData {
311313
if !self.config.persist_state {
312314
return Ok(());
313315
}
314-
316+
315317
match fs::remove_file(self.state_file()) {
316318
Ok(()) => Ok(()),
317319
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()), // File doesn't exist = already cleared
318320
Err(e) => Err(e),
319321
}
320322
}
323+
324+
fn persist_state(&self) -> io::Result<()> {
325+
if !self.config.persist_state {
326+
return Ok(());
327+
}
328+
329+
match &self.last_input {
330+
Some(text) => self.save_state(text),
331+
None => self.clear_state(),
332+
}
333+
}
321334
}
322335

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

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

579607
// Handle other key presses for selection control and all other things that may be needed
580608
let entry_clone = entry.clone();
581609
let runtime_data_clone = runtime_data.clone();
582-
610+
583611
window.connect_key_press_event(move |window, event| {
584612
use gdk::keys::constants;
585613
match event.keyval() {
@@ -689,9 +717,7 @@ fn activate(app: &gtk::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
689717
(*selected_match.data::<Match>("match").unwrap().as_ptr()).clone()
690718
}) {
691719
HandleResult::Close => {
692-
if let Err(e) = _runtime_data_clone.clear_state() {
693-
eprintln!("Failed to clear state: {}", e);
694-
}
720+
_runtime_data_clone.last_input = None;
695721
window.close();
696722
Inhibit(true)
697723
}
@@ -707,19 +733,15 @@ fn activate(app: &gtk::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
707733
}
708734
HandleResult::Copy(bytes) => {
709735
_runtime_data_clone.post_run_action = PostRunAction::Copy(bytes.into());
710-
if let Err(e) = _runtime_data_clone.clear_state() {
711-
eprintln!("Failed to clear state: {}", e);
712-
}
736+
_runtime_data_clone.last_input = None;
713737
window.close();
714738
Inhibit(true)
715739
}
716740
HandleResult::Stdout(bytes) => {
717741
if let Err(why) = io::stdout().lock().write_all(&bytes) {
718742
eprintln!("Error outputting content to stdout: {}", why);
719743
}
720-
if let Err(e) = _runtime_data_clone.clear_state() {
721-
eprintln!("Failed to clear state: {}", e);
722-
}
744+
_runtime_data_clone.last_input = None;
723745
window.close();
724746
Inhibit(true)
725747
}

0 commit comments

Comments
 (0)