feat: runtime configurable keybindings

This commit is contained in:
Michael Aaron Murphy 2024-04-03 16:02:27 +02:00 committed by Michael Murphy
parent 62afa4cf61
commit 553c49b42b
25 changed files with 674 additions and 829 deletions

View file

@ -72,13 +72,14 @@ use smithay::desktop::WindowSurface;
use tracing::debug;
use super::{
focus::{target::PointerFocusTarget, FocusDirection},
focus::target::PointerFocusTarget,
layout::{
floating::{ResizeState, TiledCorners},
tiling::NodeDesc,
},
Direction, ManagedLayer, SeatExt,
ManagedLayer, SeatExt,
};
use cosmic_settings_config::shortcuts::action::{Direction, FocusDirection};
space_elements! {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]

View file

@ -1,9 +1,9 @@
use std::sync::Mutex;
use crate::{
config::{Action, Config},
config::Config,
fl,
shell::{grabs::ResizeEdge, ResizeDirection},
shell::grabs::ResizeEdge,
utils::iced::{IcedElement, Program},
};
@ -15,6 +15,7 @@ use cosmic::{
widget::{icon::from_name, text},
Apply,
};
use cosmic_settings_config::shortcuts::action::{Action, ResizeDirection};
use smithay::utils::Size;
pub type ResizeIndicator = IcedElement<ResizeIndicatorInternal>;
@ -30,8 +31,7 @@ pub fn resize_indicator(
edges: Mutex::new(ResizeEdge::all()),
direction,
shortcut1: config
.static_conf
.key_bindings
.shortcuts
.iter()
.find_map(|(pattern, action)| {
(*action == Action::Resizing(ResizeDirection::Outwards)).then_some(pattern)
@ -39,8 +39,7 @@ pub fn resize_indicator(
.map(|pattern| format!("{}: ", pattern.to_string()))
.unwrap_or_else(|| crate::fl!("unknown-keybinding")),
shortcut2: config
.static_conf
.key_bindings
.shortcuts
.iter()
.find_map(|(pattern, action)| {
(*action == Action::Resizing(ResizeDirection::Inwards)).then_some(pattern)

View file

@ -2,10 +2,9 @@ use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface};
use crate::{
backend::render::cursor::{CursorShape, CursorState},
shell::{
focus::{target::PointerFocusTarget, FocusDirection},
focus::target::PointerFocusTarget,
grabs::{ReleaseMode, ResizeEdge},
layout::tiling::NodeDesc,
Direction,
},
state::State,
utils::{
@ -21,7 +20,9 @@ use cosmic::{
iced_widget::scrollable::AbsoluteOffset,
theme, widget as cosmic_widget, Apply, Element as CosmicElement,
};
use cosmic_settings_config::shortcuts;
use once_cell::sync::Lazy;
use shortcuts::action::{Direction, FocusDirection};
use smithay::{
backend::{
input::KeyState,

View file

@ -27,16 +27,6 @@ use super::{layout::floating::FloatingLayout, SeatExt};
pub mod target;
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
pub enum FocusDirection {
Left,
Right,
Up,
Down,
In,
Out,
}
pub struct FocusStack<'a>(pub(super) Option<&'a IndexSet<CosmicMapped>>);
pub struct FocusStackMut<'a>(pub(super) &'a mut IndexSet<CosmicMapped>);

View file

@ -1,7 +1,8 @@
use cosmic_settings_config::shortcuts::Action;
use smithay::{input::pointer::MotionEvent, utils::SERIAL_COUNTER, wayland::seat::WaylandFocus};
use crate::{
config::{Action, StaticConfig},
config::Config,
fl,
shell::{
element::{CosmicMapped, CosmicWindow},
@ -93,7 +94,7 @@ pub fn tab_items(
stack: &CosmicMapped,
tab: &CosmicSurface,
is_tiled: bool,
config: &StaticConfig,
config: &Config,
) -> impl Iterator<Item = Item> {
let unstack_clone_stack = stack.clone();
let unstack_clone_tab = tab.clone();
@ -145,7 +146,7 @@ pub fn tab_items(
Item::new(fl!("window-menu-close"), move |_handle| {
close_clone.close();
})
.shortcut(config.get_shortcut_for_action(&Action::Close)),
.shortcut(config.shortcut_for_action(&Action::Close)),
]
.into_iter()
}
@ -157,7 +158,7 @@ pub fn window_items(
is_sticky: bool,
tiling_enabled: bool,
possible_resizes: ResizeEdge,
config: &StaticConfig,
config: &Config,
) -> impl Iterator<Item = Item> {
let minimize_clone = window.clone();
let maximize_clone = window.clone();
@ -181,7 +182,7 @@ pub fn window_items(
let mapped = stack_clone.clone();
let _ = handle.insert_idle(move |state| toggle_stacking(state, &mapped));
})
.shortcut(config.get_shortcut_for_action(&Action::ToggleStacking)),
.shortcut(config.shortcut_for_action(&Action::ToggleStacking)),
),
is_stacked.then_some(
Item::new(fl!("window-menu-unstack-all"), move |handle| {
@ -190,7 +191,7 @@ pub fn window_items(
toggle_stacking(state, &mapped);
});
})
.shortcut(config.get_shortcut_for_action(&Action::ToggleStacking)),
.shortcut(config.shortcut_for_action(&Action::ToggleStacking)),
),
Some(Item::Separator),
Some(
@ -205,7 +206,7 @@ pub fn window_items(
.minimize_request(&mapped);
});
})
.shortcut(config.get_shortcut_for_action(&Action::Minimize)),
.shortcut(config.shortcut_for_action(&Action::Minimize)),
),
Some(
Item::new(fl!("window-menu-maximize"), move |handle| {
@ -216,7 +217,7 @@ pub fn window_items(
shell.maximize_toggle(&mapped, &seat);
});
})
.shortcut(config.get_shortcut_for_action(&Action::Maximize))
.shortcut(config.shortcut_for_action(&Action::Maximize))
.toggled(window.is_maximized(false)),
),
(tiling_enabled && !is_sticky).then_some(
@ -230,7 +231,7 @@ pub fn window_items(
}
});
})
.shortcut(config.get_shortcut_for_action(&Action::ToggleWindowFloating))
.shortcut(config.shortcut_for_action(&Action::ToggleWindowFloating))
.toggled(!is_tiled),
),
Some(Item::Separator),
@ -410,7 +411,7 @@ pub fn window_items(
let mapped = move_prev_clone.clone();
let _ = handle.insert_idle(move |state| move_prev_workspace(state, &mapped));
})
.shortcut(config.get_shortcut_for_action(&Action::MoveToPreviousWorkspace))
.shortcut(config.shortcut_for_action(&Action::MoveToPreviousWorkspace))
.disabled(is_sticky),
),
Some(
@ -418,7 +419,7 @@ pub fn window_items(
let mapped = move_next_clone.clone();
let _ = handle.insert_idle(move |state| move_next_workspace(state, &mapped));
})
.shortcut(config.get_shortcut_for_action(&Action::MoveToNextWorkspace))
.shortcut(config.shortcut_for_action(&Action::MoveToNextWorkspace))
.disabled(is_sticky),
),
Some(Item::Separator),
@ -445,7 +446,7 @@ pub fn window_items(
Item::new(fl!("window-menu-close"), move |_handle| {
close_clone.send_close();
})
.shortcut(config.get_shortcut_for_action(&Action::Close)),
.shortcut(config.shortcut_for_action(&Action::Close)),
)
},
]

View file

@ -1,3 +1,4 @@
use cosmic_settings_config::shortcuts;
use smithay::{
input::{
pointer::{
@ -106,6 +107,36 @@ impl ResizeEdge {
}
}
impl From<shortcuts::action::ResizeEdge> for ResizeEdge {
fn from(edge: shortcuts::action::ResizeEdge) -> Self {
match edge {
shortcuts::action::ResizeEdge::Bottom => ResizeEdge::BOTTOM,
shortcuts::action::ResizeEdge::BottomLeft => ResizeEdge::BOTTOM_LEFT,
shortcuts::action::ResizeEdge::BottomRight => ResizeEdge::BOTTOM_RIGHT,
shortcuts::action::ResizeEdge::Left => ResizeEdge::LEFT,
shortcuts::action::ResizeEdge::Right => ResizeEdge::RIGHT,
shortcuts::action::ResizeEdge::Top => ResizeEdge::TOP,
shortcuts::action::ResizeEdge::TopLeft => ResizeEdge::TOP_LEFT,
shortcuts::action::ResizeEdge::TopRight => ResizeEdge::TOP_RIGHT,
}
}
}
impl Into<shortcuts::action::ResizeEdge> for ResizeEdge {
fn into(self) -> shortcuts::action::ResizeEdge {
match self {
ResizeEdge::BOTTOM => shortcuts::action::ResizeEdge::Bottom,
ResizeEdge::BOTTOM_LEFT => shortcuts::action::ResizeEdge::BottomLeft,
ResizeEdge::BOTTOM_RIGHT => shortcuts::action::ResizeEdge::BottomRight,
ResizeEdge::LEFT => shortcuts::action::ResizeEdge::Left,
ResizeEdge::RIGHT => shortcuts::action::ResizeEdge::Right,
ResizeEdge::TOP => shortcuts::action::ResizeEdge::Top,
ResizeEdge::TOP_LEFT => shortcuts::action::ResizeEdge::TopLeft,
_ => shortcuts::action::ResizeEdge::TopRight,
}
}
}
impl From<xdg_toplevel::ResizeEdge> for ResizeEdge {
#[inline]
fn from(x: xdg_toplevel::ResizeEdge) -> Self {

View file

@ -863,7 +863,8 @@ impl Drop for MoveGrab {
state,
Some((
target,
position.as_logical().to_f64() - window.geometry().loc.to_f64() + offset,
position.as_logical().to_f64() - window.geometry().loc.to_f64()
+ offset,
)),
&MotionEvent {
location: pointer.current_location(),

View file

@ -6,6 +6,7 @@ use std::{
time::{Duration, Instant},
};
use cosmic_settings_config::shortcuts::action::ResizeDirection;
use keyframe::{ease, functions::EaseInOutCubic};
use smithay::{
backend::renderer::{
@ -36,7 +37,7 @@ use crate::{
FocusStackMut,
},
grabs::{GrabStartData, ReleaseMode, ResizeEdge},
CosmicSurface, Direction, ManagedLayer, MoveResult, ResizeDirection, ResizeMode,
CosmicSurface, Direction, ManagedLayer, MoveResult, ResizeMode,
},
state::State,
utils::{prelude::*, tween::EaseRectangle},

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic_settings_config::shortcuts::action::Orientation;
use regex::RegexSet;
use smithay::{
desktop::WindowSurface,
@ -12,22 +13,6 @@ use super::CosmicSurface;
pub mod floating;
pub mod tiling;
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Orientation {
Horizontal,
Vertical,
}
impl std::ops::Not for Orientation {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Orientation::Horizontal => Orientation::Vertical,
Orientation::Vertical => Orientation::Horizontal,
}
}
}
lazy_static::lazy_static! {
static ref EXCEPTIONS_APPID: RegexSet = RegexSet::new(&[
r"Authy Desktop",

View file

@ -1,3 +1,4 @@
use cosmic_settings_config::shortcuts;
use smithay::{
backend::input::KeyState,
input::{
@ -12,7 +13,7 @@ use smithay::{
use xkbcommon::xkb::Keysym;
use crate::{
config::{Action, KeyPattern},
config::key_bindings::cosmic_modifiers_from_smithay,
shell::{layout::tiling::NodeDesc, OverviewMode, Trigger},
state::State,
};
@ -53,12 +54,11 @@ impl KeyboardGrab<State> for SwapWindowGrab {
let focus_bindings = &data
.common
.config
.static_conf
.key_bindings
.shortcuts
.iter()
.filter(|(_, action)| matches!(action, Action::Focus(_)))
.filter(|(_, action)| matches!(action, shortcuts::Action::Focus(_)))
.map(|(pattern, action)| {
let Action::Focus(direction) = action else {
let shortcuts::Action::Focus(direction) = action else {
unreachable!()
};
(pattern.key, *direction)
@ -72,14 +72,17 @@ impl KeyboardGrab<State> for SwapWindowGrab {
return;
};
data.handle_action(
Action::Focus(direction),
data.handle_shortcut_action(
shortcuts::Action::Focus(direction),
&self.seat,
serial,
time,
KeyPattern {
modifiers: modifiers.map(Into::into).unwrap_or_default(),
shortcuts::Binding {
modifiers: modifiers
.map(cosmic_modifiers_from_smithay)
.unwrap_or_default(),
key: Some(Keysym::new(keycode)),
description: None,
},
None,
true,

View file

@ -18,12 +18,12 @@ use crate::{
},
focus::{
target::{KeyboardFocusTarget, PointerFocusTarget, WindowGroup},
FocusDirection, FocusStackMut,
FocusStackMut,
},
grabs::ResizeEdge,
layout::Orientation,
CosmicSurface, Direction, FocusResult, MoveResult, OutputNotMapped, OverviewMode,
ResizeDirection, ResizeMode, Trigger,
ResizeMode, Trigger,
},
utils::{prelude::*, tween::EaseRectangle},
wayland::{
@ -38,6 +38,7 @@ use crate::{
},
};
use cosmic_settings_config::shortcuts::action::{FocusDirection, ResizeDirection};
use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree};
use keyframe::{
ease,

View file

@ -15,6 +15,8 @@ use cosmic_comp_config::{
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::{
State as WState, TilingState,
};
use cosmic_settings_config::shortcuts;
use cosmic_settings_config::shortcuts::action::{Direction, FocusDirection, ResizeDirection};
use keyframe::{ease, functions::EaseInOutCubic};
use smithay::{
backend::{input::TouchSlot, renderer::element::RenderElementStates},
@ -49,7 +51,7 @@ use smithay::{
use crate::{
backend::render::animations::spring::{Spring, SpringParams},
config::{Config, KeyModifiers, KeyPattern},
config::Config,
utils::prelude::*,
wayland::{
handlers::{
@ -78,16 +80,14 @@ mod workspace;
pub use self::element::{CosmicMapped, CosmicMappedRenderElement, CosmicSurface};
pub use self::seats::*;
pub use self::workspace::*;
use self::{
element::{
resize_indicator::{resize_indicator, ResizeIndicator},
swap_indicator::{swap_indicator, SwapIndicator},
CosmicWindow, MaximizedState,
},
focus::{
target::{KeyboardFocusTarget, PointerFocusTarget},
FocusDirection,
},
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
grabs::{
tab_items, window_items, GrabStartData, Item, MenuGrab, MoveGrab, ReleaseMode, ResizeEdge,
ResizeGrab,
@ -106,8 +106,8 @@ const MOVE_GRAB_Y_OFFSET: f64 = 16.;
#[derive(Debug, Clone)]
pub enum Trigger {
KeyboardSwap(KeyPattern, NodeDesc),
KeyboardMove(KeyModifiers),
KeyboardSwap(shortcuts::Binding, NodeDesc),
KeyboardMove(shortcuts::Modifiers),
Pointer(u32),
Touch(TouchSlot),
}
@ -141,16 +141,10 @@ impl OverviewMode {
}
}
#[derive(Debug, Clone, Copy, serde::Deserialize, PartialEq, Eq, Hash)]
pub enum ResizeDirection {
Inwards,
Outwards,
}
#[derive(Debug, Clone)]
pub enum ResizeMode {
None,
Started(KeyPattern, Instant, ResizeDirection),
Started(shortcuts::Binding, Instant, ResizeDirection),
Ended(Instant, ResizeDirection),
}
@ -1596,7 +1590,7 @@ impl Shell {
pub fn set_resize_mode(
&mut self,
enabled: Option<(KeyPattern, ResizeDirection)>,
enabled: Option<(shortcuts::Binding, ResizeDirection)>,
config: &Config,
evlh: LoopHandle<'static, crate::state::State>,
) {
@ -2306,14 +2300,14 @@ impl Shell {
is_sticky,
tiling_enabled,
edge,
&config.static_conf,
config,
)) as Box<dyn Iterator<Item = Item>>
} else {
let (tab, _) = mapped
.windows()
.find(|(s, _)| s.wl_surface().as_deref() == Some(surface))
.unwrap();
Box::new(tab_items(&mapped, &tab, is_tiled, &config.static_conf))
Box::new(tab_items(&mapped, &tab, is_tiled, config))
as Box<dyn Iterator<Item = Item>>
},
global_position,

View file

@ -192,26 +192,6 @@ pub enum ManagedLayer {
Sticky,
}
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
Left,
Right,
Up,
Down,
}
impl std::ops::Not for Direction {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Direction::Left => Direction::Right,
Direction::Right => Direction::Left,
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum FocusResult {
None,