Skip to content

Commit c519673

Browse files
Desktop: Fix keyboard shortcuts on windows (#3139)
* Try to fix shortcuts on windows * Fix
1 parent 9411612 commit c519673

2 files changed

Lines changed: 55 additions & 236 deletions

File tree

desktop/src/cef/input.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use winit::dpi::PhysicalPosition;
44
use winit::event::{ElementState, MouseButton, MouseScrollDelta, WindowEvent};
55

66
mod keymap;
7-
use keymap::{ToDomBits, ToVKBits};
7+
use keymap::{ToNativeKeycode, ToVKBits};
88

99
pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputState, event: &WindowEvent) {
1010
match event {
@@ -106,37 +106,46 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
106106
_ => return,
107107
};
108108

109+
let native_key_code = event.physical_key.to_native_keycode();
110+
111+
let modifiers = input_state.cef_modifiers(&event.location, event.repeat).raw();
112+
109113
let mut key_event = KeyEvent {
110114
size: size_of::<KeyEvent>(),
111-
focus_on_editable_field: 1,
112-
modifiers: input_state.cef_modifiers(&event.location, event.repeat).raw(),
113-
is_system_key: 0,
115+
modifiers,
114116
..Default::default()
115117
};
116118

117119
if let Some(named_key) = named_key {
118-
key_event.native_key_code = named_key.to_dom_bits();
119120
key_event.windows_key_code = named_key.to_vk_bits();
120121
} else if let Some(char) = character {
121-
key_event.native_key_code = char.to_dom_bits();
122122
key_event.windows_key_code = char.to_vk_bits();
123123
}
124124

125+
key_event.native_key_code = native_key_code;
126+
125127
match event.state {
126128
ElementState::Pressed => {
127129
key_event.type_ = KeyEventType::from(cef_key_event_type_t::KEYEVENT_RAWKEYDOWN);
128130
host.send_key_event(Some(&key_event));
129131

130132
if let Some(char) = character {
133+
let mut char_key_event = KeyEvent {
134+
size: size_of::<KeyEvent>(),
135+
modifiers,
136+
is_system_key: 0,
137+
..Default::default()
138+
};
131139
let mut buf = [0; 2];
132140
char.encode_utf16(&mut buf);
133-
key_event.character = buf[0];
141+
char_key_event.windows_key_code = buf[0] as i32;
142+
char_key_event.character = buf[0];
143+
char_key_event.native_key_code = native_key_code;
134144
let mut buf = [0; 2];
135145
char.to_lowercase().next().unwrap().encode_utf16(&mut buf);
136-
key_event.unmodified_character = buf[0];
137-
138-
key_event.type_ = KeyEventType::from(cef_key_event_type_t::KEYEVENT_CHAR);
139-
host.send_key_event(Some(&key_event));
146+
char_key_event.unmodified_character = buf[0];
147+
char_key_event.type_ = KeyEventType::from(cef_key_event_type_t::KEYEVENT_CHAR);
148+
host.send_key_event(Some(&char_key_event));
140149
}
141150
}
142151
ElementState::Released => {

desktop/src/cef/input/keymap.rs

Lines changed: 35 additions & 225 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
1-
macro_rules! map_enum {
2-
($target:expr, $enum:ident, $( ($code:expr, $variant:ident), )+ ) => {
3-
match $target {
4-
$(
5-
$enum::$variant => $code,
6-
)+
7-
_ => 0,
1+
pub trait ToNativeKeycode {
2+
fn to_native_keycode(&self) -> i32;
3+
}
4+
5+
impl ToNativeKeycode for winit::keyboard::PhysicalKey {
6+
fn to_native_keycode(&self) -> i32 {
7+
use winit::platform::scancode::PhysicalKeyExtScancode;
8+
9+
#[cfg(target_os = "linux")]
10+
{
11+
self.to_scancode().map(|evdev| (evdev + 8) as i32).unwrap_or(0)
812
}
9-
};
13+
#[cfg(any(target_os = "macos", target_os = "windows"))]
14+
{
15+
self.to_scancode().map(|c| c as i32).unwrap_or(0)
16+
}
17+
}
1018
}
1119

12-
macro_rules! map {
13-
($target:expr, $( ($code:expr, $variant:literal), )+ ) => {
20+
// Windows Virtual keyboard binary representation
21+
pub(crate) trait ToVKBits {
22+
fn to_vk_bits(&self) -> i32;
23+
}
24+
25+
macro_rules! map_enum {
26+
($target:expr, $enum:ident, $( ($code:expr, $variant:ident), )+ ) => {
1427
match $target {
1528
$(
16-
$variant => $code,
29+
$enum::$variant => $code,
1730
)+
1831
_ => 0,
1932
}
2033
};
2134
}
2235

23-
// Windows Virtual keyboard binary representation
24-
pub(crate) trait ToVKBits {
25-
fn to_vk_bits(&self) -> i32;
26-
}
27-
2836
impl ToVKBits for winit::keyboard::NamedKey {
2937
fn to_vk_bits(&self) -> i32 {
3038
use winit::keyboard::NamedKey;
@@ -136,6 +144,17 @@ impl ToVKBits for winit::keyboard::NamedKey {
136144
}
137145
}
138146

147+
macro_rules! map {
148+
($target:expr, $( ($code:expr, $variant:literal), )+ ) => {
149+
match $target {
150+
$(
151+
$variant => $code,
152+
)+
153+
_ => 0,
154+
}
155+
};
156+
}
157+
139158
impl ToVKBits for char {
140159
fn to_vk_bits(&self) -> i32 {
141160
map!(
@@ -237,212 +256,3 @@ impl ToVKBits for char {
237256
)
238257
}
239258
}
240-
241-
// Chromium dom key binary representation
242-
pub(crate) trait ToDomBits {
243-
fn to_dom_bits(&self) -> i32;
244-
}
245-
246-
impl ToDomBits for winit::keyboard::NamedKey {
247-
fn to_dom_bits(&self) -> i32 {
248-
use winit::keyboard::NamedKey;
249-
map_enum!(
250-
self,
251-
NamedKey,
252-
(0x00, Hyper),
253-
(0x85, Super),
254-
(0x25, Control),
255-
(0x32, Shift),
256-
(0x40, Alt),
257-
(0x00, Fn),
258-
(0x00, FnLock),
259-
(0x24, Enter),
260-
(0x09, Escape),
261-
(0x16, Backspace),
262-
(0x17, Tab),
263-
(0x41, Space),
264-
(0x42, CapsLock),
265-
(0x43, F1),
266-
(0x44, F2),
267-
(0x45, F3),
268-
(0x46, F4),
269-
(0x47, F5),
270-
(0x48, F6),
271-
(0x49, F7),
272-
(0x4a, F8),
273-
(0x4b, F9),
274-
(0x4c, F10),
275-
(0x5f, F11),
276-
(0x60, F12),
277-
(0x6b, PrintScreen),
278-
(0x4e, ScrollLock),
279-
(0x7f, Pause),
280-
(0x76, Insert),
281-
(0x6e, Home),
282-
(0x70, PageUp),
283-
(0x77, Delete),
284-
(0x73, End),
285-
(0x75, PageDown),
286-
(0x72, ArrowRight),
287-
(0x71, ArrowLeft),
288-
(0x74, ArrowDown),
289-
(0x6f, ArrowUp),
290-
(0x4d, NumLock),
291-
(0x87, ContextMenu),
292-
(0x7c, Power),
293-
(0xbf, F13),
294-
(0xc0, F14),
295-
(0xc1, F15),
296-
(0xc2, F16),
297-
(0xc3, F17),
298-
(0xc4, F18),
299-
(0xc5, F19),
300-
(0xc6, F20),
301-
(0xc7, F21),
302-
(0xc8, F22),
303-
(0xc9, F23),
304-
(0xca, F24),
305-
(0x8e, Open),
306-
(0x92, Help),
307-
(0x8c, Select),
308-
(0x89, Again),
309-
(0x8b, Undo),
310-
(0x91, Cut),
311-
(0x8d, Copy),
312-
(0x8f, Paste),
313-
(0x90, Find),
314-
(0x79, AudioVolumeMute),
315-
(0x7b, AudioVolumeUp),
316-
(0x7a, AudioVolumeDown),
317-
(0x65, KanaMode),
318-
(0x64, Convert),
319-
(0x66, NonConvert),
320-
(0x00, Props),
321-
(0xe9, BrightnessUp),
322-
(0xe8, BrightnessDown),
323-
(0xd7, MediaPlay),
324-
(0xd1, MediaPause),
325-
(0xaf, MediaRecord),
326-
(0xd8, MediaFastForward),
327-
(0xb0, MediaRewind),
328-
(0xab, MediaTrackNext),
329-
(0xad, MediaTrackPrevious),
330-
(0xae, MediaStop),
331-
(0xa9, Eject),
332-
(0xac, MediaPlayPause),
333-
(0xa3, LaunchMail),
334-
(0xe1, BrowserSearch),
335-
(0xb4, BrowserHome),
336-
(0xa6, BrowserBack),
337-
(0xa7, BrowserForward),
338-
(0x88, BrowserStop),
339-
(0xb5, BrowserRefresh),
340-
(0xa4, BrowserFavorites),
341-
(0xf0, MailReply),
342-
(0xf1, MailForward),
343-
(0xef, MailSend),
344-
)
345-
}
346-
}
347-
348-
impl ToDomBits for char {
349-
fn to_dom_bits(&self) -> i32 {
350-
map!(
351-
self,
352-
(0x26, 'a'),
353-
(0x38, 'b'),
354-
(0x36, 'c'),
355-
(0x28, 'd'),
356-
(0x1a, 'e'),
357-
(0x29, 'f'),
358-
(0x2a, 'g'),
359-
(0x2b, 'h'),
360-
(0x1f, 'i'),
361-
(0x2c, 'j'),
362-
(0x2d, 'k'),
363-
(0x2e, 'l'),
364-
(0x3a, 'm'),
365-
(0x39, 'n'),
366-
(0x20, 'o'),
367-
(0x21, 'p'),
368-
(0x18, 'q'),
369-
(0x1b, 'r'),
370-
(0x27, 's'),
371-
(0x1c, 't'),
372-
(0x1e, 'u'),
373-
(0x37, 'v'),
374-
(0x19, 'w'),
375-
(0x35, 'x'),
376-
(0x1d, 'y'),
377-
(0x34, 'z'),
378-
(0x26, 'A'),
379-
(0x38, 'B'),
380-
(0x36, 'C'),
381-
(0x28, 'D'),
382-
(0x1a, 'E'),
383-
(0x29, 'F'),
384-
(0x2a, 'G'),
385-
(0x2b, 'H'),
386-
(0x1f, 'I'),
387-
(0x2c, 'J'),
388-
(0x2d, 'K'),
389-
(0x2e, 'L'),
390-
(0x3a, 'M'),
391-
(0x39, 'N'),
392-
(0x20, 'O'),
393-
(0x21, 'P'),
394-
(0x18, 'Q'),
395-
(0x1b, 'R'),
396-
(0x27, 'S'),
397-
(0x1c, 'T'),
398-
(0x1e, 'U'),
399-
(0x37, 'V'),
400-
(0x19, 'W'),
401-
(0x35, 'X'),
402-
(0x1d, 'Y'),
403-
(0x34, 'Z'),
404-
(0x0a, '1'),
405-
(0x0b, '2'),
406-
(0x0c, '3'),
407-
(0x0d, '4'),
408-
(0x0e, '5'),
409-
(0x0f, '6'),
410-
(0x10, '7'),
411-
(0x11, '8'),
412-
(0x12, '9'),
413-
(0x13, '0'),
414-
(0x0a, '!'),
415-
(0x0b, '@'),
416-
(0x0c, '#'),
417-
(0x0d, '$'),
418-
(0x0e, '%'),
419-
(0x0f, '^'),
420-
(0x10, '&'),
421-
(0x11, '*'),
422-
(0x12, '('),
423-
(0x13, ')'),
424-
(0x31, '`'),
425-
(0x31, '~'),
426-
(0x14, '-'),
427-
(0x14, '_'),
428-
(0x15, '='),
429-
(0x15, '+'),
430-
(0x22, '['),
431-
(0x22, '{'),
432-
(0x23, ']'),
433-
(0x23, '}'),
434-
(0x33, '\\'),
435-
(0x33, '|'),
436-
(0x2f, ';'),
437-
(0x2f, ':'),
438-
(0x3b, ','),
439-
(0x3b, '<'),
440-
(0x3c, '.'),
441-
(0x3c, '>'),
442-
(0x30, '\''),
443-
(0x30, '"'),
444-
(0x3d, '/'),
445-
(0x3d, '?'),
446-
)
447-
}
448-
}

0 commit comments

Comments
 (0)