Make Super_L chordable and implement hyprland-global-shortcuts-v1
This commit is contained in:
parent
8ff17aca1e
commit
6d3bff952e
16 changed files with 363 additions and 16 deletions
|
|
@ -204,6 +204,10 @@ pub enum Action {
|
|||
dx2: i32,
|
||||
dy2: i32,
|
||||
},
|
||||
TriggerGlobalShortcut {
|
||||
app_id: String,
|
||||
id: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
|
|
|||
|
|
@ -93,6 +93,10 @@ pub enum ActionParserError {
|
|||
UnknownDirection(String),
|
||||
#[error("Exactly one of `output` or `direction` must be specified")]
|
||||
OutputAndDirectionMutuallyExclusive,
|
||||
#[error("Specify either `name = \"app_id:id\"` or both `app_id` and `id`")]
|
||||
GlobalShortcutNeedsName,
|
||||
#[error("Global shortcut `name` must be of the form `app_id:id`, got `{0}`")]
|
||||
GlobalShortcutBadName(String),
|
||||
}
|
||||
|
||||
pub struct ActionParser<'a>(pub &'a Context<'a>);
|
||||
|
|
@ -516,6 +520,36 @@ impl ActionParser<'_> {
|
|||
dy2: dy2.despan().unwrap_or(0),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_global_shortcut(
|
||||
&mut self,
|
||||
span: Span,
|
||||
ext: &mut Extractor<'_>,
|
||||
) -> ParseResult<Self> {
|
||||
let (name_opt, app_id_opt, id_opt) = ext.extract((
|
||||
opt(str("name")),
|
||||
opt(str("app_id")),
|
||||
opt(str("id")),
|
||||
))?;
|
||||
let (app_id, id) = match (app_id_opt, id_opt, name_opt) {
|
||||
(Some(a), Some(i), _) => (a.value.to_string(), i.value.to_string()),
|
||||
(None, None, Some(n)) => match n.value.split_once(':') {
|
||||
Some((a, i)) if !a.is_empty() && !i.is_empty() => {
|
||||
(a.to_string(), i.to_string())
|
||||
}
|
||||
_ => {
|
||||
return Err(
|
||||
ActionParserError::GlobalShortcutBadName(n.value.to_string())
|
||||
.spanned(n.span),
|
||||
);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(ActionParserError::GlobalShortcutNeedsName.spanned(span));
|
||||
}
|
||||
};
|
||||
Ok(Action::TriggerGlobalShortcut { app_id, id })
|
||||
}
|
||||
}
|
||||
|
||||
impl Parser for ActionParser<'_> {
|
||||
|
|
@ -578,6 +612,7 @@ impl Parser for ActionParser<'_> {
|
|||
"create-virtual-output" => self.parse_create_virtual_output(&mut ext),
|
||||
"remove-virtual-output" => self.parse_remove_virtual_output(&mut ext),
|
||||
"resize" => self.parse_resize(&mut ext),
|
||||
"global-shortcut" => self.parse_global_shortcut(span, &mut ext),
|
||||
v => {
|
||||
ext.ignore_unused();
|
||||
return Err(ActionParserError::UnknownType(v.to_string()).spanned(ty.span));
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ use {
|
|||
ALT, CAPS, CTRL, LOCK, LOGO, MOD1, MOD2, MOD3, MOD4, MOD5, Modifiers, NUM, RELEASE,
|
||||
SHIFT,
|
||||
},
|
||||
syms::KeySym,
|
||||
syms::{
|
||||
KeySym, SYM_Alt_L, SYM_Alt_R, SYM_Control_L, SYM_Control_R, SYM_Hyper_L, SYM_Hyper_R,
|
||||
SYM_Meta_L, SYM_Meta_R, SYM_Shift_L, SYM_Shift_R, SYM_Super_L, SYM_Super_R,
|
||||
},
|
||||
},
|
||||
kbvm::Keysym,
|
||||
thiserror::Error,
|
||||
|
|
@ -38,23 +41,28 @@ impl Parser for ModifiedKeysymParser {
|
|||
|
||||
fn parse_string(&mut self, span: Span, string: &str) -> ParseResult<Self> {
|
||||
let mut modifiers = Modifiers(0);
|
||||
let mut sym = None;
|
||||
let mut sym: Option<KeySym> = None;
|
||||
for part in string.split("-") {
|
||||
let modifier = match parse_mod(part) {
|
||||
Some(m) => m,
|
||||
_ => match Keysym::from_str(part) {
|
||||
Some(new) if sym.is_none() => {
|
||||
sym = Some(KeySym(new.0));
|
||||
continue;
|
||||
}
|
||||
Some(_) => return Err(ModifiedKeysymParserError::MoreThanOneSym.spanned(span)),
|
||||
_ => {
|
||||
return Err(ModifiedKeysymParserError::UnknownKeysym(part.to_string())
|
||||
.spanned(span));
|
||||
}
|
||||
},
|
||||
if let Some(m) = parse_mod(part) {
|
||||
modifiers |= m;
|
||||
continue;
|
||||
}
|
||||
let Some(new) = Keysym::from_str(part) else {
|
||||
return Err(
|
||||
ModifiedKeysymParserError::UnknownKeysym(part.to_string()).spanned(span),
|
||||
);
|
||||
};
|
||||
modifiers |= modifier;
|
||||
let new = KeySym(new.0);
|
||||
match sym {
|
||||
None => sym = Some(new),
|
||||
Some(prev) => {
|
||||
let Some(m) = modifier_key_to_mod(prev) else {
|
||||
return Err(ModifiedKeysymParserError::MoreThanOneSym.spanned(span));
|
||||
};
|
||||
modifiers |= m;
|
||||
sym = Some(new);
|
||||
}
|
||||
}
|
||||
}
|
||||
match sym {
|
||||
Some(s) => Ok(modifiers | s),
|
||||
|
|
@ -63,6 +71,20 @@ impl Parser for ModifiedKeysymParser {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
fn modifier_key_to_mod(sym: KeySym) -> Option<Modifiers> {
|
||||
let m = match sym {
|
||||
SYM_Super_L | SYM_Super_R => LOGO,
|
||||
SYM_Alt_L | SYM_Alt_R => ALT,
|
||||
SYM_Control_L | SYM_Control_R => CTRL,
|
||||
SYM_Shift_L | SYM_Shift_R => SHIFT,
|
||||
SYM_Meta_L | SYM_Meta_R => MOD1,
|
||||
SYM_Hyper_L | SYM_Hyper_R => MOD4,
|
||||
_ => return None,
|
||||
};
|
||||
Some(m)
|
||||
}
|
||||
|
||||
pub struct ModifiersParser;
|
||||
|
||||
impl Parser for ModifiersParser {
|
||||
|
|
|
|||
|
|
@ -508,6 +508,11 @@ impl Action {
|
|||
Action::Resize { dx1, dy1, dx2, dy2 } => {
|
||||
window_or_seat!(s, s.resize(dx1, dy1, dx2, dy2))
|
||||
}
|
||||
Action::TriggerGlobalShortcut { app_id, id } => {
|
||||
b.new(move || {
|
||||
jay_config::trigger_global_shortcut(&app_id, &id);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue