From fc0a26f7906736f868fc8ce508a1fd613be104e7 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 3 Jul 2024 22:20:20 +0300 Subject: [PATCH] feat: don't panic when getting events for dead objects While it's a compositor bug, make handling of such cases resulting in a simple warning in the log instead of crashing user applications. Fixes #458. --- src/output.rs | 22 +++++++++++++++++----- src/seat/keyboard/mod.rs | 18 +++++++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/output.rs b/src/output.rs index a7424b544..6fd082fd4 100644 --- a/src/output.rs +++ b/src/output.rs @@ -4,6 +4,7 @@ use std::{ sync::{Arc, Mutex, Weak}, }; +use log::warn; use wayland_client::{ globals::GlobalList, protocol::wl_output::{self, Subpixel, Transform}, @@ -417,12 +418,18 @@ where conn: &Connection, qh: &QueueHandle, ) { - let inner = state + let inner = match state .output_state() .outputs .iter_mut() .find(|inner| &inner.wl_output == output) - .expect("Received event for dead output"); + { + Some(inner) => inner, + None => { + warn!("Received {event:?} for dead wl_output"); + return; + } + }; match event { wl_output::Event::Geometry { @@ -533,7 +540,6 @@ where } } } - _ => unreachable!(), } } @@ -567,12 +573,18 @@ where conn: &Connection, qh: &QueueHandle, ) { - let inner = state + let inner = match state .output_state() .outputs .iter_mut() .find(|inner| inner.xdg_output.as_ref() == Some(output)) - .expect("Received event for dead output"); + { + Some(inner) => inner, + None => { + warn!("Received {event:?} for dead xdg_output"); + return; + } + }; // zxdg_output_v1::done is deprecated in version 3. So we only need // to wait for wl_output::done, once we get any xdg output info. diff --git a/src/seat/keyboard/mod.rs b/src/seat/keyboard/mod.rs index 251875c7e..f61a26b07 100644 --- a/src/seat/keyboard/mod.rs +++ b/src/seat/keyboard/mod.rs @@ -695,13 +695,17 @@ where loop_handle.remove(token); } - let surface = udata - .focus - .lock() - .unwrap() - .as_ref() - .cloned() - .expect("wl_keyboard::key with no focused surface"); + let surface = + match udata.focus.lock().unwrap().as_ref().cloned() + { + Some(surface) => surface, + + None => { + log::warn!( + "wl_keyboard::key with no focused surface"); + return; + } + }; // Update the current repeat key. repeat_data.current_repeat.replace(RepeatedKey {