feat: runtime configurable keybindings
This commit is contained in:
parent
62afa4cf61
commit
553c49b42b
25 changed files with 674 additions and 829 deletions
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
)
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue