From c327960f3e9527f7b9f119f4a62142b769560189 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Fri, 13 Apr 2018 11:51:29 -0500 Subject: [PATCH] windows: Adjust min_dimensions and max_dimensions using AdjustWindowRectEx. (#444) --- CHANGELOG.md | 1 + src/platform/windows/events_loop.rs | 23 +++++++++++++---------- src/platform/windows/window.rs | 12 ++++++++++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f676f7f..4585d6ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fixed thread safety issues with input methods on X11. - Add support for `Touch` for win32 backend. - Fixed `Window::get_inner_size` and friends to return the size in pixels instead of points when using HIDPI displays on OSX. +- Properly calculate the minimum and maximum window size on Windows, including window decorations. # Version 0.11.3 (2018-03-28) diff --git a/src/platform/windows/events_loop.rs b/src/platform/windows/events_loop.rs index 402f1d28..6f1af175 100644 --- a/src/platform/windows/events_loop.rs +++ b/src/platform/windows/events_loop.rs @@ -33,6 +33,7 @@ use winapi::um::{winuser, shellapi, processthreadsapi}; use winapi::um::winnt::LONG; use platform::platform::event; +use platform::platform::window::adjust_size; use platform::platform::Cursor; use platform::platform::WindowId; use platform::platform::DEVICE_ID; @@ -898,18 +899,20 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT, if let Some(wstash) = cstash.windows.get(&window) { let window_state = wstash.lock().unwrap(); - match window_state.attributes.min_dimensions { - Some((width, height)) => { - (*mmi).ptMinTrackSize = POINT { x: width as i32, y: height as i32 }; - }, - None => { } - } + if window_state.attributes.min_dimensions.is_some() || + window_state.attributes.max_dimensions.is_some() { - match window_state.attributes.max_dimensions { - Some((width, height)) => { + let style = winuser::GetWindowLongA(window, winuser::GWL_STYLE) as DWORD; + let ex_style = winuser::GetWindowLongA(window, winuser::GWL_EXSTYLE) as DWORD; + + if let Some(min_dimensions) = window_state.attributes.min_dimensions { + let (width, height) = adjust_size(min_dimensions, style, ex_style); + (*mmi).ptMinTrackSize = POINT { x: width as i32, y: height as i32 }; + } + if let Some(max_dimensions) = window_state.attributes.max_dimensions { + let (width, height) = adjust_size(max_dimensions, style, ex_style); (*mmi).ptMaxTrackSize = POINT { x: width as i32, y: height as i32 }; - }, - None => { } + } } } } diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index 5d328679..e362ac2e 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -622,6 +622,14 @@ pub struct WindowWrapper(HWND, HDC); // https://github.com/retep998/winapi-rs/issues/396 unsafe impl Send for WindowWrapper {} +pub unsafe fn adjust_size( + (x, y): (u32, u32), style: DWORD, ex_style: DWORD, +) -> (LONG, LONG) { + let mut rect = RECT { left: 0, right: x as LONG, top: 0, bottom: y as LONG }; + winuser::AdjustWindowRectEx(&mut rect, style, 0, ex_style); + (rect.right - rect.left, rect.bottom - rect.top) +} + unsafe fn init(window: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, inserter: events_loop::Inserter, events_loop_proxy: events_loop::EventsLoopProxy) -> Result { let title = OsStr::new(&window.title).encode_wide().chain(Some(0).into_iter()) @@ -659,10 +667,10 @@ unsafe fn init(window: WindowAttributes, pl_attribs: PlatformSpecificWindowBuild let real_window = { let (width, height) = if window.dimensions.is_some() { let min_dimensions = window.min_dimensions - .map(|d| (d.0 as raw::c_int, d.1 as raw::c_int)) + .map(|d| adjust_size(d, style, ex_style)) .unwrap_or((0, 0)); let max_dimensions = window.max_dimensions - .map(|d| (d.0 as raw::c_int, d.1 as raw::c_int)) + .map(|d| adjust_size(d, style, ex_style)) .unwrap_or((raw::c_int::max_value(), raw::c_int::max_value())); (