improv(sctk): setup error handling
This commit is contained in:
parent
9668aeba1f
commit
e4f8120eed
1 changed files with 260 additions and 233 deletions
|
|
@ -50,6 +50,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use wayland_backend::client::Backend;
|
use wayland_backend::client::Backend;
|
||||||
|
use wayland_client::globals::GlobalError;
|
||||||
use winit::{dpi::LogicalSize, event_loop::OwnedDisplayHandle};
|
use winit::{dpi::LogicalSize, event_loop::OwnedDisplayHandle};
|
||||||
|
|
||||||
use self::state::SctkState;
|
use self::state::SctkState;
|
||||||
|
|
@ -65,6 +66,14 @@ pub struct SctkEventLoop {
|
||||||
pub(crate) state: SctkState,
|
pub(crate) state: SctkState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Error {
|
||||||
|
Connect(ConnectError),
|
||||||
|
Calloop(calloop::Error),
|
||||||
|
Global(GlobalError),
|
||||||
|
NoDisplayHandle,
|
||||||
|
NoWaylandDisplay,
|
||||||
|
}
|
||||||
|
|
||||||
impl SctkEventLoop {
|
impl SctkEventLoop {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
winit_event_sender: mpsc::UnboundedSender<Control>,
|
winit_event_sender: mpsc::UnboundedSender<Control>,
|
||||||
|
|
@ -76,12 +85,13 @@ impl SctkEventLoop {
|
||||||
> {
|
> {
|
||||||
let Ok(dh) = display.display_handle() else {
|
let Ok(dh) = display.display_handle() else {
|
||||||
log::error!("Failed to get display handle");
|
log::error!("Failed to get display handle");
|
||||||
return Err(Box::new(()));
|
return Err(Box::new(Error::NoDisplayHandle));
|
||||||
};
|
};
|
||||||
let raw_window_handle::RawDisplayHandle::Wayland(wayland_dh) =
|
let raw_window_handle::RawDisplayHandle::Wayland(wayland_dh) =
|
||||||
dh.as_raw()
|
dh.as_raw()
|
||||||
else {
|
else {
|
||||||
panic!("Invalid wayland display handle.");
|
log::error!("Display handle is not Wayland");
|
||||||
|
return Err(Box::new(Error::NoWaylandDisplay));
|
||||||
};
|
};
|
||||||
|
|
||||||
let backend = unsafe {
|
let backend = unsafe {
|
||||||
|
|
@ -90,12 +100,13 @@ impl SctkEventLoop {
|
||||||
let connection = Connection::from_backend(backend);
|
let connection = Connection::from_backend(backend);
|
||||||
|
|
||||||
let (action_tx, action_rx) = calloop::channel::channel();
|
let (action_tx, action_rx) = calloop::channel::channel();
|
||||||
let res = std::thread::spawn(move || {
|
let res: std::thread::JoinHandle<Result<(), Error>> =
|
||||||
|
std::thread::spawn(move || {
|
||||||
let _display = connection.display();
|
let _display = connection.display();
|
||||||
let (globals, event_queue) =
|
let (globals, event_queue) =
|
||||||
registry_queue_init(&connection).unwrap();
|
registry_queue_init(&connection).map_err(Error::Global)?;
|
||||||
let event_loop =
|
let event_loop = calloop::EventLoop::<SctkState>::try_new()
|
||||||
calloop::EventLoop::<SctkState>::try_new().unwrap();
|
.map_err(Error::Calloop)?;
|
||||||
let loop_handle = event_loop.handle();
|
let loop_handle = event_loop.handle();
|
||||||
|
|
||||||
let qh = event_queue.handle();
|
let qh = event_queue.handle();
|
||||||
|
|
@ -282,10 +293,14 @@ impl SctkEventLoop {
|
||||||
xdg_shell_state: XdgShell::bind(&globals, &qh)
|
xdg_shell_state: XdgShell::bind(&globals, &qh)
|
||||||
.expect("xdg shell is not available"),
|
.expect("xdg shell is not available"),
|
||||||
layer_shell: LayerShell::bind(&globals, &qh).ok(),
|
layer_shell: LayerShell::bind(&globals, &qh).ok(),
|
||||||
activation_state: ActivationState::bind(&globals, &qh).ok(),
|
activation_state: ActivationState::bind(&globals, &qh)
|
||||||
session_lock_state: SessionLockState::new(&globals, &qh),
|
.ok(),
|
||||||
|
session_lock_state: SessionLockState::new(
|
||||||
|
&globals, &qh,
|
||||||
|
),
|
||||||
session_lock: None,
|
session_lock: None,
|
||||||
overlap_notify: OverlapNotifyV1::bind(&globals, &qh).ok(),
|
overlap_notify: OverlapNotifyV1::bind(&globals, &qh)
|
||||||
|
.ok(),
|
||||||
toplevel_info: ToplevelInfoState::try_new(
|
toplevel_info: ToplevelInfoState::try_new(
|
||||||
®istry_state,
|
®istry_state,
|
||||||
&qh,
|
&qh,
|
||||||
|
|
@ -374,7 +389,8 @@ impl SctkEventLoop {
|
||||||
unmapped_subsurfaces: Vec::new(),
|
unmapped_subsurfaces: Vec::new(),
|
||||||
new_iced_subsurfaces: Vec::new(),
|
new_iced_subsurfaces: Vec::new(),
|
||||||
};
|
};
|
||||||
state.state.subsurface_state = Some(subsurface_state.clone());
|
state.state.subsurface_state =
|
||||||
|
Some(subsurface_state.clone());
|
||||||
state::send_event(
|
state::send_event(
|
||||||
&state.state.events_sender,
|
&state.state.events_sender,
|
||||||
&state.state.proxy,
|
&state.state.proxy,
|
||||||
|
|
@ -410,20 +426,23 @@ impl SctkEventLoop {
|
||||||
let had_events = !state.state.sctk_events.is_empty();
|
let had_events = !state.state.sctk_events.is_empty();
|
||||||
let mut wake_up = had_events;
|
let mut wake_up = had_events;
|
||||||
|
|
||||||
for s in state
|
for s in
|
||||||
|
state
|
||||||
.state
|
.state
|
||||||
.layer_surfaces
|
.layer_surfaces
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.surface.wl_surface())
|
.map(|s| s.surface.wl_surface())
|
||||||
.chain(
|
|
||||||
state.state.popups.iter().map(|s| s.popup.wl_surface()),
|
|
||||||
)
|
|
||||||
.chain(
|
.chain(
|
||||||
state
|
state
|
||||||
.state
|
.state
|
||||||
.lock_surfaces
|
.popups
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.session_lock_surface.wl_surface()),
|
.map(|s| s.popup.wl_surface()),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
state.state.lock_surfaces.iter().map(|s| {
|
||||||
|
s.session_lock_surface.wl_surface()
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let id = s.id();
|
let id = s.id();
|
||||||
|
|
@ -458,11 +477,13 @@ impl SctkEventLoop {
|
||||||
.events_sender
|
.events_sender
|
||||||
.unbounded_send(Control::Winit(id, e));
|
.unbounded_send(Control::Winit(id, e));
|
||||||
} else {
|
} else {
|
||||||
_ = state.state.events_sender.unbounded_send(
|
_ =
|
||||||
Control::PlatformSpecific(
|
state
|
||||||
|
.state
|
||||||
|
.events_sender
|
||||||
|
.unbounded_send(Control::PlatformSpecific(
|
||||||
crate::platform_specific::Event::Wayland(e),
|
crate::platform_specific::Event::Wayland(e),
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if wake_up {
|
if wake_up {
|
||||||
|
|
@ -473,7 +494,13 @@ impl SctkEventLoop {
|
||||||
|
|
||||||
if res.is_finished() {
|
if res.is_finished() {
|
||||||
log::warn!("SCTK thread finished.");
|
log::warn!("SCTK thread finished.");
|
||||||
res.join().map(|_: Result<(), ConnectError>| action_tx)
|
match res.join() {
|
||||||
|
Ok(_) => Ok(action_tx),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("SCTK thread exited with error: {e:?}");
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(action_tx)
|
Ok(action_tx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue