Apply resize edge restrictions from configure to our decorations

This commit is contained in:
Val Packett 2026-03-20 00:59:55 -03:00
parent de494a0453
commit f32380416a
3 changed files with 63 additions and 13 deletions

View file

@ -17,12 +17,17 @@ use wl_proxy::{
},
};
use crate::{buffer::SimpleBufferPool, globals::Globals, util::Bounds};
use crate::{
buffer::SimpleBufferPool,
globals::Globals,
util::{Bounds, Edges},
};
#[derive(Default, Debug, Clone, PartialEq)]
struct DecoParams {
has_geometry: bool,
bounds: Bounds,
restricted_edges: Edges<bool>,
}
pub struct Deco {
@ -40,26 +45,26 @@ pub struct Deco {
impl Deco {
fn resize_anchor(&self, x: i32, y: i32) -> XdgToplevelResizeEdge {
let bounds = &self.last_params.borrow().bounds;
let params = self.last_params.borrow();
let n = y < self.border_size;
let e = x >= bounds.width + self.border_size;
let e = x >= params.bounds.width + self.border_size;
let w = x < self.border_size;
let s = y >= bounds.height + self.border_size;
if n && e {
let s = y >= params.bounds.height + self.border_size;
if n && e && !params.restricted_edges.top && !params.restricted_edges.right {
XdgToplevelResizeEdge::TOP_RIGHT
} else if n && w {
} else if n && w && !params.restricted_edges.top && !params.restricted_edges.left {
XdgToplevelResizeEdge::TOP_LEFT
} else if s && e {
} else if s && e && !params.restricted_edges.bottom && !params.restricted_edges.right {
XdgToplevelResizeEdge::BOTTOM_RIGHT
} else if s && w {
} else if s && w && !params.restricted_edges.bottom && !params.restricted_edges.left {
XdgToplevelResizeEdge::BOTTOM_LEFT
} else if n {
} else if n && !params.restricted_edges.top {
XdgToplevelResizeEdge::TOP
} else if e {
} else if e && !params.restricted_edges.right {
XdgToplevelResizeEdge::RIGHT
} else if w {
} else if w && !params.restricted_edges.left {
XdgToplevelResizeEdge::LEFT
} else if s {
} else if s && !params.restricted_edges.bottom {
XdgToplevelResizeEdge::BOTTOM
} else {
XdgToplevelResizeEdge::NONE
@ -198,6 +203,11 @@ impl Deco {
(x - self.border_size, y - self.top_size, width, height)
}
pub fn set_restricted_edges(&self, edges: Edges<bool>) {
let mut params = self.next_params.borrow_mut();
params.restricted_edges = edges;
}
pub fn handle_commit(&self) -> eyre::Result<()> {
self.draw()
}

View file

@ -5,3 +5,11 @@ pub struct Bounds {
pub width: i32,
pub height: i32,
}
#[derive(Default, Debug, Clone, PartialEq)]
pub struct Edges<T> {
pub top: T,
pub right: T,
pub bottom: T,
pub left: T,
}

View file

@ -18,7 +18,12 @@ use wl_proxy::{
},
};
use crate::{client_buffer, deco::Deco, globals::Globals, util::Bounds};
use crate::{
client_buffer,
deco::Deco,
globals::Globals,
util::{Bounds, Edges},
};
pub struct ClientWlSurface {
pub xdg_surface: Rc<XdgSurface>,
@ -222,6 +227,7 @@ impl XdgToplevelHandler for ClientXdgToplevel {
fn handle_configure(&mut self, slf: &Rc<XdgToplevel>, width: i32, height: i32, states: &[u8]) {
log::debug!("configure {slf:?}: {width}x{height}, {states:?}");
let (_prefix, states, _suffix) = unsafe { states.align_to::<u32>() };
let mut restricted_edges = Edges::default();
let mut top_state = ToplevelState::Normal;
let mut resizing = false;
let mut activated = false;
@ -237,6 +243,31 @@ impl XdgToplevelHandler for ClientXdgToplevel {
top_state = ToplevelState::Maximixed;
} else if *state == XdgToplevelState::FULLSCREEN.0 {
top_state = ToplevelState::Fullscreen;
} else if *state == XdgToplevelState::TILED_TOP.0
|| *state == XdgToplevelState::CONSTRAINED_TOP.0
{
restricted_edges.top = true;
} else if *state == XdgToplevelState::TILED_RIGHT.0
|| *state == XdgToplevelState::CONSTRAINED_RIGHT.0
{
restricted_edges.right = true;
} else if *state == XdgToplevelState::TILED_BOTTOM.0
|| *state == XdgToplevelState::CONSTRAINED_BOTTOM.0
{
restricted_edges.bottom = true;
} else if *state == XdgToplevelState::TILED_LEFT.0
|| *state == XdgToplevelState::CONSTRAINED_LEFT.0
{
restricted_edges.left = true;
}
if *state == XdgToplevelState::MAXIMIZED.0 || *state == XdgToplevelState::FULLSCREEN.0 {
restricted_edges = Edges {
top: true,
right: true,
bottom: true,
left: true,
}
}
}
@ -262,6 +293,7 @@ impl XdgToplevelHandler for ClientXdgToplevel {
ToplevelState::Fullscreen => outer_state.push(XdgToplevelState::FULLSCREEN),
};
self.deco.set_restricted_edges(restricted_edges);
let (width, height) = self.deco.transform_configure(width, height);
let (_prefix, states, _suffix) = unsafe { outer_state.align_to::<u8>() };
slf.send_configure(width, height, &states[..]);