mirror of https://github.com/linebender/xilem
Isolate winit imports to `app` module (#908)
This is the first step towards #907. This doesn't split the crate yet, but adds a translation layer between winit and Masonry to facilitate that split.
This commit is contained in:
parent
125dab7949
commit
25a446029f
|
@ -496,6 +496,9 @@ name = "bitflags"
|
|||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block"
|
||||
|
@ -1758,6 +1761,17 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keyboard-types"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"serde",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "khronos-egl"
|
||||
version = "6.0.0"
|
||||
|
@ -1894,6 +1908,7 @@ dependencies = [
|
|||
"futures-intrusive",
|
||||
"image",
|
||||
"insta",
|
||||
"keyboard-types",
|
||||
"nv-flip",
|
||||
"once_cell",
|
||||
"parley",
|
||||
|
|
|
@ -58,6 +58,7 @@ nv-flip.workspace = true
|
|||
tracing-tracy = { version = "0.11.3", optional = true }
|
||||
wgpu-profiler = { optional = true, version = "0.19.0", default-features = false }
|
||||
anymap3 = "1.0.1"
|
||||
keyboard-types = "0.7.0"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
web-time.workspace = true
|
||||
|
|
|
@ -0,0 +1,633 @@
|
|||
// Copyright 2025 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Most of this file is copy-pasted directly from
|
||||
// https://github.com/DioxusLabs/blitz/blob/main/packages/blitz-shell/src/convert_events.rs
|
||||
// Should be removed once https://github.com/rust-windowing/winit/pull/4026 is merged.
|
||||
|
||||
use keyboard_types::KeyState;
|
||||
use keyboard_types::{Code, Key, KeyboardEvent, Location, Modifiers};
|
||||
use winit::event::ElementState;
|
||||
use winit::event::Force as WinitForce;
|
||||
use winit::event::Ime as WinitIme;
|
||||
use winit::event::KeyEvent as WinitKeyEvent;
|
||||
use winit::event::MouseButton as WinitMouseButton;
|
||||
use winit::keyboard::Key as WinitKey;
|
||||
use winit::keyboard::KeyCode as WinitKeyCode;
|
||||
use winit::keyboard::KeyLocation as WinitKeyLocation;
|
||||
use winit::keyboard::ModifiersState as WinitModifiers;
|
||||
use winit::keyboard::NamedKey as WinitNamedKey;
|
||||
use winit::keyboard::PhysicalKey as WinitPhysicalKey;
|
||||
use winit::window::ResizeDirection as WinitResizeDirection;
|
||||
|
||||
use crate::core::{Force, Ime, PointerButton, ResizeDirection};
|
||||
|
||||
pub(crate) fn winit_mouse_button_to_masonry(button: WinitMouseButton) -> PointerButton {
|
||||
match button {
|
||||
WinitMouseButton::Left => PointerButton::Primary,
|
||||
WinitMouseButton::Right => PointerButton::Secondary,
|
||||
WinitMouseButton::Middle => PointerButton::Auxiliary,
|
||||
WinitMouseButton::Back => PointerButton::X1,
|
||||
WinitMouseButton::Forward => PointerButton::X2,
|
||||
WinitMouseButton::Other(_) => PointerButton::Other,
|
||||
}
|
||||
}
|
||||
pub(crate) fn masonry_resize_direction_to_winit(dir: ResizeDirection) -> WinitResizeDirection {
|
||||
match dir {
|
||||
ResizeDirection::East => WinitResizeDirection::East,
|
||||
ResizeDirection::North => WinitResizeDirection::North,
|
||||
ResizeDirection::NorthEast => WinitResizeDirection::NorthEast,
|
||||
ResizeDirection::NorthWest => WinitResizeDirection::NorthWest,
|
||||
ResizeDirection::South => WinitResizeDirection::South,
|
||||
ResizeDirection::SouthEast => WinitResizeDirection::SouthEast,
|
||||
ResizeDirection::SouthWest => WinitResizeDirection::SouthWest,
|
||||
ResizeDirection::West => WinitResizeDirection::West,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn winit_force_to_masonry(force: WinitForce) -> Force {
|
||||
match force {
|
||||
WinitForce::Calibrated {
|
||||
force,
|
||||
max_possible_force,
|
||||
altitude_angle,
|
||||
} => Force::Calibrated {
|
||||
force,
|
||||
max_possible_force,
|
||||
altitude_angle,
|
||||
},
|
||||
WinitForce::Normalized(value) => Force::Normalized(value),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn winit_ime_to_masonry(event: WinitIme) -> Ime {
|
||||
match event {
|
||||
WinitIme::Enabled => Ime::Enabled,
|
||||
WinitIme::Disabled => Ime::Disabled,
|
||||
WinitIme::Preedit(text, cursor) => Ime::Preedit(text, cursor),
|
||||
WinitIme::Commit(text) => Ime::Commit(text),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn winit_key_event_to_kbt(event: &WinitKeyEvent, mods: WinitModifiers) -> KeyboardEvent {
|
||||
KeyboardEvent {
|
||||
key: winit_key_to_kbt_key(&event.logical_key),
|
||||
code: winit_physical_key_to_kbt_code(event.physical_key),
|
||||
modifiers: winit_modifiers_to_kbt_modifiers(mods),
|
||||
location: winit_key_location_to_kbt_location(event.location),
|
||||
is_composing: false,
|
||||
state: match event.state {
|
||||
ElementState::Pressed => KeyState::Down,
|
||||
ElementState::Released => KeyState::Up,
|
||||
},
|
||||
repeat: event.repeat,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn winit_modifiers_to_kbt_modifiers(winit_modifiers: WinitModifiers) -> Modifiers {
|
||||
let mut modifiers = Modifiers::default();
|
||||
if winit_modifiers.control_key() {
|
||||
modifiers.insert(Modifiers::CONTROL);
|
||||
}
|
||||
if winit_modifiers.alt_key() {
|
||||
modifiers.insert(Modifiers::ALT);
|
||||
}
|
||||
if winit_modifiers.shift_key() {
|
||||
modifiers.insert(Modifiers::SHIFT);
|
||||
}
|
||||
if winit_modifiers.super_key() {
|
||||
modifiers.insert(Modifiers::SUPER);
|
||||
}
|
||||
modifiers
|
||||
}
|
||||
|
||||
pub(crate) fn winit_key_location_to_kbt_location(location: WinitKeyLocation) -> Location {
|
||||
match location {
|
||||
WinitKeyLocation::Standard => Location::Standard,
|
||||
WinitKeyLocation::Left => Location::Left,
|
||||
WinitKeyLocation::Right => Location::Right,
|
||||
WinitKeyLocation::Numpad => Location::Numpad,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn winit_physical_key_to_kbt_code(physical_key: WinitPhysicalKey) -> Code {
|
||||
match physical_key {
|
||||
WinitPhysicalKey::Unidentified(_) => Code::Unidentified,
|
||||
WinitPhysicalKey::Code(key_code) => match key_code {
|
||||
// Variants that don't match 1:1
|
||||
WinitKeyCode::Meta => Code::Super,
|
||||
WinitKeyCode::SuperLeft => Code::Super,
|
||||
WinitKeyCode::SuperRight => Code::Super,
|
||||
|
||||
WinitKeyCode::Backquote => Code::Backquote,
|
||||
WinitKeyCode::Backslash => Code::Backslash,
|
||||
WinitKeyCode::BracketLeft => Code::BracketLeft,
|
||||
WinitKeyCode::BracketRight => Code::BracketRight,
|
||||
WinitKeyCode::Comma => Code::Comma,
|
||||
WinitKeyCode::Digit0 => Code::Digit0,
|
||||
WinitKeyCode::Digit1 => Code::Digit1,
|
||||
WinitKeyCode::Digit2 => Code::Digit2,
|
||||
WinitKeyCode::Digit3 => Code::Digit3,
|
||||
WinitKeyCode::Digit4 => Code::Digit4,
|
||||
WinitKeyCode::Digit5 => Code::Digit5,
|
||||
WinitKeyCode::Digit6 => Code::Digit6,
|
||||
WinitKeyCode::Digit7 => Code::Digit7,
|
||||
WinitKeyCode::Digit8 => Code::Digit8,
|
||||
WinitKeyCode::Digit9 => Code::Digit9,
|
||||
WinitKeyCode::Equal => Code::Equal,
|
||||
WinitKeyCode::IntlBackslash => Code::IntlBackslash,
|
||||
WinitKeyCode::IntlRo => Code::IntlRo,
|
||||
WinitKeyCode::IntlYen => Code::IntlYen,
|
||||
WinitKeyCode::KeyA => Code::KeyA,
|
||||
WinitKeyCode::KeyB => Code::KeyB,
|
||||
WinitKeyCode::KeyC => Code::KeyC,
|
||||
WinitKeyCode::KeyD => Code::KeyD,
|
||||
WinitKeyCode::KeyE => Code::KeyE,
|
||||
WinitKeyCode::KeyF => Code::KeyF,
|
||||
WinitKeyCode::KeyG => Code::KeyG,
|
||||
WinitKeyCode::KeyH => Code::KeyH,
|
||||
WinitKeyCode::KeyI => Code::KeyI,
|
||||
WinitKeyCode::KeyJ => Code::KeyJ,
|
||||
WinitKeyCode::KeyK => Code::KeyK,
|
||||
WinitKeyCode::KeyL => Code::KeyL,
|
||||
WinitKeyCode::KeyM => Code::KeyM,
|
||||
WinitKeyCode::KeyN => Code::KeyN,
|
||||
WinitKeyCode::KeyO => Code::KeyO,
|
||||
WinitKeyCode::KeyP => Code::KeyP,
|
||||
WinitKeyCode::KeyQ => Code::KeyQ,
|
||||
WinitKeyCode::KeyR => Code::KeyR,
|
||||
WinitKeyCode::KeyS => Code::KeyS,
|
||||
WinitKeyCode::KeyT => Code::KeyT,
|
||||
WinitKeyCode::KeyU => Code::KeyU,
|
||||
WinitKeyCode::KeyV => Code::KeyV,
|
||||
WinitKeyCode::KeyW => Code::KeyW,
|
||||
WinitKeyCode::KeyX => Code::KeyX,
|
||||
WinitKeyCode::KeyY => Code::KeyY,
|
||||
WinitKeyCode::KeyZ => Code::KeyZ,
|
||||
WinitKeyCode::Minus => Code::Minus,
|
||||
WinitKeyCode::Period => Code::Period,
|
||||
WinitKeyCode::Quote => Code::Quote,
|
||||
WinitKeyCode::Semicolon => Code::Semicolon,
|
||||
WinitKeyCode::Slash => Code::Slash,
|
||||
WinitKeyCode::AltLeft => Code::AltLeft,
|
||||
WinitKeyCode::AltRight => Code::AltRight,
|
||||
WinitKeyCode::Backspace => Code::Backspace,
|
||||
WinitKeyCode::CapsLock => Code::CapsLock,
|
||||
WinitKeyCode::ContextMenu => Code::ContextMenu,
|
||||
WinitKeyCode::ControlLeft => Code::ControlLeft,
|
||||
WinitKeyCode::ControlRight => Code::ControlRight,
|
||||
WinitKeyCode::Enter => Code::Enter,
|
||||
WinitKeyCode::ShiftLeft => Code::ShiftLeft,
|
||||
WinitKeyCode::ShiftRight => Code::ShiftRight,
|
||||
WinitKeyCode::Space => Code::Space,
|
||||
WinitKeyCode::Tab => Code::Tab,
|
||||
WinitKeyCode::Convert => Code::Convert,
|
||||
WinitKeyCode::KanaMode => Code::KanaMode,
|
||||
WinitKeyCode::Lang1 => Code::Lang1,
|
||||
WinitKeyCode::Lang2 => Code::Lang2,
|
||||
WinitKeyCode::Lang3 => Code::Lang3,
|
||||
WinitKeyCode::Lang4 => Code::Lang4,
|
||||
WinitKeyCode::Lang5 => Code::Lang5,
|
||||
WinitKeyCode::NonConvert => Code::NonConvert,
|
||||
WinitKeyCode::Delete => Code::Delete,
|
||||
WinitKeyCode::End => Code::End,
|
||||
WinitKeyCode::Help => Code::Help,
|
||||
WinitKeyCode::Home => Code::Home,
|
||||
WinitKeyCode::Insert => Code::Insert,
|
||||
WinitKeyCode::PageDown => Code::PageDown,
|
||||
WinitKeyCode::PageUp => Code::PageUp,
|
||||
WinitKeyCode::ArrowDown => Code::ArrowDown,
|
||||
WinitKeyCode::ArrowLeft => Code::ArrowLeft,
|
||||
WinitKeyCode::ArrowRight => Code::ArrowRight,
|
||||
WinitKeyCode::ArrowUp => Code::ArrowUp,
|
||||
WinitKeyCode::NumLock => Code::NumLock,
|
||||
WinitKeyCode::Numpad0 => Code::Numpad0,
|
||||
WinitKeyCode::Numpad1 => Code::Numpad1,
|
||||
WinitKeyCode::Numpad2 => Code::Numpad2,
|
||||
WinitKeyCode::Numpad3 => Code::Numpad3,
|
||||
WinitKeyCode::Numpad4 => Code::Numpad4,
|
||||
WinitKeyCode::Numpad5 => Code::Numpad5,
|
||||
WinitKeyCode::Numpad6 => Code::Numpad6,
|
||||
WinitKeyCode::Numpad7 => Code::Numpad7,
|
||||
WinitKeyCode::Numpad8 => Code::Numpad8,
|
||||
WinitKeyCode::Numpad9 => Code::Numpad9,
|
||||
WinitKeyCode::NumpadAdd => Code::NumpadAdd,
|
||||
WinitKeyCode::NumpadBackspace => Code::NumpadBackspace,
|
||||
WinitKeyCode::NumpadClear => Code::NumpadClear,
|
||||
WinitKeyCode::NumpadClearEntry => Code::NumpadClearEntry,
|
||||
WinitKeyCode::NumpadComma => Code::NumpadComma,
|
||||
WinitKeyCode::NumpadDecimal => Code::NumpadDecimal,
|
||||
WinitKeyCode::NumpadDivide => Code::NumpadDivide,
|
||||
WinitKeyCode::NumpadEnter => Code::NumpadEnter,
|
||||
WinitKeyCode::NumpadEqual => Code::NumpadEqual,
|
||||
WinitKeyCode::NumpadHash => Code::NumpadHash,
|
||||
WinitKeyCode::NumpadMemoryAdd => Code::NumpadMemoryAdd,
|
||||
WinitKeyCode::NumpadMemoryClear => Code::NumpadMemoryClear,
|
||||
WinitKeyCode::NumpadMemoryRecall => Code::NumpadMemoryRecall,
|
||||
WinitKeyCode::NumpadMemoryStore => Code::NumpadMemoryStore,
|
||||
WinitKeyCode::NumpadMemorySubtract => Code::NumpadMemorySubtract,
|
||||
WinitKeyCode::NumpadMultiply => Code::NumpadMultiply,
|
||||
WinitKeyCode::NumpadParenLeft => Code::NumpadParenLeft,
|
||||
WinitKeyCode::NumpadParenRight => Code::NumpadParenRight,
|
||||
WinitKeyCode::NumpadStar => Code::NumpadStar,
|
||||
WinitKeyCode::NumpadSubtract => Code::NumpadSubtract,
|
||||
WinitKeyCode::Escape => Code::Escape,
|
||||
WinitKeyCode::Fn => Code::Fn,
|
||||
WinitKeyCode::FnLock => Code::FnLock,
|
||||
WinitKeyCode::PrintScreen => Code::PrintScreen,
|
||||
WinitKeyCode::ScrollLock => Code::ScrollLock,
|
||||
WinitKeyCode::Pause => Code::Pause,
|
||||
WinitKeyCode::BrowserBack => Code::BrowserBack,
|
||||
WinitKeyCode::BrowserFavorites => Code::BrowserFavorites,
|
||||
WinitKeyCode::BrowserForward => Code::BrowserForward,
|
||||
WinitKeyCode::BrowserHome => Code::BrowserHome,
|
||||
WinitKeyCode::BrowserRefresh => Code::BrowserRefresh,
|
||||
WinitKeyCode::BrowserSearch => Code::BrowserSearch,
|
||||
WinitKeyCode::BrowserStop => Code::BrowserStop,
|
||||
WinitKeyCode::Eject => Code::Eject,
|
||||
WinitKeyCode::LaunchApp1 => Code::LaunchApp1,
|
||||
WinitKeyCode::LaunchApp2 => Code::LaunchApp2,
|
||||
WinitKeyCode::LaunchMail => Code::LaunchMail,
|
||||
WinitKeyCode::MediaPlayPause => Code::MediaPlayPause,
|
||||
WinitKeyCode::MediaSelect => Code::MediaSelect,
|
||||
WinitKeyCode::MediaStop => Code::MediaStop,
|
||||
WinitKeyCode::MediaTrackNext => Code::MediaTrackNext,
|
||||
WinitKeyCode::MediaTrackPrevious => Code::MediaTrackPrevious,
|
||||
WinitKeyCode::Power => Code::Power,
|
||||
WinitKeyCode::Sleep => Code::Sleep,
|
||||
WinitKeyCode::AudioVolumeDown => Code::AudioVolumeDown,
|
||||
WinitKeyCode::AudioVolumeMute => Code::AudioVolumeMute,
|
||||
WinitKeyCode::AudioVolumeUp => Code::AudioVolumeUp,
|
||||
WinitKeyCode::WakeUp => Code::WakeUp,
|
||||
WinitKeyCode::Hyper => Code::Hyper,
|
||||
WinitKeyCode::Turbo => Code::Turbo,
|
||||
WinitKeyCode::Abort => Code::Abort,
|
||||
WinitKeyCode::Resume => Code::Resume,
|
||||
WinitKeyCode::Suspend => Code::Suspend,
|
||||
WinitKeyCode::Again => Code::Again,
|
||||
WinitKeyCode::Copy => Code::Copy,
|
||||
WinitKeyCode::Cut => Code::Cut,
|
||||
WinitKeyCode::Find => Code::Find,
|
||||
WinitKeyCode::Open => Code::Open,
|
||||
WinitKeyCode::Paste => Code::Paste,
|
||||
WinitKeyCode::Props => Code::Props,
|
||||
WinitKeyCode::Select => Code::Select,
|
||||
WinitKeyCode::Undo => Code::Undo,
|
||||
WinitKeyCode::Hiragana => Code::Hiragana,
|
||||
WinitKeyCode::Katakana => Code::Katakana,
|
||||
WinitKeyCode::F1 => Code::F1,
|
||||
WinitKeyCode::F2 => Code::F2,
|
||||
WinitKeyCode::F3 => Code::F3,
|
||||
WinitKeyCode::F4 => Code::F4,
|
||||
WinitKeyCode::F5 => Code::F5,
|
||||
WinitKeyCode::F6 => Code::F6,
|
||||
WinitKeyCode::F7 => Code::F7,
|
||||
WinitKeyCode::F8 => Code::F8,
|
||||
WinitKeyCode::F9 => Code::F9,
|
||||
WinitKeyCode::F10 => Code::F10,
|
||||
WinitKeyCode::F11 => Code::F11,
|
||||
WinitKeyCode::F12 => Code::F12,
|
||||
WinitKeyCode::F13 => Code::F13,
|
||||
WinitKeyCode::F14 => Code::F14,
|
||||
WinitKeyCode::F15 => Code::F15,
|
||||
WinitKeyCode::F16 => Code::F16,
|
||||
WinitKeyCode::F17 => Code::F17,
|
||||
WinitKeyCode::F18 => Code::F18,
|
||||
WinitKeyCode::F19 => Code::F19,
|
||||
WinitKeyCode::F20 => Code::F20,
|
||||
WinitKeyCode::F21 => Code::F21,
|
||||
WinitKeyCode::F22 => Code::F22,
|
||||
WinitKeyCode::F23 => Code::F23,
|
||||
WinitKeyCode::F24 => Code::F24,
|
||||
WinitKeyCode::F25 => Code::F25,
|
||||
WinitKeyCode::F26 => Code::F26,
|
||||
WinitKeyCode::F27 => Code::F27,
|
||||
WinitKeyCode::F28 => Code::F28,
|
||||
WinitKeyCode::F29 => Code::F29,
|
||||
WinitKeyCode::F30 => Code::F30,
|
||||
WinitKeyCode::F31 => Code::F31,
|
||||
WinitKeyCode::F32 => Code::F32,
|
||||
WinitKeyCode::F33 => Code::F33,
|
||||
WinitKeyCode::F34 => Code::F34,
|
||||
WinitKeyCode::F35 => Code::F35,
|
||||
_ => todo!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn winit_key_to_kbt_key(winit_key: &WinitKey) -> Key {
|
||||
match winit_key {
|
||||
WinitKey::Character(c) => Key::Character(c.to_string()),
|
||||
WinitKey::Unidentified(_) => Key::Unidentified,
|
||||
WinitKey::Dead(_) => Key::Dead,
|
||||
WinitKey::Named(named_key) => match named_key {
|
||||
WinitNamedKey::Alt => Key::Alt,
|
||||
WinitNamedKey::AltGraph => Key::AltGraph,
|
||||
WinitNamedKey::CapsLock => Key::CapsLock,
|
||||
WinitNamedKey::Control => Key::Control,
|
||||
WinitNamedKey::Fn => Key::Fn,
|
||||
WinitNamedKey::FnLock => Key::FnLock,
|
||||
WinitNamedKey::NumLock => Key::NumLock,
|
||||
WinitNamedKey::ScrollLock => Key::ScrollLock,
|
||||
WinitNamedKey::Shift => Key::Shift,
|
||||
WinitNamedKey::Symbol => Key::Symbol,
|
||||
WinitNamedKey::SymbolLock => Key::SymbolLock,
|
||||
WinitNamedKey::Meta => Key::Meta,
|
||||
WinitNamedKey::Hyper => Key::Hyper,
|
||||
WinitNamedKey::Super => Key::Super,
|
||||
WinitNamedKey::Enter => Key::Enter,
|
||||
WinitNamedKey::Tab => Key::Tab,
|
||||
WinitNamedKey::Space => Key::Character(" ".to_string()),
|
||||
WinitNamedKey::ArrowDown => Key::ArrowDown,
|
||||
WinitNamedKey::ArrowLeft => Key::ArrowLeft,
|
||||
WinitNamedKey::ArrowRight => Key::ArrowRight,
|
||||
WinitNamedKey::ArrowUp => Key::ArrowUp,
|
||||
WinitNamedKey::End => Key::End,
|
||||
WinitNamedKey::Home => Key::Home,
|
||||
WinitNamedKey::PageDown => Key::PageDown,
|
||||
WinitNamedKey::PageUp => Key::PageUp,
|
||||
WinitNamedKey::Backspace => Key::Backspace,
|
||||
WinitNamedKey::Clear => Key::Clear,
|
||||
WinitNamedKey::Copy => Key::Copy,
|
||||
WinitNamedKey::CrSel => Key::CrSel,
|
||||
WinitNamedKey::Cut => Key::Cut,
|
||||
WinitNamedKey::Delete => Key::Delete,
|
||||
WinitNamedKey::EraseEof => Key::EraseEof,
|
||||
WinitNamedKey::ExSel => Key::ExSel,
|
||||
WinitNamedKey::Insert => Key::Insert,
|
||||
WinitNamedKey::Paste => Key::Paste,
|
||||
WinitNamedKey::Redo => Key::Redo,
|
||||
WinitNamedKey::Undo => Key::Undo,
|
||||
WinitNamedKey::Accept => Key::Accept,
|
||||
WinitNamedKey::Again => Key::Again,
|
||||
WinitNamedKey::Attn => Key::Attn,
|
||||
WinitNamedKey::Cancel => Key::Cancel,
|
||||
WinitNamedKey::ContextMenu => Key::ContextMenu,
|
||||
WinitNamedKey::Escape => Key::Escape,
|
||||
WinitNamedKey::Execute => Key::Execute,
|
||||
WinitNamedKey::Find => Key::Find,
|
||||
WinitNamedKey::Help => Key::Help,
|
||||
WinitNamedKey::Pause => Key::Pause,
|
||||
WinitNamedKey::Play => Key::Play,
|
||||
WinitNamedKey::Props => Key::Props,
|
||||
WinitNamedKey::Select => Key::Select,
|
||||
WinitNamedKey::ZoomIn => Key::ZoomIn,
|
||||
WinitNamedKey::ZoomOut => Key::ZoomOut,
|
||||
WinitNamedKey::BrightnessDown => Key::BrightnessDown,
|
||||
WinitNamedKey::BrightnessUp => Key::BrightnessUp,
|
||||
WinitNamedKey::Eject => Key::Eject,
|
||||
WinitNamedKey::LogOff => Key::LogOff,
|
||||
WinitNamedKey::Power => Key::Power,
|
||||
WinitNamedKey::PowerOff => Key::PowerOff,
|
||||
WinitNamedKey::PrintScreen => Key::PrintScreen,
|
||||
WinitNamedKey::Hibernate => Key::Hibernate,
|
||||
WinitNamedKey::Standby => Key::Standby,
|
||||
WinitNamedKey::WakeUp => Key::WakeUp,
|
||||
WinitNamedKey::AllCandidates => Key::AllCandidates,
|
||||
WinitNamedKey::Alphanumeric => Key::Alphanumeric,
|
||||
WinitNamedKey::CodeInput => Key::CodeInput,
|
||||
WinitNamedKey::Compose => Key::Compose,
|
||||
WinitNamedKey::Convert => Key::Convert,
|
||||
WinitNamedKey::FinalMode => Key::FinalMode,
|
||||
WinitNamedKey::GroupFirst => Key::GroupFirst,
|
||||
WinitNamedKey::GroupLast => Key::GroupLast,
|
||||
WinitNamedKey::GroupNext => Key::GroupNext,
|
||||
WinitNamedKey::GroupPrevious => Key::GroupPrevious,
|
||||
WinitNamedKey::ModeChange => Key::ModeChange,
|
||||
WinitNamedKey::NextCandidate => Key::NextCandidate,
|
||||
WinitNamedKey::NonConvert => Key::NonConvert,
|
||||
WinitNamedKey::PreviousCandidate => Key::PreviousCandidate,
|
||||
WinitNamedKey::Process => Key::Process,
|
||||
WinitNamedKey::SingleCandidate => Key::SingleCandidate,
|
||||
WinitNamedKey::HangulMode => Key::HangulMode,
|
||||
WinitNamedKey::HanjaMode => Key::HanjaMode,
|
||||
WinitNamedKey::JunjaMode => Key::JunjaMode,
|
||||
WinitNamedKey::Eisu => Key::Eisu,
|
||||
WinitNamedKey::Hankaku => Key::Hankaku,
|
||||
WinitNamedKey::Hiragana => Key::Hiragana,
|
||||
WinitNamedKey::HiraganaKatakana => Key::HiraganaKatakana,
|
||||
WinitNamedKey::KanaMode => Key::KanaMode,
|
||||
WinitNamedKey::KanjiMode => Key::KanjiMode,
|
||||
WinitNamedKey::Katakana => Key::Katakana,
|
||||
WinitNamedKey::Romaji => Key::Romaji,
|
||||
WinitNamedKey::Zenkaku => Key::Zenkaku,
|
||||
WinitNamedKey::ZenkakuHankaku => Key::ZenkakuHankaku,
|
||||
WinitNamedKey::Soft1 => Key::Soft1,
|
||||
WinitNamedKey::Soft2 => Key::Soft2,
|
||||
WinitNamedKey::Soft3 => Key::Soft3,
|
||||
WinitNamedKey::Soft4 => Key::Soft4,
|
||||
WinitNamedKey::ChannelDown => Key::ChannelDown,
|
||||
WinitNamedKey::ChannelUp => Key::ChannelUp,
|
||||
WinitNamedKey::Close => Key::Close,
|
||||
WinitNamedKey::MailForward => Key::MailForward,
|
||||
WinitNamedKey::MailReply => Key::MailReply,
|
||||
WinitNamedKey::MailSend => Key::MailSend,
|
||||
WinitNamedKey::MediaClose => Key::MediaClose,
|
||||
WinitNamedKey::MediaFastForward => Key::MediaFastForward,
|
||||
WinitNamedKey::MediaPause => Key::MediaPause,
|
||||
WinitNamedKey::MediaPlay => Key::MediaPlay,
|
||||
WinitNamedKey::MediaPlayPause => Key::MediaPlayPause,
|
||||
WinitNamedKey::MediaRecord => Key::MediaRecord,
|
||||
WinitNamedKey::MediaRewind => Key::MediaRewind,
|
||||
WinitNamedKey::MediaStop => Key::MediaStop,
|
||||
WinitNamedKey::MediaTrackNext => Key::MediaTrackNext,
|
||||
WinitNamedKey::MediaTrackPrevious => Key::MediaTrackPrevious,
|
||||
WinitNamedKey::New => Key::New,
|
||||
WinitNamedKey::Open => Key::Open,
|
||||
WinitNamedKey::Print => Key::Print,
|
||||
WinitNamedKey::Save => Key::Save,
|
||||
WinitNamedKey::SpellCheck => Key::SpellCheck,
|
||||
WinitNamedKey::Key11 => Key::Key11,
|
||||
WinitNamedKey::Key12 => Key::Key12,
|
||||
WinitNamedKey::AudioBalanceLeft => Key::AudioBalanceLeft,
|
||||
WinitNamedKey::AudioBalanceRight => Key::AudioBalanceRight,
|
||||
WinitNamedKey::AudioBassBoostDown => Key::AudioBassBoostDown,
|
||||
WinitNamedKey::AudioBassBoostToggle => Key::AudioBassBoostToggle,
|
||||
WinitNamedKey::AudioBassBoostUp => Key::AudioBassBoostUp,
|
||||
WinitNamedKey::AudioFaderFront => Key::AudioFaderFront,
|
||||
WinitNamedKey::AudioFaderRear => Key::AudioFaderRear,
|
||||
WinitNamedKey::AudioSurroundModeNext => Key::AudioSurroundModeNext,
|
||||
WinitNamedKey::AudioTrebleDown => Key::AudioTrebleDown,
|
||||
WinitNamedKey::AudioTrebleUp => Key::AudioTrebleUp,
|
||||
WinitNamedKey::AudioVolumeDown => Key::AudioVolumeDown,
|
||||
WinitNamedKey::AudioVolumeUp => Key::AudioVolumeUp,
|
||||
WinitNamedKey::AudioVolumeMute => Key::AudioVolumeMute,
|
||||
WinitNamedKey::MicrophoneToggle => Key::MicrophoneToggle,
|
||||
WinitNamedKey::MicrophoneVolumeDown => Key::MicrophoneVolumeDown,
|
||||
WinitNamedKey::MicrophoneVolumeUp => Key::MicrophoneVolumeUp,
|
||||
WinitNamedKey::MicrophoneVolumeMute => Key::MicrophoneVolumeMute,
|
||||
WinitNamedKey::SpeechCorrectionList => Key::SpeechCorrectionList,
|
||||
WinitNamedKey::SpeechInputToggle => Key::SpeechInputToggle,
|
||||
WinitNamedKey::LaunchApplication1 => Key::LaunchApplication1,
|
||||
WinitNamedKey::LaunchApplication2 => Key::LaunchApplication2,
|
||||
WinitNamedKey::LaunchCalendar => Key::LaunchCalendar,
|
||||
WinitNamedKey::LaunchContacts => Key::LaunchContacts,
|
||||
WinitNamedKey::LaunchMail => Key::LaunchMail,
|
||||
WinitNamedKey::LaunchMediaPlayer => Key::LaunchMediaPlayer,
|
||||
WinitNamedKey::LaunchMusicPlayer => Key::LaunchMusicPlayer,
|
||||
WinitNamedKey::LaunchPhone => Key::LaunchPhone,
|
||||
WinitNamedKey::LaunchScreenSaver => Key::LaunchScreenSaver,
|
||||
WinitNamedKey::LaunchSpreadsheet => Key::LaunchSpreadsheet,
|
||||
WinitNamedKey::LaunchWebBrowser => Key::LaunchWebBrowser,
|
||||
WinitNamedKey::LaunchWebCam => Key::LaunchWebCam,
|
||||
WinitNamedKey::LaunchWordProcessor => Key::LaunchWordProcessor,
|
||||
WinitNamedKey::BrowserBack => Key::BrowserBack,
|
||||
WinitNamedKey::BrowserFavorites => Key::BrowserFavorites,
|
||||
WinitNamedKey::BrowserForward => Key::BrowserForward,
|
||||
WinitNamedKey::BrowserHome => Key::BrowserHome,
|
||||
WinitNamedKey::BrowserRefresh => Key::BrowserRefresh,
|
||||
WinitNamedKey::BrowserSearch => Key::BrowserSearch,
|
||||
WinitNamedKey::BrowserStop => Key::BrowserStop,
|
||||
WinitNamedKey::AppSwitch => Key::AppSwitch,
|
||||
WinitNamedKey::Call => Key::Call,
|
||||
WinitNamedKey::Camera => Key::Camera,
|
||||
WinitNamedKey::CameraFocus => Key::CameraFocus,
|
||||
WinitNamedKey::EndCall => Key::EndCall,
|
||||
WinitNamedKey::GoBack => Key::GoBack,
|
||||
WinitNamedKey::GoHome => Key::GoHome,
|
||||
WinitNamedKey::HeadsetHook => Key::HeadsetHook,
|
||||
WinitNamedKey::LastNumberRedial => Key::LastNumberRedial,
|
||||
WinitNamedKey::Notification => Key::Notification,
|
||||
WinitNamedKey::MannerMode => Key::MannerMode,
|
||||
WinitNamedKey::VoiceDial => Key::VoiceDial,
|
||||
WinitNamedKey::TV => Key::TV,
|
||||
WinitNamedKey::TV3DMode => Key::TV3DMode,
|
||||
WinitNamedKey::TVAntennaCable => Key::TVAntennaCable,
|
||||
WinitNamedKey::TVAudioDescription => Key::TVAudioDescription,
|
||||
WinitNamedKey::TVAudioDescriptionMixDown => Key::TVAudioDescriptionMixDown,
|
||||
WinitNamedKey::TVAudioDescriptionMixUp => Key::TVAudioDescriptionMixUp,
|
||||
WinitNamedKey::TVContentsMenu => Key::TVContentsMenu,
|
||||
WinitNamedKey::TVDataService => Key::TVDataService,
|
||||
WinitNamedKey::TVInput => Key::TVInput,
|
||||
WinitNamedKey::TVInputComponent1 => Key::TVInputComponent1,
|
||||
WinitNamedKey::TVInputComponent2 => Key::TVInputComponent2,
|
||||
WinitNamedKey::TVInputComposite1 => Key::TVInputComposite1,
|
||||
WinitNamedKey::TVInputComposite2 => Key::TVInputComposite2,
|
||||
WinitNamedKey::TVInputHDMI1 => Key::TVInputHDMI1,
|
||||
WinitNamedKey::TVInputHDMI2 => Key::TVInputHDMI2,
|
||||
WinitNamedKey::TVInputHDMI3 => Key::TVInputHDMI3,
|
||||
WinitNamedKey::TVInputHDMI4 => Key::TVInputHDMI4,
|
||||
WinitNamedKey::TVInputVGA1 => Key::TVInputVGA1,
|
||||
WinitNamedKey::TVMediaContext => Key::TVMediaContext,
|
||||
WinitNamedKey::TVNetwork => Key::TVNetwork,
|
||||
WinitNamedKey::TVNumberEntry => Key::TVNumberEntry,
|
||||
WinitNamedKey::TVPower => Key::TVPower,
|
||||
WinitNamedKey::TVRadioService => Key::TVRadioService,
|
||||
WinitNamedKey::TVSatellite => Key::TVSatellite,
|
||||
WinitNamedKey::TVSatelliteBS => Key::TVSatelliteBS,
|
||||
WinitNamedKey::TVSatelliteCS => Key::TVSatelliteCS,
|
||||
WinitNamedKey::TVSatelliteToggle => Key::TVSatelliteToggle,
|
||||
WinitNamedKey::TVTerrestrialAnalog => Key::TVTerrestrialAnalog,
|
||||
WinitNamedKey::TVTerrestrialDigital => Key::TVTerrestrialDigital,
|
||||
WinitNamedKey::TVTimer => Key::TVTimer,
|
||||
WinitNamedKey::AVRInput => Key::AVRInput,
|
||||
WinitNamedKey::AVRPower => Key::AVRPower,
|
||||
WinitNamedKey::ColorF0Red => Key::ColorF0Red,
|
||||
WinitNamedKey::ColorF1Green => Key::ColorF1Green,
|
||||
WinitNamedKey::ColorF2Yellow => Key::ColorF2Yellow,
|
||||
WinitNamedKey::ColorF3Blue => Key::ColorF3Blue,
|
||||
WinitNamedKey::ColorF4Grey => Key::ColorF4Grey,
|
||||
WinitNamedKey::ColorF5Brown => Key::ColorF5Brown,
|
||||
WinitNamedKey::ClosedCaptionToggle => Key::ClosedCaptionToggle,
|
||||
WinitNamedKey::Dimmer => Key::Dimmer,
|
||||
WinitNamedKey::DisplaySwap => Key::DisplaySwap,
|
||||
WinitNamedKey::DVR => Key::DVR,
|
||||
WinitNamedKey::Exit => Key::Exit,
|
||||
WinitNamedKey::FavoriteClear0 => Key::FavoriteClear0,
|
||||
WinitNamedKey::FavoriteClear1 => Key::FavoriteClear1,
|
||||
WinitNamedKey::FavoriteClear2 => Key::FavoriteClear2,
|
||||
WinitNamedKey::FavoriteClear3 => Key::FavoriteClear3,
|
||||
WinitNamedKey::FavoriteRecall0 => Key::FavoriteRecall0,
|
||||
WinitNamedKey::FavoriteRecall1 => Key::FavoriteRecall1,
|
||||
WinitNamedKey::FavoriteRecall2 => Key::FavoriteRecall2,
|
||||
WinitNamedKey::FavoriteRecall3 => Key::FavoriteRecall3,
|
||||
WinitNamedKey::FavoriteStore0 => Key::FavoriteStore0,
|
||||
WinitNamedKey::FavoriteStore1 => Key::FavoriteStore1,
|
||||
WinitNamedKey::FavoriteStore2 => Key::FavoriteStore2,
|
||||
WinitNamedKey::FavoriteStore3 => Key::FavoriteStore3,
|
||||
WinitNamedKey::Guide => Key::Guide,
|
||||
WinitNamedKey::GuideNextDay => Key::GuideNextDay,
|
||||
WinitNamedKey::GuidePreviousDay => Key::GuidePreviousDay,
|
||||
WinitNamedKey::Info => Key::Info,
|
||||
WinitNamedKey::InstantReplay => Key::InstantReplay,
|
||||
WinitNamedKey::Link => Key::Link,
|
||||
WinitNamedKey::ListProgram => Key::ListProgram,
|
||||
WinitNamedKey::LiveContent => Key::LiveContent,
|
||||
WinitNamedKey::Lock => Key::Lock,
|
||||
WinitNamedKey::MediaApps => Key::MediaApps,
|
||||
WinitNamedKey::MediaAudioTrack => Key::MediaAudioTrack,
|
||||
WinitNamedKey::MediaLast => Key::MediaLast,
|
||||
WinitNamedKey::MediaSkipBackward => Key::MediaSkipBackward,
|
||||
WinitNamedKey::MediaSkipForward => Key::MediaSkipForward,
|
||||
WinitNamedKey::MediaStepBackward => Key::MediaStepBackward,
|
||||
WinitNamedKey::MediaStepForward => Key::MediaStepForward,
|
||||
WinitNamedKey::MediaTopMenu => Key::MediaTopMenu,
|
||||
WinitNamedKey::NavigateIn => Key::NavigateIn,
|
||||
WinitNamedKey::NavigateNext => Key::NavigateNext,
|
||||
WinitNamedKey::NavigateOut => Key::NavigateOut,
|
||||
WinitNamedKey::NavigatePrevious => Key::NavigatePrevious,
|
||||
WinitNamedKey::NextFavoriteChannel => Key::NextFavoriteChannel,
|
||||
WinitNamedKey::NextUserProfile => Key::NextUserProfile,
|
||||
WinitNamedKey::OnDemand => Key::OnDemand,
|
||||
WinitNamedKey::Pairing => Key::Pairing,
|
||||
WinitNamedKey::PinPDown => Key::PinPDown,
|
||||
WinitNamedKey::PinPMove => Key::PinPMove,
|
||||
WinitNamedKey::PinPToggle => Key::PinPToggle,
|
||||
WinitNamedKey::PinPUp => Key::PinPUp,
|
||||
WinitNamedKey::PlaySpeedDown => Key::PlaySpeedDown,
|
||||
WinitNamedKey::PlaySpeedReset => Key::PlaySpeedReset,
|
||||
WinitNamedKey::PlaySpeedUp => Key::PlaySpeedUp,
|
||||
WinitNamedKey::RandomToggle => Key::RandomToggle,
|
||||
WinitNamedKey::RcLowBattery => Key::RcLowBattery,
|
||||
WinitNamedKey::RecordSpeedNext => Key::RecordSpeedNext,
|
||||
WinitNamedKey::RfBypass => Key::RfBypass,
|
||||
WinitNamedKey::ScanChannelsToggle => Key::ScanChannelsToggle,
|
||||
WinitNamedKey::ScreenModeNext => Key::ScreenModeNext,
|
||||
WinitNamedKey::Settings => Key::Settings,
|
||||
WinitNamedKey::SplitScreenToggle => Key::SplitScreenToggle,
|
||||
WinitNamedKey::STBInput => Key::STBInput,
|
||||
WinitNamedKey::STBPower => Key::STBPower,
|
||||
WinitNamedKey::Subtitle => Key::Subtitle,
|
||||
WinitNamedKey::Teletext => Key::Teletext,
|
||||
WinitNamedKey::VideoModeNext => Key::VideoModeNext,
|
||||
WinitNamedKey::Wink => Key::Wink,
|
||||
WinitNamedKey::ZoomToggle => Key::ZoomToggle,
|
||||
WinitNamedKey::F1 => Key::F1,
|
||||
WinitNamedKey::F2 => Key::F2,
|
||||
WinitNamedKey::F3 => Key::F3,
|
||||
WinitNamedKey::F4 => Key::F4,
|
||||
WinitNamedKey::F5 => Key::F5,
|
||||
WinitNamedKey::F6 => Key::F6,
|
||||
WinitNamedKey::F7 => Key::F7,
|
||||
WinitNamedKey::F8 => Key::F8,
|
||||
WinitNamedKey::F9 => Key::F9,
|
||||
WinitNamedKey::F10 => Key::F10,
|
||||
WinitNamedKey::F11 => Key::F11,
|
||||
WinitNamedKey::F12 => Key::F12,
|
||||
WinitNamedKey::F13 => Key::F13,
|
||||
WinitNamedKey::F14 => Key::F14,
|
||||
WinitNamedKey::F15 => Key::F15,
|
||||
WinitNamedKey::F16 => Key::F16,
|
||||
WinitNamedKey::F17 => Key::F17,
|
||||
WinitNamedKey::F18 => Key::F18,
|
||||
WinitNamedKey::F19 => Key::F19,
|
||||
WinitNamedKey::F20 => Key::F20,
|
||||
WinitNamedKey::F21 => Key::F21,
|
||||
WinitNamedKey::F22 => Key::F22,
|
||||
WinitNamedKey::F23 => Key::F23,
|
||||
WinitNamedKey::F24 => Key::F24,
|
||||
WinitNamedKey::F25 => Key::F25,
|
||||
WinitNamedKey::F26 => Key::F26,
|
||||
WinitNamedKey::F27 => Key::F27,
|
||||
WinitNamedKey::F28 => Key::F28,
|
||||
WinitNamedKey::F29 => Key::F29,
|
||||
WinitNamedKey::F30 => Key::F30,
|
||||
WinitNamedKey::F31 => Key::F31,
|
||||
WinitNamedKey::F32 => Key::F32,
|
||||
WinitNamedKey::F33 => Key::F33,
|
||||
WinitNamedKey::F34 => Key::F34,
|
||||
WinitNamedKey::F35 => Key::F35,
|
||||
_ => Key::Unidentified,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ use winit::window::{Window, WindowAttributes, WindowId};
|
|||
|
||||
use crate::app::{
|
||||
AppDriver, DriverCtx, RenderRoot, RenderRootOptions, RenderRootSignal, WindowSizePolicy,
|
||||
masonry_resize_direction_to_winit, winit_force_to_masonry, winit_ime_to_masonry,
|
||||
winit_key_event_to_kbt, winit_modifiers_to_kbt_modifiers, winit_mouse_button_to_masonry,
|
||||
};
|
||||
use crate::core::{
|
||||
PointerButton, PointerEvent, PointerState, TextEvent, Widget, WidgetId, WindowEvent,
|
||||
|
@ -43,22 +45,6 @@ impl From<accesskit_winit::Event> for MasonryUserEvent {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<WinitMouseButton> for PointerButton {
|
||||
fn from(button: WinitMouseButton) -> Self {
|
||||
match button {
|
||||
WinitMouseButton::Left => Self::Primary,
|
||||
WinitMouseButton::Right => Self::Secondary,
|
||||
WinitMouseButton::Middle => Self::Auxiliary,
|
||||
WinitMouseButton::Back => Self::X1,
|
||||
WinitMouseButton::Forward => Self::X2,
|
||||
WinitMouseButton::Other(other) => {
|
||||
warn!("Got winit MouseButton::Other({other}) which is not yet fully supported.");
|
||||
Self::Other
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum WindowState<'a> {
|
||||
Uninitialized(WindowAttributes),
|
||||
Rendering {
|
||||
|
@ -79,6 +65,7 @@ pub struct MasonryState<'a> {
|
|||
render_cx: RenderContext,
|
||||
render_root: RenderRoot,
|
||||
pointer_state: PointerState,
|
||||
winit_mods: winit::event::Modifiers,
|
||||
renderer: Option<Renderer>,
|
||||
// TODO: Winit doesn't seem to let us create these proxies from within the loop
|
||||
// The reasons for this are unclear
|
||||
|
@ -247,6 +234,7 @@ impl MasonryState<'_> {
|
|||
#[cfg(feature = "tracy")]
|
||||
frame: None,
|
||||
pointer_state: PointerState::empty(),
|
||||
winit_mods: winit::event::Modifiers::default(),
|
||||
proxy: event_loop.create_proxy(),
|
||||
|
||||
window: WindowState::Uninitialized(window),
|
||||
|
@ -500,21 +488,26 @@ impl MasonryState<'_> {
|
|||
.handle_window_event(WindowEvent::Resize(size));
|
||||
}
|
||||
WinitWindowEvent::ModifiersChanged(modifiers) => {
|
||||
self.pointer_state.mods = modifiers;
|
||||
self.pointer_state.mods = winit_modifiers_to_kbt_modifiers(modifiers.state());
|
||||
self.winit_mods = modifiers;
|
||||
self.render_root
|
||||
.handle_text_event(TextEvent::ModifierChange(modifiers.state()));
|
||||
.handle_text_event(TextEvent::ModifierChange(self.pointer_state.mods));
|
||||
}
|
||||
WinitWindowEvent::KeyboardInput {
|
||||
device_id: _,
|
||||
event,
|
||||
is_synthetic: false, // TODO: Introduce an escape hatch for synthetic keys
|
||||
} => {
|
||||
let text = event.text.as_ref().map(|text| text.to_string());
|
||||
let event = winit_key_event_to_kbt(&event, self.winit_mods.state());
|
||||
self.render_root.handle_text_event(TextEvent::KeyboardKey(
|
||||
event,
|
||||
self.pointer_state.mods.state(),
|
||||
self.pointer_state.mods,
|
||||
text,
|
||||
));
|
||||
}
|
||||
WinitWindowEvent::Ime(ime) => {
|
||||
let ime = winit_ime_to_masonry(ime);
|
||||
self.render_root.handle_text_event(TextEvent::Ime(ime));
|
||||
}
|
||||
WinitWindowEvent::Focused(new_focus) => {
|
||||
|
@ -535,22 +528,31 @@ impl MasonryState<'_> {
|
|||
self.render_root
|
||||
.handle_pointer_event(PointerEvent::PointerLeave(self.pointer_state.clone()));
|
||||
}
|
||||
WinitWindowEvent::MouseInput { state, button, .. } => match state {
|
||||
WinitWindowEvent::MouseInput { state, button, .. } => {
|
||||
if let WinitMouseButton::Other(other) = button {
|
||||
warn!(
|
||||
"Got winit MouseButton::Other({other}) which is not yet fully supported."
|
||||
);
|
||||
}
|
||||
let button = winit_mouse_button_to_masonry(button);
|
||||
|
||||
match state {
|
||||
winit::event::ElementState::Pressed => {
|
||||
self.render_root
|
||||
.handle_pointer_event(PointerEvent::PointerDown(
|
||||
button.into(),
|
||||
button,
|
||||
self.pointer_state.clone(),
|
||||
));
|
||||
}
|
||||
winit::event::ElementState::Released => {
|
||||
self.render_root
|
||||
.handle_pointer_event(PointerEvent::PointerUp(
|
||||
button.into(),
|
||||
button,
|
||||
self.pointer_state.clone(),
|
||||
));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
WinitWindowEvent::MouseWheel { delta, .. } => {
|
||||
// TODO - This delta value doesn't quite make sense.
|
||||
// Figure out and document a better standard.
|
||||
|
@ -578,7 +580,7 @@ impl MasonryState<'_> {
|
|||
// It will also interact with gesture discrimination.
|
||||
self.pointer_state.physical_position = location;
|
||||
self.pointer_state.position = location.to_logical(window.scale_factor());
|
||||
self.pointer_state.force = force;
|
||||
self.pointer_state.force = force.map(winit_force_to_masonry);
|
||||
match phase {
|
||||
winit::event::TouchPhase::Started => {
|
||||
self.render_root
|
||||
|
@ -725,6 +727,7 @@ impl MasonryState<'_> {
|
|||
}
|
||||
RenderRootSignal::DragResizeWindow(direction) => {
|
||||
// TODO - Handle return value?
|
||||
let direction = masonry_resize_direction_to_winit(direction);
|
||||
let _ = window.drag_resize_window(direction);
|
||||
}
|
||||
RenderRootSignal::ToggleMaximized => {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//! Types needed for running a Masonry app.
|
||||
|
||||
mod app_driver;
|
||||
mod convert_winit_event;
|
||||
mod event_loop_runner;
|
||||
mod render_root;
|
||||
mod tracing_backend;
|
||||
|
@ -14,5 +15,9 @@ pub use event_loop_runner::{
|
|||
};
|
||||
pub use render_root::{RenderRoot, RenderRootOptions, RenderRootSignal, WindowSizePolicy};
|
||||
|
||||
pub(crate) use convert_winit_event::{
|
||||
masonry_resize_direction_to_winit, winit_force_to_masonry, winit_ime_to_masonry,
|
||||
winit_key_event_to_kbt, winit_modifiers_to_kbt_modifiers, winit_mouse_button_to_masonry,
|
||||
};
|
||||
pub(crate) use render_root::{MutateCallback, RenderRootState};
|
||||
pub(crate) use tracing_backend::{try_init_test_tracing, try_init_tracing};
|
||||
|
|
|
@ -13,7 +13,6 @@ use vello::Scene;
|
|||
use vello::kurbo::{
|
||||
Rect, {self},
|
||||
};
|
||||
use winit::window::ResizeDirection;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use std::time::Instant;
|
||||
|
@ -22,8 +21,9 @@ use web_time::Instant;
|
|||
|
||||
use crate::Handled;
|
||||
use crate::core::{
|
||||
AccessEvent, Action, BrushIndex, PointerEvent, PropertiesRef, QueryCtx, TextEvent, Widget,
|
||||
WidgetArena, WidgetId, WidgetMut, WidgetPod, WidgetRef, WidgetState, WindowEvent,
|
||||
AccessEvent, Action, BrushIndex, Ime, PointerEvent, PropertiesRef, QueryCtx, ResizeDirection,
|
||||
TextEvent, Widget, WidgetArena, WidgetId, WidgetMut, WidgetPod, WidgetRef, WidgetState,
|
||||
WindowEvent,
|
||||
};
|
||||
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||
use crate::passes::accessibility::run_accessibility_pass;
|
||||
|
@ -396,7 +396,7 @@ impl RenderRoot {
|
|||
let handled = run_on_text_event_pass(self, &event);
|
||||
run_update_focus_pass(self);
|
||||
|
||||
if matches!(event, TextEvent::Ime(winit::event::Ime::Enabled)) {
|
||||
if matches!(event, TextEvent::Ime(Ime::Enabled)) {
|
||||
// Reset the last sent IME area, as the platform reset the IME state and may have
|
||||
// forgotten it.
|
||||
self.global_state.last_sent_ime_area = INVALID_IME_AREA;
|
||||
|
|
|
@ -9,12 +9,11 @@ use dpi::LogicalPosition;
|
|||
use parley::{FontContext, LayoutContext};
|
||||
use tracing::{trace, warn};
|
||||
use tree_arena::{ArenaMutList, ArenaRefList};
|
||||
use winit::window::ResizeDirection;
|
||||
|
||||
use crate::app::{MutateCallback, RenderRootSignal, RenderRootState};
|
||||
use crate::core::{
|
||||
Action, AllowRawMut, BoxConstraints, BrushIndex, CreateWidget, FromDynWidget, PropertiesMut,
|
||||
PropertiesRef, Widget, WidgetId, WidgetMut, WidgetPod, WidgetRef, WidgetState,
|
||||
PropertiesRef, ResizeDirection, Widget, WidgetId, WidgetMut, WidgetPod, WidgetRef, WidgetState,
|
||||
};
|
||||
use crate::kurbo::{Affine, Insets, Point, Rect, Size, Vec2};
|
||||
use crate::passes::layout::run_layout_on;
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use keyboard_types::{KeyboardEvent, Modifiers};
|
||||
use vello::kurbo::Point;
|
||||
use winit::event::{Force, Ime, KeyEvent, Modifiers};
|
||||
use winit::keyboard::ModifiersState;
|
||||
|
||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||
use crate::kurbo::Rect;
|
||||
|
@ -228,11 +227,11 @@ pub enum PointerEvent {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum TextEvent {
|
||||
/// A keyboard event.
|
||||
KeyboardKey(KeyEvent, ModifiersState),
|
||||
KeyboardKey(KeyboardEvent, Modifiers, Option<String>),
|
||||
/// An IME event.
|
||||
Ime(Ime),
|
||||
/// Modifier keys (e.g. Shift, Ctrl, Alt) were pressed or released.
|
||||
ModifierChange(ModifiersState),
|
||||
ModifierChange(Modifiers),
|
||||
/// The window took or lost focus.
|
||||
WindowFocusChange(bool),
|
||||
}
|
||||
|
@ -474,8 +473,8 @@ impl TextEvent {
|
|||
/// Short name, for debug logging.
|
||||
pub fn short_name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::KeyboardKey(KeyEvent { repeat: true, .. }, _) => "KeyboardKey(repeat)",
|
||||
Self::KeyboardKey(_, _) => "KeyboardKey",
|
||||
Self::KeyboardKey(KeyboardEvent { repeat: true, .. }, ..) => "KeyboardKey(repeat)",
|
||||
Self::KeyboardKey(..) => "KeyboardKey",
|
||||
Self::Ime(Ime::Disabled) => "Ime::Disabled",
|
||||
Self::Ime(Ime::Enabled) => "Ime::Enabled",
|
||||
Self::Ime(Ime::Commit(_)) => "Ime::Commit",
|
||||
|
@ -492,7 +491,7 @@ impl TextEvent {
|
|||
/// cluttering the console.
|
||||
pub fn is_high_density(&self) -> bool {
|
||||
match self {
|
||||
Self::KeyboardKey(_, _) => false,
|
||||
Self::KeyboardKey(..) => false,
|
||||
Self::Ime(_) => false,
|
||||
// Basically every mouse click/scroll event seems to produce a modifier change event.
|
||||
Self::ModifierChange(_) => true,
|
||||
|
@ -570,3 +569,153 @@ impl Update {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes [input method](https://en.wikipedia.org/wiki/Input_method) events.
|
||||
///
|
||||
/// Mirrors [`winit::event::Ime`](https://docs.rs/winit/latest/x86_64-unknown-linux-gnu/winit/event/enum.Ime.html).
|
||||
///
|
||||
/// This is also called a "composition event".
|
||||
///
|
||||
/// Most keypresses using a latin-like keyboard layout simply generate a
|
||||
/// [`TextEvent::KeyboardKey`]. However, one couldn't possibly have a key for every single
|
||||
/// unicode character that the user might want to type
|
||||
/// - so the solution operating systems employ is to allow the user to type these using _a sequence
|
||||
/// of keypresses_ instead.
|
||||
///
|
||||
/// A prominent example of this is accents - many keyboard layouts allow you to first click the
|
||||
/// "accent key", and then the character you want to apply the accent to. In this case, some
|
||||
/// platforms will generate the following event sequence:
|
||||
///
|
||||
/// ```ignore
|
||||
/// // Press "`" key
|
||||
/// Ime::Preedit("`", Some((0, 0)))
|
||||
/// // Press "E" key
|
||||
/// Ime::Preedit("", None) // Synthetic event generated by winit to clear preedit.
|
||||
/// Ime::Commit("é")
|
||||
/// ```
|
||||
///
|
||||
/// Additionally, certain input devices are configured to display a candidate box that allow the
|
||||
/// user to select the desired character interactively. (To properly position this box, you must use
|
||||
/// [`RenderRootSignal::ImeMoved`](crate::app::RenderRootSignal::ImeMoved).)
|
||||
///
|
||||
/// An example of a keyboard layout which uses candidate boxes is pinyin. On a latin keyboard the
|
||||
/// following event sequence could be obtained:
|
||||
///
|
||||
/// ```ignore
|
||||
/// // Press "A" key
|
||||
/// Ime::Preedit("a", Some((1, 1)))
|
||||
/// // Press "B" key
|
||||
/// Ime::Preedit("a b", Some((3, 3)))
|
||||
/// // Press left arrow key
|
||||
/// Ime::Preedit("a b", Some((1, 1)))
|
||||
/// // Press space key
|
||||
/// Ime::Preedit("啊b", Some((3, 3)))
|
||||
/// // Press space key
|
||||
/// Ime::Preedit("", None) // Synthetic event generated by winit to clear preedit.
|
||||
/// Ime::Commit("啊不")
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
//#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum Ime {
|
||||
/// Notifies when the IME was enabled.
|
||||
///
|
||||
/// After getting this event you could receive [`Preedit`][Self::Preedit] and
|
||||
/// [`Commit`][Self::Commit] events. You should also start performing IME related requests
|
||||
/// like [`RenderRootSignal::ImeMoved`](crate::app::RenderRootSignal::ImeMoved).
|
||||
Enabled,
|
||||
|
||||
/// Notifies when a new composing text should be set at the cursor position.
|
||||
///
|
||||
/// The value represents a pair of the preedit string and the cursor begin position and end
|
||||
/// position. When it's `None`, the cursor should be hidden. When `String` is an empty string
|
||||
/// this indicates that preedit was cleared.
|
||||
///
|
||||
/// The cursor position is byte-wise indexed.
|
||||
Preedit(String, Option<(usize, usize)>),
|
||||
|
||||
/// Notifies when text should be inserted into the editor widget.
|
||||
///
|
||||
/// Right before this event winit will send empty [`Self::Preedit`] event.
|
||||
Commit(String),
|
||||
|
||||
/// Notifies when the IME was disabled.
|
||||
///
|
||||
/// After receiving this event you won't get any more [`Preedit`][Self::Preedit] or
|
||||
/// [`Commit`][Self::Commit] events until the next [`Enabled`][Self::Enabled] event.
|
||||
Disabled,
|
||||
}
|
||||
|
||||
/// Describes the force of a touch event
|
||||
///
|
||||
/// Mirrors [`winit::event::Force`](https://docs.rs/winit/latest/x86_64-unknown-linux-gnu/winit/event/enum.Force.html).
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Force {
|
||||
/// On iOS, the force is calibrated so that the same number corresponds to
|
||||
/// roughly the same amount of pressure on the screen regardless of the
|
||||
/// device.
|
||||
Calibrated {
|
||||
/// The force of the touch, where a value of 1.0 represents the force of
|
||||
/// an average touch (predetermined by the system, not user-specific).
|
||||
///
|
||||
/// The force reported by Apple Pencil is measured along the axis of the
|
||||
/// pencil. If you want a force perpendicular to the device, you need to
|
||||
/// calculate this value using the `altitude_angle` value.
|
||||
force: f64,
|
||||
/// The maximum possible force for a touch.
|
||||
///
|
||||
/// The value of this field is sufficiently high to provide a wide
|
||||
/// dynamic range for values of the `force` field.
|
||||
max_possible_force: f64,
|
||||
/// The altitude (in radians) of the stylus.
|
||||
///
|
||||
/// A value of 0 radians indicates that the stylus is parallel to the
|
||||
/// surface. The value of this property is Pi/2 when the stylus is
|
||||
/// perpendicular to the surface.
|
||||
altitude_angle: Option<f64>,
|
||||
},
|
||||
/// If the platform reports the force as normalized, we have no way of
|
||||
/// knowing how much pressure 1.0 corresponds to – we know it's the maximum
|
||||
/// amount of force, but as to how much force, you might either have to
|
||||
/// press really really hard, or not hard at all, depending on the device.
|
||||
Normalized(f64),
|
||||
}
|
||||
|
||||
impl Force {
|
||||
/// Returns the force normalized to the range between 0.0 and 1.0 inclusive.
|
||||
///
|
||||
/// Instead of normalizing the force, you should prefer to handle
|
||||
/// [`Force::Calibrated`] so that the amount of force the user has to apply is
|
||||
/// consistent across devices.
|
||||
pub fn normalized(&self) -> f64 {
|
||||
match self {
|
||||
Self::Calibrated {
|
||||
force,
|
||||
max_possible_force,
|
||||
altitude_angle,
|
||||
} => {
|
||||
let force = match altitude_angle {
|
||||
Some(altitude_angle) => force / altitude_angle.sin(),
|
||||
None => *force,
|
||||
};
|
||||
force / max_possible_force
|
||||
}
|
||||
Self::Normalized(force) => *force,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines the orientation that a window resize will be performed.
|
||||
///
|
||||
/// Mirrors [`winit::window::ResizeDirection`](https://docs.rs/winit/latest/x86_64-unknown-linux-gnu/winit/window/enum.ResizeDirection.html).
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[expect(missing_docs, reason = "Copied from winit")]
|
||||
pub enum ResizeDirection {
|
||||
East,
|
||||
North,
|
||||
NorthEast,
|
||||
NorthWest,
|
||||
South,
|
||||
SouthEast,
|
||||
SouthWest,
|
||||
West,
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
mod action;
|
||||
mod box_constraints;
|
||||
mod contexts;
|
||||
mod event;
|
||||
mod events;
|
||||
mod object_fit;
|
||||
mod properties;
|
||||
mod text;
|
||||
|
@ -23,9 +23,9 @@ pub use contexts::{
|
|||
AccessCtx, ComposeCtx, EventCtx, IsContext, LayoutCtx, MutateCtx, PaintCtx, QueryCtx,
|
||||
RawWrapper, RawWrapperMut, RegisterCtx, UpdateCtx,
|
||||
};
|
||||
pub use event::{
|
||||
AccessEvent, PointerButton, PointerEvent, PointerState, TextEvent, Update, WindowEvent,
|
||||
WindowTheme,
|
||||
pub use events::{
|
||||
AccessEvent, Force, Ime, PointerButton, PointerEvent, PointerState, ResizeDirection, TextEvent,
|
||||
Update, WindowEvent, WindowTheme,
|
||||
};
|
||||
pub use object_fit::ObjectFit;
|
||||
pub use properties::{Properties, PropertiesMut, PropertiesRef};
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use dpi::LogicalPosition;
|
||||
use keyboard_types::{Key, KeyState};
|
||||
use tracing::{debug, info_span, trace};
|
||||
use winit::event::ElementState;
|
||||
use winit::keyboard::{KeyCode, PhysicalKey};
|
||||
|
||||
use crate::Handled;
|
||||
use crate::app::{RenderRoot, RenderRootSignal};
|
||||
|
@ -227,22 +226,16 @@ pub(crate) fn run_on_text_event_pass(root: &mut RenderRoot, event: &TextEvent) -
|
|||
!event.is_high_density(),
|
||||
);
|
||||
|
||||
if let TextEvent::KeyboardKey(key, mods) = event {
|
||||
if let TextEvent::KeyboardKey(key, mods, _) = event {
|
||||
// Handle Tab focus
|
||||
if key.physical_key == PhysicalKey::Code(KeyCode::Tab)
|
||||
&& key.state == ElementState::Pressed
|
||||
&& handled == Handled::No
|
||||
{
|
||||
let forward = !mods.shift_key();
|
||||
if key.key == Key::Tab && key.state == KeyState::Down && handled == Handled::No {
|
||||
let forward = !mods.shift();
|
||||
let next_focused_widget = root.widget_from_focus_chain(forward);
|
||||
root.global_state.next_focused_widget = next_focused_widget;
|
||||
handled = Handled::Yes;
|
||||
}
|
||||
|
||||
if key.physical_key == PhysicalKey::Code(KeyCode::F11)
|
||||
&& key.state == ElementState::Pressed
|
||||
&& handled == Handled::No
|
||||
{
|
||||
if key.key == Key::F11 && key.state == KeyState::Down && handled == Handled::No {
|
||||
root.global_state.inspector_state.is_picking_widget =
|
||||
!root.global_state.inspector_state.is_picking_widget;
|
||||
root.global_state.inspector_state.hovered_widget = None;
|
||||
|
@ -251,10 +244,7 @@ pub(crate) fn run_on_text_event_pass(root: &mut RenderRoot, event: &TextEvent) -
|
|||
handled = Handled::Yes;
|
||||
}
|
||||
|
||||
if key.physical_key == PhysicalKey::Code(KeyCode::F12)
|
||||
&& key.state == ElementState::Pressed
|
||||
&& handled == Handled::No
|
||||
{
|
||||
if key.key == Key::F12 && key.state == KeyState::Down && handled == Handled::No {
|
||||
root.debug_paint = !root.debug_paint;
|
||||
root.root_state_mut().needs_paint = true;
|
||||
handled = Handled::Yes;
|
||||
|
|
|
@ -10,7 +10,7 @@ use tree_arena::ArenaMut;
|
|||
|
||||
use crate::app::{RenderRoot, RenderRootSignal, RenderRootState};
|
||||
use crate::core::{
|
||||
PointerEvent, PropertiesMut, QueryCtx, RegisterCtx, TextEvent, Update, UpdateCtx, Widget,
|
||||
Ime, PointerEvent, PropertiesMut, QueryCtx, RegisterCtx, TextEvent, Update, UpdateCtx, Widget,
|
||||
WidgetId, WidgetState,
|
||||
};
|
||||
use crate::passes::event::{run_on_pointer_event_pass, run_on_text_event_pass};
|
||||
|
@ -507,7 +507,7 @@ pub(crate) fn run_update_focus_pass(root: &mut RenderRoot) {
|
|||
// IME was active, but the next focused widget is going to receive the Ime::Disabled event
|
||||
// sent by the platform. Synthesize an `Ime::Disabled` event here and send it to the widget
|
||||
// about to be unfocused.
|
||||
run_on_text_event_pass(root, &TextEvent::Ime(winit::event::Ime::Disabled));
|
||||
run_on_text_event_pass(root, &TextEvent::Ime(Ime::Disabled));
|
||||
|
||||
// Disable the IME, which was enabled specifically for this widget. Note that if the newly
|
||||
// focused widget also requires IME, we will request it again - this resets the platform's
|
||||
|
|
|
@ -16,14 +16,13 @@ use wgpu::{
|
|||
BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d, ImageCopyBuffer,
|
||||
TextureDescriptor, TextureFormat, TextureUsages,
|
||||
};
|
||||
use winit::event::Ime;
|
||||
|
||||
use crate::Handled;
|
||||
use crate::app::{
|
||||
RenderRoot, RenderRootOptions, RenderRootSignal, WindowSizePolicy, try_init_test_tracing,
|
||||
};
|
||||
use crate::core::{
|
||||
Action, PointerButton, PointerEvent, PointerState, TextEvent, Widget, WidgetId, WidgetMut,
|
||||
Action, Ime, PointerButton, PointerEvent, PointerState, TextEvent, Widget, WidgetId, WidgetMut,
|
||||
WidgetRef, WindowEvent,
|
||||
};
|
||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::mem::Discriminant;
|
|||
use std::time::Instant;
|
||||
|
||||
use accesskit::{Node, NodeId, Role};
|
||||
use keyboard_types::{Key, KeyState};
|
||||
use parley::PlainEditor;
|
||||
use parley::editor::{Generation, SplitString};
|
||||
use parley::layout::Alignment;
|
||||
|
@ -13,10 +14,9 @@ use tracing::{Span, trace_span};
|
|||
use vello::Scene;
|
||||
use vello::kurbo::{Affine, Point, Rect, Size, Vec2};
|
||||
use vello::peniko::{Brush, Fill};
|
||||
use winit::keyboard::{Key, NamedKey};
|
||||
|
||||
use crate::core::{
|
||||
AccessCtx, AccessEvent, BoxConstraints, BrushIndex, EventCtx, LayoutCtx, PaintCtx,
|
||||
AccessCtx, AccessEvent, BoxConstraints, BrushIndex, EventCtx, Ime, LayoutCtx, PaintCtx,
|
||||
PointerButton, PointerEvent, PropertiesMut, PropertiesRef, QueryCtx, RegisterCtx,
|
||||
StyleProperty, TextEvent, Update, UpdateCtx, Widget, WidgetId, WidgetMut, default_styles,
|
||||
render_text,
|
||||
|
@ -578,24 +578,23 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
event: &TextEvent,
|
||||
) {
|
||||
match event {
|
||||
TextEvent::KeyboardKey(key_event, modifiers_state) => {
|
||||
if !key_event.state.is_pressed() || self.editor.is_composing() {
|
||||
TextEvent::KeyboardKey(key_event, modifiers_state, key_text) => {
|
||||
if key_event.state != KeyState::Down || self.editor.is_composing() {
|
||||
return;
|
||||
}
|
||||
#[allow(unused)]
|
||||
let (shift, action_mod) = (
|
||||
modifiers_state.shift_key(),
|
||||
modifiers_state.shift(),
|
||||
if cfg!(target_os = "macos") {
|
||||
modifiers_state.super_key()
|
||||
modifiers_state.meta()
|
||||
} else {
|
||||
modifiers_state.control_key()
|
||||
modifiers_state.ctrl()
|
||||
},
|
||||
);
|
||||
let (fctx, lctx) = ctx.text_contexts();
|
||||
// Whether the text was changed.
|
||||
let mut edited = false;
|
||||
// Ideally we'd use key_without_modifiers, but that's broken
|
||||
match &key_event.logical_key {
|
||||
match &key_event.key {
|
||||
// Cut
|
||||
#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
|
||||
Key::Character(x)
|
||||
|
@ -640,7 +639,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.select_all();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::ArrowLeft) => {
|
||||
Key::ArrowLeft => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if action_mod {
|
||||
if shift {
|
||||
|
@ -654,7 +653,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.move_left();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::ArrowRight) => {
|
||||
Key::ArrowRight => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if action_mod {
|
||||
if shift {
|
||||
|
@ -668,7 +667,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.move_right();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::ArrowUp) => {
|
||||
Key::ArrowUp => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if shift {
|
||||
drv.select_up();
|
||||
|
@ -676,7 +675,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.move_up();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::ArrowDown) => {
|
||||
Key::ArrowDown => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if shift {
|
||||
drv.select_down();
|
||||
|
@ -684,7 +683,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.move_down();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::Home) => {
|
||||
Key::Home => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if action_mod {
|
||||
if shift {
|
||||
|
@ -698,7 +697,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.move_to_line_start();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::End) => {
|
||||
Key::End => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if action_mod {
|
||||
if shift {
|
||||
|
@ -712,7 +711,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
drv.move_to_line_end();
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::Delete) if EDITABLE => {
|
||||
Key::Delete if EDITABLE => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if action_mod {
|
||||
drv.delete_word();
|
||||
|
@ -722,7 +721,7 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
|
||||
edited = true;
|
||||
}
|
||||
Key::Named(NamedKey::Backspace) if EDITABLE => {
|
||||
Key::Backspace if EDITABLE => {
|
||||
let mut drv = self.editor.driver(fctx, lctx);
|
||||
if action_mod {
|
||||
drv.backdelete_word();
|
||||
|
@ -732,13 +731,13 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
|
||||
edited = true;
|
||||
}
|
||||
Key::Named(NamedKey::Space) if EDITABLE => {
|
||||
Key::Character(sp) if EDITABLE && sp.as_str() == " " => {
|
||||
self.editor
|
||||
.driver(fctx, lctx)
|
||||
.insert_or_replace_selection(" ");
|
||||
edited = true;
|
||||
}
|
||||
Key::Named(NamedKey::Enter) => {
|
||||
Key::Enter => {
|
||||
// TODO: Multiline?
|
||||
let multiline = false;
|
||||
if multiline {
|
||||
|
@ -754,12 +753,12 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
}
|
||||
}
|
||||
|
||||
Key::Named(NamedKey::Tab) => {
|
||||
Key::Tab => {
|
||||
// Intentionally do nothing so that tabbing from a textbox/Prose works.
|
||||
// Note that this doesn't allow input of the tab character; we need to be more clever here at some point
|
||||
return;
|
||||
}
|
||||
_ if EDITABLE => match &key_event.text {
|
||||
_ if EDITABLE => match &key_text {
|
||||
Some(text) => {
|
||||
self.editor
|
||||
.driver(fctx, lctx)
|
||||
|
@ -801,10 +800,10 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
// We don't send a TextChanged when the preedit changes
|
||||
let mut edited = false;
|
||||
match e {
|
||||
winit::event::Ime::Disabled => {
|
||||
Ime::Disabled => {
|
||||
self.editor.driver(fctx, lctx).clear_compose();
|
||||
}
|
||||
winit::event::Ime::Preedit(text, cursor) => {
|
||||
Ime::Preedit(text, cursor) => {
|
||||
if text.is_empty() {
|
||||
self.editor.driver(fctx, lctx).clear_compose();
|
||||
} else {
|
||||
|
@ -812,13 +811,13 @@ impl<const EDITABLE: bool> Widget for TextArea<EDITABLE> {
|
|||
edited = true;
|
||||
}
|
||||
}
|
||||
winit::event::Ime::Commit(text) => {
|
||||
Ime::Commit(text) => {
|
||||
self.editor
|
||||
.driver(fctx, lctx)
|
||||
.insert_or_replace_selection(text);
|
||||
edited = true;
|
||||
}
|
||||
winit::event::Ime::Enabled => {}
|
||||
Ime::Enabled => {}
|
||||
}
|
||||
|
||||
ctx.set_handled();
|
||||
|
|
Loading…
Reference in New Issue