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: Linux
TODO: split patch up
  • Loading branch information
rib committed Apr 11, 2023
1 parent 0032e23 commit 30c9eff
Show file tree
Hide file tree
Showing 40 changed files with 950 additions and 282 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ mint = { version = "0.5.6", optional = true }
[dev-dependencies]
image = { version = "0.24.0", default-features = false, features = ["png"] }
simple_logger = { version = "2.1.0", default_features = false }
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
ndk = "0.7.0"
android-activity = "0.4.0"
#android-activity = { path = "../android-activity/android-activity" }

[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
objc2 = "=0.3.0-beta.3"
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(target_arch = "wasm32"))]
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(target_arch = "wasm32")]
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 @@ -5,7 +5,7 @@ use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEve
use winit::event_loop::EventLoop;
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 @@ -109,5 +109,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::WindowBuilder,
};

fn main() {
fn main() -> std::result::Result<(), impl std::error::Error> {
SimpleLogger::new()
.with_level(LevelFilter::Trace)
.init()
Expand Down Expand Up @@ -95,5 +95,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(target_arch = "wasm32"))]
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(target_arch = "wasm32"))]
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(target_arch = "wasm32")]
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 @@ -39,5 +39,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(target_arch = "wasm32")]
Expand Down
4 changes: 2 additions & 2 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 @@ -31,5 +31,5 @@ fn main() {
}
_ => (),
}
});
})
}
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 @@ -127,5 +127,5 @@ fn main() {
} if window_id == window.id() => control_flow.set_exit(),
_ => (),
}
});
})
}
4 changes: 2 additions & 2 deletions examples/window_icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use winit::{
window::{Icon, WindowBuilder},
};

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

// You'll have to choose an icon size at your own discretion. On X11, the desired size varies
Expand Down Expand Up @@ -43,7 +43,7 @@ fn main() {
_ => (),
}
}
});
})
}

fn load_icon(path: &Path) -> Icon {
Expand Down
Loading

0 comments on commit 30c9eff

Please sign in to comment.