diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e917cdad0..7ceac9bc19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [stable, nightly, '1.73'] + toolchain: [stable, nightly, '1.80'] platform: # Note: Make sure that we test all the `docs.rs` targets defined in Cargo.toml! - { name: 'Windows 64bit MSVC', target: x86_64-pc-windows-msvc, os: windows-latest, } @@ -82,13 +82,13 @@ jobs: - toolchain: nightly platform: { name: 'Windows 32bit GNU' } # Android is tested on stable-3 - - toolchain: '1.73' + - toolchain: '1.80' platform: { name: 'Android' } # Redox OS doesn't follow MSRV - - toolchain: '1.73' + - toolchain: '1.80' platform: { name: 'Redox OS' } include: - - toolchain: '1.73' + - toolchain: '1.80' platform: { name: 'Android', target: aarch64-linux-android, os: ubuntu-latest, options: '--package=winit --features=android-native-activity', cmd: 'apk --' } - toolchain: 'nightly' platform: { name: 'Web', target: wasm32-unknown-unknown, os: ubuntu-latest, test-options: -Zdoctest-xcompile } @@ -183,19 +183,19 @@ jobs: - name: Test dpi crate if: > contains(matrix.platform.name, 'Linux 64bit') && - matrix.toolchain != '1.73' + matrix.toolchain != '1.80' run: cargo test -p dpi - name: Check dpi crate (no_std) if: > contains(matrix.platform.name, 'Linux 64bit') && - matrix.toolchain != '1.73' + matrix.toolchain != '1.80' run: cargo check -p dpi --no-default-features - name: Build tests if: > !contains(matrix.platform.target, 'redox') && - matrix.toolchain != '1.73' + matrix.toolchain != '1.80' run: cargo $CMD test --no-run $OPTIONS - name: Run tests @@ -204,7 +204,7 @@ jobs: !contains(matrix.platform.target, 'ios') && (!contains(matrix.platform.target, 'wasm32') || matrix.toolchain == 'nightly') && !contains(matrix.platform.target, 'redox') && - matrix.toolchain != '1.73' + matrix.toolchain != '1.80' run: cargo $CMD test $OPTIONS - name: Lint with clippy @@ -214,7 +214,7 @@ jobs: - name: Build tests with serde enabled if: > !contains(matrix.platform.target, 'redox') && - matrix.toolchain != '1.73' + matrix.toolchain != '1.80' run: cargo $CMD test --no-run $OPTIONS $TEST_OPTIONS --features serde - name: Run tests with serde enabled @@ -223,7 +223,7 @@ jobs: !contains(matrix.platform.target, 'ios') && (!contains(matrix.platform.target, 'wasm32') || matrix.toolchain == 'nightly') && !contains(matrix.platform.target, 'redox') && - matrix.toolchain != '1.73' + matrix.toolchain != '1.80' run: cargo $CMD test $OPTIONS $TEST_OPTIONS --features serde - name: Check docs.rs documentation diff --git a/Cargo.toml b/Cargo.toml index d4896cec22..7385cf7e46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -396,7 +396,7 @@ resolver = "2" edition = "2021" license = "Apache-2.0" repository = "https://github.com/rust-windowing/winit" -rust-version = "1.73" +rust-version = "1.80" [workspace.dependencies] mint = "0.5.6" diff --git a/README.md b/README.md index ebcebba209..4aab5efbf9 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ For contributing guidelines see [CONTRIBUTING.md](./CONTRIBUTING.md). ## MSRV Policy -This crate's Minimum Supported Rust Version (MSRV) is **1.73**. Changes to +This crate's Minimum Supported Rust Version (MSRV) is **1.80**. Changes to the MSRV will be accompanied by a minor version bump. As a **tentative** policy, the upper bound of the MSRV is given by the following diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 1109dd8399..d56b693180 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -85,7 +85,7 @@ changelog entry. - `ActiveEventLoop::create_window` now returns `Box`. - `ApplicationHandler` now uses `dyn ActiveEventLoop`. - On Web, let events wake up event loop immediately when using `ControlFlow::Poll`. -- Bump MSRV from `1.70` to `1.73`. +- Bump MSRV from `1.70` to `1.80`. - Changed `ApplicationHandler::user_event` to `user_wake_up`, removing the generic user event. diff --git a/src/platform_impl/linux/common/xkb/mod.rs b/src/platform_impl/linux/common/xkb/mod.rs index ad6cf484d1..205f803895 100644 --- a/src/platform_impl/linux/common/xkb/mod.rs +++ b/src/platform_impl/linux/common/xkb/mod.rs @@ -4,6 +4,7 @@ use std::os::raw::c_char; use std::os::unix::io::OwnedFd; use std::ptr::{self, NonNull}; use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::LazyLock; use smol_str::SmolStr; use tracing::warn; @@ -16,7 +17,6 @@ use {x11_dl::xlib_xcb::xcb_connection_t, xkbcommon_dl::x11::xkbcommon_x11_handle use crate::event::{ElementState, KeyEvent}; use crate::keyboard::{Key, KeyLocation}; -use crate::utils::Lazy; mod compose; mod keymap; @@ -32,10 +32,10 @@ pub use state::XkbState; // TODO: Wire this up without using a static `AtomicBool`. static RESET_DEAD_KEYS: AtomicBool = AtomicBool::new(false); -static XKBH: Lazy<&'static XkbCommon> = Lazy::new(xkbcommon_handle); -static XKBCH: Lazy<&'static XkbCommonCompose> = Lazy::new(xkbcommon_compose_handle); +static XKBH: LazyLock<&'static XkbCommon> = LazyLock::new(xkbcommon_handle); +static XKBCH: LazyLock<&'static XkbCommonCompose> = LazyLock::new(xkbcommon_compose_handle); #[cfg(feature = "x11")] -static XKBXH: Lazy<&'static xkb::x11::XkbCommonX11> = Lazy::new(xkbcommon_x11_handle); +static XKBXH: LazyLock<&'static xkb::x11::XkbCommonX11> = LazyLock::new(xkbcommon_x11_handle); #[inline(always)] pub fn reset_dead_keys() { diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 9a92b1fd4f..1a5ac78037 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -6,7 +6,7 @@ use std::ops::Deref; use std::os::raw::*; use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; use std::sync::mpsc::{self, Receiver, Sender, TryRecvError}; -use std::sync::{Arc, Mutex, Weak}; +use std::sync::{Arc, LazyLock, Mutex, Weak}; use std::time::{Duration, Instant}; use std::{fmt, mem, ptr, slice, str}; @@ -36,7 +36,6 @@ use crate::platform::x11::XlibErrorHook; use crate::platform_impl::common::xkb::Context; use crate::platform_impl::platform::min_timeout; use crate::platform_impl::x11::window::Window; -use crate::utils::Lazy; use crate::window::{ CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, Window as CoreWindow, WindowAttributes, WindowId, @@ -74,8 +73,8 @@ type X11rbConnection = x11rb::xcb_ffi::XCBConnection; type X11Source = Generic>; #[cfg(x11_platform)] -pub(crate) static X11_BACKEND: Lazy, XNotSupported>>> = - Lazy::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))); +pub(crate) static X11_BACKEND: LazyLock, XNotSupported>>> = + LazyLock::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))); /// Hooks for X11 errors. #[cfg(x11_platform)] @@ -252,7 +251,7 @@ impl EventLoop { // Remember default locale to restore it if target locale is unsupported // by Xlib let default_locale = setlocale(LC_CTYPE, ptr::null()); - setlocale(LC_CTYPE, b"\0".as_ptr() as *const _); + setlocale(LC_CTYPE, c"".as_ptr() as *const _); // Check if set locale is supported by Xlib. // If not, calls to some Xlib functions like `XSetLocaleModifiers` diff --git a/src/platform_impl/windows/dark_mode.rs b/src/platform_impl/windows/dark_mode.rs index 87bba6ed0a..6d50e308d5 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -1,3 +1,4 @@ +use std::sync::LazyLock; /// 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}; @@ -11,10 +12,9 @@ use windows_sys::Win32::UI::Controls::SetWindowTheme; use windows_sys::Win32::UI::WindowsAndMessaging::{SystemParametersInfoA, SPI_GETHIGHCONTRAST}; use super::util; -use crate::utils::Lazy; use crate::window::Theme; -static WIN10_BUILD_VERSION: Lazy> = Lazy::new(|| { +static WIN10_BUILD_VERSION: LazyLock> = LazyLock::new(|| { type RtlGetVersion = unsafe extern "system" fn(*mut OSVERSIONINFOW) -> NTSTATUS; let handle = get_function!("ntdll.dll", RtlGetVersion); @@ -42,7 +42,7 @@ static WIN10_BUILD_VERSION: Lazy> = Lazy::new(|| { } }); -static DARK_MODE_SUPPORTED: Lazy = Lazy::new(|| { +static DARK_MODE_SUPPORTED: LazyLock = LazyLock::new(|| { // We won't try to do anything for windows versions < 17763 // (Windows 10 October 2018 update) match *WIN10_BUILD_VERSION { @@ -51,8 +51,9 @@ static DARK_MODE_SUPPORTED: Lazy = Lazy::new(|| { } }); -static DARK_THEME_NAME: Lazy> = Lazy::new(|| util::encode_wide("DarkMode_Explorer")); -static LIGHT_THEME_NAME: Lazy> = Lazy::new(|| util::encode_wide("")); +static DARK_THEME_NAME: LazyLock> = + LazyLock::new(|| util::encode_wide("DarkMode_Explorer")); +static LIGHT_THEME_NAME: LazyLock> = LazyLock::new(|| util::encode_wide("")); /// Attempt to set a theme on a window, if necessary. /// Returns the theme that was picked @@ -99,8 +100,8 @@ fn set_dark_mode_for_window(hwnd: HWND, is_dark_mode: bool) -> bool { cbData: usize, } - static SET_WINDOW_COMPOSITION_ATTRIBUTE: Lazy> = - Lazy::new(|| get_function!("user32.dll", SetWindowCompositionAttribute)); + static SET_WINDOW_COMPOSITION_ATTRIBUTE: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", SetWindowCompositionAttribute)); if let Some(set_window_composition_attribute) = *SET_WINDOW_COMPOSITION_ATTRIBUTE { unsafe { @@ -128,19 +129,20 @@ pub fn should_use_dark_mode() -> bool { fn should_apps_use_dark_mode() -> bool { type ShouldAppsUseDarkMode = unsafe extern "system" fn() -> bool; - static SHOULD_APPS_USE_DARK_MODE: Lazy> = Lazy::new(|| unsafe { - const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: PCSTR = 132 as PCSTR; + static SHOULD_APPS_USE_DARK_MODE: LazyLock> = + LazyLock::new(|| unsafe { + const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: PCSTR = 132 as PCSTR; - let module = LoadLibraryA("uxtheme.dll\0".as_ptr()); + let module = LoadLibraryA(c"uxtheme.dll".as_ptr().cast()); - if module.is_null() { - return None; - } + if module.is_null() { + 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 95019a7196..0762599d02 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -7,7 +7,7 @@ use std::ffi::c_void; use std::os::windows::io::{AsRawHandle as _, FromRawHandle as _, OwnedHandle, RawHandle}; use std::rc::Rc; use std::sync::atomic::{AtomicU32, Ordering}; -use std::sync::{Arc, Mutex, MutexGuard}; +use std::sync::{Arc, LazyLock, Mutex, MutexGuard}; use std::time::{Duration, Instant}; use std::{fmt, mem, panic, ptr}; @@ -91,7 +91,6 @@ use crate::platform_impl::platform::window_state::{ }; use crate::platform_impl::platform::{raw_input, util, wrap_device_id}; use crate::platform_impl::Window; -use crate::utils::Lazy; use crate::window::{ CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, Window as CoreWindow, WindowAttributes, WindowId, @@ -833,8 +832,8 @@ pub(crate) static DESTROY_MSG_ID: LazyMessageId = LazyMessageId::new("Winit::Des // documentation in the `window_state` module for more information. pub(crate) static SET_RETAIN_STATE_ON_SIZE_MSG_ID: LazyMessageId = LazyMessageId::new("Winit::SetRetainMaximized\0"); -static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy> = - Lazy::new(|| util::encode_wide("Winit Thread Event Target")); +static THREAD_EVENT_TARGET_WINDOW_CLASS: LazyLock> = + LazyLock::new(|| util::encode_wide("Winit Thread Event Target")); /// When the taskbar is created, it registers a message with the "TaskbarCreated" string and then /// broadcasts this message to all top-level windows pub(crate) static TASKBAR_CREATED: LazyMessageId = LazyMessageId::new("TaskbarCreated\0"); diff --git a/src/platform_impl/windows/keyboard_layout.rs b/src/platform_impl/windows/keyboard_layout.rs index 1abbb09486..9e28bb01cf 100644 --- a/src/platform_impl/windows/keyboard_layout.rs +++ b/src/platform_impl/windows/keyboard_layout.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; -use std::sync::Mutex; +use std::sync::{LazyLock, Mutex}; use smol_str::SmolStr; use windows_sys::Win32::System::SystemServices::{LANG_JAPANESE, LANG_KOREAN}; @@ -43,10 +43,9 @@ use windows_sys::Win32::UI::Input::KeyboardAndMouse::{ use crate::keyboard::{Key, KeyCode, ModifiersState, NamedKey, NativeKey, PhysicalKey}; use crate::platform_impl::{loword, primarylangid, scancode_to_physicalkey}; -use crate::utils::Lazy; -pub(crate) static LAYOUT_CACHE: Lazy> = - Lazy::new(|| Mutex::new(LayoutCache::default())); +pub(crate) static LAYOUT_CACHE: LazyLock> = + LazyLock::new(|| Mutex::new(LayoutCache::default())); fn key_pressed(vkey: VIRTUAL_KEY) -> bool { unsafe { (GetKeyState(vkey as i32) & (1 << 15)) == (1 << 15) } @@ -71,7 +70,7 @@ const NUMPAD_VKEYS: [VIRTUAL_KEY; 16] = [ VK_DIVIDE, ]; -static NUMPAD_KEYCODES: Lazy> = Lazy::new(|| { +static NUMPAD_KEYCODES: LazyLock> = LazyLock::new(|| { let mut keycodes = HashSet::new(); keycodes.insert(KeyCode::Numpad0); keycodes.insert(KeyCode::Numpad1); diff --git a/src/platform_impl/windows/util.rs b/src/platform_impl/windows/util.rs index df67e44862..2bef7915b6 100644 --- a/src/platform_impl/windows/util.rs +++ b/src/platform_impl/windows/util.rs @@ -3,6 +3,7 @@ use std::iter::once; use std::ops::BitAnd; use std::os::windows::prelude::{OsStrExt, OsStringExt}; use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::LazyLock; use std::{io, mem, ptr}; use windows_sys::core::{HRESULT, PCWSTR}; @@ -23,7 +24,6 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{ WINDOWPLACEMENT, }; -use crate::utils::Lazy; use crate::window::CursorIcon; pub fn encode_wide(string: impl AsRef) -> Vec { @@ -251,25 +251,26 @@ pub type GetPointerDeviceRects = unsafe extern "system" fn( pub type GetPointerTouchInfo = unsafe extern "system" fn(pointer_id: u32, touch_info: *mut POINTER_TOUCH_INFO) -> BOOL; -pub(crate) static GET_DPI_FOR_WINDOW: Lazy> = - Lazy::new(|| get_function!("user32.dll", GetDpiForWindow)); -pub(crate) static ADJUST_WINDOW_RECT_EX_FOR_DPI: Lazy> = - Lazy::new(|| get_function!("user32.dll", AdjustWindowRectExForDpi)); -pub(crate) static GET_DPI_FOR_MONITOR: Lazy> = - Lazy::new(|| get_function!("shcore.dll", GetDpiForMonitor)); -pub(crate) static ENABLE_NON_CLIENT_DPI_SCALING: Lazy> = - Lazy::new(|| get_function!("user32.dll", EnableNonClientDpiScaling)); -pub(crate) static SET_PROCESS_DPI_AWARENESS_CONTEXT: Lazy> = - Lazy::new(|| get_function!("user32.dll", SetProcessDpiAwarenessContext)); -pub(crate) static SET_PROCESS_DPI_AWARENESS: Lazy> = - Lazy::new(|| get_function!("shcore.dll", SetProcessDpiAwareness)); -pub(crate) static SET_PROCESS_DPI_AWARE: Lazy> = - Lazy::new(|| get_function!("user32.dll", SetProcessDPIAware)); -pub(crate) static GET_POINTER_FRAME_INFO_HISTORY: Lazy> = - Lazy::new(|| get_function!("user32.dll", GetPointerFrameInfoHistory)); -pub(crate) static SKIP_POINTER_FRAME_MESSAGES: Lazy> = - Lazy::new(|| get_function!("user32.dll", SkipPointerFrameMessages)); -pub(crate) static GET_POINTER_DEVICE_RECTS: Lazy> = - Lazy::new(|| get_function!("user32.dll", GetPointerDeviceRects)); -pub(crate) static GET_POINTER_TOUCH_INFO: Lazy> = - Lazy::new(|| get_function!("user32.dll", GetPointerTouchInfo)); +pub(crate) static GET_DPI_FOR_WINDOW: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", GetDpiForWindow)); +pub(crate) static ADJUST_WINDOW_RECT_EX_FOR_DPI: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", AdjustWindowRectExForDpi)); +pub(crate) static GET_DPI_FOR_MONITOR: LazyLock> = + LazyLock::new(|| get_function!("shcore.dll", GetDpiForMonitor)); +pub(crate) static ENABLE_NON_CLIENT_DPI_SCALING: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", EnableNonClientDpiScaling)); +pub(crate) static SET_PROCESS_DPI_AWARENESS_CONTEXT: LazyLock< + Option, +> = LazyLock::new(|| get_function!("user32.dll", SetProcessDpiAwarenessContext)); +pub(crate) static SET_PROCESS_DPI_AWARENESS: LazyLock> = + LazyLock::new(|| get_function!("shcore.dll", SetProcessDpiAwareness)); +pub(crate) static SET_PROCESS_DPI_AWARE: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", SetProcessDPIAware)); +pub(crate) static GET_POINTER_FRAME_INFO_HISTORY: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", GetPointerFrameInfoHistory)); +pub(crate) static SKIP_POINTER_FRAME_MESSAGES: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", SkipPointerFrameMessages)); +pub(crate) static GET_POINTER_DEVICE_RECTS: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", GetPointerDeviceRects)); +pub(crate) static GET_POINTER_TOUCH_INFO: LazyLock> = + LazyLock::new(|| get_function!("user32.dll", GetPointerTouchInfo)); diff --git a/src/utils.rs b/src/utils.rs index c0dcbcca82..3ef0b9f3e3 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,32 +1,4 @@ -// A poly-fill for `lazy_cell` -// Replace with std::sync::LazyLock when https://github.com/rust-lang/rust/issues/109736 is stabilized. - -// This isn't used on every platform, which can come up as dead code warnings. -#![allow(dead_code)] - use std::any::Any; -use std::ops::Deref; -use std::sync::OnceLock; - -pub(crate) struct Lazy { - cell: OnceLock, - init: fn() -> T, -} - -impl Lazy { - pub const fn new(f: fn() -> T) -> Self { - Self { cell: OnceLock::new(), init: f } - } -} - -impl Deref for Lazy { - type Target = T; - - #[inline] - fn deref(&self) -> &'_ T { - self.cell.get_or_init(self.init) - } -} // NOTE: This is `pub`, but isn't actually exposed outside the crate. // NOTE: Marked as `#[doc(hidden)]` and underscored, because they can be quite difficult to use