Skip to content

Commit

Permalink
Replace windows Mutex with parking_lot Mutex
Browse files Browse the repository at this point in the history
  • Loading branch information
Osspial committed Nov 9, 2018
1 parent 9feada2 commit 8b8a767
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 46 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
29 changes: 15 additions & 14 deletions src/platform/windows/events_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)),
Expand All @@ -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)),
Expand All @@ -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)),
Expand All @@ -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)),
Expand All @@ -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)),
Expand All @@ -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)),
Expand All @@ -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)),
Expand All @@ -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)),
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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| {
Expand Down
70 changes: 40 additions & 30 deletions src/platform/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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() {
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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(());
}
Expand All @@ -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);
});
Expand All @@ -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);
Expand All @@ -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> {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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<WindowState>) {
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.
Expand All @@ -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 || {
Expand Down Expand Up @@ -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<RootMonitorId>) {
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);

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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 || {
Expand Down Expand Up @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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())
}
};
Expand Down

0 comments on commit 8b8a767

Please sign in to comment.