On Orbital, implement KeyEventExtModifiersSupplement
This also fixes `logical_key` and `text` not reported in `KeyEvent`.
This commit is contained in:
parent
20687fef1c
commit
fedb86ea5a
4 changed files with 81 additions and 31 deletions
|
|
@ -50,6 +50,8 @@ Unreleased` header.
|
||||||
- On Wayland, fix `Window::set_{min,max}_inner_size` not always applied.
|
- On Wayland, fix `Window::set_{min,max}_inner_size` not always applied.
|
||||||
- On Windows, fix inconsistent resizing behavior with multi-monitor setups when repositioning outside the event loop.
|
- On Windows, fix inconsistent resizing behavior with multi-monitor setups when repositioning outside the event loop.
|
||||||
- On Wayland, fix `WAYLAND_SOCKET` not used when detecting platform.
|
- On Wayland, fix `WAYLAND_SOCKET` not used when detecting platform.
|
||||||
|
- On Orbital, fix `logical_key` and `text` not reported in `KeyEvent`.
|
||||||
|
- On Orbital, implement `KeyEventExtModifierSupplement`.
|
||||||
|
|
||||||
# 0.29.10
|
# 0.29.10
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ pub mod pump_events;
|
||||||
macos_platform,
|
macos_platform,
|
||||||
x11_platform,
|
x11_platform,
|
||||||
wayland_platform,
|
wayland_platform,
|
||||||
|
orbital_platform,
|
||||||
docsrs
|
docsrs
|
||||||
))]
|
))]
|
||||||
pub mod modifier_supplement;
|
pub mod modifier_supplement;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use orbclient::{
|
||||||
ButtonEvent, EventOption, FocusEvent, HoverEvent, KeyEvent, MouseEvent, MoveEvent, QuitEvent,
|
ButtonEvent, EventOption, FocusEvent, HoverEvent, KeyEvent, MouseEvent, MoveEvent, QuitEvent,
|
||||||
ResizeEvent, ScrollEvent, TextInputEvent,
|
ResizeEvent, ScrollEvent, TextInputEvent,
|
||||||
};
|
};
|
||||||
|
use smol_str::SmolStr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::EventLoopError,
|
error::EventLoopError,
|
||||||
|
|
@ -154,6 +155,22 @@ struct EventState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventState {
|
impl EventState {
|
||||||
|
fn character_all_modifiers(&self, character: char) -> char {
|
||||||
|
// Modify character if Ctrl is pressed
|
||||||
|
#[allow(clippy::collapsible_if)]
|
||||||
|
if self.keyboard.contains(KeyboardModifierState::LCTRL)
|
||||||
|
|| self.keyboard.contains(KeyboardModifierState::RCTRL)
|
||||||
|
{
|
||||||
|
if character.is_ascii_lowercase() {
|
||||||
|
return ((character as u8 - b'a') + 1) as char;
|
||||||
|
}
|
||||||
|
//TODO: more control key variants?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return character as-is if no special handling required
|
||||||
|
character
|
||||||
|
}
|
||||||
|
|
||||||
fn key(&mut self, key: PhysicalKey, pressed: bool) {
|
fn key(&mut self, key: PhysicalKey, pressed: bool) {
|
||||||
let code = match key {
|
let code = match key {
|
||||||
PhysicalKey::Code(code) => code,
|
PhysicalKey::Code(code) => code,
|
||||||
|
|
@ -333,39 +350,61 @@ impl<T: 'static> EventLoop<T> {
|
||||||
{
|
{
|
||||||
match event_option {
|
match event_option {
|
||||||
EventOption::Key(KeyEvent {
|
EventOption::Key(KeyEvent {
|
||||||
character: _,
|
character,
|
||||||
scancode,
|
scancode,
|
||||||
pressed,
|
pressed,
|
||||||
}) => {
|
}) => {
|
||||||
if scancode != 0 {
|
let physical_key = convert_scancode(scancode);
|
||||||
let physical_key = convert_scancode(scancode);
|
let modifiers_before = event_state.keyboard;
|
||||||
let modifiers_before = event_state.keyboard;
|
event_state.key(physical_key, pressed);
|
||||||
event_state.key(physical_key, pressed);
|
let mut logical_key = Key::Unidentified(NativeKey::Unidentified);
|
||||||
|
let mut key_without_modifiers = Key::Unidentified(NativeKey::Unidentified);
|
||||||
|
let mut text = None;
|
||||||
|
let mut text_with_all_modifiers = None;
|
||||||
|
if character != '\0' {
|
||||||
|
let mut tmp = [0u8; 4];
|
||||||
|
let character_str = character.encode_utf8(&mut tmp);
|
||||||
|
// The key with Shift and Caps Lock applied (but not Ctrl)
|
||||||
|
logical_key = Key::Character(character_str.into());
|
||||||
|
// The key without Shift or Caps Lock applied
|
||||||
|
key_without_modifiers =
|
||||||
|
Key::Character(SmolStr::from_iter(character.to_lowercase()));
|
||||||
|
if pressed {
|
||||||
|
// The key with Shift and Caps Lock applied (but not Ctrl)
|
||||||
|
text = Some(character_str.into());
|
||||||
|
// The key with Shift, Caps Lock, and Ctrl applied
|
||||||
|
let character_all_modifiers =
|
||||||
|
event_state.character_all_modifiers(character);
|
||||||
|
text_with_all_modifiers =
|
||||||
|
Some(character_all_modifiers.encode_utf8(&mut tmp).into())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
event_handler(event::Event::WindowEvent {
|
||||||
|
window_id: RootWindowId(window_id),
|
||||||
|
event: event::WindowEvent::KeyboardInput {
|
||||||
|
device_id: event::DeviceId(DeviceId),
|
||||||
|
event: event::KeyEvent {
|
||||||
|
logical_key,
|
||||||
|
physical_key,
|
||||||
|
location: KeyLocation::Standard,
|
||||||
|
state: element_state(pressed),
|
||||||
|
repeat: false,
|
||||||
|
text,
|
||||||
|
platform_specific: KeyEventExtra {
|
||||||
|
key_without_modifiers,
|
||||||
|
text_with_all_modifiers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
is_synthetic: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the state of the modifiers has changed, send the event.
|
||||||
|
if modifiers_before != event_state.keyboard {
|
||||||
event_handler(event::Event::WindowEvent {
|
event_handler(event::Event::WindowEvent {
|
||||||
window_id: RootWindowId(window_id),
|
window_id: RootWindowId(window_id),
|
||||||
event: event::WindowEvent::KeyboardInput {
|
event: event::WindowEvent::ModifiersChanged(event_state.modifiers()),
|
||||||
device_id: event::DeviceId(DeviceId),
|
})
|
||||||
event: event::KeyEvent {
|
|
||||||
logical_key: Key::Unidentified(NativeKey::Unidentified),
|
|
||||||
physical_key,
|
|
||||||
location: KeyLocation::Standard,
|
|
||||||
state: element_state(pressed),
|
|
||||||
repeat: false,
|
|
||||||
text: None,
|
|
||||||
|
|
||||||
platform_specific: KeyEventExtra {},
|
|
||||||
},
|
|
||||||
is_synthetic: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// If the state of the modifiers has changed, send the event.
|
|
||||||
if modifiers_before != event_state.keyboard {
|
|
||||||
event_handler(event::Event::WindowEvent {
|
|
||||||
window_id: RootWindowId(window_id),
|
|
||||||
event: event::WindowEvent::ModifiersChanged(event_state.modifiers()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EventOption::TextInput(TextInputEvent { character }) => {
|
EventOption::TextInput(TextInputEvent { character }) => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,12 @@ use std::fmt::{self, Display, Formatter};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
use smol_str::SmolStr;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
dpi::{PhysicalPosition, PhysicalSize},
|
||||||
|
keyboard::Key,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) use self::event_loop::{
|
pub(crate) use self::event_loop::{
|
||||||
EventLoop, EventLoopProxy, EventLoopWindowTarget, OwnedDisplayHandle,
|
EventLoop, EventLoopProxy, EventLoopWindowTarget, OwnedDisplayHandle,
|
||||||
|
|
@ -263,5 +268,8 @@ impl VideoModeHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct KeyEventExtra {}
|
pub struct KeyEventExtra {
|
||||||
|
pub key_without_modifiers: Key,
|
||||||
|
pub text_with_all_modifiers: Option<SmolStr>,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue