1
1
use crossterm:: event:: { self , Event , KeyCode , KeyEventKind } ;
2
- use std:: sync:: mpsc:: Sender ;
2
+ use std:: sync:: {
3
+ atomic:: { AtomicBool , Ordering :: Relaxed } ,
4
+ mpsc:: Sender ,
5
+ } ;
3
6
4
7
use super :: WatchEvent ;
5
8
9
+ static INPUT_PAUSED : AtomicBool = AtomicBool :: new ( false ) ;
10
+
11
+ // Private unit type to force using the constructor function.
12
+ #[ must_use = "When the guard is dropped, the input is unpaused" ]
13
+ pub struct InputPauseGuard ( ( ) ) ;
14
+
15
+ impl InputPauseGuard {
16
+ #[ inline]
17
+ pub fn scoped_pause ( ) -> Self {
18
+ INPUT_PAUSED . store ( true , Relaxed ) ;
19
+ Self ( ( ) )
20
+ }
21
+ }
22
+
23
+ impl Drop for InputPauseGuard {
24
+ #[ inline]
25
+ fn drop ( & mut self ) {
26
+ INPUT_PAUSED . store ( false , Relaxed ) ;
27
+ }
28
+ }
29
+
6
30
pub enum InputEvent {
7
31
Run ,
8
32
Next ,
@@ -11,46 +35,41 @@ pub enum InputEvent {
11
35
Quit ,
12
36
}
13
37
14
- pub fn terminal_event_handler ( tx : Sender < WatchEvent > , manual_run : bool ) {
15
- let last_input_event = loop {
16
- let terminal_event = match event:: read ( ) {
17
- Ok ( v) => v,
18
- Err ( e) => {
19
- // If `send` returns an error, then the receiver is dropped and
20
- // a shutdown has been already initialized.
21
- let _ = tx. send ( WatchEvent :: TerminalEventErr ( e) ) ;
22
- return ;
23
- }
24
- } ;
25
-
26
- match terminal_event {
27
- Event :: Key ( key) => {
38
+ pub fn terminal_event_handler ( sender : Sender < WatchEvent > , manual_run : bool ) {
39
+ let last_watch_event = loop {
40
+ match event:: read ( ) {
41
+ Ok ( Event :: Key ( key) ) => {
28
42
match key. kind {
29
43
KeyEventKind :: Release | KeyEventKind :: Repeat => continue ,
30
44
KeyEventKind :: Press => ( ) ,
31
45
}
32
46
47
+ if INPUT_PAUSED . load ( Relaxed ) {
48
+ continue ;
49
+ }
50
+
33
51
let input_event = match key. code {
34
52
KeyCode :: Char ( 'n' ) => InputEvent :: Next ,
35
53
KeyCode :: Char ( 'h' ) => InputEvent :: Hint ,
36
- KeyCode :: Char ( 'l' ) => break InputEvent :: List ,
37
- KeyCode :: Char ( 'q' ) => break InputEvent :: Quit ,
54
+ KeyCode :: Char ( 'l' ) => break WatchEvent :: Input ( InputEvent :: List ) ,
55
+ KeyCode :: Char ( 'q' ) => break WatchEvent :: Input ( InputEvent :: Quit ) ,
38
56
KeyCode :: Char ( 'r' ) if manual_run => InputEvent :: Run ,
39
57
_ => continue ,
40
58
} ;
41
59
42
- if tx . send ( WatchEvent :: Input ( input_event) ) . is_err ( ) {
60
+ if sender . send ( WatchEvent :: Input ( input_event) ) . is_err ( ) {
43
61
return ;
44
62
}
45
63
}
46
- Event :: Resize ( width, _) => {
47
- if tx . send ( WatchEvent :: TerminalResize { width } ) . is_err ( ) {
64
+ Ok ( Event :: Resize ( width, _) ) => {
65
+ if sender . send ( WatchEvent :: TerminalResize { width } ) . is_err ( ) {
48
66
return ;
49
67
}
50
68
}
51
- Event :: FocusGained | Event :: FocusLost | Event :: Mouse ( _) => continue ,
69
+ Ok ( Event :: FocusGained | Event :: FocusLost | Event :: Mouse ( _) ) => continue ,
70
+ Err ( e) => break WatchEvent :: TerminalEventErr ( e) ,
52
71
}
53
72
} ;
54
73
55
- let _ = tx . send ( WatchEvent :: Input ( last_input_event ) ) ;
74
+ let _ = sender . send ( last_watch_event ) ;
56
75
}
0 commit comments