config: add create-mark, jump-to-mark, and copy-mark actions
This commit is contained in:
parent
e30e2595a1
commit
eb625b34cc
19 changed files with 1193 additions and 9 deletions
|
|
@ -11,3 +11,8 @@ tasks:
|
||||||
- test: |
|
- test: |
|
||||||
cd jay
|
cd jay
|
||||||
cargo test
|
cargo test
|
||||||
|
- test-tc: |
|
||||||
|
cd jay
|
||||||
|
git submodule update --init
|
||||||
|
cd toml-config
|
||||||
|
cargo test
|
||||||
|
|
|
||||||
|
|
@ -987,6 +987,18 @@ impl ConfigClient {
|
||||||
self.send(&ClientMessage::SetMiddleClickPasteEnabled { enabled });
|
self.send(&ClientMessage::SetMiddleClickPasteEnabled { enabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn seat_create_mark(&self, seat: Seat, kc: Option<u32>) {
|
||||||
|
self.send(&ClientMessage::SeatCreateMark { seat, kc });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn seat_jump_to_mark(&self, seat: Seat, kc: Option<u32>) {
|
||||||
|
self.send(&ClientMessage::SeatJumpToMark { seat, kc });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn seat_copy_mark(&self, seat: Seat, src: u32, dst: u32) {
|
||||||
|
self.send(&ClientMessage::SeatCopyMark { seat, src, dst });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_show_float_pin_icon(&self, show: bool) {
|
pub fn set_show_float_pin_icon(&self, show: bool) {
|
||||||
self.send(&ClientMessage::SetShowFloatPinIcon { show });
|
self.send(&ClientMessage::SetShowFloatPinIcon { show });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -747,6 +747,19 @@ pub enum ClientMessage<'a> {
|
||||||
SetMiddleClickPasteEnabled {
|
SetMiddleClickPasteEnabled {
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
},
|
},
|
||||||
|
SeatCreateMark {
|
||||||
|
seat: Seat,
|
||||||
|
kc: Option<u32>,
|
||||||
|
},
|
||||||
|
SeatJumpToMark {
|
||||||
|
seat: Seat,
|
||||||
|
kc: Option<u32>,
|
||||||
|
},
|
||||||
|
SeatCopyMark {
|
||||||
|
seat: Seat,
|
||||||
|
src: u32,
|
||||||
|
dst: u32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -566,6 +566,34 @@ impl Seat {
|
||||||
pub fn set_pointer_revert_key(self, sym: KeySym) {
|
pub fn set_pointer_revert_key(self, sym: KeySym) {
|
||||||
get!().set_pointer_revert_key(self, sym);
|
get!().set_pointer_revert_key(self, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a mark for the currently focused window.
|
||||||
|
///
|
||||||
|
/// `kc` should be an evdev keycode. If `kc` is none, then the keycode will be
|
||||||
|
/// inferred from the next key press. Pressing escape during this interactive
|
||||||
|
/// selection aborts the process.
|
||||||
|
///
|
||||||
|
/// Currently very few `u32` are valid keycodes. Large numbers can therefore be used
|
||||||
|
/// to create marks that do not correspond to a key. However, `kc` should always be
|
||||||
|
/// less than `u32::MAX - 8`.
|
||||||
|
pub fn create_mark(self, kc: Option<u32>) {
|
||||||
|
get!().seat_create_mark(self, kc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moves the keyboard focus to a window identified by a mark.
|
||||||
|
///
|
||||||
|
/// See [`Seat::create_mark`] for information about the `kc` parameter.
|
||||||
|
pub fn jump_to_mark(self, kc: Option<u32>) {
|
||||||
|
get!().seat_jump_to_mark(self, kc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copies a mark from one keycode to another.
|
||||||
|
///
|
||||||
|
/// If the `src` keycode identifies a mark before this function is called, the `dst`
|
||||||
|
/// keycode will identify the same mark afterwards.
|
||||||
|
pub fn copy_mark(self, src: u32, dst: u32) {
|
||||||
|
get!().seat_copy_mark(self, src, dst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A focus-follows-mouse mode.
|
/// A focus-follows-mouse mode.
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ use {
|
||||||
window::{TileState, Window, WindowMatcher},
|
window::{TileState, Window, WindowMatcher},
|
||||||
xwayland::XScalingMode,
|
xwayland::XScalingMode,
|
||||||
},
|
},
|
||||||
|
kbvm::Keycode,
|
||||||
libloading::Library,
|
libloading::Library,
|
||||||
log::Level,
|
log::Level,
|
||||||
regex::Regex,
|
regex::Regex,
|
||||||
|
|
@ -2208,6 +2209,32 @@ impl ConfigProxyHandler {
|
||||||
self.state.enable_primary_selection.set(enabled);
|
self.state.enable_primary_selection.set(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_seat_create_mark(&self, seat: Seat, kc: Option<u32>) -> Result<(), CphError> {
|
||||||
|
let seat = self.get_seat(seat)?;
|
||||||
|
if let Some(kc) = kc {
|
||||||
|
seat.create_mark(Keycode::from_evdev(kc));
|
||||||
|
} else {
|
||||||
|
seat.create_mark_interactive();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_seat_jump_to_mark(&self, seat: Seat, kc: Option<u32>) -> Result<(), CphError> {
|
||||||
|
let seat = self.get_seat(seat)?;
|
||||||
|
if let Some(kc) = kc {
|
||||||
|
seat.jump_to_mark(Keycode::from_evdev(kc));
|
||||||
|
} else {
|
||||||
|
seat.jump_to_mark_interactive();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_seat_copy_mark(&self, seat: Seat, src: u32, dst: u32) -> Result<(), CphError> {
|
||||||
|
let seat = self.get_seat(seat)?;
|
||||||
|
seat.copy_mark(Keycode::from_evdev(src), Keycode::from_evdev(dst));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn spaces_change(&self) {
|
fn spaces_change(&self) {
|
||||||
struct V;
|
struct V;
|
||||||
impl NodeVisitorBase for V {
|
impl NodeVisitorBase for V {
|
||||||
|
|
@ -3071,6 +3098,15 @@ impl ConfigProxyHandler {
|
||||||
ClientMessage::SetMiddleClickPasteEnabled { enabled } => {
|
ClientMessage::SetMiddleClickPasteEnabled { enabled } => {
|
||||||
self.handle_set_middle_click_paste_enabled(enabled)
|
self.handle_set_middle_click_paste_enabled(enabled)
|
||||||
}
|
}
|
||||||
|
ClientMessage::SeatCreateMark { seat, kc } => self
|
||||||
|
.handle_seat_create_mark(seat, kc)
|
||||||
|
.wrn("seat_create_mark")?,
|
||||||
|
ClientMessage::SeatJumpToMark { seat, kc } => self
|
||||||
|
.handle_seat_jump_to_mark(seat, kc)
|
||||||
|
.wrn("seat_jump_to_mark")?,
|
||||||
|
ClientMessage::SeatCopyMark { seat, src, dst } => self
|
||||||
|
.handle_seat_copy_mark(seat, src, dst)
|
||||||
|
.wrn("seat_copy_mark")?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ use {
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
jay_config::keyboard::syms::{KeySym, SYM_Escape},
|
jay_config::keyboard::syms::{KeySym, SYM_Escape},
|
||||||
|
kbvm::Keycode,
|
||||||
smallvec::SmallVec,
|
smallvec::SmallVec,
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
|
|
@ -232,6 +233,14 @@ pub struct WlSeatGlobal {
|
||||||
focus_history_rotate: NumCell<u64>,
|
focus_history_rotate: NumCell<u64>,
|
||||||
focus_history_visible_only: Cell<bool>,
|
focus_history_visible_only: Cell<bool>,
|
||||||
focus_history_same_workspace: Cell<bool>,
|
focus_history_same_workspace: Cell<bool>,
|
||||||
|
mark_mode: Cell<Option<MarkMode>>,
|
||||||
|
marks: CopyHashMap<Keycode, Rc<dyn Node>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum MarkMode {
|
||||||
|
Mark,
|
||||||
|
Jump,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
||||||
|
|
@ -311,6 +320,8 @@ impl WlSeatGlobal {
|
||||||
focus_history_rotate: Default::default(),
|
focus_history_rotate: Default::default(),
|
||||||
focus_history_visible_only: Cell::new(false),
|
focus_history_visible_only: Cell::new(false),
|
||||||
focus_history_same_workspace: Cell::new(false),
|
focus_history_same_workspace: Cell::new(false),
|
||||||
|
mark_mode: Default::default(),
|
||||||
|
marks: Default::default(),
|
||||||
});
|
});
|
||||||
slf.pointer_cursor.set_owner(slf.clone());
|
slf.pointer_cursor.set_owner(slf.clone());
|
||||||
let seat = slf.clone();
|
let seat = slf.clone();
|
||||||
|
|
@ -1186,6 +1197,7 @@ impl WlSeatGlobal {
|
||||||
self.cursor_user_group.detach();
|
self.cursor_user_group.detach();
|
||||||
self.tablet_clear();
|
self.tablet_clear();
|
||||||
self.ei_seats.clear();
|
self.ei_seats.clear();
|
||||||
|
self.marks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> SeatId {
|
pub fn id(&self) -> SeatId {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wl_seat::{
|
wl_seat::{
|
||||||
CHANGE_CURSOR_MOVED, CHANGE_TREE, Dnd, SeatId, WlSeat, WlSeatGlobal,
|
CHANGE_CURSOR_MOVED, CHANGE_TREE, Dnd, MarkMode, SeatId, WlSeat, WlSeatGlobal,
|
||||||
tablet::{TabletPad, TabletPadId, TabletTool, TabletToolId},
|
tablet::{TabletPad, TabletPadId, TabletTool, TabletToolId},
|
||||||
text_input::TextDisconnectReason,
|
text_input::TextDisconnectReason,
|
||||||
wl_keyboard::WlKeyboard,
|
wl_keyboard::WlKeyboard,
|
||||||
|
|
@ -56,7 +56,7 @@ use {
|
||||||
syms::KeySym,
|
syms::KeySym,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kbvm::{ModifierMask, state_machine::Event},
|
kbvm::{Keycode, ModifierMask, evdev, state_machine::Event},
|
||||||
linearize::LinearizeExt,
|
linearize::LinearizeExt,
|
||||||
smallvec::SmallVec,
|
smallvec::SmallVec,
|
||||||
std::{
|
std::{
|
||||||
|
|
@ -80,6 +80,12 @@ pub struct NodeSeatState {
|
||||||
tablet_pad_foci: SmallMap<TabletPadId, Rc<TabletPad>, 1>,
|
tablet_pad_foci: SmallMap<TabletPadId, Rc<TabletPad>, 1>,
|
||||||
tablet_tool_foci: SmallMap<TabletToolId, Rc<TabletTool>, 1>,
|
tablet_tool_foci: SmallMap<TabletToolId, Rc<TabletTool>, 1>,
|
||||||
ui_drags: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
ui_drags: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||||
|
marks: RefCell<SmallMapMut<SeatId, Marks, 1>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Marks {
|
||||||
|
seat: Rc<WlSeatGlobal>,
|
||||||
|
marks: SmallMapMut<Keycode, (), 1>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FocusHistoryData {
|
pub struct FocusHistoryData {
|
||||||
|
|
@ -217,6 +223,12 @@ impl NodeSeatState {
|
||||||
entry.visible.set(false);
|
entry.visible.set(false);
|
||||||
entry.detach();
|
entry.detach();
|
||||||
}
|
}
|
||||||
|
for (_, marks) in self.marks.borrow_mut().iter_mut() {
|
||||||
|
for (kc, _) in &marks.marks {
|
||||||
|
marks.seat.marks.remove(kc);
|
||||||
|
}
|
||||||
|
marks.marks.clear();
|
||||||
|
}
|
||||||
self.destroy_node2(node, true);
|
self.destroy_node2(node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -870,6 +882,23 @@ impl WlSeatGlobal {
|
||||||
KeyState::Pressed => pk.insert(kc.to_evdev()),
|
KeyState::Pressed => pk.insert(kc.to_evdev()),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if key_state == KeyState::Pressed
|
||||||
|
&& let Some(mode) = self.mark_mode.take()
|
||||||
|
{
|
||||||
|
update_pressed_keys(&mut kbvm_state);
|
||||||
|
if kc == evdev::ESC {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
match mode {
|
||||||
|
MarkMode::Mark => self.create_mark(kc),
|
||||||
|
MarkMode::Jump => {
|
||||||
|
drop(kbvm_state);
|
||||||
|
self.jump_to_mark(kc);
|
||||||
|
kbvm_state = kbvm_state_rc.borrow_mut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
shortcuts.clear();
|
shortcuts.clear();
|
||||||
{
|
{
|
||||||
let mut mods = kbvm_state.kb_state.mods.mods.0 & !(CAPS.0 | NUM.0);
|
let mut mods = kbvm_state.kb_state.mods.mods.0 & !(CAPS.0 | NUM.0);
|
||||||
|
|
@ -949,6 +978,60 @@ impl WlSeatGlobal {
|
||||||
self.send_components(&mut components_changed, &kbvm_state);
|
self.send_components(&mut components_changed, &kbvm_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_mark_interactive(&self) {
|
||||||
|
self.mark_mode.set(Some(MarkMode::Mark));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_mark(self: &Rc<Self>, kc: Keycode) {
|
||||||
|
self.create_mark_(kc, self.keyboard_node.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_mark_(self: &Rc<Self>, kc: Keycode, node: Rc<dyn Node>) {
|
||||||
|
let prev = self.marks.set(kc, node.clone());
|
||||||
|
if let Some(prev) = prev {
|
||||||
|
if prev.node_id() == node.node_id() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(marks) = prev.node_seat_state().marks.borrow_mut().get_mut(&self.id) {
|
||||||
|
marks.marks.remove(&kc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node.node_seat_state()
|
||||||
|
.marks
|
||||||
|
.borrow_mut()
|
||||||
|
.get_or_insert_with(self.id, || Marks {
|
||||||
|
seat: self.clone(),
|
||||||
|
marks: Default::default(),
|
||||||
|
})
|
||||||
|
.marks
|
||||||
|
.insert(kc, ());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jump_to_mark_interactive(&self) {
|
||||||
|
self.mark_mode.set(Some(MarkMode::Jump));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jump_to_mark(self: &Rc<Self>, kc: Keycode) {
|
||||||
|
if let Some(node) = self.marks.get(&kc)
|
||||||
|
&& node.node_accepts_focus()
|
||||||
|
&& node.node_id() != self.keyboard_node.get().node_id()
|
||||||
|
{
|
||||||
|
if !node.node_visible() {
|
||||||
|
node.clone().node_make_visible();
|
||||||
|
if !node.node_visible() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.focus_node(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_mark(self: &Rc<Self>, src: Keycode, dst: Keycode) {
|
||||||
|
if let Some(node) = self.marks.get(&src) {
|
||||||
|
self.create_mark_(dst, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn send_components(&self, components_changed: &mut bool, kbvm_state: &KbvmState) {
|
fn send_components(&self, components_changed: &mut bool, kbvm_state: &KbvmState) {
|
||||||
if !mem::take(components_changed) {
|
if !mem::take(components_changed) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,15 @@ impl<K: Eq, V, const N: usize> SmallMapMut<K, V, N> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
|
||||||
|
for (ek, ev) in &mut self.m {
|
||||||
|
if ek == k {
|
||||||
|
return Some(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_or_default_mut(&mut self, k: K) -> &mut V
|
pub fn get_or_default_mut(&mut self, k: K) -> &mut V
|
||||||
where
|
where
|
||||||
V: Default,
|
V: Default,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
mod context;
|
mod context;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod extractor;
|
mod extractor;
|
||||||
|
mod keycodes;
|
||||||
mod keysyms;
|
mod keysyms;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod parsers;
|
mod parsers;
|
||||||
|
|
@ -36,6 +37,7 @@ use {
|
||||||
xwayland::XScalingMode,
|
xwayland::XScalingMode,
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
|
cell::RefCell,
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
|
@ -77,6 +79,8 @@ pub enum SimpleCommand {
|
||||||
FocusHistory(Timeline),
|
FocusHistory(Timeline),
|
||||||
FocusLayerRel(LayerDirection),
|
FocusLayerRel(LayerDirection),
|
||||||
FocusTiles,
|
FocusTiles,
|
||||||
|
CreateMark,
|
||||||
|
JumpToMark,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -160,6 +164,9 @@ pub enum Action {
|
||||||
NamedAction {
|
NamedAction {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
CreateMark(u32),
|
||||||
|
JumpToMark(u32),
|
||||||
|
CopyMark(u32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
|
@ -505,13 +512,18 @@ pub enum ConfigError {
|
||||||
Parser(#[from] ConfigParserError),
|
Parser(#[from] ConfigParserError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_config<F>(input: &[u8], handle_error: F) -> Option<Config>
|
pub fn parse_config<F>(
|
||||||
|
input: &[u8],
|
||||||
|
mark_names: &RefCell<AHashMap<String, u32>>,
|
||||||
|
handle_error: F,
|
||||||
|
) -> Option<Config>
|
||||||
where
|
where
|
||||||
F: FnOnce(&dyn Error),
|
F: FnOnce(&dyn Error),
|
||||||
{
|
{
|
||||||
let cx = Context {
|
let cx = Context {
|
||||||
input,
|
input,
|
||||||
used: Default::default(),
|
used: Default::default(),
|
||||||
|
mark_names,
|
||||||
};
|
};
|
||||||
macro_rules! fatal {
|
macro_rules! fatal {
|
||||||
($e:expr) => {{
|
($e:expr) => {{
|
||||||
|
|
@ -554,5 +566,5 @@ where
|
||||||
#[test]
|
#[test]
|
||||||
fn default_config_parses() {
|
fn default_config_parses() {
|
||||||
let input = include_bytes!("default-config.toml");
|
let input = include_bytes!("default-config.toml");
|
||||||
parse_config(input, |_| ()).unwrap();
|
parse_config(input, &Default::default(), |_| ()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use {
|
||||||
toml_span::{Span, Spanned},
|
toml_span::{Span, Spanned},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ahash::AHashSet,
|
ahash::{AHashMap, AHashSet},
|
||||||
error_reporter::Report,
|
error_reporter::Report,
|
||||||
std::{cell::RefCell, convert::Infallible, error::Error},
|
std::{cell::RefCell, convert::Infallible, error::Error},
|
||||||
};
|
};
|
||||||
|
|
@ -14,6 +14,7 @@ use {
|
||||||
pub struct Context<'a> {
|
pub struct Context<'a> {
|
||||||
pub input: &'a [u8],
|
pub input: &'a [u8],
|
||||||
pub used: RefCell<Used>,
|
pub used: RefCell<Used>,
|
||||||
|
pub mark_names: &'a RefCell<AHashMap<String, u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
||||||
520
toml-config/src/config/keycodes.rs
Normal file
520
toml-config/src/config/keycodes.rs
Normal file
|
|
@ -0,0 +1,520 @@
|
||||||
|
use phf::phf_map;
|
||||||
|
|
||||||
|
pub static KEYCODES: phf::Map<&'static str, u32> = phf_map! {
|
||||||
|
"esc" => 1,
|
||||||
|
"1" => 2,
|
||||||
|
"2" => 3,
|
||||||
|
"3" => 4,
|
||||||
|
"4" => 5,
|
||||||
|
"5" => 6,
|
||||||
|
"6" => 7,
|
||||||
|
"7" => 8,
|
||||||
|
"8" => 9,
|
||||||
|
"9" => 10,
|
||||||
|
"0" => 11,
|
||||||
|
"minus" => 12,
|
||||||
|
"equal" => 13,
|
||||||
|
"backspace" => 14,
|
||||||
|
"tab" => 15,
|
||||||
|
"q" => 16,
|
||||||
|
"w" => 17,
|
||||||
|
"e" => 18,
|
||||||
|
"r" => 19,
|
||||||
|
"t" => 20,
|
||||||
|
"y" => 21,
|
||||||
|
"u" => 22,
|
||||||
|
"i" => 23,
|
||||||
|
"o" => 24,
|
||||||
|
"p" => 25,
|
||||||
|
"leftbrace" => 26,
|
||||||
|
"rightbrace" => 27,
|
||||||
|
"enter" => 28,
|
||||||
|
"leftctrl" => 29,
|
||||||
|
"a" => 30,
|
||||||
|
"s" => 31,
|
||||||
|
"d" => 32,
|
||||||
|
"f" => 33,
|
||||||
|
"g" => 34,
|
||||||
|
"h" => 35,
|
||||||
|
"j" => 36,
|
||||||
|
"k" => 37,
|
||||||
|
"l" => 38,
|
||||||
|
"semicolon" => 39,
|
||||||
|
"apostrophe" => 40,
|
||||||
|
"grave" => 41,
|
||||||
|
"leftshift" => 42,
|
||||||
|
"backslash" => 43,
|
||||||
|
"z" => 44,
|
||||||
|
"x" => 45,
|
||||||
|
"c" => 46,
|
||||||
|
"v" => 47,
|
||||||
|
"b" => 48,
|
||||||
|
"n" => 49,
|
||||||
|
"m" => 50,
|
||||||
|
"comma" => 51,
|
||||||
|
"dot" => 52,
|
||||||
|
"slash" => 53,
|
||||||
|
"rightshift" => 54,
|
||||||
|
"kpasterisk" => 55,
|
||||||
|
"leftalt" => 56,
|
||||||
|
"space" => 57,
|
||||||
|
"capslock" => 58,
|
||||||
|
"f1" => 59,
|
||||||
|
"f2" => 60,
|
||||||
|
"f3" => 61,
|
||||||
|
"f4" => 62,
|
||||||
|
"f5" => 63,
|
||||||
|
"f6" => 64,
|
||||||
|
"f7" => 65,
|
||||||
|
"f8" => 66,
|
||||||
|
"f9" => 67,
|
||||||
|
"f10" => 68,
|
||||||
|
"numlock" => 69,
|
||||||
|
"scrolllock" => 70,
|
||||||
|
"kp7" => 71,
|
||||||
|
"kp8" => 72,
|
||||||
|
"kp9" => 73,
|
||||||
|
"kpminus" => 74,
|
||||||
|
"kp4" => 75,
|
||||||
|
"kp5" => 76,
|
||||||
|
"kp6" => 77,
|
||||||
|
"kpplus" => 78,
|
||||||
|
"kp1" => 79,
|
||||||
|
"kp2" => 80,
|
||||||
|
"kp3" => 81,
|
||||||
|
"kp0" => 82,
|
||||||
|
"kpdot" => 83,
|
||||||
|
"zenkakuhankaku" => 85,
|
||||||
|
"102nd" => 86,
|
||||||
|
"f11" => 87,
|
||||||
|
"f12" => 88,
|
||||||
|
"ro" => 89,
|
||||||
|
"katakana" => 90,
|
||||||
|
"hiragana" => 91,
|
||||||
|
"henkan" => 92,
|
||||||
|
"katakanahiragana" => 93,
|
||||||
|
"muhenkan" => 94,
|
||||||
|
"kpjpcomma" => 95,
|
||||||
|
"kpenter" => 96,
|
||||||
|
"rightctrl" => 97,
|
||||||
|
"kpslash" => 98,
|
||||||
|
"sysrq" => 99,
|
||||||
|
"rightalt" => 100,
|
||||||
|
"linefeed" => 101,
|
||||||
|
"home" => 102,
|
||||||
|
"up" => 103,
|
||||||
|
"pageup" => 104,
|
||||||
|
"left" => 105,
|
||||||
|
"right" => 106,
|
||||||
|
"end" => 107,
|
||||||
|
"down" => 108,
|
||||||
|
"pagedown" => 109,
|
||||||
|
"insert" => 110,
|
||||||
|
"delete" => 111,
|
||||||
|
"macro" => 112,
|
||||||
|
"mute" => 113,
|
||||||
|
"volumedown" => 114,
|
||||||
|
"volumeup" => 115,
|
||||||
|
"power" => 116,
|
||||||
|
"kpequal" => 117,
|
||||||
|
"kpplusminus" => 118,
|
||||||
|
"pause" => 119,
|
||||||
|
"scale" => 120,
|
||||||
|
"kpcomma" => 121,
|
||||||
|
"hangeul" => 122,
|
||||||
|
"hanguel" => 122,
|
||||||
|
"hanja" => 123,
|
||||||
|
"yen" => 124,
|
||||||
|
"leftmeta" => 125,
|
||||||
|
"rightmeta" => 126,
|
||||||
|
"compose" => 127,
|
||||||
|
"stop" => 128,
|
||||||
|
"again" => 129,
|
||||||
|
"props" => 130,
|
||||||
|
"undo" => 131,
|
||||||
|
"front" => 132,
|
||||||
|
"copy" => 133,
|
||||||
|
"open" => 134,
|
||||||
|
"paste" => 135,
|
||||||
|
"find" => 136,
|
||||||
|
"cut" => 137,
|
||||||
|
"help" => 138,
|
||||||
|
"menu" => 139,
|
||||||
|
"calc" => 140,
|
||||||
|
"setup" => 141,
|
||||||
|
"sleep" => 142,
|
||||||
|
"wakeup" => 143,
|
||||||
|
"file" => 144,
|
||||||
|
"sendfile" => 145,
|
||||||
|
"deletefile" => 146,
|
||||||
|
"xfer" => 147,
|
||||||
|
"prog1" => 148,
|
||||||
|
"prog2" => 149,
|
||||||
|
"www" => 150,
|
||||||
|
"msdos" => 151,
|
||||||
|
"coffee" => 152,
|
||||||
|
"screenlock" => 152,
|
||||||
|
"rotate_display" => 153,
|
||||||
|
"direction" => 153,
|
||||||
|
"cyclewindows" => 154,
|
||||||
|
"mail" => 155,
|
||||||
|
"bookmarks" => 156,
|
||||||
|
"computer" => 157,
|
||||||
|
"back" => 158,
|
||||||
|
"forward" => 159,
|
||||||
|
"closecd" => 160,
|
||||||
|
"ejectcd" => 161,
|
||||||
|
"ejectclosecd" => 162,
|
||||||
|
"nextsong" => 163,
|
||||||
|
"playpause" => 164,
|
||||||
|
"previoussong" => 165,
|
||||||
|
"stopcd" => 166,
|
||||||
|
"record" => 167,
|
||||||
|
"rewind" => 168,
|
||||||
|
"phone" => 169,
|
||||||
|
"iso" => 170,
|
||||||
|
"config" => 171,
|
||||||
|
"homepage" => 172,
|
||||||
|
"refresh" => 173,
|
||||||
|
"exit" => 174,
|
||||||
|
"move" => 175,
|
||||||
|
"edit" => 176,
|
||||||
|
"scrollup" => 177,
|
||||||
|
"scrolldown" => 178,
|
||||||
|
"kpleftparen" => 179,
|
||||||
|
"kprightparen" => 180,
|
||||||
|
"new" => 181,
|
||||||
|
"redo" => 182,
|
||||||
|
"f13" => 183,
|
||||||
|
"f14" => 184,
|
||||||
|
"f15" => 185,
|
||||||
|
"f16" => 186,
|
||||||
|
"f17" => 187,
|
||||||
|
"f18" => 188,
|
||||||
|
"f19" => 189,
|
||||||
|
"f20" => 190,
|
||||||
|
"f21" => 191,
|
||||||
|
"f22" => 192,
|
||||||
|
"f23" => 193,
|
||||||
|
"f24" => 194,
|
||||||
|
"playcd" => 200,
|
||||||
|
"pausecd" => 201,
|
||||||
|
"prog3" => 202,
|
||||||
|
"prog4" => 203,
|
||||||
|
"all_applications" => 204,
|
||||||
|
"dashboard" => 204,
|
||||||
|
"suspend" => 205,
|
||||||
|
"close" => 206,
|
||||||
|
"play" => 207,
|
||||||
|
"fastforward" => 208,
|
||||||
|
"bassboost" => 209,
|
||||||
|
"print" => 210,
|
||||||
|
"hp" => 211,
|
||||||
|
"camera" => 212,
|
||||||
|
"sound" => 213,
|
||||||
|
"question" => 214,
|
||||||
|
"email" => 215,
|
||||||
|
"chat" => 216,
|
||||||
|
"search" => 217,
|
||||||
|
"connect" => 218,
|
||||||
|
"finance" => 219,
|
||||||
|
"sport" => 220,
|
||||||
|
"shop" => 221,
|
||||||
|
"alterase" => 222,
|
||||||
|
"cancel" => 223,
|
||||||
|
"brightnessdown" => 224,
|
||||||
|
"brightnessup" => 225,
|
||||||
|
"media" => 226,
|
||||||
|
"switchvideomode" => 227,
|
||||||
|
"kbdillumtoggle" => 228,
|
||||||
|
"kbdillumdown" => 229,
|
||||||
|
"kbdillumup" => 230,
|
||||||
|
"send" => 231,
|
||||||
|
"reply" => 232,
|
||||||
|
"forwardmail" => 233,
|
||||||
|
"save" => 234,
|
||||||
|
"documents" => 235,
|
||||||
|
"battery" => 236,
|
||||||
|
"bluetooth" => 237,
|
||||||
|
"wlan" => 238,
|
||||||
|
"uwb" => 239,
|
||||||
|
"unknown" => 240,
|
||||||
|
"video_next" => 241,
|
||||||
|
"video_prev" => 242,
|
||||||
|
"brightness_cycle" => 243,
|
||||||
|
"brightness_auto" => 244,
|
||||||
|
"brightness_zero" => 244,
|
||||||
|
"display_off" => 245,
|
||||||
|
"wwan" => 246,
|
||||||
|
"wimax" => 246,
|
||||||
|
"rfkill" => 247,
|
||||||
|
"micmute" => 248,
|
||||||
|
"ok" => 0x160,
|
||||||
|
"select" => 0x161,
|
||||||
|
"goto" => 0x162,
|
||||||
|
"clear" => 0x163,
|
||||||
|
"power2" => 0x164,
|
||||||
|
"option" => 0x165,
|
||||||
|
"info" => 0x166,
|
||||||
|
"time" => 0x167,
|
||||||
|
"vendor" => 0x168,
|
||||||
|
"archive" => 0x169,
|
||||||
|
"program" => 0x16a,
|
||||||
|
"channel" => 0x16b,
|
||||||
|
"favorites" => 0x16c,
|
||||||
|
"epg" => 0x16d,
|
||||||
|
"pvr" => 0x16e,
|
||||||
|
"mhp" => 0x16f,
|
||||||
|
"language" => 0x170,
|
||||||
|
"title" => 0x171,
|
||||||
|
"subtitle" => 0x172,
|
||||||
|
"angle" => 0x173,
|
||||||
|
"full_screen" => 0x174,
|
||||||
|
"zoom" => 0x174,
|
||||||
|
"mode" => 0x175,
|
||||||
|
"keyboard" => 0x176,
|
||||||
|
"aspect_ratio" => 0x177,
|
||||||
|
"screen" => 0x177,
|
||||||
|
"pc" => 0x178,
|
||||||
|
"tv" => 0x179,
|
||||||
|
"tv2" => 0x17a,
|
||||||
|
"vcr" => 0x17b,
|
||||||
|
"vcr2" => 0x17c,
|
||||||
|
"sat" => 0x17d,
|
||||||
|
"sat2" => 0x17e,
|
||||||
|
"cd" => 0x17f,
|
||||||
|
"tape" => 0x180,
|
||||||
|
"radio" => 0x181,
|
||||||
|
"tuner" => 0x182,
|
||||||
|
"player" => 0x183,
|
||||||
|
"text" => 0x184,
|
||||||
|
"dvd" => 0x185,
|
||||||
|
"aux" => 0x186,
|
||||||
|
"mp3" => 0x187,
|
||||||
|
"audio" => 0x188,
|
||||||
|
"video" => 0x189,
|
||||||
|
"directory" => 0x18a,
|
||||||
|
"list" => 0x18b,
|
||||||
|
"memo" => 0x18c,
|
||||||
|
"calendar" => 0x18d,
|
||||||
|
"red" => 0x18e,
|
||||||
|
"green" => 0x18f,
|
||||||
|
"yellow" => 0x190,
|
||||||
|
"blue" => 0x191,
|
||||||
|
"channelup" => 0x192,
|
||||||
|
"channeldown" => 0x193,
|
||||||
|
"first" => 0x194,
|
||||||
|
"last" => 0x195,
|
||||||
|
"ab" => 0x196,
|
||||||
|
"next" => 0x197,
|
||||||
|
"restart" => 0x198,
|
||||||
|
"slow" => 0x199,
|
||||||
|
"shuffle" => 0x19a,
|
||||||
|
"break" => 0x19b,
|
||||||
|
"previous" => 0x19c,
|
||||||
|
"digits" => 0x19d,
|
||||||
|
"teen" => 0x19e,
|
||||||
|
"twen" => 0x19f,
|
||||||
|
"videophone" => 0x1a0,
|
||||||
|
"games" => 0x1a1,
|
||||||
|
"zoomin" => 0x1a2,
|
||||||
|
"zoomout" => 0x1a3,
|
||||||
|
"zoomreset" => 0x1a4,
|
||||||
|
"wordprocessor" => 0x1a5,
|
||||||
|
"editor" => 0x1a6,
|
||||||
|
"spreadsheet" => 0x1a7,
|
||||||
|
"graphicseditor" => 0x1a8,
|
||||||
|
"presentation" => 0x1a9,
|
||||||
|
"database" => 0x1aa,
|
||||||
|
"news" => 0x1ab,
|
||||||
|
"voicemail" => 0x1ac,
|
||||||
|
"addressbook" => 0x1ad,
|
||||||
|
"messenger" => 0x1ae,
|
||||||
|
"displaytoggle" => 0x1af,
|
||||||
|
"brightness_toggle" => 0x1af,
|
||||||
|
"spellcheck" => 0x1b0,
|
||||||
|
"logoff" => 0x1b1,
|
||||||
|
"dollar" => 0x1b2,
|
||||||
|
"euro" => 0x1b3,
|
||||||
|
"frameback" => 0x1b4,
|
||||||
|
"frameforward" => 0x1b5,
|
||||||
|
"context_menu" => 0x1b6,
|
||||||
|
"media_repeat" => 0x1b7,
|
||||||
|
"10channelsup" => 0x1b8,
|
||||||
|
"10channelsdown" => 0x1b9,
|
||||||
|
"images" => 0x1ba,
|
||||||
|
"notification_center" => 0x1bc,
|
||||||
|
"pickup_phone" => 0x1bd,
|
||||||
|
"hangup_phone" => 0x1be,
|
||||||
|
"del_eol" => 0x1c0,
|
||||||
|
"del_eos" => 0x1c1,
|
||||||
|
"ins_line" => 0x1c2,
|
||||||
|
"del_line" => 0x1c3,
|
||||||
|
"fn" => 0x1d0,
|
||||||
|
"fn_esc" => 0x1d1,
|
||||||
|
"fn_f1" => 0x1d2,
|
||||||
|
"fn_f2" => 0x1d3,
|
||||||
|
"fn_f3" => 0x1d4,
|
||||||
|
"fn_f4" => 0x1d5,
|
||||||
|
"fn_f5" => 0x1d6,
|
||||||
|
"fn_f6" => 0x1d7,
|
||||||
|
"fn_f7" => 0x1d8,
|
||||||
|
"fn_f8" => 0x1d9,
|
||||||
|
"fn_f9" => 0x1da,
|
||||||
|
"fn_f10" => 0x1db,
|
||||||
|
"fn_f11" => 0x1dc,
|
||||||
|
"fn_f12" => 0x1dd,
|
||||||
|
"fn_1" => 0x1de,
|
||||||
|
"fn_2" => 0x1df,
|
||||||
|
"fn_d" => 0x1e0,
|
||||||
|
"fn_e" => 0x1e1,
|
||||||
|
"fn_f" => 0x1e2,
|
||||||
|
"fn_s" => 0x1e3,
|
||||||
|
"fn_b" => 0x1e4,
|
||||||
|
"fn_right_shift" => 0x1e5,
|
||||||
|
"brl_dot1" => 0x1f1,
|
||||||
|
"brl_dot2" => 0x1f2,
|
||||||
|
"brl_dot3" => 0x1f3,
|
||||||
|
"brl_dot4" => 0x1f4,
|
||||||
|
"brl_dot5" => 0x1f5,
|
||||||
|
"brl_dot6" => 0x1f6,
|
||||||
|
"brl_dot7" => 0x1f7,
|
||||||
|
"brl_dot8" => 0x1f8,
|
||||||
|
"brl_dot9" => 0x1f9,
|
||||||
|
"brl_dot10" => 0x1fa,
|
||||||
|
"numeric_0" => 0x200,
|
||||||
|
"numeric_1" => 0x201,
|
||||||
|
"numeric_2" => 0x202,
|
||||||
|
"numeric_3" => 0x203,
|
||||||
|
"numeric_4" => 0x204,
|
||||||
|
"numeric_5" => 0x205,
|
||||||
|
"numeric_6" => 0x206,
|
||||||
|
"numeric_7" => 0x207,
|
||||||
|
"numeric_8" => 0x208,
|
||||||
|
"numeric_9" => 0x209,
|
||||||
|
"numeric_star" => 0x20a,
|
||||||
|
"numeric_pound" => 0x20b,
|
||||||
|
"numeric_a" => 0x20c,
|
||||||
|
"numeric_b" => 0x20d,
|
||||||
|
"numeric_c" => 0x20e,
|
||||||
|
"numeric_d" => 0x20f,
|
||||||
|
"camera_focus" => 0x210,
|
||||||
|
"wps_button" => 0x211,
|
||||||
|
"touchpad_toggle" => 0x212,
|
||||||
|
"touchpad_on" => 0x213,
|
||||||
|
"touchpad_off" => 0x214,
|
||||||
|
"camera_zoomin" => 0x215,
|
||||||
|
"camera_zoomout" => 0x216,
|
||||||
|
"camera_up" => 0x217,
|
||||||
|
"camera_down" => 0x218,
|
||||||
|
"camera_left" => 0x219,
|
||||||
|
"camera_right" => 0x21a,
|
||||||
|
"attendant_on" => 0x21b,
|
||||||
|
"attendant_off" => 0x21c,
|
||||||
|
"attendant_toggle" => 0x21d,
|
||||||
|
"lights_toggle" => 0x21e,
|
||||||
|
"als_toggle" => 0x230,
|
||||||
|
"rotate_lock_toggle" => 0x231,
|
||||||
|
"refresh_rate_toggle" => 0x232,
|
||||||
|
"buttonconfig" => 0x240,
|
||||||
|
"taskmanager" => 0x241,
|
||||||
|
"journal" => 0x242,
|
||||||
|
"controlpanel" => 0x243,
|
||||||
|
"appselect" => 0x244,
|
||||||
|
"screensaver" => 0x245,
|
||||||
|
"voicecommand" => 0x246,
|
||||||
|
"assistant" => 0x247,
|
||||||
|
"kbd_layout_next" => 0x248,
|
||||||
|
"emoji_picker" => 0x249,
|
||||||
|
"dictate" => 0x24a,
|
||||||
|
"camera_access_enable" => 0x24b,
|
||||||
|
"camera_access_disable" => 0x24c,
|
||||||
|
"camera_access_toggle" => 0x24d,
|
||||||
|
"accessibility" => 0x24e,
|
||||||
|
"do_not_disturb" => 0x24f,
|
||||||
|
"brightness_min" => 0x250,
|
||||||
|
"brightness_max" => 0x251,
|
||||||
|
"kbdinputassist_prev" => 0x260,
|
||||||
|
"kbdinputassist_next" => 0x261,
|
||||||
|
"kbdinputassist_prevgroup" => 0x262,
|
||||||
|
"kbdinputassist_nextgroup" => 0x263,
|
||||||
|
"kbdinputassist_accept" => 0x264,
|
||||||
|
"kbdinputassist_cancel" => 0x265,
|
||||||
|
"right_up" => 0x266,
|
||||||
|
"right_down" => 0x267,
|
||||||
|
"left_up" => 0x268,
|
||||||
|
"left_down" => 0x269,
|
||||||
|
"root_menu" => 0x26a,
|
||||||
|
"media_top_menu" => 0x26b,
|
||||||
|
"numeric_11" => 0x26c,
|
||||||
|
"numeric_12" => 0x26d,
|
||||||
|
"audio_desc" => 0x26e,
|
||||||
|
"3d_mode" => 0x26f,
|
||||||
|
"next_favorite" => 0x270,
|
||||||
|
"stop_record" => 0x271,
|
||||||
|
"pause_record" => 0x272,
|
||||||
|
"vod" => 0x273,
|
||||||
|
"unmute" => 0x274,
|
||||||
|
"fastreverse" => 0x275,
|
||||||
|
"slowreverse" => 0x276,
|
||||||
|
"data" => 0x277,
|
||||||
|
"onscreen_keyboard" => 0x278,
|
||||||
|
"privacy_screen_toggle" => 0x279,
|
||||||
|
"selective_screenshot" => 0x27a,
|
||||||
|
"next_element" => 0x27b,
|
||||||
|
"previous_element" => 0x27c,
|
||||||
|
"autopilot_engage_toggle" => 0x27d,
|
||||||
|
"mark_waypoint" => 0x27e,
|
||||||
|
"sos" => 0x27f,
|
||||||
|
"nav_chart" => 0x280,
|
||||||
|
"fishing_chart" => 0x281,
|
||||||
|
"single_range_radar" => 0x282,
|
||||||
|
"dual_range_radar" => 0x283,
|
||||||
|
"radar_overlay" => 0x284,
|
||||||
|
"traditional_sonar" => 0x285,
|
||||||
|
"clearvu_sonar" => 0x286,
|
||||||
|
"sidevu_sonar" => 0x287,
|
||||||
|
"nav_info" => 0x288,
|
||||||
|
"brightness_menu" => 0x289,
|
||||||
|
"macro1" => 0x290,
|
||||||
|
"macro2" => 0x291,
|
||||||
|
"macro3" => 0x292,
|
||||||
|
"macro4" => 0x293,
|
||||||
|
"macro5" => 0x294,
|
||||||
|
"macro6" => 0x295,
|
||||||
|
"macro7" => 0x296,
|
||||||
|
"macro8" => 0x297,
|
||||||
|
"macro9" => 0x298,
|
||||||
|
"macro10" => 0x299,
|
||||||
|
"macro11" => 0x29a,
|
||||||
|
"macro12" => 0x29b,
|
||||||
|
"macro13" => 0x29c,
|
||||||
|
"macro14" => 0x29d,
|
||||||
|
"macro15" => 0x29e,
|
||||||
|
"macro16" => 0x29f,
|
||||||
|
"macro17" => 0x2a0,
|
||||||
|
"macro18" => 0x2a1,
|
||||||
|
"macro19" => 0x2a2,
|
||||||
|
"macro20" => 0x2a3,
|
||||||
|
"macro21" => 0x2a4,
|
||||||
|
"macro22" => 0x2a5,
|
||||||
|
"macro23" => 0x2a6,
|
||||||
|
"macro24" => 0x2a7,
|
||||||
|
"macro25" => 0x2a8,
|
||||||
|
"macro26" => 0x2a9,
|
||||||
|
"macro27" => 0x2aa,
|
||||||
|
"macro28" => 0x2ab,
|
||||||
|
"macro29" => 0x2ac,
|
||||||
|
"macro30" => 0x2ad,
|
||||||
|
"macro_record_start" => 0x2b0,
|
||||||
|
"macro_record_stop" => 0x2b1,
|
||||||
|
"macro_preset_cycle" => 0x2b2,
|
||||||
|
"macro_preset1" => 0x2b3,
|
||||||
|
"macro_preset2" => 0x2b4,
|
||||||
|
"macro_preset3" => 0x2b5,
|
||||||
|
"kbd_lcd_menu1" => 0x2b8,
|
||||||
|
"kbd_lcd_menu2" => 0x2b9,
|
||||||
|
"kbd_lcd_menu3" => 0x2ba,
|
||||||
|
"kbd_lcd_menu4" => 0x2bb,
|
||||||
|
"kbd_lcd_menu5" => 0x2bc,
|
||||||
|
};
|
||||||
|
|
@ -30,6 +30,7 @@ mod input_match;
|
||||||
pub mod keymap;
|
pub mod keymap;
|
||||||
mod libei;
|
mod libei;
|
||||||
mod log_level;
|
mod log_level;
|
||||||
|
pub mod mark_id;
|
||||||
mod mode;
|
mod mode;
|
||||||
pub mod modified_keysym;
|
pub mod modified_keysym;
|
||||||
mod output;
|
mod output;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
config::{
|
config::{
|
||||||
Action,
|
Action, SimpleCommand,
|
||||||
context::Context,
|
context::Context,
|
||||||
extractor::{Extractor, ExtractorError, arr, bol, n32, opt, str, val},
|
extractor::{Extractor, ExtractorError, arr, bol, n32, opt, str, val},
|
||||||
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
|
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
|
||||||
|
|
@ -17,6 +17,7 @@ use {
|
||||||
input::{InputParser, InputParserError},
|
input::{InputParser, InputParserError},
|
||||||
keymap::{KeymapParser, KeymapParserError},
|
keymap::{KeymapParser, KeymapParserError},
|
||||||
log_level::{LogLevelParser, LogLevelParserError},
|
log_level::{LogLevelParser, LogLevelParserError},
|
||||||
|
mark_id::{MarkIdParser, MarkIdParserError},
|
||||||
output::{OutputParser, OutputParserError},
|
output::{OutputParser, OutputParserError},
|
||||||
output_match::{OutputMatchParser, OutputMatchParserError},
|
output_match::{OutputMatchParser, OutputMatchParserError},
|
||||||
repeat_rate::{RepeatRateParser, RepeatRateParserError},
|
repeat_rate::{RepeatRateParser, RepeatRateParserError},
|
||||||
|
|
@ -81,6 +82,12 @@ pub enum ActionParserError {
|
||||||
MoveToOutput(#[source] OutputMatchParserError),
|
MoveToOutput(#[source] OutputMatchParserError),
|
||||||
#[error("Could not parse a set-repeat-rate action")]
|
#[error("Could not parse a set-repeat-rate action")]
|
||||||
RepeatRate(#[source] RepeatRateParserError),
|
RepeatRate(#[source] RepeatRateParserError),
|
||||||
|
#[error("Could not parse a create-mark action")]
|
||||||
|
CreateMark(#[source] MarkIdParserError),
|
||||||
|
#[error("Could not parse a jump-to-mark action")]
|
||||||
|
JumpToMark(#[source] MarkIdParserError),
|
||||||
|
#[error("Could not parse a copy-mark action")]
|
||||||
|
CopyMark(#[source] MarkIdParserError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ActionParser<'a>(pub &'a Context<'a>);
|
pub struct ActionParser<'a>(pub &'a Context<'a>);
|
||||||
|
|
@ -142,6 +149,8 @@ impl ActionParser<'_> {
|
||||||
"focus-below" => FocusLayerRel(LayerDirection::Below),
|
"focus-below" => FocusLayerRel(LayerDirection::Below),
|
||||||
"focus-above" => FocusLayerRel(LayerDirection::Above),
|
"focus-above" => FocusLayerRel(LayerDirection::Above),
|
||||||
"focus-tiles" => FocusTiles,
|
"focus-tiles" => FocusTiles,
|
||||||
|
"create-mark" => CreateMark,
|
||||||
|
"jump-to-mark" => JumpToMark,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(
|
return Err(
|
||||||
ActionParserError::UnknownSimpleAction(string.to_string()).spanned(span)
|
ActionParserError::UnknownSimpleAction(string.to_string()).spanned(span)
|
||||||
|
|
@ -368,6 +377,43 @@ impl ActionParser<'_> {
|
||||||
name: name.value.to_string(),
|
name: name.value.to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_create_mark(&mut self, ext: &mut Extractor<'_>) -> ParseResult<Self> {
|
||||||
|
let (id,) = ext.extract((opt(val("id")),))?;
|
||||||
|
let Some(id) = id else {
|
||||||
|
return Ok(Action::SimpleCommand {
|
||||||
|
cmd: SimpleCommand::CreateMark,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let id = id
|
||||||
|
.parse(&mut MarkIdParser(self.0))
|
||||||
|
.map_spanned_err(ActionParserError::CreateMark)?;
|
||||||
|
Ok(Action::CreateMark(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_jump_to_mark(&mut self, ext: &mut Extractor<'_>) -> ParseResult<Self> {
|
||||||
|
let (id,) = ext.extract((opt(val("id")),))?;
|
||||||
|
let Some(id) = id else {
|
||||||
|
return Ok(Action::SimpleCommand {
|
||||||
|
cmd: SimpleCommand::JumpToMark,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let id = id
|
||||||
|
.parse(&mut MarkIdParser(self.0))
|
||||||
|
.map_spanned_err(ActionParserError::JumpToMark)?;
|
||||||
|
Ok(Action::JumpToMark(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_copy_mark(&mut self, ext: &mut Extractor<'_>) -> ParseResult<Self> {
|
||||||
|
let (src, dst) = ext.extract((val("src"), val("dst")))?;
|
||||||
|
let src = src
|
||||||
|
.parse(&mut MarkIdParser(self.0))
|
||||||
|
.map_spanned_err(ActionParserError::CopyMark)?;
|
||||||
|
let dst = dst
|
||||||
|
.parse(&mut MarkIdParser(self.0))
|
||||||
|
.map_spanned_err(ActionParserError::CopyMark)?;
|
||||||
|
Ok(Action::CopyMark(src, dst))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parser for ActionParser<'_> {
|
impl Parser for ActionParser<'_> {
|
||||||
|
|
@ -422,6 +468,9 @@ impl Parser for ActionParser<'_> {
|
||||||
"define-action" => self.parse_define_action(&mut ext),
|
"define-action" => self.parse_define_action(&mut ext),
|
||||||
"undefine-action" => self.parse_undefine_action(&mut ext),
|
"undefine-action" => self.parse_undefine_action(&mut ext),
|
||||||
"named" => self.parse_named_action(&mut ext),
|
"named" => self.parse_named_action(&mut ext),
|
||||||
|
"create-mark" => self.parse_create_mark(&mut ext),
|
||||||
|
"jump-to-mark" => self.parse_jump_to_mark(&mut ext),
|
||||||
|
"copy-mark" => self.parse_copy_mark(&mut ext),
|
||||||
v => {
|
v => {
|
||||||
ext.ignore_unused();
|
ext.ignore_unused();
|
||||||
return Err(ActionParserError::UnknownType(v.to_string()).spanned(ty.span));
|
return Err(ActionParserError::UnknownType(v.to_string()).spanned(ty.span));
|
||||||
|
|
|
||||||
61
toml-config/src/config/parsers/mark_id.rs
Normal file
61
toml-config/src/config/parsers/mark_id.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
config::{
|
||||||
|
context::Context,
|
||||||
|
extractor::{Extractor, ExtractorError, opt, str},
|
||||||
|
keycodes::KEYCODES,
|
||||||
|
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
|
||||||
|
},
|
||||||
|
toml::{
|
||||||
|
toml_span::{Span, Spanned, SpannedExt},
|
||||||
|
toml_value::Value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
indexmap::IndexMap,
|
||||||
|
thiserror::Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum MarkIdParserError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Expected(#[from] UnexpectedDataType),
|
||||||
|
#[error(transparent)]
|
||||||
|
Extract(#[from] ExtractorError),
|
||||||
|
#[error("MarkId must have exactly one field set")]
|
||||||
|
ExactlyOneField,
|
||||||
|
#[error("Unknown key {0}")]
|
||||||
|
UnknownKey(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MarkIdParser<'a>(pub &'a Context<'a>);
|
||||||
|
|
||||||
|
impl Parser for MarkIdParser<'_> {
|
||||||
|
type Value = u32;
|
||||||
|
type Error = MarkIdParserError;
|
||||||
|
const EXPECTED: &'static [DataType] = &[DataType::Table];
|
||||||
|
|
||||||
|
fn parse_table(
|
||||||
|
&mut self,
|
||||||
|
span: Span,
|
||||||
|
table: &IndexMap<Spanned<String>, Spanned<Value>>,
|
||||||
|
) -> ParseResult<Self> {
|
||||||
|
let mut ext = Extractor::new(self.0, span, table);
|
||||||
|
let (key, name) = ext.extract((opt(str("key")), opt(str("name"))))?;
|
||||||
|
let id = match (key, name) {
|
||||||
|
(None, None) | (Some(_), Some(_)) => {
|
||||||
|
return Err(MarkIdParserError::ExactlyOneField.spanned(span));
|
||||||
|
}
|
||||||
|
(Some(key), _) => match KEYCODES.get(key.value) {
|
||||||
|
Some(c) => *c,
|
||||||
|
_ => return Err(key.map(|s| MarkIdParserError::UnknownKey(s.to_string()))),
|
||||||
|
},
|
||||||
|
(_, Some(name)) => {
|
||||||
|
let mn = &mut *self.0.mark_names.borrow_mut();
|
||||||
|
let len = mn.len() as u32;
|
||||||
|
*mn.entry(name.value.to_string())
|
||||||
|
.or_insert(u32::MAX - 8 - len)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -168,6 +168,14 @@ impl Action {
|
||||||
let persistent = state.persistent.clone();
|
let persistent = state.persistent.clone();
|
||||||
B::new(move || persistent.seat.focus_tiles())
|
B::new(move || persistent.seat.focus_tiles())
|
||||||
}
|
}
|
||||||
|
SimpleCommand::CreateMark => {
|
||||||
|
let persistent = state.persistent.clone();
|
||||||
|
B::new(move || persistent.seat.create_mark(None))
|
||||||
|
}
|
||||||
|
SimpleCommand::JumpToMark => {
|
||||||
|
let persistent = state.persistent.clone();
|
||||||
|
B::new(move || persistent.seat.jump_to_mark(None))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Action::Multi { actions } => {
|
Action::Multi { actions } => {
|
||||||
let actions: Vec<_> = actions.into_iter().map(|a| a.into_fn(state)).collect();
|
let actions: Vec<_> = actions.into_iter().map(|a| a.into_fn(state)).collect();
|
||||||
|
|
@ -324,6 +332,18 @@ impl Action {
|
||||||
action();
|
action();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Action::CreateMark(m) => {
|
||||||
|
let persistent = state.persistent.clone();
|
||||||
|
B::new(move || persistent.seat.create_mark(Some(m)))
|
||||||
|
}
|
||||||
|
Action::JumpToMark(m) => {
|
||||||
|
let persistent = state.persistent.clone();
|
||||||
|
B::new(move || persistent.seat.jump_to_mark(Some(m)))
|
||||||
|
}
|
||||||
|
Action::CopyMark(s, d) => {
|
||||||
|
let persistent = state.persistent.clone();
|
||||||
|
B::new(move || persistent.seat.copy_mark(s, d))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -973,13 +993,14 @@ struct PersistentState {
|
||||||
client_rules: Cell<Vec<MatcherTemp<ClientRule>>>,
|
client_rules: Cell<Vec<MatcherTemp<ClientRule>>>,
|
||||||
client_rule_mapper: RefCell<Option<RuleMapper<ClientRule>>>,
|
client_rule_mapper: RefCell<Option<RuleMapper<ClientRule>>>,
|
||||||
window_rules: Cell<Vec<MatcherTemp<WindowRule>>>,
|
window_rules: Cell<Vec<MatcherTemp<WindowRule>>>,
|
||||||
|
mark_names: RefCell<AHashMap<String, u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_config(initial_load: bool, persistent: &Rc<PersistentState>) {
|
fn load_config(initial_load: bool, persistent: &Rc<PersistentState>) {
|
||||||
let mut path = PathBuf::from(config_dir());
|
let mut path = PathBuf::from(config_dir());
|
||||||
path.push("config.toml");
|
path.push("config.toml");
|
||||||
let mut config = match std::fs::read(&path) {
|
let mut config = match std::fs::read(&path) {
|
||||||
Ok(input) => match parse_config(&input, |e| {
|
Ok(input) => match parse_config(&input, &persistent.mark_names, |e| {
|
||||||
log::warn!("Error while parsing {}: {}", path.display(), Report::new(e))
|
log::warn!("Error while parsing {}: {}", path.display(), Report::new(e))
|
||||||
}) {
|
}) {
|
||||||
None if initial_load => {
|
None if initial_load => {
|
||||||
|
|
@ -1294,7 +1315,8 @@ fn create_command(exec: &Exec) -> Command {
|
||||||
const DEFAULT: &[u8] = include_bytes!("default-config.toml");
|
const DEFAULT: &[u8] = include_bytes!("default-config.toml");
|
||||||
|
|
||||||
pub fn configure() {
|
pub fn configure() {
|
||||||
let default = parse_config(DEFAULT, |e| {
|
let mark_names = Default::default();
|
||||||
|
let default = parse_config(DEFAULT, &mark_names, |e| {
|
||||||
panic!("Could not parse the default config: {}", Report::new(e))
|
panic!("Could not parse the default config: {}", Report::new(e))
|
||||||
});
|
});
|
||||||
let persistent = Rc::new(PersistentState {
|
let persistent = Rc::new(PersistentState {
|
||||||
|
|
@ -1306,6 +1328,7 @@ pub fn configure() {
|
||||||
client_rules: Default::default(),
|
client_rules: Default::default(),
|
||||||
client_rule_mapper: Default::default(),
|
client_rule_mapper: Default::default(),
|
||||||
window_rules: Default::default(),
|
window_rules: Default::default(),
|
||||||
|
mark_names,
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
let p = persistent.clone();
|
let p = persistent.clone();
|
||||||
|
|
|
||||||
1
toml-config/toml-test
Submodule
1
toml-config/toml-test
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 8448bc678600561a00380dfe18c887cc72d2261d
|
||||||
|
|
@ -479,6 +479,60 @@
|
||||||
"type",
|
"type",
|
||||||
"name"
|
"name"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Creates a mark for the currently focused window.\n\n- Example 1:\n\n This example interactively selects a key that identifies the mark.\n\n ```toml\n [shortcuts]\n alt-x = { type = \"create-mark\" }\n ```\n\n- Example 2:\n\n This example hard-codes a key.\n\n ```toml\n [shortcuts]\n alt-x = { type = \"create-mark\", id.key = \"a\" }\n ```\n",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"const": "create-mark"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"description": "The identifier of the mark.\n\nIf this field is omitted, the next pressed key identifies the mark.\n",
|
||||||
|
"$ref": "#/$defs/MarkId"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Moves the keyboard focus to a window identified by a mark.\n\n- Example 1:\n\n This example interactively selects a key that identifies the mark.\n\n ```toml\n [shortcuts]\n alt-x = { type = \"jump-to-mark\" }\n ```\n\n- Example 2:\n\n This example hard-codes a key.\n\n ```toml\n [shortcuts]\n alt-x = { type = \"jump-to-mark\", id.key = \"a\" }\n ```\n",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"const": "jump-to-mark"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"description": "The identifier of the mark.\n\nIf this field is omitted, the next pressed key identifies the mark.\n",
|
||||||
|
"$ref": "#/$defs/MarkId"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Copies a mark.\n\nIf the `src` id identifies a mark before this function is called, the `dst`\nid will identify the same mark afterwards.\n",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"const": "copy-mark"
|
||||||
|
},
|
||||||
|
"src": {
|
||||||
|
"description": "The source id to copy from.",
|
||||||
|
"$ref": "#/$defs/MarkId"
|
||||||
|
},
|
||||||
|
"dst": {
|
||||||
|
"description": "The destination id to copy to.",
|
||||||
|
"$ref": "#/$defs/MarkId"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"src",
|
||||||
|
"dst"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -1416,6 +1470,21 @@
|
||||||
"error"
|
"error"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"MarkId": {
|
||||||
|
"description": "Identifies a mark.\n\nExactly one of the fields must be set.\n\n- Example:\n\n ```toml\n [shortcuts]\n alt-x = { type = \"create-mark\", id.key = \"a\" }\n ```\n",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"key": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Identifies a mark by a key press.\n\nThe names of the keys can be found in [1] with the `KEY_` prefix removed. The key\nnames must be written all lowercase.\n\n[1]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h\n"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Identifies a mark with an arbitrary string.\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
"MessageFormat": {
|
"MessageFormat": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A message format used by status programs.",
|
"description": "A message format used by status programs.",
|
||||||
|
|
@ -1621,7 +1690,9 @@
|
||||||
"focus-next",
|
"focus-next",
|
||||||
"focus-below",
|
"focus-below",
|
||||||
"focus-above",
|
"focus-above",
|
||||||
"focus-tiles"
|
"focus-tiles",
|
||||||
|
"create-mark",
|
||||||
|
"jump-to-mark"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Status": {
|
"Status": {
|
||||||
|
|
|
||||||
|
|
@ -671,6 +671,91 @@ This table is a tagged union. The variant is determined by the `type` field. It
|
||||||
|
|
||||||
The value of this field should be a string.
|
The value of this field should be a string.
|
||||||
|
|
||||||
|
- `create-mark`:
|
||||||
|
|
||||||
|
Creates a mark for the currently focused window.
|
||||||
|
|
||||||
|
- Example 1:
|
||||||
|
|
||||||
|
This example interactively selects a key that identifies the mark.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "create-mark" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Example 2:
|
||||||
|
|
||||||
|
This example hard-codes a key.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "create-mark", id.key = "a" }
|
||||||
|
```
|
||||||
|
|
||||||
|
The table has the following fields:
|
||||||
|
|
||||||
|
- `id` (optional):
|
||||||
|
|
||||||
|
The identifier of the mark.
|
||||||
|
|
||||||
|
If this field is omitted, the next pressed key identifies the mark.
|
||||||
|
|
||||||
|
The value of this field should be a [MarkId](#types-MarkId).
|
||||||
|
|
||||||
|
- `jump-to-mark`:
|
||||||
|
|
||||||
|
Moves the keyboard focus to a window identified by a mark.
|
||||||
|
|
||||||
|
- Example 1:
|
||||||
|
|
||||||
|
This example interactively selects a key that identifies the mark.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "jump-to-mark" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Example 2:
|
||||||
|
|
||||||
|
This example hard-codes a key.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "jump-to-mark", id.key = "a" }
|
||||||
|
```
|
||||||
|
|
||||||
|
The table has the following fields:
|
||||||
|
|
||||||
|
- `id` (optional):
|
||||||
|
|
||||||
|
The identifier of the mark.
|
||||||
|
|
||||||
|
If this field is omitted, the next pressed key identifies the mark.
|
||||||
|
|
||||||
|
The value of this field should be a [MarkId](#types-MarkId).
|
||||||
|
|
||||||
|
- `copy-mark`:
|
||||||
|
|
||||||
|
Copies a mark.
|
||||||
|
|
||||||
|
If the `src` id identifies a mark before this function is called, the `dst`
|
||||||
|
id will identify the same mark afterwards.
|
||||||
|
|
||||||
|
The table has the following fields:
|
||||||
|
|
||||||
|
- `src` (required):
|
||||||
|
|
||||||
|
The source id to copy from.
|
||||||
|
|
||||||
|
The value of this field should be a [MarkId](#types-MarkId).
|
||||||
|
|
||||||
|
- `dst` (required):
|
||||||
|
|
||||||
|
The destination id to copy to.
|
||||||
|
|
||||||
|
The value of this field should be a [MarkId](#types-MarkId).
|
||||||
|
|
||||||
|
|
||||||
<a name="types-Brightness"></a>
|
<a name="types-Brightness"></a>
|
||||||
### `Brightness`
|
### `Brightness`
|
||||||
|
|
@ -3071,6 +3156,42 @@ The string should have one of the following values:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="types-MarkId"></a>
|
||||||
|
### `MarkId`
|
||||||
|
|
||||||
|
Identifies a mark.
|
||||||
|
|
||||||
|
Exactly one of the fields must be set.
|
||||||
|
|
||||||
|
- Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "create-mark", id.key = "a" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Values of this type should be tables.
|
||||||
|
|
||||||
|
The table has the following fields:
|
||||||
|
|
||||||
|
- `key` (optional):
|
||||||
|
|
||||||
|
Identifies a mark by a key press.
|
||||||
|
|
||||||
|
The names of the keys can be found in [1] with the `KEY_` prefix removed. The key
|
||||||
|
names must be written all lowercase.
|
||||||
|
|
||||||
|
[1]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
|
||||||
|
|
||||||
|
The value of this field should be a string.
|
||||||
|
|
||||||
|
- `name` (optional):
|
||||||
|
|
||||||
|
Identifies a mark with an arbitrary string.
|
||||||
|
|
||||||
|
The value of this field should be a string.
|
||||||
|
|
||||||
|
|
||||||
<a name="types-MessageFormat"></a>
|
<a name="types-MessageFormat"></a>
|
||||||
### `MessageFormat`
|
### `MessageFormat`
|
||||||
|
|
||||||
|
|
@ -3697,6 +3818,18 @@ The string should have one of the following values:
|
||||||
|
|
||||||
Focuses the tile layer.
|
Focuses the tile layer.
|
||||||
|
|
||||||
|
- `create-mark`:
|
||||||
|
|
||||||
|
Interactively creates a mark.
|
||||||
|
|
||||||
|
The next pressed key becomes the identifier for the mark.
|
||||||
|
|
||||||
|
- `jump-to-mark`:
|
||||||
|
|
||||||
|
Interactively jumps to a mark.
|
||||||
|
|
||||||
|
The next pressed key identifies the mark to jump to.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="types-Status"></a>
|
<a name="types-Status"></a>
|
||||||
|
|
|
||||||
|
|
@ -602,6 +602,79 @@ Action:
|
||||||
kind: string
|
kind: string
|
||||||
description: The name of the action.
|
description: The name of the action.
|
||||||
required: true
|
required: true
|
||||||
|
create-mark:
|
||||||
|
description: |
|
||||||
|
Creates a mark for the currently focused window.
|
||||||
|
|
||||||
|
- Example 1:
|
||||||
|
|
||||||
|
This example interactively selects a key that identifies the mark.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "create-mark" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Example 2:
|
||||||
|
|
||||||
|
This example hard-codes a key.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "create-mark", id.key = "a" }
|
||||||
|
```
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
description: |
|
||||||
|
The identifier of the mark.
|
||||||
|
|
||||||
|
If this field is omitted, the next pressed key identifies the mark.
|
||||||
|
required: false
|
||||||
|
ref: MarkId
|
||||||
|
jump-to-mark:
|
||||||
|
description: |
|
||||||
|
Moves the keyboard focus to a window identified by a mark.
|
||||||
|
|
||||||
|
- Example 1:
|
||||||
|
|
||||||
|
This example interactively selects a key that identifies the mark.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "jump-to-mark" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Example 2:
|
||||||
|
|
||||||
|
This example hard-codes a key.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "jump-to-mark", id.key = "a" }
|
||||||
|
```
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
description: |
|
||||||
|
The identifier of the mark.
|
||||||
|
|
||||||
|
If this field is omitted, the next pressed key identifies the mark.
|
||||||
|
required: false
|
||||||
|
ref: MarkId
|
||||||
|
copy-mark:
|
||||||
|
description: |
|
||||||
|
Copies a mark.
|
||||||
|
|
||||||
|
If the `src` id identifies a mark before this function is called, the `dst`
|
||||||
|
id will identify the same mark afterwards.
|
||||||
|
fields:
|
||||||
|
src:
|
||||||
|
description: The source id to copy from.
|
||||||
|
required: true
|
||||||
|
ref: MarkId
|
||||||
|
dst:
|
||||||
|
description: The destination id to copy to.
|
||||||
|
required: true
|
||||||
|
ref: MarkId
|
||||||
|
|
||||||
|
|
||||||
Exec:
|
Exec:
|
||||||
|
|
@ -870,6 +943,16 @@ SimpleActionName:
|
||||||
description: Focuses the layer above the currently focused layer.
|
description: Focuses the layer above the currently focused layer.
|
||||||
- value: focus-tiles
|
- value: focus-tiles
|
||||||
description: Focuses the tile layer.
|
description: Focuses the tile layer.
|
||||||
|
- value: create-mark
|
||||||
|
description: |
|
||||||
|
Interactively creates a mark.
|
||||||
|
|
||||||
|
The next pressed key becomes the identifier for the mark.
|
||||||
|
- value: jump-to-mark
|
||||||
|
description: |
|
||||||
|
Interactively jumps to a mark.
|
||||||
|
|
||||||
|
The next pressed key identifies the mark to jump to.
|
||||||
|
|
||||||
|
|
||||||
Color:
|
Color:
|
||||||
|
|
@ -3779,3 +3862,34 @@ FocusHistory:
|
||||||
The default is `false`.
|
The default is `false`.
|
||||||
kind: boolean
|
kind: boolean
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
|
||||||
|
MarkId:
|
||||||
|
kind: table
|
||||||
|
description: |
|
||||||
|
Identifies a mark.
|
||||||
|
|
||||||
|
Exactly one of the fields must be set.
|
||||||
|
|
||||||
|
- Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[shortcuts]
|
||||||
|
alt-x = { type = "create-mark", id.key = "a" }
|
||||||
|
```
|
||||||
|
fields:
|
||||||
|
key:
|
||||||
|
description: |
|
||||||
|
Identifies a mark by a key press.
|
||||||
|
|
||||||
|
The names of the keys can be found in [1] with the `KEY_` prefix removed. The key
|
||||||
|
names must be written all lowercase.
|
||||||
|
|
||||||
|
[1]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
|
||||||
|
kind: string
|
||||||
|
required: false
|
||||||
|
name:
|
||||||
|
description: |
|
||||||
|
Identifies a mark with an arbitrary string.
|
||||||
|
kind: string
|
||||||
|
required: false
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue