diff --git a/Cargo.toml b/Cargo.toml index 3ae8aa2d75..dc9ac5598a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,5 +63,7 @@ features = [ wayland-client = { version = "0.21", features = [ "dlopen", "egl", "cursor"] } smithay-client-toolkit = "0.4" x11-dl = "2.18.3" -parking_lot = "0.6" percent-encoding = "1.0" + +[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "windows"))'.dependencies.parking_lot] +version = "0.6" diff --git a/src/lib.rs b/src/lib.rs index bdfdb9928a..0cd3309d7d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,7 +109,7 @@ extern crate core_foundation; extern crate core_graphics; #[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] extern crate x11_dl; -#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] +#[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "windows"))] extern crate parking_lot; #[cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] extern crate percent_encoding; diff --git a/src/platform/windows/events_loop.rs b/src/platform/windows/events_loop.rs index 5c588550a3..a206df6dc5 100644 --- a/src/platform/windows/events_loop.rs +++ b/src/platform/windows/events_loop.rs @@ -17,8 +17,9 @@ use winapi::shared::basetsd::UINT_PTR; use std::rc::Rc; use std::{mem, ptr}; use std::cell::RefCell; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::collections::VecDeque; +use parking_lot::Mutex; use winapi::ctypes::c_int; use winapi::shared::minwindef::{ @@ -463,7 +464,7 @@ pub unsafe extern "system" fn callback( winuser::WM_MOUSEMOVE => { use events::WindowEvent::{CursorEntered, CursorMoved}; let mouse_outside_window = { - let mut window = subclass_input.window_state.lock().unwrap(); + let mut window = subclass_input.window_state.lock(); if !window.mouse_in_window { window.mouse_in_window = true; true @@ -503,7 +504,7 @@ pub unsafe extern "system" fn callback( winuser::WM_MOUSELEAVE => { use events::WindowEvent::CursorLeft; let mouse_in_window = { - let mut window = subclass_input.window_state.lock().unwrap(); + let mut window = subclass_input.window_state.lock(); if window.mouse_in_window { window.mouse_in_window = false; true @@ -594,7 +595,7 @@ pub unsafe extern "system" fn callback( use events::MouseButton::Left; use events::ElementState::Pressed; - capture_mouse(window, &mut *subclass_input.window_state.lock().unwrap()); + capture_mouse(window, &mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -608,7 +609,7 @@ pub unsafe extern "system" fn callback( use events::MouseButton::Left; use events::ElementState::Released; - release_mouse(&mut *subclass_input.window_state.lock().unwrap()); + release_mouse(&mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -622,7 +623,7 @@ pub unsafe extern "system" fn callback( use events::MouseButton::Right; use events::ElementState::Pressed; - capture_mouse(window, &mut *subclass_input.window_state.lock().unwrap()); + capture_mouse(window, &mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -636,7 +637,7 @@ pub unsafe extern "system" fn callback( use events::MouseButton::Right; use events::ElementState::Released; - release_mouse(&mut *subclass_input.window_state.lock().unwrap()); + release_mouse(&mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -650,7 +651,7 @@ pub unsafe extern "system" fn callback( use events::MouseButton::Middle; use events::ElementState::Pressed; - capture_mouse(window, &mut *subclass_input.window_state.lock().unwrap()); + capture_mouse(window, &mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -664,7 +665,7 @@ pub unsafe extern "system" fn callback( use events::MouseButton::Middle; use events::ElementState::Released; - release_mouse(&mut *subclass_input.window_state.lock().unwrap()); + release_mouse(&mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -679,7 +680,7 @@ pub unsafe extern "system" fn callback( use events::ElementState::Pressed; let xbutton = winuser::GET_XBUTTON_WPARAM(wparam); - capture_mouse(window, &mut *subclass_input.window_state.lock().unwrap()); + capture_mouse(window, &mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -694,7 +695,7 @@ pub unsafe extern "system" fn callback( use events::ElementState::Released; let xbutton = winuser::GET_XBUTTON_WPARAM(wparam); - release_mouse(&mut *subclass_input.window_state.lock().unwrap()); + release_mouse(&mut *subclass_input.window_state.lock()); subclass_input.send_event(Event::WindowEvent { window_id: SuperWindowId(WindowId(window)), @@ -893,7 +894,7 @@ pub unsafe extern "system" fn callback( winuser::WM_SETCURSOR => { let call_def_window_proc = { - let window_state = subclass_input.window_state.lock().unwrap(); + let window_state = subclass_input.window_state.lock(); if window_state.mouse_in_window { let cursor = winuser::LoadCursorW( ptr::null_mut(), @@ -921,7 +922,7 @@ pub unsafe extern "system" fn callback( winuser::WM_GETMINMAXINFO => { let mmi = lparam as *mut winuser::MINMAXINFO; - let window_state = subclass_input.window_state.lock().unwrap(); + let window_state = subclass_input.window_state.lock(); if window_state.min_size.is_some() || window_state.max_size.is_some() { let style = winuser::GetWindowLongA(window, winuser::GWL_STYLE) as DWORD; @@ -952,7 +953,7 @@ pub unsafe extern "system" fn callback( let new_dpi_factor = dpi_to_scale_factor(new_dpi_x); let suppress_resize = { - let mut window_state = subclass_input.window_state.lock().unwrap(); + let mut window_state = subclass_input.window_state.lock(); let suppress_resize = window_state.saved_window_info .as_mut() .map(|saved_window_info| { diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index 899e461077..49d9d15e3a 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -4,14 +4,15 @@ use std::{io, mem, ptr}; use std::cell::Cell; use std::ffi::OsStr; use std::os::windows::ffi::OsStrExt; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::sync::mpsc::channel; +use parking_lot::{Mutex, MutexGuard}; use winapi::ctypes::c_int; use winapi::shared::minwindef::{BOOL, DWORD, FALSE, LPARAM, TRUE, UINT, WORD, WPARAM}; use winapi::shared::windef::{HWND, LPPOINT, POINT, RECT}; use winapi::um::{combaseapi, dwmapi, libloaderapi, winuser, ole2}; -use winapi::um::objbase::COINIT_MULTITHREADED; +use winapi::um::objbase::COINIT_APARTMENTTHREADED; use winapi::um::shobjidl_core::{CLSID_TaskbarList, ITaskbarList2}; use winapi::um::wingdi::{CreateRectRgn, DeleteObject}; use winapi::um::oleidl::LPDROPTARGET; @@ -237,7 +238,7 @@ impl Window { } pub(crate) fn set_min_dimensions_physical(&self, dimensions: Option<(u32, u32)>) { - self.window_state.lock().unwrap().min_size = dimensions.map(Into::into); + self.window_state.lock().min_size = dimensions.map(Into::into); // Make windows re-check the window size bounds. self.get_inner_size_physical() .map(|(width, height)| self.set_inner_size_physical(width, height)); @@ -253,7 +254,7 @@ impl Window { } pub fn set_max_dimensions_physical(&self, dimensions: Option<(u32, u32)>) { - self.window_state.lock().unwrap().max_size = dimensions.map(Into::into); + self.window_state.lock().max_size = dimensions.map(Into::into); // Make windows re-check the window size bounds. self.get_inner_size_physical() .map(|(width, height)| self.set_inner_size_physical(width, height)); @@ -270,7 +271,7 @@ impl Window { #[inline] pub fn set_resizable(&self, resizable: bool) { - let mut window_state = self.window_state.lock().unwrap(); + let mut window_state = self.window_state.lock(); if mem::replace(&mut window_state.resizable, resizable) != resizable { // If we're in fullscreen, update stored configuration but don't apply anything. if window_state.fullscreen.is_none() { @@ -320,7 +321,7 @@ impl Window { MouseCursor::Help => winuser::IDC_HELP, _ => winuser::IDC_ARROW, // use arrow for the missing cases. }); - self.window_state.lock().unwrap().cursor = cursor_id; + self.window_state.lock().cursor = cursor_id; self.events_loop_proxy.execute_in_thread(move || unsafe { let cursor = winuser::LoadCursorW( ptr::null_mut(), @@ -376,7 +377,7 @@ impl Window { #[inline] pub fn grab_cursor(&self, grab: bool) -> Result<(), String> { let currently_grabbed = unsafe { self.cursor_is_grabbed() }?; - let window_state_lock = self.window_state.lock().unwrap(); + let window_state_lock = self.window_state.lock(); if currently_grabbed == grab && grab == window_state_lock.cursor_grabbed { return Ok(()); } @@ -386,7 +387,7 @@ impl Window { self.events_loop_proxy.execute_in_thread(move || { let result = unsafe { Self::grab_cursor_inner(&window, grab) }; if result.is_ok() { - window_state.lock().unwrap().cursor_grabbed = grab; + window_state.lock().cursor_grabbed = grab; } let _ = tx.send(result); }); @@ -404,14 +405,14 @@ impl Window { #[inline] pub fn hide_cursor(&self, hide: bool) { - let window_state_lock = self.window_state.lock().unwrap(); + let window_state_lock = self.window_state.lock(); // We don't want to increment/decrement the display count more than once! if hide == window_state_lock.cursor_hidden { return; } let (tx, rx) = channel(); let window_state = Arc::clone(&self.window_state); self.events_loop_proxy.execute_in_thread(move || { unsafe { Self::hide_cursor_inner(hide) }; - window_state.lock().unwrap().cursor_hidden = hide; + window_state.lock().cursor_hidden = hide; let _ = tx.send(()); }); drop(window_state_lock); @@ -420,7 +421,7 @@ impl Window { #[inline] pub fn get_hidpi_factor(&self) -> f64 { - self.window_state.lock().unwrap().dpi_factor + self.window_state.lock().dpi_factor } fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), String> { @@ -450,7 +451,7 @@ impl Window { #[inline] pub fn set_maximized(&self, maximized: bool) { - let mut window_state = self.window_state.lock().unwrap(); + let mut window_state = self.window_state.lock(); if mem::replace(&mut window_state.maximized, maximized) != maximized { // We only maximize if we're not in fullscreen. if window_state.fullscreen.is_none() { @@ -495,7 +496,7 @@ impl Window { (saved_window_info.style, saved_window_info.ex_style) } - unsafe fn restore_saved_window(&self, window_state_lock: &mut WindowState) { + unsafe fn restore_saved_window(&self, mut window_state_lock: MutexGuard) { let (rect, mut style, ex_style) = { // 'saved_window_info' can be None if the window has never been // in fullscreen mode before this method gets called. @@ -520,6 +521,7 @@ impl Window { let resizable = window_state_lock.resizable; let maximized = window_state_lock.maximized; + drop(window_state_lock); // We're restoring the window to its size and position from before being fullscreened. // `ShowWindow` resizes the window, so it must be called from the main thread. self.events_loop_proxy.execute_in_thread(move || { @@ -558,23 +560,31 @@ impl Window { mark_fullscreen(window.0, false); - let window_state_lock = window_state.lock().unwrap(); + let window_state_lock = window_state.lock(); let _ = Self::grab_cursor_inner(&window, window_state_lock.cursor_grabbed); }); } #[inline] pub fn set_fullscreen(&self, monitor: Option) { - let mut window_state_lock = self.window_state.lock().unwrap(); + let mut window_state_lock = self.window_state.lock(); unsafe { - match &monitor { - &Some(RootMonitorId { ref inner }) => { + let monitor_rect = monitor.as_ref() + .map(|RootMonitorId{ ref inner }| { let (x, y): (i32, i32) = inner.get_position().into(); let (width, height): (u32, u32) = inner.get_dimensions().into(); + (x, y, width, height) + }); + + match monitor_rect { + Some((x, y, width, height)) => { let window = self.window.clone(); let window_state = Arc::clone(&self.window_state); let (style, ex_style) = self.set_fullscreen_style(&mut window_state_lock); + window_state_lock.fullscreen = monitor; + drop(window_state_lock); + self.events_loop_proxy.execute_in_thread(move || { let _ = Self::grab_cursor_inner(&window, false); @@ -609,25 +619,24 @@ impl Window { mark_fullscreen(window.0, true); - let window_state_lock = window_state.lock().unwrap(); + let window_state_lock = window_state.lock(); let _ = Self::grab_cursor_inner(&window, window_state_lock.cursor_grabbed); }); - } - &None => { - self.restore_saved_window(&mut window_state_lock); + }, + None => { + window_state_lock.fullscreen = None; + self.restore_saved_window(window_state_lock) } } } - - window_state_lock.fullscreen = monitor; } #[inline] pub fn set_decorations(&self, decorations: bool) { - let mut window_state = self.window_state.lock().unwrap(); + let mut window_state = self.window_state.lock(); if mem::replace(&mut window_state.decorations, decorations) != decorations { - let style_flags = (winuser::WS_CAPTION | winuser::WS_THICKFRAME) as LONG; - let ex_style_flags = (winuser::WS_EX_WINDOWEDGE) as LONG; + let style_flags = (winuser::WS_CAPTION | winuser::WS_THICKFRAME) as LONG; + let ex_style_flags = (winuser::WS_EX_WINDOWEDGE) as LONG; // if we are in fullscreen mode, we only change the saved window info if window_state.fullscreen.is_some() { @@ -697,7 +706,7 @@ impl Window { #[inline] pub fn set_always_on_top(&self, always_on_top: bool) { - let mut window_state = self.window_state.lock().unwrap(); + let mut window_state = self.window_state.lock(); if mem::replace(&mut window_state.always_on_top, always_on_top) != always_on_top { let window = self.window.clone(); self.events_loop_proxy.execute_in_thread(move || { @@ -739,7 +748,7 @@ impl Window { } else { icon::unset_for_window(self.window.0, IconType::Small); } - self.window_state.lock().unwrap().window_icon = window_icon; + self.window_state.lock().window_icon = window_icon; } #[inline] @@ -752,7 +761,7 @@ impl Window { } else { icon::unset_for_window(self.window.0, IconType::Big); } - self.window_state.lock().unwrap().taskbar_icon = taskbar_icon; + self.window_state.lock().taskbar_icon = taskbar_icon; } #[inline] @@ -1057,6 +1066,7 @@ unsafe fn init( let file_drop_handler = { use winapi::shared::winerror::{OLE_E_WRONGCOMPOBJ, RPC_E_CHANGED_MODE, S_OK}; + let ole_init_result = ole2::OleInitialize(ptr::null_mut()); // It is ok if the initialize result is `S_FALSE` because it might happen that // multiple windows are created on the same thread. @@ -1136,7 +1146,7 @@ impl Drop for ComInitialized { thread_local!{ static COM_INITIALIZED: ComInitialized = { unsafe { - combaseapi::CoInitializeEx(ptr::null_mut(), COINIT_MULTITHREADED); + combaseapi::CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED); ComInitialized(ptr::null_mut()) } };