diff --git a/src/deco.rs b/src/deco.rs index c813d06..c5002ad 100644 --- a/src/deco.rs +++ b/src/deco.rs @@ -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, } 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) { + let mut params = self.next_params.borrow_mut(); + params.restricted_edges = edges; + } + pub fn handle_commit(&self) -> eyre::Result<()> { self.draw() } diff --git a/src/util.rs b/src/util.rs index d624ac6..81425d5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,3 +5,11 @@ pub struct Bounds { pub width: i32, pub height: i32, } + +#[derive(Default, Debug, Clone, PartialEq)] +pub struct Edges { + pub top: T, + pub right: T, + pub bottom: T, + pub left: T, +} diff --git a/src/xdg.rs b/src/xdg.rs index 26fea08..e22536f 100644 --- a/src/xdg.rs +++ b/src/xdg.rs @@ -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, @@ -222,6 +227,7 @@ impl XdgToplevelHandler for ClientXdgToplevel { fn handle_configure(&mut self, slf: &Rc, width: i32, height: i32, states: &[u8]) { log::debug!("configure {slf:?}: {width}x{height}, {states:?}"); let (_prefix, states, _suffix) = unsafe { states.align_to::() }; + 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::() }; slf.send_configure(width, height, &states[..]);