Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor winit key handling #21250

Merged
merged 1 commit into from Jul 30, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -367,10 +367,8 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {

(EmbedderMsg::KeyEvent(ch, key, state, modified),
ShutdownState::NotShuttingDown) => {
if state == KeyState::Pressed {
let event = (top_level_browsing_context, EmbedderMsg::KeyEvent(ch, key, state, modified));
self.embedder_events.push(event);
}
let event = (top_level_browsing_context, EmbedderMsg::KeyEvent(ch, key, state, modified));
self.embedder_events.push(event);
},

(msg, ShutdownState::NotShuttingDown) => {
@@ -85,89 +85,92 @@ impl Browser {

/// Handle key events before sending them to Servo.
fn handle_key_from_window(&mut self, ch: Option<char>, key: Key, state: KeyState, mods: KeyModifiers) {
match (mods, ch, key) {
(CMD_OR_CONTROL, Some('r'), _) => {
if let Some(id) = self.browser_id {
self.event_queue.push(WindowEvent::Reload(id));
}
let pressed = state == KeyState::Pressed;
// We don't match the state in the parent `match` because we don't want to do anything
// on KeyState::Released when it's a combo that we handle on Pressed. For example,
// if we catch Alt-Left on pressed, we don't want the Release event to be sent to Servo.
match (mods, ch, key, self.browser_id) {
(CMD_OR_CONTROL, _, Key::R, Some(id)) => if pressed {
self.event_queue.push(WindowEvent::Reload(id));
}
(CMD_OR_CONTROL, Some('l'), _) => {
if let Some(id) = self.browser_id {
let url: String = if let Some(ref current_url) = self.current_url {
current_url.to_string()
} else {
String::from("")
};
let title = "URL or search query";
if let Some(input) = get_url_input(title, &url) {
if let Some(url) = sanitize_url(&input) {
self.event_queue.push(WindowEvent::LoadUrl(id, url));
}
(CMD_OR_CONTROL, _, Key::L, Some(id)) => if pressed {
let url: String = if let Some(ref current_url) = self.current_url {
current_url.to_string()
} else {
String::from("")
};
let title = "URL or search query";
if let Some(input) = get_url_input(title, &url) {
if let Some(url) = sanitize_url(&input) {
self.event_queue.push(WindowEvent::LoadUrl(id, url));
}
}
}
(CMD_OR_CONTROL, Some('q'), _) => {
(CMD_OR_CONTROL, _, Key::Q, _) => if pressed {
self.event_queue.push(WindowEvent::Quit);
}
(_, Some('3'), _) if mods ^ KeyModifiers::CONTROL == KeyModifiers::SHIFT => {
(_, Some('3'), _, _) if mods ^ KeyModifiers::CONTROL == KeyModifiers::SHIFT => if pressed {
self.event_queue.push(WindowEvent::CaptureWebRender);
}
(KeyModifiers::CONTROL, None, Key::F10) => {
(KeyModifiers::CONTROL, None, Key::F10, _) => if pressed {
let event = WindowEvent::ToggleWebRenderDebug(WebRenderDebugOption::RenderTargetDebug);
self.event_queue.push(event);
}
(KeyModifiers::CONTROL, None, Key::F11) => {
(KeyModifiers::CONTROL, None, Key::F11, _) => if pressed {
let event = WindowEvent::ToggleWebRenderDebug(WebRenderDebugOption::TextureCacheDebug);
self.event_queue.push(event);
}
(KeyModifiers::CONTROL, None, Key::F12) => {
(KeyModifiers::CONTROL, None, Key::F12, _) => if pressed {
let event = WindowEvent::ToggleWebRenderDebug(WebRenderDebugOption::Profiler);
self.event_queue.push(event);
}
(CMD_OR_ALT, None, Key::Right) | (KeyModifiers::NONE, None, Key::NavigateForward) => {
if let Some(id) = self.browser_id {
let event = WindowEvent::Navigation(id, TraversalDirection::Forward(1));
self.event_queue.push(event);
}
(CMD_OR_ALT, None, Key::Right, Some(id)) |
(KeyModifiers::NONE, None, Key::NavigateForward, Some(id)) => if pressed {
let event = WindowEvent::Navigation(id, TraversalDirection::Forward(1));
self.event_queue.push(event);
}
(CMD_OR_ALT, None, Key::Left) | (KeyModifiers::NONE, None, Key::NavigateBackward) => {
if let Some(id) = self.browser_id {
let event = WindowEvent::Navigation(id, TraversalDirection::Back(1));
self.event_queue.push(event);
}
(CMD_OR_ALT, None, Key::Left, Some(id)) |
(KeyModifiers::NONE, None, Key::NavigateBackward, Some(id)) => if pressed {
let event = WindowEvent::Navigation(id, TraversalDirection::Back(1));
self.event_queue.push(event);
}
(KeyModifiers::NONE, None, Key::Escape) => {
(KeyModifiers::NONE, None, Key::Escape, _) => if pressed {
self.event_queue.push(WindowEvent::Quit);
}
_ => {
let event = self.platform_handle_key(key, mods);
self.event_queue.push(event.unwrap_or(WindowEvent::KeyEvent(ch, key, state, mods)));
self.platform_handle_key(ch, key, mods, state);
}
}

}

#[cfg(not(target_os = "win"))]
fn platform_handle_key(&self, key: Key, mods: KeyModifiers) -> Option<WindowEvent> {
fn platform_handle_key(&mut self, ch: Option<char>, key: Key, mods: KeyModifiers, state: KeyState) {
let pressed = state == KeyState::Pressed;
match (mods, key, self.browser_id) {
(CMD_OR_CONTROL, Key::LeftBracket, Some(id)) => {
Some(WindowEvent::Navigation(id, TraversalDirection::Back(1)))
(CMD_OR_CONTROL, Key::LeftBracket, Some(id)) => if pressed {
let event = WindowEvent::Navigation(id, TraversalDirection::Back(1));
self.event_queue.push(event);
}
(CMD_OR_CONTROL, Key::RightBracket, Some(id)) => {
Some(WindowEvent::Navigation(id, TraversalDirection::Forward(1)))
(CMD_OR_CONTROL, Key::RightBracket, Some(id)) => if pressed {
let event = WindowEvent::Navigation(id, TraversalDirection::Back(1));
self.event_queue.push(event);
}
_ => {
self.event_queue.push(WindowEvent::KeyEvent(ch, key, state, mods));
}
_ => None
}
}

#[cfg(target_os = "win")]
fn platform_handle_key(&self, key: Key, mods: KeyModifiers) -> Option<WindowEvent> {
None
fn platform_handle_key(&mut self, _ch: Option<char>, _key: Key, _mods: KeyModifiers, _state: KeyState) {
}

/// Handle key events after they have been handled by Servo.
fn handle_key_from_servo(&mut self, _: Option<BrowserId>, ch: Option<char>,
key: Key, _: KeyState, mods: KeyModifiers) {
key: Key, state: KeyState, mods: KeyModifiers) {
if state == KeyState::Pressed {
return;
}
match (mods, ch, key) {
(_, Some('+'), _) => {
if mods & !KeyModifiers::SHIFT == CMD_OR_CONTROL {
@@ -329,23 +329,3 @@ pub fn is_printable(key_code: VirtualKeyCode) -> bool {
}
}

/// Detect if given char is default ignorable in unicode
/// http://www.unicode.org/L2/L2002/02368-default-ignorable.pdf
pub fn is_identifier_ignorable(ch: &char) -> bool {
match *ch {
'\u{0000}'...'\u{0008}' | '\u{000E}'...'\u{001F}' |
'\u{007F}'...'\u{0084}' | '\u{0086}'...'\u{009F}' |
'\u{06DD}' | '\u{070F}' |
'\u{180B}'...'\u{180D}' | '\u{180E}' |
'\u{200C}'...'\u{200F}' |
'\u{202A}'...'\u{202E}' | '\u{2060}'...'\u{2063}' |
'\u{2064}'...'\u{2069}' | '\u{206A}'...'\u{206F}' |
'\u{FE00}'...'\u{FE0F}' | '\u{FEFF}' |
'\u{FFF0}'...'\u{FFF8}' | '\u{FFF9}'...'\u{FFFB}' |
'\u{1D173}'...'\u{1D17A}' | '\u{E0000}' |
'\u{E0001}' |
'\u{E0002}'...'\u{E001F}' | '\u{E0020}'...'\u{E007F}' |
'\u{E0080}'...'\u{E0FFF}' => true,
_ => false
}
}
@@ -412,29 +412,23 @@ impl Window {
}

fn handle_received_character(&self, ch: char) {
let modifiers = keyutils::winit_mods_to_script_mods(self.key_modifiers.get());
if keyutils::is_identifier_ignorable(&ch) {
return
}
if let Some(last_pressed_key) = self.last_pressed_key.get() {
let event = WindowEvent::KeyEvent(Some(ch), last_pressed_key, KeyState::Pressed, modifiers);
self.event_queue.borrow_mut().push(event);
let last_key = if let Some(key) = self.last_pressed_key.get() {
key
} else {
// Only send the character if we can print it (by ignoring characters like backspace)
if !ch.is_control() {
match keyutils::char_to_script_key(ch) {
Some(key) => {
let event = WindowEvent::KeyEvent(Some(ch),
key,
KeyState::Pressed,
modifiers);
self.event_queue.borrow_mut().push(event);
}
None => {}
}
}
}
return;
};

self.last_pressed_key.set(None);

let (key, ch) = if let Some(key) = keyutils::char_to_script_key(ch) {
(key, Some(ch))
} else {
(last_key, None)
};

let modifiers = keyutils::winit_mods_to_script_mods(self.key_modifiers.get());
let event = WindowEvent::KeyEvent(ch, key, KeyState::Pressed, modifiers);
self.event_queue.borrow_mut().push(event);
}

fn toggle_keyboard_modifiers(&self, virtual_key_code: VirtualKeyCode) {
@@ -459,13 +453,14 @@ impl Window {
ElementState::Pressed => KeyState::Pressed,
ElementState::Released => KeyState::Released,
};
if element_state == ElementState::Pressed {
if keyutils::is_printable(virtual_key_code) {
self.last_pressed_key.set(Some(key));
}
if element_state == ElementState::Pressed && keyutils::is_printable(virtual_key_code) {
// If pressed and printable, we expect a ReceivedCharacter event.
self.last_pressed_key.set(Some(key));
} else {
self.last_pressed_key.set(None);
let modifiers = keyutils::winit_mods_to_script_mods(self.key_modifiers.get());
self.event_queue.borrow_mut().push(WindowEvent::KeyEvent(None, key, state, modifiers));
}
let modifiers = keyutils::winit_mods_to_script_mods(self.key_modifiers.get());
self.event_queue.borrow_mut().push(WindowEvent::KeyEvent(None, key, state, modifiers));
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.