Winit update to master

Conflicts:
	internal/backends/winit/event_loop.rs
	internal/common/key_codes.rs
This commit is contained in:
Tobias Hunger 2023-06-22 18:57:35 +02:00 committed by Olivier Goffart
parent 1e8574aa74
commit 58d61606cc
4 changed files with 77 additions and 136 deletions

View file

@ -139,3 +139,5 @@ panic = "abort"
[profile.dev]
panic = "abort"
[patch.crates-io]
winit = { path = "../winit" }

View file

@ -10,7 +10,6 @@
use copypasta::ClipboardProvider;
use corelib::items::PointerEventButton;
use corelib::lengths::LogicalPoint;
use corelib::SharedString;
use i_slint_core as corelib;
use corelib::api::EventLoopError;
@ -247,9 +246,9 @@ impl std::fmt::Debug for CustomEvent {
mod key_codes {
macro_rules! winit_key_to_char_fn {
($($char:literal # $name:ident # $($_qt:ident)|* # $($winit:ident)|* # $($_xkb:ident)|*;)*) => {
pub fn winit_key_to_char(virtual_keycode: winit::event::VirtualKeyCode) -> Option<char> {
pub fn winit_key_to_char(virtual_keycode: winit::keyboard::KeyCode) -> Option<char> {
let char = match(virtual_keycode) {
$($(winit::event::VirtualKeyCode::$winit => $char,)*)*
$($(winit::keyboard::KeyCode::$winit => $char,)*)*
_ => return None,
};
Some(char)
@ -273,33 +272,33 @@ fn process_window_event(
WindowEvent::CloseRequested => {
window.window().dispatch_event(corelib::platform::WindowEvent::CloseRequested);
}
WindowEvent::ReceivedCharacter(ch) => {
// On Windows, X11 and Wayland sequences like Ctrl+C will send a ReceivedCharacter after the pressed keyboard input event,
// with a control character. We choose not to forward those but try to use the current key code instead.
//
// We do not want to change the text to the value of the key press when that was a
// control key itself: We already sent that event when handling the KeyboardInput.
let text: SharedString = if ch.is_control() {
if let Some(ch) = window
.currently_pressed_key_code()
.take()
.and_then(winit_key_code_to_string)
.filter(|ch| !ch.is_control())
{
ch
} else {
return Ok(());
}
} else {
ch
}
.into();
window
.window()
.dispatch_event(corelib::platform::WindowEvent::KeyPressed { text: text.clone() });
window.window().dispatch_event(corelib::platform::WindowEvent::KeyReleased { text });
}
// WindowEvent::ReceivedCharacter(ch) => {
// // On Windows, X11 and Wayland sequences like Ctrl+C will send a ReceivedCharacter after the pressed keyboard input event,
// // with a control character. We choose not to forward those but try to use the current key code instead.
// //
// // We do not want to change the text to the value of the key press when that was a
// // control key itself: We already sent that event when handling the KeyboardInput.
// let text: SharedString = if ch.is_control() {
// if let Some(ch) = window
// .currently_pressed_key_code()
// .take()
// .and_then(winit_key_code_to_string)
// .filter(|ch| !ch.is_control())
// {
// ch
// } else {
// return Ok(());
// }
// } else {
// ch
// }
// .into();
//
// window
// .window()
// .dispatch_event(corelib::platform::WindowEvent::KeyPressed { text: text.clone() });
// window.window().dispatch_event(corelib::platform::WindowEvent::KeyReleased { text });
// }
WindowEvent::Focused(have_focus) => {
let have_focus = have_focus || window.input_method_focused();
// We don't render popups as separate windows yet, so treat
@ -310,26 +309,26 @@ fn process_window_event(
);
}
}
WindowEvent::KeyboardInput { ref input, .. } => {
WindowEvent::KeyboardInput { ref event, .. } => {
// For now: Match Qt's behavior of mapping command to control and control to meta (LWin/RWin).
let key_code = input.virtual_keycode.map(|key_code| match key_code {
let key_code = match event.physical_key {
#[cfg(target_os = "macos")]
winit::event::VirtualKeyCode::LControl => winit::event::VirtualKeyCode::LWin,
winit::keyboard::KeyCode::ControlLeft => winit::keyboard::KeyCode::WinLeft,
#[cfg(target_os = "macos")]
winit::event::VirtualKeyCode::RControl => winit::event::VirtualKeyCode::RWin,
winit::keyboard::KeyCode::ControlRight => winit::keyboard::KeyCode::WinRight,
#[cfg(target_os = "macos")]
winit::event::VirtualKeyCode::LWin => winit::event::VirtualKeyCode::LControl,
winit::keyboard::KeyCode::WinLeft => winit::keyboard::KeyCode::ControlLeft,
#[cfg(target_os = "macos")]
winit::event::VirtualKeyCode::RWin => winit::event::VirtualKeyCode::RControl,
winit::keyboard::KeyCode::WinRight => winit::keyboard::KeyCode::ControlRight,
code => code,
});
window.currently_pressed_key_code().set(match input.state {
winit::event::ElementState::Pressed => key_code,
};
window.currently_pressed_key_code().set(match event.state {
winit::event::ElementState::Pressed => Some(key_code),
_ => None,
});
if let Some(text) = key_code.and_then(key_codes::winit_key_to_char).map(|ch| ch.into())
{
window.window().dispatch_event(match input.state {
if let Some(text) = &event.text {
let text = text.as_str().into();
window.window().dispatch_event(match event.state {
winit::event::ElementState::Pressed => {
corelib::platform::WindowEvent::KeyPressed { text }
}
@ -389,6 +388,8 @@ fn process_window_event(
winit::event::MouseButton::Right => PointerEventButton::Right,
winit::event::MouseButton::Middle => PointerEventButton::Middle,
winit::event::MouseButton::Other(_) => PointerEventButton::Other,
winit::event::MouseButton::Back => PointerEventButton::Other,
winit::event::MouseButton::Forward => PointerEventButton::Other,
};
let ev = match state {
winit::event::ElementState::Pressed => {
@ -699,68 +700,6 @@ pub fn run() -> Result<(), corelib::platform::PlatformError> {
}
}
// This function is called when we receive a control character via WindowEvent::ReceivedCharacter and
// instead want to use the last virtual key code. That happens when for example pressing Ctrl+some_key
// on Windows/X11/Wayland. This function may be missing mappings, it's trying to cover what we may be
// getting when we're getting control character sequences.
fn winit_key_code_to_string(virtual_keycode: winit::event::VirtualKeyCode) -> Option<char> {
use winit::event::VirtualKeyCode;
Some(match virtual_keycode {
VirtualKeyCode::Key1 => '1',
VirtualKeyCode::Key2 => '2',
VirtualKeyCode::Key3 => '3',
VirtualKeyCode::Key4 => '4',
VirtualKeyCode::Key5 => '5',
VirtualKeyCode::Key6 => '6',
VirtualKeyCode::Key7 => '7',
VirtualKeyCode::Key8 => '8',
VirtualKeyCode::Key9 => '9',
VirtualKeyCode::Key0 => '0',
VirtualKeyCode::A => 'a',
VirtualKeyCode::B => 'b',
VirtualKeyCode::C => 'c',
VirtualKeyCode::D => 'd',
VirtualKeyCode::E => 'e',
VirtualKeyCode::F => 'f',
VirtualKeyCode::G => 'g',
VirtualKeyCode::H => 'h',
VirtualKeyCode::I => 'i',
VirtualKeyCode::J => 'j',
VirtualKeyCode::K => 'k',
VirtualKeyCode::L => 'l',
VirtualKeyCode::M => 'm',
VirtualKeyCode::N => 'n',
VirtualKeyCode::O => 'o',
VirtualKeyCode::P => 'p',
VirtualKeyCode::Q => 'q',
VirtualKeyCode::R => 'r',
VirtualKeyCode::S => 's',
VirtualKeyCode::T => 't',
VirtualKeyCode::U => 'u',
VirtualKeyCode::V => 'v',
VirtualKeyCode::W => 'w',
VirtualKeyCode::X => 'x',
VirtualKeyCode::Y => 'y',
VirtualKeyCode::Z => 'z',
VirtualKeyCode::Space => ' ',
VirtualKeyCode::Caret => '^',
VirtualKeyCode::Apostrophe => '\'',
VirtualKeyCode::Asterisk => '*',
VirtualKeyCode::Backslash => '\\',
VirtualKeyCode::Colon => ':',
VirtualKeyCode::Comma => ',',
VirtualKeyCode::Equals => '=',
VirtualKeyCode::Grave => '`',
VirtualKeyCode::Minus => '-',
VirtualKeyCode::Period => '.',
VirtualKeyCode::Plus => '+',
VirtualKeyCode::Semicolon => ';',
VirtualKeyCode::Slash => '/',
VirtualKeyCode::Tab => '\t',
_ => return None,
})
}
fn create_clipboard<T>(_event_loop: &winit::event_loop::EventLoopWindowTarget<T>) -> ClipboardPair {
// Provide a truly silent no-op clipboard context, as copypasta's NoopClipboard spams stdout with
// println.

View file

@ -115,7 +115,7 @@ pub struct WinitWindowAdapter {
window: OnceCell<corelib::api::Window>,
#[cfg(target_arch = "wasm32")]
self_weak: Weak<Self>,
currently_pressed_key_code: std::cell::Cell<Option<winit::event::VirtualKeyCode>>,
currently_pressed_key_code: std::cell::Cell<Option<winit::keyboard::KeyCode>>,
pending_redraw: Cell<bool>,
dark_color_scheme: OnceCell<Pin<Box<Property<bool>>>>,
constraints: Cell<corelib::window::LayoutConstraints>,
@ -242,7 +242,7 @@ impl WinitWindowAdapter {
self.pending_redraw.take()
}
pub fn currently_pressed_key_code(&self) -> &Cell<Option<winit::event::VirtualKeyCode>> {
pub fn currently_pressed_key_code(&self) -> &Cell<Option<winit::keyboard::KeyCode>> {
&self.currently_pressed_key_code
}
@ -583,7 +583,7 @@ impl WindowAdapterInternal for WinitWindowAdapter {
MouseCursor::Default => winit::window::CursorIcon::Default,
MouseCursor::None => winit::window::CursorIcon::Default,
MouseCursor::Help => winit::window::CursorIcon::Help,
MouseCursor::Pointer => winit::window::CursorIcon::Hand,
MouseCursor::Pointer => winit::window::CursorIcon::Pointer,
MouseCursor::Progress => winit::window::CursorIcon::Progress,
MouseCursor::Wait => winit::window::CursorIcon::Wait,
MouseCursor::Crosshair => winit::window::CursorIcon::Crosshair,

View file

@ -25,32 +25,32 @@
macro_rules! for_each_special_keys {
($macro:ident) => {
$macro![
'\u{0008}' # Backspace # Qt_Key_Key_Backspace # Back # BackSpace ;
'\u{0008}' # Backspace # Qt_Key_Key_Backspace # Backspace # BackSpace ;
'\u{0009}' # Tab # Qt_Key_Key_Tab # Tab # Tab ;
'\u{000a}' # Return # Qt_Key_Key_Enter|Qt_Key_Key_Return # NumpadEnter|Return # Return;
'\u{000a}' # Return # Qt_Key_Key_Enter|Qt_Key_Key_Return # NumpadEnter|Enter # Return;
'\u{001b}' # Escape # Qt_Key_Key_Escape # Escape # Escape ;
'\u{0019}' # Backtab # Qt_Key_Key_Backtab # # BackTab ;
'\u{007f}' # Delete # Qt_Key_Key_Delete # Delete # Delete ;
// The modifier key codes comes from https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode.
'\u{0010}' # Shift # Qt_Key_Key_Shift # LShift # Shift_L ;
'\u{0011}' # Control # Qt_Key_Key_Control # LControl # Control_L ;
'\u{0012}' # Alt # Qt_Key_Key_Alt # LAlt # Alt_L ;
'\u{0013}' # AltGr # Qt_Key_Key_AltGr # RAlt # Mode_switch;
'\u{0010}' # Shift # Qt_Key_Key_Shift # ShiftLeft # Shift_L ;
'\u{0011}' # Control # Qt_Key_Key_Control # ControlLeft # Control_L ;
'\u{0012}' # Alt # Qt_Key_Key_Alt # AltLeft # Alt_L ;
'\u{0013}' # AltGr # Qt_Key_Key_AltGr # AltRight # Mode_switch;
'\u{0014}' # CapsLock # Qt_Key_Key_CapsLock # # Caps_Lock ;
'\u{0015}' # ShiftR # # RShift # Shift_R ;
'\u{0016}' # ControlR # # RControl # Control_R ;
'\u{0015}' # ShiftR # # ShiftRight # Shift_R ;
'\u{0016}' # ControlR # # ControlRight # Control_R ;
// Use custom codes instead of DOM_VK_META for meta, because the Mozilla defined code is a regular character (E0; LATIN SMALL LETTER A WITH GRAVE)
// which makes those keys appear as text.
'\u{0017}' # Meta # Qt_Key_Key_Meta # LWin # Meta_L ;
'\u{0018}' # MetaR # # RWin # Meta_R ;
'\u{0017}' # Meta # Qt_Key_Key_Meta # SuperLeft # Meta_L ;
'\u{0018}' # MetaR # # SuperRight # Meta_R ;
'\u{F700}' # UpArrow # Qt_Key_Key_Up # Up # Up ;
'\u{F701}' # DownArrow # Qt_Key_Key_Down # Down # Down ;
'\u{F702}' # LeftArrow # Qt_Key_Key_Left # Left # Left ;
'\u{F703}' # RightArrow # Qt_Key_Key_Right # Right # Right ;
'\u{F700}' # UpArrow # Qt_Key_Key_Up # ArrowUp # Up ;
'\u{F701}' # DownArrow # Qt_Key_Key_Down # ArrowDown # Down ;
'\u{F702}' # LeftArrow # Qt_Key_Key_Left # ArrowLeft # Left ;
'\u{F703}' # RightArrow # Qt_Key_Key_Right # ArrowRight # Right ;
'\u{F704}' # F1 # Qt_Key_Key_F1 # F1 # F1 ;
'\u{F705}' # F2 # Qt_Key_Key_F2 # F2 # F2 ;
'\u{F706}' # F3 # Qt_Key_Key_F3 # F3 # F3 ;
@ -75,17 +75,17 @@ macro_rules! for_each_special_keys {
'\u{F719}' # F22 # Qt_Key_Key_F22 # F22 # F22 ;
'\u{F71A}' # F23 # Qt_Key_Key_F23 # F23 # F23 ;
'\u{F71B}' # F24 # Qt_Key_Key_F24 # F24 # F24 ;
//'\u{F71C}'# F25 # Qt_Key_Key_F25 # # F25 ;
//'\u{F71D}'# F26 # Qt_Key_Key_F26 # # F26 ;
//'\u{F71E}'# F27 # Qt_Key_Key_F27 # # F27 ;
//'\u{F71F}'# F28 # Qt_Key_Key_F28 # # F28 ;
//'\u{F720}'# F29 # Qt_Key_Key_F29 # # F29 ;
//'\u{F721}'# F30 # Qt_Key_Key_F30 # # F30 ;
//'\u{F722}'# F31 # Qt_Key_Key_F31 # # F31 ;
//'\u{F723}'# F32 # Qt_Key_Key_F32 # # F32 ;
//'\u{F724}'# F33 # Qt_Key_Key_F33 # # F33 ;
//'\u{F725}'# F34 # Qt_Key_Key_F34 # # F34 ;
//'\u{F726}'# F35 # Qt_Key_Key_F35 # # F35 ;
//'\u{F71C}'# F25 # Qt_Key_Key_F25 # F25 # F25 ;
//'\u{F71D}'# F26 # Qt_Key_Key_F26 # F26 # F26 ;
//'\u{F71E}'# F27 # Qt_Key_Key_F27 # F27 # F27 ;
//'\u{F71F}'# F28 # Qt_Key_Key_F28 # F28 # F28 ;
//'\u{F720}'# F29 # Qt_Key_Key_F29 # F29 # F29 ;
//'\u{F721}'# F30 # Qt_Key_Key_F30 # F30 # F30 ;
//'\u{F722}'# F31 # Qt_Key_Key_F31 # F31 # F31 ;
//'\u{F723}'# F32 # Qt_Key_Key_F32 # F32 # F32 ;
//'\u{F724}'# F33 # Qt_Key_Key_F33 # F33 # F33 ;
//'\u{F725}'# F34 # Qt_Key_Key_F34 # F34 # F34 ;
//'\u{F726}'# F35 # Qt_Key_Key_F35 # F35 # F35 ;
'\u{F727}' # Insert # Qt_Key_Key_Insert # Insert # Insert ;
//'\u{F728}' # Delete ; // already as a control code
'\u{F729}' # Home # Qt_Key_Key_Home # Home # Home ;
@ -94,13 +94,13 @@ macro_rules! for_each_special_keys {
'\u{F72C}' # PageUp # Qt_Key_Key_PageUp # PageUp # Page_Up ;
'\u{F72D}' # PageDown # Qt_Key_Key_PageDown # PageDown # Page_Down ;
//'\u{F72E}' # PrintScreen # # Snapshot ;
'\u{F72F}' # ScrollLock # Qt_Key_Key_ScrollLock # Scroll # Scroll_Lock;
'\u{F72F}' # ScrollLock # Qt_Key_Key_ScrollLock # ScrollLock # Scroll_Lock;
'\u{F730}' # Pause # Qt_Key_Key_Pause # Pause # Pause ;
'\u{F731}' # SysReq # Qt_Key_Key_SysReq # Sysrq # Sys_Req ;
'\u{F731}' # SysReq # Qt_Key_Key_SysReq # PrintScreen # Sys_Req ;
//'\u{F732}' # Break # # ;
//'\u{F733}' # Reset # # ;
'\u{F734}' # Stop # Qt_Key_Key_Stop # Stop # XF86_Stop ;
'\u{F735}' # Menu # Qt_Key_Key_Menu # # Menu ;
'\u{F734}' # Stop # Qt_Key_Key_Stop # # XF86_Stop ;
'\u{F735}' # Menu # Qt_Key_Key_Menu # ContextMenu # Menu ;
//'\u{F736}' # User # # ;
//'\u{F737}' # System # # ;
//'\u{F738}' # Print # Qt_Key_Key_Print # ;