shell/tiling: Implement window swap mode
This commit is contained in:
parent
ac4bf01315
commit
1251b7e9f7
18 changed files with 1305 additions and 197 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
mod resize;
|
||||
mod swap;
|
||||
|
||||
pub use self::resize::*;
|
||||
pub use self::swap::*;
|
||||
|
|
|
|||
93
src/shell/layout/tiling/grabs/swap.rs
Normal file
93
src/shell/layout/tiling/grabs/swap.rs
Normal 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
Loading…
Add table
Add a link
Reference in a new issue