From 90227471bf66b4f63554905becfcf3308f3fedeb Mon Sep 17 00:00:00 2001 From: Ryan Brue Date: Fri, 19 Apr 2024 20:38:14 -0500 Subject: [PATCH] feat: floating window tiling gaps --- src/shell/grabs/moving.rs | 31 +++++++---- src/shell/layout/floating/mod.rs | 88 +++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 36 deletions(-) diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 7adae721..72f92a90 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -42,7 +42,7 @@ use smithay::{ Seat, }, output::Output, - utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial, SERIAL_COUNTER}, + utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial, Size, SERIAL_COUNTER}, }; use std::{cell::RefCell, collections::HashSet, sync::atomic::Ordering, time::Instant}; @@ -142,10 +142,12 @@ impl MoveGrabState { layers.non_exclusive_zone() }; + let gaps = (theme.gaps.0 as i32, theme.gaps.1 as i32); + let snapping_indicator = match &self.snapping_zone { Some(t) if &self.cursor_output == output => { let base_color = theme.palette.neutral_9; - let overlay_geometry = t.overlay_geometry(non_exclusive_geometry); + let overlay_geometry = t.overlay_geometry(non_exclusive_geometry, gaps); vec![ CosmicMappedRenderElement::from(IndicatorShader::element( renderer, @@ -165,7 +167,7 @@ impl MoveGrabState { CosmicMappedRenderElement::from(BackdropShader::element( renderer, Key::Window(Usage::SnappingIndicator, self.window.clone()), - t.overlay_geometry(non_exclusive_geometry), + t.overlay_geometry(non_exclusive_geometry, gaps), theme.radius_s()[0], // TODO: Fix once shaders support 4 corner radii customization 0.4, [base_color.red, base_color.green, base_color.blue], @@ -290,24 +292,31 @@ impl SnappingZone { pub fn overlay_geometry( &self, non_exclusive_geometry: Rectangle, + gaps: (i32, i32), ) -> Rectangle { match self { SnappingZone::Maximize => non_exclusive_geometry.as_local(), - SnappingZone::Top => TiledCorners::Top.relative_geometry(non_exclusive_geometry), + SnappingZone::Top => TiledCorners::Top.relative_geometry(non_exclusive_geometry, gaps), SnappingZone::TopLeft => { - TiledCorners::TopLeft.relative_geometry(non_exclusive_geometry) + TiledCorners::TopLeft.relative_geometry(non_exclusive_geometry, gaps) + } + SnappingZone::Left => { + TiledCorners::Left.relative_geometry(non_exclusive_geometry, gaps) } - SnappingZone::Left => TiledCorners::Left.relative_geometry(non_exclusive_geometry), SnappingZone::BottomLeft => { - TiledCorners::BottomLeft.relative_geometry(non_exclusive_geometry) + TiledCorners::BottomLeft.relative_geometry(non_exclusive_geometry, gaps) + } + SnappingZone::Bottom => { + TiledCorners::Bottom.relative_geometry(non_exclusive_geometry, gaps) } - SnappingZone::Bottom => TiledCorners::Bottom.relative_geometry(non_exclusive_geometry), SnappingZone::BottomRight => { - TiledCorners::BottomRight.relative_geometry(non_exclusive_geometry) + TiledCorners::BottomRight.relative_geometry(non_exclusive_geometry, gaps) + } + SnappingZone::Right => { + TiledCorners::Right.relative_geometry(non_exclusive_geometry, gaps) } - SnappingZone::Right => TiledCorners::Right.relative_geometry(non_exclusive_geometry), SnappingZone::TopRight => { - TiledCorners::TopRight.relative_geometry(non_exclusive_geometry) + TiledCorners::TopRight.relative_geometry(non_exclusive_geometry, gaps) } } } diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index b8bbd5b8..a97d413a 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -127,6 +127,7 @@ impl Animation { output_geometry: Rectangle, current_geometry: Rectangle, tiled_state: Option<&TiledCorners>, + gaps: (i32, i32), ) -> Rectangle { let (duration, target_rect) = match self { Animation::Minimize { @@ -137,7 +138,7 @@ impl Animation { } => (MINIMIZE_ANIMATION_DURATION, target_geometry.clone()), Animation::Tiled { .. } => { let target_geometry = if let Some(target_rect) = - tiled_state.map(|state| state.relative_geometry(output_geometry)) + tiled_state.map(|state| state.relative_geometry(output_geometry, gaps)) { target_rect } else { @@ -178,54 +179,80 @@ impl TiledCorners { pub fn relative_geometry( &self, output_geometry: Rectangle, + gaps: (i32, i32), ) -> Rectangle { + let (_, inner) = gaps; let (loc, size) = match self { TiledCorners::Bottom => ( Point::from(( - output_geometry.loc.x, - output_geometry.loc.y + (output_geometry.size.h / 2), + output_geometry.loc.x + inner, + output_geometry.loc.y + (output_geometry.size.h / 2) + inner / 2, + )), + Size::from(( + output_geometry.size.w - inner * 2, + output_geometry.size.h / 2 - inner * 3 / 2, )), - Size::from((output_geometry.size.w, output_geometry.size.h / 2)), ), TiledCorners::BottomLeft => ( Point::from(( - output_geometry.loc.x, - output_geometry.loc.y + (output_geometry.size.h / 2), + output_geometry.loc.x + inner, + output_geometry.loc.y + (output_geometry.size.h / 2) + inner / 2, + )), + Size::from(( + output_geometry.size.w / 2 - inner * 3 / 2, + output_geometry.size.h / 2 - inner * 3 / 2, )), - Size::from((output_geometry.size.w / 2, output_geometry.size.h / 2)), ), TiledCorners::BottomRight => ( Point::from(( - output_geometry.loc.x + (output_geometry.size.w / 2), - output_geometry.loc.y + (output_geometry.size.h / 2), + output_geometry.loc.x + (output_geometry.size.w / 2) + inner / 2, + output_geometry.loc.y + (output_geometry.size.h / 2) + inner / 2, + )), + Size::from(( + output_geometry.size.w / 2 - inner * 3 / 2, + output_geometry.size.h / 2 - inner * 3 / 2, )), - Size::from((output_geometry.size.w / 2, output_geometry.size.h / 2)), ), TiledCorners::Left => ( - output_geometry.loc, - Size::from((output_geometry.size.w / 2, output_geometry.size.h)), + Point::from((output_geometry.loc.x + inner, output_geometry.loc.y + inner)), + Size::from(( + output_geometry.size.w / 2 - inner * 3 / 2, + output_geometry.size.h - inner * 2, + )), ), TiledCorners::Top => ( - output_geometry.loc, - Size::from((output_geometry.size.w, output_geometry.size.h / 2)), + Point::from((output_geometry.loc.x + inner, output_geometry.loc.y + inner)), + Size::from(( + output_geometry.size.w - inner * 2, + output_geometry.size.h / 2 - inner * 3 / 2, + )), ), TiledCorners::TopLeft => ( - output_geometry.loc, - Size::from((output_geometry.size.w / 2, output_geometry.size.h / 2)), + Point::from((output_geometry.loc.x + inner, output_geometry.loc.y + inner)), + Size::from(( + output_geometry.size.w / 2 - inner * 3 / 2, + output_geometry.size.h / 2 - inner * 3 / 2, + )), ), TiledCorners::TopRight => ( Point::from(( - output_geometry.loc.x + (output_geometry.size.w / 2), - output_geometry.loc.y, + output_geometry.loc.x + (output_geometry.size.w / 2) + inner / 2, + output_geometry.loc.y + inner, + )), + Size::from(( + output_geometry.size.w / 2 - inner * 3 / 2, + output_geometry.size.h / 2 - inner * 3 / 2, )), - Size::from((output_geometry.size.w / 2, output_geometry.size.h / 2)), ), TiledCorners::Right => ( Point::from(( - output_geometry.loc.x + (output_geometry.size.w / 2), - output_geometry.loc.y, + output_geometry.loc.x + (output_geometry.size.w / 2) + inner / 2, + output_geometry.loc.y + inner, + )), + Size::from(( + output_geometry.size.w / 2 - inner * 3 / 2, + output_geometry.size.h - inner * 2, )), - Size::from((output_geometry.size.w / 2, output_geometry.size.h)), ), }; @@ -266,7 +293,7 @@ impl FloatingLayout { { let tiled_state = mapped.floating_tiled.lock().unwrap().clone(); if let Some(tiled_state) = tiled_state { - let geometry = tiled_state.relative_geometry(output_geometry); + let geometry = tiled_state.relative_geometry(output_geometry, self.gaps()); self.map_internal( mapped, Some(geometry.loc), @@ -966,7 +993,12 @@ impl FloatingLayout { .map(RectExt::as_local) .unwrap(); let start_rectangle = if let Some(anim) = self.animations.remove(element) { - anim.geometry(output_geometry, current_geometry, tiled_state.as_ref()) + anim.geometry( + output_geometry, + current_geometry, + tiled_state.as_ref(), + self.gaps(), + ) } else { current_geometry }; @@ -1045,7 +1077,7 @@ impl FloatingLayout { (Direction::Left, _) => TiledCorners::Left, }; - let new_geo = new_state.relative_geometry(output_geometry); + let new_geo = new_state.relative_geometry(output_geometry, self.gaps()); let (new_pos, new_size) = (new_geo.loc, new_geo.size); element.set_tiled(true); // TODO: More fine grained? element.set_maximized(false); @@ -1234,6 +1266,7 @@ impl FloatingLayout { .map(RectExt::as_local) .unwrap_or(geometry), elem.floating_tiled.lock().unwrap().as_ref(), + self.gaps(), ); let buffer_size = elem.geometry().size; @@ -1340,4 +1373,9 @@ impl FloatingLayout { (window_elements, popup_elements) } + + fn gaps(&self) -> (i32, i32) { + let g = self.theme.cosmic().gaps; + (g.0 as i32, g.1 as i32) + } }