Compare commits

..

7 Commits

Author SHA1 Message Date
Kirill Chibisov
911fad0af0 Winit version 0.30.11 2025-05-21 17:50:00 +09:00
Kirill Chibisov
2191eacfc8 chore: appease clippy 2025-05-21 17:50:00 +09:00
Kirill Chibisov
f7ac8127e3 wayland: fix pump events's loop drop deadlock 2025-05-21 17:50:00 +09:00
Varphone Wong
bd2b5cda8d windows: Fix crash in for Windows versions < 17763
In Windows versions < 17763, `GetProcAddress("#132")` from `uxtheme.dll`
also returns a non-null pointer. However, the function does not match
the expected `extern "system" fn() -> bool` prototype, which causes a
crash when it is called.

This fix ensures compatibility by adding proper checks to prevent such
crashes on older Windows versions.
2025-05-21 17:50:00 +09:00
Kirill Chibisov
3930a6334f ci/deny: allow scripts in zerocopy 2025-05-21 17:50:00 +09:00
Bruce Mitchener
17b5737972 Fix typos from updated typos tool (#4213) 2025-05-21 17:50:00 +09:00
Kirill Chibisov
f49a2a1827 clippy: fix casing in windows backend 2025-05-21 17:50:00 +09:00
17 changed files with 63 additions and 31 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "winit"
version = "0.30.10"
version = "0.30.11"
authors = [
"The winit contributors",
"Pierre Krieger <pierre.krieger1708@gmail.com>",

View File

@@ -8,7 +8,7 @@
```toml
[dependencies]
winit = "0.30.10"
winit = "0.30.11"
```
## [Documentation](https://docs.rs/winit)
@@ -33,6 +33,10 @@ Winit is designed to be a low-level brick in a hierarchy of libraries. Consequen
show something on the window you need to use the platform-specific getters provided by winit, or
another library.
## CONTRIBUTING
For contributing guidelines see [CONTRIBUTING.md](./CONTRIBUTING.md).
## MSRV Policy
This crate's Minimum Supported Rust Version (MSRV) is **1.70**. Changes to

View File

@@ -53,6 +53,10 @@ allow = [
]
crate = "android-activity"
[[bans.build.bypass]]
allow-globs = ["ci/*", "githooks/*"]
crate = "zerocopy"
[[bans.build.bypass]]
allow-globs = ["freetype2/*"]
crate = "freetype-sys"

View File

@@ -1,3 +1,10 @@
## 0.30.11
### Fixed
- On Windows, fixed crash in should_apps_use_dark_mode() for Windows versions < 17763.
- On Wayland, fixed `pump_events` driven loop deadlocking when loop was not drained before exit.
## 0.30.10
### Added

View File

@@ -1232,7 +1232,7 @@ pub enum NamedKey {
Dimmer,
/// Swap video sources. (`VK_DISPLAY_SWAP`)
DisplaySwap,
/// Select Digital Video Rrecorder. (`KEYCODE_DVR`)
/// Select Digital Video Recorder. (`KEYCODE_DVR`)
DVR,
/// Exit the current application. (`VK_EXIT`)
Exit,

View File

@@ -62,7 +62,7 @@
//! If your application is currently based on `NativeActivity` via the `ndk-glue` crate and building
//! with `cargo apk`, then the minimal changes would be:
//! 1. Remove `ndk-glue` from your `Cargo.toml`
//! 2. Enable the `"android-native-activity"` feature for Winit: `winit = { version = "0.30.10",
//! 2. Enable the `"android-native-activity"` feature for Winit: `winit = { version = "0.30.11",
//! features = [ "android-native-activity" ] }`
//! 3. Add an `android_main` entrypoint (as above), instead of using the '`[ndk_glue::main]` proc
//! macro from `ndk-macros` (optionally add a dependency on `android_logger` and initialize

View File

@@ -320,7 +320,7 @@ impl<'a, 'b> KeyEventResults<'a, 'b> {
// The current behaviour makes it so composing a character overrides attempts to input a
// control character with the `Ctrl` key. We can potentially add a configuration option
// if someone specifically wants the oppsite behaviour.
// if someone specifically wants the opposite behaviour.
pub fn text_with_all_modifiers(&mut self) -> Option<SmolStr> {
match self.composed_text() {
Ok(text) => text,

View File

@@ -696,6 +696,7 @@ unsafe extern "C" fn x_error_callback(
0
}
#[allow(clippy::large_enum_variant)]
pub enum EventLoop<T: 'static> {
#[cfg(wayland_platform)]
Wayland(Box<wayland::EventLoop<T>>),
@@ -849,6 +850,7 @@ impl<T: 'static> EventLoopProxy<T> {
}
}
#[allow(clippy::large_enum_variant)]
pub enum ActiveEventLoop {
#[cfg(wayland_platform)]
Wayland(wayland::ActiveEventLoop),

View File

@@ -734,7 +734,7 @@ impl Drop for PumpEventNotifier {
if let Some(worker_waker) = self.worker_waker.as_ref() {
let _ = rustix::io::write(worker_waker.as_fd(), &[0u8]);
}
*self.control.0.lock().unwrap() = PumpEventNotifierAction::Monitor;
*self.control.0.lock().unwrap() = PumpEventNotifierAction::Shutdown;
self.control.1.notify_one();
if let Some(handle) = self.handle.take() {
@@ -762,6 +762,14 @@ impl PumpEventNotifier {
while *wait == PumpEventNotifierAction::Pause {
wait = cvar.wait(wait).unwrap();
}
// Exit the loop when we're asked to. Given that we poll
// only once we can take the `prepare_read`, but in some cases
// it could be not possible, we may block on `join`.
if *wait == PumpEventNotifierAction::Shutdown {
break 'outer;
}
// Wake-up the main loop and put this one back to sleep.
*wait = PumpEventNotifierAction::Pause;
drop(wait);
@@ -797,4 +805,6 @@ enum PumpEventNotifierAction {
Monitor,
/// Pause monitoring.
Pause,
/// Shutdown the thread.
Shutdown,
}

View File

@@ -194,7 +194,7 @@ impl PointerHandler for WinitState {
pointer_data.phase = phase;
// Mice events have both pixel and discrete delta's at the same time. So prefer
// the descrite values if they are present.
// the discrete values if they are present.
let delta = if has_discrete_scroll {
// NOTE: Wayland sign convention is the inverse of winit.
MouseScrollDelta::LineDelta(

View File

@@ -51,7 +51,7 @@ where
}
impl XConnection {
// This is impoartant, so pay attention!
// This is important, so pay attention!
// Xlib has an output buffer, and tries to hide the async nature of X from you.
// This buffer contains the requests you make, and is flushed under various circumstances:
// 1. `XPending`, `XNextEvent`, and `XWindowEvent` flush "as needed"

View File

@@ -79,7 +79,7 @@ impl XConnection {
.iter()
// XRROutputInfo contains an array of mode ids that correspond to
// modes in the array in XRRScreenResources
.filter(|x| output_modes.iter().any(|id| x.id == *id))
.filter(|x| output_modes.contains(&x.id))
.map(|mode| {
VideoModeHandle {
size: (mode.width.into(), mode.height.into()),

View File

@@ -976,8 +976,8 @@ impl UnownedWindow {
let vert_atom = atoms[_NET_WM_STATE_MAXIMIZED_VERT];
match state {
Ok(atoms) => {
let horz_maximized = atoms.iter().any(|atom: &xproto::Atom| *atom == horz_atom);
let vert_maximized = atoms.iter().any(|atom: &xproto::Atom| *atom == vert_atom);
let horz_maximized = atoms.contains(&horz_atom);
let vert_maximized = atoms.contains(&vert_atom);
horz_maximized && vert_maximized
},
_ => false,

View File

@@ -132,7 +132,13 @@ fn should_apps_use_dark_mode() -> bool {
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());
// We won't try to do anything for windows versions < 17763
// (Windows 10 October 2018 update)
if !*DARK_MODE_SUPPORTED {
return None;
}
let module = LoadLibraryA("uxtheme.dll\0".as_ptr().cast());
if module == 0 {
return None;

View File

@@ -213,8 +213,7 @@ impl KeyEventBuilder {
.unwrap_or(false);
if more_char_coming {
// No need to produce an event just yet, because there are still more
// characters that need to appended to this keyobard
// event
// characters that need to be appended to this keyboard event
MatchResult::TokenToRemove(pending_token)
} else {
let mut event_info = self.event_info.lock().unwrap();
@@ -335,8 +334,8 @@ impl KeyEventBuilder {
// 1. If caps-lock is *not* held down but *is* active, then we have to synthesize all
// printable keys, respecting the caps-lock state.
// 2. If caps-lock is held down, we could choose to synthesize its keypress after every
// other key, in which case all other keys *must* be sythesized as if the caps-lock state
// was be the opposite of what it currently is.
// other key, in which case all other keys *must* be synthesized as if the caps-lock
// state was be the opposite of what it currently is.
// --
// For the sake of simplicity we are choosing to always synthesize
// caps-lock first, and always use the current caps-lock state

View File

@@ -225,16 +225,16 @@ pub fn get_keyboard_physical_key(keyboard: RAWKEYBOARD) -> Option<PhysicalKey> {
if scancode == 0xe11d || scancode == 0xe02a {
// At the hardware (or driver?) level, pressing the Pause key is equivalent to pressing
// Ctrl+NumLock.
// This equvalence means that if the user presses Pause, the keyboard will emit two
// This equivalence means that if the user presses Pause, the keyboard will emit two
// subsequent keypresses:
// 1, 0xE11D - Which is a left Ctrl (0x1D) with an extension flag (0xE100)
// 2, 0x0045 - Which on its own can be interpreted as Pause
//
// There's another combination which isn't quite an equivalence:
// PrtSc used to be Shift+Asterisk. This means that on some keyboards, presssing
// PrtSc used to be Shift+Asterisk. This means that on some keyboards, pressing
// PrtSc (print screen) produces the following sequence:
// 1, 0xE02A - Which is a left shift (0x2A) with an extension flag (0xE000)
// 2, 0xE037 - Which is a numpad multiply (0x37) with an exteion flag (0xE000). This on
// 2, 0xE037 - Which is a numpad multiply (0x37) with an extension flag (0xE000). This on
// its own it can be interpreted as PrtSc
//
// For this reason, if we encounter the first keypress, we simply ignore it, trusting

View File

@@ -228,31 +228,31 @@ pub type GetDpiForMonitor = unsafe extern "system" fn(
pub type EnableNonClientDpiScaling = unsafe extern "system" fn(hwnd: HWND) -> BOOL;
pub type AdjustWindowRectExForDpi = unsafe extern "system" fn(
rect: *mut RECT,
dwStyle: u32,
bMenu: BOOL,
dwExStyle: u32,
dw_style: u32,
b_menu: BOOL,
dw_ex_style: u32,
dpi: u32,
) -> BOOL;
pub type GetPointerFrameInfoHistory = unsafe extern "system" fn(
pointerId: u32,
entriesCount: *mut u32,
pointerCount: *mut u32,
pointerInfo: *mut POINTER_INFO,
pointer_id: u32,
entries_count: *mut u32,
pointer_count: *mut u32,
pointer_info: *mut POINTER_INFO,
) -> BOOL;
pub type SkipPointerFrameMessages = unsafe extern "system" fn(pointerId: u32) -> BOOL;
pub type SkipPointerFrameMessages = unsafe extern "system" fn(pointer_id: u32) -> BOOL;
pub type GetPointerDeviceRects = unsafe extern "system" fn(
device: HANDLE,
pointerDeviceRect: *mut RECT,
displayRect: *mut RECT,
pointer_device_rect: *mut RECT,
display_rect: *mut RECT,
) -> BOOL;
pub type GetPointerTouchInfo =
unsafe extern "system" fn(pointerId: u32, touchInfo: *mut POINTER_TOUCH_INFO) -> BOOL;
unsafe extern "system" fn(pointer_id: u32, touch_info: *mut POINTER_TOUCH_INFO) -> BOOL;
pub type GetPointerPenInfo =
unsafe extern "system" fn(pointId: u32, penInfo: *mut POINTER_PEN_INFO) -> BOOL;
unsafe extern "system" fn(point_id: u32, pen_info: *mut POINTER_PEN_INFO) -> BOOL;
pub(crate) static GET_DPI_FOR_WINDOW: Lazy<Option<GetDpiForWindow>> =
Lazy::new(|| get_function!("user32.dll", GetDpiForWindow));