feat: support direct session vt switching
This commit is contained in:
1 parent
ee9da5d8c9
commit
bf512cdd9b
2 files changed
+71
No files matched your search
@@ -273,6 +273,16 @@ pub fn render_all(state: &mut Ferese) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn switch_vt(state: &mut Ferese, vt: i32) {
|
||||||
|
let Some(backend) = state.direct_backend.as_mut() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(error) = backend.session.change_vt(vt) {
|
||||||
|
tracing::error!(vt, %error, "failed to switch virtual terminal");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn render_device(state: &mut Ferese, node: DrmNode) {
|
fn render_device(state: &mut Ferese, node: DrmNode) {
|
||||||
let Some(mut device) = state
|
let Some(mut device) = state
|
||||||
.direct_backend
|
.direct_backend
|
||||||
|
|||||||
@@ -35,6 +35,20 @@ impl Ferese {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let symbol = keysym.modified_sym().raw();
|
let symbol = keysym.modified_sym().raw();
|
||||||
|
if let Some(vt) = virtual_terminal(
|
||||||
|
symbol,
|
||||||
|
modifiers.ctrl,
|
||||||
|
modifiers.alt,
|
||||||
|
data.direct_backend.is_some(),
|
||||||
|
) {
|
||||||
|
if state == KeyState::Pressed {
|
||||||
|
data.intercepted_keys.insert(keycode);
|
||||||
|
crate::backends::direct::switch_vt(data, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FilterResult::Intercept(());
|
||||||
|
}
|
||||||
|
|
||||||
let direction = if modifiers.logo && !modifiers.ctrl && !modifiers.alt {
|
let direction = if modifiers.logo && !modifiers.ctrl && !modifiers.alt {
|
||||||
match symbol {
|
match symbol {
|
||||||
keysyms::KEY_h | keysyms::KEY_H => Some(Direction::Left),
|
keysyms::KEY_h | keysyms::KEY_H => Some(Direction::Left),
|
||||||
@@ -344,3 +358,50 @@ impl Ferese {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn virtual_terminal(symbol: u32, ctrl: bool, alt: bool, direct: bool) -> Option<i32> {
|
||||||
|
if !direct {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysyms::KEY_XF86Switch_VT_1..=keysyms::KEY_XF86Switch_VT_12).contains(&symbol) {
|
||||||
|
return Some((symbol - keysyms::KEY_XF86Switch_VT_1 + 1) as i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
(ctrl && alt && (keysyms::KEY_F1..=keysyms::KEY_F12).contains(&symbol))
|
||||||
|
.then_some((symbol - keysyms::KEY_F1 + 1) as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::virtual_terminal;
|
||||||
|
use smithay::input::keyboard::keysyms;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn maps_xkb_virtual_terminal_symbols_for_direct_sessions() {
|
||||||
|
assert_eq!(
|
||||||
|
virtual_terminal(keysyms::KEY_XF86Switch_VT_1, false, false, true),
|
||||||
|
Some(1)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
virtual_terminal(keysyms::KEY_XF86Switch_VT_12, false, false, true),
|
||||||
|
Some(12)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn accepts_plain_function_symbols_only_with_control_alt() {
|
||||||
|
assert_eq!(virtual_terminal(keysyms::KEY_F7, true, true, true), Some(7));
|
||||||
|
assert_eq!(virtual_terminal(keysyms::KEY_F7, true, false, true), None);
|
||||||
|
assert_eq!(virtual_terminal(keysyms::KEY_F7, false, true, true), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn leaves_virtual_terminal_keys_to_nested_clients() {
|
||||||
|
assert_eq!(
|
||||||
|
virtual_terminal(keysyms::KEY_XF86Switch_VT_3, false, false, false),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
assert_eq!(virtual_terminal(keysyms::KEY_F3, true, true, false), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user