Window handling library in pure Rust
APACHE-2.0 License
DeviceId::dummy()
and WindowId::dummy()
are no longer marked unsafe
.WindowEvent::Resized
not using requestAnimationFrame
when sendingWindowEvent::RedrawRequested
and also potentially causing WindowEvent::RedrawRequested
Published by kchibisov 4 months ago
EventLoopExtWebSys::(set_)poll_strategy()
to allow settingWaitUntilStrategy
, which allows to set different strategies forControlFlow::WaitUntil
. By default the Prioritized Task Scheduling API issetTimeout()
with a trick to circumvent throttlingNSWindow
instead of application-wide.WindowBuilder::with_theme
not having any effect on the window.Published by kchibisov 4 months ago
EventLoopProxy::send_event()
triggering event loop immediatelyCursorIcon::Default
.InnerSizeWriter::request_inner_size()
.Published by kchibisov 4 months ago
raw-window-handle
versions 0.4 and 0.5 as raw_window_handle_04
and raw_window_handle_05
.ApplicationHandler
for &mut
references and heap allocations to something that implements ApplicationHandler
.EventLoopExtWayland
and EventLoopExtX11
, providing methods is_wayland
and is_x11
on EventLoop
.Ime::Preedit
.Published by kchibisov 6 months ago
OwnedDisplayHandle
type for allowing safe display handle usage outside ofApplicationHandler<T>
trait which mimics Event<T>
.WindowBuilder::with_cursor
and Window::set_cursor
which takes aCursorIcon
or CustomCursor
.Sync
implementation for EventLoopProxy<T: Send>
.Window::default_attributes
to get default WindowAttributes
.EventLoop::builder
to get EventLoopBuilder
without export.CustomCursor::from_rgba
to allow creating cursor images from RGBA data.CustomCursorExtWebSys::from_url
to allow loading cursor images from URLs.CustomCursorExtWebSys::from_animation
to allow creating animatedCustomCursor
s.{Active,}EventLoop::create_custom_cursor
to load custom cursor image sources.ActiveEventLoop::create_window
and EventLoop::create_window
.CustomCursor
which could be set via Window::set_cursor
, implemented onEvent.preventDefault()
on Window
.PinchGesture
, DoubleTapGesture
, PanGesture
and RotationGesture
.UIGestureRecognizerDelegate
for fine grained control of gesture recognizers.with_title_text_color
, and with_corner_preference
onWindowAttributesExtWindows
.AnyThread
API to access window handle off the main thread.1.65
to 1.70
.sctk-adwaita
to 0.9.0
, which changed system libraryTouchpadMagnify
to PinchGesture
.SmartMagnify
to DoubleTapGesture
.TouchpadRotate
to RotationGesture
.EventLoopWindowTarget
to ActiveEventLoop
.platform::x11::XWindowType
to platform::x11::WindowType
.VideoMode
to VideoModeHandle
to represent that it doesn't holdDebug
formatting of WindowId
more concise.dpi
types to its own crate, and re-export it from the root crate.log
with tracing
, use log
feature on tracing
to restore oldEventLoop::with_user_event
now returns EventLoopBuilder
.HandleError::Unavailable
when a window handle is not available.RawWindowHandle::WebCanvas
instead of RawWindowHandle::Web
.HandleError::Unavailable
when a window handle is not available.HandleError::Unavailable
when a window handle is not available.WS_CAPTION
, WS_BORDER
, and WS_EX_WINDOWEDGE
stylesndk
to 0.9.0
and android-activity
to 0.6.0
,ndk-sys
.Deprecate EventLoop::run
, use EventLoop::run_app
.
Deprecate EventLoopExtRunOnDemand::run_on_demand
, use EventLoop::run_app_on_demand
.
Deprecate EventLoopExtPumpEvents::pump_events
, use EventLoopExtPumpEvents::pump_app_events
.
The new app
APIs accept a newly added ApplicationHandler<T>
instead of
Fn
. The semantics are mostly the same, given that the capture list of the
closure is your new State
. Consider the following code:
use winit::event::Event;
use winit::event_loop::EventLoop;
use winit::window::Window;
struct MyUserEvent;
let event_loop = EventLoop::<MyUserEvent>::with_user_event().build().unwrap();
let window = event_loop.create_window(Window::default_attributes()).unwrap();
let mut counter = 0;
let _ = event_loop.run(move |event, event_loop| {
match event {
Event::AboutToWait => {
window.request_redraw();
counter += 1;
}
Event::WindowEvent { window_id, event } => {
// Handle window event.
}
Event::UserEvent(event) => {
// Handle user event.
}
Event::DeviceEvent { device_id, event } => {
// Handle device event.
}
_ => (),
}
});
To migrate this code, you should move all the captured values into some
newtype State
and implement ApplicationHandler
for this type. Finally,
we move particular match event
arms into methods on ApplicationHandler
,
for example:
use winit::application::ApplicationHandler;
use winit::event::{Event, WindowEvent, DeviceEvent, DeviceId};
use winit::event_loop::{EventLoop, ActiveEventLoop};
use winit::window::{Window, WindowId};
struct MyUserEvent;
struct State {
window: Window,
counter: i32,
}
impl ApplicationHandler<MyUserEvent> for State {
fn user_event(&mut self, event_loop: &ActiveEventLoop, user_event: MyUserEvent) {
// Handle user event.
}
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
// Your application got resumed.
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, window_id: WindowId, event: WindowEvent) {
// Handle window event.
}
fn device_event(&mut self, event_loop: &ActiveEventLoop, device_id: DeviceId, event: DeviceEvent) {
// Handle device event.
}
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
self.window.request_redraw();
self.counter += 1;
}
}
let event_loop = EventLoop::<MyUserEvent>::with_user_event().build().unwrap();
#[allow(deprecated)]
let window = event_loop.create_window(Window::default_attributes()).unwrap();
let mut state = State { window, counter: 0 };
let _ = event_loop.run_app(&mut state);
Please submit your feedback after migrating in this issue.
Deprecate Window::set_cursor_icon
, use Window::set_cursor
.
Remove Window::new
, use ActiveEventLoop::create_window
instead.
You now have to create your windows inside the actively running event loop
(usually the new_events(cause: StartCause::Init)
or resumed()
events),
and can no longer do it before the application has properly launched.
This change is done to fix many long-standing issues on iOS and macOS, and
will improve things on Wayland once fully implemented.
To ease migration, we provide the deprecated EventLoop::create_window
that
will allow you to bypass this restriction in this release.
Using the migration example from above, you can change your code as follows:
use winit::application::ApplicationHandler;
use winit::event::{Event, WindowEvent, DeviceEvent, DeviceId};
use winit::event_loop::{EventLoop, ActiveEventLoop};
use winit::window::{Window, WindowId};
#[derive(Default)]
struct State {
// Use an `Option` to allow the window to not be available until the
// application is properly running.
window: Option<Window>,
counter: i32,
}
impl ApplicationHandler for State {
// This is a common indicator that you can create a window.
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap());
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, window_id: WindowId, event: WindowEvent) {
// `unwrap` is fine, the window will always be available when
// receiving a window event.
let window = self.window.as_ref().unwrap();
// Handle window event.
}
fn device_event(&mut self, event_loop: &ActiveEventLoop, device_id: DeviceId, event: DeviceEvent) {
// Handle window event.
}
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
if let Some(window) = self.window.as_ref() {
window.request_redraw();
self.counter += 1;
}
}
}
let event_loop = EventLoop::new().unwrap();
let mut state = State::default();
let _ = event_loop.run_app(&mut state);
Remove Deref
implementation for EventLoop
that gave EventLoopWindowTarget
.
Remove WindowBuilder
in favor of WindowAttributes
.
Remove Generic parameter T
from ActiveEventLoop
.
Remove EventLoopBuilder::with_user_event
, use EventLoop::with_user_event
.
Remove Redundant EventLoopError::AlreadyRunning
.
Remove WindowAttributes::fullscreen
and expose as field directly.
On X11, remove platform::x11::XNotSupported
export.
Published by kchibisov 7 months ago
Published by kchibisov 8 months ago
text
and text_with_all_modifiers
not being None
during compose.Published by daxpedda 8 months ago
ControlFlow::Wait
and ControlFlow::WaitUntil
.Published by kchibisov 8 months ago
Published by kchibisov 8 months ago
Occluded
event handling._XSETTINGS_SETTINGS
update.Focused(false)
being send when other seats still have window focused.Window::set_{min,max}_inner_size
not always applied.WAYLAND_SOCKET
not used when detecting platform.logical_key
and text
not reported in KeyEvent
.KeyEventExtModifierSupplement
.NamedKey
when possible.set_cursor_grab
.set_cursor_visible
.drag_window
.drag_resize_window
.set_transparent
.set_visible
.is_visible
.set_resizable
.is_resizable
.set_maximized
.is_maximized
.set_decorations
.is_decorated
.set_window_level
.DeviceEvent::MouseMotion
.AboutToWait
.Published by kchibisov 9 months ago
Published by kchibisov 10 months ago
NotSupported
error not propagated when creating event loop.ArrowLeft
.Published by kchibisov 10 months ago
ModifiersChanged
not sent from xdotool-like inputWindow::request_inner_size
being overwritten by resize.Window::inner_size
not using the correct rounding.Published by kchibisov 10 months ago
Xft.dpi
reload during runtime.Published by kchibisov 10 months ago
with_prevent_default(true)
.WindowEvent::Destroyed
not being delivered after destroying window.EventLoopExtRunOnDemand::run_on_demand
not working for consequent invocationPublished by kchibisov 10 months ago
Fn
.refresh_rate_millihertz
.wl_subcompositor
is not supported.Xft.dpi
detection from Xresources.window.set_fullscreen(Some(Fullscreen::Borderless(None)))
resulting in losing previous window state when eventually exiting fullscreen using window.set_fullscreen(None)
.set_ime_cursor_area
.Published by kchibisov 11 months ago
drag_window
and drag_resize_window
can be called from another thread.set_control_flow
in AboutToWait
not being taken in account.Resized
event after each ScaleFactorChanged
event.wl_surface
being destroyed before associated objects.Fn
key.Published by kchibisov 12 months ago
PhysicalSize
passed in WindowBuilder::with_inner_size
when possible.RedrawRequsted
being always sent without decorations and sctk-adwaita
feature.configure_bounds
to constrain with_inner_size
when compositor wants users to pick size.Cursor{Enter,Leave}
.Window::set_transparent
.Window::set_blur
.Published by kchibisov about 1 year ago
1.60
to 1.65
.Event::MemoryWarning
; implemented on iOS/Android.ndk
version to 0.8.0
, ndk-sys to 0.5.0
, android-activity
to 0.5.0
.ControlFlow
from Poll
to Wait
.Event::RedrawRequested
to WindowEvent::RedrawRequested
.ControlFlow::Exit
to EventLoopWindowTarget::exit()
and EventLoopWindowTarget::exiting()
and removed ControlFlow::ExitWithCode(_)
entirely.ControlFlow
to EventLoopWindowTarget::set_control_flow()
and EventLoopWindowTarget::control_flow()
.EventLoop::new
and EventLoopBuilder::build
now return Result<Self, EventLoopError>
WINIT_UNIX_BACKEND
was removed in favor of standard WAYLAND_DISPLAY
and DISPLAY
variables.DeviceEvent::Text
.Event
and WindowEvent
.Window::set_inner_size
to Window::request_inner_size
and indicate if the size was applied immediately.ActivationTokenDone
event which could be requested with the new startup_notify
module, see its docs for more.ScaleFactorChanged
now contains a writer instead of a reference to update inner size.run() -> !
has been replaced by run() -> Result<(), EventLoopError>
for returning errors without calling std::process::exit()
(#2767)EventLoopExtRunReturn
/ run_return
in favor of EventLoopExtPumpEvents
/ pump_events
and EventLoopExtRunOnDemand
/ run_on_demand
(#2767)RedrawRequested
is no longer guaranteed to be emitted after MainEventsCleared
, it is now platform-specific when the event is emitted after being requested via redraw_request()
.
RedrawRequested
is now driven by WM_PAINT
messages which are requested via redraw_request()
LoopDestroyed
renamed to LoopExiting
(#2900)RedrawEventsCleared
removed (#2900)MainEventsCleared
removed (#2900)modifiers
fields.DeviceEventFilter
to DeviceEvents
reversing the behavior of variants.AboutToWait
event which is emitted when the event loop is about to block and wait for new events (#2900)EventLoopWindowTarget::set_device_event_filter
to listen_device_events
.Window::set_ime_position
to Window::set_ime_cursor_area
adding a way to set exclusive zone.with_x11_visual
now takes the visual ID instead of the bare pointer.MouseButton
now supports Back
and Forward
variants, emitted from mouse events on Wayland, X11, Windows, macOS and Web.instant
is now replaced by web_time
.WindowEvent::Resized
.bitflags
crate version to 2
, which changes the API on exposed types.CursorIcon::Arrow
was removed.CursorIcon::Hand
is now named CursorIcon::Pointer
.CursorIcon
is now used from the cursor-icon
crate.WindowExtWebSys::canvas()
now returns an Option
.KeyboardInput
with KeyEvent
and RawKeyEvent
.
WindowEvent::KeyboardInput
to contain a KeyEvent
.Event::Key
to contain a RawKeyEvent
.Event::ReceivedCharacter
. In its place, you should useKeyEvent.text
in combination with WindowEvent::Ime
.VirtualKeyCode
with the Key
enum.ScanCode
with the KeyCode
enum.ModifiersState::LOGO
to SUPER
and ModifiersState::CTRL
to CONTROL
.PhysicalKey
wrapping KeyCode
and NativeKeyCode
.KeyCode
to refer to keys (roughly) by their physical location.NativeKeyCode
to represent raw KeyCode
s which Winit doesn'tKey
to represent the keys after they've been interpreted by theNamedKey
to represent the categorized keys.NativeKey
to represent raw Key
s which Winit doesn't understand.KeyLocation
to tell apart Key
s which usually "mean" the same thing,Window::reset_dead_keys
to enable application-controlled cancellationKeyEventExtModifierSupplement
to expose additional (and lessPhysicalKeyExtScancode
, which lets you convert between scancodes andPhysicalKey
.ModifiersChanged
now uses dedicated Modifiers
struct.raw-window-handle
trait implementations instead:
platform::windows::HINSTANCE
.WindowExtWindows::hinstance
.WindowExtWindows::hwnd
.WindowExtIOS::ui_window
.WindowExtIOS::ui_view_controller
.WindowExtIOS::ui_view
.WindowExtMacOS::ns_window
.WindowExtMacOS::ns_view
.EventLoopWindowTargetExtWayland::wayland_display
.WindowExtWayland::wayland_surface
.WindowExtWayland::wayland_display
.WindowExtX11::xlib_window
.WindowExtX11::xlib_display
.WindowExtX11::xlib_screen_id
.WindowExtX11::xcb_connection
.raw-window-handle
in window
module.ElementState::is_pressed
.Window::pre_present_notify
to notify winit before presenting to the windowing system.Window::set_blur
to request a blur behind the window; implemented on Wayland for now.Window::show_window_menu
to request a titlebar/system menu; implemented on Wayland/Windows for now.AsFd
/AsRawFd
for EventLoop<T>
on X11 and Wayland.PartialOrd
and Ord
for MouseButton
.PartialOrd
and Ord
on types in the dpi
module.WindowBuilder
Send + Sync
.MonitorHandle
and VideoMode
usable from other threads.EventLoopBuilderExtAndroid::handle_volume_keys
to indicate that the application will handle the volume keys manually.DeviceId
to contain device id's.ModifiersChanged
not being sent.Window::outer_size
now accounts for client side decorations.Window::drag_resize_window
method.WINIT_WAYLAND_CSD_THEME
variable.TouchPhase::Canceled
being sent for moved events.Occluded
event with xdg-shell v6RedrawRequested
events so redraws will align with compositor.ControlFlow::WaitUntil
now uses the Prioritized Task Scheduling API. setTimeout()
, with a trick to circumvent throttling to 4ms, is used as a fallback.EventLoopProxy
now implements Send
.Window
now implements Send
and Sync
.padding
, border
, and margin
when getting or setting the canvas position.DeviceEvent::Motion
, DeviceEvent::MouseWheel
, DeviceEvent::Button
and DeviceEvent::Key
support.EventLoopWindowTargetExtWebSys
and PollStrategy
, which allows to set different strategies for ControlFlow::Poll
. By default the Prioritized Task Scheduling API is used, but an option to use Window.requestIdleCallback
is available as well. Both use setTimeout()
, with a trick to circumvent throttling to 4ms, as a fallback.WindowBuilderExtWebSys::with_append()
to append the canvas element to the web page on creation.spawn
.ControlFlow::WaitUntil
to never wake up before the given time.DeviceEvent::MouseMotion
only being emitted for each canvas instead of the whole window.Window:::set_fullscreen
doing nothing when called outside the event loop but during transient activation.WindowBuilder
methods doing nothing.Window
methods using incorrect HTML attributes instead of CSS properties.beforeunload
event and map bfcache loading/unloading to Suspended
/Resumed
events.Window::focus_window()
.Window::set_(min|max)_inner_size()
.WindowEvent::Occluded
.MonitorHandle
.Window::is_dark_mode()
, which was replaced with Window::theme()
.EventLoopWindowTarget::listen_device_events()
settings.Window.requestAnimationFrame()
to throttle RedrawRequested
events.Window::request_redraw
not waking the event loop when called from outside the loop.drag_resize_window
method support.DeviceEvent
.WindowBuilderExtWindows::with_class_name
to customize the internal class name.CursorEnter/Left
not being sent when grabbing the mouse.RedrawRequested
not being delivered when calling Window::request_redraw
from RedrawRequested
.windows-sys
version 0.48.0.with_embedded_parent_window
function to the window builder to allow embedding a window into another window.ControlFlow::Poll
and ControlFlow::WaitUntil
.visual_id
in returned raw-window-handle
.ControlFlow::Poll
to ControlFlow::Poll
.WindowEvent::Occluded(false)
, WindowEvent::Occluded(true)
when application enters/leaves foreground.WindowExtMacOS
and EventLoopWindowTargetExtMacOS
.Globe
key.window.set_minimized(false)
.Window
.Published by madsmtm about 1 year ago