slint-ui/slint · error
Unable to quit event loop multiple times
Error message
Unable to quit event loop multiple times
What it means
When the user presses Ctrl+Alt+Delete or Ctrl+Alt+Backspace on the linuxkms backend, `quit_event_loop()` is called and its Result is unwrapped with `expect("Unable to quit event loop multiple times")`. `quit_event_loop` returns an error if the event loop is not running or has already been asked to quit, so a repeated keypress (or a quit during loop teardown) panics inside the event-processing callback.
Solutions
- Ignore the Result instead of expecting: replace `.expect(...)` with `let _ = i_slint_core::api::quit_event_loop();` — quitting twice is benign.
- Check the returned error and log it rather than panicking in the input callback.
- Guard application-side: once quit is requested, stop processing further quit hotkey presses (track a quit_requested flag).
Example fix
// before
i_slint_core::api::quit_event_loop()
.expect("Unable to quit event loop multiple times");
// after
let _ = i_slint_core::api::quit_event_loop(); Defensive patterns
Strategy: try-catch
Try / catch
// treat double-quit as benign in the hotkey handler
if let Err(e) = i_slint_core::api::quit_event_loop() {
eprintln!("quit_event_loop: {e}"); // already quitting or not running
} Prevention
- Never .expect() on quit_event_loop in input handlers; the event loop may already be quitting
- Track a quit_requested flag to skip duplicate quit hotkey handling
- Test hotkey mash scenarios in kiosk/embedded deployments
When it happens
Trigger: Pressing Ctrl+Alt+Del or Ctrl+Alt+Backspace twice (or after the event loop already received a quit request / while the loop is being torn down) in an application using the linuxkms calloop backend.
Common situations: Full-screen kiosk/embedded apps where a frustrated user mashes the quit hotkey; quit triggered programmatically right before the hotkey press; event loop already exiting due to window close or error.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Error compiling keymap
- Seat deactivation is not implemented
- a setter belongs to a field
- an identifier
- binding was of the wrong type
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/8f388252bc71a05d.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backends/linuxkms/calloop_backend/input.rs:358
);
let control = xkb_key_state
.mod_name_is_active(xkb::MOD_NAME_CTRL, xkb::STATE_MODS_EFFECTIVE);
let alt = xkb_key_state
.mod_name_is_active(xkb::MOD_NAME_ALT, xkb::STATE_MODS_EFFECTIVE);
if state == KeyState::Pressed {
//eprintln!(
//"key {} state {:#?} sym {:x} control {control} alt {alt}",
//key_code, state, sym
//);
if (sym == xkb::Keysym::Delete || sym == xkb::Keysym::BackSpace)
&& alt
&& control
{
i_slint_core::api::quit_event_loop()
.expect("Unable to quit event loop multiple times");
} else if (xkb::Keysym::XF86_Switch_VT_1..=xkb::Keysym::XF86_Switch_VT_12)
.contains(&sym)
{
// let target_vt = (sym - xkb::KEY_XF86Switch_VT_1 + 1) as i32;
// TODO: eprintln!("switch vt {target_vt}");
}
}
if let Some(text) = map_key_sym(sym) {
let event = match state {
KeyState::Pressed => WindowEvent::KeyPressed { text },
KeyState::Released => WindowEvent::KeyReleased { text },
};
window.dispatch_event_with_result(event).map_err(Self::Error::other)?;
}
}
_ => {}
}View on GitHub (pinned to bb937076de)