This allows the user more control over how they pass their application state
to Winit, and will hopefully allow `Drop` implementations on the application
handler to work in the future on all platforms.
Let the users wake up the event loop and then they could poll their
user sources.
Co-authored-by: Mads Marquart <mads@marquart.dk>
Co-authored-by: daxpedda <daxpedda@gmail.com>
There are AV rules out there which cause almost any
program that contains github URLs to become marked as malware.
While those rules are spurious, they're years old, and AV vendors have a
very poor reputation at appropriately following up with these problems.
Remove these strings from the panic data present in the binary
prevents binaries linking the winit from being spuriously marked as
Trojan:Win32/Wacatac.B!ml.
Tracing is a modern replacement for the log crate that allows for
annotating log messages with the function that they come from.
Signed-off-by: John Nunley <dev@notgull.net>
Closes: #3482
Removes the once_cell dependency, instead using std::sync::OnceLock and a
minimal polyfill for std::sync::LazyLock, which may be stabilized soon
(see rust-lang/rust#121377).
This should not require a bump in MSRV, as OnceLock was stabilized in 1.70,
which this crate is using.
Replace the `CustomCursorBuilder` with the `CustomCursorSource` and
perform the loading of the cursor via the
`EventLoop::create_custom_cursor` instead of passing it to the builder
itself.
This follows the `EventLoop::create_window` API.
Creating window when event loop is not running generally doesn't work,
since a bunch of events and sync OS requests can't be processed. This
is also an issue on e.g. Android, since window can't be created outside
event loop easily.
Thus deprecate the window creation when event loop is not running,
as well as other resource creation to running event loop.
Given that all the examples use the bad pattern of creating the window
when event loop is not running and also most example existence is
questionable, since they show single thing and the majority of their
code is window/event loop initialization, they wore merged into
a single example 'window.rs' example that showcases very simple
application using winit.
Fixes#3399.
Mainly fix typos in comments, but also some minor code changes:
* Rename `apply_on_poiner` to `apply_on_pointer`.
* Rename `ImeState::Commited` to `ImeState::Committed`
* Correct `cfg_attr` usage: `wayland_platfrom` -> `wayland_platform`.
This was supposed to be rolled out with the rwh v0.6 update, but it
was left behind for some reason. I've added this type back.
Signed-off-by: John Nunley <dev@notgull.net>
* make `EventLoopWindowTarget` independent of UserEvent type
the `EventLoopWindowTarget` is needed for window creation. conceptually,
only `EventLoop` and `EventLoopProxy` need to be parameterized, and all
other parts of the backend should be agnostic about the user event type,
parallel to how `Event<T>` is parameterized, but `WindowEvent` is not.
this change removes the dependency on the type of user events from the
`EventLoopWindowTarget` for the Windows backend, but keep a phantom data
to keep the API intact. to achieve this, I moved the `Receiver` end of
the mpsc channel from `ThreadMsgTargetData` into `EventLoop` itself, so
the `UserEvent` is only passed between `EventLoop` and `EventLoopProxy`,
all other part of the backend just use unit type as a placeholder for
user events.
it's similar to the macos backend where an erased `EventHandler` trait
object is used so all component except `EventLoop` and `EventLoopProxy`
need to be parameterized. however `EventLoop` of the Windows backend
already use an `Box<dyn FnMut>` to wrap the user provided event handler
callback, so no need for an dedicated trait object, I just modified the
wrapper to replace the placeholder user event with real value pulled
from the channel. I find this is the approach which need minimum change
to be made to existing code. but it does the job and could serve as a
starting point to future Windows backend re-works.
* fix CI clippy failure.
* make UserEventPlaceholder a new type instead of alias
* invariance is maintained by top-level EventLoopWindowTarget<T>
this field is transitional and her to keep API compatibility only.
the correct variance and such is already ensured by the top-level
`EventLoopWindowTarget`, just use `PhantomData<T>` here.
There seems to be many PRs relating to this issue, but they don't include all
platforms and for some reason lost steam. This PR again tries to make this
feature happen, and does it for all desktop platforms (x11, wayland, macos,
windows, web).
I think the best user of this feature and the reason I'm doing this is Bevy and
game engines in general. There non laggy hardware cursors with custom images are
very important. Game devs also like their PNGs so supporting platform native
cursor files is not that important, but I guess could be added too.
Co-authored-by: daxpedda <daxpedda@gmail.com>
Co-authored-by: Mads Marquart <mads@marquart.dk>
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
While working with device events, I noticed that there was an inconsistency in the mouse button device events between Windows/X11 and for example web, because web uses the same ids/order as the MouseButton enum, and Windows/X11 are using the X11 ids, and hwheel device event was ignored on Windows.
Mouse button device events are now using the same order as the MouseButton enum, and I also added hwheel device events for Windows.
When calling `Window::request_redraw` from the `RedrawRequested`
handler the `RedrawWindow` won't result in `WM_PAINT` being delivered
due since user callback is run before `DefWindowProcW` is called.
Track whether the user called `Window::request_redraw` and ask for
`RedrawWindow` after running the said function during `WM_PAINT`
handling.
Fixes#3150.
Split `Key` into clear categories, like `Named`, `Dead`, Character`, `Unidentified`
removing the `#[non_exhaustive]` from the `Key` itself.
Similar action was done for the `KeyCode`.
Fixes: #2995
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
Inner panics could make it hard to trouble shoot the issues and for some
users it's not desirable.
The inner panics were left only when they are used to `assert!` during
development.
This reverts commit 9f91bc413fe20618bd7090829832bb074aab15c3 which
reverted the original patch which was merged without a proper review.
Fixes: #500.
Inner panics could make it hard to trouble shoot the issues and for some
users ints not desirable.
The inner panics were left only when they are used to `assert!` during
development.
There's no need to force the static on the users, given that internally
some backends were not using static in the first place.
Co-authored-by: daxpedda <daxpedda@gmail.com>
Lifetimes don't work nicely when dealing with multithreaded environments
in the current design of the existing winit's event handling model, so
remove it in favor of `InnerSizeWriter` fences passed to client, so they
could try to update the size.
Fixes#1387.
The idea that redraw events are dispatched with a specific ordering
that makes it possible to specifically report when we have finished
dispatching redraw events isn't portable and the way in which we
dispatched RedrawEventsCleared was inconsistent across backends.
More generally speaking, there is no inherent relationship between
redrawing and event loop iterations. An event loop may wake up at any
frequency depending on what sources of input events are being listened
to but redrawing is generally throttled and in some way synchronized
with the display frequency.
Similarly there's no inherent relationship between a single event loop
iteration and the dispatching of any specific kind of "main" event.
An event loop wakes up when there are events to read (e.g. input
events or responses from a display server / compositor) and goes back
to waiting when there's nothing else to read.
There isn't really a special kind of "main" event that is dispatched
in order with respect to other events.
What we can do more portably is emit an event when the event loop
is about to block and wait for new events.
In practice this is very similar to how MainEventsCleared was
implemented except it wasn't the very last event previously since
redraw events could be dispatched afterwards.
The main backend where we don't strictly know when we're going to
wait for events is Web (since the real event loop is internal to
the browser). For now we emulate AboutToWait on Web similar to how
MainEventsCleared was dispatched.
In practice most applications almost certainly shouldn't care about
AboutToWait because the frequency of event loop iterations is
essentially arbitrary and usually irrelevant.
Considering the possibility of re-running an event loop via run_ondemand
then it's more correct to say that the loop is about to exit without
assuming it's going to be destroyed.
This renames all internal implementations of pump_events_with_timeout
to pump_events and makes them public.
Since all platforms that support pump_events support timeouts there's
no need to have a separate API.
This re-works the portable `run()` API that consumes the `EventLoop` and
runs the loop on the calling thread until the app exits.
This can be supported across _all_ platforms and compared to the
previous `run() -> !` API is now able to return a `Result` status on all
platforms except iOS and Web. Fixes: #2709
By moving away from `run() -> !` we stop calling `std::process::exit()`
internally as a means to kill the process without returning which means
it's possible to return an exit status and applications can return from
their `main()` function normally.
This also fixes Android support where an Activity runs in a thread but
we can't assume to have full ownership of the process (other services
could be running in separate threads).
Additionally all examples have generally been updated so that `main()`
returns a `Result` from `run()`
Fixes: #2709
A surprising amount of work was required to enable these extensions
on Windows.
I had originally assumed that pump_events was going to be very similar
to run except would use PeekMessageW instead of GetMessageW to avoid
blocking the external loop but I found the Windows backend broke
several assumptions I had.
Overall I think these changes can hopefully be considered a quite a
significant simplification (I think it's a net deletion of a fair amount
of code) and I think it also helps bring it into slightly closer alignment
with other backends too
Key changes:
- I have removed the `wait_thread` that was a fairly fiddly way of handling
`ControlFlow::WaitUntil` timeouts in favor of using `SetTimer` which works
with the same messages picked up by `GetMessage` and `PeekMessage`.
- I have removed the ordering guarantees between `MainEventsCleared`,
`RedrawRequested` and `RedrawEventsCleared` events due to the complexity in
maintaining this artificial ordering, which is already not supported
consistently across backends anyway (in particular this ordering already
isn't compatible with how MacOS / iOS work).
- `RedrawRequested` events are now directly dispatched via `WM_PAINT` messages
- comparable to how `RedrawRequested` is dispatched via `drawRect` in the
MacOS backend.
- I have re-worked how `NewEvents`, `MainEventsCleared`, and `RedrawEventsCleared`
get dispatched to be more in line with the MacOS backend and also more in line
with how we have recently discussed defining them for all platforms.
`NewEvents` is conceptually delivered when the event loop "wakes up" and
`MainEventsCleared` gets dispatched when the event loop is about to ask the
OS to wait for new events.
This is a more portable model, and is already how these events work in the
MacOS backend.
`RedrawEventsCleared` are just delivered after `MainEventsCleared` but this
event no longer has a useful meaning.
Probably the most controversial thing here is that this "breaks" the ordering
rules for redraw event handling, but since my changes interacted with how the
order is maintained I was very reluctant to figure out how to continue
maintaining something that we have recently been discussing changing:
https://github.com/rust-windowing/winit/issues/2640.
Additionally, since the MacOS backend already doesn't strictly maintain this
order it's somewhat academic to see this as a breakage if Winit applications
can't really rely on it already.
This updates the documentation for `request_redraw()` to reflect that we
no longer guarantee that `RedrawRequested` events must be dispatched
after `MainEventsCleared`.