egui-winit: emit physical key presses when a non-Latin layout is active (#4461)
resolves https://github.com/emilk/egui/issues/4081 (see discussion starting from https://github.com/emilk/egui/issues/3653#issuecomment-1962740175 for extra context) 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. while originally I have only limited this to clipboard shortcuts (Ctrl+C/V/X), honestly it felt like a half-assed solution. as a result, I decided to expand this behaviour to all key events to stick to the original logic, in case there are other workflows and hotkeys people rely on or expect to work out of the box. let me know if this is an issue.
This commit is contained in:
parent
f19f99180e
commit
2b2e70cb91
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue