mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 14:51:30 +11:00
6a330a2894
* Fix bug causing RedrawRequested events to only get emitted every other iteration of the event loop. * Initialize simple_logger in examples. This PR's primary bug was discovered because a friend of mine reported that winit was emitting concerning log messages, which I'd never seen since none of the examples print out the log messages. This addresses that, to hopefully reduce the chance of bugs going unnoticed in the future. * Add changelog entry * Format
186 lines
8.6 KiB
Rust
186 lines
8.6 KiB
Rust
#[cfg(not(target_arch = "wasm32"))]
|
|
fn main() {
|
|
use std::{collections::HashMap, sync::mpsc, thread, time::Duration};
|
|
|
|
use winit::{
|
|
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
|
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
|
event_loop::{ControlFlow, EventLoop},
|
|
window::{CursorIcon, Fullscreen, WindowBuilder},
|
|
};
|
|
|
|
const WINDOW_COUNT: usize = 3;
|
|
const WINDOW_SIZE: PhysicalSize<u32> = PhysicalSize::new(600, 400);
|
|
|
|
simple_logger::init().unwrap();
|
|
let event_loop = EventLoop::new();
|
|
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
|
|
for _ in 0..WINDOW_COUNT {
|
|
let window = WindowBuilder::new()
|
|
.with_inner_size(WINDOW_SIZE)
|
|
.build(&event_loop)
|
|
.unwrap();
|
|
|
|
let mut video_modes: Vec<_> = window.current_monitor().video_modes().collect();
|
|
let mut video_mode_id = 0usize;
|
|
|
|
let (tx, rx) = mpsc::channel();
|
|
window_senders.insert(window.id(), tx);
|
|
thread::spawn(move || {
|
|
while let Ok(event) = rx.recv() {
|
|
match event {
|
|
WindowEvent::Moved { .. } => {
|
|
// We need to update our chosen video mode if the window
|
|
// was moved to an another monitor, so that the window
|
|
// appears on this monitor instead when we go fullscreen
|
|
let previous_video_mode = video_modes.iter().cloned().nth(video_mode_id);
|
|
video_modes = window.current_monitor().video_modes().collect();
|
|
video_mode_id = video_mode_id.min(video_modes.len());
|
|
let video_mode = video_modes.iter().nth(video_mode_id);
|
|
|
|
// Different monitors may support different video modes,
|
|
// and the index we chose previously may now point to a
|
|
// completely different video mode, so notify the user
|
|
if video_mode != previous_video_mode.as_ref() {
|
|
println!(
|
|
"Window moved to another monitor, picked video mode: {}",
|
|
video_modes.iter().nth(video_mode_id).unwrap()
|
|
);
|
|
}
|
|
}
|
|
#[allow(deprecated)]
|
|
WindowEvent::KeyboardInput {
|
|
input:
|
|
KeyboardInput {
|
|
state: ElementState::Released,
|
|
virtual_keycode: Some(key),
|
|
modifiers,
|
|
..
|
|
},
|
|
..
|
|
} => {
|
|
window.set_title(&format!("{:?}", key));
|
|
let state = !modifiers.shift();
|
|
use VirtualKeyCode::*;
|
|
match key {
|
|
A => window.set_always_on_top(state),
|
|
C => window.set_cursor_icon(match state {
|
|
true => CursorIcon::Progress,
|
|
false => CursorIcon::Default,
|
|
}),
|
|
D => window.set_decorations(!state),
|
|
// Cycle through video modes
|
|
Right | Left => {
|
|
video_mode_id = match key {
|
|
Left => video_mode_id.saturating_sub(1),
|
|
Right => (video_modes.len() - 1).min(video_mode_id + 1),
|
|
_ => unreachable!(),
|
|
};
|
|
println!(
|
|
"Picking video mode: {}",
|
|
video_modes.iter().nth(video_mode_id).unwrap()
|
|
);
|
|
}
|
|
F => window.set_fullscreen(match (state, modifiers.alt()) {
|
|
(true, false) => {
|
|
Some(Fullscreen::Borderless(window.current_monitor()))
|
|
}
|
|
(true, true) => Some(Fullscreen::Exclusive(
|
|
video_modes.iter().nth(video_mode_id).unwrap().clone(),
|
|
)),
|
|
(false, _) => None,
|
|
}),
|
|
G => window.set_cursor_grab(state).unwrap(),
|
|
H => window.set_cursor_visible(!state),
|
|
I => {
|
|
println!("Info:");
|
|
println!("-> outer_position : {:?}", window.outer_position());
|
|
println!("-> inner_position : {:?}", window.inner_position());
|
|
println!("-> outer_size : {:?}", window.outer_size());
|
|
println!("-> inner_size : {:?}", window.inner_size());
|
|
println!("-> fullscreen : {:?}", window.fullscreen());
|
|
}
|
|
L => window.set_min_inner_size(match state {
|
|
true => Some(WINDOW_SIZE),
|
|
false => None,
|
|
}),
|
|
M => window.set_maximized(state),
|
|
P => window.set_outer_position({
|
|
let mut position = window.outer_position().unwrap();
|
|
let sign = if state { 1 } else { -1 };
|
|
position.x += 10 * sign;
|
|
position.y += 10 * sign;
|
|
position
|
|
}),
|
|
Q => window.request_redraw(),
|
|
R => window.set_resizable(state),
|
|
S => window.set_inner_size(match state {
|
|
true => PhysicalSize::new(
|
|
WINDOW_SIZE.width + 100,
|
|
WINDOW_SIZE.height + 100,
|
|
),
|
|
false => WINDOW_SIZE,
|
|
}),
|
|
W => {
|
|
if let Size::Physical(size) = WINDOW_SIZE.into() {
|
|
window
|
|
.set_cursor_position(Position::Physical(
|
|
PhysicalPosition::new(
|
|
size.width as i32 / 2,
|
|
size.height as i32 / 2,
|
|
),
|
|
))
|
|
.unwrap()
|
|
}
|
|
}
|
|
Z => {
|
|
window.set_visible(false);
|
|
thread::sleep(Duration::from_secs(1));
|
|
window.set_visible(true);
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
});
|
|
}
|
|
event_loop.run(move |event, _event_loop, control_flow| {
|
|
*control_flow = match !window_senders.is_empty() {
|
|
true => ControlFlow::Wait,
|
|
false => ControlFlow::Exit,
|
|
};
|
|
match event {
|
|
Event::WindowEvent { event, window_id } => match event {
|
|
WindowEvent::CloseRequested
|
|
| WindowEvent::Destroyed
|
|
| WindowEvent::KeyboardInput {
|
|
input:
|
|
KeyboardInput {
|
|
state: ElementState::Released,
|
|
virtual_keycode: Some(VirtualKeyCode::Escape),
|
|
..
|
|
},
|
|
..
|
|
} => {
|
|
window_senders.remove(&window_id);
|
|
}
|
|
_ => {
|
|
if let Some(tx) = window_senders.get(&window_id) {
|
|
if let Some(event) = event.to_static() {
|
|
tx.send(event).unwrap();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
_ => (),
|
|
}
|
|
})
|
|
}
|
|
|
|
#[cfg(target_arch = "wasm32")]
|
|
fn main() {
|
|
panic!("Example not supported on Wasm");
|
|
}
|