From 6f097ea5a87554749995afc8dd8b301b52127146 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 20 Dec 2023 12:06:23 +0100 Subject: [PATCH] egui-winit: Handle `Cut`, `Copy` and `Paste` commands The comment added in commit 8a0bc97e ("[egui_glium] Fix paste") seems to assume that `winit` "should have translated" common "paste" keyboard combos to a `Cut`/`Copy`/`Paste` "KeyCode", but completely glossed over the fact that this `KeyCode` (now also `NamedKey`) maps to a special key dedicated to this purpose found on some keyboards and OSes. Make sure that this key is still handled in addition to the combo that is detected. --- crates/egui-winit/src/lib.rs | 94 +++++++++++++++++++---------------- crates/egui/src/data/input.rs | 15 ++++++ 2 files changed, 66 insertions(+), 43 deletions(-) diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index da4d2bc4358..d8238f4b460 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -686,8 +686,6 @@ impl State { if let Some(logical_key) = logical_key { if pressed { - // KeyCode::Paste etc in winit are broken/untrustworthy, - // so we detect these things manually: if is_cut_command(self.egui_input.modifiers, logical_key) { self.egui_input.events.push(egui::Event::Cut); return true; @@ -941,17 +939,20 @@ fn is_printable_char(chr: char) -> bool { } fn is_cut_command(modifiers: egui::Modifiers, keycode: egui::Key) -> bool { - (modifiers.command && keycode == egui::Key::X) + keycode == egui::Key::Cut + || (modifiers.command && keycode == egui::Key::X) || (cfg!(target_os = "windows") && modifiers.shift && keycode == egui::Key::Delete) } fn is_copy_command(modifiers: egui::Modifiers, keycode: egui::Key) -> bool { - (modifiers.command && keycode == egui::Key::C) + keycode == egui::Key::Copy + || (modifiers.command && keycode == egui::Key::C) || (cfg!(target_os = "windows") && modifiers.ctrl && keycode == egui::Key::Insert) } fn is_paste_command(modifiers: egui::Modifiers, keycode: egui::Key) -> bool { - (modifiers.command && keycode == egui::Key::V) + keycode == egui::Key::Paste + || (modifiers.command && keycode == egui::Key::V) || (cfg!(target_os = "windows") && modifiers.shift && keycode == egui::Key::Insert) } @@ -978,47 +979,50 @@ fn key_from_named_key(named_key: winit::keyboard::NamedKey) -> Option use egui::Key; use winit::keyboard::NamedKey; - match named_key { - NamedKey::Enter => Some(Key::Enter), - NamedKey::Tab => Some(Key::Tab), - NamedKey::Space => Some(Key::Space), - NamedKey::ArrowDown => Some(Key::ArrowDown), - NamedKey::ArrowLeft => Some(Key::ArrowLeft), - NamedKey::ArrowRight => Some(Key::ArrowRight), - NamedKey::ArrowUp => Some(Key::ArrowUp), - NamedKey::End => Some(Key::End), - NamedKey::Home => Some(Key::Home), - NamedKey::PageDown => Some(Key::PageDown), - NamedKey::PageUp => Some(Key::PageUp), - NamedKey::Backspace => Some(Key::Backspace), - NamedKey::Delete => Some(Key::Delete), - NamedKey::Insert => Some(Key::Insert), - NamedKey::Escape => Some(Key::Escape), - NamedKey::F1 => Some(Key::F1), - NamedKey::F2 => Some(Key::F2), - NamedKey::F3 => Some(Key::F3), - NamedKey::F4 => Some(Key::F4), - NamedKey::F5 => Some(Key::F5), - NamedKey::F6 => Some(Key::F6), - NamedKey::F7 => Some(Key::F7), - NamedKey::F8 => Some(Key::F8), - NamedKey::F9 => Some(Key::F9), - NamedKey::F10 => Some(Key::F10), - NamedKey::F11 => Some(Key::F11), - NamedKey::F12 => Some(Key::F12), - NamedKey::F13 => Some(Key::F13), - NamedKey::F14 => Some(Key::F14), - NamedKey::F15 => Some(Key::F15), - NamedKey::F16 => Some(Key::F16), - NamedKey::F17 => Some(Key::F17), - NamedKey::F18 => Some(Key::F18), - NamedKey::F19 => Some(Key::F19), - NamedKey::F20 => Some(Key::F20), + Some(match named_key { + NamedKey::Enter => Key::Enter, + NamedKey::Tab => Key::Tab, + NamedKey::Space => Key::Space, + NamedKey::ArrowDown => Key::ArrowDown, + NamedKey::ArrowLeft => Key::ArrowLeft, + NamedKey::ArrowRight => Key::ArrowRight, + NamedKey::ArrowUp => Key::ArrowUp, + NamedKey::End => Key::End, + NamedKey::Home => Key::Home, + NamedKey::PageDown => Key::PageDown, + NamedKey::PageUp => Key::PageUp, + NamedKey::Backspace => Key::Backspace, + NamedKey::Delete => Key::Delete, + NamedKey::Insert => Key::Insert, + NamedKey::Escape => Key::Escape, + NamedKey::Cut => Key::Cut, + NamedKey::Copy => Key::Copy, + NamedKey::Paste => Key::Paste, + NamedKey::F1 => Key::F1, + NamedKey::F2 => Key::F2, + NamedKey::F3 => Key::F3, + NamedKey::F4 => Key::F4, + NamedKey::F5 => Key::F5, + NamedKey::F6 => Key::F6, + NamedKey::F7 => Key::F7, + NamedKey::F8 => Key::F8, + NamedKey::F9 => Key::F9, + NamedKey::F10 => Key::F10, + NamedKey::F11 => Key::F11, + NamedKey::F12 => Key::F12, + NamedKey::F13 => Key::F13, + NamedKey::F14 => Key::F14, + NamedKey::F15 => Key::F15, + NamedKey::F16 => Key::F16, + NamedKey::F17 => Key::F17, + NamedKey::F18 => Key::F18, + NamedKey::F19 => Key::F19, + NamedKey::F20 => Key::F20, _ => { log::trace!("Unknown key: {named_key:?}"); - None + return None; } - } + }) } fn key_from_key_code(key: winit::keyboard::KeyCode) -> Option { @@ -1049,6 +1053,10 @@ fn key_from_key_code(key: winit::keyboard::KeyCode) -> Option { // KeyCode::Colon => Key::Colon, // NOTE: there is no physical colon key on an american keyboard KeyCode::Semicolon => Key::Semicolon, + KeyCode::Cut => Key::Cut, + KeyCode::Copy => Key::Copy, + KeyCode::Paste => Key::Paste, + KeyCode::Minus | KeyCode::NumpadSubtract => Key::Minus, // Using Mac the key with the Plus sign on it is reported as the Equals key diff --git a/crates/egui/src/data/input.rs b/crates/egui/src/data/input.rs index afb6e1dcbeb..71b77d97020 100644 --- a/crates/egui/src/data/input.rs +++ b/crates/egui/src/data/input.rs @@ -879,6 +879,10 @@ pub enum Key { PageUp, PageDown, + Copy, + Cut, + Paste, + // ---------------------------------------------- // Punctuation: /// `:` @@ -1005,6 +1009,9 @@ impl Key { Self::End, Self::PageUp, Self::PageDown, + Self::Copy, + Self::Cut, + Self::Paste, // Punctuation: Self::Colon, Self::Comma, @@ -1102,6 +1109,10 @@ impl Key { "PageUp" => Self::PageUp, "PageDown" => Self::PageDown, + "Copy" => Self::Copy, + "Cut" => Self::Cut, + "Paste" => Self::Paste, + "Colon" | ":" => Self::Colon, "Comma" | "," => Self::Comma, "Minus" | "-" | "−" => Self::Minus, @@ -1209,6 +1220,10 @@ impl Key { Key::PageUp => "PageUp", Key::PageDown => "PageDown", + Key::Copy => "Copy", + Key::Cut => "Cut", + Key::Paste => "Paste", + Key::Colon => "Colon", Key::Comma => "Comma", Key::Minus => "Minus",