From d6434d322e397bdeb288d2f6e2e18c7a25c76480 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 23 Oct 2023 21:09:38 +0200 Subject: [PATCH] floating: Limit resizing to current output --- src/input/mod.rs | 19 +++++++++- src/shell/layout/floating/grabs/resize.rs | 43 ++++++++++++++++++++--- src/shell/layout/floating/mod.rs | 1 + 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index aeb2658c..11b4ea1a 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -6,7 +6,10 @@ use crate::{ shell::{ focus::{target::PointerFocusTarget, FocusDirection}, grabs::{ResizeEdge, SeatMoveGrabState}, - layout::tiling::{SwapWindowGrab, TilingLayout}, + layout::{ + floating::ResizeGrabMarker, + tiling::{SwapWindowGrab, TilingLayout}, + }, Direction, FocusResult, MoveResult, OverviewMode, ResizeDirection, ResizeMode, Trigger, Workspace, }, @@ -620,6 +623,20 @@ impl State { .find(|output| output.geometry().to_f64().contains(position)) .cloned() .unwrap_or(current_output.clone()); + + if ptr.is_grabbed() + && seat + .user_data() + .get::() + .map(|marker| marker.get()) + .unwrap_or(false) + { + if output != current_output { + ptr.frame(self); + return; + } + } + let output_geometry = output.geometry(); let workspace = self.common.shell.workspaces.active_mut(&output); diff --git a/src/shell/layout/floating/grabs/resize.rs b/src/shell/layout/floating/grabs/resize.rs index b87aebd2..d245ef22 100644 --- a/src/shell/layout/floating/grabs/resize.rs +++ b/src/shell/layout/floating/grabs/resize.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only +use std::sync::atomic::{AtomicBool, Ordering}; + use crate::{ shell::{ element::CosmicMapped, focus::target::PointerFocusTarget, grabs::ResizeEdge, CosmicSurface, @@ -8,11 +10,15 @@ use crate::{ }; use smithay::{ desktop::space::SpaceElement, - input::pointer::{ - AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent, - GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent, - GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData, - MotionEvent, PointerGrab, PointerInnerHandle, RelativeMotionEvent, + input::{ + pointer::{ + AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent, + GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent, + GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, + GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, PointerInnerHandle, + RelativeMotionEvent, + }, + Seat, }, utils::{IsAlive, Logical, Point, Rectangle, Size}, }; @@ -39,6 +45,7 @@ pub enum ResizeState { pub struct ResizeSurfaceGrab { start_data: PointerGrabStartData, + seat: Seat, window: CosmicMapped, edges: ResizeEdge, initial_window_size: Size, @@ -58,6 +65,12 @@ impl PointerGrab for ResizeSurfaceGrab { // It is impossible to get `min_size` and `max_size` of dead toplevel, so we return early. if !self.window.alive() { + self.seat + .user_data() + .get::() + .unwrap() + .0 + .store(false, Ordering::SeqCst); handle.unset_grab(data, event.serial, event.time, true); return; } @@ -129,6 +142,12 @@ impl PointerGrab for ResizeSurfaceGrab { handle.button(data, event); if handle.current_pressed().is_empty() { // No more buttons are pressed, release the grab. + self.seat + .user_data() + .get::() + .unwrap() + .0 + .store(false, Ordering::SeqCst); handle.unset_grab(data, event.serial, event.time, true); // If toplevel is dead, we can't resize it, so we return early. @@ -245,6 +264,14 @@ impl PointerGrab for ResizeSurfaceGrab { } } +pub struct ResizeGrabMarker(AtomicBool); + +impl ResizeGrabMarker { + pub fn get(&self) -> bool { + self.0.load(Ordering::SeqCst) + } +} + impl ResizeSurfaceGrab { pub fn new( start_data: PointerGrabStartData, @@ -252,6 +279,7 @@ impl ResizeSurfaceGrab { edges: ResizeEdge, initial_window_location: Point, initial_window_size: Size, + seat: &Seat, ) -> ResizeSurfaceGrab { let resize_state = ResizeState::Resizing(ResizeData { edges, @@ -260,9 +288,14 @@ impl ResizeSurfaceGrab { }); *mapped.resize_state.lock().unwrap() = Some(resize_state); + seat.user_data() + .get_or_insert::(|| ResizeGrabMarker(AtomicBool::new(true))) + .0 + .store(true, Ordering::SeqCst); ResizeSurfaceGrab { start_data, + seat: seat.clone(), window: mapped, edges, initial_window_size, diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index a06b8458..f8af90a4 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -188,6 +188,7 @@ impl FloatingLayout { edges, location, size, + seat, )) } else { None