input: Wire up internal resize action

This commit is contained in:
Victoria Brekenfeld 2023-07-05 23:57:38 +02:00
parent 691b6dfa8a
commit f5dcd97c42
4 changed files with 104 additions and 26 deletions

View file

@ -2,7 +2,8 @@
use crate::{ use crate::{
shell::{ shell::{
focus::FocusDirection, layout::tiling::Direction, ResizeDirection, Shell, WorkspaceAmount, focus::FocusDirection, grabs::ResizeEdge, layout::tiling::Direction, ResizeDirection,
Shell, WorkspaceAmount,
}, },
state::{BackendData, Data, State}, state::{BackendData, Data, State},
wayland::protocols::output_configuration::OutputConfigurationState, wayland::protocols::output_configuration::OutputConfigurationState,
@ -1049,6 +1050,8 @@ pub enum Action {
ToggleWindowFloating, ToggleWindowFloating,
Resizing(ResizeDirection), Resizing(ResizeDirection),
#[serde(skip)]
_ResizingInternal(ResizeDirection, ResizeEdge, KeyState),
Maximize, Maximize,
Spawn(String), Spawn(String),
} }

View file

@ -9,7 +9,7 @@ use crate::{
floating::SeatMoveGrabState, floating::SeatMoveGrabState,
tiling::{Direction, FocusResult, MoveResult}, tiling::{Direction, FocusResult, MoveResult},
}, },
OverviewMode, ResizeMode, Workspace, OverviewMode, ResizeDirection, ResizeMode, Workspace,
}, // shell::grabs::SeatMoveGrabState }, // shell::grabs::SeatMoveGrabState
state::Common, state::Common,
utils::prelude::*, utils::prelude::*,
@ -244,13 +244,13 @@ impl State {
} }
// Leave or update resize mode, if modifiers changed or initial key was released // Leave or update resize mode, if modifiers changed or initial key was released
if let ResizeMode::Started(action_pattern, _, _) = if let (ResizeMode::Started(action_pattern, _, _), _) =
data.common.shell.resize_mode() data.common.shell.resize_mode()
{ {
if state == KeyState::Released if state == KeyState::Released
&& handle.raw_syms().contains(&action_pattern.key) && handle.raw_syms().contains(&action_pattern.key)
{ {
data.common.shell.set_resize_mode(None); data.common.shell.set_resize_mode(None, &data.common.config, data.common.event_loop_handle.clone());
return FilterResult::Intercept(None); return FilterResult::Intercept(None);
} else if action_pattern.modifiers != *modifiers { } else if action_pattern.modifiers != *modifiers {
let mut new_pattern = action_pattern.clone(); let mut new_pattern = action_pattern.clone();
@ -271,27 +271,33 @@ impl State {
None None
} }
}); });
data.common.shell.set_resize_mode(enabled); data.common.shell.set_resize_mode(enabled, &data.common.config, data.common.event_loop_handle.clone());
} }
} }
// Special case resizing with regards to arrow keys // Special case resizing with regards to arrow keys
if let ResizeMode::Started(_, _, direction) = if let (ResizeMode::Started(_, _, direction), _) =
data.common.shell.resize_mode() data.common.shell.resize_mode()
{ {
if state == KeyState::Pressed { let resize_edge = match handle.modified_sym() {
let resize_edge = match handle.modified_sym() { keysyms::KEY_Left | keysyms::KEY_H => Some(ResizeEdge::LEFT),
keysyms::KEY_Left | keysyms::KEY_H => Some(ResizeEdge::LEFT), keysyms::KEY_Down | keysyms::KEY_J => Some(ResizeEdge::BOTTOM),
keysyms::KEY_Down | keysyms::KEY_J => Some(ResizeEdge::BOTTOM), keysyms::KEY_Up | keysyms::KEY_K => Some(ResizeEdge::TOP),
keysyms::KEY_Up | keysyms::KEY_K => Some(ResizeEdge::TOP), keysyms::KEY_Right | keysyms::KEY_L => Some(ResizeEdge::RIGHT),
keysyms::KEY_Right | keysyms::KEY_L => Some(ResizeEdge::RIGHT), _ => None,
_ => None, };
};
if let Some(edge) = resize_edge { if let Some(mut edge) = resize_edge {
data.common.shell.resize_active_window(seat, direction, edge); if direction == ResizeDirection::Inwards {
return FilterResult::Intercept(None); edge.flip_direction();
} }
return FilterResult::Intercept(Some((
Action::_ResizingInternal(direction, edge, state),
KeyPattern {
modifiers: modifiers.clone().into(),
key: handle.raw_code(),
},
)));
} }
} }
@ -1175,10 +1181,18 @@ impl State {
workspace.maximize_toggle(&window, &current_output); workspace.maximize_toggle(&window, &current_output);
} }
} }
Action::Resizing(direction) => self Action::Resizing(direction) => self.common.shell.set_resize_mode(
.common Some((pattern, direction)),
.shell &self.common.config,
.set_resize_mode(Some((pattern, direction))), self.common.event_loop_handle.clone(),
),
Action::_ResizingInternal(direction, edge, state) => {
if state == KeyState::Pressed {
self.common.shell.start_resize(seat, direction, edge);
} else {
self.common.shell.stop_resize(seat, direction, edge);
}
}
Action::ToggleOrientation => { Action::ToggleOrientation => {
let output = seat.active_output(); let output = seat.active_output();
let workspace = self.common.shell.active_space_mut(&output); let workspace = self.common.shell.active_space_mut(&output);

View file

@ -19,11 +19,11 @@ use smithay::{
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct ResizeData { pub struct ResizeData {
/// The edges the surface is being resized with. /// The edges the surface is being resized with.
edges: ResizeEdge, pub edges: ResizeEdge,
/// The initial window location. /// The initial window location.
initial_window_location: Point<i32, Logical>, pub initial_window_location: Point<i32, Logical>,
/// The initial window size (geometry width and height). /// The initial window size (geometry width and height).
initial_window_size: Size<i32, Logical>, pub initial_window_size: Size<i32, Logical>,
} }
/// State of the resize operation. /// State of the resize operation.

View file

@ -55,11 +55,14 @@ mod workspace;
pub use self::element::{CosmicMapped, CosmicMappedRenderElement, CosmicSurface}; pub use self::element::{CosmicMapped, CosmicMappedRenderElement, CosmicSurface};
pub use self::workspace::*; pub use self::workspace::*;
use self::{ use self::{
element::CosmicWindow, element::{
resize_indicator::{resize_indicator, ResizeIndicator},
CosmicWindow,
},
focus::target::KeyboardFocusTarget, focus::target::KeyboardFocusTarget,
grabs::ResizeEdge, grabs::ResizeEdge,
layout::{ layout::{
floating::FloatingLayout, floating::{FloatingLayout, ResizeState},
tiling::{Direction, TilingLayout, ANIMATION_DURATION}, tiling::{Direction, TilingLayout, ANIMATION_DURATION},
}, },
}; };
@ -103,6 +106,14 @@ pub struct Shell {
gaps: (u8, u8), gaps: (u8, u8),
overview_mode: OverviewMode, overview_mode: OverviewMode,
resize_mode: ResizeMode, resize_mode: ResizeMode,
resize_state: Option<(
KeyboardFocusTarget,
ResizeDirection,
ResizeEdge,
i32,
usize,
Output,
)>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -562,6 +573,7 @@ impl Shell {
gaps: config.static_conf.gaps, gaps: config.static_conf.gaps,
overview_mode: OverviewMode::None, overview_mode: OverviewMode::None,
resize_mode: ResizeMode::None, resize_mode: ResizeMode::None,
resize_state: None,
} }
} }
@ -1527,6 +1539,55 @@ impl Shell {
} }
} }
} }
pub fn start_resize(
&mut self,
seat: &Seat<State>,
direction: ResizeDirection,
edge: ResizeEdge,
) {
let output = seat.active_output();
let (_, idx) = self.workspaces.active_num(&output);
let Some(focused) = seat.get_keyboard().unwrap().current_focus() else { return };
if let Some(workspace) = self.workspaces.get_mut(idx, &output) {
let amount = (self
.resize_state
.take()
.map(|(_, _, _, amount, _, _)| amount)
.unwrap_or(10)
+ 2)
.min(20);
if workspace.resize(&focused, direction, edge, amount) {
self.resize_state = Some((focused, direction, edge, amount, idx, output));
}
}
}
pub fn stop_resize(
&mut self,
_seat: &Seat<State>,
direction: ResizeDirection,
edge: ResizeEdge,
) {
if let Some((old_focused, old_direction, old_edge, _, idx, output)) =
self.resize_state.take()
{
let workspace = self.workspaces.get(idx, &output).unwrap();
if old_direction == direction && old_edge == edge {
let Some(toplevel) = old_focused.toplevel() else { return };
let Some(mapped) = workspace
.mapped()
.find(|m| m.has_surface(&toplevel, WindowSurfaceType::TOPLEVEL))
.cloned()
else { return };
let mut resize_state = mapped.resize_state.lock().unwrap();
if let Some(ResizeState::Resizing(data)) = *resize_state {
*resize_state = Some(ResizeState::WaitingForCommit(data));
}
}
}
}
} }
fn workspace_set_idx<'a>( fn workspace_set_idx<'a>(