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