Revert "Propagate error from EventLoop creation" (#3010)

This reverts commit ed26dd58fd.
The patched was merged with a review by accident.
This commit is contained in:
Kirill Chibisov 2023-08-06 06:07:01 +04:00 committed by GitHub
parent ed26dd58fd
commit 793c535b01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 291 additions and 344 deletions

View file

@ -30,7 +30,7 @@ use crate::{
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel,
},
};
use crate::{error::EventLoopError, platform_impl::Fullscreen};
use crate::{error::RunLoopError, platform_impl::Fullscreen};
mod keycodes;
@ -186,15 +186,13 @@ fn sticky_exit_callback<T, F>(
}
impl<T: 'static> EventLoop<T> {
pub(crate) fn new(
attributes: &PlatformSpecificEventLoopAttributes,
) -> Result<Self, EventLoopError> {
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
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();
Ok(Self {
Self {
android_app: android_app.clone(),
window_target: event_loop::EventLoopWindowTarget {
p: EventLoopWindowTarget {
@ -216,7 +214,7 @@ impl<T: 'static> EventLoop<T> {
control_flow: Default::default(),
cause: StartCause::Init,
ignore_volume_keys: attributes.ignore_volume_keys,
})
}
}
fn single_iteration<F>(&mut self, main_event: Option<MainEvent<'_>>, callback: &mut F)
@ -526,19 +524,19 @@ impl<T: 'static> EventLoop<T> {
self.pending_redraw = pending_redraw;
}
pub fn run<F>(mut self, event_handler: F) -> Result<(), EventLoopError>
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
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<(), EventLoopError>
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
where
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{
if self.loop_running {
return Err(EventLoopError::AlreadyRunning);
return Err(RunLoopError::AlreadyRunning);
}
loop {
@ -547,7 +545,7 @@ impl<T: 'static> EventLoop<T> {
break Ok(());
}
PumpStatus::Exit(code) => {
break Err(EventLoopError::ExitFailure(code));
break Err(RunLoopError::ExitFailure(code));
}
_ => {
continue;

View file

@ -19,9 +19,11 @@ 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,
@ -29,10 +31,6 @@ 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>),
@ -77,9 +75,7 @@ pub struct EventLoop<T: 'static> {
pub(crate) struct PlatformSpecificEventLoopAttributes {}
impl<T: 'static> EventLoop<T> {
pub(crate) fn new(
_: &PlatformSpecificEventLoopAttributes,
) -> Result<EventLoop<T>, EventLoopError> {
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> EventLoop<T> {
assert_main_thread!("`EventLoop` can only be created on the main thread on iOS");
static mut SINGLETON_INIT: bool = false;
@ -97,7 +93,7 @@ impl<T: 'static> EventLoop<T> {
// this line sets up the main run loop before `UIApplicationMain`
setup_control_flow_observers();
Ok(EventLoop {
EventLoop {
window_target: RootEventLoopWindowTarget {
p: EventLoopWindowTarget {
receiver,
@ -105,7 +101,7 @@ impl<T: 'static> EventLoop<T> {
},
_marker: PhantomData,
},
})
}
}
pub fn run<F>(self, event_handler: F) -> !

View file

@ -3,22 +3,33 @@
#[cfg(all(not(x11_platform), not(wayland_platform)))]
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
use std::sync::Arc;
use std::time::Duration;
#[cfg(wayland_platform)]
use std::error::Error;
use std::{collections::VecDeque, env, fmt};
#[cfg(x11_platform)]
use std::{ffi::CStr, mem::MaybeUninit, os::raw::*, sync::Mutex};
use std::{
ffi::CStr,
mem::MaybeUninit,
os::raw::*,
sync::{Arc, 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::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError},
error::{ExternalError, NotSupportedError, OsError as RootOsError, RunLoopError},
event::{Event, KeyEvent},
event_loop::{
AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed,
@ -35,10 +46,6 @@ 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;
@ -49,6 +56,15 @@ 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)]
@ -116,21 +132,23 @@ 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)]
WaylandError(Arc<wayland::WaylandError>),
WaylandMisc(&'static str),
}
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::WaylandError(ref e) => fmt::Display::fmt(e, _f),
OsError::WaylandMisc(e) => _f.pad(e),
}
}
}
@ -726,9 +744,7 @@ impl<T: 'static> Clone for EventLoopProxy<T> {
}
impl<T: 'static> EventLoop<T> {
pub(crate) fn new(
attributes: &PlatformSpecificEventLoopAttributes,
) -> Result<Self, EventLoopError> {
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
if !attributes.any_thread && !is_main_thread() {
panic!(
"Initializing the event loop outside of the main thread is a significant \
@ -738,26 +754,65 @@ impl<T: 'static> EventLoop<T> {
);
}
// NOTE: Wayland first because of X11 could be present under wayland as well.
#[cfg(wayland_platform)]
if attributes.forced_backend == Some(Backend::Wayland)
|| env::var("WAYLAND_DISPLAY").is_ok()
{
return EventLoop::new_wayland_any_thread().map_err(Into::into);
#[cfg(x11_platform)]
if attributes.forced_backend == Some(Backend::X) {
// TODO: Propagate
return EventLoop::new_x11_any_thread().unwrap();
}
#[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 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)]
if attributes.forced_backend == Some(Backend::X) || env::var("DISPLAY").is_ok() {
return Ok(EventLoop::new_x11_any_thread().unwrap());
}
let x11_err = match EventLoop::new_x11_any_thread() {
Ok(event_loop) => return event_loop,
Err(err) => err,
};
Err(EventLoopError::Os(os_error!(OsError::Misc(
"neither WAYLAND_DISPLAY nor DISPLAY is set."
))))
#[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:?}",
);
}
#[cfg(wayland_platform)]
fn new_wayland_any_thread() -> Result<EventLoop<T>, EventLoopError> {
fn new_wayland_any_thread() -> Result<EventLoop<T>, Box<dyn Error>> {
wayland::EventLoop::new().map(|evlp| EventLoop::Wayland(Box::new(evlp)))
}
@ -775,14 +830,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<(), EventLoopError>
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
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<(), EventLoopError>
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
where
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
{

View file

@ -1,6 +1,7 @@
//! 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;
@ -12,12 +13,11 @@ 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::{EventLoopError, OsError as RootOsError};
use crate::error::{OsError as RootOsError, RunLoopError};
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, WaylandError, WindowId};
use super::{DeviceId, WindowId};
type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource<WinitState>, WinitState>;
@ -73,38 +73,22 @@ pub struct EventLoop<T: 'static> {
}
impl<T: 'static> EventLoop<T> {
pub fn new() -> Result<EventLoop<T>, EventLoopError> {
macro_rules! map_err {
($e:expr, $err:expr) => {
$e.map_err(|error| os_error!($err(error).into()))
};
}
pub fn new() -> Result<EventLoop<T>, Box<dyn Error>> {
let connection = Connection::connect_to_env()?;
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 (globals, mut event_queue) = globals::registry_queue_init(&connection)?;
let queue_handle = event_queue.handle();
let event_loop = map_err!(
calloop::EventLoop::<WinitState>::try_new(),
WaylandError::Calloop
)?;
let event_loop = calloop::EventLoop::<WinitState>::try_new()?;
let mut winit_state = WinitState::new(&globals, &queue_handle, event_loop.handle())
.map_err(|error| os_error!(error))?;
let mut winit_state = WinitState::new(&globals, &queue_handle, event_loop.handle())?;
// NOTE: do a roundtrip after binding the globals to prevent potential
// races with the server.
map_err!(
event_queue.roundtrip(&mut winit_state),
WaylandError::Dispatch
)?;
event_queue.roundtrip(&mut winit_state)?;
// Register Wayland source.
let wayland_source = map_err!(WaylandSource::new(event_queue), WaylandError::Wire)?;
let wayland_source = WaylandSource::new(event_queue)?;
let wayland_dispatcher =
calloop::Dispatcher::new(wayland_source, |_, queue, winit_state: &mut WinitState| {
let result = queue.dispatch_pending(winit_state);
@ -117,52 +101,32 @@ impl<T: 'static> EventLoop<T> {
result
});
map_err!(
event_loop
.handle()
.register_dispatcher(wayland_dispatcher.clone()),
WaylandError::Calloop
)?;
event_loop
.handle()
.register_dispatcher(wayland_dispatcher.clone())?;
// 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();
map_err!(
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),
WaylandError::Calloop
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);
}
},
)?;
// An event's loop awakener to wake up for window events from winit's windows.
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
)?;
map_err!(
event_loop
.handle()
.insert_source(
event_loop_awakener_source,
move |_, _, winit_state: &mut WinitState| {
// No extra handling is required, we just need to wake-up.
winit_state.dispatched_events = true;
},
)
.map_err(|error| error.error),
WaylandError::Calloop
let (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| {
// No extra handling is required, we just need to wake-up.
winit_state.dispatched_events = true;
},
)?;
let window_target = EventLoopWindowTarget {
@ -194,12 +158,12 @@ impl<T: 'static> EventLoop<T> {
Ok(event_loop)
}
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), EventLoopError>
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
where
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{
if self.loop_running {
return Err(EventLoopError::AlreadyRunning);
return Err(RunLoopError::AlreadyRunning);
}
let exit = loop {
@ -208,7 +172,7 @@ impl<T: 'static> EventLoop<T> {
break Ok(());
}
PumpStatus::Exit(code) => {
break Err(EventLoopError::ExitFailure(code));
break Err(RunLoopError::ExitFailure(code));
}
_ => {
continue;
@ -220,7 +184,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(EventLoopError::Os);
let _ = self.roundtrip().map_err(RunLoopError::Os);
exit
}
@ -653,10 +617,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(|error| {
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
error
))))
event_queue.roundtrip(state).map_err(|_| {
os_error!(OsError::WaylandMisc(
"failed to do a final roundtrip before exiting the loop."
))
})
}
}

View file

@ -2,14 +2,10 @@
//! Winit's Wayland backend.
use std::fmt::Display;
use std::sync::Arc;
use sctk::reexports::client::globals::{BindError, GlobalError};
use sctk::reexports::client::protocol::wl_surface::WlSurface;
use sctk::reexports::client::{self, ConnectError, DispatchError, Proxy};
use sctk::reexports::client::Proxy;
pub use crate::platform_impl::platform::{OsError, WindowId};
pub use crate::platform_impl::platform::WindowId;
pub use event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
pub use output::{MonitorHandle, VideoMode};
pub use window::Window;
@ -21,46 +17,6 @@ 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;

View file

@ -1,4 +1,5 @@
use std::cell::RefCell;
use std::error::Error;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex};
@ -23,7 +24,6 @@ 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::{WaylandError, WindowId};
use super::WindowId;
/// Winit's Wayland state.
pub struct WinitState {
@ -116,16 +116,14 @@ impl WinitState {
globals: &GlobalList,
queue_handle: &QueueHandle<Self>,
loop_handle: LoopHandle<'static, WinitState>,
) -> Result<Self, OsError> {
) -> Result<Self, Box<dyn Error>> {
let registry_state = RegistryState::new(globals);
let compositor_state =
CompositorState::bind(globals, queue_handle).map_err(WaylandError::Bind)?;
let compositor_state = CompositorState::bind(globals, queue_handle)?;
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();
@ -150,9 +148,9 @@ impl WinitState {
subcompositor_state: Arc::new(subcompositor_state),
output_state,
seat_state,
shm: Shm::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
shm: Shm::bind(globals, queue_handle)?,
xdg_shell: XdgShell::bind(globals, queue_handle).map_err(WaylandError::Bind)?,
xdg_shell: XdgShell::bind(globals, queue_handle)?,
xdg_activation: XdgActivationState::bind(globals, queue_handle).ok(),
windows: Default::default(),

View file

@ -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, WaylandError, WindowId};
use super::{EventLoopWindowTarget, 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(|error| {
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
error
))))
event_queue.roundtrip(&mut state).map_err(|_| {
os_error!(OsError::WaylandMisc(
"failed to do initial roundtrip for the window."
))
})?;
// XXX Wait for the initial configure to arrive.
while !window_state.lock().unwrap().is_configured() {
event_queue.blocking_dispatch(&mut state).map_err(|error| {
os_error!(OsError::WaylandError(Arc::new(WaylandError::Dispatch(
error
))))
event_queue.blocking_dispatch(&mut state).map_err(|_| {
os_error!(OsError::WaylandMisc(
"failed to dispatch queue while waiting for initial configure."
))
})?;
}
@ -570,7 +570,9 @@ impl Window {
Ok(())
} else {
let region = Region::new(&*self.compositor).map_err(|_| {
ExternalError::Os(os_error!(OsError::Misc("failed to set input region.")))
ExternalError::Os(os_error!(OsError::WaylandMisc(
"failed to set input region."
)))
})?;
region.add(0, 0, 0, 0);
surface.set_input_region(Some(region.wl_region()));

View file

@ -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::Misc(
crate::platform_impl::OsError::WaylandMisc(
"cursor position can be set only for locked cursor."
)
)));

View file

@ -64,7 +64,7 @@ use self::{
};
use super::{common::xkb_state::KbdState, OsError};
use crate::{
error::{EventLoopError, OsError as RootOsError},
error::{OsError as RootOsError, RunLoopError},
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<(), EventLoopError>
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
where
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
{
if self.loop_running {
return Err(EventLoopError::AlreadyRunning);
return Err(RunLoopError::AlreadyRunning);
}
let exit = loop {
@ -446,7 +446,7 @@ impl<T: 'static> EventLoop<T> {
break Ok(());
}
PumpStatus::Exit(code) => {
break Err(EventLoopError::ExitFailure(code));
break Err(RunLoopError::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| {
EventLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err)))))
RunLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err)))))
})?;
exit

View file

@ -485,7 +485,7 @@ impl UnownedWindow {
&mut supported_ptr,
);
if supported_ptr == ffi::False {
return Err(os_error!(OsError::Misc(
return Err(os_error!(OsError::XMisc(
"`XkbSetDetectableAutoRepeat` failed"
)));
}
@ -1488,7 +1488,7 @@ impl UnownedWindow {
}
_ => unreachable!(),
}
.map_err(|err| ExternalError::Os(os_error!(OsError::Misc(err))))
.map_err(|err| ExternalError::Os(os_error!(OsError::XMisc(err))))
}
CursorGrabMode::Locked => {
return Err(ExternalError::NotSupported(NotSupportedError::new()));

View file

@ -24,7 +24,7 @@ use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle};
use super::appkit::{NSApp, NSApplicationActivationPolicy, NSEvent, NSWindow};
use crate::{
error::EventLoopError,
error::RunLoopError,
event::Event,
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget},
platform::{macos::ActivationPolicy, pump_events::PumpStatus},
@ -148,9 +148,7 @@ impl Default for PlatformSpecificEventLoopAttributes {
}
impl<T> EventLoop<T> {
pub(crate) fn new(
attributes: &PlatformSpecificEventLoopAttributes,
) -> Result<Self, EventLoopError> {
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
if !is_main_thread() {
panic!("On macOS, `EventLoop` must be created on the main thread!");
}
@ -180,7 +178,7 @@ impl<T> EventLoop<T> {
let panic_info: Rc<PanicInfo> = Default::default();
setup_control_flow_observers(Rc::downgrade(&panic_info));
Ok(EventLoop {
EventLoop {
_delegate: delegate,
window_target: Rc::new(RootWindowTarget {
p: Default::default(),
@ -188,14 +186,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<(), EventLoopError>
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
where
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
{
@ -206,12 +204,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<(), EventLoopError>
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
where
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
{
if AppState::is_running() {
return Err(EventLoopError::AlreadyRunning);
return Err(RunLoopError::AlreadyRunning);
}
// # Safety
@ -289,7 +287,7 @@ impl<T> EventLoop<T> {
if exit_code == 0 {
Ok(())
} else {
Err(EventLoopError::ExitFailure(exit_code))
Err(RunLoopError::ExitFailure(exit_code))
}
}

View file

@ -12,7 +12,7 @@ use orbclient::{
use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle};
use crate::{
error::EventLoopError,
error::RunLoopError,
event::{self, Ime, Modifiers, StartCause},
event_loop::{self, ControlFlow},
keyboard::{
@ -22,8 +22,8 @@ use crate::{
};
use super::{
DeviceId, KeyEventExtra, MonitorHandle, OsError, PlatformSpecificEventLoopAttributes,
RedoxSocket, TimeSocket, WindowId, WindowProperties,
DeviceId, KeyEventExtra, MonitorHandle, PlatformSpecificEventLoopAttributes, RedoxSocket,
TimeSocket, WindowId, WindowProperties,
};
fn convert_scancode(scancode: u8) -> KeyCode {
@ -270,20 +270,12 @@ pub struct EventLoop<T: 'static> {
}
impl<T: 'static> EventLoop<T> {
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self {
let (user_events_sender, user_events_receiver) = mpsc::channel();
let event_socket = Arc::new(
RedoxSocket::event()
.map_err(OsError::new)
.map_err(|error| EventLoopError::Os(os_error!(error)))?,
);
let event_socket = Arc::new(RedoxSocket::event().unwrap());
let wake_socket = Arc::new(
TimeSocket::open()
.map_err(OsError::new)
.map_err(|error| EventLoopError::Os(os_error!(error)))?,
);
let wake_socket = Arc::new(TimeSocket::open().unwrap());
event_socket
.write(&syscall::Event {
@ -291,10 +283,9 @@ impl<T: 'static> EventLoop<T> {
flags: syscall::EventFlags::EVENT_READ,
data: wake_socket.0.fd,
})
.map_err(OsError::new)
.map_err(|error| EventLoopError::Os(os_error!(error)))?;
.unwrap();
Ok(Self {
Self {
windows: Vec::new(),
window_target: event_loop::EventLoopWindowTarget {
p: EventLoopWindowTarget {
@ -308,7 +299,7 @@ impl<T: 'static> EventLoop<T> {
},
_marker: std::marker::PhantomData,
},
})
}
}
fn process_event<F>(
@ -452,7 +443,7 @@ impl<T: 'static> EventLoop<T> {
}
}
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), EventLoopError>
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError>
where
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{
@ -694,7 +685,7 @@ impl<T: 'static> EventLoop<T> {
if code == 0 {
Ok(())
} else {
Err(EventLoopError::ExitFailure(code))
Err(RunLoopError::ExitFailure(code))
}
}

View file

@ -1,8 +1,6 @@
#![cfg(target_os = "redox")]
use std::fmt::{self, Display, Formatter};
use std::str;
use std::sync::Arc;
use crate::dpi::{PhysicalPosition, PhysicalSize};
@ -178,18 +176,13 @@ impl<'a> fmt::Display for WindowProperties<'a> {
}
}
#[derive(Clone, Debug)]
pub struct OsError(Arc<syscall::Error>);
impl OsError {
fn new(error: syscall::Error) -> Self {
Self(Arc::new(error))
}
}
#[derive(Default, Clone, Debug)]
pub struct OsError;
use std::fmt::{self, Display, Formatter};
impl Display for OsError {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
self.0.fmt(fmt)
write!(fmt, "Redox OS Error")
}
}

View file

@ -1,18 +1,16 @@
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 proxy::EventLoopProxy;
pub use window_target::EventLoopWindowTarget;
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 struct EventLoop<T: 'static> {
elw: RootEventLoopWindowTarget<T>,
@ -22,13 +20,13 @@ pub struct EventLoop<T: 'static> {
pub(crate) struct PlatformSpecificEventLoopAttributes {}
impl<T> EventLoop<T> {
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
Ok(EventLoop {
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Self {
EventLoop {
elw: RootEventLoopWindowTarget {
p: EventLoopWindowTarget::new(),
_marker: PhantomData,
},
})
}
}
pub fn run<F>(self, mut event_handler: F) -> !

View file

@ -75,7 +75,7 @@ use windows_sys::Win32::{
use crate::{
dpi::{PhysicalPosition, PhysicalSize},
error::EventLoopError,
error::RunLoopError,
event::{
DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase,
WindowEvent,
@ -201,9 +201,7 @@ pub struct EventLoopWindowTarget<T: 'static> {
}
impl<T: 'static> EventLoop<T> {
pub(crate) fn new(
attributes: &mut PlatformSpecificEventLoopAttributes,
) -> Result<Self, EventLoopError> {
pub(crate) fn new(attributes: &mut PlatformSpecificEventLoopAttributes) -> Self {
let thread_id = unsafe { GetCurrentThreadId() };
if !attributes.any_thread && thread_id != main_thread_id() {
@ -230,7 +228,7 @@ impl<T: 'static> EventLoop<T> {
Default::default(),
);
Ok(EventLoop {
EventLoop {
thread_msg_sender,
window_target: RootELW {
p: EventLoopWindowTarget {
@ -241,28 +239,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<(), EventLoopError>
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
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<(), EventLoopError>
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
where
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
{
{
let runner = &self.window_target.p.runner_shared;
if runner.state() != RunnerState::Uninitialized {
return Err(EventLoopError::AlreadyRunning);
return Err(RunLoopError::AlreadyRunning);
}
let event_loop_windows_ref = &self.window_target;
@ -297,7 +295,7 @@ impl<T: 'static> EventLoop<T> {
if exit_code == 0 {
Ok(())
} else {
Err(EventLoopError::ExitFailure(exit_code))
Err(RunLoopError::ExitFailure(exit_code))
}
}