cosmic-comp/src/shell/layout/tiling/grabs/swap.rs
2024-07-15 16:31:24 +02:00

107 lines
2.9 KiB
Rust

use cosmic_settings_config::shortcuts;
use smithay::{
backend::input::KeyState,
input::{
keyboard::{
GrabStartData as KeyboardGrabStartData, KeyboardGrab, KeyboardInnerHandle,
ModifiersState,
},
Seat, SeatHandler,
},
utils::Serial,
};
use xkbcommon::xkb::Keysym;
use crate::{
config::key_bindings::cosmic_modifiers_from_smithay,
shell::{layout::tiling::NodeDesc, Trigger},
state::State,
};
pub struct SwapWindowGrab {
seat: Seat<State>,
desc: NodeDesc,
}
impl SwapWindowGrab {
pub fn new(seat: Seat<State>, desc: NodeDesc) -> Self {
SwapWindowGrab { seat, desc }
}
}
impl KeyboardGrab<State> for SwapWindowGrab {
fn input(
&mut self,
data: &mut State,
handle: &mut KeyboardInnerHandle<'_, State>,
keycode: u32,
state: KeyState,
modifiers: Option<ModifiersState>,
serial: Serial,
time: u32,
) {
if !matches!(&data.common.shell.read().unwrap().overview_mode.active_trigger(), Some(Trigger::KeyboardSwap(_, d)) if d == &self.desc)
{
handle.unset_grab(self, data, serial, false);
return;
}
if state == KeyState::Released {
return;
}
let syms = Vec::from(handle.keysym_handle(keycode).raw_syms());
let focus_bindings = &data
.common
.config
.shortcuts
.iter()
.filter(|(_, action)| matches!(action, shortcuts::Action::Focus(_)))
.map(|(pattern, action)| {
let shortcuts::Action::Focus(direction) = action else {
unreachable!()
};
(pattern.key, *direction)
})
.collect::<Vec<_>>();
let Some(direction) = syms.iter().find_map(|sym| {
focus_bindings.iter().find_map(|(key, direction)| {
(key.is_some() && sym == key.as_ref().unwrap()).then_some(*direction)
})
}) else {
return;
};
data.handle_shortcut_action(
shortcuts::Action::Focus(direction),
&self.seat,
serial,
time,
shortcuts::Binding {
modifiers: modifiers
.map(cosmic_modifiers_from_smithay)
.unwrap_or_default(),
key: Some(Keysym::new(keycode)),
description: None,
},
None,
true,
);
}
fn set_focus(
&mut self,
data: &mut State,
handle: &mut KeyboardInnerHandle<'_, State>,
focus: Option<<State as SeatHandler>::KeyboardFocus>,
serial: Serial,
) {
handle.set_focus(data, focus, serial)
}
fn start_data(&self) -> &KeyboardGrabStartData<State> {
&KeyboardGrabStartData { focus: None }
}
fn unset(&mut self, _state: &mut State) {}
}