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 | //! |
11 | //! # // Intentionally use `fn main` for clarity |
12 | //! fn main() { |
13 | //! let event_loop = EventLoop::new().unwrap(); |
14 | //! // ... |
15 | //! } |
16 | //! ``` |
17 | //! |
18 | //! Then you create a [`Window`] with [`create_window`]. |
19 | //! |
20 | //! # Event handling |
21 | //! |
22 | //! Once a [`Window`] has been created, it will generate different *events*. A [`Window`] object can |
23 | //! generate [`WindowEvent`]s when certain input events occur, such as a cursor moving over the |
24 | //! window or a key getting pressed while the window is focused. Devices can generate |
25 | //! [`DeviceEvent`]s, which contain unfiltered event data that isn't specific to a certain window. |
26 | //! Some user activity, like mouse movement, can generate both a [`WindowEvent`] *and* a |
27 | //! [`DeviceEvent`]. You can also create and handle your own custom [`Event::UserEvent`]s, if |
28 | //! desired. |
29 | //! |
30 | //! You can retrieve events by calling [`EventLoop::run_app()`]. This function will |
31 | //! dispatch events for every [`Window`] that was created with that particular [`EventLoop`], and |
32 | //! will run until [`exit()`] is used, at which point [`Event::LoopExiting`]. |
33 | //! |
34 | //! Winit no longer uses a `EventLoop::poll_events() -> impl Iterator<Event>`-based event loop |
35 | //! model, since that can't be implemented properly on some platforms (e.g web, iOS) and works |
36 | //! poorly on most other platforms. However, this model can be re-implemented to an extent with |
37 | #![cfg_attr ( |
38 | any(windows_platform, macos_platform, android_platform, x11_platform, wayland_platform), |
39 | doc = "[`EventLoopExtPumpEvents::pump_app_events()`][platform::pump_events::EventLoopExtPumpEvents::pump_app_events()]" |
40 | )] |
41 | #![cfg_attr ( |
42 | not(any(windows_platform, macos_platform, android_platform, x11_platform, wayland_platform)), |
43 | doc = "`EventLoopExtPumpEvents::pump_app_events()`" |
44 | )] |
45 | //! [^1]. See that method's documentation for more reasons about why |
46 | //! it's discouraged beyond compatibility reasons. |
47 | //! |
48 | //! |
49 | //! ```no_run |
50 | //! use winit::application::ApplicationHandler; |
51 | //! use winit::event::WindowEvent; |
52 | //! use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; |
53 | //! use winit::window::{Window, WindowId}; |
54 | //! |
55 | //! #[derive(Default)] |
56 | //! struct App { |
57 | //! window: Option<Window>, |
58 | //! } |
59 | //! |
60 | //! impl ApplicationHandler for App { |
61 | //! fn resumed(&mut self, event_loop: &ActiveEventLoop) { |
62 | //! self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap()); |
63 | //! } |
64 | //! |
65 | //! fn window_event(&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) { |
66 | //! match event { |
67 | //! WindowEvent::CloseRequested => { |
68 | //! println!("The close button was pressed; stopping" ); |
69 | //! event_loop.exit(); |
70 | //! }, |
71 | //! WindowEvent::RedrawRequested => { |
72 | //! // Redraw the application. |
73 | //! // |
74 | //! // It's preferable for applications that do not render continuously to render in |
75 | //! // this event rather than in AboutToWait, since rendering in here allows |
76 | //! // the program to gracefully handle redraws requested by the OS. |
77 | //! |
78 | //! // Draw. |
79 | //! |
80 | //! // Queue a RedrawRequested event. |
81 | //! // |
82 | //! // You only need to call this if you've determined that you need to redraw in |
83 | //! // applications which do not always need to. Applications that redraw continuously |
84 | //! // can render here instead. |
85 | //! self.window.as_ref().unwrap().request_redraw(); |
86 | //! } |
87 | //! _ => (), |
88 | //! } |
89 | //! } |
90 | //! } |
91 | //! |
92 | //! # // Intentionally use `fn main` for clarity |
93 | //! fn main() { |
94 | //! let event_loop = EventLoop::new().unwrap(); |
95 | //! |
96 | //! // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't |
97 | //! // dispatched any events. This is ideal for games and similar applications. |
98 | //! event_loop.set_control_flow(ControlFlow::Poll); |
99 | //! |
100 | //! // ControlFlow::Wait pauses the event loop if no events are available to process. |
101 | //! // This is ideal for non-game applications that only update in response to user |
102 | //! // input, and uses significantly less power/CPU time than ControlFlow::Poll. |
103 | //! event_loop.set_control_flow(ControlFlow::Wait); |
104 | //! |
105 | //! let mut app = App::default(); |
106 | //! event_loop.run_app(&mut app); |
107 | //! } |
108 | //! ``` |
109 | //! |
110 | //! [`WindowEvent`] has a [`WindowId`] member. In multi-window environments, it should be |
111 | //! compared to the value returned by [`Window::id()`] to determine which [`Window`] |
112 | //! dispatched the event. |
113 | //! |
114 | //! # Drawing on the window |
115 | //! |
116 | //! Winit doesn't directly provide any methods for drawing on a [`Window`]. However, it allows you |
117 | //! to retrieve the raw handle of the window and display (see the [`platform`] module and/or the |
118 | //! [`raw_window_handle`] and [`raw_display_handle`] methods), which in turn allows |
119 | //! you to create an OpenGL/Vulkan/DirectX/Metal/etc. context that can be used to render graphics. |
120 | //! |
121 | //! Note that many platforms will display garbage data in the window's client area if the |
122 | //! application doesn't render anything to the window by the time the desktop compositor is ready to |
123 | //! display the window to the user. If you notice this happening, you should create the window with |
124 | //! [`visible` set to `false`][crate::window::WindowAttributes::with_visible] and explicitly make |
125 | //! the window visible only once you're ready to render into it. |
126 | //! |
127 | //! # UI scaling |
128 | //! |
129 | //! UI scaling is important, go read the docs for the [`dpi`] crate for an |
130 | //! introduction. |
131 | //! |
132 | //! All of Winit's functions return physical types, but can take either logical or physical |
133 | //! coordinates as input, allowing you to use the most convenient coordinate system for your |
134 | //! particular application. |
135 | //! |
136 | //! Winit will dispatch a [`ScaleFactorChanged`] event whenever a window's scale factor has changed. |
137 | //! This can happen if the user drags their window from a standard-resolution monitor to a high-DPI |
138 | //! monitor or if the user changes their DPI settings. This allows you to rescale your application's |
139 | //! UI elements and adjust how the platform changes the window's size to reflect the new scale |
140 | //! factor. If a window hasn't received a [`ScaleFactorChanged`] event, its scale factor |
141 | //! can be found by calling [`window.scale_factor()`]. |
142 | //! |
143 | //! [`ScaleFactorChanged`]: event::WindowEvent::ScaleFactorChanged |
144 | //! [`window.scale_factor()`]: window::Window::scale_factor |
145 | //! |
146 | //! # Cargo Features |
147 | //! |
148 | //! Winit provides the following Cargo features: |
149 | //! |
150 | //! * `x11` (enabled by default): On Unix platforms, enables the X11 backend. |
151 | //! * `wayland` (enabled by default): On Unix platforms, enables the Wayland backend. |
152 | //! * `rwh_04`: Implement `raw-window-handle v0.4` traits. |
153 | //! * `rwh_05`: Implement `raw-window-handle v0.5` traits. |
154 | //! * `rwh_06`: Implement `raw-window-handle v0.6` traits. |
155 | //! * `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde). |
156 | //! * `mint`: Enables mint (math interoperability standard types) conversions. |
157 | //! |
158 | //! See the [`platform`] module for documentation on platform-specific cargo |
159 | //! features. |
160 | //! |
161 | //! [`EventLoop`]: event_loop::EventLoop |
162 | //! [`EventLoop::new()`]: event_loop::EventLoop::new |
163 | //! [`EventLoop::run_app()`]: event_loop::EventLoop::run_app |
164 | //! [`exit()`]: event_loop::ActiveEventLoop::exit |
165 | //! [`Window`]: window::Window |
166 | //! [`WindowId`]: window::WindowId |
167 | //! [`WindowAttributes`]: window::WindowAttributes |
168 | //! [window_new]: window::Window::new |
169 | //! [`create_window`]: event_loop::ActiveEventLoop::create_window |
170 | //! [`Window::id()`]: window::Window::id |
171 | //! [`WindowEvent`]: event::WindowEvent |
172 | //! [`DeviceEvent`]: event::DeviceEvent |
173 | //! [`Event::UserEvent`]: event::Event::UserEvent |
174 | //! [`Event::LoopExiting`]: event::Event::LoopExiting |
175 | //! [`raw_window_handle`]: ./window/struct.Window.html#method.raw_window_handle |
176 | //! [`raw_display_handle`]: ./window/struct.Window.html#method.raw_display_handle |
177 | //! [^1]: `EventLoopExtPumpEvents::pump_app_events()` is only available on Windows, macOS, Android, X11 and Wayland. |
178 | |
179 | #![deny (rust_2018_idioms)] |
180 | #![deny (rustdoc::broken_intra_doc_links)] |
181 | #![deny (clippy::all)] |
182 | #![deny (unsafe_op_in_unsafe_fn)] |
183 | #![cfg_attr (clippy, deny(warnings))] |
184 | // Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly |
185 | // doc |
186 | #![cfg_attr (docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc, docsrs)))] |
187 | #![allow (clippy::missing_safety_doc)] |
188 | |
189 | #[cfg (feature = "rwh_04" )] |
190 | pub use rwh_04 as raw_window_handle_04; |
191 | #[cfg (feature = "rwh_05" )] |
192 | pub use rwh_05 as raw_window_handle_05; |
193 | #[cfg (feature = "rwh_06" )] |
194 | pub use rwh_06 as raw_window_handle; |
195 | |
196 | // Re-export DPI types so that users don't have to put it in Cargo.toml. |
197 | #[doc (inline)] |
198 | pub use dpi; |
199 | |
200 | pub mod application; |
201 | #[cfg (any(doc, doctest, test))] |
202 | pub mod changelog; |
203 | #[macro_use ] |
204 | pub mod error; |
205 | mod cursor; |
206 | pub mod event; |
207 | pub mod event_loop; |
208 | mod icon; |
209 | pub mod keyboard; |
210 | pub mod monitor; |
211 | mod platform_impl; |
212 | mod utils; |
213 | pub mod window; |
214 | |
215 | pub mod platform; |
216 | |