mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
0d366ffbda
This re-works the portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: #2709 By moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: #2709
113 lines
4.2 KiB
Rust
113 lines
4.2 KiB
Rust
#![allow(clippy::single_match)]
|
|
|
|
#[cfg(target_os = "macos")]
|
|
use std::{collections::HashMap, num::NonZeroUsize};
|
|
|
|
#[cfg(target_os = "macos")]
|
|
use simple_logger::SimpleLogger;
|
|
#[cfg(target_os = "macos")]
|
|
use winit::{
|
|
event::{ElementState, Event, KeyEvent, WindowEvent},
|
|
event_loop::EventLoop,
|
|
keyboard::Key,
|
|
platform::macos::{WindowBuilderExtMacOS, WindowExtMacOS},
|
|
window::{Window, WindowBuilder},
|
|
};
|
|
|
|
#[cfg(target_os = "macos")]
|
|
#[path = "util/fill.rs"]
|
|
mod fill;
|
|
|
|
#[cfg(target_os = "macos")]
|
|
fn main() -> Result<(), impl std::error::Error> {
|
|
SimpleLogger::new().init().unwrap();
|
|
let event_loop = EventLoop::new();
|
|
|
|
let mut windows = HashMap::new();
|
|
let window = Window::new(&event_loop).unwrap();
|
|
println!("Opened a new window: {:?}", window.id());
|
|
windows.insert(window.id(), window);
|
|
|
|
println!("Press N to open a new window.");
|
|
|
|
event_loop.run(move |event, event_loop, control_flow| {
|
|
control_flow.set_wait();
|
|
|
|
match event {
|
|
Event::WindowEvent { event, window_id } => {
|
|
match event {
|
|
WindowEvent::CloseRequested => {
|
|
println!("Window {window_id:?} has received the signal to close");
|
|
|
|
// This drops the window, causing it to close.
|
|
windows.remove(&window_id);
|
|
|
|
if windows.is_empty() {
|
|
control_flow.set_exit();
|
|
}
|
|
}
|
|
WindowEvent::Resized(_) => {
|
|
if let Some(window) = windows.get(&window_id) {
|
|
window.request_redraw();
|
|
}
|
|
}
|
|
WindowEvent::KeyboardInput {
|
|
event:
|
|
KeyEvent {
|
|
state: ElementState::Pressed,
|
|
logical_key,
|
|
..
|
|
},
|
|
is_synthetic: false,
|
|
..
|
|
} => match logical_key.as_ref() {
|
|
Key::Character("t") => {
|
|
let tabbing_id = windows.get(&window_id).unwrap().tabbing_identifier();
|
|
let window = WindowBuilder::new()
|
|
.with_tabbing_identifier(&tabbing_id)
|
|
.build(event_loop)
|
|
.unwrap();
|
|
println!("Added a new tab: {:?}", window.id());
|
|
windows.insert(window.id(), window);
|
|
}
|
|
Key::Character("w") => {
|
|
let _ = windows.remove(&window_id);
|
|
}
|
|
Key::ArrowRight => {
|
|
windows.get(&window_id).unwrap().select_next_tab();
|
|
}
|
|
Key::ArrowLeft => {
|
|
windows.get(&window_id).unwrap().select_previous_tab();
|
|
}
|
|
Key::Character(ch) => {
|
|
if let Ok(index) = ch.parse::<NonZeroUsize>() {
|
|
let index = index.get();
|
|
// Select the last tab when pressing `9`.
|
|
let window = windows.get(&window_id).unwrap();
|
|
if index == 9 {
|
|
window.select_tab_at_index(window.num_tabs() - 1)
|
|
} else {
|
|
window.select_tab_at_index(index - 1);
|
|
}
|
|
}
|
|
}
|
|
_ => (),
|
|
},
|
|
_ => (),
|
|
}
|
|
}
|
|
Event::RedrawRequested(window_id) => {
|
|
if let Some(window) = windows.get(&window_id) {
|
|
fill::fill_window(window);
|
|
}
|
|
}
|
|
_ => (),
|
|
}
|
|
})
|
|
}
|
|
|
|
#[cfg(not(target_os = "macos"))]
|
|
fn main() {
|
|
println!("This example is only supported on MacOS");
|
|
}
|