Skip to content

Commit

Permalink
Re-work event loop run APIs
Browse files Browse the repository at this point in the history
Overall this re-works the APIs for how an `EventLoop` is run to cover
these use-cases, with varying portability caveats:

1. A portable `run()` API that consumes the `EventLoop` and runs the
   loop on the calling thread until the app exits. This can be
   supported across _all_ platforms and compared to the previous
   `run() -> !` API is now able to return a `Result` status on all platforms
   except iOS and Web. Fixes: rust-windowing#2709
2. A less portable `run_ondmand()` API that covers the use case in rust-windowing#2431
   where applications need to be able to re-run a Winit application
   multiple times against a persistent `EventLoop`. This doesn't allow
   `Window` state to carry across separate runs of the loop, but does
   allow orthogonal re-instantiations of a gui application.

   Available On: Windows, Linux, MacOS
   Could be supported on Android if there's a use case
   Incompatible with iOS, Web
   Fixes: rust-windowing#2431
3. A less portable (and on MacOS, likely less-optimal) `pump_events()`
   API that covers the use case in rust-windowing#2706 and allows a Winit event loop to
   be embedded within an external `loop {}`. Applications call `pump_events()`
   once per iteration of their own external loop to dispatch all pending Winit
   events, without blocking the external loop.

   Available On: Windows, Linux, MacOS, Android
   Incompatible With: iOS, Web
   Fixes: rust-windowing#2706

Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)

In particular by moving away from `run() -> !` we stop calling
`std::process::exit()` internally as a means to kill the process without
returning which means it's possible to return an exit status and
applications can return from their `main()` function normally. This also
fixes Android support where an Activity runs in a thread but we can't
assume to have full ownership of the process (other services could be
running in separate threads).

`run_return` has been removed, and the overlapping use cases that
`run_return` previously partially aimed to support have been split
across `run_ondemand` and `pump_events`.

To help test the changes this adds:
  examples/window_ondemand
  examples/window_pump_events
  examples/window_pump_events_rfd

The last _rfd example, tests the interaction between the `rfd` crate and
using `pump_events` to embed Winit within an external event loop.

Additionally all examples have generally been updated so that `main()`
returns a `Result` from `run()`

Fixes: rust-windowing#2709
Fixes: rust-windowing#2706
Fixes: rust-windowing#2431
Fixes: rust-windowing#2752

TODO: X11/Wayland backends
TODO: ask someone to test orbital changes, made blindly
TODO: split patch up

Second pass over the windows backend

I had totally underestimated what was involved in updating the windows
backend since I hadn't seen the special `wait_thread` that was also
dispatching messages and implementing control_flow timeouts via
MsgWaitForMultipleObjects, nor had I grokked all the special stuff being
done with `WM_PAINT` messages.

This "breaks" the MainEventsCleared -> RedrawRequested ->
RedrawEventsCleared ordering guarantees, similar to how this is anyway
inherently broken in the MacOS backend.

The switches to using SetTimer to handle control_flow Wait timeouts and
removes the need to use MsgWaitForMultipleObjects.

Overall this is a pretty nice simplification of several things

TODO: tidy up (lots of debug and misc changes + comments atm)

stash
  • Loading branch information
rib committed Apr 12, 2023
1 parent 2486f0f commit a245b62
Show file tree
Hide file tree
Showing 43 changed files with 1,087 additions and 703 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ serde = { version = "1", optional = true, features = ["serde_derive"] }
image = { version = "0.24.0", default-features = false, features = ["png"] }
simple_logger = { version = "2.1.0", default_features = false }

[target.'cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))'.dev-dependencies]
rfd = { version = "0.11.0" }

[target.'cfg(target_os = "android")'.dependencies]
# Coordinate the next winit release with android-ndk-rs: https://github.com/rust-windowing/winit/issues/1995
android-activity = "0.4.0"
Expand Down
2 changes: 1 addition & 1 deletion examples/child_window.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[cfg(any(x11_platform, macos_platform, windows_platform))]
fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
use std::collections::HashMap;

use raw_window_handle::HasRawWindowHandle;
Expand Down
4 changes: 2 additions & 2 deletions examples/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ enum Mode {
const WAIT_TIME: time::Duration = time::Duration::from_millis(100);
const POLL_SLEEP_TIME: time::Duration = time::Duration::from_millis(100);

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();

println!("Press '1' to switch to Wait mode.");
Expand Down Expand Up @@ -110,5 +110,5 @@ fn main() {
}
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::{CursorIcon, WindowBuilder},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -48,7 +48,7 @@ fn main() {
}
_ => (),
}
});
})
}

const CURSORS: &[CursorIcon] = &[
Expand Down
4 changes: 2 additions & 2 deletions examples/cursor_grab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::{CursorGrabMode, WindowBuilder},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -66,5 +66,5 @@ fn main() {
},
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/custom_events.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(clippy::single_match)]

#[cfg(not(wasm_platform))]
fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
use simple_logger::SimpleLogger;
use winit::{
event::{Event, WindowEvent},
Expand Down Expand Up @@ -46,7 +46,7 @@ fn main() {
} => control_flow.set_exit(),
_ => (),
}
});
})
}

#[cfg(wasm_platform)]
Expand Down
4 changes: 2 additions & 2 deletions examples/drag_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use winit::{
window::{Window, WindowBuilder, WindowId},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -60,7 +60,7 @@ fn main() {
_ => (),
},
_ => (),
});
})
}

fn name_windows(window_id: WindowId, switched: bool, window_1: &Window, window_2: &Window) {
Expand Down
4 changes: 2 additions & 2 deletions examples/fullscreen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use winit::window::{Fullscreen, WindowBuilder};
#[cfg(target_os = "macos")]
use winit::platform::macos::WindowExtMacOS;

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -118,5 +118,5 @@ fn main() {
},
_ => {}
}
});
})
}
4 changes: 2 additions & 2 deletions examples/handling_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -82,5 +82,5 @@ fn main() {
}
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/ime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use winit::{
window::{ImePurpose, WindowBuilder},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new()
.with_level(LevelFilter::Trace)
.init()
Expand Down Expand Up @@ -108,5 +108,5 @@ fn main() {
}
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/mouse_wheel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -58,5 +58,5 @@ In other words, the deltas indicate the direction in which to move the content (
},
_ => (),
}
});
})
}
2 changes: 1 addition & 1 deletion examples/multithreaded.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(clippy::single_match)]

#[cfg(not(wasm_platform))]
fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
use std::{collections::HashMap, sync::mpsc, thread, time::Duration};

use simple_logger::SimpleLogger;
Expand Down
2 changes: 1 addition & 1 deletion examples/multiwindow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use winit::{
window::Window,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down
4 changes: 2 additions & 2 deletions examples/request_redraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -37,5 +37,5 @@ fn main() {
}
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/request_redraw_threaded.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(clippy::single_match)]

#[cfg(not(wasm_platform))]
fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
use std::{thread, time};

use simple_logger::SimpleLogger;
Expand Down Expand Up @@ -39,7 +39,7 @@ fn main() {
}
_ => (),
}
});
})
}

#[cfg(wasm_platform)]
Expand Down
4 changes: 2 additions & 2 deletions examples/resizable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -46,5 +46,5 @@ fn main() {
},
_ => (),
};
});
})
}
4 changes: 2 additions & 2 deletions examples/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::{Theme, WindowBuilder},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -67,5 +67,5 @@ fn main() {
},
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -38,5 +38,5 @@ fn main() {
} => control_flow.set_exit(),
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/touchpad_gestures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -42,5 +42,5 @@ fn main() {
_ => (),
}
}
});
})
}
4 changes: 2 additions & 2 deletions examples/transparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand All @@ -30,5 +30,5 @@ fn main() {
} => control_flow.set_exit(),
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use winit::{
window::WindowBuilder,
};

pub fn main() {
pub fn main() -> std::result::Result<(), impl std::error::Error> {
let event_loop = EventLoop::new();

let window = WindowBuilder::new()
Expand All @@ -33,7 +33,7 @@ pub fn main() {
}
_ => (),
}
});
})
}

#[cfg(wasm_platform)]
Expand Down
9 changes: 6 additions & 3 deletions examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winit::{
window::WindowBuilder,
};

fn main() {
fn main() -> Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand All @@ -25,11 +25,14 @@ fn main() {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => control_flow.set_exit(),
} if window_id == window.id() => {
log::warn!("Close button pressed");
control_flow.set_exit()
}
Event::MainEventsCleared => {
window.request_redraw();
}
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/window_buttons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use winit::{
window::{WindowBuilder, WindowButtons},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -64,5 +64,5 @@ fn main() {
} if window_id == window.id() => control_flow.set_exit(),
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/window_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use winit::{
window::{Fullscreen, WindowBuilder},
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -128,5 +128,5 @@ fn main() {
} if window_id == window.id() => control_flow.set_exit(),
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/window_drag_resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use winit::{

const BORDER: f64 = 8.0;

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new();

Expand Down Expand Up @@ -67,7 +67,7 @@ fn main() {
_ => (),
},
_ => (),
});
})
}

fn cursor_direction_icon(resize_direction: Option<ResizeDirection>) -> CursorIcon {
Expand Down
Loading

0 comments on commit a245b62

Please sign in to comment.