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..b67f47eb12 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -1,38 +1,41 @@ #![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}, looper::{ForeignLooper, Poll, ThreadLooper}, }; 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, }; -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..c21ceff53b 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -10,6 +10,7 @@ use std::{ }; use objc::runtime::{BOOL, YES}; +use once_cell::sync::Lazy; use crate::{ dpi::LogicalSize, @@ -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..c9431297ec 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -18,6 +18,8 @@ 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; @@ -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..5a1695cb0e 100644 --- a/src/platform_impl/linux/x11/ime/input_method.rs +++ b/src/platform_impl/linux/x11/ime/input_method.rs @@ -7,13 +7,12 @@ use std::{ sync::Arc, }; +use once_cell::sync::Lazy; 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..8249d83caf 100644 --- a/src/platform_impl/linux/x11/monitor.rs +++ b/src/platform_impl/linux/x11/monitor.rs @@ -1,5 +1,6 @@ use std::os::raw::*; +use once_cell::sync::Lazy; use parking_lot::Mutex; use super::{ @@ -18,9 +19,7 @@ use crate::{ // 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..5bfa386a49 100644 --- a/src/platform_impl/linux/x11/util/atom.rs +++ b/src/platform_impl/linux/x11/util/atom.rs @@ -5,15 +5,14 @@ use std::{ os::raw::*, }; +use once_cell::sync::Lazy; 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..21fa790d73 100644 --- a/src/platform_impl/linux/x11/util/wm.rs +++ b/src/platform_impl/linux/x11/util/wm.rs @@ -1,12 +1,12 @@ +use once_cell::sync::Lazy; use parking_lot::Mutex; use super::*; // 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..5ff8be2fb0 100644 --- a/src/platform_impl/macos/app_delegate.rs +++ b/src/platform_impl/macos/app_delegate.rs @@ -1,14 +1,16 @@ -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::{ declare::ClassDecl, runtime::{Class, Object, Sel}, }; -use std::{ - cell::{RefCell, RefMut}, - os::raw::c_void, -}; +use once_cell::sync::Lazy; + +use crate::{platform::macos::ActivationPolicy, platform_impl::platform::app_state::AppState}; static AUX_DELEGATE_STATE_NAME: &str = "auxState"; @@ -21,23 +23,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..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, @@ -41,9 +42,7 @@ use crate::{ window::WindowId, }; -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..94e3c73863 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -18,6 +18,7 @@ use objc::{ declare::ClassDecl, runtime::{Class, Object, Protocol, Sel, BOOL, NO, YES}, }; +use once_cell::sync::Lazy; use crate::{ dpi::{LogicalPosition, LogicalSize}, @@ -155,173 +156,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..6bada6dc1f 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -47,6 +47,7 @@ use objc::{ rc::autoreleasepool, runtime::{Class, Object, Sel, BOOL, NO, YES}, }; +use once_cell::sync::Lazy; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(pub usize); @@ -247,32 +248,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..c6129a27a8 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -14,6 +14,7 @@ use objc::{ rc::autoreleasepool, runtime::{Class, Object, Sel, BOOL, NO, YES}, }; +use once_cell::sync::Lazy; use crate::{ dpi::{LogicalPosition, LogicalSize}, @@ -135,97 +136,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..6487617f2c 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -2,6 +2,7 @@ /// 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::{ @@ -22,47 +23,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); + + 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); - 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 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 +112,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 +141,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));