aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <chrisduerr@users.noreply.github.com>2018-10-16 18:46:26 +0000
committerGitHub <noreply@github.com>2018-10-16 18:46:26 +0000
commita727801f60286282795e850637de7e21f15d4114 (patch)
treefe2660439e54de2fb4419ae9e4132fb995a8d148
parent15e0deae2b49078b47a782679300cdf99d9ce687 (diff)
downloadalacritty-a727801f60286282795e850637de7e21f15d4114.tar.gz
alacritty-a727801f60286282795e850637de7e21f15d4114.zip
Allow the usage of scancodes in the config
This change should allow the usage of scancodes in the configuration file. When a VirtualKeyCode for glutin is not present, this should now allow the user to use the scancodes instead. If the user specifiecs a key with its scancode even though the key has a VirtualKeyCode, it should still work. The behavior of directly specifying a VirtualKeyCode should be unchanged by this. This fixes #1265.
-rw-r--r--CHANGELOG.md2
-rw-r--r--alacritty.yml6
-rw-r--r--alacritty_macos.yml6
-rw-r--r--src/config.rs342
-rw-r--r--src/event.rs5
-rw-r--r--src/input.rs42
6 files changed, 219 insertions, 184 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7231fb89..397d7c99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,8 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add support for windows
- Add terminfo capabilities advertising support for changing the window title
+- Allow using scancodes in the key_bindings section
### Fixed
+
- Fixed erroneous results when using the `indexed_colors` config option
## Version 0.2.1
diff --git a/alacritty.yml b/alacritty.yml
index 11a9e6ae..63bb7a4b 100644
--- a/alacritty.yml
+++ b/alacritty.yml
@@ -324,6 +324,12 @@ live_config_reload: true
# A full list with available key codes can be found here:
# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants
#
+# Instead of using the name of the keys, the `key` field also supports using
+# the scancode of the desired key. Scancodes have to be specified as a
+# decimal number.
+# This command will allow you to display the hex scancodes for certain keys:
+# `showkey --scancodes`
+#
# Values for `mods`:
# - Command
# - Control
diff --git a/alacritty_macos.yml b/alacritty_macos.yml
index 1feffbd1..b9abc58e 100644
--- a/alacritty_macos.yml
+++ b/alacritty_macos.yml
@@ -321,6 +321,12 @@ live_config_reload: true
# A full list with available key codes can be found here:
# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants
#
+# Instead of using the name of the keys, the `key` field also supports using
+# the scancode of the desired key. Scancodes have to be specified as a
+# decimal number.
+# This command will allow you to display the hex scancodes for certain keys:
+# `showkey --scancodes`
+#
# Values for `mods`:
# - Command
# - Control
diff --git a/src/config.rs b/src/config.rs
index c7d7ea58..069eef0e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -837,7 +837,7 @@ impl<'a> de::Deserialize<'a> for MouseButton {
/// Bindings are deserialized into a `RawBinding` before being parsed as a
/// `KeyBinding` or `MouseBinding`.
struct RawBinding {
- key: Option<::glutin::VirtualKeyCode>,
+ key: Option<Key>,
mouse: Option<::glutin::MouseButton>,
mods: ModifiersState,
mode: TermMode,
@@ -941,7 +941,7 @@ impl<'a> de::Deserialize<'a> for RawBinding {
where V: MapAccess<'a>,
{
let mut mods: Option<ModifiersState> = None;
- let mut key: Option<::glutin::VirtualKeyCode> = None;
+ let mut key: Option<Key> = None;
let mut chars: Option<String> = None;
let mut action: Option<::input::Action> = None;
let mut mode: Option<TermMode> = None;
@@ -958,8 +958,21 @@ impl<'a> de::Deserialize<'a> for RawBinding {
return Err(<V::Error as Error>::duplicate_field("key"));
}
- let coherent_key = map.next_value::<Key>()?;
- key = Some(coherent_key.to_glutin_key());
+ let val = map.next_value::<serde_yaml::Value>()?;
+ if val.is_u64() {
+ let scancode = val.as_u64().unwrap();
+ if scancode > u64::from(::std::u32::MAX) {
+ return Err(<V::Error as Error>::custom(format!(
+ "invalid key binding, scancode too big: {}",
+ scancode
+ )));
+ }
+ key = Some(Key::Scancode(scancode as u32));
+ } else {
+ let k = Key::deserialize(val)
+ .map_err(V::Error::custom)?;
+ key = Some(k);
+ }
},
Field::Mods => {
if mods.is_some() {
@@ -2059,8 +2072,9 @@ mod tests {
}
#[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
-#[derive(Deserialize, Copy, Clone)]
-enum Key {
+#[derive(Deserialize, Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Key {
+ Scancode(u32),
Key1,
Key2,
Key3,
@@ -2218,164 +2232,164 @@ enum Key {
}
impl Key {
- fn to_glutin_key(self) -> ::glutin::VirtualKeyCode {
- use ::glutin::VirtualKeyCode::*;
- // Thank you, vim macros!
- match self {
- Key::Key1 => Key1,
- Key::Key2 => Key2,
- Key::Key3 => Key3,
- Key::Key4 => Key4,
- Key::Key5 => Key5,
- Key::Key6 => Key6,
- Key::Key7 => Key7,
- Key::Key8 => Key8,
- Key::Key9 => Key9,
- Key::Key0 => Key0,
- Key::A => A,
- Key::B => B,
- Key::C => C,
- Key::D => D,
- Key::E => E,
- Key::F => F,
- Key::G => G,
- Key::H => H,
- Key::I => I,
- Key::J => J,
- Key::K => K,
- Key::L => L,
- Key::M => M,
- Key::N => N,
- Key::O => O,
- Key::P => P,
- Key::Q => Q,
- Key::R => R,
- Key::S => S,
- Key::T => T,
- Key::U => U,
- Key::V => V,
- Key::W => W,
- Key::X => X,
- Key::Y => Y,
- Key::Z => Z,
- Key::Escape => Escape,
- Key::F1 => F1,
- Key::F2 => F2,
- Key::F3 => F3,
- Key::F4 => F4,
- Key::F5 => F5,
- Key::F6 => F6,
- Key::F7 => F7,
- Key::F8 => F8,
- Key::F9 => F9,
- Key::F10 => F10,
- Key::F11 => F11,
- Key::F12 => F12,
- Key::F13 => F13,
- Key::F14 => F14,
- Key::F15 => F15,
- Key::Snapshot => Snapshot,
- Key::Scroll => Scroll,
- Key::Pause => Pause,
- Key::Insert => Insert,
- Key::Home => Home,
- Key::Delete => Delete,
- Key::End => End,
- Key::PageDown => PageDown,
- Key::PageUp => PageUp,
- Key::Left => Left,
- Key::Up => Up,
- Key::Right => Right,
- Key::Down => Down,
- Key::Back => Back,
- Key::Return => Return,
- Key::Space => Space,
- Key::Compose => Compose,
- Key::Numlock => Numlock,
- Key::Numpad0 => Numpad0,
- Key::Numpad1 => Numpad1,
- Key::Numpad2 => Numpad2,
- Key::Numpad3 => Numpad3,
- Key::Numpad4 => Numpad4,
- Key::Numpad5 => Numpad5,
- Key::Numpad6 => Numpad6,
- Key::Numpad7 => Numpad7,
- Key::Numpad8 => Numpad8,
- Key::Numpad9 => Numpad9,
- Key::AbntC1 => AbntC1,
- Key::AbntC2 => AbntC2,
- Key::Add => Add,
- Key::Apostrophe => Apostrophe,
- Key::Apps => Apps,
- Key::At => At,
- Key::Ax => Ax,
- Key::Backslash => Backslash,
- Key::Calculator => Calculator,
- Key::Capital => Capital,
- Key::Colon => Colon,
- Key::Comma => Comma,
- Key::Convert => Convert,
- Key::Decimal => Decimal,
- Key::Divide => Divide,
- Key::Equals => Equals,
- Key::Grave => Grave,
- Key::Kana => Kana,
- Key::Kanji => Kanji,
- Key::LAlt => LAlt,
- Key::LBracket => LBracket,
- Key::LControl => LControl,
- Key::LMenu => LMenu,
- Key::LShift => LShift,
- Key::LWin => LWin,
- Key::Mail => Mail,
- Key::MediaSelect => MediaSelect,
- Key::MediaStop => MediaStop,
- Key::Minus => Minus,
- Key::Multiply => Multiply,
- Key::Mute => Mute,
- Key::MyComputer => MyComputer,
- Key::NavigateForward => NavigateForward,
- Key::NavigateBackward => NavigateBackward,
- Key::NextTrack => NextTrack,
- Key::NoConvert => NoConvert,
- Key::NumpadComma => NumpadComma,
- Key::NumpadEnter => NumpadEnter,
- Key::NumpadEquals => NumpadEquals,
- Key::OEM102 => OEM102,
- Key::Period => Period,
- Key::PlayPause => PlayPause,
- Key::Power => Power,
- Key::PrevTrack => PrevTrack,
- Key::RAlt => RAlt,
- Key::RBracket => RBracket,
- Key::RControl => RControl,
- Key::RMenu => RMenu,
- Key::RShift => RShift,
- Key::RWin => RWin,
- Key::Semicolon => Semicolon,
- Key::Slash => Slash,
- Key::Sleep => Sleep,
- Key::Stop => Stop,
- Key::Subtract => Subtract,
- Key::Sysrq => Sysrq,
- Key::Tab => Tab,
- Key::Underline => Underline,
- Key::Unlabeled => Unlabeled,
- Key::VolumeDown => VolumeDown,
- Key::VolumeUp => VolumeUp,
- Key::Wake => Wake,
- Key::WebBack => WebBack,
- Key::WebFavorites => WebFavorites,
- Key::WebForward => WebForward,
- Key::WebHome => WebHome,
- Key::WebRefresh => WebRefresh,
- Key::WebSearch => WebSearch,
- Key::WebStop => WebStop,
- Key::Yen => Yen,
- Key::Caret => Caret,
- Key::Copy => Copy,
- Key::Paste => Paste,
- Key::Cut => Cut,
+ pub fn from_glutin_input(key: ::glutin::VirtualKeyCode) -> Self {
+ use glutin::VirtualKeyCode::*;
+ // Thank you, vim macros and regex!
+ match key {
+ Key1 => Key::Key1,
+ Key2 => Key::Key2,
+ Key3 => Key::Key3,
+ Key4 => Key::Key4,
+ Key5 => Key::Key5,
+ Key6 => Key::Key6,
+ Key7 => Key::Key7,
+ Key8 => Key::Key8,
+ Key9 => Key::Key9,
+ Key0 => Key::Key0,
+ A => Key::A,
+ B => Key::B,
+ C => Key::C,
+ D => Key::D,
+ E => Key::E,
+ F => Key::F,
+ G => Key::G,
+ H => Key::H,
+ I => Key::I,
+ J => Key::J,
+ K => Key::K,
+ L => Key::L,
+ M => Key::M,
+ N => Key::N,
+ O => Key::O,
+ P => Key::P,
+ Q => Key::Q,
+ R => Key::R,
+ S => Key::S,
+ T => Key::T,
+ U => Key::U,
+ V => Key::V,
+ W => Key::W,
+ X => Key::X,
+ Y => Key::Y,
+ Z => Key::Z,
+ Escape => Key::Escape,
+ F1 => Key::F1,
+ F2 => Key::F2,
+ F3 => Key::F3,
+ F4 => Key::F4,
+ F5 => Key::F5,
+ F6 => Key::F6,
+ F7 => Key::F7,
+ F8 => Key::F8,
+ F9 => Key::F9,
+ F10 => Key::F10,
+ F11 => Key::F11,
+ F12 => Key::F12,
+ F13 => Key::F13,
+ F14 => Key::F14,
+ F15 => Key::F15,
+ Snapshot => Key::Snapshot,
+ Scroll => Key::Scroll,
+ Pause => Key::Pause,
+ Insert => Key::Insert,
+ Home => Key::Home,
+ Delete => Key::Delete,
+ End => Key::End,
+ PageDown => Key::PageDown,
+ PageUp => Key::PageUp,
+ Left => Key::Left,
+ Up => Key::Up,
+ Right => Key::Right,
+ Down => Key::Down,
+ Back => Key::Back,
+ Return => Key::Return,
+ Space => Key::Space,
+ Compose => Key::Compose,
+ Numlock => Key::Numlock,
+ Numpad0 => Key::Numpad0,
+ Numpad1 => Key::Numpad1,
+ Numpad2 => Key::Numpad2,
+ Numpad3 => Key::Numpad3,
+ Numpad4 => Key::Numpad4,
+ Numpad5 => Key::Numpad5,
+ Numpad6 => Key::Numpad6,
+ Numpad7 => Key::Numpad7,
+ Numpad8 => Key::Numpad8,
+ Numpad9 => Key::Numpad9,
+ AbntC1 => Key::AbntC1,
+ AbntC2 => Key::AbntC2,
+ Add => Key::Add,
+ Apostrophe => Key::Apostrophe,
+ Apps => Key::Apps,
+ At => Key::At,
+ Ax => Key::Ax,
+ Backslash => Key::Backslash,
+ Calculator => Key::Calculator,
+ Capital => Key::Capital,
+ Colon => Key::Colon,
+ Comma => Key::Comma,
+ Convert => Key::Convert,
+ Decimal => Key::Decimal,
+ Divide => Key::Divide,
+ Equals => Key::Equals,
+ Grave => Key::Grave,
+ Kana => Key::Kana,
+ Kanji => Key::Kanji,
+ LAlt => Key::LAlt,
+ LBracket => Key::LBracket,
+ LControl => Key::LControl,
+ LMenu => Key::LMenu,
+ LShift => Key::LShift,
+ LWin => Key::LWin,
+ Mail => Key::Mail,
+ MediaSelect => Key::MediaSelect,
+ MediaStop => Key::MediaStop,
+ Minus => Key::Minus,
+ Multiply => Key::Multiply,
+ Mute => Key::Mute,
+ MyComputer => Key::MyComputer,
+ NavigateForward => Key::NavigateForward,
+ NavigateBackward => Key::NavigateBackward,
+ NextTrack => Key::NextTrack,
+ NoConvert => Key::NoConvert,
+ NumpadComma => Key::NumpadComma,
+ NumpadEnter => Key::NumpadEnter,
+ NumpadEquals => Key::NumpadEquals,
+ OEM102 => Key::OEM102,
+ Period => Key::Period,
+ PlayPause => Key::PlayPause,
+ Power => Key::Power,
+ PrevTrack => Key::PrevTrack,
+ RAlt => Key::RAlt,
+ RBracket => Key::RBracket,
+ RControl => Key::RControl,
+ RMenu => Key::RMenu,
+ RShift => Key::RShift,
+ RWin => Key::RWin,
+ Semicolon => Key::Semicolon,
+ Slash => Key::Slash,
+ Sleep => Key::Sleep,
+ Stop => Key::Stop,
+ Subtract => Key::Subtract,
+ Sysrq => Key::Sysrq,
+ Tab => Key::Tab,
+ Underline => Key::Underline,
+ Unlabeled => Key::Unlabeled,
+ VolumeDown => Key::VolumeDown,
+ VolumeUp => Key::VolumeUp,
+ Wake => Key::Wake,
+ WebBack => Key::WebBack,
+ WebFavorites => Key::WebFavorites,
+ WebForward => Key::WebForward,
+ WebHome => Key::WebHome,
+ WebRefresh => Key::WebRefresh,
+ WebSearch => Key::WebSearch,
+ WebStop => Key::WebStop,
+ Yen => Key::Yen,
+ Caret => Key::Caret,
+ Copy => Key::Copy,
+ Paste => Key::Paste,
+ Cut => Key::Cut,
}
}
}
diff --git a/src/event.rs b/src/event.rs
index 9db0680d..eef04a8c 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -334,9 +334,8 @@ impl<N: Notify> Processor<N> {
processor.ctx.terminal.dirty = true;
},
KeyboardInput { input, .. } => {
- let glutin::KeyboardInput { state, virtual_keycode, modifiers, .. } = input;
- processor.process_key(state, virtual_keycode, modifiers);
- if state == ElementState::Pressed {
+ processor.process_key(input);
+ if input.state == ElementState::Pressed {
// Hide cursor while typing
*hide_cursor = true;
}
diff --git a/src/input.rs b/src/input.rs
index 6d3b407a..ed9aa7fc 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -26,9 +26,9 @@ use std::time::Instant;
use std::os::unix::process::CommandExt;
use copypasta::{Clipboard, Load, Buffer as ClipboardBuffer};
-use glutin::{ElementState, VirtualKeyCode, MouseButton, TouchPhase, MouseScrollDelta, ModifiersState};
+use glutin::{ElementState, MouseButton, TouchPhase, MouseScrollDelta, ModifiersState, KeyboardInput};
-use config;
+use config::{self, Key};
use grid::Scroll;
use event::{ClickState, Mouse};
use index::{Line, Column, Side, Point};
@@ -100,7 +100,7 @@ pub struct Binding<T> {
}
/// Bindings that are triggered by a keyboard key
-pub type KeyBinding = Binding<VirtualKeyCode>;
+pub type KeyBinding = Binding<Key>;
/// Bindings that are triggered by a mouse button
pub type MouseBinding = Binding<MouseButton>;
@@ -618,24 +618,18 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
/// Process key input
///
/// If a keybinding was run, returns true. Otherwise returns false.
- pub fn process_key(
- &mut self,
- state: ElementState,
- key: Option<VirtualKeyCode>,
- mods: ModifiersState,
- ) {
- match (key, state) {
- (Some(key), ElementState::Pressed) => {
- *self.ctx.last_modifiers() = mods;
+ pub fn process_key(&mut self, input: KeyboardInput) {
+ match input.state {
+ ElementState::Pressed => {
+ *self.ctx.last_modifiers() = input.modifiers;
*self.ctx.received_count() = 0;
*self.ctx.suppress_chars() = false;
- if self.process_key_bindings(mods, key) {
+ if self.process_key_bindings(input) {
*self.ctx.suppress_chars() = true;
}
},
- (_, ElementState::Released) => *self.ctx.suppress_chars() = false,
- _ => ()
+ ElementState::Released => *self.ctx.suppress_chars() = false,
}
}
@@ -668,10 +662,24 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
/// for its action to be executed.
///
/// Returns true if an action is executed.
- fn process_key_bindings(&mut self, mods: ModifiersState, key: VirtualKeyCode) -> bool {
+ fn process_key_bindings(&mut self, input: KeyboardInput) -> bool {
let mut has_binding = false;
for binding in self.key_bindings {
- if binding.is_triggered_by(self.ctx.terminal_mode(), mods, &key) {
+ let is_triggered = match binding.trigger {
+ Key::Scancode(_) => binding.is_triggered_by(
+ self.ctx.terminal_mode(),
+ input.modifiers,
+ &Key::Scancode(input.scancode),
+ ),
+ _ => if let Some(key) = input.virtual_keycode {
+ let key = Key::from_glutin_input(key);
+ binding.is_triggered_by(self.ctx.terminal_mode(), input.modifiers, &key)
+ } else {
+ false
+ },
+ };
+
+ if is_triggered {
// binding was triggered; run the action
binding.execute(&mut self.ctx);
has_binding = true;