Skip to content

Support external event loop providers - #4818

Open
richerfu wants to merge 2 commits into
rust-windowing:masterfrom
richerfu:feat/event-loop-provider
Open

richerfu wants to merge 2 commits into
rust-windowing:masterfrom
richerfu:feat/event-loop-provider

Conversation

@richerfu

@richerfu richerfu commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Winit currently selects its event loop from built-in backends, so an external
backend cannot use the winit::EventLoop facade. This adds from_backend and
from_boxed_backend so backend crates can integrate without becoming Winit
dependencies, including on targets with no built-in backend.

This follows the proposal to keep backends out of tree and share the necessary
types through winit-core, discussed in
#4684.

The provider trait becomes dyn-compatible through a single owning run_app
entry point. EventLoop and concrete built-in backends retain their generic
run_app(app) methods. Optional capabilities cover event pumping, on-demand
execution, callback registration, never-return execution, and Unix file
descriptors. Unsupported owning conversions return the original provider so
callers can fall back without losing configuration. Backend access and
downcasting support platform-specific extensions.

Provider implementations must update run_app to accept self: Box<Self> and
Box<dyn ApplicationHandler>, and implement into_register and
into_never_return (returning Err(self) when unsupported). Existing infallible
extension methods retain their signatures; callers selecting providers
dynamically should query the corresponding capability first.

Validation completed locally:

  • cargo test -p winit -p winit-core, including 19 provider integration tests
    covering dispatch, capability fallback, ownership, and callback lifetimes.
  • Clippy for both crates and all host targets with warnings denied; rustdoc
    with warnings denied; nightly rustfmt, Taplo, and spelling checks.
  • Library compilation for Windows, Web, iOS, Android, Linux (default, X11,
    Wayland, and no built-in backend), and OHOS with no built-in backend.
  • An external OHOS backend integration fixture compiled against this API.

Runtime tests were run on macOS. Cross-target checks are compile-only; Redox
was not checked locally. CI adds a generic external-provider test on Ubuntu.

  • Tested on all platforms changed
  • Added an entry to the changelog module if knowledge of this change could
    be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes
    of platform-specific behavior
  • Created or updated an example program if it would help users understand
    this functionality (usage is covered by rustdoc examples and integration
    tests)

Make EventLoopProvider dyn-compatible with a single owning run_app entry point and allow EventLoop to accept concrete or boxed providers.

Expose optional pumping, on-demand, registration, never-return and file-descriptor capabilities. Preserve unsupported providers for fallback and expose backend-specific access through downcasting. Adapt built-in backends while retaining their generic convenience APIs.

Support configurations without a built-in backend and cover dispatch, ownership and callback lifetimes with integration tests and CI.

@kchibisov kchibisov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the main issue for external integration at this point is generic, which I understand why is getting removed, if it's getting removed, all should be gone together and moved to some dyn.

cc @ogoffart @timon-schelling this is maybe one of the last API changes I'd consider for 0.31 that maybe would be nice to merge, so would like to know what you think about proposed approach here and if it makes sense.

Comment thread winit-core/src/event_loop/mod.rs Resolved
Comment thread .github/workflows/ci.yml Resolved
Comment thread winit-core/src/event_loop/mod.rs Resolved
Comment thread winit-core/src/event_loop/mod.rs Resolved
Comment thread winit-core/src/event_loop/mod.rs Resolved
Comment thread winit/tests/external_provider.rs Resolved
Comment thread winit/src/event_loop.rs Resolved
Comment thread winit/src/event_loop.rs Resolved
Comment thread winit/src/event_loop.rs Resolved
Comment thread winit/src/event_loop.rs Resolved
Switch EventLoop::run_app, EventLoop::from_backend, and the EventLoopExtPumpEvents, EventLoopExtRunOnDemand, EventLoopExtRegister, and EventLoopExtNeverReturn traits to accept dyn ApplicationHandler and dyn EventLoopProvider directly instead of duplicating generic traits.

Implement HasDisplayHandle on dyn EventLoopProvider via rwh_06_handle, removing the cached OwnedDisplayHandle in EventLoop and allowing is_wayland/is_x11 to inspect DisplayHandle directly. Drop forwarding AsFd/AsRawFd and EventLoopExt* impls on EventLoop in favor of the explicit *_ext/into_* accessors, and simplify platform_impl creation.

Replace the synthetic external_provider mock test with a custom_backend example and fold the --no-default-features test into the main CI matrix.
@richerfu
richerfu force-pushed the feat/event-loop-provider branch from 93e8401 to 44f5312 Compare November 11, 2026 02:17
@richerfu
richerfu requested a review from kchibisov November 11, 2026 07:33

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants