mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-26 17:03:09 +00:00
fix(compositor): replace panic-prone unwraps with explicit error handling in winit and DRM backends
- winit backend: client insertion and dispatch_clients failures now log and continue instead of unwinding the event loop - winit backend: bind/render/submit failures in the redraw handler skip the frame and log a warning; the compositor stays running - DRM backend: same client insertion and dispatch_clients treatment - DRM device_added: use .context()? instead of unwrap() when inserting the new device entry after the drm field is known to be initialised - DRM render_output: use guard-return instead of unwrap() to access drm state that was already verified non-None lines above - compositor state: duplicate layer surface mapping from a misbehaving client logs a warning and returns instead of panicking
This commit is contained in:
parent
67f54c39be
commit
b82345d24e
3 changed files with 49 additions and 24 deletions
|
|
@ -137,10 +137,12 @@ pub fn run() -> anyhow::Result<()> {
|
|||
|
||||
loop_handle
|
||||
.insert_source(listening_socket, |stream, _, state| {
|
||||
state
|
||||
if let Err(e) = state
|
||||
.display_handle
|
||||
.insert_client(stream, Arc::new(WeftClientState::default()))
|
||||
.unwrap();
|
||||
{
|
||||
tracing::warn!(?e, "failed to insert Wayland client");
|
||||
}
|
||||
})
|
||||
.map_err(|e| anyhow::anyhow!("socket source: {e}"))?;
|
||||
|
||||
|
|
@ -150,7 +152,9 @@ pub fn run() -> anyhow::Result<()> {
|
|||
|_, display, state| {
|
||||
// Safety: Display is owned by this Generic source and outlives the event loop.
|
||||
unsafe {
|
||||
display.get_mut().dispatch_clients(state).unwrap();
|
||||
if let Err(e) = display.get_mut().dispatch_clients(state) {
|
||||
tracing::warn!(?e, "Wayland dispatch error");
|
||||
}
|
||||
}
|
||||
Ok(PostAction::Continue)
|
||||
},
|
||||
|
|
@ -375,16 +379,21 @@ fn device_added(state: &mut WeftCompositorState, node: DrmNode, path: &Path) ->
|
|||
)
|
||||
.map_err(|e| anyhow::anyhow!("DRM notifier: {e}"))?;
|
||||
|
||||
state.drm.as_mut().unwrap().devices.insert(
|
||||
node,
|
||||
WeftDrmDevice {
|
||||
drm_output_manager,
|
||||
drm_scanner: DrmScanner::new(),
|
||||
surfaces: HashMap::new(),
|
||||
render_node,
|
||||
registration_token,
|
||||
},
|
||||
);
|
||||
state
|
||||
.drm
|
||||
.as_mut()
|
||||
.context("DRM data missing after initialization")?
|
||||
.devices
|
||||
.insert(
|
||||
node,
|
||||
WeftDrmDevice {
|
||||
drm_output_manager,
|
||||
drm_scanner: DrmScanner::new(),
|
||||
surfaces: HashMap::new(),
|
||||
render_node,
|
||||
registration_token,
|
||||
},
|
||||
);
|
||||
|
||||
device_changed(state, node);
|
||||
Ok(())
|
||||
|
|
@ -604,7 +613,7 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
|||
};
|
||||
|
||||
let render_node = {
|
||||
let d = state.drm.as_ref().unwrap();
|
||||
let Some(d) = state.drm.as_ref() else { return };
|
||||
d.devices
|
||||
.get(&node)
|
||||
.and_then(|d| d.render_node)
|
||||
|
|
|
|||
|
|
@ -63,10 +63,12 @@ pub fn run() -> anyhow::Result<()> {
|
|||
|
||||
loop_handle
|
||||
.insert_source(listening_socket, |client_stream, _, state| {
|
||||
state
|
||||
if let Err(e) = state
|
||||
.display_handle
|
||||
.insert_client(client_stream, Arc::new(WeftClientState::default()))
|
||||
.unwrap();
|
||||
{
|
||||
tracing::warn!(?e, "failed to insert Wayland client");
|
||||
}
|
||||
})
|
||||
.map_err(|e| anyhow::anyhow!("socket source insertion failed: {e}"))?;
|
||||
|
||||
|
|
@ -78,7 +80,9 @@ pub fn run() -> anyhow::Result<()> {
|
|||
// Safety: the display is owned by this Generic source and is never dropped
|
||||
// while the event loop runs.
|
||||
unsafe {
|
||||
display.get_mut().dispatch_clients(state).unwrap();
|
||||
if let Err(e) = display.get_mut().dispatch_clients(state) {
|
||||
tracing::warn!(?e, "Wayland dispatch error");
|
||||
}
|
||||
}
|
||||
Ok(PostAction::Continue)
|
||||
},
|
||||
|
|
@ -129,9 +133,8 @@ pub fn run() -> anyhow::Result<()> {
|
|||
let size = backend.window_size();
|
||||
let full_damage = Rectangle::from_size(size);
|
||||
|
||||
{
|
||||
let (renderer, mut framebuffer) = backend.bind().unwrap();
|
||||
smithay::desktop::space::render_output::<
|
||||
let render_ok = match backend.bind() {
|
||||
Ok((renderer, mut framebuffer)) => smithay::desktop::space::render_output::<
|
||||
_,
|
||||
WaylandSurfaceRenderElement<GlesRenderer>,
|
||||
_,
|
||||
|
|
@ -147,9 +150,18 @@ pub fn run() -> anyhow::Result<()> {
|
|||
&mut damage_tracker,
|
||||
[0.1_f32, 0.1, 0.1, 1.0],
|
||||
)
|
||||
.unwrap();
|
||||
.map_err(|e| tracing::warn!(?e, "render_output failed"))
|
||||
.is_ok(),
|
||||
Err(e) => {
|
||||
tracing::warn!(?e, "backend bind failed");
|
||||
false
|
||||
}
|
||||
};
|
||||
if render_ok {
|
||||
if let Err(e) = backend.submit(Some(&[full_damage])) {
|
||||
tracing::warn!(?e, "backend submit failed");
|
||||
}
|
||||
}
|
||||
backend.submit(Some(&[full_damage])).unwrap();
|
||||
|
||||
state.space.elements().for_each(|window| {
|
||||
window.send_frame(
|
||||
|
|
|
|||
|
|
@ -294,9 +294,13 @@ impl WlrLayerShellHandler for WeftCompositorState {
|
|||
) {
|
||||
let desktop_surface = DesktopLayerSurface::new(surface, namespace);
|
||||
if let Some(output) = self.space.outputs().next().cloned() {
|
||||
layer_map_for_output(&output)
|
||||
if layer_map_for_output(&output)
|
||||
.map_layer(&desktop_surface)
|
||||
.expect("layer surface must not already be mapped");
|
||||
.is_err()
|
||||
{
|
||||
tracing::warn!("received duplicate layer surface mapping; ignoring");
|
||||
return;
|
||||
}
|
||||
layer_map_for_output(&output).arrange();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue