From f5dcd97c422848b483c58826075790c69250bdf3 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 5 Jul 2023 23:57:38 +0200 Subject: [PATCH] input: Wire up internal resize action --- src/config/mod.rs | 5 +- src/input/mod.rs | 54 ++++++++++++------- src/shell/layout/floating/grabs/resize.rs | 6 +-- src/shell/mod.rs | 65 ++++++++++++++++++++++- 4 files changed, 104 insertions(+), 26 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index c5478238..ecf8a5ee 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -2,7 +2,8 @@ use crate::{ shell::{ - focus::FocusDirection, layout::tiling::Direction, ResizeDirection, Shell, WorkspaceAmount, + focus::FocusDirection, grabs::ResizeEdge, layout::tiling::Direction, ResizeDirection, + Shell, WorkspaceAmount, }, state::{BackendData, Data, State}, wayland::protocols::output_configuration::OutputConfigurationState, @@ -1049,6 +1050,8 @@ pub enum Action { ToggleWindowFloating, Resizing(ResizeDirection), + #[serde(skip)] + _ResizingInternal(ResizeDirection, ResizeEdge, KeyState), Maximize, Spawn(String), } diff --git a/src/input/mod.rs b/src/input/mod.rs index 91b67b8f..ac228548 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -9,7 +9,7 @@ use crate::{ floating::SeatMoveGrabState, tiling::{Direction, FocusResult, MoveResult}, }, - OverviewMode, ResizeMode, Workspace, + OverviewMode, ResizeDirection, ResizeMode, Workspace, }, // shell::grabs::SeatMoveGrabState state::Common, utils::prelude::*, @@ -244,13 +244,13 @@ impl State { } // 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() { if state == KeyState::Released && 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); } else if action_pattern.modifiers != *modifiers { let mut new_pattern = action_pattern.clone(); @@ -271,27 +271,33 @@ impl State { 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 - if let ResizeMode::Started(_, _, direction) = + if let (ResizeMode::Started(_, _, direction), _) = data.common.shell.resize_mode() { - if state == KeyState::Pressed { - let resize_edge = match handle.modified_sym() { - keysyms::KEY_Left | keysyms::KEY_H => Some(ResizeEdge::LEFT), - keysyms::KEY_Down | keysyms::KEY_J => Some(ResizeEdge::BOTTOM), - keysyms::KEY_Up | keysyms::KEY_K => Some(ResizeEdge::TOP), - keysyms::KEY_Right | keysyms::KEY_L => Some(ResizeEdge::RIGHT), - _ => None, - }; + let resize_edge = match handle.modified_sym() { + keysyms::KEY_Left | keysyms::KEY_H => Some(ResizeEdge::LEFT), + keysyms::KEY_Down | keysyms::KEY_J => Some(ResizeEdge::BOTTOM), + keysyms::KEY_Up | keysyms::KEY_K => Some(ResizeEdge::TOP), + keysyms::KEY_Right | keysyms::KEY_L => Some(ResizeEdge::RIGHT), + _ => None, + }; - if let Some(edge) = resize_edge { - data.common.shell.resize_active_window(seat, direction, edge); - return FilterResult::Intercept(None); + if let Some(mut edge) = resize_edge { + if direction == ResizeDirection::Inwards { + 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, ¤t_output); } } - Action::Resizing(direction) => self - .common - .shell - .set_resize_mode(Some((pattern, direction))), + Action::Resizing(direction) => self.common.shell.set_resize_mode( + Some((pattern, direction)), + &self.common.config, + 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 => { let output = seat.active_output(); let workspace = self.common.shell.active_space_mut(&output); diff --git a/src/shell/layout/floating/grabs/resize.rs b/src/shell/layout/floating/grabs/resize.rs index b9acd24b..fec6dd75 100644 --- a/src/shell/layout/floating/grabs/resize.rs +++ b/src/shell/layout/floating/grabs/resize.rs @@ -19,11 +19,11 @@ use smithay::{ #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct ResizeData { /// The edges the surface is being resized with. - edges: ResizeEdge, + pub edges: ResizeEdge, /// The initial window location. - initial_window_location: Point, + pub initial_window_location: Point, /// The initial window size (geometry width and height). - initial_window_size: Size, + pub initial_window_size: Size, } /// State of the resize operation. diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 07c47aef..2288b082 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -55,11 +55,14 @@ mod workspace; pub use self::element::{CosmicMapped, CosmicMappedRenderElement, CosmicSurface}; pub use self::workspace::*; use self::{ - element::CosmicWindow, + element::{ + resize_indicator::{resize_indicator, ResizeIndicator}, + CosmicWindow, + }, focus::target::KeyboardFocusTarget, grabs::ResizeEdge, layout::{ - floating::FloatingLayout, + floating::{FloatingLayout, ResizeState}, tiling::{Direction, TilingLayout, ANIMATION_DURATION}, }, }; @@ -103,6 +106,14 @@ pub struct Shell { gaps: (u8, u8), overview_mode: OverviewMode, resize_mode: ResizeMode, + resize_state: Option<( + KeyboardFocusTarget, + ResizeDirection, + ResizeEdge, + i32, + usize, + Output, + )>, } #[derive(Debug)] @@ -562,6 +573,7 @@ impl Shell { gaps: config.static_conf.gaps, overview_mode: OverviewMode::None, resize_mode: ResizeMode::None, + resize_state: None, } } @@ -1527,6 +1539,55 @@ impl Shell { } } } + + pub fn start_resize( + &mut self, + seat: &Seat, + 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, + 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>(