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:
parent
ed26dd58fd
commit
793c535b01
57 changed files with 291 additions and 344 deletions
|
|
@ -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."
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
)
|
||||
)));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue