diff --git a/src/lib.rs b/src/lib.rs index 7d81677..0d9170a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,8 @@ mod title; mod wl_typed; use crate::theme::{ - ColorMap, ColorTheme, BORDER_SIZE, CORNER_RADIUS, HEADER_SIZE, VISIBLE_BORDER_SIZE, + ColorMap, ColorTheme, BORDER_SIZE, CORNER_RADIUS, HEADER_SIZE, RESIZE_HANDLE_CORNER_SIZE, + VISIBLE_BORDER_SIZE, }; use buttons::Buttons; @@ -134,27 +135,58 @@ where self.dirty = true; } - fn precise_location(&self, location: Location, header_width: u32, x: f64, y: f64) -> Location { + fn precise_location( + &self, + location: Location, + decoration: &DecorationParts, + x: f64, + y: f64, + ) -> Location { + let header_width = decoration.header().width; + let side_height = decoration.side_height(); + + let left_corner_x = BORDER_SIZE + RESIZE_HANDLE_CORNER_SIZE; + let right_corner_x = (header_width + BORDER_SIZE).saturating_sub(RESIZE_HANDLE_CORNER_SIZE); + let top_corner_y = RESIZE_HANDLE_CORNER_SIZE; + let bottom_corner_y = side_height.saturating_sub(RESIZE_HANDLE_CORNER_SIZE); match location { Location::Head | Location::Button(_) => self.buttons.find_button(x, y), Location::Top | Location::TopLeft | Location::TopRight => { - if x <= f64::from(BORDER_SIZE) { + if x <= f64::from(left_corner_x) { Location::TopLeft - } else if x >= f64::from(header_width + BORDER_SIZE) { + } else if x >= f64::from(right_corner_x) { Location::TopRight } else { Location::Top } } Location::Bottom | Location::BottomLeft | Location::BottomRight => { - if x <= f64::from(BORDER_SIZE) { + if x <= f64::from(left_corner_x) { Location::BottomLeft - } else if x >= f64::from(header_width + BORDER_SIZE) { + } else if x >= f64::from(right_corner_x) { Location::BottomRight } else { Location::Bottom } } + Location::Left => { + if y <= f64::from(top_corner_y) { + Location::TopLeft + } else if y >= f64::from(bottom_corner_y) { + Location::BottomLeft + } else { + Location::Left + } + } + Location::Right => { + if y <= f64::from(top_corner_y) { + Location::TopRight + } else if y >= f64::from(bottom_corner_y) { + Location::BottomRight + } else { + Location::Right + } + } other => other, } } @@ -454,10 +486,9 @@ where return None; } - let header_width = decorations.header().width; let old_location = self.mouse.location; - let location = self.precise_location(location, header_width, x, y); + let location = self.precise_location(location, decorations, x, y); let new_cursor = self.mouse.moved(location, x, y, self.resizable); // Set dirty if we moved the cursor between the buttons. diff --git a/src/parts.rs b/src/parts.rs index 2eb783b..ee20769 100644 --- a/src/parts.rs +++ b/src/parts.rs @@ -126,6 +126,10 @@ impl DecorationParts { &self.parts[Self::HEADER] } + pub fn side_height(&self) -> u32 { + self.parts[Self::LEFT].height + } + pub fn find_surface(&self, surface: &ObjectId) -> Location { let pos = match self .parts diff --git a/src/theme.rs b/src/theme.rs index 1923855..f89af74 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -1,7 +1,11 @@ pub use tiny_skia::Color; use tiny_skia::{Paint, Shader}; -pub(crate) const BORDER_SIZE: u32 = 10; +// https://gitlab.gnome.org/GNOME/gtk/-/blob/1bf88f1d81043fd99740e2f91e56ade7ede7303b/gtk/gtkwindow.c#L165 +pub(crate) const RESIZE_HANDLE_SIZE: u32 = 12; +// https://gitlab.gnome.org/GNOME/gtk/-/blob/1bf88f1d81043fd99740e2f91e56ade7ede7303b/gtk/gtkwindow.c#L166 +pub(crate) const RESIZE_HANDLE_CORNER_SIZE: u32 = 24; +pub(crate) const BORDER_SIZE: u32 = VISIBLE_BORDER_SIZE + RESIZE_HANDLE_SIZE; pub(crate) const HEADER_SIZE: u32 = 35; pub(crate) const CORNER_RADIUS: u32 = 10; pub(crate) const VISIBLE_BORDER_SIZE: u32 = 1;