feat: floating window tiling gaps

This commit is contained in:
Ryan Brue 2024-04-19 20:38:14 -05:00 committed by Victoria Brekenfeld
parent 8cee91c88f
commit 90227471bf
2 changed files with 83 additions and 36 deletions

View file

@ -42,7 +42,7 @@ use smithay::{
Seat, Seat,
}, },
output::Output, 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}; use std::{cell::RefCell, collections::HashSet, sync::atomic::Ordering, time::Instant};
@ -142,10 +142,12 @@ impl MoveGrabState {
layers.non_exclusive_zone() layers.non_exclusive_zone()
}; };
let gaps = (theme.gaps.0 as i32, theme.gaps.1 as i32);
let snapping_indicator = match &self.snapping_zone { let snapping_indicator = match &self.snapping_zone {
Some(t) if &self.cursor_output == output => { Some(t) if &self.cursor_output == output => {
let base_color = theme.palette.neutral_9; 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![ vec![
CosmicMappedRenderElement::from(IndicatorShader::element( CosmicMappedRenderElement::from(IndicatorShader::element(
renderer, renderer,
@ -165,7 +167,7 @@ impl MoveGrabState {
CosmicMappedRenderElement::from(BackdropShader::element( CosmicMappedRenderElement::from(BackdropShader::element(
renderer, renderer,
Key::Window(Usage::SnappingIndicator, self.window.clone()), 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 theme.radius_s()[0], // TODO: Fix once shaders support 4 corner radii customization
0.4, 0.4,
[base_color.red, base_color.green, base_color.blue], [base_color.red, base_color.green, base_color.blue],
@ -290,24 +292,31 @@ impl SnappingZone {
pub fn overlay_geometry( pub fn overlay_geometry(
&self, &self,
non_exclusive_geometry: Rectangle<i32, Logical>, non_exclusive_geometry: Rectangle<i32, Logical>,
gaps: (i32, i32),
) -> Rectangle<i32, Local> { ) -> Rectangle<i32, Local> {
match self { match self {
SnappingZone::Maximize => non_exclusive_geometry.as_local(), 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 => { 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 => { 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 => { 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 => { SnappingZone::TopRight => {
TiledCorners::TopRight.relative_geometry(non_exclusive_geometry) TiledCorners::TopRight.relative_geometry(non_exclusive_geometry, gaps)
} }
} }
} }

View file

@ -127,6 +127,7 @@ impl Animation {
output_geometry: Rectangle<i32, Logical>, output_geometry: Rectangle<i32, Logical>,
current_geometry: Rectangle<i32, Local>, current_geometry: Rectangle<i32, Local>,
tiled_state: Option<&TiledCorners>, tiled_state: Option<&TiledCorners>,
gaps: (i32, i32),
) -> Rectangle<i32, Local> { ) -> Rectangle<i32, Local> {
let (duration, target_rect) = match self { let (duration, target_rect) = match self {
Animation::Minimize { Animation::Minimize {
@ -137,7 +138,7 @@ impl Animation {
} => (MINIMIZE_ANIMATION_DURATION, target_geometry.clone()), } => (MINIMIZE_ANIMATION_DURATION, target_geometry.clone()),
Animation::Tiled { .. } => { Animation::Tiled { .. } => {
let target_geometry = if let Some(target_rect) = 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 target_rect
} else { } else {
@ -178,54 +179,80 @@ impl TiledCorners {
pub fn relative_geometry( pub fn relative_geometry(
&self, &self,
output_geometry: Rectangle<i32, Logical>, output_geometry: Rectangle<i32, Logical>,
gaps: (i32, i32),
) -> Rectangle<i32, Local> { ) -> Rectangle<i32, Local> {
let (_, inner) = gaps;
let (loc, size) = match self { let (loc, size) = match self {
TiledCorners::Bottom => ( TiledCorners::Bottom => (
Point::from(( Point::from((
output_geometry.loc.x, output_geometry.loc.x + inner,
output_geometry.loc.y + (output_geometry.size.h / 2), 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 => ( TiledCorners::BottomLeft => (
Point::from(( Point::from((
output_geometry.loc.x, output_geometry.loc.x + inner,
output_geometry.loc.y + (output_geometry.size.h / 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::BottomRight => ( TiledCorners::BottomRight => (
Point::from(( Point::from((
output_geometry.loc.x + (output_geometry.size.w / 2), output_geometry.loc.x + (output_geometry.size.w / 2) + inner / 2,
output_geometry.loc.y + (output_geometry.size.h / 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 => ( TiledCorners::Left => (
output_geometry.loc, Point::from((output_geometry.loc.x + inner, output_geometry.loc.y + inner)),
Size::from((output_geometry.size.w / 2, output_geometry.size.h)), Size::from((
output_geometry.size.w / 2 - inner * 3 / 2,
output_geometry.size.h - inner * 2,
)),
), ),
TiledCorners::Top => ( TiledCorners::Top => (
output_geometry.loc, Point::from((output_geometry.loc.x + inner, output_geometry.loc.y + inner)),
Size::from((output_geometry.size.w, output_geometry.size.h / 2)), Size::from((
output_geometry.size.w - inner * 2,
output_geometry.size.h / 2 - inner * 3 / 2,
)),
), ),
TiledCorners::TopLeft => ( TiledCorners::TopLeft => (
output_geometry.loc, Point::from((output_geometry.loc.x + inner, output_geometry.loc.y + inner)),
Size::from((output_geometry.size.w / 2, output_geometry.size.h / 2)), Size::from((
output_geometry.size.w / 2 - inner * 3 / 2,
output_geometry.size.h / 2 - inner * 3 / 2,
)),
), ),
TiledCorners::TopRight => ( TiledCorners::TopRight => (
Point::from(( Point::from((
output_geometry.loc.x + (output_geometry.size.w / 2), output_geometry.loc.x + (output_geometry.size.w / 2) + inner / 2,
output_geometry.loc.y, 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 => ( TiledCorners::Right => (
Point::from(( Point::from((
output_geometry.loc.x + (output_geometry.size.w / 2), output_geometry.loc.x + (output_geometry.size.w / 2) + inner / 2,
output_geometry.loc.y, 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(); let tiled_state = mapped.floating_tiled.lock().unwrap().clone();
if let Some(tiled_state) = tiled_state { 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( self.map_internal(
mapped, mapped,
Some(geometry.loc), Some(geometry.loc),
@ -966,7 +993,12 @@ impl FloatingLayout {
.map(RectExt::as_local) .map(RectExt::as_local)
.unwrap(); .unwrap();
let start_rectangle = if let Some(anim) = self.animations.remove(element) { 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 { } else {
current_geometry current_geometry
}; };
@ -1045,7 +1077,7 @@ impl FloatingLayout {
(Direction::Left, _) => TiledCorners::Left, (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); let (new_pos, new_size) = (new_geo.loc, new_geo.size);
element.set_tiled(true); // TODO: More fine grained? element.set_tiled(true); // TODO: More fine grained?
element.set_maximized(false); element.set_maximized(false);
@ -1234,6 +1266,7 @@ impl FloatingLayout {
.map(RectExt::as_local) .map(RectExt::as_local)
.unwrap_or(geometry), .unwrap_or(geometry),
elem.floating_tiled.lock().unwrap().as_ref(), elem.floating_tiled.lock().unwrap().as_ref(),
self.gaps(),
); );
let buffer_size = elem.geometry().size; let buffer_size = elem.geometry().size;
@ -1340,4 +1373,9 @@ impl FloatingLayout {
(window_elements, popup_elements) (window_elements, popup_elements)
} }
fn gaps(&self) -> (i32, i32) {
let g = self.theme.cosmic().gaps;
(g.0 as i32, g.1 as i32)
}
} }