diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 8992c63b1d..47ebff002b 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -7,12 +7,11 @@ use std::{ marker::PhantomData, sync::{ atomic::{AtomicBool, Ordering}, - mpsc, Arc, Mutex, RwLock, + mpsc, Arc, Mutex, }, time::{Duration, Instant}, }; -use crate::utils::Lazy; use android_activity::input::{InputEvent, KeyAction, Keycode, MotionAction}; use android_activity::{ AndroidApp, AndroidAppWaker, ConfigurationRef, InputStatus, MainEvent, Rect, @@ -39,7 +38,7 @@ pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursor; pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursorSource; pub(crate) use crate::icon::NoIcon as PlatformIcon; -static HAS_FOCUS: Lazy> = Lazy::new(|| RwLock::new(true)); +static HAS_FOCUS: AtomicBool = AtomicBool::new(true); /// Returns the minimum `Option`, taking into account that `None` /// equates to an infinite timeout, not a zero timeout (so can't just use @@ -236,7 +235,7 @@ impl EventLoop { warn!("TODO: find a way to notify application of content rect change"); } MainEvent::GainedFocus => { - *HAS_FOCUS.write().unwrap() = true; + HAS_FOCUS.store(true, Ordering::Relaxed); callback( event::Event::WindowEvent { window_id: window::WindowId(WindowId), @@ -246,7 +245,7 @@ impl EventLoop { ); } MainEvent::LostFocus => { - *HAS_FOCUS.write().unwrap() = false; + HAS_FOCUS.store(false, Ordering::Relaxed); callback( event::Event::WindowEvent { window_id: window::WindowId(WindowId), @@ -1046,7 +1045,7 @@ impl Window { pub fn set_content_protected(&self, _protected: bool) {} pub fn has_focus(&self) -> bool { - *HAS_FOCUS.read().unwrap() + HAS_FOCUS.load(Ordering::Relaxed) } pub fn title(&self) -> String { diff --git a/src/platform_impl/ios/app_state.rs b/src/platform_impl/ios/app_state.rs index beef5a1df1..182689bd34 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -6,11 +6,10 @@ use std::{ fmt, mem, os::raw::c_void, ptr, - sync::{Arc, Mutex}, + sync::{Arc, Mutex, OnceLock}, time::Instant, }; -use crate::utils::Lazy; use core_foundation::base::CFRelease; use core_foundation::date::CFAbsoluteTimeGetCurrent; use core_foundation::runloop::{ @@ -902,10 +901,10 @@ macro_rules! os_capabilities { os_version: NSOperatingSystemVersion, } - impl From for OSCapabilities { - fn from(os_version: NSOperatingSystemVersion) -> OSCapabilities { + impl OSCapabilities { + fn from_os_version(os_version: NSOperatingSystemVersion) -> Self { $(let $name = meets_requirements(os_version, $major, $minor);)* - OSCapabilities { $($name,)* os_version, } + Self { $($name,)* os_version, } } } @@ -950,25 +949,29 @@ fn meets_requirements( (version.majorVersion, version.minorVersion) >= (required_major, required_minor) } +fn get_version() -> NSOperatingSystemVersion { + unsafe { + let process_info = NSProcessInfo::processInfo(); + let atleast_ios_8: bool = msg_send![ + &process_info, + respondsToSelector: sel!(operatingSystemVersion) + ]; + // winit requires atleast iOS 8 because no one has put the time into supporting earlier os versions. + // Older iOS versions are increasingly difficult to test. For example, Xcode 11 does not support + // debugging on devices with an iOS version of less than 8. Another example, in order to use an iOS + // simulator older than iOS 8, you must download an older version of Xcode (<9), and at least Xcode 7 + // has been tested to not even run on macOS 10.15 - Xcode 8 might? + // + // The minimum required iOS version is likely to grow in the future. + assert!(atleast_ios_8, "`winit` requires iOS version 8 or greater"); + process_info.operatingSystemVersion() + } +} + pub fn os_capabilities() -> OSCapabilities { - static OS_CAPABILITIES: Lazy = Lazy::new(|| { - let version: NSOperatingSystemVersion = unsafe { - let process_info = NSProcessInfo::processInfo(); - let atleast_ios_8: bool = msg_send![ - &process_info, - respondsToSelector: sel!(operatingSystemVersion) - ]; - // winit requires atleast iOS 8 because no one has put the time into supporting earlier os versions. - // Older iOS versions are increasingly difficult to test. For example, Xcode 11 does not support - // debugging on devices with an iOS version of less than 8. Another example, in order to use an iOS - // simulator older than iOS 8, you must download an older version of Xcode (<9), and at least Xcode 7 - // has been tested to not even run on macOS 10.15 - Xcode 8 might? - // - // The minimum required iOS version is likely to grow in the future. - assert!(atleast_ios_8, "`winit` requires iOS version 8 or greater"); - process_info.operatingSystemVersion() - }; - version.into() - }); - OS_CAPABILITIES.clone() + // Cache the version lookup for efficiency + static OS_CAPABILITIES: OnceLock = OnceLock::new(); + OS_CAPABILITIES + .get_or_init(|| OSCapabilities::from_os_version(get_version())) + .clone() } diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 84ff9ef5f0..9a0eb94b10 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -647,8 +647,7 @@ pub(crate) enum PlatformCustomCursor { /// Hooks for X11 errors. #[cfg(x11_platform)] -pub(crate) static mut XLIB_ERROR_HOOKS: Lazy>> = - Lazy::new(|| Mutex::new(Vec::new())); +pub(crate) static mut XLIB_ERROR_HOOKS: Mutex> = Mutex::new(Vec::new()); #[cfg(x11_platform)] unsafe extern "C" fn x_error_callback( diff --git a/src/platform_impl/linux/x11/ime/input_method.rs b/src/platform_impl/linux/x11/ime/input_method.rs index 9221efcd68..44cb8164d3 100644 --- a/src/platform_impl/linux/x11/ime/input_method.rs +++ b/src/platform_impl/linux/x11/ime/input_method.rs @@ -8,10 +8,9 @@ use std::{ }; use super::{super::atoms::*, ffi, util, XConnection, XError}; -use crate::utils::Lazy; use x11rb::protocol::xproto; -static GLOBAL_LOCK: Lazy> = Lazy::new(Default::default); +static GLOBAL_LOCK: Mutex<()> = Mutex::new(()); unsafe fn open_im(xconn: &Arc, locale_modifiers: &CStr) -> Option { let _lock = GLOBAL_LOCK.lock(); diff --git a/src/platform_impl/linux/x11/util/wm.rs b/src/platform_impl/linux/x11/util/wm.rs index 57efb6bf7a..6c96ff143c 100644 --- a/src/platform_impl/linux/x11/util/wm.rs +++ b/src/platform_impl/linux/x11/util/wm.rs @@ -1,7 +1,5 @@ use std::sync::Mutex; -use crate::utils::Lazy; - use super::*; // https://specifications.freedesktop.org/wm-spec/latest/ar01s04.html#idm46075117309248 @@ -16,9 +14,8 @@ pub const MOVERESIZE_LEFT: isize = 7; pub const MOVERESIZE_MOVE: isize = 8; // This info is global to the window manager. -static SUPPORTED_HINTS: Lazy>> = - Lazy::new(|| Mutex::new(Vec::with_capacity(0))); -static WM_NAME: Lazy>> = Lazy::new(|| Mutex::new(None)); +static SUPPORTED_HINTS: Mutex> = Mutex::new(Vec::new()); +static WM_NAME: Mutex> = Mutex::new(None); pub fn hint_is_supported(hint: xproto::Atom) -> bool { (*SUPPORTED_HINTS.lock().unwrap()).contains(&hint) diff --git a/src/platform_impl/macos/cursor.rs b/src/platform_impl/macos/cursor.rs index fc105eba9c..e856c09e2a 100644 --- a/src/platform_impl/macos/cursor.rs +++ b/src/platform_impl/macos/cursor.rs @@ -1,4 +1,7 @@ -use crate::utils::Lazy; +use std::ffi::c_uchar; +use std::slice; +use std::sync::OnceLock; + use icrate::AppKit::{NSBitmapImageRep, NSCursor, NSDeviceRGBColorSpace, NSImage}; use icrate::Foundation::{ ns_string, NSData, NSDictionary, NSNumber, NSObject, NSObjectProtocol, NSPoint, NSSize, @@ -7,8 +10,6 @@ use icrate::Foundation::{ use objc2::rc::Id; use objc2::runtime::Sel; use objc2::{msg_send_id, sel, ClassType}; -use std::ffi::c_uchar; -use std::slice; use crate::cursor::CursorImage; use crate::cursor::OnlyCursorImageSource; @@ -171,19 +172,20 @@ pub(crate) fn invisible_cursor() -> Id { 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B, ]; - static CURSOR: Lazy = Lazy::new(|| { + fn new_invisible() -> Id { // TODO: Consider using `dataWithBytesNoCopy:` let data = NSData::with_bytes(CURSOR_BYTES); let image = NSImage::initWithData(NSImage::alloc(), &data).unwrap(); let hotspot = NSPoint::new(0.0, 0.0); - CustomCursor(NSCursor::initWithImage_hotSpot( - NSCursor::alloc(), - &image, - hotspot, - )) - }); - - CURSOR.0.clone() + NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot) + } + + // Cache this for efficiency + static CURSOR: OnceLock = OnceLock::new(); + CURSOR + .get_or_init(|| CustomCursor(new_invisible())) + .0 + .clone() } pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Id {