macOS: Fix cursor hiding thread unsafety (#611)

This commit is contained in:
Francesca Frangipane 2018-07-26 17:14:16 -04:00 committed by GitHub
parent 72b24a9348
commit 88427262a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 7 additions and 4 deletions

View file

@ -5,6 +5,7 @@
- Added NetBSD support. - Added NetBSD support.
- **Breaking:** On iOS, `UIView` is now the default root view. `WindowBuilderExt::with_root_view_class` can be used to set the root view objective-c class to `GLKView` (OpenGLES) or `MTKView` (Metal/MoltenVK). - **Breaking:** On iOS, `UIView` is now the default root view. `WindowBuilderExt::with_root_view_class` can be used to set the root view objective-c class to `GLKView` (OpenGLES) or `MTKView` (Metal/MoltenVK).
- On iOS, the `UIApplication` is not started until `Window::new` is called. - On iOS, the `UIApplication` is not started until `Window::new` is called.
- Fixed thread unsafety with cursor hiding on macOS.
# Version 0.16.2 (2018-07-07) # Version 0.16.2 (2018-07-07)

View file

@ -1,8 +1,9 @@
use std; use std;
use std::cell::{Cell, RefCell};
use std::ops::Deref; use std::ops::Deref;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::sync::Weak; use std::sync::Weak;
use std::cell::{Cell, RefCell}; use std::sync::atomic::{Ordering, AtomicBool};
use cocoa; use cocoa;
use cocoa::appkit::{ use cocoa::appkit::{
@ -45,6 +46,7 @@ use window::MonitorId as RootMonitorId;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(pub usize); pub struct Id(pub usize);
// TODO: It's possible for delegate methods to be called asynchronously, causing data races / `RefCell` panics.
pub struct DelegateState { pub struct DelegateState {
view: IdRef, view: IdRef,
window: IdRef, window: IdRef,
@ -526,7 +528,7 @@ pub struct Window2 {
pub window: IdRef, pub window: IdRef,
pub delegate: WindowDelegate, pub delegate: WindowDelegate,
pub input_context: IdRef, pub input_context: IdRef,
cursor_hidden: Cell<bool>, cursor_hidden: AtomicBool,
} }
unsafe impl Send for Window2 {} unsafe impl Send for Window2 {}
@ -1007,13 +1009,13 @@ impl Window2 {
let cursor_class = class!(NSCursor); let cursor_class = class!(NSCursor);
// macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once. // macOS uses a "hide counter" like Windows does, so we avoid incrementing it more than once.
// (otherwise, `hide_cursor(false)` would need to be called n times!) // (otherwise, `hide_cursor(false)` would need to be called n times!)
if hide != self.cursor_hidden.get() { if hide != self.cursor_hidden.load(Ordering::Acquire) {
if hide { if hide {
let _: () = unsafe { msg_send![cursor_class, hide] }; let _: () = unsafe { msg_send![cursor_class, hide] };
} else { } else {
let _: () = unsafe { msg_send![cursor_class, unhide] }; let _: () = unsafe { msg_send![cursor_class, unhide] };
} }
self.cursor_hidden.replace(hide); self.cursor_hidden.store(hide, Ordering::Release);
} }
} }