mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-26 22:53:15 -04:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6893a4390 | ||
|
|
c0a8bedee2 | ||
|
|
b248ecba31 | ||
|
|
b49d34ebf0 | ||
|
|
cc43ea13d9 | ||
|
|
911fad0af0 | ||
|
|
2191eacfc8 | ||
|
|
f7ac8127e3 | ||
|
|
bd2b5cda8d | ||
|
|
3930a6334f | ||
|
|
17b5737972 | ||
|
|
f49a2a1827 |
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "winit"
|
||||
version = "0.30.10"
|
||||
version = "0.30.12"
|
||||
authors = [
|
||||
"The winit contributors",
|
||||
"Pierre Krieger <pierre.krieger1708@gmail.com>",
|
||||
@@ -119,7 +119,7 @@ ndk = { version = "0.9.0", default-features = false }
|
||||
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
|
||||
block2 = "0.5.1"
|
||||
core-foundation = "0.9.3"
|
||||
objc2 = "0.5.2"
|
||||
objc2 = { version = "0.5.2", features = ["relax-sign-encoding"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-graphics = "0.23.1"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
winit = "0.30.10"
|
||||
winit = "0.30.12"
|
||||
```
|
||||
|
||||
## [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
|
||||
|
||||
@@ -40,8 +40,10 @@ multiple-versions = "deny"
|
||||
skip = [
|
||||
{ crate = "raw-window-handle", reason = "we depend on multiple behind features" },
|
||||
{ crate = "bitflags@1", reason = "the ecosystem is in the process of migrating" },
|
||||
{ crate = "rustix@0.38", reason = "the ecosystem is in the process of migrating" },
|
||||
{ crate = "linux-raw-sys@0.4", reason = "the ecosystem is in the process of migrating" },
|
||||
]
|
||||
wildcards = "allow" # at least until https://github.com/EmbarkStudios/cargo-deny/issues/241 is fixed
|
||||
wildcards = "allow" # at least until https://github.com/EmbarkStudios/cargo-deny/issues/241 is fixed
|
||||
|
||||
[bans.build]
|
||||
include-archives = true
|
||||
@@ -53,6 +55,10 @@ allow = [
|
||||
]
|
||||
crate = "android-activity"
|
||||
|
||||
[[bans.build.bypass]]
|
||||
allow-globs = ["ci/*", "githooks/*"]
|
||||
crate = "zerocopy"
|
||||
|
||||
[[bans.build.bypass]]
|
||||
allow-globs = ["freetype2/*"]
|
||||
crate = "freetype-sys"
|
||||
|
||||
@@ -39,3 +39,7 @@ The migration guide could reference other migration examples in the current
|
||||
changelog entry.
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Fixed
|
||||
|
||||
- On macOS, fix crash on macOS 26 by using objc2's `relax-sign-encoding` feature.
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
- On Web, fix some `WindowBuilder` methods doing nothing.
|
||||
- On Web, fix some `Window` methods using incorrect HTML attributes instead of CSS properties.
|
||||
- On Web, fix the bfcache by not using the `beforeunload` event and map bfcache loading/unloading to `Suspended`/`Resumed` events.
|
||||
- On Web, fix touch input not gaining or loosing focus.
|
||||
- On Web, fix touch input not gaining or losing focus.
|
||||
- On Web, fix touch location to be as accurate as mouse position.
|
||||
- On Web, handle coalesced pointer events, which increases the resolution of pointer inputs.
|
||||
- On Web, implement `Window::focus_window()`.
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
## 0.30.12
|
||||
|
||||
### Fixed
|
||||
|
||||
- On macOS, fix crash on macOS 26 by using objc2's `relax-sign-encoding` feature.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![warn(clippy::uninlined_format_args)]
|
||||
// TODO: wasm-binding needs to be updated for that to be resolved, for now just silence it.
|
||||
#![cfg_attr(web_platform, allow(unknown_lints, wasm_c_abi))]
|
||||
#![cfg_attr(web_platform, allow(unknown_lints, renamed_and_removed_lints, wasm_c_abi))]
|
||||
|
||||
#[cfg(feature = "rwh_04")]
|
||||
pub use rwh_04 as raw_window_handle_04;
|
||||
|
||||
@@ -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.12",
|
||||
//! 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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ impl Dispatch<WlKeyboard, KeyboardData, WinitState> for WinitState {
|
||||
WlKeyboardEvent::Leave { surface, .. } => {
|
||||
let window_id = wayland::make_wid(&surface);
|
||||
|
||||
// NOTE: we should drop the repeat regardless whethere it was for the present
|
||||
// NOTE: we should drop the repeat regardless whether it was for the present
|
||||
// window of for the window which just went gone.
|
||||
keyboard_state.current_repeat = None;
|
||||
if let Some(token) = keyboard_state.repeat_token.take() {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -738,7 +738,7 @@ fn wait_for_messages_impl(
|
||||
|
||||
unsafe {
|
||||
// Either:
|
||||
// 1. User wants to wait indefinely if timeout is not set.
|
||||
// 1. User wants to wait indefinitely if timeout is not set.
|
||||
// 2. We failed to get and set high resolution timer and we need something instead of it.
|
||||
let wait_duration_ms = timeout.map(dur2timeout).unwrap_or(INFINITE);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -466,7 +465,7 @@ enum PartialText {
|
||||
|
||||
enum PartialLogicalKey {
|
||||
/// Use the text provided by the WM_CHAR messages and report that as a `Character` variant. If
|
||||
/// the text consists of multiple grapheme clusters (user-precieved characters) that means that
|
||||
/// the text consists of multiple grapheme clusters (user-perceived characters) that means that
|
||||
/// dead key could not be combined with the second input, and in that case we should fall back
|
||||
/// to using what would have without a dead-key input.
|
||||
TextOr(Key),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user