1
1
//! The canvas handles drawing the selection frame
2
2
use iced:: Event :: { Keyboard , Mouse } ;
3
+ use iced:: advanced:: debug:: core:: SmolStr ;
3
4
use iced:: keyboard:: Event :: KeyPressed ;
4
5
use iced:: keyboard:: Event :: KeyReleased ;
5
6
use iced:: keyboard:: Key :: { self , Character , Named } ;
7
+ use iced:: keyboard:: Modifiers ;
6
8
use iced:: keyboard:: Modifiers as Mods ;
7
9
use iced:: keyboard:: key:: Named :: F11 ;
8
10
use iced:: keyboard:: key:: Named :: { Enter , Escape , Shift } ;
@@ -108,12 +110,52 @@ impl canvas::Program<Message> for App {
108
110
_bounds : Rectangle ,
109
111
cursor : iced:: advanced:: mouse:: Cursor ,
110
112
) -> Option < widget:: Action < Message > > {
111
- if let Keyboard ( KeyPressed { key, modifiers, .. } ) = event {
113
+ if let Keyboard ( KeyPressed {
114
+ modifiers,
115
+ text,
116
+ key,
117
+ ..
118
+ } ) = event
119
+ {
120
+ let mut modifiers = * modifiers;
121
+
122
+ // Shift key does not matter. For example:
123
+ // - pressing `<` and the `SHIFT` modifier will be pressed
124
+ // - `G` will also trigger the `SHIFT` modifier
125
+ modifiers. remove ( Modifiers :: SHIFT ) ;
126
+
127
+ let key = if let Key :: Named ( name) = key {
128
+ // named key takes priority over anything.
129
+ //
130
+ // For example, if we input `Escape` it will send the `text`
131
+ // `\u{1b}` which won't match any of the keys that we have. So we must
132
+ // intercept before that happens
133
+ Key :: Named ( * name)
134
+ } else {
135
+ // if we input `G` for example, it actually sends:
136
+ // - modifier: `shift`
137
+ // - key: `g`
138
+ // - text: `G`
139
+ //
140
+ // if we input `<` it sends:
141
+ // - modifier: `shift`
142
+ // - key: `,`
143
+ // - text: `<`
144
+ //
145
+ // So `text` is our source of truth. However, sometimes it is not available.
146
+ // If `key != Key::Named` and `text == None` then we use the actual `key`
147
+ // as a fallback.
148
+ //
149
+ // It is unknown when this fallback might be used, but it is kept just in case.
150
+ text. as_ref ( )
151
+ . map_or_else ( || key. clone ( ) , |ch| Key :: Character ( ch. clone ( ) ) )
152
+ } ;
112
153
if let Some ( ( _, action) ) = CONFIG
113
154
. keys
114
155
. keys
115
156
// e.g. for instance keybind for `g` should take priority over `gg`
116
157
. get ( & KeySequence ( ( key. clone ( ) , None ) ) )
158
+ . filter ( |( mods, _) | modifiers == mods. 0 )
117
159
// e.g. in this case we try the `gg` keybinding since `g` does not exist
118
160
. or_else ( || {
119
161
state
@@ -126,7 +168,7 @@ impl canvas::Program<Message> for App {
126
168
. get ( & KeySequence ( ( last_key_pressed. clone ( ) , Some ( key. clone ( ) ) ) ) )
127
169
} )
128
170
} )
129
- . filter ( |( mods, _) | * modifiers == mods. 0 )
171
+ . filter ( |( mods, _) | modifiers == mods. 0 )
130
172
{
131
173
// the last key pressed needs to be reset for it to be
132
174
// correct in future invocations
@@ -140,7 +182,12 @@ impl canvas::Program<Message> for App {
140
182
return Some ( Action :: publish ( Message :: KeyBind ( action. clone ( ) ) ) ) ;
141
183
}
142
184
143
- state. last_key_pressed = Some ( key. clone ( ) ) ;
185
+ // the "Shift" is already included in the modifiers
186
+ //
187
+ // This way pressing e.g. `G` would only set the last_key_pressed once
188
+ if key != Named ( Shift ) {
189
+ state. last_key_pressed = Some ( key) ;
190
+ }
144
191
}
145
192
146
193
let message = match event {
0 commit comments