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

  1. Ignore the Result instead of expecting: replace `.expect(...)` with `let _ = i_slint_core::api::quit_event_loop();` — quitting twice is benign.
  2. Check the returned error and log it rather than panicking in the input callback.
  3. 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

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


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)