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 it's not desirable. The inner panics were left only when they are used to `assert!` during development. This reverts commit 9f91bc413fe20618bd7090829832bb074aab15c3 which reverted the original patch which was merged without a proper review. Fixes: #500.
This commit is contained in:
parent
778d70c001
commit
f9758528f6
|
@ -8,6 +8,8 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
|
||||
# Unreleased
|
||||
|
||||
- **Breaking:** `WINIT_UNIX_BACKEND` was removed in favor of standard `WAYLAND_DISPLAY` and `DISPLAY` variables.
|
||||
- **Breaking:** `EventLoop::new` and `EventLoopBuilder::build` now return `Result<Self, EventLoopError>`
|
||||
- On X11, set `visual_id` in returned `raw-window-handle`.
|
||||
- **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:
|
||||
|
@ -51,7 +53,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, add `WindowBuilderExtWebSys::with_append()` to append the canvas element to the web page on creation.
|
||||
- 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))
|
||||
- `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()`
|
||||
|
|
|
@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
|
||||
let mut windows = HashMap::new();
|
||||
|
||||
let event_loop: EventLoop<()> = EventLoop::new();
|
||||
let event_loop: EventLoop<()> = EventLoop::new().unwrap();
|
||||
let parent_window = WindowBuilder::new()
|
||||
.with_title("parent window")
|
||||
.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 'Esc' to close the window.");
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.")
|
||||
.build(&event_loop)
|
||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
window.set_title("A fantastic window!");
|
||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("Super Cursor Grab'n'Hide Simulator 9000")
|
||||
|
|
|
@ -18,7 +18,9 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
}
|
||||
|
||||
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()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
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_2 = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
|
|
|
@ -15,7 +15,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let mut decorations = true;
|
||||
let mut minimized = false;
|
||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.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 F3 to cycle through IME purposes.");
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(256f64, 128f64))
|
||||
|
|
|
@ -22,7 +22,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
mod fill;
|
||||
|
||||
simple_logger::SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_inner_size(LogicalSize::new(400.0, 200.0))
|
||||
|
|
|
@ -7,7 +7,7 @@ use winit::{event_loop::EventLoop, window::WindowBuilder};
|
|||
|
||||
fn main() {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
|
||||
if let Some(mon) = window.primary_monitor() {
|
||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.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);
|
||||
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
|
||||
for _ in 0..WINDOW_COUNT {
|
||||
let window = WindowBuilder::new()
|
||||
|
|
|
@ -15,7 +15,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let mut windows = HashMap::new();
|
||||
for _ in 0..3 {
|
||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -15,7 +15,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
mod fill;
|
||||
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = {
|
||||
let window = WindowBuilder::new()
|
||||
|
|
|
@ -14,7 +14,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let mut resizable = false;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ mod example {
|
|||
|
||||
pub(super) fn main() -> Result<(), impl std::error::Error> {
|
||||
// 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() {
|
||||
Some(token) => Some(token),
|
||||
None => {
|
||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -18,7 +18,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -10,7 +10,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("Touchpad gestures")
|
||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_decorations(false)
|
||||
|
|
|
@ -5,7 +5,7 @@ use winit::event_loop::EventLoop;
|
|||
|
||||
fn main() {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let monitor = match event_loop.primary_monitor() {
|
||||
Some(monitor) => monitor,
|
||||
None => {
|
||||
|
|
|
@ -8,7 +8,7 @@ use winit::{
|
|||
};
|
||||
|
||||
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!");
|
||||
#[cfg(wasm_platform)]
|
||||
|
|
|
@ -31,7 +31,7 @@ This example demonstrates the desired future functionality which will possibly b
|
|||
#[wasm_bindgen(start)]
|
||||
pub fn run() {
|
||||
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()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -12,7 +12,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -16,7 +16,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -16,7 +16,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -15,7 +15,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.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 event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("An iconic window!")
|
||||
|
|
|
@ -8,7 +8,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
use simple_logger::SimpleLogger;
|
||||
|
||||
use winit::{
|
||||
error::RunLoopError,
|
||||
error::EventLoopError,
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::EventLoop,
|
||||
platform::run_ondemand::EventLoopExtRunOnDemand,
|
||||
|
@ -25,9 +25,9 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
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.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -22,7 +22,7 @@ fn main() -> std::process::ExitCode {
|
|||
#[path = "util/fill.rs"]
|
||||
mod fill;
|
||||
|
||||
let mut event_loop = EventLoop::new();
|
||||
let mut event_loop = EventLoop::new().unwrap();
|
||||
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let window = WindowBuilder::new()
|
||||
|
|
|
@ -13,7 +13,7 @@ mod fill;
|
|||
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("A fantastic window!")
|
||||
|
|
|
@ -21,7 +21,7 @@ mod fill;
|
|||
#[cfg(target_os = "macos")]
|
||||
fn main() -> Result<(), impl std::error::Error> {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let mut windows = HashMap::new();
|
||||
let window = Window::new(&event_loop).unwrap();
|
||||
|
|
|
@ -23,7 +23,7 @@ mod imple {
|
|||
.parse::<u32>()?;
|
||||
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new()?;
|
||||
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("An embedded window!")
|
||||
|
|
23
src/error.rs
23
src/error.rs
|
@ -30,17 +30,25 @@ pub struct OsError {
|
|||
|
||||
/// A general error that may occur while running the Winit event loop
|
||||
#[derive(Debug)]
|
||||
pub enum RunLoopError {
|
||||
pub enum EventLoopError {
|
||||
/// The operation is not supported by the backend.
|
||||
NotSupported(NotSupportedError),
|
||||
/// The OS cannot perform the operation.
|
||||
Os(OsError),
|
||||
/// The event loop can't be re-run while it's already running
|
||||
AlreadyRunning,
|
||||
/// The event loop can't be re-created.
|
||||
RecreationAttempt,
|
||||
/// Application has exit with an error status.
|
||||
ExitFailure(i32),
|
||||
}
|
||||
|
||||
impl From<OsError> for EventLoopError {
|
||||
fn from(value: OsError) -> Self {
|
||||
Self::Os(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl NotSupportedError {
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
|
@ -94,13 +102,14 @@ 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> {
|
||||
match self {
|
||||
RunLoopError::AlreadyRunning => write!(f, "EventLoop is already running"),
|
||||
RunLoopError::NotSupported(e) => e.fmt(f),
|
||||
RunLoopError::Os(e) => e.fmt(f),
|
||||
RunLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"),
|
||||
EventLoopError::AlreadyRunning => write!(f, "EventLoop is already running"),
|
||||
EventLoopError::RecreationAttempt => write!(f, "EventLoop can't be recreated"),
|
||||
EventLoopError::NotSupported(e) => e.fmt(f),
|
||||
EventLoopError::Os(e) => e.fmt(f),
|
||||
EventLoopError::ExitFailure(status) => write!(f, "Exit Failure: {status}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +117,7 @@ impl fmt::Display for RunLoopError {
|
|||
impl error::Error for OsError {}
|
||||
impl error::Error for ExternalError {}
|
||||
impl error::Error for NotSupportedError {}
|
||||
impl error::Error for RunLoopError {}
|
||||
impl error::Error for EventLoopError {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::time::{Duration, Instant};
|
|||
#[cfg(wasm_platform)]
|
||||
use web_time::{Duration, Instant};
|
||||
|
||||
use crate::error::RunLoopError;
|
||||
use crate::error::EventLoopError;
|
||||
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
|
||||
|
@ -88,23 +88,23 @@ impl<T> EventLoopBuilder<T> {
|
|||
/// ***For cross-platform compatibility, the [`EventLoop`] must be created on the main thread,
|
||||
/// and only once per application.***
|
||||
///
|
||||
/// Attempting to create the event loop on a different thread, or multiple event loops in
|
||||
/// the same application, will panic. This restriction isn't
|
||||
/// strictly necessary on all platforms, but is imposed to eliminate any nasty surprises when
|
||||
/// porting to platforms that require it. `EventLoopBuilderExt::any_thread` functions are exposed
|
||||
/// in the relevant [`platform`] module if the target platform supports creating an event loop on
|
||||
/// any thread.
|
||||
///
|
||||
/// Calling this function will result in display backend initialisation.
|
||||
///
|
||||
/// ## Panics
|
||||
///
|
||||
/// Attempting to create the event loop off the main thread will panic. This
|
||||
/// restriction isn't strictly necessary on all platforms, but is imposed to
|
||||
/// eliminate any nasty surprises when porting to platforms that require it.
|
||||
/// `EventLoopBuilderExt::any_thread` functions are exposed in the relevant
|
||||
/// [`platform`] module if the target platform supports creating an event
|
||||
/// loop on any thread.
|
||||
///
|
||||
/// ## 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
|
||||
/// [`.with_android_app(app)`] before calling `.build()`.
|
||||
/// - **Wayland/X11:** to prevent running under `Wayland` or `X11` unset `WAYLAND_DISPLAY`
|
||||
/// or `DISPLAY` respectively when building the event loop.
|
||||
/// - **Android:** must be configured with an `AndroidApp` from `android_main()` by calling
|
||||
/// [`.with_android_app(app)`] before calling `.build()`, otherwise it'll panic.
|
||||
///
|
||||
/// [`platform`]: crate::platform
|
||||
#[cfg_attr(
|
||||
|
@ -116,17 +116,17 @@ impl<T> EventLoopBuilder<T> {
|
|||
doc = "[`.with_android_app(app)`]: #only-available-on-android"
|
||||
)]
|
||||
#[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) {
|
||||
panic!("Creating EventLoop multiple times is not supported.");
|
||||
return Err(EventLoopError::RecreationAttempt);
|
||||
}
|
||||
|
||||
// Certain platforms accept a mutable reference in their API.
|
||||
#[allow(clippy::unnecessary_mut_passed)]
|
||||
EventLoop {
|
||||
event_loop: platform_impl::EventLoop::new(&mut self.platform_specific),
|
||||
Ok(EventLoop {
|
||||
event_loop: platform_impl::EventLoop::new(&mut self.platform_specific)?,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(wasm_platform)]
|
||||
|
@ -269,20 +269,14 @@ impl EventLoop<()> {
|
|||
///
|
||||
/// [`EventLoopBuilder::new().build()`]: EventLoopBuilder::build
|
||||
#[inline]
|
||||
pub fn new() -> EventLoop<()> {
|
||||
pub fn new() -> Result<EventLoop<()>, EventLoopError> {
|
||||
EventLoopBuilder::new().build()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for EventLoop<()> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EventLoop<T> {
|
||||
#[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()
|
||||
}
|
||||
|
||||
|
@ -315,7 +309,7 @@ impl<T> EventLoop<T> {
|
|||
/// [`ControlFlow`]: crate::event_loop::ControlFlow
|
||||
#[inline]
|
||||
#[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
|
||||
F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//!
|
||||
//! ```no_run
|
||||
//! 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`]:
|
||||
|
@ -48,7 +48,7 @@
|
|||
//! window::WindowBuilder,
|
||||
//! };
|
||||
//!
|
||||
//! let event_loop = EventLoop::new();
|
||||
//! let event_loop = EventLoop::new().unwrap();
|
||||
//! let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
//!
|
||||
//! event_loop.run(move |event, _, control_flow| {
|
||||
|
|
|
@ -53,7 +53,7 @@ pub trait EventLoopExtPumpEvents {
|
|||
/// # platform::pump_events::{EventLoopExtPumpEvents, PumpStatus},
|
||||
/// # window::WindowBuilder,
|
||||
/// # };
|
||||
/// let mut event_loop = EventLoop::new();
|
||||
/// let mut event_loop = EventLoop::new().unwrap();
|
||||
/// #
|
||||
/// # SimpleLogger::new().init().unwrap();
|
||||
/// let window = WindowBuilder::new()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
error::RunLoopError,
|
||||
error::EventLoopError,
|
||||
event::Event,
|
||||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ pub trait EventLoopExtRunOnDemand {
|
|||
/// polled to ask for new events. Events are delivered via callbacks based
|
||||
/// 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.
|
||||
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), EventLoopError>
|
||||
where
|
||||
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ pub trait EventLoopExtRunOnDemand {
|
|||
impl<T> EventLoopExtRunOnDemand for EventLoop<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
|
||||
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
|
||||
{
|
||||
|
|
|
@ -130,7 +130,7 @@ pub trait WindowBuilderExtX11 {
|
|||
/// use winit::window::WindowBuilder;
|
||||
/// use winit::platform::x11::{XWindow, WindowBuilderExtX11};
|
||||
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// let event_loop = winit::event_loop::EventLoop::new();
|
||||
/// let event_loop = winit::event_loop::EventLoop::new().unwrap();
|
||||
/// let parent_window_id = std::env::args().nth(1).unwrap().parse::<XWindow>()?;
|
||||
/// let window = WindowBuilder::new()
|
||||
/// .with_embed_parent_window(parent_window_id)
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::{
|
|||
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
|
||||
},
|
||||
};
|
||||
use crate::{error::RunLoopError, platform_impl::Fullscreen};
|
||||
use crate::{error::EventLoopError, platform_impl::Fullscreen};
|
||||
|
||||
mod keycodes;
|
||||
|
||||
|
@ -186,13 +186,15 @@ fn sticky_exit_callback<T, F>(
|
|||
}
|
||||
|
||||
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 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();
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
android_app: android_app.clone(),
|
||||
window_target: event_loop::EventLoopWindowTarget {
|
||||
p: EventLoopWindowTarget {
|
||||
|
@ -215,7 +217,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
cause: StartCause::Init,
|
||||
ignore_volume_keys: attributes.ignore_volume_keys,
|
||||
combining_accent: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn single_iteration<F>(&mut self, main_event: Option<MainEvent<'_>>, callback: &mut F)
|
||||
|
@ -533,19 +535,19 @@ impl<T: 'static> EventLoop<T> {
|
|||
input_status
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), EventLoopError>
|
||||
where
|
||||
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
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
|
||||
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
if self.loop_running {
|
||||
return Err(RunLoopError::AlreadyRunning);
|
||||
return Err(EventLoopError::AlreadyRunning);
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -554,7 +556,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
break Ok(());
|
||||
}
|
||||
PumpStatus::Exit(code) => {
|
||||
break Err(RunLoopError::ExitFailure(code));
|
||||
break Err(EventLoopError::ExitFailure(code));
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
|
|
|
@ -19,11 +19,9 @@ use objc2::rc::Id;
|
|||
use objc2::ClassType;
|
||||
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::{
|
||||
dpi::LogicalSize,
|
||||
error::EventLoopError,
|
||||
event::Event,
|
||||
event_loop::{
|
||||
ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootEventLoopWindowTarget,
|
||||
|
@ -31,6 +29,10 @@ use crate::{
|
|||
platform::ios::Idiom,
|
||||
};
|
||||
|
||||
use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen};
|
||||
use super::view::WinitUIWindow;
|
||||
use super::{app_state, monitor, view, MonitorHandle};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum EventWrapper {
|
||||
StaticEvent(Event<Never>),
|
||||
|
@ -75,7 +77,9 @@ pub struct EventLoop<T: 'static> {
|
|||
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
||||
|
||||
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");
|
||||
|
||||
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`
|
||||
setup_control_flow_observers();
|
||||
|
||||
EventLoop {
|
||||
Ok(EventLoop {
|
||||
window_target: RootEventLoopWindowTarget {
|
||||
p: EventLoopWindowTarget {
|
||||
receiver,
|
||||
|
@ -101,7 +105,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
},
|
||||
_marker: PhantomData,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run<F>(self, event_handler: F) -> !
|
||||
|
|
|
@ -3,33 +3,22 @@
|
|||
#[cfg(all(not(x11_platform), not(wayland_platform)))]
|
||||
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
|
||||
|
||||
#[cfg(wayland_platform)]
|
||||
use std::error::Error;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::{collections::VecDeque, env, fmt};
|
||||
#[cfg(x11_platform)]
|
||||
use std::{
|
||||
ffi::CStr,
|
||||
mem::MaybeUninit,
|
||||
os::raw::*,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Mutex};
|
||||
|
||||
#[cfg(x11_platform)]
|
||||
use once_cell::sync::Lazy;
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||
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)]
|
||||
use crate::platform::x11::XlibErrorHook;
|
||||
use crate::{
|
||||
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
||||
error::{ExternalError, NotSupportedError, OsError as RootOsError, RunLoopError},
|
||||
error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError},
|
||||
event::{Event, KeyEvent},
|
||||
event_loop::{
|
||||
AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed,
|
||||
|
@ -46,6 +35,10 @@ use crate::{
|
|||
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::platform_impl::Fullscreen;
|
||||
|
@ -56,15 +49,6 @@ pub mod wayland;
|
|||
#[cfg(x11_platform)]
|
||||
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)]
|
||||
pub(crate) enum Backend {
|
||||
#[cfg(x11_platform)]
|
||||
|
@ -136,23 +120,21 @@ pub(crate) static X11_BACKEND: Lazy<Mutex<Result<Arc<XConnection>, XNotSupported
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum OsError {
|
||||
Misc(&'static str),
|
||||
#[cfg(x11_platform)]
|
||||
XError(Arc<X11Error>),
|
||||
#[cfg(x11_platform)]
|
||||
XMisc(&'static str),
|
||||
#[cfg(wayland_platform)]
|
||||
WaylandMisc(&'static str),
|
||||
WaylandError(Arc<wayland::WaylandError>),
|
||||
}
|
||||
|
||||
impl fmt::Display for OsError {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
match *self {
|
||||
OsError::Misc(e) => _f.pad(e),
|
||||
#[cfg(x11_platform)]
|
||||
OsError::XError(ref e) => fmt::Display::fmt(e, _f),
|
||||
#[cfg(x11_platform)]
|
||||
OsError::XMisc(e) => _f.pad(e),
|
||||
#[cfg(wayland_platform)]
|
||||
OsError::WaylandMisc(e) => _f.pad(e),
|
||||
OsError::WaylandError(ref e) => fmt::Display::fmt(e, _f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +730,9 @@ impl<T: 'static> Clone for EventLoopProxy<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() {
|
||||
panic!(
|
||||
"Initializing the event loop outside of the main thread is a significant \
|
||||
|
@ -758,65 +742,26 @@ impl<T: 'static> EventLoop<T> {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(x11_platform)]
|
||||
if attributes.forced_backend == Some(Backend::X) {
|
||||
// TODO: Propagate
|
||||
return EventLoop::new_x11_any_thread().unwrap();
|
||||
}
|
||||
|
||||
// NOTE: Wayland first because of X11 could be present under wayland as well.
|
||||
#[cfg(wayland_platform)]
|
||||
if attributes.forced_backend == Some(Backend::Wayland) {
|
||||
// TODO: Propagate
|
||||
return EventLoop::new_wayland_any_thread().expect("failed to open Wayland connection");
|
||||
if attributes.forced_backend == Some(Backend::Wayland)
|
||||
|| env::var("WAYLAND_DISPLAY").is_ok()
|
||||
{
|
||||
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)]
|
||||
let x11_err = match EventLoop::new_x11_any_thread() {
|
||||
Ok(event_loop) => return event_loop,
|
||||
Err(err) => err,
|
||||
};
|
||||
if attributes.forced_backend == Some(Backend::X) || env::var("DISPLAY").is_ok() {
|
||||
return Ok(EventLoop::new_x11_any_thread().unwrap());
|
||||
}
|
||||
|
||||
#[cfg(not(wayland_platform))]
|
||||
let wayland_err = "backend disabled";
|
||||
#[cfg(not(x11_platform))]
|
||||
let x11_err = "backend disabled";
|
||||
|
||||
panic!(
|
||||
"Failed to initialize any backend! Wayland status: {wayland_err:?} X11 status: {x11_err:?}",
|
||||
);
|
||||
Err(EventLoopError::Os(os_error!(OsError::Misc(
|
||||
"neither WAYLAND_DISPLAY nor DISPLAY is set."
|
||||
))))
|
||||
}
|
||||
|
||||
#[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)))
|
||||
}
|
||||
|
||||
|
@ -834,14 +779,14 @@ impl<T: 'static> EventLoop<T> {
|
|||
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
|
||||
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
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
|
||||
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! The event-loop routines.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error;
|
||||
use std::io::Result as IOResult;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
@ -13,11 +12,12 @@ use std::time::{Duration, Instant};
|
|||
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
|
||||
|
||||
use sctk::reexports::calloop;
|
||||
use sctk::reexports::calloop::Error as CalloopError;
|
||||
use sctk::reexports::client::globals;
|
||||
use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource};
|
||||
|
||||
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_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
|
@ -33,7 +33,7 @@ use sink::EventSink;
|
|||
|
||||
use super::state::{WindowCompositorUpdate, WinitState};
|
||||
use super::window::state::FrameCallbackState;
|
||||
use super::{DeviceId, WindowId};
|
||||
use super::{DeviceId, WaylandError, WindowId};
|
||||
|
||||
type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource<WinitState>, WinitState>;
|
||||
|
||||
|
@ -73,22 +73,38 @@ pub struct EventLoop<T: 'static> {
|
|||
}
|
||||
|
||||
impl<T: 'static> EventLoop<T> {
|
||||
pub fn new() -> Result<EventLoop<T>, Box<dyn Error>> {
|
||||
let connection = Connection::connect_to_env()?;
|
||||
pub fn new() -> Result<EventLoop<T>, EventLoopError> {
|
||||
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 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
|
||||
// races with the server.
|
||||
event_queue.roundtrip(&mut winit_state)?;
|
||||
map_err!(
|
||||
event_queue.roundtrip(&mut winit_state),
|
||||
WaylandError::Dispatch
|
||||
)?;
|
||||
|
||||
// Register Wayland source.
|
||||
let wayland_source = WaylandSource::new(event_queue)?;
|
||||
let wayland_source = map_err!(WaylandSource::new(event_queue), WaylandError::Wire)?;
|
||||
let wayland_dispatcher =
|
||||
calloop::Dispatcher::new(wayland_source, |_, queue, winit_state: &mut WinitState| {
|
||||
let result = queue.dispatch_pending(winit_state);
|
||||
|
@ -101,34 +117,50 @@ impl<T: 'static> EventLoop<T> {
|
|||
result
|
||||
});
|
||||
|
||||
event_loop
|
||||
.handle()
|
||||
.register_dispatcher(wayland_dispatcher.clone())?;
|
||||
map_err!(
|
||||
event_loop
|
||||
.handle()
|
||||
.register_dispatcher(wayland_dispatcher.clone()),
|
||||
WaylandError::Calloop
|
||||
)?;
|
||||
|
||||
// Setup the user proxy.
|
||||
let pending_user_events = Rc::new(RefCell::new(Vec::new()));
|
||||
let pending_user_events_clone = pending_user_events.clone();
|
||||
let (user_events_sender, user_events_channel) = calloop::channel::channel();
|
||||
event_loop.handle().insert_source(
|
||||
user_events_channel,
|
||||
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);
|
||||
}
|
||||
},
|
||||
)?;
|
||||
let result = event_loop
|
||||
.handle()
|
||||
.insert_source(
|
||||
user_events_channel,
|
||||
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);
|
||||
map_err!(result, WaylandError::Calloop)?;
|
||||
|
||||
// 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()?;
|
||||
event_loop.handle().insert_source(
|
||||
event_loop_awakener_source,
|
||||
move |_, _, winit_state: &mut WinitState| {
|
||||
// Mark that we have something to dispatch.
|
||||
winit_state.dispatched_events = true;
|
||||
},
|
||||
let (event_loop_awakener, event_loop_awakener_source) = map_err!(
|
||||
calloop::ping::make_ping()
|
||||
.map_err(|error| CalloopError::OtherError(Box::new(error).into())),
|
||||
WaylandError::Calloop
|
||||
)?;
|
||||
|
||||
let result = event_loop
|
||||
.handle()
|
||||
.insert_source(
|
||||
event_loop_awakener_source,
|
||||
move |_, _, winit_state: &mut WinitState| {
|
||||
// Mark that we have something to dispatch.
|
||||
winit_state.dispatched_events = true;
|
||||
},
|
||||
)
|
||||
.map_err(|error| error.error);
|
||||
map_err!(result, WaylandError::Calloop)?;
|
||||
|
||||
let window_target = EventLoopWindowTarget {
|
||||
connection: connection.clone(),
|
||||
wayland_dispatcher: wayland_dispatcher.clone(),
|
||||
|
@ -158,12 +190,12 @@ impl<T: 'static> EventLoop<T> {
|
|||
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
|
||||
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
if self.loop_running {
|
||||
return Err(RunLoopError::AlreadyRunning);
|
||||
return Err(EventLoopError::AlreadyRunning);
|
||||
}
|
||||
|
||||
let exit = loop {
|
||||
|
@ -172,7 +204,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
break Ok(());
|
||||
}
|
||||
PumpStatus::Exit(code) => {
|
||||
break Err(RunLoopError::ExitFailure(code));
|
||||
break Err(EventLoopError::ExitFailure(code));
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
|
@ -184,7 +216,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
// `run_ondemand` calls but if they have only just dropped their
|
||||
// windows we need to make sure those last requests are sent to the
|
||||
// compositor.
|
||||
let _ = self.roundtrip().map_err(RunLoopError::Os);
|
||||
let _ = self.roundtrip().map_err(EventLoopError::Os);
|
||||
|
||||
exit
|
||||
}
|
||||
|
@ -617,10 +649,10 @@ impl<T: 'static> EventLoop<T> {
|
|||
|
||||
let mut wayland_source = self.wayland_dispatcher.as_source_mut();
|
||||
let event_queue = wayland_source.queue();
|
||||
event_queue.roundtrip(state).map_err(|_| {
|
||||
os_error!(OsError::WaylandMisc(
|
||||
"failed to do a final roundtrip before exiting the loop."
|
||||
))
|
||||
event_queue.roundtrip(state).map_err(|error| {
|
||||
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
|
||||
error
|
||||
))))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
//! Winit's Wayland backend.
|
||||
|
||||
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||
use sctk::reexports::client::Proxy;
|
||||
use std::fmt::Display;
|
||||
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 output::{MonitorHandle, VideoMode};
|
||||
pub use window::Window;
|
||||
|
@ -17,6 +21,46 @@ mod state;
|
|||
mod types;
|
||||
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.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct DeviceId;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use std::cell::RefCell;
|
||||
use std::error::Error;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
|
@ -24,6 +23,7 @@ use sctk::shm::{Shm, ShmHandler};
|
|||
use sctk::subcompositor::SubcompositorState;
|
||||
|
||||
use crate::dpi::LogicalSize;
|
||||
use crate::platform_impl::OsError;
|
||||
|
||||
use super::event_loop::sink::EventSink;
|
||||
use super::output::MonitorHandle;
|
||||
|
@ -35,7 +35,7 @@ use super::types::wp_fractional_scaling::FractionalScalingManager;
|
|||
use super::types::wp_viewporter::ViewporterState;
|
||||
use super::types::xdg_activation::XdgActivationState;
|
||||
use super::window::{WindowRequests, WindowState};
|
||||
use super::WindowId;
|
||||
use super::{WaylandError, WindowId};
|
||||
|
||||
/// Winit's Wayland state.
|
||||
pub struct WinitState {
|
||||
|
@ -116,14 +116,16 @@ impl WinitState {
|
|||
globals: &GlobalList,
|
||||
queue_handle: &QueueHandle<Self>,
|
||||
loop_handle: LoopHandle<'static, WinitState>,
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
) -> Result<Self, OsError> {
|
||||
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(
|
||||
compositor_state.wl_compositor().clone(),
|
||||
globals,
|
||||
queue_handle,
|
||||
)?;
|
||||
)
|
||||
.map_err(WaylandError::Bind)?;
|
||||
|
||||
let output_state = OutputState::new(globals, queue_handle);
|
||||
let monitors = output_state.outputs().map(MonitorHandle::new).collect();
|
||||
|
@ -148,9 +150,9 @@ impl WinitState {
|
|||
subcompositor_state: Arc::new(subcompositor_state),
|
||||
output_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(),
|
||||
|
||||
windows: Default::default(),
|
||||
|
|
|
@ -36,7 +36,7 @@ use super::event_loop::sink::EventSink;
|
|||
use super::output::MonitorHandle;
|
||||
use super::state::WinitState;
|
||||
use super::types::xdg_activation::XdgActivationTokenData;
|
||||
use super::{EventLoopWindowTarget, WindowId};
|
||||
use super::{EventLoopWindowTarget, WaylandError, WindowId};
|
||||
|
||||
pub(crate) mod state;
|
||||
|
||||
|
@ -205,18 +205,18 @@ impl Window {
|
|||
let event_queue = wayland_source.queue();
|
||||
|
||||
// Do a roundtrip.
|
||||
event_queue.roundtrip(&mut state).map_err(|_| {
|
||||
os_error!(OsError::WaylandMisc(
|
||||
"failed to do initial roundtrip for the window."
|
||||
))
|
||||
event_queue.roundtrip(&mut state).map_err(|error| {
|
||||
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
|
||||
error
|
||||
))))
|
||||
})?;
|
||||
|
||||
// XXX Wait for the initial configure to arrive.
|
||||
while !window_state.lock().unwrap().is_configured() {
|
||||
event_queue.blocking_dispatch(&mut state).map_err(|_| {
|
||||
os_error!(OsError::WaylandMisc(
|
||||
"failed to dispatch queue while waiting for initial configure."
|
||||
))
|
||||
event_queue.blocking_dispatch(&mut state).map_err(|error| {
|
||||
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
|
||||
error
|
||||
))))
|
||||
})?;
|
||||
}
|
||||
|
||||
|
@ -574,9 +574,7 @@ impl Window {
|
|||
Ok(())
|
||||
} else {
|
||||
let region = Region::new(&*self.compositor).map_err(|_| {
|
||||
ExternalError::Os(os_error!(OsError::WaylandMisc(
|
||||
"failed to set input region."
|
||||
)))
|
||||
ExternalError::Os(os_error!(OsError::Misc("failed to set input region.")))
|
||||
})?;
|
||||
region.add(0, 0, 0, 0);
|
||||
surface.set_input_region(Some(region.wl_region()));
|
||||
|
|
|
@ -712,7 +712,7 @@ impl WindowState {
|
|||
// Positon can be set only for locked cursor.
|
||||
if self.cursor_grab_mode.current_grab_mode != CursorGrabMode::Locked {
|
||||
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."
|
||||
)
|
||||
)));
|
||||
|
|
|
@ -64,7 +64,7 @@ use self::{
|
|||
};
|
||||
use super::{common::xkb_state::KbdState, OsError};
|
||||
use crate::{
|
||||
error::{OsError as RootOsError, RunLoopError},
|
||||
error::{EventLoopError, OsError as RootOsError},
|
||||
event::{Event, StartCause},
|
||||
event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
||||
platform::pump_events::PumpStatus,
|
||||
|
@ -432,12 +432,12 @@ impl<T: 'static> EventLoop<T> {
|
|||
&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
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
if self.loop_running {
|
||||
return Err(RunLoopError::AlreadyRunning);
|
||||
return Err(EventLoopError::AlreadyRunning);
|
||||
}
|
||||
|
||||
let exit = loop {
|
||||
|
@ -446,7 +446,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
break Ok(());
|
||||
}
|
||||
PumpStatus::Exit(code) => {
|
||||
break Err(RunLoopError::ExitFailure(code));
|
||||
break Err(EventLoopError::ExitFailure(code));
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
|
@ -460,7 +460,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
// X Server.
|
||||
let wt = get_xtarget(&self.target);
|
||||
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
|
||||
|
|
|
@ -507,7 +507,7 @@ impl UnownedWindow {
|
|||
&mut supported_ptr,
|
||||
);
|
||||
if supported_ptr == ffi::False {
|
||||
return Err(os_error!(OsError::XMisc(
|
||||
return Err(os_error!(OsError::Misc(
|
||||
"`XkbSetDetectableAutoRepeat` failed"
|
||||
)));
|
||||
}
|
||||
|
@ -1525,7 +1525,7 @@ impl UnownedWindow {
|
|||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err))))
|
||||
.map_err(|err| ExternalError::Os(os_error!(OsError::Misc(err))))
|
||||
}
|
||||
CursorGrabMode::Locked => {
|
||||
return Err(ExternalError::NotSupported(NotSupportedError::new()));
|
||||
|
|
|
@ -24,7 +24,7 @@ use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle};
|
|||
|
||||
use super::appkit::{NSApp, NSApplicationActivationPolicy, NSEvent, NSWindow};
|
||||
use crate::{
|
||||
error::RunLoopError,
|
||||
error::EventLoopError,
|
||||
event::Event,
|
||||
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget},
|
||||
platform::{macos::ActivationPolicy, pump_events::PumpStatus},
|
||||
|
@ -148,7 +148,9 @@ impl Default for PlatformSpecificEventLoopAttributes {
|
|||
}
|
||||
|
||||
impl<T> EventLoop<T> {
|
||||
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
|
||||
pub(crate) fn new(
|
||||
attributes: &PlatformSpecificEventLoopAttributes,
|
||||
) -> Result<Self, EventLoopError> {
|
||||
if !is_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();
|
||||
setup_control_flow_observers(Rc::downgrade(&panic_info));
|
||||
EventLoop {
|
||||
Ok(EventLoop {
|
||||
_delegate: delegate,
|
||||
window_target: Rc::new(RootWindowTarget {
|
||||
p: Default::default(),
|
||||
|
@ -186,14 +188,14 @@ impl<T> EventLoop<T> {
|
|||
}),
|
||||
panic_info,
|
||||
_callback: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootWindowTarget<T> {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
||||
pub fn run<F>(mut self, callback: F) -> Result<(), EventLoopError>
|
||||
where
|
||||
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
|
||||
// time and so a layered implementation would end up using a lot of CPU due to
|
||||
// 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
|
||||
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
if AppState::is_running() {
|
||||
return Err(RunLoopError::AlreadyRunning);
|
||||
return Err(EventLoopError::AlreadyRunning);
|
||||
}
|
||||
|
||||
// # Safety
|
||||
|
@ -287,7 +289,7 @@ impl<T> EventLoop<T> {
|
|||
if exit_code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(RunLoopError::ExitFailure(exit_code))
|
||||
Err(EventLoopError::ExitFailure(exit_code))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use orbclient::{
|
|||
use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle};
|
||||
|
||||
use crate::{
|
||||
error::RunLoopError,
|
||||
error::EventLoopError,
|
||||
event::{self, Ime, Modifiers, StartCause},
|
||||
event_loop::{self, ControlFlow},
|
||||
keyboard::{
|
||||
|
@ -22,8 +22,8 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{
|
||||
DeviceId, KeyEventExtra, MonitorHandle, PlatformSpecificEventLoopAttributes, RedoxSocket,
|
||||
TimeSocket, WindowId, WindowProperties,
|
||||
DeviceId, KeyEventExtra, MonitorHandle, OsError, PlatformSpecificEventLoopAttributes,
|
||||
RedoxSocket, TimeSocket, WindowId, WindowProperties,
|
||||
};
|
||||
|
||||
fn convert_scancode(scancode: u8) -> KeyCode {
|
||||
|
@ -270,12 +270,20 @@ pub struct EventLoop<T: 'static> {
|
|||
}
|
||||
|
||||
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 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
|
||||
.write(&syscall::Event {
|
||||
|
@ -283,9 +291,10 @@ impl<T: 'static> EventLoop<T> {
|
|||
flags: syscall::EventFlags::EVENT_READ,
|
||||
data: wake_socket.0.fd,
|
||||
})
|
||||
.unwrap();
|
||||
.map_err(OsError::new)
|
||||
.map_err(|error| EventLoopError::Os(os_error!(error)))?;
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
windows: Vec::new(),
|
||||
window_target: event_loop::EventLoopWindowTarget {
|
||||
p: EventLoopWindowTarget {
|
||||
|
@ -299,7 +308,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
},
|
||||
_marker: std::marker::PhantomData,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
|
@ -685,7 +694,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
if code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(RunLoopError::ExitFailure(code))
|
||||
Err(EventLoopError::ExitFailure(code))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#![cfg(target_os = "redox")]
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
|
||||
|
@ -176,13 +178,18 @@ impl<'a> fmt::Display for WindowProperties<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct OsError;
|
||||
#[derive(Clone, Debug)]
|
||||
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 {
|
||||
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;
|
||||
pub(crate) mod runner;
|
||||
mod state;
|
||||
mod window_target;
|
||||
|
||||
pub use self::proxy::EventLoopProxy;
|
||||
pub use self::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 use proxy::EventLoopProxy;
|
||||
pub use window_target::EventLoopWindowTarget;
|
||||
|
||||
pub struct EventLoop<T: 'static> {
|
||||
elw: RootEventLoopWindowTarget<T>,
|
||||
|
@ -20,13 +22,13 @@ pub struct EventLoop<T: 'static> {
|
|||
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
||||
|
||||
impl<T> EventLoop<T> {
|
||||
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self {
|
||||
EventLoop {
|
||||
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
|
||||
Ok(EventLoop {
|
||||
elw: RootEventLoopWindowTarget {
|
||||
p: EventLoopWindowTarget::new(),
|
||||
_marker: PhantomData,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run<F>(self, mut event_handler: F) -> !
|
||||
|
|
|
@ -75,7 +75,7 @@ use windows_sys::Win32::{
|
|||
|
||||
use crate::{
|
||||
dpi::{PhysicalPosition, PhysicalSize},
|
||||
error::RunLoopError,
|
||||
error::EventLoopError,
|
||||
event::{
|
||||
DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase,
|
||||
WindowEvent,
|
||||
|
@ -201,7 +201,9 @@ pub struct EventLoopWindowTarget<T: 'static> {
|
|||
}
|
||||
|
||||
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() };
|
||||
|
||||
if !attributes.any_thread && thread_id != main_thread_id() {
|
||||
|
@ -228,7 +230,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
Default::default(),
|
||||
);
|
||||
|
||||
EventLoop {
|
||||
Ok(EventLoop {
|
||||
thread_msg_sender,
|
||||
window_target: RootELW {
|
||||
p: EventLoopWindowTarget {
|
||||
|
@ -239,28 +241,28 @@ impl<T: 'static> EventLoop<T> {
|
|||
_marker: PhantomData,
|
||||
},
|
||||
msg_hook: attributes.msg_hook.take(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootELW<T> {
|
||||
&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
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
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
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
{
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
if runner.state() != RunnerState::Uninitialized {
|
||||
return Err(RunLoopError::AlreadyRunning);
|
||||
return Err(EventLoopError::AlreadyRunning);
|
||||
}
|
||||
|
||||
let event_loop_windows_ref = &self.window_target;
|
||||
|
@ -295,7 +297,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
if exit_code == 0 {
|
||||
Ok(())
|
||||
} 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,
|
||||
/// };
|
||||
///
|
||||
/// let mut event_loop = EventLoop::new();
|
||||
/// let mut event_loop = EventLoop::new().unwrap();
|
||||
/// let window = Window::new(&event_loop).unwrap();
|
||||
///
|
||||
/// event_loop.run(move |event, _, control_flow| {
|
||||
|
@ -570,7 +570,7 @@ impl Window {
|
|||
/// ```no_run
|
||||
/// # use winit::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// # fn swap_buffers() {}
|
||||
/// // Do the actual drawing with OpenGL.
|
||||
|
@ -660,7 +660,7 @@ impl Window {
|
|||
/// # use winit::dpi::{LogicalPosition, PhysicalPosition};
|
||||
/// # use winit::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// // Specify the position in logical dimensions like this:
|
||||
/// window.set_outer_position(LogicalPosition::new(400.0, 200.0));
|
||||
|
@ -720,7 +720,7 @@ impl Window {
|
|||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||
/// # use winit::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// // Specify the size in logical dimensions like this:
|
||||
/// let _ = window.request_inner_size(LogicalSize::new(400.0, 200.0));
|
||||
|
@ -763,7 +763,7 @@ impl Window {
|
|||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||
/// # use winit::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// // Specify the size in logical dimensions like this:
|
||||
/// 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::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// // Specify the size in logical dimensions like this:
|
||||
/// 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::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// // Specify the position in logical dimensions like this:
|
||||
/// 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::event_loop::EventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # let mut event_loop = EventLoop::new();
|
||||
/// # let mut event_loop = EventLoop::new().unwrap();
|
||||
/// # let window = Window::new(&event_loop).unwrap();
|
||||
/// // Specify the position in logical dimensions like this:
|
||||
/// window.set_cursor_position(LogicalPosition::new(400.0, 200.0));
|
||||
|
@ -1292,7 +1292,7 @@ impl Window {
|
|||
/// ```no_run
|
||||
/// # use winit::event_loop::EventLoop;
|
||||
/// # 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();
|
||||
/// window.set_cursor_grab(CursorGrabMode::Confined)
|
||||
/// .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked))
|
||||
|
|
Loading…
Reference in a new issue