From 7a6d8441b6bc69dbd069d89dc1c68ef4578b1b38 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 5 Jun 2022 01:43:04 -0700 Subject: [PATCH 1/6] Migrate from lazy_static to once_cell --- Cargo.toml | 2 +- src/lib.rs | 3 - src/platform_impl/android/mod.rs | 25 +- src/platform_impl/ios/app_state.rs | 45 ++- src/platform_impl/linux/mod.rs | 8 +- .../linux/x11/ime/input_method.rs | 8 +- src/platform_impl/linux/x11/monitor.rs | 5 +- src/platform_impl/linux/x11/util/atom.rs | 8 +- src/platform_impl/linux/x11/util/wm.rs | 8 +- src/platform_impl/macos/app.rs | 21 +- src/platform_impl/macos/app_delegate.rs | 27 +- src/platform_impl/macos/app_state.rs | 24 +- src/platform_impl/macos/view.rs | 352 +++++++++--------- src/platform_impl/macos/window.rs | 68 ++-- src/platform_impl/macos/window_delegate.rs | 192 +++++----- src/platform_impl/windows/dark_mode.rs | 104 +++--- src/platform_impl/windows/event_loop.rs | 129 +++---- src/platform_impl/windows/util.rs | 31 +- 18 files changed, 504 insertions(+), 556 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3f5acfb21d..764da52e81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ wayland-csd-adwaita-notitle = ["sctk-adwaita"] [dependencies] instant = { version = "0.1", features = ["wasm-bindgen"] } -lazy_static = "1" +once_cell = "1.12" log = "0.4" serde = { version = "1", optional = true, features = ["serde_derive"] } raw-window-handle = "0.4.2" diff --git a/src/lib.rs b/src/lib.rs index a74586f850..4ad8f806fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -133,9 +133,6 @@ #![deny(rust_2018_idioms)] #![deny(rustdoc::broken_intra_doc_links)] -#[allow(unused_imports)] -#[macro_use] -extern crate lazy_static; #[allow(unused_imports)] #[macro_use] extern crate log; diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 27d9984b1d..489211860f 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -13,6 +13,7 @@ use ndk::{ looper::{ForeignLooper, Poll, ThreadLooper}, }; use ndk_glue::{Event, Rect}; +use once_cell::sync::Lazy; use raw_window_handle::{AndroidNdkHandle, RawWindowHandle}; use std::{ collections::VecDeque, @@ -20,19 +21,19 @@ use std::{ time::{Duration, Instant}, }; -lazy_static! { - static ref CONFIG: RwLock = RwLock::new(Configuration::from_asset_manager( +static CONFIG: Lazy> = Lazy::new(|| { + RwLock::new(Configuration::from_asset_manager( #[allow(deprecated)] // TODO: rust-windowing/winit#2196 - &ndk_glue::native_activity().asset_manager() - )); - // If this is `Some()` a `Poll::Wake` is considered an `EventSource::Internal` with the event - // contained in the `Option`. The event is moved outside of the `Option` replacing it with a - // `None`. - // - // This allows us to inject event into the event loop without going through `ndk-glue` and - // calling unsafe function that should only be called by Android. - static ref INTERNAL_EVENT: RwLock> = RwLock::new(None); -} + &ndk_glue::native_activity().asset_manager(), + )) +}); +// If this is `Some()` a `Poll::Wake` is considered an `EventSource::Internal` with the event +// contained in the `Option`. The event is moved outside of the `Option` replacing it with a +// `None`. +// +// This allows us to inject event into the event loop without going through `ndk-glue` and +// calling unsafe function that should only be called by Android. +static INTERNAL_EVENT: Lazy>> = Lazy::new(|| RwLock::new(None)); enum InternalEvent { RedrawRequested, diff --git a/src/platform_impl/ios/app_state.rs b/src/platform_impl/ios/app_state.rs index 6d1d206942..848d16b36f 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -1,5 +1,6 @@ #![deny(unused_results)] +use once_cell::sync::Lazy; use std::{ cell::{RefCell, RefMut}, collections::HashSet, @@ -1016,29 +1017,27 @@ impl NSOperatingSystemVersion { } pub fn os_capabilities() -> OSCapabilities { - lazy_static! { - static ref OS_CAPABILITIES: OSCapabilities = { - let version: NSOperatingSystemVersion = unsafe { - let process_info: id = msg_send![class!(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 == YES, - "`winit` requires iOS version 8 or greater" - ); - msg_send![process_info, operatingSystemVersion] - }; - version.into() + static OS_CAPABILITIES: Lazy = Lazy::new(|| { + let version: NSOperatingSystemVersion = unsafe { + let process_info: id = msg_send![class!(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 == YES, + "`winit` requires iOS version 8 or greater" + ); + msg_send![process_info, operatingSystemVersion] }; - } + version.into() + }); OS_CAPABILITIES.clone() } diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 6552a8227d..a07f6d198f 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -14,6 +14,8 @@ use crate::window::Theme; #[cfg(feature = "wayland")] use std::error::Error; +#[cfg(feature = "x11")] +use once_cell::sync::Lazy; use std::{collections::VecDeque, env, fmt}; #[cfg(feature = "x11")] use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Arc}; @@ -133,10 +135,8 @@ impl Default for PlatformSpecificWindowBuilderAttributes { } #[cfg(feature = "x11")] -lazy_static! { - pub static ref X11_BACKEND: Mutex, XNotSupported>> = - Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)); -} +pub static X11_BACKEND: Lazy, XNotSupported>>> = + Lazy::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))); #[derive(Debug, Clone)] pub enum OsError { diff --git a/src/platform_impl/linux/x11/ime/input_method.rs b/src/platform_impl/linux/x11/ime/input_method.rs index e552f55635..f71d523487 100644 --- a/src/platform_impl/linux/x11/ime/input_method.rs +++ b/src/platform_impl/linux/x11/ime/input_method.rs @@ -1,3 +1,5 @@ +use once_cell::sync::Lazy; +use parking_lot::Mutex; use std::{ env, ffi::{CStr, CString, IntoStringError}, @@ -7,13 +9,9 @@ use std::{ sync::Arc, }; -use parking_lot::Mutex; - use super::{ffi, util, XConnection, XError}; -lazy_static! { - static ref GLOBAL_LOCK: Mutex<()> = Default::default(); -} +static GLOBAL_LOCK: Lazy> = Lazy::new(Default::default); unsafe fn open_im(xconn: &Arc, locale_modifiers: &CStr) -> Option { let _lock = GLOBAL_LOCK.lock(); diff --git a/src/platform_impl/linux/x11/monitor.rs b/src/platform_impl/linux/x11/monitor.rs index 2bd0ab17fb..555bbd99af 100644 --- a/src/platform_impl/linux/x11/monitor.rs +++ b/src/platform_impl/linux/x11/monitor.rs @@ -14,13 +14,12 @@ use crate::{ monitor::{MonitorHandle as RootMonitorHandle, VideoMode as RootVideoMode}, platform_impl::{MonitorHandle as PlatformMonitorHandle, VideoMode as PlatformVideoMode}, }; +use once_cell::sync::Lazy; // Used for testing. This should always be committed as false. const DISABLE_MONITOR_LIST_CACHING: bool = false; -lazy_static! { - static ref MONITORS: Mutex>> = Mutex::default(); -} +static MONITORS: Lazy>>> = Lazy::new(Mutex::default); pub fn invalidate_cached_monitor_list() -> Option> { // We update this lazily. diff --git a/src/platform_impl/linux/x11/util/atom.rs b/src/platform_impl/linux/x11/util/atom.rs index 4138722483..b861d9e67c 100644 --- a/src/platform_impl/linux/x11/util/atom.rs +++ b/src/platform_impl/linux/x11/util/atom.rs @@ -1,3 +1,5 @@ +use once_cell::sync::Lazy; +use parking_lot::Mutex; use std::{ collections::HashMap, ffi::{CStr, CString}, @@ -5,15 +7,11 @@ use std::{ os::raw::*, }; -use parking_lot::Mutex; - use super::*; type AtomCache = HashMap; -lazy_static! { - static ref ATOM_CACHE: Mutex = Mutex::new(HashMap::with_capacity(2048)); -} +static ATOM_CACHE: Lazy> = Lazy::new(|| Mutex::new(HashMap::with_capacity(2048))); impl XConnection { pub fn get_atom + Debug>(&self, name: T) -> ffi::Atom { diff --git a/src/platform_impl/linux/x11/util/wm.rs b/src/platform_impl/linux/x11/util/wm.rs index 6fef5a3c4d..31441e8456 100644 --- a/src/platform_impl/linux/x11/util/wm.rs +++ b/src/platform_impl/linux/x11/util/wm.rs @@ -1,12 +1,12 @@ use parking_lot::Mutex; use super::*; +use once_cell::sync::Lazy; // This info is global to the window manager. -lazy_static! { - static ref SUPPORTED_HINTS: Mutex> = Mutex::new(Vec::with_capacity(0)); - static ref WM_NAME: Mutex> = Mutex::new(None); -} +static SUPPORTED_HINTS: Lazy>> = + Lazy::new(|| Mutex::new(Vec::with_capacity(0))); +static WM_NAME: Lazy>> = Lazy::new(|| Mutex::new(None)); pub fn hint_is_supported(hint: ffi::Atom) -> bool { (*SUPPORTED_HINTS.lock()).contains(&hint) diff --git a/src/platform_impl/macos/app.rs b/src/platform_impl/macos/app.rs index b5a5582cc3..a4a6ef0b4d 100644 --- a/src/platform_impl/macos/app.rs +++ b/src/platform_impl/macos/app.rs @@ -8,6 +8,7 @@ use objc::{ declare::ClassDecl, runtime::{Class, Object, Sel}, }; +use once_cell::sync::Lazy; use super::{app_state::AppState, event::EventWrapper, util, DEVICE_ID}; use crate::event::{DeviceEvent, ElementState, Event}; @@ -16,19 +17,17 @@ pub struct AppClass(pub *const Class); unsafe impl Send for AppClass {} unsafe impl Sync for AppClass {} -lazy_static! { - pub static ref APP_CLASS: AppClass = unsafe { - let superclass = class!(NSApplication); - let mut decl = ClassDecl::new("WinitApp", superclass).unwrap(); +pub static APP_CLASS: Lazy = Lazy::new(|| unsafe { + let superclass = class!(NSApplication); + let mut decl = ClassDecl::new("WinitApp", superclass).unwrap(); - decl.add_method( - sel!(sendEvent:), - send_event as extern "C" fn(&Object, Sel, id), - ); + decl.add_method( + sel!(sendEvent:), + send_event as extern "C" fn(&Object, Sel, id), + ); - AppClass(decl.register()) - }; -} + AppClass(decl.register()) +}); // Normally, holding Cmd + any key never sends us a `keyUp` event for that key. // Overriding `sendEvent:` like this fixes that. (https://stackoverflow.com/a/15294196) diff --git a/src/platform_impl/macos/app_delegate.rs b/src/platform_impl/macos/app_delegate.rs index 940a5538e6..cf813f4fe2 100644 --- a/src/platform_impl/macos/app_delegate.rs +++ b/src/platform_impl/macos/app_delegate.rs @@ -5,6 +5,7 @@ use objc::{ declare::ClassDecl, runtime::{Class, Object, Sel}, }; +use once_cell::sync::Lazy; use std::{ cell::{RefCell, RefMut}, os::raw::c_void, @@ -21,23 +22,21 @@ pub struct AppDelegateClass(pub *const Class); unsafe impl Send for AppDelegateClass {} unsafe impl Sync for AppDelegateClass {} -lazy_static! { - pub static ref APP_DELEGATE_CLASS: AppDelegateClass = unsafe { - let superclass = class!(NSResponder); - let mut decl = ClassDecl::new("WinitAppDelegate", superclass).unwrap(); +pub static APP_DELEGATE_CLASS: Lazy = Lazy::new(|| unsafe { + let superclass = class!(NSResponder); + let mut decl = ClassDecl::new("WinitAppDelegate", superclass).unwrap(); - decl.add_class_method(sel!(new), new as extern "C" fn(&Class, Sel) -> id); - decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); + decl.add_class_method(sel!(new), new as extern "C" fn(&Class, Sel) -> id); + decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); - decl.add_method( - sel!(applicationDidFinishLaunching:), - did_finish_launching as extern "C" fn(&Object, Sel, id), - ); - decl.add_ivar::<*mut c_void>(AUX_DELEGATE_STATE_NAME); + decl.add_method( + sel!(applicationDidFinishLaunching:), + did_finish_launching as extern "C" fn(&Object, Sel, id), + ); + decl.add_ivar::<*mut c_void>(AUX_DELEGATE_STATE_NAME); - AppDelegateClass(decl.register()) - }; -} + AppDelegateClass(decl.register()) +}); /// Safety: Assumes that Object is an instance of APP_DELEGATE_CLASS pub unsafe fn get_aux_state_mut(this: &Object) -> RefMut<'_, AuxDelegateState> { diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 7b392a4124..2d7905244f 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -12,16 +12,6 @@ use std::{ time::Instant, }; -use cocoa::{ - appkit::{NSApp, NSApplication, NSWindow}, - base::{id, nil}, - foundation::NSSize, -}; -use objc::{ - rc::autoreleasepool, - runtime::{Object, BOOL, NO, YES}, -}; - use crate::{ dpi::LogicalSize, event::{Event, StartCause, WindowEvent}, @@ -40,10 +30,18 @@ use crate::{ }, window::WindowId, }; +use cocoa::{ + appkit::{NSApp, NSApplication, NSWindow}, + base::{id, nil}, + foundation::NSSize, +}; +use objc::{ + rc::autoreleasepool, + runtime::{Object, BOOL, NO, YES}, +}; +use once_cell::sync::Lazy; -lazy_static! { - static ref HANDLER: Handler = Default::default(); -} +static HANDLER: Lazy = Lazy::new(Default::default); impl<'a, Never> Event<'a, Never> { fn userify(self) -> Event<'a, T> { diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 302282119b..93cc19b723 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -1,3 +1,13 @@ +use cocoa::{ + appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow}, + base::{id, nil}, + foundation::{NSInteger, NSPoint, NSRect, NSSize, NSString, NSUInteger}, +}; +use objc::{ + declare::ClassDecl, + runtime::{Class, Object, Protocol, Sel, BOOL, NO, YES}, +}; +use once_cell::sync::Lazy; use std::{ boxed::Box, collections::VecDeque, @@ -9,16 +19,6 @@ use std::{ }, }; -use cocoa::{ - appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow}, - base::{id, nil}, - foundation::{NSInteger, NSPoint, NSRect, NSSize, NSString, NSUInteger}, -}; -use objc::{ - declare::ClassDecl, - runtime::{Class, Object, Protocol, Sel, BOOL, NO, YES}, -}; - use crate::{ dpi::{LogicalPosition, LogicalSize}, event::{ @@ -155,173 +155,171 @@ struct ViewClass(*const Class); unsafe impl Send for ViewClass {} unsafe impl Sync for ViewClass {} -lazy_static! { - static ref VIEW_CLASS: ViewClass = unsafe { - let superclass = class!(NSView); - let mut decl = ClassDecl::new("WinitView", superclass).unwrap(); - decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); - decl.add_method( - sel!(initWithWinit:), - init_with_winit as extern "C" fn(&Object, Sel, *mut c_void) -> id, - ); - decl.add_method( - sel!(viewDidMoveToWindow), - view_did_move_to_window as extern "C" fn(&Object, Sel), - ); - decl.add_method( - sel!(drawRect:), - draw_rect as extern "C" fn(&Object, Sel, NSRect), - ); - decl.add_method( - sel!(acceptsFirstResponder), - accepts_first_responder as extern "C" fn(&Object, Sel) -> BOOL, - ); - decl.add_method( - sel!(touchBar), - touch_bar as extern "C" fn(&Object, Sel) -> BOOL, - ); - decl.add_method( - sel!(resetCursorRects), - reset_cursor_rects as extern "C" fn(&Object, Sel), - ); - - // ------------------------------------------------------------------ - // NSTextInputClient - decl.add_method( - sel!(hasMarkedText), - has_marked_text as extern "C" fn(&Object, Sel) -> BOOL, - ); - decl.add_method( - sel!(markedRange), - marked_range as extern "C" fn(&Object, Sel) -> NSRange, - ); - decl.add_method( - sel!(selectedRange), - selected_range as extern "C" fn(&Object, Sel) -> NSRange, - ); - decl.add_method( - sel!(setMarkedText:selectedRange:replacementRange:), - set_marked_text as extern "C" fn(&mut Object, Sel, id, NSRange, NSRange), - ); - decl.add_method(sel!(unmarkText), unmark_text as extern "C" fn(&Object, Sel)); - decl.add_method( - sel!(validAttributesForMarkedText), - valid_attributes_for_marked_text as extern "C" fn(&Object, Sel) -> id, - ); - decl.add_method( - sel!(attributedSubstringForProposedRange:actualRange:), - attributed_substring_for_proposed_range - as extern "C" fn(&Object, Sel, NSRange, *mut c_void) -> id, - ); - decl.add_method( - sel!(insertText:replacementRange:), - insert_text as extern "C" fn(&Object, Sel, id, NSRange), - ); - decl.add_method( - sel!(characterIndexForPoint:), - character_index_for_point as extern "C" fn(&Object, Sel, NSPoint) -> NSUInteger, - ); - decl.add_method( - sel!(firstRectForCharacterRange:actualRange:), - first_rect_for_character_range - as extern "C" fn(&Object, Sel, NSRange, *mut c_void) -> NSRect, - ); - decl.add_method( - sel!(doCommandBySelector:), - do_command_by_selector as extern "C" fn(&Object, Sel, Sel), - ); - // ------------------------------------------------------------------ - - decl.add_method(sel!(keyDown:), key_down as extern "C" fn(&Object, Sel, id)); - decl.add_method(sel!(keyUp:), key_up as extern "C" fn(&Object, Sel, id)); - decl.add_method( - sel!(flagsChanged:), - flags_changed as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(insertTab:), - insert_tab as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(insertBackTab:), - insert_back_tab as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(mouseDown:), - mouse_down as extern "C" fn(&Object, Sel, id), - ); - decl.add_method(sel!(mouseUp:), mouse_up as extern "C" fn(&Object, Sel, id)); - decl.add_method( - sel!(rightMouseDown:), - right_mouse_down as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(rightMouseUp:), - right_mouse_up as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(otherMouseDown:), - other_mouse_down as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(otherMouseUp:), - other_mouse_up as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(mouseMoved:), - mouse_moved as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(mouseDragged:), - mouse_dragged as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(rightMouseDragged:), - right_mouse_dragged as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(otherMouseDragged:), - other_mouse_dragged as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(mouseEntered:), - mouse_entered as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(mouseExited:), - mouse_exited as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(scrollWheel:), - scroll_wheel as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(pressureChangeWithEvent:), - pressure_change_with_event as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(_wantsKeyDownForEvent:), - wants_key_down_for_event as extern "C" fn(&Object, Sel, id) -> BOOL, - ); - decl.add_method( - sel!(cancelOperation:), - cancel_operation as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(frameDidChange:), - frame_did_change as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(acceptsFirstMouse:), - accepts_first_mouse as extern "C" fn(&Object, Sel, id) -> BOOL, - ); - decl.add_ivar::<*mut c_void>("winitState"); - decl.add_ivar::("markedText"); - let protocol = Protocol::get("NSTextInputClient").unwrap(); - decl.add_protocol(protocol); - ViewClass(decl.register()) - }; -} +static VIEW_CLASS: Lazy = Lazy::new(|| unsafe { + let superclass = class!(NSView); + let mut decl = ClassDecl::new("WinitView", superclass).unwrap(); + decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); + decl.add_method( + sel!(initWithWinit:), + init_with_winit as extern "C" fn(&Object, Sel, *mut c_void) -> id, + ); + decl.add_method( + sel!(viewDidMoveToWindow), + view_did_move_to_window as extern "C" fn(&Object, Sel), + ); + decl.add_method( + sel!(drawRect:), + draw_rect as extern "C" fn(&Object, Sel, NSRect), + ); + decl.add_method( + sel!(acceptsFirstResponder), + accepts_first_responder as extern "C" fn(&Object, Sel) -> BOOL, + ); + decl.add_method( + sel!(touchBar), + touch_bar as extern "C" fn(&Object, Sel) -> BOOL, + ); + decl.add_method( + sel!(resetCursorRects), + reset_cursor_rects as extern "C" fn(&Object, Sel), + ); + + // ------------------------------------------------------------------ + // NSTextInputClient + decl.add_method( + sel!(hasMarkedText), + has_marked_text as extern "C" fn(&Object, Sel) -> BOOL, + ); + decl.add_method( + sel!(markedRange), + marked_range as extern "C" fn(&Object, Sel) -> NSRange, + ); + decl.add_method( + sel!(selectedRange), + selected_range as extern "C" fn(&Object, Sel) -> NSRange, + ); + decl.add_method( + sel!(setMarkedText:selectedRange:replacementRange:), + set_marked_text as extern "C" fn(&mut Object, Sel, id, NSRange, NSRange), + ); + decl.add_method(sel!(unmarkText), unmark_text as extern "C" fn(&Object, Sel)); + decl.add_method( + sel!(validAttributesForMarkedText), + valid_attributes_for_marked_text as extern "C" fn(&Object, Sel) -> id, + ); + decl.add_method( + sel!(attributedSubstringForProposedRange:actualRange:), + attributed_substring_for_proposed_range + as extern "C" fn(&Object, Sel, NSRange, *mut c_void) -> id, + ); + decl.add_method( + sel!(insertText:replacementRange:), + insert_text as extern "C" fn(&Object, Sel, id, NSRange), + ); + decl.add_method( + sel!(characterIndexForPoint:), + character_index_for_point as extern "C" fn(&Object, Sel, NSPoint) -> NSUInteger, + ); + decl.add_method( + sel!(firstRectForCharacterRange:actualRange:), + first_rect_for_character_range + as extern "C" fn(&Object, Sel, NSRange, *mut c_void) -> NSRect, + ); + decl.add_method( + sel!(doCommandBySelector:), + do_command_by_selector as extern "C" fn(&Object, Sel, Sel), + ); + // ------------------------------------------------------------------ + + decl.add_method(sel!(keyDown:), key_down as extern "C" fn(&Object, Sel, id)); + decl.add_method(sel!(keyUp:), key_up as extern "C" fn(&Object, Sel, id)); + decl.add_method( + sel!(flagsChanged:), + flags_changed as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(insertTab:), + insert_tab as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(insertBackTab:), + insert_back_tab as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(mouseDown:), + mouse_down as extern "C" fn(&Object, Sel, id), + ); + decl.add_method(sel!(mouseUp:), mouse_up as extern "C" fn(&Object, Sel, id)); + decl.add_method( + sel!(rightMouseDown:), + right_mouse_down as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(rightMouseUp:), + right_mouse_up as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(otherMouseDown:), + other_mouse_down as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(otherMouseUp:), + other_mouse_up as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(mouseMoved:), + mouse_moved as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(mouseDragged:), + mouse_dragged as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(rightMouseDragged:), + right_mouse_dragged as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(otherMouseDragged:), + other_mouse_dragged as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(mouseEntered:), + mouse_entered as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(mouseExited:), + mouse_exited as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(scrollWheel:), + scroll_wheel as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(pressureChangeWithEvent:), + pressure_change_with_event as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(_wantsKeyDownForEvent:), + wants_key_down_for_event as extern "C" fn(&Object, Sel, id) -> BOOL, + ); + decl.add_method( + sel!(cancelOperation:), + cancel_operation as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(frameDidChange:), + frame_did_change as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(acceptsFirstMouse:), + accepts_first_mouse as extern "C" fn(&Object, Sel, id) -> BOOL, + ); + decl.add_ivar::<*mut c_void>("winitState"); + decl.add_ivar::("markedText"); + let protocol = Protocol::get("NSTextInputClient").unwrap(); + decl.add_protocol(protocol); + ViewClass(decl.register()) +}); extern "C" fn dealloc(this: &Object, _sel: Sel) { unsafe { diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index d4856cb91b..d9033ab355 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -1,15 +1,3 @@ -use raw_window_handle::{AppKitHandle, RawWindowHandle}; -use std::{ - collections::VecDeque, - convert::TryInto, - f64, ops, - os::raw::c_void, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, MutexGuard, Weak, - }, -}; - use crate::{ dpi::{ LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical, @@ -47,6 +35,18 @@ use objc::{ rc::autoreleasepool, runtime::{Class, Object, Sel, BOOL, NO, YES}, }; +use once_cell::sync::Lazy; +use raw_window_handle::{AppKitHandle, RawWindowHandle}; +use std::{ + collections::VecDeque, + convert::TryInto, + f64, ops, + os::raw::c_void, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Mutex, MutexGuard, Weak, + }, +}; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(pub usize); @@ -247,32 +247,30 @@ struct WindowClass(*const Class); unsafe impl Send for WindowClass {} unsafe impl Sync for WindowClass {} -lazy_static! { - static ref WINDOW_CLASS: WindowClass = unsafe { - let window_superclass = class!(NSWindow); - let mut decl = ClassDecl::new("WinitWindow", window_superclass).unwrap(); +static WINDOW_CLASS: Lazy = Lazy::new(|| unsafe { + let window_superclass = class!(NSWindow); + let mut decl = ClassDecl::new("WinitWindow", window_superclass).unwrap(); - pub extern "C" fn can_become_main_window(_: &Object, _: Sel) -> BOOL { - trace_scope!("canBecomeMainWindow"); - YES - } + pub extern "C" fn can_become_main_window(_: &Object, _: Sel) -> BOOL { + trace_scope!("canBecomeMainWindow"); + YES + } - pub extern "C" fn can_become_key_window(_: &Object, _: Sel) -> BOOL { - trace_scope!("canBecomeKeyWindow"); - YES - } + pub extern "C" fn can_become_key_window(_: &Object, _: Sel) -> BOOL { + trace_scope!("canBecomeKeyWindow"); + YES + } - decl.add_method( - sel!(canBecomeMainWindow), - can_become_main_window as extern "C" fn(&Object, Sel) -> BOOL, - ); - decl.add_method( - sel!(canBecomeKeyWindow), - can_become_key_window as extern "C" fn(&Object, Sel) -> BOOL, - ); - WindowClass(decl.register()) - }; -} + decl.add_method( + sel!(canBecomeMainWindow), + can_become_main_window as extern "C" fn(&Object, Sel) -> BOOL, + ); + decl.add_method( + sel!(canBecomeKeyWindow), + can_become_key_window as extern "C" fn(&Object, Sel) -> BOOL, + ); + WindowClass(decl.register()) +}); #[derive(Default)] pub struct SharedState { diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 01a8c5fa8c..79b3308d90 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -1,9 +1,3 @@ -use std::{ - f64, - os::raw::c_void, - sync::{atomic::Ordering, Arc, Weak}, -}; - use cocoa::{ appkit::{self, NSApplicationPresentationOptions, NSView, NSWindow}, base::{id, nil}, @@ -14,6 +8,12 @@ use objc::{ rc::autoreleasepool, runtime::{Class, Object, Sel, BOOL, NO, YES}, }; +use once_cell::sync::Lazy; +use std::{ + f64, + os::raw::c_void, + sync::{atomic::Ordering, Arc, Weak}, +}; use crate::{ dpi::{LogicalPosition, LogicalSize}, @@ -135,97 +135,95 @@ struct WindowDelegateClass(*const Class); unsafe impl Send for WindowDelegateClass {} unsafe impl Sync for WindowDelegateClass {} -lazy_static! { - static ref WINDOW_DELEGATE_CLASS: WindowDelegateClass = unsafe { - let superclass = class!(NSResponder); - let mut decl = ClassDecl::new("WinitWindowDelegate", superclass).unwrap(); - - decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); - decl.add_method( - sel!(initWithWinit:), - init_with_winit as extern "C" fn(&Object, Sel, *mut c_void) -> id, - ); - - decl.add_method( - sel!(windowShouldClose:), - window_should_close as extern "C" fn(&Object, Sel, id) -> BOOL, - ); - decl.add_method( - sel!(windowWillClose:), - window_will_close as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidResize:), - window_did_resize as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidMove:), - window_did_move as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidChangeBackingProperties:), - window_did_change_backing_properties as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidBecomeKey:), - window_did_become_key as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidResignKey:), - window_did_resign_key as extern "C" fn(&Object, Sel, id), - ); - - decl.add_method( - sel!(draggingEntered:), - dragging_entered as extern "C" fn(&Object, Sel, id) -> BOOL, - ); - decl.add_method( - sel!(prepareForDragOperation:), - prepare_for_drag_operation as extern "C" fn(&Object, Sel, id) -> BOOL, - ); - decl.add_method( - sel!(performDragOperation:), - perform_drag_operation as extern "C" fn(&Object, Sel, id) -> BOOL, - ); - decl.add_method( - sel!(concludeDragOperation:), - conclude_drag_operation as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(draggingExited:), - dragging_exited as extern "C" fn(&Object, Sel, id), - ); - - decl.add_method( - sel!(window:willUseFullScreenPresentationOptions:), - window_will_use_fullscreen_presentation_options - as extern "C" fn(&Object, Sel, id, NSUInteger) -> NSUInteger, - ); - decl.add_method( - sel!(windowDidEnterFullScreen:), - window_did_enter_fullscreen as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowWillEnterFullScreen:), - window_will_enter_fullscreen as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidExitFullScreen:), - window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowWillExitFullScreen:), - window_will_exit_fullscreen as extern "C" fn(&Object, Sel, id), - ); - decl.add_method( - sel!(windowDidFailToEnterFullScreen:), - window_did_fail_to_enter_fullscreen as extern "C" fn(&Object, Sel, id), - ); - - decl.add_ivar::<*mut c_void>("winitState"); - WindowDelegateClass(decl.register()) - }; -} +static WINDOW_DELEGATE_CLASS: Lazy = Lazy::new(|| unsafe { + let superclass = class!(NSResponder); + let mut decl = ClassDecl::new("WinitWindowDelegate", superclass).unwrap(); + + decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); + decl.add_method( + sel!(initWithWinit:), + init_with_winit as extern "C" fn(&Object, Sel, *mut c_void) -> id, + ); + + decl.add_method( + sel!(windowShouldClose:), + window_should_close as extern "C" fn(&Object, Sel, id) -> BOOL, + ); + decl.add_method( + sel!(windowWillClose:), + window_will_close as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidResize:), + window_did_resize as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidMove:), + window_did_move as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidChangeBackingProperties:), + window_did_change_backing_properties as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidBecomeKey:), + window_did_become_key as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidResignKey:), + window_did_resign_key as extern "C" fn(&Object, Sel, id), + ); + + decl.add_method( + sel!(draggingEntered:), + dragging_entered as extern "C" fn(&Object, Sel, id) -> BOOL, + ); + decl.add_method( + sel!(prepareForDragOperation:), + prepare_for_drag_operation as extern "C" fn(&Object, Sel, id) -> BOOL, + ); + decl.add_method( + sel!(performDragOperation:), + perform_drag_operation as extern "C" fn(&Object, Sel, id) -> BOOL, + ); + decl.add_method( + sel!(concludeDragOperation:), + conclude_drag_operation as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(draggingExited:), + dragging_exited as extern "C" fn(&Object, Sel, id), + ); + + decl.add_method( + sel!(window:willUseFullScreenPresentationOptions:), + window_will_use_fullscreen_presentation_options + as extern "C" fn(&Object, Sel, id, NSUInteger) -> NSUInteger, + ); + decl.add_method( + sel!(windowDidEnterFullScreen:), + window_did_enter_fullscreen as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowWillEnterFullScreen:), + window_will_enter_fullscreen as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidExitFullScreen:), + window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowWillExitFullScreen:), + window_will_exit_fullscreen as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidFailToEnterFullScreen:), + window_did_fail_to_enter_fullscreen as extern "C" fn(&Object, Sel, id), + ); + + decl.add_ivar::<*mut c_void>("winitState"); + WindowDelegateClass(decl.register()) +}); // This function is definitely unsafe, but labeling that would increase // boilerplate and wouldn't really clarify anything... diff --git a/src/platform_impl/windows/dark_mode.rs b/src/platform_impl/windows/dark_mode.rs index 8e1deac3ae..6480379dfc 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -1,7 +1,7 @@ +use once_cell::sync::Lazy; /// This is a simple implementation of support for Windows Dark Mode, /// which is inspired by the solution in https://github.com/ysc3839/win32-darkmode use std::{ffi::c_void, ptr}; - use windows_sys::{ core::PCSTR, Win32::{ @@ -22,47 +22,45 @@ use crate::window::Theme; use super::util; -lazy_static! { - static ref WIN10_BUILD_VERSION: Option = { - type RtlGetVersion = unsafe extern "system" fn (*mut OSVERSIONINFOW) -> NTSTATUS; - let handle = get_function!("ntdll.dll", RtlGetVersion); - - if let Some(rtl_get_version) = handle { - unsafe { - let mut vi = OSVERSIONINFOW { - dwOSVersionInfoSize: 0, - dwMajorVersion: 0, - dwMinorVersion: 0, - dwBuildNumber: 0, - dwPlatformId: 0, - szCSDVersion: [0; 128], - }; - - let status = (rtl_get_version)(&mut vi); - - if status >= 0 && vi.dwMajorVersion == 10 && vi.dwMinorVersion == 0 { - Some(vi.dwBuildNumber) - } else { - None - } - } - } else { - None - } - }; +static WIN10_BUILD_VERSION: Lazy> = Lazy::new(|| { + type RtlGetVersion = unsafe extern "system" fn(*mut OSVERSIONINFOW) -> NTSTATUS; + let handle = get_function!("ntdll.dll", RtlGetVersion); - static ref DARK_MODE_SUPPORTED: bool = { - // We won't try to do anything for windows versions < 17763 - // (Windows 10 October 2018 update) - match *WIN10_BUILD_VERSION { - Some(v) => v >= 17763, - None => false + if let Some(rtl_get_version) = handle { + unsafe { + let mut vi = OSVERSIONINFOW { + dwOSVersionInfoSize: 0, + dwMajorVersion: 0, + dwMinorVersion: 0, + dwBuildNumber: 0, + dwPlatformId: 0, + szCSDVersion: [0; 128], + }; + + let status = (rtl_get_version)(&mut vi); + + if status >= 0 && vi.dwMajorVersion == 10 && vi.dwMinorVersion == 0 { + Some(vi.dwBuildNumber) + } else { + None + } } - }; + } else { + None + } +}); + +static DARK_MODE_SUPPORTED: Lazy = Lazy::new(|| { + // We won't try to do anything for windows versions < 17763 + // (Windows 10 October 2018 update) + match *WIN10_BUILD_VERSION { + Some(v) => v >= 17763, + None => false, + } +}); - static ref DARK_THEME_NAME: Vec = util::encode_wide("DarkMode_Explorer"); - static ref LIGHT_THEME_NAME: Vec = util::encode_wide(""); -} +static DARK_THEME_NAME: Lazy> = Lazy::new(|| util::encode_wide("DarkMode_Explorer")); +static LIGHT_THEME_NAME: Lazy> = Lazy::new(|| util::encode_wide("")); /// Attempt to set a theme on a window, if necessary. /// Returns the theme that was picked @@ -113,10 +111,8 @@ fn set_dark_mode_for_window(hwnd: HWND, is_dark_mode: bool) -> bool { cbData: usize, } - lazy_static! { - static ref SET_WINDOW_COMPOSITION_ATTRIBUTE: Option = - get_function!("user32.dll", SetWindowCompositionAttribute); - } + static SET_WINDOW_COMPOSITION_ATTRIBUTE: Lazy> = + Lazy::new(|| get_function!("user32.dll", SetWindowCompositionAttribute)); if let Some(set_window_composition_attribute) = *SET_WINDOW_COMPOSITION_ATTRIBUTE { unsafe { @@ -144,23 +140,19 @@ fn should_use_dark_mode() -> bool { fn should_apps_use_dark_mode() -> bool { type ShouldAppsUseDarkMode = unsafe extern "system" fn() -> bool; - lazy_static! { - static ref SHOULD_APPS_USE_DARK_MODE: Option = { - unsafe { - const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: PCSTR = 132 as PCSTR; + static SHOULD_APPS_USE_DARK_MODE: Lazy> = Lazy::new(|| unsafe { + const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: PCSTR = 132 as PCSTR; - let module = LoadLibraryA("uxtheme.dll\0".as_ptr()); + let module = LoadLibraryA("uxtheme.dll\0".as_ptr()); - if module == 0 { - return None; - } + if module == 0 { + return None; + } - let handle = GetProcAddress(module, UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL); + let handle = GetProcAddress(module, UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL); - handle.map(|handle| std::mem::transmute(handle)) - } - }; - } + handle.map(|handle| std::mem::transmute(handle)) + }); SHOULD_APPS_USE_DARK_MODE .map(|should_apps_use_dark_mode| unsafe { (should_apps_use_dark_mode)() }) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index b3e9826649..b23f320346 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -2,6 +2,7 @@ mod runner; +use once_cell::sync::Lazy; use parking_lot::Mutex; use std::{ cell::Cell, @@ -112,18 +113,17 @@ type GetPointerTouchInfo = type GetPointerPenInfo = unsafe extern "system" fn(pointId: u32, penInfo: *mut POINTER_PEN_INFO) -> BOOL; -lazy_static! { - static ref GET_POINTER_FRAME_INFO_HISTORY: Option = - get_function!("user32.dll", GetPointerFrameInfoHistory); - static ref SKIP_POINTER_FRAME_MESSAGES: Option = - get_function!("user32.dll", SkipPointerFrameMessages); - static ref GET_POINTER_DEVICE_RECTS: Option = - get_function!("user32.dll", GetPointerDeviceRects); - static ref GET_POINTER_TOUCH_INFO: Option = - get_function!("user32.dll", GetPointerTouchInfo); - static ref GET_POINTER_PEN_INFO: Option = - get_function!("user32.dll", GetPointerPenInfo); -} +static GET_POINTER_FRAME_INFO_HISTORY: Lazy> = + Lazy::new(|| get_function!("user32.dll", GetPointerFrameInfoHistory)); +static SKIP_POINTER_FRAME_MESSAGES: Lazy> = + Lazy::new(|| get_function!("user32.dll", SkipPointerFrameMessages)); +static GET_POINTER_DEVICE_RECTS: Lazy> = + Lazy::new(|| get_function!("user32.dll", GetPointerDeviceRects)); +static GET_POINTER_TOUCH_INFO: Lazy> = + Lazy::new(|| get_function!("user32.dll", GetPointerTouchInfo)); +static GET_POINTER_PEN_INFO: Lazy> = + Lazy::new(|| get_function!("user32.dll", GetPointerPenInfo)); + pub(crate) struct WindowData { pub window_state: Arc>, pub event_loop_runner: EventLoopRunnerShared, @@ -375,19 +375,17 @@ fn get_wait_thread_id() -> u32 { } } -lazy_static! { - static ref WAIT_PERIOD_MIN: Option = unsafe { - let mut caps = TIMECAPS { - wPeriodMin: 0, - wPeriodMax: 0, - }; - if timeGetDevCaps(&mut caps, mem::size_of::() as u32) == TIMERR_NOERROR { - Some(caps.wPeriodMin) - } else { - None - } +static WAIT_PERIOD_MIN: Lazy> = Lazy::new(|| unsafe { + let mut caps = TIMECAPS { + wPeriodMin: 0, + wPeriodMax: 0, }; -} + if timeGetDevCaps(&mut caps, mem::size_of::() as u32) == TIMERR_NOERROR { + Some(caps.wPeriodMin) + } else { + None + } +}); fn wait_thread(parent_thread_id: u32, msg_window_id: HWND) { unsafe { @@ -582,59 +580,36 @@ impl EventLoopProxy { type WaitUntilInstantBox = Box; -lazy_static! { - // Message sent by the `EventLoopProxy` when we want to wake up the thread. - // WPARAM and LPARAM are unused. - static ref USER_EVENT_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::WakeupMsg\0".as_ptr()) - } - }; - // Message sent when we want to execute a closure in the thread. - // WPARAM contains a Box> that must be retrieved with `Box::from_raw`, - // and LPARAM is unused. - static ref EXEC_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::ExecMsg\0".as_ptr()) - } - }; - static ref PROCESS_NEW_EVENTS_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::ProcessNewEvents\0".as_ptr()) - } - }; - /// lparam is the wait thread's message id. - static ref SEND_WAIT_THREAD_ID_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::SendWaitThreadId\0".as_ptr()) - } - }; - /// lparam points to a `Box` signifying the time `PROCESS_NEW_EVENTS_MSG_ID` should - /// be sent. - static ref WAIT_UNTIL_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::WaitUntil\0".as_ptr()) - } - }; - static ref CANCEL_WAIT_UNTIL_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::CancelWaitUntil\0".as_ptr()) - } - }; - // Message sent by a `Window` when it wants to be destroyed by the main thread. - // WPARAM and LPARAM are unused. - pub static ref DESTROY_MSG_ID: u32 = { - unsafe { - RegisterWindowMessageA("Winit::DestroyMsg\0".as_ptr()) - } - }; - // WPARAM is a bool specifying the `WindowFlags::MARKER_RETAIN_STATE_ON_SIZE` flag. See the - // documentation in the `window_state` module for more information. - pub static ref SET_RETAIN_STATE_ON_SIZE_MSG_ID: u32 = unsafe { - RegisterWindowMessageA("Winit::SetRetainMaximized\0".as_ptr()) - }; - static ref THREAD_EVENT_TARGET_WINDOW_CLASS: Vec = util::encode_wide("Winit Thread Event Target"); -} +// Message sent by the `EventLoopProxy` when we want to wake up the thread. +// WPARAM and LPARAM are unused. +static USER_EVENT_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::WakeupMsg\0".as_ptr()) }); +// Message sent when we want to execute a closure in the thread. +// WPARAM contains a Box> that must be retrieved with `Box::from_raw`, +// and LPARAM is unused. +static EXEC_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::ExecMsg\0".as_ptr()) }); +static PROCESS_NEW_EVENTS_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::ProcessNewEvents\0".as_ptr()) }); +/// lparam is the wait thread's message id. +static SEND_WAIT_THREAD_ID_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::SendWaitThreadId\0".as_ptr()) }); +/// lparam points to a `Box` signifying the time `PROCESS_NEW_EVENTS_MSG_ID` should +/// be sent. +static WAIT_UNTIL_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::WaitUntil\0".as_ptr()) }); +static CANCEL_WAIT_UNTIL_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::CancelWaitUntil\0".as_ptr()) }); +// Message sent by a `Window` when it wants to be destroyed by the main thread. +// WPARAM and LPARAM are unused. +pub static DESTROY_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::DestroyMsg\0".as_ptr()) }); +// WPARAM is a bool specifying the `WindowFlags::MARKER_RETAIN_STATE_ON_SIZE` flag. See the +// documentation in the `window_state` module for more information. +pub static SET_RETAIN_STATE_ON_SIZE_MSG_ID: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::SetRetainMaximized\0".as_ptr()) }); +static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy> = + Lazy::new(|| util::encode_wide("Winit Thread Event Target")); fn create_event_target_window() -> HWND { unsafe { diff --git a/src/platform_impl/windows/util.rs b/src/platform_impl/windows/util.rs index a327701ffa..fd74b674f6 100644 --- a/src/platform_impl/windows/util.rs +++ b/src/platform_impl/windows/util.rs @@ -9,6 +9,7 @@ use std::{ sync::atomic::{AtomicBool, Ordering}, }; +use once_cell::sync::Lazy; use windows_sys::{ core::{HRESULT, PCWSTR}, Win32::{ @@ -298,19 +299,17 @@ pub type AdjustWindowRectExForDpi = unsafe extern "system" fn( dpi: u32, ) -> BOOL; -lazy_static! { - pub static ref GET_DPI_FOR_WINDOW: Option = - get_function!("user32.dll", GetDpiForWindow); - pub static ref ADJUST_WINDOW_RECT_EX_FOR_DPI: Option = - get_function!("user32.dll", AdjustWindowRectExForDpi); - pub static ref GET_DPI_FOR_MONITOR: Option = - get_function!("shcore.dll", GetDpiForMonitor); - pub static ref ENABLE_NON_CLIENT_DPI_SCALING: Option = - get_function!("user32.dll", EnableNonClientDpiScaling); - pub static ref SET_PROCESS_DPI_AWARENESS_CONTEXT: Option = - get_function!("user32.dll", SetProcessDpiAwarenessContext); - pub static ref SET_PROCESS_DPI_AWARENESS: Option = - get_function!("shcore.dll", SetProcessDpiAwareness); - pub static ref SET_PROCESS_DPI_AWARE: Option = - get_function!("user32.dll", SetProcessDPIAware); -} +pub static GET_DPI_FOR_WINDOW: Lazy> = + Lazy::new(|| get_function!("user32.dll", GetDpiForWindow)); +pub static ADJUST_WINDOW_RECT_EX_FOR_DPI: Lazy> = + Lazy::new(|| get_function!("user32.dll", AdjustWindowRectExForDpi)); +pub static GET_DPI_FOR_MONITOR: Lazy> = + Lazy::new(|| get_function!("shcore.dll", GetDpiForMonitor)); +pub static ENABLE_NON_CLIENT_DPI_SCALING: Lazy> = + Lazy::new(|| get_function!("user32.dll", EnableNonClientDpiScaling)); +pub static SET_PROCESS_DPI_AWARENESS_CONTEXT: Lazy> = + Lazy::new(|| get_function!("user32.dll", SetProcessDpiAwarenessContext)); +pub static SET_PROCESS_DPI_AWARENESS: Lazy> = + Lazy::new(|| get_function!("shcore.dll", SetProcessDpiAwareness)); +pub static SET_PROCESS_DPI_AWARE: Lazy> = + Lazy::new(|| get_function!("user32.dll", SetProcessDPIAware)); From 32cbcfc9421283605a2128e8f1c312483c6aee12 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 8 Jun 2022 04:08:27 -0700 Subject: [PATCH 2/6] Revert some of the unintentional cargo fmt --all moves --- src/platform_impl/linux/mod.rs | 4 ++-- .../linux/x11/ime/input_method.rs | 5 +++-- src/platform_impl/linux/x11/monitor.rs | 2 +- src/platform_impl/linux/x11/util/wm.rs | 2 +- src/platform_impl/macos/app_state.rs | 19 +++++++++-------- src/platform_impl/macos/view.rs | 21 ++++++++++--------- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index a07f6d198f..26647e57f4 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -14,8 +14,6 @@ use crate::window::Theme; #[cfg(feature = "wayland")] use std::error::Error; -#[cfg(feature = "x11")] -use once_cell::sync::Lazy; use std::{collections::VecDeque, env, fmt}; #[cfg(feature = "x11")] use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Arc}; @@ -23,6 +21,8 @@ use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Arc}; #[cfg(feature = "x11")] use parking_lot::Mutex; use raw_window_handle::RawWindowHandle; +#[cfg(feature = "x11")] +use once_cell::sync::Lazy; #[cfg(feature = "x11")] pub use self::x11::XNotSupported; diff --git a/src/platform_impl/linux/x11/ime/input_method.rs b/src/platform_impl/linux/x11/ime/input_method.rs index f71d523487..5a1695cb0e 100644 --- a/src/platform_impl/linux/x11/ime/input_method.rs +++ b/src/platform_impl/linux/x11/ime/input_method.rs @@ -1,5 +1,3 @@ -use once_cell::sync::Lazy; -use parking_lot::Mutex; use std::{ env, ffi::{CStr, CString, IntoStringError}, @@ -9,6 +7,9 @@ use std::{ sync::Arc, }; +use once_cell::sync::Lazy; +use parking_lot::Mutex; + use super::{ffi, util, XConnection, XError}; static GLOBAL_LOCK: Lazy> = Lazy::new(Default::default); diff --git a/src/platform_impl/linux/x11/monitor.rs b/src/platform_impl/linux/x11/monitor.rs index 555bbd99af..7d03ab2b6e 100644 --- a/src/platform_impl/linux/x11/monitor.rs +++ b/src/platform_impl/linux/x11/monitor.rs @@ -1,6 +1,7 @@ use std::os::raw::*; use parking_lot::Mutex; +use once_cell::sync::Lazy; use super::{ ffi::{ @@ -14,7 +15,6 @@ use crate::{ monitor::{MonitorHandle as RootMonitorHandle, VideoMode as RootVideoMode}, platform_impl::{MonitorHandle as PlatformMonitorHandle, VideoMode as PlatformVideoMode}, }; -use once_cell::sync::Lazy; // Used for testing. This should always be committed as false. const DISABLE_MONITOR_LIST_CACHING: bool = false; diff --git a/src/platform_impl/linux/x11/util/wm.rs b/src/platform_impl/linux/x11/util/wm.rs index 31441e8456..89ba25814a 100644 --- a/src/platform_impl/linux/x11/util/wm.rs +++ b/src/platform_impl/linux/x11/util/wm.rs @@ -1,7 +1,7 @@ use parking_lot::Mutex; +use once_cell::sync::Lazy; use super::*; -use once_cell::sync::Lazy; // This info is global to the window manager. static SUPPORTED_HINTS: Lazy>> = diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 2d7905244f..d9aa449c3b 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -12,6 +12,16 @@ use std::{ time::Instant, }; +use cocoa::{ + appkit::{NSApp, NSApplication, NSWindow}, + base::{id, nil}, + foundation::NSSize, +}; +use objc::{ + rc::autoreleasepool, + runtime::{Object, BOOL, NO, YES}, +}; + use crate::{ dpi::LogicalSize, event::{Event, StartCause, WindowEvent}, @@ -30,15 +40,6 @@ use crate::{ }, window::WindowId, }; -use cocoa::{ - appkit::{NSApp, NSApplication, NSWindow}, - base::{id, nil}, - foundation::NSSize, -}; -use objc::{ - rc::autoreleasepool, - runtime::{Object, BOOL, NO, YES}, -}; use once_cell::sync::Lazy; static HANDLER: Lazy = Lazy::new(Default::default); diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 93cc19b723..94e3c73863 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -1,13 +1,3 @@ -use cocoa::{ - appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow}, - base::{id, nil}, - foundation::{NSInteger, NSPoint, NSRect, NSSize, NSString, NSUInteger}, -}; -use objc::{ - declare::ClassDecl, - runtime::{Class, Object, Protocol, Sel, BOOL, NO, YES}, -}; -use once_cell::sync::Lazy; use std::{ boxed::Box, collections::VecDeque, @@ -19,6 +9,17 @@ use std::{ }, }; +use cocoa::{ + appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow}, + base::{id, nil}, + foundation::{NSInteger, NSPoint, NSRect, NSSize, NSString, NSUInteger}, +}; +use objc::{ + declare::ClassDecl, + runtime::{Class, Object, Protocol, Sel, BOOL, NO, YES}, +}; +use once_cell::sync::Lazy; + use crate::{ dpi::{LogicalPosition, LogicalSize}, event::{ From 7c4a8033437988190776de270a537ac24b7d23e7 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 8 Jun 2022 04:20:22 -0700 Subject: [PATCH 3/6] Fix formatting errors and fix the import order for other files --- src/platform_impl/linux/x11/monitor.rs | 2 +- src/platform_impl/linux/x11/util/atom.rs | 5 +++-- src/platform_impl/linux/x11/util/wm.rs | 2 +- src/platform_impl/macos/app_delegate.rs | 11 ++++++----- src/platform_impl/macos/app_state.rs | 2 +- src/platform_impl/macos/window.rs | 23 ++++++++++++----------- 6 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/platform_impl/linux/x11/monitor.rs b/src/platform_impl/linux/x11/monitor.rs index 7d03ab2b6e..8249d83caf 100644 --- a/src/platform_impl/linux/x11/monitor.rs +++ b/src/platform_impl/linux/x11/monitor.rs @@ -1,7 +1,7 @@ use std::os::raw::*; -use parking_lot::Mutex; use once_cell::sync::Lazy; +use parking_lot::Mutex; use super::{ ffi::{ diff --git a/src/platform_impl/linux/x11/util/atom.rs b/src/platform_impl/linux/x11/util/atom.rs index b861d9e67c..5bfa386a49 100644 --- a/src/platform_impl/linux/x11/util/atom.rs +++ b/src/platform_impl/linux/x11/util/atom.rs @@ -1,5 +1,3 @@ -use once_cell::sync::Lazy; -use parking_lot::Mutex; use std::{ collections::HashMap, ffi::{CStr, CString}, @@ -7,6 +5,9 @@ use std::{ os::raw::*, }; +use once_cell::sync::Lazy; +use parking_lot::Mutex; + use super::*; type AtomCache = HashMap; diff --git a/src/platform_impl/linux/x11/util/wm.rs b/src/platform_impl/linux/x11/util/wm.rs index 89ba25814a..21fa790d73 100644 --- a/src/platform_impl/linux/x11/util/wm.rs +++ b/src/platform_impl/linux/x11/util/wm.rs @@ -1,5 +1,5 @@ -use parking_lot::Mutex; use once_cell::sync::Lazy; +use parking_lot::Mutex; use super::*; diff --git a/src/platform_impl/macos/app_delegate.rs b/src/platform_impl/macos/app_delegate.rs index cf813f4fe2..5ff8be2fb0 100644 --- a/src/platform_impl/macos/app_delegate.rs +++ b/src/platform_impl/macos/app_delegate.rs @@ -1,4 +1,7 @@ -use crate::{platform::macos::ActivationPolicy, platform_impl::platform::app_state::AppState}; +use std::{ + cell::{RefCell, RefMut}, + os::raw::c_void, +}; use cocoa::base::id; use objc::{ @@ -6,10 +9,8 @@ use objc::{ runtime::{Class, Object, Sel}, }; use once_cell::sync::Lazy; -use std::{ - cell::{RefCell, RefMut}, - os::raw::c_void, -}; + +use crate::{platform::macos::ActivationPolicy, platform_impl::platform::app_state::AppState}; static AUX_DELEGATE_STATE_NAME: &str = "auxState"; diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index d9aa449c3b..94aefe04a1 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -21,6 +21,7 @@ use objc::{ rc::autoreleasepool, runtime::{Object, BOOL, NO, YES}, }; +use once_cell::sync::Lazy; use crate::{ dpi::LogicalSize, @@ -40,7 +41,6 @@ use crate::{ }, window::WindowId, }; -use once_cell::sync::Lazy; static HANDLER: Lazy = Lazy::new(Default::default); diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index d9033ab355..6bada6dc1f 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -1,3 +1,15 @@ +use raw_window_handle::{AppKitHandle, RawWindowHandle}; +use std::{ + collections::VecDeque, + convert::TryInto, + f64, ops, + os::raw::c_void, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Mutex, MutexGuard, Weak, + }, +}; + use crate::{ dpi::{ LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical, @@ -36,17 +48,6 @@ use objc::{ runtime::{Class, Object, Sel, BOOL, NO, YES}, }; use once_cell::sync::Lazy; -use raw_window_handle::{AppKitHandle, RawWindowHandle}; -use std::{ - collections::VecDeque, - convert::TryInto, - f64, ops, - os::raw::c_void, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, MutexGuard, Weak, - }, -}; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(pub usize); From a1cd124ae39eed9f8a7f9fc3c6a88fd063ede44a Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 8 Jun 2022 04:22:44 -0700 Subject: [PATCH 4/6] Undo more spurious moves --- src/platform_impl/macos/window_delegate.rs | 11 ++++++----- src/platform_impl/windows/dark_mode.rs | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 79b3308d90..c6129a27a8 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -1,3 +1,9 @@ +use std::{ + f64, + os::raw::c_void, + sync::{atomic::Ordering, Arc, Weak}, +}; + use cocoa::{ appkit::{self, NSApplicationPresentationOptions, NSView, NSWindow}, base::{id, nil}, @@ -9,11 +15,6 @@ use objc::{ runtime::{Class, Object, Sel, BOOL, NO, YES}, }; use once_cell::sync::Lazy; -use std::{ - f64, - os::raw::c_void, - sync::{atomic::Ordering, Arc, Weak}, -}; use crate::{ dpi::{LogicalPosition, LogicalSize}, diff --git a/src/platform_impl/windows/dark_mode.rs b/src/platform_impl/windows/dark_mode.rs index 6480379dfc..6487617f2c 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -1,7 +1,8 @@ -use once_cell::sync::Lazy; /// This is a simple implementation of support for Windows Dark Mode, /// which is inspired by the solution in https://github.com/ysc3839/win32-darkmode use std::{ffi::c_void, ptr}; + +use once_cell::sync::Lazy; use windows_sys::{ core::PCSTR, Win32::{ From 8e0266b58394c03595dedaaa12f9b1123d11b715 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 8 Jun 2022 04:23:45 -0700 Subject: [PATCH 5/6] Fix formatting --- src/platform_impl/linux/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 26647e57f4..c9431297ec 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -18,11 +18,11 @@ use std::{collections::VecDeque, env, fmt}; #[cfg(feature = "x11")] use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Arc}; +#[cfg(feature = "x11")] +use once_cell::sync::Lazy; #[cfg(feature = "x11")] use parking_lot::Mutex; use raw_window_handle::RawWindowHandle; -#[cfg(feature = "x11")] -use once_cell::sync::Lazy; #[cfg(feature = "x11")] pub use self::x11::XNotSupported; From 818b727fef962a8d773aa9a24570b5622e0e9d90 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 8 Jun 2022 04:25:53 -0700 Subject: [PATCH 6/6] Fix up more imports --- src/platform_impl/android/mod.rs | 22 ++++++++++++---------- src/platform_impl/ios/app_state.rs | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 489211860f..b67f47eb12 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -1,12 +1,11 @@ #![cfg(target_os = "android")] -use crate::{ - dpi::{PhysicalPosition, PhysicalSize, Position, Size}, - error, - event::{self, VirtualKeyCode}, - event_loop::{self, ControlFlow}, - monitor, window, +use std::{ + collections::VecDeque, + sync::{Arc, Mutex, RwLock}, + time::{Duration, Instant}, }; + use ndk::{ configuration::Configuration, event::{InputEvent, KeyAction, Keycode, MotionAction}, @@ -15,10 +14,13 @@ use ndk::{ use ndk_glue::{Event, Rect}; use once_cell::sync::Lazy; use raw_window_handle::{AndroidNdkHandle, RawWindowHandle}; -use std::{ - collections::VecDeque, - sync::{Arc, Mutex, RwLock}, - time::{Duration, Instant}, + +use crate::{ + dpi::{PhysicalPosition, PhysicalSize, Position, Size}, + error, + event::{self, VirtualKeyCode}, + event_loop::{self, ControlFlow}, + monitor, window, }; static CONFIG: Lazy> = Lazy::new(|| { diff --git a/src/platform_impl/ios/app_state.rs b/src/platform_impl/ios/app_state.rs index 848d16b36f..c21ceff53b 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -1,6 +1,5 @@ #![deny(unused_results)] -use once_cell::sync::Lazy; use std::{ cell::{RefCell, RefMut}, collections::HashSet, @@ -11,6 +10,7 @@ use std::{ }; use objc::runtime::{BOOL, YES}; +use once_cell::sync::Lazy; use crate::{ dpi::LogicalSize,