winit/lib.rs
1//! Winit is a cross-platform window creation and event loop management library.
2//!
3//! # Building windows
4//!
5//! Before you can create a [`Window`], you first need to build an [`EventLoop`]. This is done with
6//! the [`EventLoop::new()`] function.
7//!
8//! ```no_run
9//! use winit::event_loop::EventLoop;
10//! let event_loop = EventLoop::new().unwrap();
11//! ```
12//!
13//! Then you create a [`Window`] with [`create_window`].
14//!
15//! # Event handling
16//!
17//! Once a [`Window`] has been created, it will generate different *events*. A [`Window`] object can
18//! generate [`WindowEvent`]s when certain input events occur, such as a cursor moving over the
19//! window or a key getting pressed while the window is focused. Devices can generate
20//! [`DeviceEvent`]s, which contain unfiltered event data that isn't specific to a certain window.
21//! Some user activity, like mouse movement, can generate both a [`WindowEvent`] *and* a
22//! [`DeviceEvent`].
23//!
24//! You can retrieve events by calling [`EventLoop::run_app()`]. This function will
25//! dispatch events for every [`Window`] that was created with that particular [`EventLoop`], and
26//! will run until [`exit()`] is used, at which point [`exiting()`] is called.
27//!
28//! Winit no longer uses a `EventLoop::poll_events() -> impl Iterator<Event>`-based event loop
29//! model, since that can't be implemented properly on some platforms (e.g Web, iOS) and works
30//! poorly on most other platforms. However, this model can be re-implemented to an extent with
31#![cfg_attr(
32 any(windows_platform, macos_platform, android_platform, x11_platform, wayland_platform),
33 doc = "[`EventLoopExtPumpEvents::pump_app_events()`][platform::pump_events::EventLoopExtPumpEvents::pump_app_events()]"
34)]
35#![cfg_attr(
36 not(any(windows_platform, macos_platform, android_platform, x11_platform, wayland_platform)),
37 doc = "`EventLoopExtPumpEvents::pump_app_events()`"
38)]
39//! [^1]. See that method's documentation for more reasons about why
40//! it's discouraged beyond compatibility reasons.
41//!
42//!
43//! ```no_run
44//! use winit::application::ApplicationHandler;
45//! use winit::event::WindowEvent;
46//! use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
47//! use winit::window::{Window, WindowId, WindowAttributes};
48//!
49//! #[derive(Default)]
50//! struct App {
51//! window: Option<Box<dyn Window>>,
52//! }
53//!
54//! impl ApplicationHandler for App {
55//! fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
56//! self.window = Some(event_loop.create_window(WindowAttributes::default()).unwrap());
57//! }
58//!
59//! fn window_event(&mut self, event_loop: &dyn ActiveEventLoop, id: WindowId, event: WindowEvent) {
60//! match event {
61//! WindowEvent::CloseRequested => {
62//! println!("The close button was pressed; stopping");
63//! event_loop.exit();
64//! },
65//! WindowEvent::RedrawRequested => {
66//! // Redraw the application.
67//! //
68//! // It's preferable for applications that do not render continuously to render in
69//! // this event rather than in AboutToWait, since rendering in here allows
70//! // the program to gracefully handle redraws requested by the OS.
71//!
72//! // Draw.
73//!
74//! // Queue a RedrawRequested event.
75//! //
76//! // You only need to call this if you've determined that you need to redraw in
77//! // applications which do not always need to. Applications that redraw continuously
78//! // can render here instead.
79//! self.window.as_ref().unwrap().request_redraw();
80//! }
81//! _ => (),
82//! }
83//! }
84//! }
85//!
86//! let event_loop = EventLoop::new().unwrap();
87//!
88//! // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't
89//! // dispatched any events. This is ideal for games and similar applications.
90//! event_loop.set_control_flow(ControlFlow::Poll);
91//!
92//! // ControlFlow::Wait pauses the event loop if no events are available to process.
93//! // This is ideal for non-game applications that only update in response to user
94//! // input, and uses significantly less power/CPU time than ControlFlow::Poll.
95//! event_loop.set_control_flow(ControlFlow::Wait);
96//!
97//! let mut app = App::default();
98//! event_loop.run_app(&mut app);
99//! ```
100//!
101//! [`WindowEvent`] has a [`WindowId`] member. In multi-window environments, it should be
102//! compared to the value returned by [`Window::id()`] to determine which [`Window`]
103//! dispatched the event.
104//!
105//! # Drawing on the window
106//!
107//! Winit doesn't directly provide any methods for drawing on a [`Window`]. However, it allows you
108//! to retrieve the raw handle of the window and display (see the [`platform`] module and/or the
109//! [`raw_window_handle`] and [`raw_display_handle`] methods), which in turn allows
110//! you to create an OpenGL/Vulkan/DirectX/Metal/etc. context that can be used to render graphics.
111//!
112//! Note that many platforms will display garbage data in the window's client area if the
113//! application doesn't render anything to the window by the time the desktop compositor is ready to
114//! display the window to the user. If you notice this happening, you should create the window with
115//! [`visible` set to `false`][crate::window::WindowAttributes::with_visible] and explicitly make
116//! the window visible only once you're ready to render into it.
117//!
118//! # UI scaling
119//!
120//! UI scaling is important, go read the docs for the [`dpi`] crate for an
121//! introduction.
122//!
123//! All of Winit's functions return physical types, but can take either logical or physical
124//! coordinates as input, allowing you to use the most convenient coordinate system for your
125//! particular application.
126//!
127//! Winit will dispatch a [`ScaleFactorChanged`] event whenever a window's scale factor has changed.
128//! This can happen if the user drags their window from a standard-resolution monitor to a high-DPI
129//! monitor or if the user changes their DPI settings. This allows you to rescale your application's
130//! UI elements and adjust how the platform changes the window's size to reflect the new scale
131//! factor. If a window hasn't received a [`ScaleFactorChanged`] event, its scale factor
132//! can be found by calling [`window.scale_factor()`].
133//!
134//! [`ScaleFactorChanged`]: event::WindowEvent::ScaleFactorChanged
135//! [`window.scale_factor()`]: window::Window::scale_factor
136//!
137//! # Cargo Features
138//!
139//! Winit provides the following Cargo features:
140//!
141//! * `x11` (enabled by default): On Unix platforms, enables the X11 backend.
142//! * `wayland` (enabled by default): On Unix platforms, enables the Wayland backend.
143//! * `rwh_06`: Implement `raw-window-handle v0.6` traits.
144//! * `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde).
145//! * `mint`: Enables mint (math interoperability standard types) conversions.
146//!
147//! See the [`platform`] module for documentation on platform-specific cargo
148//! features.
149//!
150//! # Platform/Architecture Support
151//!
152//! Platform support on `winit` has two tiers: Tier 1 and Tier 2.
153//!
154//! - Tier 1 is **guaranteed to work**. Targets in this tier are actively tested both in CI and by
155//! maintainers.
156//! - Tier 2 is **guaranteed to build**. Code compilation is tested in CI, but deeper testing is not
157//! done.
158//!
159//! Please open an issue if you would like to add a Tier 2 target, or if you would
160//! like a Tier 2 target moved to Tier 1.
161//!
162//! ## Tier 1 Targets
163//!
164//! |Target Name |Target Triple |APIs |
165//! |-------------------------------|------------------------------------|---------------|
166//! |32-Bit x86 Windows with MSVC |`i686-pc-windows-msvc` |Win32 |
167//! |64-Bit x86 Windows with MSVC |`x86_64-pc-windows-msvc` |Win32 |
168//! |32-Bit x86 Windows with glibc |`i686-pc-windows-gnu` |Win32 |
169//! |64-Bit x86 Windows with glibc |`x86_64-pc-windows-gnu` |Win32 |
170//! |32-Bit x86 Linux with glibc |`i686-unknown-linux-gnu` |X11, Wayland |
171//! |64-Bit x86 Linux with glibc |`x86_64-unknown-linux-gnu` |X11, Wayland |
172//! |64-Bit ARM Android |`aarch64-linux-android` |Android |
173//! |64-Bit x86 Redox OS |`x86_64-unknown-redox` |Orbital |
174//! |32-Bit x86 Redox OS |`i686-unknown-redox` |Orbital |
175//! |64-Bit ARM Redox OS |`aarch64-unknown-redox` |Orbital |
176//! |64-bit x64 macOS |`x86_64-apple-darwin` |AppKit |
177//! |64-bit ARM macOS |`aarch64-apple-darwin` |AppKit |
178//! |32-bit Wasm Web browser |`wasm32-unknown-unknown` |`wasm-bindgen` |
179//!
180//! ## Tier 2 Targets
181//!
182//! |Target Name |Target Triple |APIs |
183//! |------------------------------------|------------------------------------|---------------|
184//! |64-Bit ARM Windows with MSVC |`aarch64-pc-windows-msvc` |Win32 |
185//! |32-Bit x86 Windows 7 with MSVC |`i686-win7-windows-msvc` |Win32 |
186//! |64-Bit x86 Windows 7 with MSVC |`x86_64-win7-windows-msvc` |Win32 |
187//! |64-bit x86 Linux with Musl |`x86_64-unknown-linux-musl` |X11, Wayland |
188//! |64-bit x86 Linux with 32-bit glibc |`x86_64-unknown-linux-gnux32` |X11, Wayland |
189//! |64-bit x86 Android |`x86_64-linux-android` |Android |
190//! |64-bit x64 iOS |`x86_64-apple-ios` |UIKit |
191//! |64-bit ARM iOS |`aarch64-apple-ios` |UIKit |
192//! |64-bit ARM Mac Catalyst |`aarch64-apple-ios-macabi` |UIKit |
193//! |32-bit x86 Android |`i686-linux-android` |Android |
194//! |64-bit x86 FreeBSD |`x86_64-unknown-freebsd` |X11, Wayland |
195//! |64-bit x86 NetBSD |`x86_64-unknown-netbsd` |X11 |
196//! |32-bit x86 Linux with Musl |`i686-unknown-linux-musl` |X11, Wayland |
197//! |64-bit RISC-V Linux with glibc |`riscv64gc-unknown-linux-gnu` |X11, Wayland |
198//! |64-bit ARM Linux with glibc |`aarch64-unknown-linux-gnu` |X11, Wayland |
199//! |64-bit ARM Linux with Musl |`aarch64-unknown-linux-musl` |X11, Wayland |
200//! |64-bit PowerPC Linux with glibc |`powerpc64le-unknown-linux-gnu` |X11, Wayland |
201//! |32-Bit ARM Linux with glibc |`armv5te-unknown-linux-gnueabi` |X11, Wayland |
202//! |64-Bit Linux on IBM Supercomputers |`s390x-unknown-linux-gnu` |X11, Wayland |
203//! |32-bit ARM Android |`arm-linux-androideabi` |Android |
204//! |64-bit SPARC Linux with glibc |`sparc64-unknown-linux-gnu` |X11, Wayland |
205//!
206//! [`EventLoop`]: event_loop::EventLoop
207//! [`EventLoop::new()`]: event_loop::EventLoop::new
208//! [`EventLoop::run_app()`]: event_loop::EventLoop::run_app
209//! [`exit()`]: event_loop::ActiveEventLoop::exit
210//! [`Window`]: window::Window
211//! [`WindowId`]: window::WindowId
212//! [`WindowAttributes`]: window::WindowAttributes
213//! [window_new]: window::Window::new
214//! [`create_window`]: event_loop::ActiveEventLoop::create_window
215//! [`Window::id()`]: window::Window::id
216//! [`WindowEvent`]: event::WindowEvent
217//! [`DeviceEvent`]: event::DeviceEvent
218//! [`Event::UserEvent`]: event::Event::UserEvent
219//! [`exiting()`]: crate::application::ApplicationHandler::exiting
220//! [`raw_window_handle`]: ./window/struct.Window.html#method.raw_window_handle
221//! [`raw_display_handle`]: ./window/struct.Window.html#method.raw_display_handle
222//! [^1]: `EventLoopExtPumpEvents::pump_app_events()` is only available on Windows, macOS, Android, X11 and Wayland.
223
224#![deny(rust_2018_idioms)]
225#![deny(rustdoc::broken_intra_doc_links)]
226#![deny(clippy::all)]
227#![deny(unsafe_op_in_unsafe_fn)]
228#![cfg_attr(clippy, deny(warnings))]
229// Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly
230// doc
231#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))]
232#![allow(clippy::missing_safety_doc)]
233
234// Re-export DPI types so that users don't have to put it in Cargo.toml.
235#[doc(inline)]
236pub use dpi;
237#[cfg(feature = "rwh_06")]
238pub use rwh_06 as raw_window_handle;
239
240pub mod application;
241#[cfg(any(doc, doctest, test))]
242pub mod changelog;
243#[macro_use]
244pub mod error;
245mod cursor;
246pub mod event;
247pub mod event_loop;
248mod icon;
249pub mod keyboard;
250pub mod monitor;
251mod platform_impl;
252mod utils;
253pub mod window;
254
255pub mod platform;