aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2016-07-30 12:47:22 -0700
committerJoe Wilm <joe@jwilm.com>2016-07-30 12:52:53 -0700
commit66e7228f41a9fef79fec2cf57d8e9ac92e936855 (patch)
tree498421f6bc1ebeb06d39c8b901d45ff4c90a1b6b
parentc687eca3fadef5d64daf5fce5582e0037c45d5b4 (diff)
downloadalacritty-66e7228f41a9fef79fec2cf57d8e9ac92e936855.tar.gz
alacritty-66e7228f41a9fef79fec2cf57d8e9ac92e936855.zip
Input expects modifier keys from Glutin
This is experimental on a separate branch of Glutin. It's intended to fix the problem of certain key events not being delivered on alt-tab and breaking the modifier state tracking.
-rw-r--r--Cargo.lock5
-rw-r--r--Cargo.toml7
-rw-r--r--src/input.rs202
-rw-r--r--src/main.rs3
4 files changed, 71 insertions, 146 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 72ba3110..1c80b490 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,7 +7,7 @@ dependencies = [
"errno 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"font 0.1.0",
"gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "glutin 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glutin 0.6.1 (git+https://github.com/jwilm/glutin?rev=d287fa96e3a8b2568b189067eedd28807c4568d6)",
"libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 2.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -285,9 +285,10 @@ dependencies = [
[[package]]
name = "glutin"
version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+source = "git+https://github.com/jwilm/glutin?rev=d287fa96e3a8b2568b189067eedd28807c4568d6#d287fa96e3a8b2568b189067eedd28807c4568d6"
dependencies = [
"android_glue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 0430f625..dc9b62a9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,8 +22,5 @@ serde_macros = "0.7"
gl_generator = "0.5"
[dependencies.glutin]
-version = "*"
-# git = "https://github.com/jwilm/glutin"
-# rev = "c95e6973ace3cbf321123a64588b27f032675be9"
-# version = "*"
-# path = "../glutin"
+git = "https://github.com/jwilm/glutin"
+rev = "d287fa96e3a8b2568b189067eedd28807c4568d6"
diff --git a/src/input.rs b/src/input.rs
index 3dba1a64..d859abd1 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -26,72 +26,10 @@
use std::io::Write;
use glutin::{ElementState, VirtualKeyCode};
+use glutin::{Mods, mods};
use term::mode::{self, TermMode};
-/// Modifier keys
-///
-/// Contains a bitflags for modifier keys which are now namespaced thanks to
-/// this module wrapper.
-mod modifier {
- use glutin::ElementState;
-
- bitflags! {
- /// Flags indicating active modifier keys
- pub flags Keys: u8 {
- /// Left shift
- const SHIFT_LEFT = 0b00000001,
- /// Right shift
- const SHIFT_RIGHT = 0b00000010,
- /// Left meta
- const META_LEFT = 0b00000100,
- /// Right meta
- const META_RIGHT = 0b00001000,
- /// Left control
- const CONTROL_LEFT = 0b00010000,
- /// Right control
- const CONTROL_RIGHT = 0b00100000,
- /// Left alt
- const ALT_LEFT = 0b01000000,
- /// Right alt
- const ALT_RIGHT = 0b10000000,
- /// Any shift key
- const SHIFT = SHIFT_LEFT.bits
- | SHIFT_RIGHT.bits,
- /// Any control key
- const CONTROL = CONTROL_LEFT.bits
- | CONTROL_RIGHT.bits,
- /// Any alt key
- const ALT = ALT_LEFT.bits
- | ALT_RIGHT.bits,
- /// Any meta key
- const META = META_LEFT.bits
- | META_RIGHT.bits,
- /// Any mod
- const ANY = 0b11111111,
- /// No mod
- const NONE = 0b00000000,
- }
- }
-
- impl Default for Keys {
- fn default() -> Keys {
- Keys::empty()
- }
- }
-
- impl Keys {
- /// Take appropriate action given a modifier key and its state
- #[inline]
- pub fn update(&mut self, state: ElementState, key: Keys) {
- match state {
- ElementState::Pressed => self.insert(key),
- ElementState::Released => self.remove(key),
- }
- }
- }
-}
-
/// Processes input from glutin.
///
/// An escape sequence may be emitted in case specific keys or key combinations
@@ -99,10 +37,7 @@ mod modifier {
///
/// TODO also need terminal state when processing input
#[derive(Default)]
-pub struct Processor {
- /// Active modifier keys
- mods: modifier::Keys,
-}
+pub struct Processor;
/// Types that are notified of escape sequences from the input::Processor.
pub trait Notify {
@@ -125,7 +60,7 @@ impl<'a, W: Write> Notify for WriteNotifier<'a, W> {
#[derive(Debug)]
pub struct Binding {
/// Modifier keys required to activate binding
- mods: modifier::Keys,
+ mods: Mods,
/// String to send to pty if mods and mode match
send: &'static str,
/// Terminal mode required to activate binding
@@ -136,98 +71,98 @@ pub struct Binding {
/// Bindings for the LEFT key.
static LEFT_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::SHIFT, send: "\x1b[1;2D", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::CONTROL, send: "\x1b[1;5D", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ALT, send: "\x1b[1;3D", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ANY, send: "\x1b[D", mode: mode::ANY, notmode: mode::APP_CURSOR },
- Binding { mods: modifier::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ Binding { mods: mods::SHIFT, send: "\x1b[1;2D", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::CONTROL, send: "\x1b[1;5D", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ALT, send: "\x1b[1;3D", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[D", mode: mode::ANY, notmode: mode::APP_CURSOR },
+ Binding { mods: mods::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
];
/// Bindings for the RIGHT key
static RIGHT_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::SHIFT, send: "\x1b[1;2C", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::CONTROL, send: "\x1b[1;5C", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ALT, send: "\x1b[1;3C", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ANY, send: "\x1b[C", mode: mode::ANY, notmode: mode::APP_CURSOR },
- Binding { mods: modifier::ANY, send: "\x1bOC", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ Binding { mods: mods::SHIFT, send: "\x1b[1;2C", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::CONTROL, send: "\x1b[1;5C", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ALT, send: "\x1b[1;3C", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[C", mode: mode::ANY, notmode: mode::APP_CURSOR },
+ Binding { mods: mods::ANY, send: "\x1bOC", mode: mode::APP_CURSOR, notmode: mode::NONE },
];
/// Bindings for the UP key
static UP_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::SHIFT, send: "\x1b[1;2A", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::CONTROL, send: "\x1b[1;5A", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ALT, send: "\x1b[1;3A", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ANY, send: "\x1b[A", mode: mode::ANY, notmode: mode::APP_CURSOR },
- Binding { mods: modifier::ANY, send: "\x1bOA", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ Binding { mods: mods::SHIFT, send: "\x1b[1;2A", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::CONTROL, send: "\x1b[1;5A", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ALT, send: "\x1b[1;3A", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[A", mode: mode::ANY, notmode: mode::APP_CURSOR },
+ Binding { mods: mods::ANY, send: "\x1bOA", mode: mode::APP_CURSOR, notmode: mode::NONE },
];
/// Bindings for the DOWN key
static DOWN_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::SHIFT, send: "\x1b[1;2B", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::CONTROL, send: "\x1b[1;5B", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ALT, send: "\x1b[1;3B", mode: mode::ANY, notmode: mode::NONE },
- Binding { mods: modifier::ANY, send: "\x1b[B", mode: mode::ANY, notmode: mode::APP_CURSOR },
- Binding { mods: modifier::ANY, send: "\x1bOB", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ Binding { mods: mods::SHIFT, send: "\x1b[1;2B", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::CONTROL, send: "\x1b[1;5B", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ALT, send: "\x1b[1;3B", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[B", mode: mode::ANY, notmode: mode::APP_CURSOR },
+ Binding { mods: mods::ANY, send: "\x1bOB", mode: mode::APP_CURSOR, notmode: mode::NONE },
];
/// Bindings for the F1 key
static F1_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1bOP", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1bOP", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F2 key
static F2_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1bOQ", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1bOQ", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F3 key
static F3_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1bOR", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1bOR", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F4 key
static F4_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1bOS", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1bOS", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F5 key
static F5_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[15~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[15~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F6 key
static F6_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[17~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[17~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F7 key
static F7_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[18~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[18~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F8 key
static F8_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[19~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[19~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F9 key
static F9_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[20~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[20~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F10 key
static F10_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[21~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[21~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F11 key
static F11_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[23~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[23~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the F11 key
static F12_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[24~", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[24~", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the H key
@@ -236,18 +171,18 @@ static F12_BINDINGS: &'static [Binding] = &[
/// since DEL and BACKSPACE are inverted. This binding is a work around to that
/// capture.
static H_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::CONTROL, send: "\x08", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::CONTROL, send: "\x08", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the Backspace key
static BACKSPACE_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x7f", mode: mode::ANY, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x7f", mode: mode::ANY, notmode: mode::NONE },
];
/// Bindings for the Delete key
static DELETE_BINDINGS: &'static [Binding] = &[
- Binding { mods: modifier::ANY, send: "\x1b[3~", mode: mode::APP_KEYPAD, notmode: mode::NONE },
- Binding { mods: modifier::ANY, send: "\x1b[P", mode: mode::ANY, notmode: mode::APP_KEYPAD },
+ Binding { mods: mods::ANY, send: "\x1b[3~", mode: mode::APP_KEYPAD, notmode: mode::NONE },
+ Binding { mods: mods::ANY, send: "\x1b[P", mode: mode::ANY, notmode: mode::APP_KEYPAD },
];
// key mods escape appkey appcursor crlf
@@ -264,25 +199,12 @@ impl Processor {
pub fn process<N>(&mut self,
state: ElementState,
key: Option<VirtualKeyCode>,
+ mods: Mods,
notifier: &mut N,
mode: TermMode)
where N: Notify
{
if let Some(key) = key {
-
- // Handle state updates
- match key {
- VirtualKeyCode::LAlt => return self.mods.update(state, modifier::ALT_LEFT),
- VirtualKeyCode::RAlt => return self.mods.update(state, modifier::ALT_RIGHT),
- VirtualKeyCode::LShift => return self.mods.update(state, modifier::SHIFT_LEFT),
- VirtualKeyCode::RShift => return self.mods.update(state, modifier::SHIFT_RIGHT),
- VirtualKeyCode::LControl => return self.mods.update(state, modifier::CONTROL_LEFT),
- VirtualKeyCode::RControl => return self.mods.update(state, modifier::CONTROL_RIGHT),
- VirtualKeyCode::LWin => return self.mods.update(state, modifier::META_LEFT),
- VirtualKeyCode::RWin => return self.mods.update(state, modifier::META_RIGHT),
- _ => ()
- }
-
// Ignore release events
if state == ElementState::Released {
return;
@@ -330,16 +252,20 @@ impl Processor {
// Log something by default
_ => {
println!("Unhandled key: {:?}; state: {:?}; mods: {:?}",
- key, state, self.mods);
+ key, state, mods);
return;
},
};
- self.process_bindings(bindings, mode, notifier);
+ self.process_bindings(bindings, mode, notifier, mods);
}
}
- fn process_bindings<N>(&self, bindings: &[Binding], mode: TermMode, notifier: &mut N)
+ fn process_bindings<N>(&self,
+ bindings: &[Binding],
+ mode: TermMode,
+ notifier: &mut N,
+ mods: Mods)
where N: Notify
{
// Check each binding
@@ -349,7 +275,7 @@ impl Processor {
// TermMode negative
if binding.notmode.is_empty() || !mode.intersects(binding.notmode) {
// Modifier keys
- if binding.mods.is_all() || self.mods.intersects(binding.mods) {
+ if binding.mods.is_all() || mods.intersects(binding.mods) {
// everything matches
notifier.notify(binding.send);
break;
@@ -363,6 +289,7 @@ impl Processor {
#[cfg(test)]
mod tests {
use term::mode::{self, TermMode};
+ use glutin::mods;
use super::Processor;
use super::modifier;
@@ -393,10 +320,9 @@ mod tests {
let bindings = &[$binding];
let mut processor = Processor::new();
- processor.mods.insert($mods);
let mut receiver = Receiver::default();
- processor.process_bindings(bindings, $mode, &mut receiver);
+ processor.process_bindings(bindings, $mode, &mut receiver, $mods);
assert_eq!(receiver.got, $expect);
}
}
@@ -404,57 +330,57 @@ mod tests {
test_process_binding! {
name: process_binding_nomode_shiftmod_require_shift,
- binding: Binding { mods: modifier::SHIFT, send: "\x1b[1;2D", mode: mode::ANY, notmode: mode::NONE },
+ binding: Binding { mods: mods::SHIFT, send: "\x1b[1;2D", mode: mode::ANY, notmode: mode::NONE },
expect: Some(String::from("\x1b[1;2D")),
mode: mode::NONE,
- mods: modifier::SHIFT
+ mods: mods::SHIFT
}
test_process_binding! {
name: process_binding_nomode_nomod_require_shift,
- binding: Binding { mods: modifier::SHIFT, send: "\x1b[1;2D", mode: mode::ANY, notmode: mode::NONE },
+ binding: Binding { mods: mods::SHIFT, send: "\x1b[1;2D", mode: mode::ANY, notmode: mode::NONE },
expect: None,
mode: mode::NONE,
- mods: modifier::NONE
+ mods: mods::NONE
}
test_process_binding! {
name: process_binding_nomode_controlmod,
- binding: Binding { mods: modifier::CONTROL, send: "\x1b[1;5D", mode: mode::ANY, notmode: mode::NONE },
+ binding: Binding { mods: mods::CONTROL, send: "\x1b[1;5D", mode: mode::ANY, notmode: mode::NONE },
expect: Some(String::from("\x1b[1;5D")),
mode: mode::NONE,
- mods: modifier::CONTROL
+ mods: mods::CONTROL
}
test_process_binding! {
name: process_binding_nomode_nomod_require_not_appcursor,
- binding: Binding { mods: modifier::ANY, send: "\x1b[D", mode: mode::ANY, notmode: mode::APP_CURSOR },
+ binding: Binding { mods: mods::ANY, send: "\x1b[D", mode: mode::ANY, notmode: mode::APP_CURSOR },
expect: Some(String::from("\x1b[D")),
mode: mode::NONE,
- mods: modifier::NONE
+ mods: mods::NONE
}
test_process_binding! {
name: process_binding_appcursormode_nomod_require_appcursor,
- binding: Binding { mods: modifier::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ binding: Binding { mods: mods::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
expect: Some(String::from("\x1bOD")),
mode: mode::APP_CURSOR,
- mods: modifier::NONE
+ mods: mods::NONE
}
test_process_binding! {
name: process_binding_nomode_nomod_require_appcursor,
- binding: Binding { mods: modifier::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ binding: Binding { mods: mods::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
expect: None,
mode: mode::NONE,
- mods: modifier::NONE
+ mods: mods::NONE
}
test_process_binding! {
name: process_binding_appcursormode_appkeypadmode_nomod_require_appcursor,
- binding: Binding { mods: modifier::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
+ binding: Binding { mods: mods::ANY, send: "\x1bOD", mode: mode::APP_CURSOR, notmode: mode::NONE },
expect: Some(String::from("\x1bOD")),
mode: mode::APP_CURSOR | mode::APP_KEYPAD,
- mods: modifier::NONE
+ mods: mods::NONE
}
}
diff --git a/src/main.rs b/src/main.rs
index e24ed9f8..2f07ab76 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -242,9 +242,10 @@ fn main() {
glutin::Event::Resized(w, h) => {
new_size = Some((w, h));
},
- glutin::Event::KeyboardInput(state, _code, key) => {
+ glutin::Event::KeyboardInput(state, _code, key, mods) => {
input_processor.process(state,
key,
+ mods,
&mut input::WriteNotifier(&mut writer),
*terminal.mode())
},