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