Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
static HAS_FOCUS: AtomicBool = AtomicBool::new(true);

/// Returns the minimum `Option<Duration>`, taking into account that `None`
/// equates to an infinite timeout, not a zero timeout (so can't just use
Expand Down Expand Up @@ -236,7 +235,7 @@ impl<T: 'static> EventLoop<T> {
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),
Expand All @@ -246,7 +245,7 @@ impl<T: 'static> EventLoop<T> {
);
}
MainEvent::LostFocus => {
*HAS_FOCUS.write().unwrap() = false;
HAS_FOCUS.store(false, Ordering::Relaxed);
callback(
event::Event::WindowEvent {
window_id: window::WindowId(WindowId),
Expand Down Expand Up @@ -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 {
Expand Down
53 changes: 28 additions & 25 deletions src/platform_impl/ios/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -902,10 +901,10 @@ macro_rules! os_capabilities {
os_version: NSOperatingSystemVersion,
}

impl From<NSOperatingSystemVersion> 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, }
}
}

Expand Down Expand Up @@ -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<OSCapabilities> = 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<OSCapabilities> = OnceLock::new();
OS_CAPABILITIES
.get_or_init(|| OSCapabilities::from_os_version(get_version()))
.clone()
}
3 changes: 1 addition & 2 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,7 @@ pub(crate) enum PlatformCustomCursor {

/// Hooks for X11 errors.
#[cfg(x11_platform)]
pub(crate) static mut XLIB_ERROR_HOOKS: Lazy<Mutex<Vec<XlibErrorHook>>> =
Lazy::new(|| Mutex::new(Vec::new()));
pub(crate) static mut XLIB_ERROR_HOOKS: Mutex<Vec<XlibErrorHook>> = Mutex::new(Vec::new());

#[cfg(x11_platform)]
unsafe extern "C" fn x_error_callback(
Expand Down
3 changes: 1 addition & 2 deletions src/platform_impl/linux/x11/ime/input_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Mutex<()>> = Lazy::new(Default::default);
static GLOBAL_LOCK: Mutex<()> = Mutex::new(());

unsafe fn open_im(xconn: &Arc<XConnection>, locale_modifiers: &CStr) -> Option<ffi::XIM> {
let _lock = GLOBAL_LOCK.lock();
Expand Down
7 changes: 2 additions & 5 deletions src/platform_impl/linux/x11/util/wm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::sync::Mutex;

use crate::utils::Lazy;

use super::*;

// https://specifications.freedesktop.org/wm-spec/latest/ar01s04.html#idm46075117309248
Expand All @@ -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<Mutex<Vec<xproto::Atom>>> =
Lazy::new(|| Mutex::new(Vec::with_capacity(0)));
static WM_NAME: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None));
static SUPPORTED_HINTS: Mutex<Vec<xproto::Atom>> = Mutex::new(Vec::new());
static WM_NAME: Mutex<Option<String>> = Mutex::new(None);

pub fn hint_is_supported(hint: xproto::Atom) -> bool {
(*SUPPORTED_HINTS.lock().unwrap()).contains(&hint)
Expand Down
26 changes: 14 additions & 12 deletions src/platform_impl/macos/cursor.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -171,19 +172,20 @@ pub(crate) fn invisible_cursor() -> Id<NSCursor> {
0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B,
];

static CURSOR: Lazy<CustomCursor> = Lazy::new(|| {
fn new_invisible() -> Id<NSCursor> {
// 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<CustomCursor> = OnceLock::new();
CURSOR
.get_or_init(|| CustomCursor(new_invisible()))
.0
.clone()
}

pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Id<NSCursor> {
Expand Down