feat: floating window tiling gaps
This commit is contained in:
parent
8cee91c88f
commit
90227471bf
2 changed files with 83 additions and 36 deletions
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue