mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Associate logical and physical keypresses together to support non-QWERTY keyboards.
This commit is contained in:
parent
87c7772527
commit
04ce86c08c
15 changed files with 137 additions and 77 deletions
|
@ -5,7 +5,7 @@
|
|||
//! The `ByteString` struct.
|
||||
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::ToOwned;
|
||||
use std::borrow::{ToOwned, Cow};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops;
|
||||
|
@ -204,6 +204,15 @@ impl<'a> From<&'a str> for DOMString {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Cow<'a, str>> for DOMString {
|
||||
fn from(contents: Cow<'a, str>) -> DOMString {
|
||||
match contents {
|
||||
Cow::Owned(s) => DOMString::from(s),
|
||||
Cow::Borrowed(s) => DOMString::from(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DOMString> for Atom {
|
||||
fn from(contents: DOMString) -> Atom {
|
||||
Atom::from(contents.0)
|
||||
|
|
|
@ -1044,6 +1044,7 @@ impl Document {
|
|||
|
||||
/// The entry point for all key processing for web content
|
||||
pub fn dispatch_key_event(&self,
|
||||
ch: Option<char>,
|
||||
key: Key,
|
||||
state: KeyState,
|
||||
modifiers: KeyModifiers,
|
||||
|
@ -1070,7 +1071,7 @@ impl Document {
|
|||
}
|
||||
.to_owned());
|
||||
|
||||
let props = KeyboardEvent::key_properties(key, modifiers);
|
||||
let props = KeyboardEvent::key_properties(ch, key, modifiers);
|
||||
|
||||
let keyevent = KeyboardEvent::new(&self.window,
|
||||
ev_type,
|
||||
|
@ -1078,8 +1079,9 @@ impl Document {
|
|||
true,
|
||||
Some(&self.window),
|
||||
0,
|
||||
ch,
|
||||
Some(key),
|
||||
DOMString::from(props.key_string),
|
||||
DOMString::from(props.key_string.clone()),
|
||||
DOMString::from(props.code),
|
||||
props.location,
|
||||
is_repeating,
|
||||
|
@ -1103,6 +1105,7 @@ impl Document {
|
|||
true,
|
||||
Some(&self.window),
|
||||
0,
|
||||
ch,
|
||||
Some(key),
|
||||
DOMString::from(props.key_string),
|
||||
DOMString::from(props.code),
|
||||
|
@ -1122,7 +1125,7 @@ impl Document {
|
|||
}
|
||||
|
||||
if !prevented {
|
||||
constellation.send(ConstellationMsg::SendKeyEvent(key, state, modifiers)).unwrap();
|
||||
constellation.send(ConstellationMsg::SendKeyEvent(key, state, modifiers, ch)).unwrap();
|
||||
}
|
||||
|
||||
// This behavior is unspecced
|
||||
|
|
|
@ -17,6 +17,7 @@ use dom::uievent::UIEvent;
|
|||
use dom::window::Window;
|
||||
use msg::constellation_msg;
|
||||
use msg::constellation_msg::{Key, KeyModifiers};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::Cell;
|
||||
|
||||
no_jsmanaged_fields!(Key);
|
||||
|
@ -69,6 +70,7 @@ impl KeyboardEvent {
|
|||
cancelable: bool,
|
||||
view: Option<&Window>,
|
||||
_detail: i32,
|
||||
ch: Option<char>,
|
||||
key: Option<Key>,
|
||||
key_string: DOMString,
|
||||
code: DOMString,
|
||||
|
@ -84,7 +86,7 @@ impl KeyboardEvent {
|
|||
let ev = KeyboardEvent::new_uninitialized(window);
|
||||
ev.InitKeyboardEvent(type_, canBubble, cancelable, view, key_string, location,
|
||||
DOMString::new(), repeat, DOMString::new());
|
||||
ev.key.set(key);
|
||||
ev.key.set(logical_key(ch, key, location));
|
||||
*ev.code.borrow_mut() = code;
|
||||
ev.ctrl.set(ctrlKey);
|
||||
ev.alt.set(altKey);
|
||||
|
@ -103,7 +105,9 @@ impl KeyboardEvent {
|
|||
init.parent.parent.parent.bubbles,
|
||||
init.parent.parent.parent.cancelable,
|
||||
init.parent.parent.view.r(),
|
||||
init.parent.parent.detail, key_from_string(&init.key, init.location),
|
||||
init.parent.parent.detail,
|
||||
None,
|
||||
key_from_string(&init.key, init.location),
|
||||
init.key.clone(), init.code.clone(), init.location,
|
||||
init.repeat, init.isComposing, init.parent.ctrlKey,
|
||||
init.parent.altKey, init.parent.shiftKey, init.parent.metaKey,
|
||||
|
@ -111,13 +115,13 @@ impl KeyboardEvent {
|
|||
Ok(event)
|
||||
}
|
||||
|
||||
pub fn key_properties(key: Key, mods: KeyModifiers)
|
||||
pub fn key_properties(ch: Option<char>, key: Key, mods: KeyModifiers)
|
||||
-> KeyEventProperties {
|
||||
KeyEventProperties {
|
||||
key_string: key_value(key, mods),
|
||||
key_string: key_value(ch, key, mods),
|
||||
code: code_value(key),
|
||||
location: key_location(key),
|
||||
char_code: key_charcode(key, mods),
|
||||
char_code: ch.map(|ch| ch as u32),
|
||||
key_code: key_keycode(key),
|
||||
}
|
||||
}
|
||||
|
@ -147,11 +151,26 @@ impl KeyboardEvent {
|
|||
}
|
||||
}
|
||||
|
||||
fn logical_key(ch: Option<char>, key: Option<Key>, location: u32) -> Option<Key> {
|
||||
if let Some(ch) = ch {
|
||||
let key = key_from_string(&format!("{}", ch), location);
|
||||
if key.is_some() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
key
|
||||
}
|
||||
|
||||
|
||||
// https://w3c.github.io/uievents-key/#key-value-tables
|
||||
pub fn key_value(key: Key, mods: KeyModifiers) -> &'static str {
|
||||
pub fn key_value(ch: Option<char>, key: Key, mods: KeyModifiers) -> Cow<'static, str> {
|
||||
if let Some(ch) = ch {
|
||||
return Cow::from(format!("{}", ch));
|
||||
}
|
||||
|
||||
let shift = mods.contains(constellation_msg::SHIFT);
|
||||
match key {
|
||||
Cow::from(match key {
|
||||
Key::Space => " ",
|
||||
Key::Apostrophe if shift => "\"",
|
||||
Key::Apostrophe => "'",
|
||||
|
@ -321,7 +340,7 @@ pub fn key_value(key: Key, mods: KeyModifiers) -> &'static str {
|
|||
Key::Menu => "ContextMenu",
|
||||
Key::NavigateForward => "BrowserForward",
|
||||
Key::NavigateBackward => "BrowserBack",
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn key_from_string(key_string: &str, location: u32) -> Option<Key> {
|
||||
|
@ -647,16 +666,6 @@ fn key_location(key: Key) -> u32 {
|
|||
}
|
||||
}
|
||||
|
||||
// https://w3c.github.io/uievents/#dom-keyboardevent-charcode
|
||||
fn key_charcode(key: Key, mods: KeyModifiers) -> Option<u32> {
|
||||
let key_string = key_value(key, mods);
|
||||
if key_string.len() == 1 {
|
||||
Some(key_string.chars().next().unwrap() as u32)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// https://w3c.github.io/uievents/#legacy-key-models
|
||||
fn key_keycode(key: Key) -> u32 {
|
||||
match key {
|
||||
|
@ -739,7 +748,7 @@ fn key_keycode(key: Key) -> u32 {
|
|||
|
||||
#[derive(HeapSizeOf)]
|
||||
pub struct KeyEventProperties {
|
||||
pub key_string: &'static str,
|
||||
pub key_string: Cow<'static, str>,
|
||||
pub code: &'static str,
|
||||
pub location: u32,
|
||||
pub char_code: Option<u32>,
|
||||
|
|
|
@ -1937,12 +1937,12 @@ impl ScriptThread {
|
|||
document.r().handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase);
|
||||
}
|
||||
|
||||
KeyEvent(key, state, modifiers) => {
|
||||
KeyEvent(key, state, modifiers, ch) => {
|
||||
let document = match self.root_browsing_context().find(pipeline_id) {
|
||||
Some(browsing_context) => browsing_context.active_document(),
|
||||
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
|
||||
};
|
||||
document.dispatch_key_event(key, state, modifiers, &self.constellation_chan);
|
||||
document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::str::DOMString;
|
|||
use dom::keyboardevent::{KeyboardEvent, key_value};
|
||||
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
|
||||
use msg::constellation_msg::{Key, KeyModifiers};
|
||||
use std::borrow::ToOwned;
|
||||
use std::borrow::{ToOwned, Borrow};
|
||||
use std::cmp::{max, min};
|
||||
use std::default::Default;
|
||||
use std::ops::Range;
|
||||
|
@ -510,7 +510,7 @@ impl<T: ClipboardProvider> TextInput<T> {
|
|||
KeyReaction::DispatchInput
|
||||
},
|
||||
_ if is_printable_key(key) => {
|
||||
self.insert_string(key_value(key, mods));
|
||||
self.insert_string::<&str>(key_value(None, key, mods).borrow());
|
||||
KeyReaction::DispatchInput
|
||||
}
|
||||
Key::Space => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue