mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
Propagate error from EventLoop
creation
Inner panics could make it hard to trouble shoot the issues and for some users ints not desirable. The inner panics were left only when they are used to `assert!` during development.
This commit is contained in:
parent
584aab4cd0
commit
ed26dd58fd
|
@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- **Breaking:** `EventLoop::new` and `EventLoopBuilder::build` now return `Result<Self, EventLoopError>`
|
||||||
- **Breaking:** on Wayland, dispatching user created wayland queue won't wake up the loop unless winit has event to send back.
|
- **Breaking:** on Wayland, dispatching user created wayland queue won't wake up the loop unless winit has event to send back.
|
||||||
- Removed platform-specific extensions that should be retrieved through `raw-window-handle` trait implementations instead:
|
- Removed platform-specific extensions that should be retrieved through `raw-window-handle` trait implementations instead:
|
||||||
- `platform::windows::HINSTANCE`.
|
- `platform::windows::HINSTANCE`.
|
||||||
|
@ -50,7 +51,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
- On Web, remove unnecessary `Window::is_dark_mode()`, which was replaced with `Window::theme()`.
|
- On Web, remove unnecessary `Window::is_dark_mode()`, which was replaced with `Window::theme()`.
|
||||||
- On Web, add `WindowBuilderExtWebSys::with_append()` to append the canvas element to the web page on creation.
|
- On Web, add `WindowBuilderExtWebSys::with_append()` to append the canvas element to the web page on creation.
|
||||||
- On Windows, add `drag_resize_window` method support.
|
- On Windows, add `drag_resize_window` method support.
|
||||||
- **Breaking** `run() ->!` has been replaced by `run() -> Result<(), RunLoopError>` for returning errors without calling `std::process::exit()` ([#2767](https://github.com/rust-windowing/winit/pull/2767))
|
- **Breaking** `run() ->!` has been replaced by `run() -> Result<(), EventLoopError>` for returning errors without calling `std::process::exit()` ([#2767](https://github.com/rust-windowing/winit/pull/2767))
|
||||||
- **Breaking** Removed `EventLoopExtRunReturn` / `run_return` in favor of `EventLoopExtPumpEvents` / `pump_events` and `EventLoopExtRunOnDemand` / `run_ondemand` ([#2767](https://github.com/rust-windowing/winit/pull/2767))
|
- **Breaking** Removed `EventLoopExtRunReturn` / `run_return` in favor of `EventLoopExtPumpEvents` / `pump_events` and `EventLoopExtRunOnDemand` / `run_ondemand` ([#2767](https://github.com/rust-windowing/winit/pull/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 no longer guaranteed to be emitted after `MainEventsCleared`, it is now platform-specific when the event is emitted after being requested via `redraw_request()`.
|
||||||
- On Windows, `RedrawRequested` is now driven by `WM_PAINT` messages which are requested via `redraw_request()`
|
- On Windows, `RedrawRequested` is now driven by `WM_PAINT` messages which are requested via `redraw_request()`
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
|
|
||||||
let mut windows = HashMap::new();
|
let mut windows = HashMap::new();
|
||||||
|
|
||||||
let event_loop: EventLoop<()> = EventLoop::new();
|
let event_loop: EventLoop<()> = EventLoop::new().unwrap();
|
||||||
let parent_window = WindowBuilder::new()
|
let parent_window = WindowBuilder::new()
|
||||||
.with_title("parent window")
|
.with_title("parent window")
|
||||||
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
println!("Press 'R' to toggle request_redraw() calls.");
|
println!("Press 'R' to toggle request_redraw() calls.");
|
||||||
println!("Press 'Esc' to close the window.");
|
println!("Press 'Esc' to close the window.");
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.")
|
.with_title("Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.")
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
window.set_title("A fantastic window!");
|
window.set_title("A fantastic window!");
|
||||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Super Cursor Grab'n'Hide Simulator 9000")
|
.with_title("Super Cursor Grab'n'Hide Simulator 9000")
|
||||||
|
|
|
@ -18,7 +18,9 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoopBuilder::<CustomEvent>::with_user_event().build();
|
let event_loop = EventLoopBuilder::<CustomEvent>::with_user_event()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window_1 = WindowBuilder::new().build(&event_loop).unwrap();
|
let window_1 = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
let window_2 = WindowBuilder::new().build(&event_loop).unwrap();
|
let window_2 = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let mut decorations = true;
|
let mut decorations = true;
|
||||||
let mut minimized = false;
|
let mut minimized = false;
|
||||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Your faithful window")
|
.with_title("Your faithful window")
|
||||||
|
|
|
@ -24,7 +24,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
println!("Press F2 to toggle IME. See the documentation of `set_ime_allowed` for more info");
|
println!("Press F2 to toggle IME. See the documentation of `set_ime_allowed` for more info");
|
||||||
println!("Press F3 to cycle through IME purposes.");
|
println!("Press F3 to cycle through IME purposes.");
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_inner_size(winit::dpi::LogicalSize::new(256f64, 128f64))
|
.with_inner_size(winit::dpi::LogicalSize::new(256f64, 128f64))
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
mod fill;
|
mod fill;
|
||||||
|
|
||||||
simple_logger::SimpleLogger::new().init().unwrap();
|
simple_logger::SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_inner_size(LogicalSize::new(400.0, 200.0))
|
.with_inner_size(LogicalSize::new(400.0, 200.0))
|
||||||
|
|
|
@ -7,7 +7,7 @@ use winit::{event_loop::EventLoop, window::WindowBuilder};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
|
|
||||||
if let Some(mon) = window.primary_monitor() {
|
if let Some(mon) = window.primary_monitor() {
|
||||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Mouse Wheel events")
|
.with_title("Mouse Wheel events")
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
const WINDOW_SIZE: PhysicalSize<u32> = PhysicalSize::new(600, 400);
|
const WINDOW_SIZE: PhysicalSize<u32> = PhysicalSize::new(600, 400);
|
||||||
|
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
|
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
|
||||||
for _ in 0..WINDOW_COUNT {
|
for _ in 0..WINDOW_COUNT {
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let mut windows = HashMap::new();
|
let mut windows = HashMap::new();
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -15,7 +15,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
mod fill;
|
mod fill;
|
||||||
|
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = {
|
let window = {
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
|
|
|
@ -14,7 +14,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let mut resizable = false;
|
let mut resizable = false;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ mod example {
|
||||||
|
|
||||||
pub(super) fn main() -> Result<(), impl std::error::Error> {
|
pub(super) fn main() -> Result<(), impl std::error::Error> {
|
||||||
// Create the event loop and get the activation token.
|
// Create the event loop and get the activation token.
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let mut current_token = match event_loop.read_token_from_env() {
|
let mut current_token = match event_loop.read_token_from_env() {
|
||||||
Some(token) => Some(token),
|
Some(token) => Some(token),
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -18,7 +18,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -10,7 +10,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("Touchpad gestures")
|
.with_title("Touchpad gestures")
|
||||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_decorations(false)
|
.with_decorations(false)
|
||||||
|
|
|
@ -5,7 +5,7 @@ use winit::event_loop::EventLoop;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let monitor = match event_loop.primary_monitor() {
|
let monitor = match event_loop.primary_monitor() {
|
||||||
Some(monitor) => monitor,
|
Some(monitor) => monitor,
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use winit::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn main() -> Result<(), impl std::error::Error> {
|
pub fn main() -> Result<(), impl std::error::Error> {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let builder = WindowBuilder::new().with_title("A fantastic window!");
|
let builder = WindowBuilder::new().with_title("A fantastic window!");
|
||||||
#[cfg(wasm_platform)]
|
#[cfg(wasm_platform)]
|
||||||
|
|
|
@ -31,7 +31,7 @@ This example demonstrates the desired future functionality which will possibly b
|
||||||
#[wasm_bindgen(start)]
|
#[wasm_bindgen(start)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
console_log::init_with_level(log::Level::Debug).expect("error initializing logger");
|
console_log::init_with_level(log::Level::Debug).expect("error initializing logger");
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -16,7 +16,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -16,7 +16,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_inner_size(winit::dpi::LogicalSize::new(600.0, 400.0))
|
.with_inner_size(winit::dpi::LogicalSize::new(600.0, 400.0))
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
|
|
||||||
let icon = load_icon(Path::new(path));
|
let icon = load_icon(Path::new(path));
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("An iconic window!")
|
.with_title("An iconic window!")
|
||||||
|
|
|
@ -8,7 +8,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
use simple_logger::SimpleLogger;
|
use simple_logger::SimpleLogger;
|
||||||
|
|
||||||
use winit::{
|
use winit::{
|
||||||
error::RunLoopError,
|
error::EventLoopError,
|
||||||
event::{Event, WindowEvent},
|
event::{Event, WindowEvent},
|
||||||
event_loop::EventLoop,
|
event_loop::EventLoop,
|
||||||
platform::run_ondemand::EventLoopExtRunOnDemand,
|
platform::run_ondemand::EventLoopExtRunOnDemand,
|
||||||
|
@ -25,9 +25,9 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let mut event_loop = EventLoop::new();
|
let mut event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
fn run_app(event_loop: &mut EventLoop<()>, idx: usize) -> Result<(), RunLoopError> {
|
fn run_app(event_loop: &mut EventLoop<()>, idx: usize) -> Result<(), EventLoopError> {
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
|
||||||
event_loop.run_ondemand(move |event, event_loop, control_flow| {
|
event_loop.run_ondemand(move |event, event_loop, control_flow| {
|
||||||
|
|
|
@ -19,7 +19,7 @@ mod fill;
|
||||||
/// A left mouse click will toggle option_is_alt.
|
/// A left mouse click will toggle option_is_alt.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn main() -> std::process::ExitCode {
|
||||||
#[path = "util/fill.rs"]
|
#[path = "util/fill.rs"]
|
||||||
mod fill;
|
mod fill;
|
||||||
|
|
||||||
let mut event_loop = EventLoop::new();
|
let mut event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
||||||
|
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_title("A fantastic window!")
|
.with_title("A fantastic window!")
|
||||||
|
|
|
@ -21,7 +21,7 @@ mod fill;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn main() -> Result<(), impl std::error::Error> {
|
fn main() -> Result<(), impl std::error::Error> {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
|
||||||
let mut windows = HashMap::new();
|
let mut windows = HashMap::new();
|
||||||
let window = Window::new(&event_loop).unwrap();
|
let window = Window::new(&event_loop).unwrap();
|
||||||
|
|
20
src/error.rs
20
src/error.rs
|
@ -30,7 +30,7 @@ pub struct OsError {
|
||||||
|
|
||||||
/// A general error that may occur while running the Winit event loop
|
/// A general error that may occur while running the Winit event loop
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RunLoopError {
|
pub enum EventLoopError {
|
||||||
/// The operation is not supported by the backend.
|
/// The operation is not supported by the backend.
|
||||||
NotSupported(NotSupportedError),
|
NotSupported(NotSupportedError),
|
||||||
/// The OS cannot perform the operation.
|
/// The OS cannot perform the operation.
|
||||||
|
@ -41,6 +41,12 @@ pub enum RunLoopError {
|
||||||
ExitFailure(i32),
|
ExitFailure(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<OsError> for EventLoopError {
|
||||||
|
fn from(value: OsError) -> Self {
|
||||||
|
Self::Os(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl NotSupportedError {
|
impl NotSupportedError {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -94,13 +100,13 @@ impl fmt::Display for NotSupportedError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for RunLoopError {
|
impl fmt::Display for EventLoopError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
RunLoopError::AlreadyRunning => write!(f, "EventLoop is already running"),
|
EventLoopError::AlreadyRunning => write!(f, "EventLoop is already running"),
|
||||||
RunLoopError::NotSupported(e) => e.fmt(f),
|
EventLoopError::NotSupported(e) => e.fmt(f),
|
||||||
RunLoopError::Os(e) => e.fmt(f),
|
EventLoopError::Os(e) => e.fmt(f),
|
||||||
RunLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"),
|
EventLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +114,7 @@ impl fmt::Display for RunLoopError {
|
||||||
impl error::Error for OsError {}
|
impl error::Error for OsError {}
|
||||||
impl error::Error for ExternalError {}
|
impl error::Error for ExternalError {}
|
||||||
impl error::Error for NotSupportedError {}
|
impl error::Error for NotSupportedError {}
|
||||||
impl error::Error for RunLoopError {}
|
impl error::Error for EventLoopError {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use std::time::{Duration, Instant};
|
||||||
#[cfg(wasm_platform)]
|
#[cfg(wasm_platform)]
|
||||||
use web_time::{Duration, Instant};
|
use web_time::{Duration, Instant};
|
||||||
|
|
||||||
use crate::error::RunLoopError;
|
use crate::error::EventLoopError;
|
||||||
use crate::{event::Event, monitor::MonitorHandle, platform_impl};
|
use crate::{event::Event, monitor::MonitorHandle, platform_impl};
|
||||||
|
|
||||||
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
||||||
|
@ -88,21 +88,18 @@ impl<T> EventLoopBuilder<T> {
|
||||||
/// ***For cross-platform compatibility, the [`EventLoop`] must be created on the main thread,
|
/// ***For cross-platform compatibility, the [`EventLoop`] must be created on the main thread,
|
||||||
/// and only once per application.***
|
/// and only once per application.***
|
||||||
///
|
///
|
||||||
/// Attempting to create the event loop on a different thread, or multiple event loops in
|
/// Attempting to create the event loop on a different thread, or multiple
|
||||||
/// the same application, will panic. This restriction isn't
|
/// event loops in the same application, will panic. This restriction
|
||||||
/// strictly necessary on all platforms, but is imposed to eliminate any nasty surprises when
|
/// isn't strictly necessary on all platforms, but is imposed to eliminate
|
||||||
/// porting to platforms that require it. `EventLoopBuilderExt::any_thread` functions are exposed
|
/// any nasty surprises when porting to platforms that require it.
|
||||||
/// in the relevant [`platform`] module if the target platform supports creating an event loop on
|
/// `EventLoopBuilderExt::any_thread` functions are exposed in the relevant
|
||||||
/// any thread.
|
/// [`platform`] module if the target platform supports creating an event
|
||||||
|
/// loop on any thread.
|
||||||
///
|
///
|
||||||
/// Calling this function will result in display backend initialisation.
|
/// Calling this function will result in display backend initialisation.
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// ## Platform-specific
|
||||||
///
|
///
|
||||||
/// - **Linux:** Backend type can be controlled using an environment variable
|
|
||||||
/// `WINIT_UNIX_BACKEND`. Legal values are `x11` and `wayland`.
|
|
||||||
/// If it is not set, winit will try to connect to a Wayland connection, and if that fails,
|
|
||||||
/// will fall back on X11. If this variable is set with any other value, winit will panic.
|
|
||||||
/// - **Android:** Must be configured with an `AndroidApp` from `android_main()` by calling
|
/// - **Android:** Must be configured with an `AndroidApp` from `android_main()` by calling
|
||||||
/// [`.with_android_app(app)`] before calling `.build()`.
|
/// [`.with_android_app(app)`] before calling `.build()`.
|
||||||
///
|
///
|
||||||
|
@ -116,17 +113,17 @@ impl<T> EventLoopBuilder<T> {
|
||||||
doc = "[`.with_android_app(app)`]: #only-available-on-android"
|
doc = "[`.with_android_app(app)`]: #only-available-on-android"
|
||||||
)]
|
)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build(&mut self) -> EventLoop<T> {
|
pub fn build(&mut self) -> Result<EventLoop<T>, EventLoopError> {
|
||||||
if EVENT_LOOP_CREATED.swap(true, Ordering::Relaxed) {
|
if EVENT_LOOP_CREATED.swap(true, Ordering::Relaxed) {
|
||||||
panic!("Creating EventLoop multiple times is not supported.");
|
return Err(EventLoopError::AlreadyRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Certain platforms accept a mutable reference in their API.
|
// Certain platforms accept a mutable reference in their API.
|
||||||
#[allow(clippy::unnecessary_mut_passed)]
|
#[allow(clippy::unnecessary_mut_passed)]
|
||||||
EventLoop {
|
Ok(EventLoop {
|
||||||
event_loop: platform_impl::EventLoop::new(&mut self.platform_specific),
|
event_loop: platform_impl::EventLoop::new(&mut self.platform_specific)?,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(wasm_platform)]
|
#[cfg(wasm_platform)]
|
||||||
|
@ -269,20 +266,14 @@ impl EventLoop<()> {
|
||||||
///
|
///
|
||||||
/// [`EventLoopBuilder::new().build()`]: EventLoopBuilder::build
|
/// [`EventLoopBuilder::new().build()`]: EventLoopBuilder::build
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> EventLoop<()> {
|
pub fn new() -> Result<EventLoop<()>, EventLoopError> {
|
||||||
EventLoopBuilder::new().build()
|
EventLoopBuilder::new().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EventLoop<()> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> EventLoop<T> {
|
impl<T> EventLoop<T> {
|
||||||
#[deprecated = "Use `EventLoopBuilder::<T>::with_user_event().build()` instead."]
|
#[deprecated = "Use `EventLoopBuilder::<T>::with_user_event().build()` instead."]
|
||||||
pub fn with_user_event() -> EventLoop<T> {
|
pub fn with_user_event() -> Result<EventLoop<T>, EventLoopError> {
|
||||||
EventLoopBuilder::<T>::with_user_event().build()
|
EventLoopBuilder::<T>::with_user_event().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +306,7 @@ impl<T> EventLoop<T> {
|
||||||
/// [`ControlFlow`]: crate::event_loop::ControlFlow
|
/// [`ControlFlow`]: crate::event_loop::ControlFlow
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(all(wasm_platform, target_feature = "exception-handling")))]
|
#[cfg(not(all(wasm_platform, target_feature = "exception-handling")))]
|
||||||
pub fn run<F>(self, event_handler: F) -> Result<(), RunLoopError>
|
pub fn run<F>(self, event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use winit::event_loop::EventLoop;
|
//! use winit::event_loop::EventLoop;
|
||||||
//! let event_loop = EventLoop::new();
|
//! let event_loop = EventLoop::new().unwrap();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Once this is done there are two ways to create a [`Window`]:
|
//! Once this is done there are two ways to create a [`Window`]:
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
//! window::WindowBuilder,
|
//! window::WindowBuilder,
|
||||||
//! };
|
//! };
|
||||||
//!
|
//!
|
||||||
//! let event_loop = EventLoop::new();
|
//! let event_loop = EventLoop::new().unwrap();
|
||||||
//! let window = WindowBuilder::new().build(&event_loop).unwrap();
|
//! let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
//!
|
//!
|
||||||
//! event_loop.run(move |event, _, control_flow| {
|
//! event_loop.run(move |event, _, control_flow| {
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub trait EventLoopExtPumpEvents {
|
||||||
/// # platform::pump_events::{EventLoopExtPumpEvents, PumpStatus},
|
/// # platform::pump_events::{EventLoopExtPumpEvents, PumpStatus},
|
||||||
/// # window::WindowBuilder,
|
/// # window::WindowBuilder,
|
||||||
/// # };
|
/// # };
|
||||||
/// let mut event_loop = EventLoop::new();
|
/// let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// #
|
/// #
|
||||||
/// # SimpleLogger::new().init().unwrap();
|
/// # SimpleLogger::new().init().unwrap();
|
||||||
/// let window = WindowBuilder::new()
|
/// let window = WindowBuilder::new()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
error::RunLoopError,
|
error::EventLoopError,
|
||||||
event::Event,
|
event::Event,
|
||||||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
||||||
};
|
};
|
||||||
|
@ -57,7 +57,7 @@ pub trait EventLoopExtRunOnDemand {
|
||||||
/// polled to ask for new events. Events are delivered via callbacks based
|
/// polled to ask for new events. Events are delivered via callbacks based
|
||||||
/// on an event loop that is internal to the browser itself.
|
/// on an event loop that is internal to the browser itself.
|
||||||
/// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS.
|
/// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS.
|
||||||
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ pub trait EventLoopExtRunOnDemand {
|
||||||
impl<T> EventLoopExtRunOnDemand for EventLoop<T> {
|
impl<T> EventLoopExtRunOnDemand for EventLoop<T> {
|
||||||
type UserEvent = T;
|
type UserEvent = T;
|
||||||
|
|
||||||
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
|
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ use crate::{
|
||||||
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
|
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::{error::RunLoopError, platform_impl::Fullscreen};
|
use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
||||||
|
|
||||||
mod keycodes;
|
mod keycodes;
|
||||||
|
|
||||||
|
@ -186,13 +186,15 @@ fn sticky_exit_callback<T, F>(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(
|
||||||
|
attributes: &PlatformSpecificEventLoopAttributes,
|
||||||
|
) -> Result<Self, EventLoopError> {
|
||||||
let (user_events_sender, user_events_receiver) = mpsc::channel();
|
let (user_events_sender, user_events_receiver) = mpsc::channel();
|
||||||
|
|
||||||
let android_app = attributes.android_app.as_ref().expect("An `AndroidApp` as passed to android_main() is required to create an `EventLoop` on Android");
|
let android_app = attributes.android_app.as_ref().expect("An `AndroidApp` as passed to android_main() is required to create an `EventLoop` on Android");
|
||||||
let redraw_flag = SharedFlag::new();
|
let redraw_flag = SharedFlag::new();
|
||||||
|
|
||||||
Self {
|
Ok(Self {
|
||||||
android_app: android_app.clone(),
|
android_app: android_app.clone(),
|
||||||
window_target: event_loop::EventLoopWindowTarget {
|
window_target: event_loop::EventLoopWindowTarget {
|
||||||
p: EventLoopWindowTarget {
|
p: EventLoopWindowTarget {
|
||||||
|
@ -214,7 +216,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
control_flow: Default::default(),
|
control_flow: Default::default(),
|
||||||
cause: StartCause::Init,
|
cause: StartCause::Init,
|
||||||
ignore_volume_keys: attributes.ignore_volume_keys,
|
ignore_volume_keys: attributes.ignore_volume_keys,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_iteration<F>(&mut self, main_event: Option<MainEvent<'_>>, callback: &mut F)
|
fn single_iteration<F>(&mut self, main_event: Option<MainEvent<'_>>, callback: &mut F)
|
||||||
|
@ -524,19 +526,19 @@ impl<T: 'static> EventLoop<T> {
|
||||||
self.pending_redraw = pending_redraw;
|
self.pending_redraw = pending_redraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(event_handler)
|
self.run_ondemand(event_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if self.loop_running {
|
if self.loop_running {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(EventLoopError::AlreadyRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -545,7 +547,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
break Ok(());
|
break Ok(());
|
||||||
}
|
}
|
||||||
PumpStatus::Exit(code) => {
|
PumpStatus::Exit(code) => {
|
||||||
break Err(RunLoopError::ExitFailure(code));
|
break Err(EventLoopError::ExitFailure(code));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -19,11 +19,9 @@ use objc2::rc::Id;
|
||||||
use objc2::ClassType;
|
use objc2::ClassType;
|
||||||
use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle};
|
use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle};
|
||||||
|
|
||||||
use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen};
|
|
||||||
use super::view::WinitUIWindow;
|
|
||||||
use super::{app_state, monitor, view, MonitorHandle};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
|
error::EventLoopError,
|
||||||
event::Event,
|
event::Event,
|
||||||
event_loop::{
|
event_loop::{
|
||||||
ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootEventLoopWindowTarget,
|
ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootEventLoopWindowTarget,
|
||||||
|
@ -31,6 +29,10 @@ use crate::{
|
||||||
platform::ios::Idiom,
|
platform::ios::Idiom,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen};
|
||||||
|
use super::view::WinitUIWindow;
|
||||||
|
use super::{app_state, monitor, view, MonitorHandle};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum EventWrapper {
|
pub(crate) enum EventWrapper {
|
||||||
StaticEvent(Event<Never>),
|
StaticEvent(Event<Never>),
|
||||||
|
@ -75,7 +77,9 @@ pub struct EventLoop<T: 'static> {
|
||||||
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> EventLoop<T> {
|
pub(crate) fn new(
|
||||||
|
_: &PlatformSpecificEventLoopAttributes,
|
||||||
|
) -> Result<EventLoop<T>, EventLoopError> {
|
||||||
assert_main_thread!("`EventLoop` can only be created on the main thread on iOS");
|
assert_main_thread!("`EventLoop` can only be created on the main thread on iOS");
|
||||||
|
|
||||||
static mut SINGLETON_INIT: bool = false;
|
static mut SINGLETON_INIT: bool = false;
|
||||||
|
@ -93,7 +97,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
// this line sets up the main run loop before `UIApplicationMain`
|
// this line sets up the main run loop before `UIApplicationMain`
|
||||||
setup_control_flow_observers();
|
setup_control_flow_observers();
|
||||||
|
|
||||||
EventLoop {
|
Ok(EventLoop {
|
||||||
window_target: RootEventLoopWindowTarget {
|
window_target: RootEventLoopWindowTarget {
|
||||||
p: EventLoopWindowTarget {
|
p: EventLoopWindowTarget {
|
||||||
receiver,
|
receiver,
|
||||||
|
@ -101,7 +105,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
},
|
},
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(self, event_handler: F) -> !
|
pub fn run<F>(self, event_handler: F) -> !
|
||||||
|
|
|
@ -3,33 +3,22 @@
|
||||||
#[cfg(all(not(x11_platform), not(wayland_platform)))]
|
#[cfg(all(not(x11_platform), not(wayland_platform)))]
|
||||||
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
|
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
|
||||||
|
|
||||||
#[cfg(wayland_platform)]
|
use std::sync::Arc;
|
||||||
use std::error::Error;
|
use std::time::Duration;
|
||||||
|
|
||||||
use std::{collections::VecDeque, env, fmt};
|
use std::{collections::VecDeque, env, fmt};
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
use std::{
|
use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Mutex};
|
||||||
ffi::CStr,
|
|
||||||
mem::MaybeUninit,
|
|
||||||
os::raw::*,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
#[cfg(x11_platform)]
|
|
||||||
pub use self::x11::XNotSupported;
|
|
||||||
#[cfg(x11_platform)]
|
|
||||||
use self::x11::{util::WindowType as XWindowType, X11Error, XConnection, XError};
|
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
use crate::platform::x11::XlibErrorHook;
|
use crate::platform::x11::XlibErrorHook;
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
||||||
error::{ExternalError, NotSupportedError, OsError as RootOsError, RunLoopError},
|
error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError},
|
||||||
event::{Event, KeyEvent},
|
event::{Event, KeyEvent},
|
||||||
event_loop::{
|
event_loop::{
|
||||||
AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed,
|
AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed,
|
||||||
|
@ -46,6 +35,10 @@ use crate::{
|
||||||
UserAttentionType, WindowAttributes, WindowButtons, WindowLevel,
|
UserAttentionType, WindowAttributes, WindowButtons, WindowLevel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#[cfg(x11_platform)]
|
||||||
|
pub use x11::XNotSupported;
|
||||||
|
#[cfg(x11_platform)]
|
||||||
|
use x11::{util::WindowType as XWindowType, X11Error, XConnection, XError};
|
||||||
|
|
||||||
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
||||||
pub(crate) use crate::platform_impl::Fullscreen;
|
pub(crate) use crate::platform_impl::Fullscreen;
|
||||||
|
@ -56,15 +49,6 @@ pub mod wayland;
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
pub mod x11;
|
pub mod x11;
|
||||||
|
|
||||||
/// Environment variable specifying which backend should be used on unix platform.
|
|
||||||
///
|
|
||||||
/// Legal values are x11 and wayland. If this variable is set only the named backend
|
|
||||||
/// will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
|
||||||
/// and if it fails will fallback on x11.
|
|
||||||
///
|
|
||||||
/// If this variable is set with any other value, winit will panic.
|
|
||||||
const BACKEND_PREFERENCE_ENV_VAR: &str = "WINIT_UNIX_BACKEND";
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub(crate) enum Backend {
|
pub(crate) enum Backend {
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
|
@ -132,23 +116,21 @@ pub(crate) static X11_BACKEND: Lazy<Mutex<Result<Arc<XConnection>, XNotSupported
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum OsError {
|
pub enum OsError {
|
||||||
|
Misc(&'static str),
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
XError(Arc<X11Error>),
|
XError(Arc<X11Error>),
|
||||||
#[cfg(x11_platform)]
|
|
||||||
XMisc(&'static str),
|
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
WaylandMisc(&'static str),
|
WaylandError(Arc<wayland::WaylandError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for OsError {
|
impl fmt::Display for OsError {
|
||||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
|
OsError::Misc(e) => _f.pad(e),
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
OsError::XError(ref e) => fmt::Display::fmt(e, _f),
|
OsError::XError(ref e) => fmt::Display::fmt(e, _f),
|
||||||
#[cfg(x11_platform)]
|
|
||||||
OsError::XMisc(e) => _f.pad(e),
|
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
OsError::WaylandMisc(e) => _f.pad(e),
|
OsError::WaylandError(ref e) => fmt::Display::fmt(e, _f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -744,7 +726,9 @@ impl<T: 'static> Clone for EventLoopProxy<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(
|
||||||
|
attributes: &PlatformSpecificEventLoopAttributes,
|
||||||
|
) -> Result<Self, EventLoopError> {
|
||||||
if !attributes.any_thread && !is_main_thread() {
|
if !attributes.any_thread && !is_main_thread() {
|
||||||
panic!(
|
panic!(
|
||||||
"Initializing the event loop outside of the main thread is a significant \
|
"Initializing the event loop outside of the main thread is a significant \
|
||||||
|
@ -754,65 +738,26 @@ impl<T: 'static> EventLoop<T> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(x11_platform)]
|
// NOTE: Wayland first because of X11 could be present under wayland as well.
|
||||||
if attributes.forced_backend == Some(Backend::X) {
|
|
||||||
// TODO: Propagate
|
|
||||||
return EventLoop::new_x11_any_thread().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
if attributes.forced_backend == Some(Backend::Wayland) {
|
if attributes.forced_backend == Some(Backend::Wayland)
|
||||||
// TODO: Propagate
|
|| env::var("WAYLAND_DISPLAY").is_ok()
|
||||||
return EventLoop::new_wayland_any_thread().expect("failed to open Wayland connection");
|
{
|
||||||
|
return EventLoop::new_wayland_any_thread().map_err(Into::into);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) {
|
|
||||||
match env_var.as_str() {
|
|
||||||
"x11" => {
|
|
||||||
// TODO: propagate
|
|
||||||
#[cfg(x11_platform)]
|
|
||||||
return EventLoop::new_x11_any_thread()
|
|
||||||
.expect("Failed to initialize X11 backend");
|
|
||||||
#[cfg(not(x11_platform))]
|
|
||||||
panic!("x11 feature is not enabled")
|
|
||||||
}
|
|
||||||
"wayland" => {
|
|
||||||
#[cfg(wayland_platform)]
|
|
||||||
return EventLoop::new_wayland_any_thread()
|
|
||||||
.expect("Failed to initialize Wayland backend");
|
|
||||||
#[cfg(not(wayland_platform))]
|
|
||||||
panic!("wayland feature is not enabled");
|
|
||||||
}
|
|
||||||
_ => panic!(
|
|
||||||
"Unknown environment variable value for {BACKEND_PREFERENCE_ENV_VAR}, try one of `x11`,`wayland`",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(wayland_platform)]
|
|
||||||
let wayland_err = match EventLoop::new_wayland_any_thread() {
|
|
||||||
Ok(event_loop) => return event_loop,
|
|
||||||
Err(err) => err,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
let x11_err = match EventLoop::new_x11_any_thread() {
|
if attributes.forced_backend == Some(Backend::X) || env::var("DISPLAY").is_ok() {
|
||||||
Ok(event_loop) => return event_loop,
|
return Ok(EventLoop::new_x11_any_thread().unwrap());
|
||||||
Err(err) => err,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(not(wayland_platform))]
|
Err(EventLoopError::Os(os_error!(OsError::Misc(
|
||||||
let wayland_err = "backend disabled";
|
"neither WAYLAND_DISPLAY nor DISPLAY is set."
|
||||||
#[cfg(not(x11_platform))]
|
))))
|
||||||
let x11_err = "backend disabled";
|
|
||||||
|
|
||||||
panic!(
|
|
||||||
"Failed to initialize any backend! Wayland status: {wayland_err:?} X11 status: {x11_err:?}",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
fn new_wayland_any_thread() -> Result<EventLoop<T>, Box<dyn Error>> {
|
fn new_wayland_any_thread() -> Result<EventLoop<T>, EventLoopError> {
|
||||||
wayland::EventLoop::new().map(|evlp| EventLoop::Wayland(Box::new(evlp)))
|
wayland::EventLoop::new().map(|evlp| EventLoop::Wayland(Box::new(evlp)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,14 +775,14 @@ impl<T: 'static> EventLoop<T> {
|
||||||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
|
x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, callback: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(callback)
|
self.run_ondemand(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! The event-loop routines.
|
//! The event-loop routines.
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::error::Error;
|
|
||||||
use std::io::Result as IOResult;
|
use std::io::Result as IOResult;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -13,11 +12,12 @@ use std::time::{Duration, Instant};
|
||||||
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
|
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
|
||||||
|
|
||||||
use sctk::reexports::calloop;
|
use sctk::reexports::calloop;
|
||||||
|
use sctk::reexports::calloop::Error as CalloopError;
|
||||||
use sctk::reexports::client::globals;
|
use sctk::reexports::client::globals;
|
||||||
use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource};
|
use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource};
|
||||||
|
|
||||||
use crate::dpi::{LogicalSize, PhysicalSize};
|
use crate::dpi::{LogicalSize, PhysicalSize};
|
||||||
use crate::error::{OsError as RootOsError, RunLoopError};
|
use crate::error::{EventLoopError, OsError as RootOsError};
|
||||||
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
||||||
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
|
@ -33,7 +33,7 @@ use sink::EventSink;
|
||||||
|
|
||||||
use super::state::{WindowCompositorUpdate, WinitState};
|
use super::state::{WindowCompositorUpdate, WinitState};
|
||||||
use super::window::state::FrameCallbackState;
|
use super::window::state::FrameCallbackState;
|
||||||
use super::{DeviceId, WindowId};
|
use super::{DeviceId, WaylandError, WindowId};
|
||||||
|
|
||||||
type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource<WinitState>, WinitState>;
|
type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource<WinitState>, WinitState>;
|
||||||
|
|
||||||
|
@ -73,22 +73,38 @@ pub struct EventLoop<T: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub fn new() -> Result<EventLoop<T>, Box<dyn Error>> {
|
pub fn new() -> Result<EventLoop<T>, EventLoopError> {
|
||||||
let connection = Connection::connect_to_env()?;
|
macro_rules! map_err {
|
||||||
|
($e:expr, $err:expr) => {
|
||||||
|
$e.map_err(|error| os_error!($err(error).into()))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let (globals, mut event_queue) = globals::registry_queue_init(&connection)?;
|
let connection = map_err!(Connection::connect_to_env(), WaylandError::Connection)?;
|
||||||
|
|
||||||
|
let (globals, mut event_queue) = map_err!(
|
||||||
|
globals::registry_queue_init(&connection),
|
||||||
|
WaylandError::Global
|
||||||
|
)?;
|
||||||
let queue_handle = event_queue.handle();
|
let queue_handle = event_queue.handle();
|
||||||
|
|
||||||
let event_loop = calloop::EventLoop::<WinitState>::try_new()?;
|
let event_loop = map_err!(
|
||||||
|
calloop::EventLoop::<WinitState>::try_new(),
|
||||||
|
WaylandError::Calloop
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut winit_state = WinitState::new(&globals, &queue_handle, event_loop.handle())?;
|
let mut winit_state = WinitState::new(&globals, &queue_handle, event_loop.handle())
|
||||||
|
.map_err(|error| os_error!(error))?;
|
||||||
|
|
||||||
// NOTE: do a roundtrip after binding the globals to prevent potential
|
// NOTE: do a roundtrip after binding the globals to prevent potential
|
||||||
// races with the server.
|
// races with the server.
|
||||||
event_queue.roundtrip(&mut winit_state)?;
|
map_err!(
|
||||||
|
event_queue.roundtrip(&mut winit_state),
|
||||||
|
WaylandError::Dispatch
|
||||||
|
)?;
|
||||||
|
|
||||||
// Register Wayland source.
|
// Register Wayland source.
|
||||||
let wayland_source = WaylandSource::new(event_queue)?;
|
let wayland_source = map_err!(WaylandSource::new(event_queue), WaylandError::Wire)?;
|
||||||
let wayland_dispatcher =
|
let wayland_dispatcher =
|
||||||
calloop::Dispatcher::new(wayland_source, |_, queue, winit_state: &mut WinitState| {
|
calloop::Dispatcher::new(wayland_source, |_, queue, winit_state: &mut WinitState| {
|
||||||
let result = queue.dispatch_pending(winit_state);
|
let result = queue.dispatch_pending(winit_state);
|
||||||
|
@ -101,32 +117,52 @@ impl<T: 'static> EventLoop<T> {
|
||||||
result
|
result
|
||||||
});
|
});
|
||||||
|
|
||||||
event_loop
|
map_err!(
|
||||||
.handle()
|
event_loop
|
||||||
.register_dispatcher(wayland_dispatcher.clone())?;
|
.handle()
|
||||||
|
.register_dispatcher(wayland_dispatcher.clone()),
|
||||||
|
WaylandError::Calloop
|
||||||
|
)?;
|
||||||
|
|
||||||
// Setup the user proxy.
|
// Setup the user proxy.
|
||||||
let pending_user_events = Rc::new(RefCell::new(Vec::new()));
|
let pending_user_events = Rc::new(RefCell::new(Vec::new()));
|
||||||
let pending_user_events_clone = pending_user_events.clone();
|
let pending_user_events_clone = pending_user_events.clone();
|
||||||
let (user_events_sender, user_events_channel) = calloop::channel::channel();
|
let (user_events_sender, user_events_channel) = calloop::channel::channel();
|
||||||
event_loop.handle().insert_source(
|
map_err!(
|
||||||
user_events_channel,
|
event_loop
|
||||||
move |event, _, winit_state: &mut WinitState| {
|
.handle()
|
||||||
if let calloop::channel::Event::Msg(msg) = event {
|
.insert_source(
|
||||||
winit_state.dispatched_events = true;
|
user_events_channel,
|
||||||
pending_user_events_clone.borrow_mut().push(msg);
|
move |event, _, winit_state: &mut WinitState| {
|
||||||
}
|
if let calloop::channel::Event::Msg(msg) = event {
|
||||||
},
|
winit_state.dispatched_events = true;
|
||||||
|
pending_user_events_clone.borrow_mut().push(msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.map_err(|error| error.error),
|
||||||
|
WaylandError::Calloop
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// An event's loop awakener to wake up for window events from winit's windows.
|
// An event's loop awakener to wake up for window events from winit's windows.
|
||||||
let (event_loop_awakener, event_loop_awakener_source) = calloop::ping::make_ping()?;
|
let (event_loop_awakener, event_loop_awakener_source) = map_err!(
|
||||||
event_loop.handle().insert_source(
|
calloop::ping::make_ping()
|
||||||
event_loop_awakener_source,
|
.map_err(|error| CalloopError::OtherError(Box::new(error).into())),
|
||||||
move |_, _, winit_state: &mut WinitState| {
|
WaylandError::Calloop
|
||||||
// No extra handling is required, we just need to wake-up.
|
)?;
|
||||||
winit_state.dispatched_events = true;
|
|
||||||
},
|
map_err!(
|
||||||
|
event_loop
|
||||||
|
.handle()
|
||||||
|
.insert_source(
|
||||||
|
event_loop_awakener_source,
|
||||||
|
move |_, _, winit_state: &mut WinitState| {
|
||||||
|
// No extra handling is required, we just need to wake-up.
|
||||||
|
winit_state.dispatched_events = true;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.map_err(|error| error.error),
|
||||||
|
WaylandError::Calloop
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let window_target = EventLoopWindowTarget {
|
let window_target = EventLoopWindowTarget {
|
||||||
|
@ -158,12 +194,12 @@ impl<T: 'static> EventLoop<T> {
|
||||||
Ok(event_loop)
|
Ok(event_loop)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if self.loop_running {
|
if self.loop_running {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(EventLoopError::AlreadyRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
let exit = loop {
|
let exit = loop {
|
||||||
|
@ -172,7 +208,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
break Ok(());
|
break Ok(());
|
||||||
}
|
}
|
||||||
PumpStatus::Exit(code) => {
|
PumpStatus::Exit(code) => {
|
||||||
break Err(RunLoopError::ExitFailure(code));
|
break Err(EventLoopError::ExitFailure(code));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
continue;
|
continue;
|
||||||
|
@ -184,7 +220,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
// `run_ondemand` calls but if they have only just dropped their
|
// `run_ondemand` calls but if they have only just dropped their
|
||||||
// windows we need to make sure those last requests are sent to the
|
// windows we need to make sure those last requests are sent to the
|
||||||
// compositor.
|
// compositor.
|
||||||
let _ = self.roundtrip().map_err(RunLoopError::Os);
|
let _ = self.roundtrip().map_err(EventLoopError::Os);
|
||||||
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
@ -617,10 +653,10 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
let mut wayland_source = self.wayland_dispatcher.as_source_mut();
|
let mut wayland_source = self.wayland_dispatcher.as_source_mut();
|
||||||
let event_queue = wayland_source.queue();
|
let event_queue = wayland_source.queue();
|
||||||
event_queue.roundtrip(state).map_err(|_| {
|
event_queue.roundtrip(state).map_err(|error| {
|
||||||
os_error!(OsError::WaylandMisc(
|
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
|
||||||
"failed to do a final roundtrip before exiting the loop."
|
error
|
||||||
))
|
))))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
//! Winit's Wayland backend.
|
//! Winit's Wayland backend.
|
||||||
|
|
||||||
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
use std::fmt::Display;
|
||||||
use sctk::reexports::client::Proxy;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub use crate::platform_impl::platform::WindowId;
|
use sctk::reexports::client::globals::{BindError, GlobalError};
|
||||||
|
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
|
use sctk::reexports::client::{self, ConnectError, DispatchError, Proxy};
|
||||||
|
|
||||||
|
pub use crate::platform_impl::platform::{OsError, WindowId};
|
||||||
pub use event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
pub use event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
||||||
pub use output::{MonitorHandle, VideoMode};
|
pub use output::{MonitorHandle, VideoMode};
|
||||||
pub use window::Window;
|
pub use window::Window;
|
||||||
|
@ -17,6 +21,46 @@ mod state;
|
||||||
mod types;
|
mod types;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum WaylandError {
|
||||||
|
/// Error connecting to the socket.
|
||||||
|
Connection(ConnectError),
|
||||||
|
|
||||||
|
/// Error binding the global.
|
||||||
|
Global(GlobalError),
|
||||||
|
|
||||||
|
// Bind error.
|
||||||
|
Bind(BindError),
|
||||||
|
|
||||||
|
/// Error during the dispatching the event queue.
|
||||||
|
Dispatch(DispatchError),
|
||||||
|
|
||||||
|
/// Calloop error.
|
||||||
|
Calloop(calloop::Error),
|
||||||
|
|
||||||
|
/// Wayland
|
||||||
|
Wire(client::backend::WaylandError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for WaylandError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
WaylandError::Connection(error) => error.fmt(f),
|
||||||
|
WaylandError::Global(error) => error.fmt(f),
|
||||||
|
WaylandError::Bind(error) => error.fmt(f),
|
||||||
|
WaylandError::Dispatch(error) => error.fmt(f),
|
||||||
|
WaylandError::Calloop(error) => error.fmt(f),
|
||||||
|
WaylandError::Wire(error) => error.fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WaylandError> for OsError {
|
||||||
|
fn from(value: WaylandError) -> Self {
|
||||||
|
Self::WaylandError(Arc::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Dummy device id, since Wayland doesn't have device events.
|
/// Dummy device id, since Wayland doesn't have device events.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct DeviceId;
|
pub struct DeviceId;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::error::Error;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
@ -24,6 +23,7 @@ use sctk::shm::{Shm, ShmHandler};
|
||||||
use sctk::subcompositor::SubcompositorState;
|
use sctk::subcompositor::SubcompositorState;
|
||||||
|
|
||||||
use crate::dpi::LogicalSize;
|
use crate::dpi::LogicalSize;
|
||||||
|
use crate::platform_impl::OsError;
|
||||||
|
|
||||||
use super::event_loop::sink::EventSink;
|
use super::event_loop::sink::EventSink;
|
||||||
use super::output::MonitorHandle;
|
use super::output::MonitorHandle;
|
||||||
|
@ -35,7 +35,7 @@ use super::types::wp_fractional_scaling::FractionalScalingManager;
|
||||||
use super::types::wp_viewporter::ViewporterState;
|
use super::types::wp_viewporter::ViewporterState;
|
||||||
use super::types::xdg_activation::XdgActivationState;
|
use super::types::xdg_activation::XdgActivationState;
|
||||||
use super::window::{WindowRequests, WindowState};
|
use super::window::{WindowRequests, WindowState};
|
||||||
use super::WindowId;
|
use super::{WaylandError, WindowId};
|
||||||
|
|
||||||
/// Winit's Wayland state.
|
/// Winit's Wayland state.
|
||||||
pub struct WinitState {
|
pub struct WinitState {
|
||||||
|
@ -116,14 +116,16 @@ impl WinitState {
|
||||||
globals: &GlobalList,
|
globals: &GlobalList,
|
||||||
queue_handle: &QueueHandle<Self>,
|
queue_handle: &QueueHandle<Self>,
|
||||||
loop_handle: LoopHandle<'static, WinitState>,
|
loop_handle: LoopHandle<'static, WinitState>,
|
||||||
) -> Result<Self, Box<dyn Error>> {
|
) -> Result<Self, OsError> {
|
||||||
let registry_state = RegistryState::new(globals);
|
let registry_state = RegistryState::new(globals);
|
||||||
let compositor_state = CompositorState::bind(globals, queue_handle)?;
|
let compositor_state =
|
||||||
|
CompositorState::bind(globals, queue_handle).map_err(WaylandError::Bind)?;
|
||||||
let subcompositor_state = SubcompositorState::bind(
|
let subcompositor_state = SubcompositorState::bind(
|
||||||
compositor_state.wl_compositor().clone(),
|
compositor_state.wl_compositor().clone(),
|
||||||
globals,
|
globals,
|
||||||
queue_handle,
|
queue_handle,
|
||||||
)?;
|
)
|
||||||
|
.map_err(WaylandError::Bind)?;
|
||||||
|
|
||||||
let output_state = OutputState::new(globals, queue_handle);
|
let output_state = OutputState::new(globals, queue_handle);
|
||||||
let monitors = output_state.outputs().map(MonitorHandle::new).collect();
|
let monitors = output_state.outputs().map(MonitorHandle::new).collect();
|
||||||
|
@ -148,9 +150,9 @@ impl WinitState {
|
||||||
subcompositor_state: Arc::new(subcompositor_state),
|
subcompositor_state: Arc::new(subcompositor_state),
|
||||||
output_state,
|
output_state,
|
||||||
seat_state,
|
seat_state,
|
||||||
shm: Shm::bind(globals, queue_handle)?,
|
shm: Shm::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
|
||||||
|
|
||||||
xdg_shell: XdgShell::bind(globals, queue_handle)?,
|
xdg_shell: XdgShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
|
||||||
xdg_activation: XdgActivationState::bind(globals, queue_handle).ok(),
|
xdg_activation: XdgActivationState::bind(globals, queue_handle).ok(),
|
||||||
|
|
||||||
windows: Default::default(),
|
windows: Default::default(),
|
||||||
|
|
|
@ -36,7 +36,7 @@ use super::event_loop::sink::EventSink;
|
||||||
use super::output::MonitorHandle;
|
use super::output::MonitorHandle;
|
||||||
use super::state::WinitState;
|
use super::state::WinitState;
|
||||||
use super::types::xdg_activation::XdgActivationTokenData;
|
use super::types::xdg_activation::XdgActivationTokenData;
|
||||||
use super::{EventLoopWindowTarget, WindowId};
|
use super::{EventLoopWindowTarget, WaylandError, WindowId};
|
||||||
|
|
||||||
pub(crate) mod state;
|
pub(crate) mod state;
|
||||||
|
|
||||||
|
@ -205,18 +205,18 @@ impl Window {
|
||||||
let event_queue = wayland_source.queue();
|
let event_queue = wayland_source.queue();
|
||||||
|
|
||||||
// Do a roundtrip.
|
// Do a roundtrip.
|
||||||
event_queue.roundtrip(&mut state).map_err(|_| {
|
event_queue.roundtrip(&mut state).map_err(|error| {
|
||||||
os_error!(OsError::WaylandMisc(
|
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
|
||||||
"failed to do initial roundtrip for the window."
|
error
|
||||||
))
|
))))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// XXX Wait for the initial configure to arrive.
|
// XXX Wait for the initial configure to arrive.
|
||||||
while !window_state.lock().unwrap().is_configured() {
|
while !window_state.lock().unwrap().is_configured() {
|
||||||
event_queue.blocking_dispatch(&mut state).map_err(|_| {
|
event_queue.blocking_dispatch(&mut state).map_err(|error| {
|
||||||
os_error!(OsError::WaylandMisc(
|
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
|
||||||
"failed to dispatch queue while waiting for initial configure."
|
error
|
||||||
))
|
))))
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,9 +570,7 @@ impl Window {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let region = Region::new(&*self.compositor).map_err(|_| {
|
let region = Region::new(&*self.compositor).map_err(|_| {
|
||||||
ExternalError::Os(os_error!(OsError::WaylandMisc(
|
ExternalError::Os(os_error!(OsError::Misc("failed to set input region.")))
|
||||||
"failed to set input region."
|
|
||||||
)))
|
|
||||||
})?;
|
})?;
|
||||||
region.add(0, 0, 0, 0);
|
region.add(0, 0, 0, 0);
|
||||||
surface.set_input_region(Some(region.wl_region()));
|
surface.set_input_region(Some(region.wl_region()));
|
||||||
|
|
|
@ -712,7 +712,7 @@ impl WindowState {
|
||||||
// Positon can be set only for locked cursor.
|
// Positon can be set only for locked cursor.
|
||||||
if self.cursor_grab_mode.current_grab_mode != CursorGrabMode::Locked {
|
if self.cursor_grab_mode.current_grab_mode != CursorGrabMode::Locked {
|
||||||
return Err(ExternalError::Os(os_error!(
|
return Err(ExternalError::Os(os_error!(
|
||||||
crate::platform_impl::OsError::WaylandMisc(
|
crate::platform_impl::OsError::Misc(
|
||||||
"cursor position can be set only for locked cursor."
|
"cursor position can be set only for locked cursor."
|
||||||
)
|
)
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -64,7 +64,7 @@ use self::{
|
||||||
};
|
};
|
||||||
use super::{common::xkb_state::KbdState, OsError};
|
use super::{common::xkb_state::KbdState, OsError};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{OsError as RootOsError, RunLoopError},
|
error::{EventLoopError, OsError as RootOsError},
|
||||||
event::{Event, StartCause},
|
event::{Event, StartCause},
|
||||||
event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
||||||
platform::pump_events::PumpStatus,
|
platform::pump_events::PumpStatus,
|
||||||
|
@ -432,12 +432,12 @@ impl<T: 'static> EventLoop<T> {
|
||||||
&self.target
|
&self.target
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if self.loop_running {
|
if self.loop_running {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(EventLoopError::AlreadyRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
let exit = loop {
|
let exit = loop {
|
||||||
|
@ -446,7 +446,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
break Ok(());
|
break Ok(());
|
||||||
}
|
}
|
||||||
PumpStatus::Exit(code) => {
|
PumpStatus::Exit(code) => {
|
||||||
break Err(RunLoopError::ExitFailure(code));
|
break Err(EventLoopError::ExitFailure(code));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
continue;
|
continue;
|
||||||
|
@ -460,7 +460,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
// X Server.
|
// X Server.
|
||||||
let wt = get_xtarget(&self.target);
|
let wt = get_xtarget(&self.target);
|
||||||
wt.x_connection().sync_with_server().map_err(|x_err| {
|
wt.x_connection().sync_with_server().map_err(|x_err| {
|
||||||
RunLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err)))))
|
EventLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err)))))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
exit
|
exit
|
||||||
|
|
|
@ -485,7 +485,7 @@ impl UnownedWindow {
|
||||||
&mut supported_ptr,
|
&mut supported_ptr,
|
||||||
);
|
);
|
||||||
if supported_ptr == ffi::False {
|
if supported_ptr == ffi::False {
|
||||||
return Err(os_error!(OsError::XMisc(
|
return Err(os_error!(OsError::Misc(
|
||||||
"`XkbSetDetectableAutoRepeat` failed"
|
"`XkbSetDetectableAutoRepeat` failed"
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -1488,7 +1488,7 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
.map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err))))
|
.map_err(|err| ExternalError::Os(os_error!(OsError::Misc(err))))
|
||||||
}
|
}
|
||||||
CursorGrabMode::Locked => {
|
CursorGrabMode::Locked => {
|
||||||
return Err(ExternalError::NotSupported(NotSupportedError::new()));
|
return Err(ExternalError::NotSupported(NotSupportedError::new()));
|
||||||
|
|
|
@ -24,7 +24,7 @@ use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle};
|
||||||
|
|
||||||
use super::appkit::{NSApp, NSApplicationActivationPolicy, NSEvent, NSWindow};
|
use super::appkit::{NSApp, NSApplicationActivationPolicy, NSEvent, NSWindow};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::RunLoopError,
|
error::EventLoopError,
|
||||||
event::Event,
|
event::Event,
|
||||||
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget},
|
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget},
|
||||||
platform::{macos::ActivationPolicy, pump_events::PumpStatus},
|
platform::{macos::ActivationPolicy, pump_events::PumpStatus},
|
||||||
|
@ -148,7 +148,9 @@ impl Default for PlatformSpecificEventLoopAttributes {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventLoop<T> {
|
impl<T> EventLoop<T> {
|
||||||
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(
|
||||||
|
attributes: &PlatformSpecificEventLoopAttributes,
|
||||||
|
) -> Result<Self, EventLoopError> {
|
||||||
if !is_main_thread() {
|
if !is_main_thread() {
|
||||||
panic!("On macOS, `EventLoop` must be created on the main thread!");
|
panic!("On macOS, `EventLoop` must be created on the main thread!");
|
||||||
}
|
}
|
||||||
|
@ -178,7 +180,7 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
let panic_info: Rc<PanicInfo> = Default::default();
|
let panic_info: Rc<PanicInfo> = Default::default();
|
||||||
setup_control_flow_observers(Rc::downgrade(&panic_info));
|
setup_control_flow_observers(Rc::downgrade(&panic_info));
|
||||||
EventLoop {
|
Ok(EventLoop {
|
||||||
_delegate: delegate,
|
_delegate: delegate,
|
||||||
window_target: Rc::new(RootWindowTarget {
|
window_target: Rc::new(RootWindowTarget {
|
||||||
p: Default::default(),
|
p: Default::default(),
|
||||||
|
@ -186,14 +188,14 @@ impl<T> EventLoop<T> {
|
||||||
}),
|
}),
|
||||||
panic_info,
|
panic_info,
|
||||||
_callback: None,
|
_callback: None,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_target(&self) -> &RootWindowTarget<T> {
|
pub fn window_target(&self) -> &RootWindowTarget<T> {
|
||||||
&self.window_target
|
&self.window_target
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, callback: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
|
@ -204,12 +206,12 @@ impl<T> EventLoop<T> {
|
||||||
// `pump_events` elegantly (we just ask to run the loop for a "short" amount of
|
// `pump_events` elegantly (we just ask to run the loop for a "short" amount of
|
||||||
// time and so a layered implementation would end up using a lot of CPU due to
|
// time and so a layered implementation would end up using a lot of CPU due to
|
||||||
// redundant wake ups.
|
// redundant wake ups.
|
||||||
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if AppState::is_running() {
|
if AppState::is_running() {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(EventLoopError::AlreadyRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
// # Safety
|
// # Safety
|
||||||
|
@ -287,7 +289,7 @@ impl<T> EventLoop<T> {
|
||||||
if exit_code == 0 {
|
if exit_code == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(RunLoopError::ExitFailure(exit_code))
|
Err(EventLoopError::ExitFailure(exit_code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use orbclient::{
|
||||||
use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle};
|
use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::RunLoopError,
|
error::EventLoopError,
|
||||||
event::{self, Ime, Modifiers, StartCause},
|
event::{self, Ime, Modifiers, StartCause},
|
||||||
event_loop::{self, ControlFlow},
|
event_loop::{self, ControlFlow},
|
||||||
keyboard::{
|
keyboard::{
|
||||||
|
@ -22,8 +22,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
DeviceId, KeyEventExtra, MonitorHandle, PlatformSpecificEventLoopAttributes, RedoxSocket,
|
DeviceId, KeyEventExtra, MonitorHandle, OsError, PlatformSpecificEventLoopAttributes,
|
||||||
TimeSocket, WindowId, WindowProperties,
|
RedoxSocket, TimeSocket, WindowId, WindowProperties,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn convert_scancode(scancode: u8) -> KeyCode {
|
fn convert_scancode(scancode: u8) -> KeyCode {
|
||||||
|
@ -270,12 +270,20 @@ pub struct EventLoop<T: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
|
||||||
let (user_events_sender, user_events_receiver) = mpsc::channel();
|
let (user_events_sender, user_events_receiver) = mpsc::channel();
|
||||||
|
|
||||||
let event_socket = Arc::new(RedoxSocket::event().unwrap());
|
let event_socket = Arc::new(
|
||||||
|
RedoxSocket::event()
|
||||||
|
.map_err(OsError::new)
|
||||||
|
.map_err(|error| EventLoopError::Os(os_error!(error)))?,
|
||||||
|
);
|
||||||
|
|
||||||
let wake_socket = Arc::new(TimeSocket::open().unwrap());
|
let wake_socket = Arc::new(
|
||||||
|
TimeSocket::open()
|
||||||
|
.map_err(OsError::new)
|
||||||
|
.map_err(|error| EventLoopError::Os(os_error!(error)))?,
|
||||||
|
);
|
||||||
|
|
||||||
event_socket
|
event_socket
|
||||||
.write(&syscall::Event {
|
.write(&syscall::Event {
|
||||||
|
@ -283,9 +291,10 @@ impl<T: 'static> EventLoop<T> {
|
||||||
flags: syscall::EventFlags::EVENT_READ,
|
flags: syscall::EventFlags::EVENT_READ,
|
||||||
data: wake_socket.0.fd,
|
data: wake_socket.0.fd,
|
||||||
})
|
})
|
||||||
.unwrap();
|
.map_err(OsError::new)
|
||||||
|
.map_err(|error| EventLoopError::Os(os_error!(error)))?;
|
||||||
|
|
||||||
Self {
|
Ok(Self {
|
||||||
windows: Vec::new(),
|
windows: Vec::new(),
|
||||||
window_target: event_loop::EventLoopWindowTarget {
|
window_target: event_loop::EventLoopWindowTarget {
|
||||||
p: EventLoopWindowTarget {
|
p: EventLoopWindowTarget {
|
||||||
|
@ -299,7 +308,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
},
|
},
|
||||||
_marker: std::marker::PhantomData,
|
_marker: std::marker::PhantomData,
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event<F>(
|
fn process_event<F>(
|
||||||
|
@ -443,7 +452,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
|
@ -685,7 +694,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
if code == 0 {
|
if code == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(RunLoopError::ExitFailure(code))
|
Err(EventLoopError::ExitFailure(code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#![cfg(target_os = "redox")]
|
#![cfg(target_os = "redox")]
|
||||||
|
|
||||||
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::str;
|
use std::str;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||||
|
|
||||||
|
@ -176,13 +178,18 @@ impl<'a> fmt::Display for WindowProperties<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct OsError;
|
pub struct OsError(Arc<syscall::Error>);
|
||||||
|
|
||||||
|
impl OsError {
|
||||||
|
fn new(error: syscall::Error) -> Self {
|
||||||
|
Self(Arc::new(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
|
||||||
impl Display for OsError {
|
impl Display for OsError {
|
||||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
write!(fmt, "Redox OS Error")
|
self.0.fmt(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::error::EventLoopError;
|
||||||
|
use crate::event::Event;
|
||||||
|
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
||||||
|
|
||||||
|
use super::{backend, device, window};
|
||||||
|
|
||||||
mod proxy;
|
mod proxy;
|
||||||
pub(crate) mod runner;
|
pub(crate) mod runner;
|
||||||
mod state;
|
mod state;
|
||||||
mod window_target;
|
mod window_target;
|
||||||
|
|
||||||
pub use self::proxy::EventLoopProxy;
|
pub use proxy::EventLoopProxy;
|
||||||
pub use self::window_target::EventLoopWindowTarget;
|
pub use window_target::EventLoopWindowTarget;
|
||||||
|
|
||||||
use super::{backend, device, window};
|
|
||||||
use crate::event::Event;
|
|
||||||
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
pub struct EventLoop<T: 'static> {
|
pub struct EventLoop<T: 'static> {
|
||||||
elw: RootEventLoopWindowTarget<T>,
|
elw: RootEventLoopWindowTarget<T>,
|
||||||
|
@ -20,13 +22,13 @@ pub struct EventLoop<T: 'static> {
|
||||||
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
||||||
|
|
||||||
impl<T> EventLoop<T> {
|
impl<T> EventLoop<T> {
|
||||||
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
|
||||||
EventLoop {
|
Ok(EventLoop {
|
||||||
elw: RootEventLoopWindowTarget {
|
elw: RootEventLoopWindowTarget {
|
||||||
p: EventLoopWindowTarget::new(),
|
p: EventLoopWindowTarget::new(),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(self, mut event_handler: F) -> !
|
pub fn run<F>(self, mut event_handler: F) -> !
|
||||||
|
|
|
@ -75,7 +75,7 @@ use windows_sys::Win32::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{PhysicalPosition, PhysicalSize},
|
dpi::{PhysicalPosition, PhysicalSize},
|
||||||
error::RunLoopError,
|
error::EventLoopError,
|
||||||
event::{
|
event::{
|
||||||
DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase,
|
DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase,
|
||||||
WindowEvent,
|
WindowEvent,
|
||||||
|
@ -201,7 +201,9 @@ pub struct EventLoopWindowTarget<T: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub(crate) fn new(attributes: &mut PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(
|
||||||
|
attributes: &mut PlatformSpecificEventLoopAttributes,
|
||||||
|
) -> Result<Self, EventLoopError> {
|
||||||
let thread_id = unsafe { GetCurrentThreadId() };
|
let thread_id = unsafe { GetCurrentThreadId() };
|
||||||
|
|
||||||
if !attributes.any_thread && thread_id != main_thread_id() {
|
if !attributes.any_thread && thread_id != main_thread_id() {
|
||||||
|
@ -228,7 +230,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
EventLoop {
|
Ok(EventLoop {
|
||||||
thread_msg_sender,
|
thread_msg_sender,
|
||||||
window_target: RootELW {
|
window_target: RootELW {
|
||||||
p: EventLoopWindowTarget {
|
p: EventLoopWindowTarget {
|
||||||
|
@ -239,28 +241,28 @@ impl<T: 'static> EventLoop<T> {
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
},
|
},
|
||||||
msg_hook: attributes.msg_hook.take(),
|
msg_hook: attributes.msg_hook.take(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_target(&self) -> &RootELW<T> {
|
pub fn window_target(&self) -> &RootELW<T> {
|
||||||
&self.window_target
|
&self.window_target
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(event_handler)
|
self.run_ondemand(event_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), EventLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let runner = &self.window_target.p.runner_shared;
|
let runner = &self.window_target.p.runner_shared;
|
||||||
if runner.state() != RunnerState::Uninitialized {
|
if runner.state() != RunnerState::Uninitialized {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(EventLoopError::AlreadyRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
let event_loop_windows_ref = &self.window_target;
|
let event_loop_windows_ref = &self.window_target;
|
||||||
|
@ -295,7 +297,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
if exit_code == 0 {
|
if exit_code == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(RunLoopError::ExitFailure(exit_code))
|
Err(EventLoopError::ExitFailure(exit_code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError};
|
||||||
/// window::Window,
|
/// window::Window,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// let mut event_loop = EventLoop::new();
|
/// let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// let window = Window::new(&event_loop).unwrap();
|
/// let window = Window::new(&event_loop).unwrap();
|
||||||
///
|
///
|
||||||
/// event_loop.run(move |event, _, control_flow| {
|
/// event_loop.run(move |event, _, control_flow| {
|
||||||
|
@ -570,7 +570,7 @@ impl Window {
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// # fn swap_buffers() {}
|
/// # fn swap_buffers() {}
|
||||||
/// // Do the actual drawing with OpenGL.
|
/// // Do the actual drawing with OpenGL.
|
||||||
|
@ -660,7 +660,7 @@ impl Window {
|
||||||
/// # use winit::dpi::{LogicalPosition, PhysicalPosition};
|
/// # use winit::dpi::{LogicalPosition, PhysicalPosition};
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// // Specify the position in logical dimensions like this:
|
/// // Specify the position in logical dimensions like this:
|
||||||
/// window.set_outer_position(LogicalPosition::new(400.0, 200.0));
|
/// window.set_outer_position(LogicalPosition::new(400.0, 200.0));
|
||||||
|
@ -720,7 +720,7 @@ impl Window {
|
||||||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// // Specify the size in logical dimensions like this:
|
/// // Specify the size in logical dimensions like this:
|
||||||
/// let _ = window.request_inner_size(LogicalSize::new(400.0, 200.0));
|
/// let _ = window.request_inner_size(LogicalSize::new(400.0, 200.0));
|
||||||
|
@ -763,7 +763,7 @@ impl Window {
|
||||||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// // Specify the size in logical dimensions like this:
|
/// // Specify the size in logical dimensions like this:
|
||||||
/// window.set_min_inner_size(Some(LogicalSize::new(400.0, 200.0)));
|
/// window.set_min_inner_size(Some(LogicalSize::new(400.0, 200.0)));
|
||||||
|
@ -786,7 +786,7 @@ impl Window {
|
||||||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// // Specify the size in logical dimensions like this:
|
/// // Specify the size in logical dimensions like this:
|
||||||
/// window.set_max_inner_size(Some(LogicalSize::new(400.0, 200.0)));
|
/// window.set_max_inner_size(Some(LogicalSize::new(400.0, 200.0)));
|
||||||
|
@ -1098,7 +1098,7 @@ impl Window {
|
||||||
/// # use winit::dpi::{LogicalPosition, PhysicalPosition, LogicalSize, PhysicalSize};
|
/// # use winit::dpi::{LogicalPosition, PhysicalPosition, LogicalSize, PhysicalSize};
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// // Specify the position in logical dimensions like this:
|
/// // Specify the position in logical dimensions like this:
|
||||||
/// window.set_ime_cursor_area(LogicalPosition::new(400.0, 200.0), LogicalSize::new(100, 100));
|
/// window.set_ime_cursor_area(LogicalPosition::new(400.0, 200.0), LogicalSize::new(100, 100));
|
||||||
|
@ -1266,7 +1266,7 @@ impl Window {
|
||||||
/// # use winit::dpi::{LogicalPosition, PhysicalPosition};
|
/// # use winit::dpi::{LogicalPosition, PhysicalPosition};
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::Window;
|
/// # use winit::window::Window;
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// // Specify the position in logical dimensions like this:
|
/// // Specify the position in logical dimensions like this:
|
||||||
/// window.set_cursor_position(LogicalPosition::new(400.0, 200.0));
|
/// window.set_cursor_position(LogicalPosition::new(400.0, 200.0));
|
||||||
|
@ -1292,7 +1292,7 @@ impl Window {
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # use winit::event_loop::EventLoop;
|
/// # use winit::event_loop::EventLoop;
|
||||||
/// # use winit::window::{CursorGrabMode, Window};
|
/// # use winit::window::{CursorGrabMode, Window};
|
||||||
/// # let mut event_loop = EventLoop::new();
|
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||||
/// # let window = Window::new(&event_loop).unwrap();
|
/// # let window = Window::new(&event_loop).unwrap();
|
||||||
/// window.set_cursor_grab(CursorGrabMode::Confined)
|
/// window.set_cursor_grab(CursorGrabMode::Confined)
|
||||||
/// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))
|
/// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))
|
||||||
|
|
Loading…
Reference in a new issue