Migrate from lazy_static to once_cell

This commit is contained in:
James Liu 2022-06-08 11:50:26 -07:00 committed by GitHub
parent 4c39b3188c
commit 2c01e9e747
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 477 additions and 519 deletions

View file

@ -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"

View file

@ -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;

View file

@ -1,5 +1,20 @@
#![cfg(target_os = "android")]
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 crate::{
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
error,
@ -7,32 +22,20 @@ use crate::{
event_loop::{self, ControlFlow},
monitor, window,
};
use ndk::{
configuration::Configuration,
event::{InputEvent, KeyAction, Keycode, MotionAction},
looper::{ForeignLooper, Poll, ThreadLooper},
};
use ndk_glue::{Event, Rect};
use raw_window_handle::{AndroidNdkHandle, RawWindowHandle};
use std::{
collections::VecDeque,
sync::{Arc, Mutex, RwLock},
time::{Duration, Instant},
};
lazy_static! {
static ref CONFIG: RwLock<Configuration> = RwLock::new(Configuration::from_asset_manager(
static CONFIG: Lazy<RwLock<Configuration>> = 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<Option<InternalEvent>> = 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<RwLock<Option<InternalEvent>>> = Lazy::new(|| RwLock::new(None));
enum InternalEvent {
RedrawRequested,

View file

@ -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<OSCapabilities> = 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()
}

View file

@ -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;
@ -135,10 +137,8 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
}
#[cfg(feature = "x11")]
lazy_static! {
pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> =
Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new));
}
pub static X11_BACKEND: Lazy<Mutex<Result<Arc<XConnection>, XNotSupported>>> =
Lazy::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)));
#[derive(Debug, Clone)]
pub enum OsError {

View file

@ -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<Mutex<()>> = Lazy::new(Default::default);
unsafe fn open_im(xconn: &Arc<XConnection>, locale_modifiers: &CStr) -> Option<ffi::XIM> {
let _lock = GLOBAL_LOCK.lock();

View file

@ -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<Option<Vec<MonitorHandle>>> = Mutex::default();
}
static MONITORS: Lazy<Mutex<Option<Vec<MonitorHandle>>>> = Lazy::new(Mutex::default);
pub fn invalidate_cached_monitor_list() -> Option<Vec<MonitorHandle>> {
// We update this lazily.

View file

@ -5,15 +5,14 @@ use std::{
os::raw::*,
};
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use super::*;
type AtomCache = HashMap<CString, ffi::Atom>;
lazy_static! {
static ref ATOM_CACHE: Mutex<AtomCache> = Mutex::new(HashMap::with_capacity(2048));
}
static ATOM_CACHE: Lazy<Mutex<AtomCache>> = Lazy::new(|| Mutex::new(HashMap::with_capacity(2048)));
impl XConnection {
pub fn get_atom<T: AsRef<CStr> + Debug>(&self, name: T) -> ffi::Atom {

View file

@ -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<Vec<ffi::Atom>> = Mutex::new(Vec::with_capacity(0));
static ref WM_NAME: Mutex<Option<String>> = Mutex::new(None);
}
static SUPPORTED_HINTS: Lazy<Mutex<Vec<ffi::Atom>>> =
Lazy::new(|| Mutex::new(Vec::with_capacity(0)));
static WM_NAME: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None));
pub fn hint_is_supported(hint: ffi::Atom) -> bool {
(*SUPPORTED_HINTS.lock()).contains(&hint)

View file

@ -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<AppClass> = 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)

View file

@ -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<AppDelegateClass> = 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> {

View file

@ -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<Handler> = Lazy::new(Default::default);
impl<'a, Never> Event<'a, Never> {
fn userify<T: 'static>(self) -> Event<'a, T> {

View file

@ -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),
);
static VIEW_CLASS: Lazy<ViewClass> = 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),
);
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// 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::<id>("markedText");
let protocol = Protocol::get("NSTextInputClient").unwrap();
decl.add_protocol(protocol);
ViewClass(decl.register())
};
}
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::<id>("markedText");
let protocol = Protocol::get("NSTextInputClient").unwrap();
decl.add_protocol(protocol);
ViewClass(decl.register())
});
extern "C" fn dealloc(this: &Object, _sel: Sel) {
unsafe {

View file

@ -46,6 +46,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);
@ -246,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<WindowClass> = 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 {

View file

@ -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},
@ -134,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();
static WINDOW_DELEGATE_CLASS: Lazy<WindowDelegateClass> = 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!(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!(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!(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_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())
};
}
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...

View file

@ -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<u32> = {
type RtlGetVersion = unsafe extern "system" fn (*mut OSVERSIONINFOW) -> NTSTATUS;
let handle = get_function!("ntdll.dll", RtlGetVersion);
static WIN10_BUILD_VERSION: Lazy<Option<u32>> = 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],
};
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);
let status = (rtl_get_version)(&mut vi);
if status >= 0 && vi.dwMajorVersion == 10 && vi.dwMinorVersion == 0 {
Some(vi.dwBuildNumber)
} else {
None
}
if status >= 0 && vi.dwMajorVersion == 10 && vi.dwMinorVersion == 0 {
Some(vi.dwBuildNumber)
} else {
None
}
} else {
None
}
};
} else {
None
}
});
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
}
};
static DARK_MODE_SUPPORTED: Lazy<bool> = 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<u16> = util::encode_wide("DarkMode_Explorer");
static ref LIGHT_THEME_NAME: Vec<u16> = util::encode_wide("");
}
static DARK_THEME_NAME: Lazy<Vec<u16>> = Lazy::new(|| util::encode_wide("DarkMode_Explorer"));
static LIGHT_THEME_NAME: Lazy<Vec<u16>> = 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<SetWindowCompositionAttribute> =
get_function!("user32.dll", SetWindowCompositionAttribute);
}
static SET_WINDOW_COMPOSITION_ATTRIBUTE: Lazy<Option<SetWindowCompositionAttribute>> =
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<ShouldAppsUseDarkMode> = {
unsafe {
const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: PCSTR = 132 as PCSTR;
static SHOULD_APPS_USE_DARK_MODE: Lazy<Option<ShouldAppsUseDarkMode>> = 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)() })

View file

@ -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<GetPointerFrameInfoHistory> =
get_function!("user32.dll", GetPointerFrameInfoHistory);
static ref SKIP_POINTER_FRAME_MESSAGES: Option<SkipPointerFrameMessages> =
get_function!("user32.dll", SkipPointerFrameMessages);
static ref GET_POINTER_DEVICE_RECTS: Option<GetPointerDeviceRects> =
get_function!("user32.dll", GetPointerDeviceRects);
static ref GET_POINTER_TOUCH_INFO: Option<GetPointerTouchInfo> =
get_function!("user32.dll", GetPointerTouchInfo);
static ref GET_POINTER_PEN_INFO: Option<GetPointerPenInfo> =
get_function!("user32.dll", GetPointerPenInfo);
}
static GET_POINTER_FRAME_INFO_HISTORY: Lazy<Option<GetPointerFrameInfoHistory>> =
Lazy::new(|| get_function!("user32.dll", GetPointerFrameInfoHistory));
static SKIP_POINTER_FRAME_MESSAGES: Lazy<Option<SkipPointerFrameMessages>> =
Lazy::new(|| get_function!("user32.dll", SkipPointerFrameMessages));
static GET_POINTER_DEVICE_RECTS: Lazy<Option<GetPointerDeviceRects>> =
Lazy::new(|| get_function!("user32.dll", GetPointerDeviceRects));
static GET_POINTER_TOUCH_INFO: Lazy<Option<GetPointerTouchInfo>> =
Lazy::new(|| get_function!("user32.dll", GetPointerTouchInfo));
static GET_POINTER_PEN_INFO: Lazy<Option<GetPointerPenInfo>> =
Lazy::new(|| get_function!("user32.dll", GetPointerPenInfo));
pub(crate) struct WindowData<T: 'static> {
pub window_state: Arc<Mutex<WindowState>>,
pub event_loop_runner: EventLoopRunnerShared<T>,
@ -375,19 +375,17 @@ fn get_wait_thread_id() -> u32 {
}
}
lazy_static! {
static ref WAIT_PERIOD_MIN: Option<u32> = unsafe {
let mut caps = TIMECAPS {
wPeriodMin: 0,
wPeriodMax: 0,
};
if timeGetDevCaps(&mut caps, mem::size_of::<TIMECAPS>() as u32) == TIMERR_NOERROR {
Some(caps.wPeriodMin)
} else {
None
}
static WAIT_PERIOD_MIN: Lazy<Option<u32>> = Lazy::new(|| unsafe {
let mut caps = TIMECAPS {
wPeriodMin: 0,
wPeriodMax: 0,
};
}
if timeGetDevCaps(&mut caps, mem::size_of::<TIMECAPS>() 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<T: 'static> EventLoopProxy<T> {
type WaitUntilInstantBox = Box<Instant>;
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<Box<dyn FnMut()>> 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<Instant>` 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<u16> = 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<u32> =
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<Box<dyn FnMut()>> that must be retrieved with `Box::from_raw`,
// and LPARAM is unused.
static EXEC_MSG_ID: Lazy<u32> =
Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::ExecMsg\0".as_ptr()) });
static PROCESS_NEW_EVENTS_MSG_ID: Lazy<u32> =
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<u32> =
Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::SendWaitThreadId\0".as_ptr()) });
/// lparam points to a `Box<Instant>` signifying the time `PROCESS_NEW_EVENTS_MSG_ID` should
/// be sent.
static WAIT_UNTIL_MSG_ID: Lazy<u32> =
Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::WaitUntil\0".as_ptr()) });
static CANCEL_WAIT_UNTIL_MSG_ID: Lazy<u32> =
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<u32> =
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<u32> =
Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::SetRetainMaximized\0".as_ptr()) });
static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy<Vec<u16>> =
Lazy::new(|| util::encode_wide("Winit Thread Event Target"));
fn create_event_target_window<T: 'static>() -> HWND {
unsafe {

View file

@ -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<GetDpiForWindow> =
get_function!("user32.dll", GetDpiForWindow);
pub static ref ADJUST_WINDOW_RECT_EX_FOR_DPI: Option<AdjustWindowRectExForDpi> =
get_function!("user32.dll", AdjustWindowRectExForDpi);
pub static ref GET_DPI_FOR_MONITOR: Option<GetDpiForMonitor> =
get_function!("shcore.dll", GetDpiForMonitor);
pub static ref ENABLE_NON_CLIENT_DPI_SCALING: Option<EnableNonClientDpiScaling> =
get_function!("user32.dll", EnableNonClientDpiScaling);
pub static ref SET_PROCESS_DPI_AWARENESS_CONTEXT: Option<SetProcessDpiAwarenessContext> =
get_function!("user32.dll", SetProcessDpiAwarenessContext);
pub static ref SET_PROCESS_DPI_AWARENESS: Option<SetProcessDpiAwareness> =
get_function!("shcore.dll", SetProcessDpiAwareness);
pub static ref SET_PROCESS_DPI_AWARE: Option<SetProcessDPIAware> =
get_function!("user32.dll", SetProcessDPIAware);
}
pub static GET_DPI_FOR_WINDOW: Lazy<Option<GetDpiForWindow>> =
Lazy::new(|| get_function!("user32.dll", GetDpiForWindow));
pub static ADJUST_WINDOW_RECT_EX_FOR_DPI: Lazy<Option<AdjustWindowRectExForDpi>> =
Lazy::new(|| get_function!("user32.dll", AdjustWindowRectExForDpi));
pub static GET_DPI_FOR_MONITOR: Lazy<Option<GetDpiForMonitor>> =
Lazy::new(|| get_function!("shcore.dll", GetDpiForMonitor));
pub static ENABLE_NON_CLIENT_DPI_SCALING: Lazy<Option<EnableNonClientDpiScaling>> =
Lazy::new(|| get_function!("user32.dll", EnableNonClientDpiScaling));
pub static SET_PROCESS_DPI_AWARENESS_CONTEXT: Lazy<Option<SetProcessDpiAwarenessContext>> =
Lazy::new(|| get_function!("user32.dll", SetProcessDpiAwarenessContext));
pub static SET_PROCESS_DPI_AWARENESS: Lazy<Option<SetProcessDpiAwareness>> =
Lazy::new(|| get_function!("shcore.dll", SetProcessDpiAwareness));
pub static SET_PROCESS_DPI_AWARE: Lazy<Option<SetProcessDPIAware>> =
Lazy::new(|| get_function!("user32.dll", SetProcessDPIAware));