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.
The `text` is retrieved as UTF-8 while `attributes` are based on UTF-16,
thus the offset was getting out of sync on some unicode payloads
like surrogate pairs.
Fixes#3967.
iOS parts of #3758.
This allows the user to override the application delegate themselves,
which opens several doors for customization that were previously closed.
To do this, we use notifications instead of a top-level application
delegate.
One effect of not providing an application delegate on iOS is that we no
longer act as-if the application successfully open all URLs there.
This is a breaking change, although unlikely to matter in practice,
since the return value of `application:didFinishLaunchingWithOptions:`
is seldom used by the system (and this is likely the preferred behaviour
anyhow).
This is done to avoid order-dependent behavior that you'd otherwise
encounter where `EventLoop::new` had to be called at the beginning of
`fn main` to ensure that Winit's application was the one being
registered as the main application by calling `sharedApplication`.
Fixes https://github.com/rust-windowing/winit/issues/3772.
This should also make it (more) possible to use multiple versions of
Winit in the same application (though that's still untested).
Finally, it should allow the user to override `NSApplication` themselves
if they need to do that for some reason.
Only mark that the grab was applied when it actually got applied.
Previously there was an issue with grab being marked as applied without
a pointer over the window, when in reality it wasn't.
Fixes#4073.
Using `Duration::Zero` with `Wait` polling mode was still blocking until
the event was actually delivered. Thus when `pump_events` API is used,
ensure that it's not happening.
Fixes#4130.
* Prevent panic when calling set_simple_fullscreen(false) on macos
Calling `set_simple_fullscreen(false)` to restore the window after
a previous call to `set_simple_fullscreen(true)` panics with
`view must be installed in a window` in the call to `set_style_mask`
with the old style.
Moving the `set_style_mask` call after the frame has been resized
fixes the issue.
* Hide the doc and menubar on macos when using set_borderless_game
with set_simple_fullscreen
* Fix a pause in the event loop when clicking the title bar on windows
When clicking the title bar on Windows, to drag the window, there is
a noticible pause in continuous redraw requests. This was fixed
in #839 and then regressed in #1852. The cursor blinks in both
cases and is unrelated. The regression made the blink happen after
the pause instead of immediately.
* Update the event loop pause note on the WM_NCLBUTTONDOWN handler
The application example was also updated to optionally animate the fill color
in order to demonstrate continuous redraw without pauses in the event
loop.
The serial was not unique, thus leading to issues and replay being
triggered for normal input. Track modifiers based on they keycodes
instead, since it's more unique.
Links: https://github.com/alacritty/alacritty/issues/8461
Let's just not forward events to the IME once the user requested that
it should be disabled, though, still try to change its state explicitly.
Fixes#4082.
When all we'll be doing is setting a new preedit, the preedit doesn't
have to be explicitly cleared first. This change is perhaps debatable.
The direct reason for this is to make it easier to work around
quirks/bugs: in Masonry we've found IBus appears to resend
the IME preedit in response to `Window::set_ime_cursor_area`
(`zwp_text_input_v3::set_cursor_rectangle`). Because currently the
preedit is first cleared, a new IME cursor area is sent, which again
causes IBus to resend the preedit. This can loop for a while.
The Wayland protocol is mechanically quite prescriptive,
it says for zwp_text_input_v3:event:done.
> 1. Replace existing preedit string with the cursor.
> 2. Delete requested surrounding text.
> 3. Insert commit string with the cursor at its end.
> 4. Calculate surrounding text to send.
> 5. Insert new preedit text in cursor position.
> 6. Place cursor inside preedit text.
Winit currently doesn't do surrounding text, so 2. and 4. can be
ignored. In Winit's IME model, without a commit, sending just the
`Ime::Preedit` event without explicitly clearing is arguably still
equivalent to doing 1., 5., and 6.
This no longer exposes `CGDisplayCreateUUIDFromDisplayID` and instead
uses `CFUUID` to avoid a leak.
Monitor comparisons should also be more stable now.
`AnyClass::responds_to` delegates to `class_respondsToSelector`, a
function provided by the Objective-C runtime. However, at some point,
this began to return `false` for selectors referring to undocumented
cursors, despite the cursors remaining accessible via said selectors.
That this check fails prevents the cursors from being used.
We can instead send `respondsToSelector:` to the `NSCursor` class
itself. As an instance method, this is nominally impossible; however,
Apple grants an exemption[1] that permits class objects to perform
instance methods defined in the root class.
Checking for the undocumented cursors in this way gets them working
again, at least on macOS Sequoia 15.1.1.
[1]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-TPXREF120
Events emitted by `flagsChanged:` cannot access
`charactersIgnoringModifiers`. We were previously doing this because we
were trying to re-use the `create_key_event` function, but that is unsuited
for this purpose, so I have separated the `flagsChanged:` logic out from it.
This implements basic iOS IME support (typing, backspace, support for emojis
etc but no autocomplete or copy / paste menu).
Co-authored-by: Mads Marquart <mads@marquart.dk>
Based on https://github.com/rust-windowing/winit/pull/3973, which should
be merged first.
There's an API to programmatically specify X11 screen id (override what
is determined from the `DISPLAY` env variable), but it doesn't work.
Seeting up X Server with 2 screens and calling `DISPLAY=:0
X11_SCREEN_ID=1 cargo run --example window` should be equivalent to
calling `DISPLAY=:0.1 cargo run --example window`
The latter works (and places the window on the correct screen), but the
former yields
`failed to create initial window: Os(OsError { line: 620, file:
"src/platform_impl/linux/x11/window.rs", error: X11Error(X11Error {
error_kind: Match, error_code: 8, sequence: 219, bad_value: 1319,
minor_opcode: 0, major_opcode: 1, extension_name: None, request_name:
Some("CreateWindow") }) })`
_Here `1319` is the root window id for screen 0, which doesn't match the
screen 1 that we request._
The problem is that we need to factor in the screen id when determining
the parent (root) window when not explicitly set. This patch does that.
---
Also: Extend the window example with X11_{SCREEN,VISUAL}_ID env variables
Previous version used [`SetTimer`] with `GetMessageW` for waiting.
The downside of UI timers like ones created by `SetTimer`,
is that they may be late by up to 15-16 ms.
To fix this behaviour, I added use of high resolution timers created by
[`CreateWaitableTimerExW`] with the flag
`CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`.
In my previous experience, waiting on such timers have precision of
roundly 0.5 ms which is the best available on Windows at the moment. I
use [`MsgWaitForMultipleObjectsEx`] to wait simultaneously for both
timer and newly arriving events.
Unfortunately, high resolution timers are available only since Windows
10 1803. However:
1. Win 10 is already getting to the end of support, like all previous
versions, so it is OK to rely on APIs introduced in it;
2. I use `dwMilliseconds` parameter of `MsgWaitForMultipleObjectsEx` as
a fallback. It should perform not worse compared to waiting for
events from `SetTimer`.
I also refactored code to remove event dispatching from function
responsible for waiting for events. This provides more clear separations
of concern and avoids unnecessary duplication of dispatching logic.
After [review] from @rib, I also moved the waiting itself from
`wait_for_messages` method to separate function, so it is clearly seen
that `wait_for_messages` do 3 things: notify app that we about to wait,
wait, notify that we have new events.
I have tested behaviour using a egui app with Vulkan rendering with
`VK_PRESENT_MODE_IMMEDIATE_KHR`, and older version consistently have
twice less FPS than requested (e.g. 30 FPS when limit is 60 and 60 FPS
when limit is 120) while newer version works more correctly (almost
always 60 FPS when limit is 60, and only 5-10 frames missing when FPS is
set to 120 or more).
Fixes https://github.com/rust-windowing/winit/issues/1610
[`CreateWaitableTimerExW`]: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createwaitabletimerexw
[`MsgWaitForMultipleObjectsEx`]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-msgwaitformultipleobjectsex
[`SetTimer`]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer
[review]: https://github.com/rust-windowing/winit/pull/3950#discussion_r1800184479