From 86cc3958ac5c80ca122ce459df0b4e17acf7dc6a Mon Sep 17 00:00:00 2001 From: TicClick Date: Sun, 5 May 2024 02:18:30 +0200 Subject: [PATCH 1/2] egui-winit: emit physical key presses when a non-Latin layout is active this partly restores event-emitting behaviour to the state before #3649, when shortcuts such as Ctrl-C used to work regardless of the active layout. the difference is that physical keys are only used in case of the logical ones' absence now among the named keys. --- crates/egui-winit/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index abadd9ee5c2..4ee404e4436 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -746,15 +746,19 @@ impl State { physical_key ); - if let Some(logical_key) = logical_key { + // "Logical OR physical key" is a fallback mechanism for keyboard layouts without Latin characters: it lets them + // emit events as if the corresponding keys from the Latin layout were pressed. In this case, clipboard shortcuts + // are mapped to the physical keys that normally contain C, X, V, etc. + // See also: https://github.com/emilk/egui/issues/3653 + if let Some(active_key) = logical_key.or(physical_key) { if pressed { - if is_cut_command(self.egui_input.modifiers, logical_key) { + if is_cut_command(self.egui_input.modifiers, active_key) { self.egui_input.events.push(egui::Event::Cut); return; - } else if is_copy_command(self.egui_input.modifiers, logical_key) { + } else if is_copy_command(self.egui_input.modifiers, active_key) { self.egui_input.events.push(egui::Event::Copy); return; - } else if is_paste_command(self.egui_input.modifiers, logical_key) { + } else if is_paste_command(self.egui_input.modifiers, active_key) { if let Some(contents) = self.clipboard.get() { let contents = contents.replace("\r\n", "\n"); if !contents.is_empty() { @@ -766,7 +770,7 @@ impl State { } self.egui_input.events.push(egui::Event::Key { - key: logical_key, + key: active_key, physical_key, pressed, repeat: false, // egui will fill this in for us! From 73d9ecc1076e6f22747519d67edbe3ec31540318 Mon Sep 17 00:00:00 2001 From: TicClick Date: Fri, 10 May 2024 23:04:59 +0200 Subject: [PATCH 2/2] document that `egui::Key::key` may contain a physical key code --- crates/egui/src/data/input.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/egui/src/data/input.rs b/crates/egui/src/data/input.rs index 8217f4f5a4d..2260db1f433 100644 --- a/crates/egui/src/data/input.rs +++ b/crates/egui/src/data/input.rs @@ -361,10 +361,12 @@ pub enum Event { /// A key was pressed or released. Key { - /// The logical key, heeding the users keymap. + /// Most of the time, it's the logical key, heeding the active keymap -- for instance, if the user has Dvorak + /// keyboard layout, it will be taken into account. /// - /// For instance, if the user is using Dvorak keyboard layout, - /// this will take that into account. + /// If it's impossible to determine the logical key on desktop platforms (say, in case of non-Latin letters), + /// `key` falls back to the value of the corresponding physical key. This is necessary for proper work of + /// standard shortcuts that only respond to Latin-based bindings (such as `Ctrl` + `V`). key: Key, /// The physical key, corresponding to the actual position on the keyboard.