@@ -185,6 +185,7 @@ struct RuntimeData {
185
185
error_label : String ,
186
186
config_dir : String ,
187
187
state_dir : Option < String > ,
188
+ last_input : Option < String > ,
188
189
}
189
190
190
191
#[ derive( Deserialize , Serialize ) ]
@@ -254,6 +255,7 @@ impl RuntimeData {
254
255
error_label,
255
256
config_dir,
256
257
state_dir,
258
+ last_input : None ,
257
259
}
258
260
}
259
261
@@ -266,19 +268,19 @@ impl RuntimeData {
266
268
if !self . config . persist_state {
267
269
return Ok ( ( ) ) ;
268
270
}
269
-
271
+
270
272
let state = PersistentState {
271
273
timestamp : SystemTime :: now ( )
272
274
. duration_since ( UNIX_EPOCH )
273
275
. unwrap ( )
274
276
. as_secs ( ) ,
275
277
text : text. to_string ( ) ,
276
278
} ;
277
-
279
+
278
280
fs:: write ( self . state_file ( ) , ron:: ser:: to_string_pretty ( & state, ron:: ser:: PrettyConfig :: default ( ) )
279
281
. map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?)
280
282
}
281
-
283
+
282
284
fn load_state ( & self ) -> io:: Result < Option < String > > {
283
285
if !self . config . persist_state {
284
286
return Ok ( None ) ;
@@ -311,13 +313,24 @@ impl RuntimeData {
311
313
if !self . config . persist_state {
312
314
return Ok ( ( ) ) ;
313
315
}
314
-
316
+
315
317
match fs:: remove_file ( self . state_file ( ) ) {
316
318
Ok ( ( ) ) => Ok ( ( ) ) ,
317
319
Err ( e) if e. kind ( ) == io:: ErrorKind :: NotFound => Ok ( ( ) ) , // File doesn't exist = already cleared
318
320
Err ( e) => Err ( e) ,
319
321
}
320
322
}
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
+ }
321
334
}
322
335
323
336
/// The naming scheme for CSS styling
@@ -566,20 +579,35 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
566
579
. name ( style_names:: ENTRY )
567
580
. build ( ) ;
568
581
569
- // Update last_input, save state and refresh matches when text changes
582
+ // Refresh the matches when text input changes
570
583
let runtime_data_clone = runtime_data. clone ( ) ;
571
584
entry. connect_changed ( move |entry| {
572
585
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) ;
575
603
}
576
- refresh_matches ( text , runtime_data_clone . clone ( ) ) ;
604
+ Inhibit ( false )
577
605
} ) ;
578
606
579
607
// Handle other key presses for selection control and all other things that may be needed
580
608
let entry_clone = entry. clone ( ) ;
581
609
let runtime_data_clone = runtime_data. clone ( ) ;
582
-
610
+
583
611
window. connect_key_press_event ( move |window, event| {
584
612
use gdk:: keys:: constants;
585
613
match event. keyval ( ) {
@@ -689,9 +717,7 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
689
717
( * selected_match. data :: < Match > ( "match" ) . unwrap ( ) . as_ptr ( ) ) . clone ( )
690
718
} ) {
691
719
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 ;
695
721
window. close ( ) ;
696
722
Inhibit ( true )
697
723
}
@@ -707,19 +733,15 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<RuntimeData>>) {
707
733
}
708
734
HandleResult :: Copy ( bytes) => {
709
735
_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 ;
713
737
window. close ( ) ;
714
738
Inhibit ( true )
715
739
}
716
740
HandleResult :: Stdout ( bytes) => {
717
741
if let Err ( why) = io:: stdout ( ) . lock ( ) . write_all ( & bytes) {
718
742
eprintln ! ( "Error outputting content to stdout: {}" , why) ;
719
743
}
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 ;
723
745
window. close ( ) ;
724
746
Inhibit ( true )
725
747
}
0 commit comments