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 build a [`Window`], you first need to build an [`EventLoop`]. This is done with the
6//! [`EventLoop::new()`] function.
7//!
8//! ```no_run
9//! use winit::event_loop::EventLoop;
10//! let event_loop = EventLoop::new();
11//! ```
12//!
13//! Once this is done there are two ways to create a [`Window`]:
14//!
15//!  - Calling [`Window::new(&event_loop)`][window_new].
16//!  - Calling [`let builder = WindowBuilder::new()`][window_builder_new] then [`builder.build(&event_loop)`][window_builder_build].
17//!
18//! The first method is the simplest, and will give you default values for everything. The second
19//! method allows you to customize the way your [`Window`] will look and behave by modifying the
20//! fields of the [`WindowBuilder`] object before you create the [`Window`].
21//!
22//! # Event handling
23//!
24//! Once a [`Window`] has been created, it will generate different *events*. A [`Window`] object can
25//! generate [`WindowEvent`]s when certain input events occur, such as a cursor moving over the
26//! window or a key getting pressed while the window is focused. Devices can generate
27//! [`DeviceEvent`]s, which contain unfiltered event data that isn't specific to a certain window.
28//! Some user activity, like mouse movement, can generate both a [`WindowEvent`] *and* a
29//! [`DeviceEvent`]. You can also create and handle your own custom [`UserEvent`]s, if desired.
30//!
31//! You can retrieve events by calling [`EventLoop::run`][event_loop_run]. This function will
32//! dispatch events for every [`Window`] that was created with that particular [`EventLoop`], and
33//! will run until the `control_flow` argument given to the closure is set to
34//! [`ControlFlow`]`::`[`Exit`], at which point [`Event`]`::`[`LoopDestroyed`] is emitted and the
35//! entire program terminates.
36//!
37//! Winit no longer uses a `EventLoop::poll_events() -> impl Iterator<Event>`-based event loop
38//! model, since that can't be implemented properly on some platforms (e.g web, iOS) and works poorly on
39//! most other platforms. However, this model can be re-implemented to an extent with
40//! [`EventLoopExtRunReturn::run_return`]. See that method's documentation for more reasons about why
41//! it's discouraged, beyond compatibility reasons.
42//!
43//!
44//! ```no_run
45//! use winit::{
46//!     event::{Event, WindowEvent},
47//!     event_loop::{ControlFlow, EventLoop},
48//!     window::WindowBuilder,
49//! };
50//!
51//! let event_loop = EventLoop::new();
52//! let window = WindowBuilder::new().build(&event_loop).unwrap();
53//!
54//! event_loop.run(move |event, _, control_flow| {
55//!     // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't
56//!     // dispatched any events. This is ideal for games and similar applications.
57//!     *control_flow = ControlFlow::Poll;
58//!
59//!     // ControlFlow::Wait pauses the event loop if no events are available to process.
60//!     // This is ideal for non-game applications that only update in response to user
61//!     // input, and uses significantly less power/CPU time than ControlFlow::Poll.
62//!     *control_flow = ControlFlow::Wait;
63//!
64//!     match event {
65//!         Event::WindowEvent {
66//!             event: WindowEvent::CloseRequested,
67//!             ..
68//!         } => {
69//!             println!("The close button was pressed; stopping");
70//!             *control_flow = ControlFlow::Exit
71//!         },
72//!         Event::MainEventsCleared => {
73//!             // Application update code.
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 just render here instead.
80//!             window.request_redraw();
81//!         },
82//!         Event::RedrawRequested(_) => {
83//!             // Redraw the application.
84//!             //
85//!             // It's preferable for applications that do not render continuously to render in
86//!             // this event rather than in MainEventsCleared, since rendering in here allows
87//!             // the program to gracefully handle redraws requested by the OS.
88//!         },
89//!         _ => ()
90//!     }
91//! });
92//! ```
93//!
94//! [`Event`]`::`[`WindowEvent`] has a [`WindowId`] member. In multi-window environments, it should be
95//! compared to the value returned by [`Window::id()`][window_id_fn] to determine which [`Window`]
96//! dispatched the event.
97//!
98//! # Drawing on the window
99//!
100//! Winit doesn't directly provide any methods for drawing on a [`Window`]. However it allows you to
101//! retrieve the raw handle of the window (see the [`platform`] module and/or the
102//! [`raw_window_handle`] method), which in turn allows you to create an
103//! OpenGL/Vulkan/DirectX/Metal/etc. context that can be used to render graphics.
104//!
105//! Note that many platforms will display garbage data in the window's client area if the
106//! application doesn't render anything to the window by the time the desktop compositor is ready to
107//! display the window to the user. If you notice this happening, you should create the window with
108//! [`visible` set to `false`](crate::window::WindowBuilder::with_visible) and explicitly make the
109//! window visible only once you're ready to render into it.
110//!
111//! [`EventLoop`]: event_loop::EventLoop
112//! [`EventLoopExtRunReturn::run_return`]: ./platform/run_return/trait.EventLoopExtRunReturn.html#tymethod.run_return
113//! [`EventLoop::new()`]: event_loop::EventLoop::new
114//! [event_loop_run]: event_loop::EventLoop::run
115//! [`ControlFlow`]: event_loop::ControlFlow
116//! [`Exit`]: event_loop::ControlFlow::Exit
117//! [`Window`]: window::Window
118//! [`WindowId`]: window::WindowId
119//! [`WindowBuilder`]: window::WindowBuilder
120//! [window_new]: window::Window::new
121//! [window_builder_new]: window::WindowBuilder::new
122//! [window_builder_build]: window::WindowBuilder::build
123//! [window_id_fn]: window::Window::id
124//! [`Event`]: event::Event
125//! [`WindowEvent`]: event::WindowEvent
126//! [`DeviceEvent`]: event::DeviceEvent
127//! [`UserEvent`]: event::Event::UserEvent
128//! [`LoopDestroyed`]: event::Event::LoopDestroyed
129//! [`platform`]: platform
130//! [`raw_window_handle`]: ./window/struct.Window.html#method.raw_window_handle
131
132#![deny(rust_2018_idioms)]
133#![deny(broken_intra_doc_links)]
134
135#[allow(unused_imports)]
136#[macro_use]
137extern crate lazy_static;
138#[allow(unused_imports)]
139#[macro_use]
140extern crate log;
141#[cfg(feature = "serde")]
142#[macro_use]
143extern crate serde;
144#[macro_use]
145extern crate bitflags;
146#[cfg(any(target_os = "macos", target_os = "ios"))]
147#[macro_use]
148extern crate objc;
149#[cfg(all(target_arch = "wasm32", feature = "std_web"))]
150extern crate std_web as stdweb;
151
152pub mod dpi;
153#[macro_use]
154pub mod error;
155pub mod event;
156pub mod event_loop;
157mod icon;
158pub mod monitor;
159mod platform_impl;
160pub mod window;
161
162pub mod platform;