shell/tiling: Implement window swap mode

This commit is contained in:
Victoria Brekenfeld 2023-08-11 18:15:22 +02:00
parent ac4bf01315
commit 1251b7e9f7
18 changed files with 1305 additions and 197 deletions

View file

@ -13,7 +13,7 @@ use smithay::{
use std::collections::HashMap;
use crate::{
backend::render::{element::AsGlowRenderer, IndicatorShader},
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
shell::{
element::{
resize_indicator::ResizeIndicator, stack::CosmicStackRenderElement,
@ -514,7 +514,7 @@ impl FloatingLayout {
if indicator_thickness > 0 {
let element = IndicatorShader::focus_element(
renderer,
elem.clone(),
Key::Window(Usage::FocusIndicator, elem.clone()),
indicator_geometry,
indicator_thickness,
output_scale,

View file

@ -1,3 +1,5 @@
mod resize;
mod swap;
pub use self::resize::*;
pub use self::swap::*;

View file

@ -0,0 +1,93 @@
use smithay::{
backend::input::KeyState,
input::{
keyboard::{
GrabStartData as KeyboardGrabStartData, KeyboardGrab, KeyboardInnerHandle,
ModifiersState,
},
Seat, SeatHandler,
},
utils::Serial,
};
use crate::{
config::{Action, KeyPattern},
shell::{layout::tiling::NodeDesc, OverviewMode, 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 self.desc.output.upgrade().is_none()
|| !matches!(&data.common.shell.overview_mode, OverviewMode::Started(Trigger::KeyboardSwap(_, d), _) if d == &self.desc)
{
handle.unset_grab(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
.static_conf
.key_bindings
.iter()
.filter(|(_, action)| matches!(action, Action::Focus(_)))
.map(|(pattern, action)| {
let 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)| (sym == key).then_some(*direction))) else { return };
data.handle_action(
Action::Focus(direction),
&self.seat,
serial,
time,
KeyPattern {
modifiers: modifiers.map(Into::into).unwrap_or_default(),
key: keycode,
},
None,
);
}
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 }
}
}

File diff suppressed because it is too large Load diff