From 163563073fe08c3865e10ada9375e400b732b82e Mon Sep 17 00:00:00 2001 From: Osspial Date: Sat, 7 May 2016 21:00:50 -0400 Subject: [PATCH 1/2] Fixed win32 bug where resizing window wouldn't show resize cursors --- src/api/win32/callback.rs | 69 ++++++++++++++++++++++++++++----------- src/api/win32/init.rs | 3 +- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/api/win32/callback.rs b/src/api/win32/callback.rs index 2d10699d..fc531ae7 100644 --- a/src/api/win32/callback.rs +++ b/src/api/win32/callback.rs @@ -24,7 +24,8 @@ thread_local!(pub static CONTEXT_STASH: RefCell> = RefCe pub struct ThreadLocalData { pub win: winapi::HWND, pub sender: Sender, - pub window_state: Arc> + pub window_state: Arc>, + pub mouse_in_window: bool } struct MinMaxInfo { @@ -122,15 +123,40 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, winapi::WM_MOUSEMOVE => { use events::Event::MouseMoved; + CONTEXT_STASH.with(|context_stash| { + let mut context_stash = context_stash.borrow_mut(); + if let Some(context_stash) = context_stash.as_mut() { + context_stash.mouse_in_window = true; + } + }); let x = winapi::GET_X_LPARAM(lparam) as i32; let y = winapi::GET_Y_LPARAM(lparam) as i32; + let mut mouse_track = winapi::TRACKMOUSEEVENT { + cbSize: mem::size_of::() as winapi::DWORD, + dwFlags: winapi::TME_HOVER | winapi::TME_LEAVE, + hwndTrack: window, + dwHoverTime: winapi::HOVER_DEFAULT + }; + user32::TrackMouseEvent(&mut mouse_track); + send_event(window, MouseMoved((x, y))); 0 }, + winapi::WM_MOUSELEAVE => { + CONTEXT_STASH.with(|context_stash| { + let mut context_stash = context_stash.borrow_mut(); + if let Some(context_stash) = context_stash.as_mut() { + context_stash.mouse_in_window = false; + } + }); + + 0 + }, + winapi::WM_MOUSEWHEEL => { use events::Event::MouseWheel; use events::MouseScrollDelta::LineDelta; @@ -264,31 +290,36 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_SETCURSOR => { - CONTEXT_STASH.with(|context_stash| { + let call_def_window_proc = CONTEXT_STASH.with(|context_stash| { let cstash = context_stash.borrow(); - let cstash = cstash.as_ref(); - // there's a very bizarre borrow checker bug - // possibly related to rust-lang/rust/#23338 - let _cursor_state = if let Some(cstash) = cstash { + let mut call_def_window_proc = false; + if let Some(cstash) = cstash.as_ref() { if let Ok(window_state) = cstash.window_state.lock() { - match window_state.cursor_state { - CursorState::Normal => { - user32::SetCursor(user32::LoadCursorW( - ptr::null_mut(), - window_state.cursor)); - }, - CursorState::Grab | CursorState::Hide => { - user32::SetCursor(ptr::null_mut()); + if cstash.mouse_in_window { + match window_state.cursor_state { + CursorState::Normal => { + user32::SetCursor(user32::LoadCursorW( + ptr::null_mut(), + window_state.cursor)); + }, + CursorState::Grab | CursorState::Hide => { + user32::SetCursor(ptr::null_mut()); + } } + } else { + call_def_window_proc = true; } } - } else { - return - }; + } -// let &ThreadLocalData { ref cursor_state, .. } = stored; + call_def_window_proc }); - 0 + + if call_def_window_proc { + user32::DefWindowProcW(window, msg, wparam, lparam) + } else { + 0 + } }, winapi::WM_DROPFILES => { diff --git a/src/api/win32/init.rs b/src/api/win32/init.rs index 79482a3f..bc563847 100644 --- a/src/api/win32/init.rs +++ b/src/api/win32/init.rs @@ -169,7 +169,8 @@ unsafe fn init(title: Vec, window: &WindowAttributes) -> Result Date: Sat, 7 May 2016 21:05:45 -0400 Subject: [PATCH 2/2] Fixed some warnings when building on Windows --- src/api/win32/callback.rs | 7 +++++-- src/lib.rs | 4 ---- src/platform/windows/mod.rs | 2 -- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/api/win32/callback.rs b/src/api/win32/callback.rs index fc531ae7..e2b74121 100644 --- a/src/api/win32/callback.rs +++ b/src/api/win32/callback.rs @@ -6,7 +6,6 @@ use std::sync::{Arc, Mutex}; use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; -use WindowAttributes; use CursorState; use Event; use super::event; @@ -28,6 +27,10 @@ pub struct ThreadLocalData { pub mouse_in_window: bool } +/// Equivalent to the windows api [MINMAXINFO](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632605%28v=vs.85%29.aspx) +/// struct. Used because winapi-rs doesn't have this declared. +#[repr(C)] +#[allow(dead_code)] struct MinMaxInfo { reserved: winapi::POINT, // Do not use/change max_size: winapi::POINT, @@ -342,7 +345,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, }, winapi::WM_GETMINMAXINFO => { - let mut mmi = lparam as *mut MinMaxInfo; + let mmi = lparam as *mut MinMaxInfo; //(*mmi).max_position = winapi::POINT { x: -8, y: -8 }; // The upper left corner of the window if it were maximized on the primary monitor. //(*mmi).max_size = winapi::POINT { x: .., y: .. }; // The dimensions of the primary monitor. diff --git a/src/lib.rs b/src/lib.rs index e92dc031..dea319cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,10 +65,6 @@ pub use window::{WindowBuilder, WindowProxy, PollEventsIterator, WaitEventsItera pub use window::{AvailableMonitorsIter, MonitorId, get_available_monitors, get_primary_monitor}; pub use native_monitor::NativeMonitorId; -use std::io; -#[cfg(not(target_os = "macos"))] -use std::cmp::Ordering; - mod api; mod platform; mod events; diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index 413a12f2..249ee157 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -7,9 +7,7 @@ pub use api::win32::{WindowProxy, PollEventsIterator, WaitEventsIterator}; use CreationError; use WindowAttributes; -use std::ffi::CString; use std::ops::{Deref, DerefMut}; -use kernel32; #[derive(Default)] pub struct PlatformSpecificWindowBuilderAttributes;