winit-sonoma-fix/examples/cursor_grab.rs

71 lines
2.5 KiB
Rust
Raw Normal View History

2022-06-10 20:43:33 +10:00
#![allow(clippy::single_match)]
use simple_logger::SimpleLogger;
use winit::{
event::{DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, WindowEvent},
event_loop::EventLoop,
window::{CursorGrabMode, WindowBuilder},
};
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
fn main() {
SimpleLogger::new().init().unwrap();
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
let event_loop = EventLoop::new();
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
let window = WindowBuilder::new()
.with_title("Super Cursor Grab'n'Hide Simulator 9000")
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
.build(&event_loop)
.unwrap();
let mut modifiers = ModifiersState::default();
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
event_loop.run(move |event, _, control_flow| {
control_flow.set_wait();
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => control_flow.set_exit(),
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Released,
virtual_keycode: Some(key),
..
},
..
} => {
Event Loop 2.0 API and Windows implementation (#638) * Rename EventsLoop and associated types to EventLoop * Rename WindowEvent::Refresh to WindowEvent::Redraw * Remove second thread from win32 backend * Update run_forever to hijack thread * Replace windows Mutex with parking_lot Mutex * Implement new ControlFlow and associated events * Add StartCause::Init support, timer example * Add ability to send custom user events * Fully invert windows control flow so win32 calls into winit's callback * Add request_redraw * Rename platform to platform_impl * Rename os to platform, add Ext trait postfixes * Add platform::desktop module with EventLoopExt::run_return * Re-organize into module structure * Improve documentation * Small changes to examples * Improve docs for run and run_return * Change instances of "events_loop" to "event_loop" * Rename MonitorId to MonitorHandle * Add CHANGELOG entry * Improve WaitUntil timer precision * When SendEvent is called during event closure, buffer events * Fix resize lag when waiting in some situations * Update send test and errors that broke some examples/APIs * Improve clarity/fix typos in docs * Fix unreachable panic after setting ControlFlow to Poll during some RedrawRequested events. * Fix crash when running in release mode * Remove crossbeam dependency and make drop events work again * Remove serde implementations from ControlFlow * Fix 1.24.1 build * Fix freeze when setting decorations * Replace &EventLoop in callback with &EventLoopWindowTarget * Document and implement Debug for EventLoopWindowTarget * Fix some deadlocks that could occur when changing window state * Fix thread executor not executing closure when called from non-loop thread * Fix buffered events not getting dispatched * Fix crash with runner refcell not getting dropped * Address review feedback * Fix CHANGELOG typo * Catch panics in user callback
2019-02-06 02:30:33 +11:00
use winit::event::VirtualKeyCode::*;
let result = match key {
Escape => {
control_flow.set_exit();
Ok(())
}
G => window.set_cursor_grab(CursorGrabMode::Confined),
L => window.set_cursor_grab(CursorGrabMode::Locked),
A => window.set_cursor_grab(CursorGrabMode::None),
H => {
window.set_cursor_visible(modifiers.shift());
Ok(())
}
_ => Ok(()),
};
if let Err(err) = result {
println!("error: {}", err);
}
2019-06-25 02:14:55 +10:00
}
Move `ModifiersChanged` variant to `WindowEvent` (#1381) * Move `ModifiersChanged` variant to `WindowEvent` * macos: Fix flags_changed for ModifiersChanged variant move I haven't look too deep at what this does internally, but at least cargo-check is fully happy now. :) Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * macos: Fire a ModifiersChanged event on window_did_resign_key From debugging, I determined that macOS' emission of a flagsChanged around window switching is inconsistent. It is fair to assume, I think, that when the user switches windows, they do not expect their former modifiers state to remain effective; so I think it's best to clear that state by sending a ModifiersChanged(ModifiersState::empty()). Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * windows: Fix build I don't know enough about the code to implement the fix as it is done on this branch, but this commit at least fixes the build. Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * windows: Send ModifiersChanged(ModifiersState::empty) on KILLFOCUS Very similar to the changes made in [1], as focus is lost, send an event to the window indicating that the modifiers have been released. It's unclear to me (without a Windows device to test this on) whether this is necessary, but it certainly ensures that unfocused windows will have at least received this event, which is an improvement. [1]: f79f21641a31da3e4039d41be89047cdcc6028f7 Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * macos: Add a hook to update stale modifiers Sometimes, `ViewState` and `event` might have different values for their stored `modifiers` flags. These are internally stored as a bitmask in the latter and an enum in the former. We can check to see if they differ, and if they do, automatically dispatch an event to update consumers of modifier state as well as the stored `state.modifiers`. That's what the hook does. This hook is then called in the key_down, mouse_entered, mouse_exited, mouse_click, scroll_wheel, and pressure_change_with_event callbacks, which each will contain updated modifiers. Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * Only call event_mods once when determining whether to update state Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * flags_changed: Memoize window_id collection Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * window_did_resign_key: Remove synthetic ModifiersChanged event We no longer need to emit this event, since we are checking the state of our modifiers before emitting most other events. Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * mouse_motion: Add a call to update_potentially_stale_modifiers Now, cover all events (that I can think of, at least) where stale modifiers might affect how user programs behave. Effectively, every human-interface event (keypress, mouse click, keydown, etc.) will cause a ModifiersChanged event to be fired if something has changed. Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * key_up: Add a call to update_potentially_stale_modifiers We also want to make sure modifiers state is synchronized here, too. Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * mouse_motion: Remove update_potentially_stale_modifiers invocation Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * Retry CI * ViewState: Promote visibility of modifiers to the macos impl This is so that we can interact with the ViewState directly from the WindowDelegate. Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * window_delegate: Synthetically set modifiers state to empty on resignKey This logic is implemented similarly on other platforms, so we wish to regain parity here. Originally this behavior was implemented to always fire an event with ModifiersState::empty(), but that was not the best as it was not necessarily correct and could be a duplicate event. This solution is perhaps the most elegant possible to implement the desired behavior of sending a synthetic empty modifiers event when a window loses focus, trading some safety for interoperation between the NSWindowDelegate and the NSView (as the objc runtime must now be consulted in order to acquire access to the ViewState which is "owned" by the NSView). Signed-off-by: Kristofer Rye <kristofer.rye@gmail.com> * Check for modifiers change in window events * Fix modifier changed on macOS Since the `mouse_entered` function was generating a mouse motion, which updates the modifier state, a modifiers changed event was incorrectly generated. The updating of the modifier state has also been changed to make sure it consistently happens before events that have a modifier state attached to it, without happening on any other event. This of course means that no `CursorMoved` event is generated anymore when the user enters the window without it being focused, however I'd say that is consistent with how winit should behave. * Fix unused variable warning * Move changelog entry into `Unreleased` section Co-authored-by: Freya Gentz <zegentzy@protonmail.com> Co-authored-by: Kristofer Rye <kristofer.rye@gmail.com> Co-authored-by: Christian Duerr <contact@christianduerr.com>
2020-03-07 09:43:55 +11:00
WindowEvent::ModifiersChanged(m) => modifiers = m,
_ => (),
},
Event::DeviceEvent { event, .. } => match event {
DeviceEvent::MouseMotion { delta } => println!("mouse moved: {:?}", delta),
DeviceEvent::Button { button, state } => match state {
ElementState::Pressed => println!("mouse button {} pressed", button),
ElementState::Released => println!("mouse button {} released", button),
},
_ => (),
},
_ => (),
}
});
}