diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b43fef..27974689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Unreleased +- Corrected `get_position` on Windows to be relative to the screen rather than to the taskbar. +- Corrected `Moved` event on Windows to use position values equivalent to those returned by `get_position`. It previously supplied client area positions instead of window positions, and would additionally interpret negative values as being very large (around `u16::MAX`). + # Version 0.13.1 (2018-04-26) - Ensure necessary `x11-dl` version is used. diff --git a/src/events.rs b/src/events.rs index 1faaadf6..2dcc3ead 100644 --- a/src/events.rs +++ b/src/events.rs @@ -24,10 +24,10 @@ pub enum Event { #[derive(Clone, Debug)] pub enum WindowEvent { - /// The size of the window has changed. + /// The size of the window has changed. Contains the client area's new dimensions. Resized(u32, u32), - /// The position of the window has changed. + /// The position of the window has changed. Contains the window's new position. Moved(i32, i32), /// The window has been requested to close. diff --git a/src/os/macos.rs b/src/os/macos.rs old mode 100755 new mode 100644 diff --git a/src/platform/windows/events_loop.rs b/src/platform/windows/events_loop.rs index 72b014d7..3ca51802 100644 --- a/src/platform/windows/events_loop.rs +++ b/src/platform/windows/events_loop.rs @@ -423,6 +423,22 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT, winuser::DefWindowProcW(window, msg, wparam, lparam) }, + // WM_MOVE supplies client area positions, so we send Moved here instead. + winuser::WM_WINDOWPOSCHANGED => { + use events::WindowEvent::Moved; + + let windowpos = lparam as *const winuser::WINDOWPOS; + if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE { + send_event(Event::WindowEvent { + window_id: SuperWindowId(WindowId(window)), + event: Moved((*windowpos).x, (*windowpos).y), + }); + } + + // This is necessary for us to still get sent WM_SIZE. + winuser::DefWindowProcW(window, msg, wparam, lparam) + }, + winuser::WM_SIZE => { use events::WindowEvent::Resized; let w = LOWORD(lparam as DWORD) as u32; @@ -461,17 +477,6 @@ pub unsafe extern "system" fn callback(window: HWND, msg: UINT, 0 }, - winuser::WM_MOVE => { - use events::WindowEvent::Moved; - let x = LOWORD(lparam as DWORD) as i32; - let y = HIWORD(lparam as DWORD) as i32; - send_event(Event::WindowEvent { - window_id: SuperWindowId(WindowId(window)), - event: Moved(x, y), - }); - 0 - }, - winuser::WM_CHAR => { use std::mem; use events::WindowEvent::ReceivedCharacter; diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index 23011497..e0a37a0c 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -116,24 +116,20 @@ impl Window { /// See the docs in the crate root file. pub fn get_position(&self) -> Option<(i32, i32)> { - use std::mem; + let mut rect: RECT = unsafe { mem::uninitialized() }; - let mut placement: winuser::WINDOWPLACEMENT = unsafe { mem::zeroed() }; - placement.length = mem::size_of::() as UINT; - - if unsafe { winuser::GetWindowPlacement(self.window.0, &mut placement) } == 0 { - return None + if unsafe { winuser::GetWindowRect(self.window.0, &mut rect) } != 0 { + Some((rect.left as i32, rect.top as i32)) + } else { + None } - - let ref rect = placement.rcNormalPosition; - Some((rect.left as i32, rect.top as i32)) } pub fn get_inner_position(&self) -> Option<(i32, i32)> { use std::mem; - let mut position: POINT = unsafe{ mem::zeroed() }; - if unsafe{ winuser::ClientToScreen(self.window.0, &mut position) } == 0 { + let mut position: POINT = unsafe { mem::zeroed() }; + if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 { return None; } @@ -749,7 +745,7 @@ unsafe fn init(window: WindowAttributes, pl_attribs: PlatformSpecificWindowBuild winuser::RegisterTouchWindow( real_window.0, winuser::TWF_WANTPALM ); } } - + // Creating a mutex to track the current window state let window_state = Arc::new(Mutex::new(events_loop::WindowState { cursor: winuser::IDC_ARROW, // use arrow by default