From aee594d23c709fa9c6b83e31aadef862f6eb5d9e Mon Sep 17 00:00:00 2001 From: Billy Messenger Date: Thu, 15 Oct 2020 16:31:38 -0500 Subject: [PATCH] add window resize hints --- examples/open_window.rs | 4 ++-- src/lib.rs | 17 +++++++++++++---- src/x11/window.rs | 38 +++++++++++++++++++++++++++++++++++--- src/x11/xcb_connection.rs | 4 +++- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/examples/open_window.rs b/examples/open_window.rs index 260e0ad..a764453 100644 --- a/examples/open_window.rs +++ b/examples/open_window.rs @@ -25,8 +25,8 @@ impl WindowHandler for MyProgram { fn main() { let window_open_options = baseview::WindowOpenOptions { title: "baseview".into(), - logical_width: 512, - logical_height: 512, + logical_size: (512, 512), + resize: baseview::WindowResize::None, scale: 1.0, parent: baseview::Parent::None, }; diff --git a/src/lib.rs b/src/lib.rs index be05a54..c0531ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,13 +32,22 @@ pub enum Parent { unsafe impl Send for Parent {} +pub enum WindowResize { + None, + MinMax { + min_logical_size: (u32, u32), + max_logical_size: (u32, u32), + keep_aspect: bool, + }, +} + pub struct WindowOpenOptions { pub title: String, - /// The logical width of the window - pub logical_width: u32, - /// The logical height of the window - pub logical_height: u32, + /// The logical width and height of the window + pub logical_size: (u32, u32), + + pub resize: WindowResize, /// The dpi scale factor. This will used in conjunction with the dpi scale /// factor of the system. diff --git a/src/x11/window.rs b/src/x11/window.rs index b4a56b4..a48bb46 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -12,7 +12,7 @@ use raw_window_handle::{ use super::XcbConnection; use crate::{ Event, KeyboardEvent, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta, WindowEvent, - WindowHandle, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult, + WindowHandle, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult, WindowResize, }; pub struct Window { @@ -81,9 +81,10 @@ impl Window { let scaling = xcb_connection.get_scaling().unwrap_or(1.0) * options.scale; + let (logical_width, logical_height) = options.logical_size; let window_info = WindowInfo::from_logical_size( - options.logical_width, - options.logical_height, + logical_width, + logical_height, scaling ); @@ -126,6 +127,37 @@ impl Window { title.as_bytes(), ); + match options.resize { + WindowResize::MinMax { min_logical_size, max_logical_size, keep_aspect } => { + let size_hints = if keep_aspect { + xcb_util::icccm::SizeHints::empty() + .min_size(min_logical_size.0 as i32, min_logical_size.1 as i32) + .max_size(max_logical_size.0 as i32, max_logical_size.1 as i32) + .aspect( + (min_logical_size.0 as i32, min_logical_size.1 as i32), + (max_logical_size.0 as i32, max_logical_size.1 as i32), + ) + .build() + } else { + xcb_util::icccm::SizeHints::empty() + .min_size(min_logical_size.0 as i32, min_logical_size.1 as i32) + .max_size(max_logical_size.0 as i32, max_logical_size.1 as i32) + .build() + }; + + xcb_connection.atoms.wm_normal_hints + .map(|wm_normal_hints| { + xcb_util::icccm::set_wm_size_hints( + &xcb_connection.conn, + window_id, + wm_normal_hints, + &size_hints, + ); + }); + } + _ => {} + } + xcb_connection.atoms.wm_protocols .zip(xcb_connection.atoms.wm_delete_window) .map(|(wm_protocols, wm_delete_window)| { diff --git a/src/x11/xcb_connection.rs b/src/x11/xcb_connection.rs index 3819ee6..db2113a 100644 --- a/src/x11/xcb_connection.rs +++ b/src/x11/xcb_connection.rs @@ -13,6 +13,7 @@ use super::cursor; pub(crate) struct Atoms { pub wm_protocols: Option, pub wm_delete_window: Option, + pub wm_normal_hints: Option, } pub struct XcbConnection { @@ -45,7 +46,7 @@ impl XcbConnection { pub fn new() -> Result { let (conn, xlib_display) = xcb::Connection::connect_with_xlib_display()?; - let (wm_protocols, wm_delete_window) = intern_atoms!(&conn, WM_PROTOCOLS, WM_DELETE_WINDOW); + let (wm_protocols, wm_delete_window, wm_normal_hints) = intern_atoms!(&conn, WM_PROTOCOLS, WM_DELETE_WINDOW, WM_NORMAL_HINTS); Ok(Self { conn, @@ -54,6 +55,7 @@ impl XcbConnection { atoms: Atoms { wm_protocols, wm_delete_window, + wm_normal_hints, }, cursor_cache: HashMap::new()