Make textinput handle actual key values. Don't restrict character values to a single byte.

This commit is contained in:
Josh Matthews 2016-06-30 12:41:09 -04:00
parent 04ce86c08c
commit 6496d73210
12 changed files with 123 additions and 72 deletions

View file

@ -17,6 +17,7 @@ use libc::{c_double, c_int};
use msg::constellation_msg::{self, KeyModifiers, KeyState};
use script_traits::{MouseButton, TouchEventType};
use std::cell::{Cell, RefCell};
use std::char;
pub struct ServoCefBrowserHost {
/// A reference to the browser.
@ -424,7 +425,8 @@ full_cef_class_impl! {
if (*event).modifiers & EVENTFLAG_ALT_DOWN as u32 != 0 {
key_modifiers = key_modifiers | constellation_msg::ALT;
}
this.downcast().send_window_event(WindowEvent::KeyEvent(key, key_state, key_modifiers))
let ch = char::from_u32((*event).character as u32);
this.downcast().send_window_event(WindowEvent::KeyEvent(ch, key, key_state, key_modifiers))
}}
fn send_mouse_click_event(&this,

View file

@ -479,7 +479,7 @@ impl WindowMethods for Window {
}
}
fn handle_key(&self, _: Key, _: KeyModifiers) {
fn handle_key(&self, _: Option<char>, _: Key, _: KeyModifiers) {
// TODO(negge)
}

View file

@ -242,9 +242,8 @@ impl Window {
fn handle_window_event(&self, event: glutin::Event) -> bool {
match event {
Event::ReceivedCharacter(ch) => {
// Glutin ends up providing non-printable characters like escape and backspace,
// which is no good for trying to figure out the logical key that was pressed.
if !ch.is_control() && ch.len_utf8() == 1 {
assert!(self.pending_key_event_char.get().is_none());
if !ch.is_control() {
self.pending_key_event_char.set(Some(ch));
}
}
@ -266,7 +265,9 @@ impl Window {
// Retrieve any previosly stored ReceivedCharacter value.
// Store the association between the scan code and the actual
// character value, if there is one.
let ch = self.pending_key_event_char.get();
let ch = self.pending_key_event_char
.get()
.and_then(|ch| filter_nonprintable(ch, virtual_key_code));
self.pending_key_event_char.set(None);
if let Some(ch) = ch {
self.pressed_key_map.borrow_mut().push((scan_code, ch));
@ -962,6 +963,77 @@ fn glutin_pressure_stage_to_touchpad_pressure_phase(stage: i64) -> TouchpadPress
}
}
fn filter_nonprintable(ch: char, key_code: VirtualKeyCode) -> Option<char> {
use glutin::VirtualKeyCode::*;
match key_code {
Escape |
F1 |
F2 |
F3 |
F4 |
F5 |
F6 |
F7 |
F8 |
F9 |
F10 |
F11 |
F12 |
F13 |
F14 |
F15 |
Snapshot |
Scroll |
Pause |
Insert |
Home |
Delete |
End |
PageDown |
PageUp |
Left |
Up |
Right |
Down |
Back |
LAlt |
LControl |
LMenu |
LShift |
LWin |
Mail |
MediaSelect |
MediaStop |
Mute |
MyComputer |
NavigateForward |
NavigateBackward |
NextTrack |
NoConvert |
PlayPause |
Power |
PrevTrack |
RAlt |
RControl |
RMenu |
RShift |
RWin |
Sleep |
Stop |
VolumeDown |
VolumeUp |
Wake |
WebBack |
WebFavorites |
WebForward |
WebHome |
WebRefresh |
WebSearch |
WebStop => None,
_ => Some(ch),
}
}
// These functions aren't actually called. They are here as a link
// hack because Skia references them.