Focus raised sessions via active terminal

Summary

Yakuake restores focus after raising a session by asking the session widget for focusWidget() and then focusing the returned child. This patch uses the session's tracked active terminal instead:

  • fetch Session::activeTerminalId() through Session::getTerminal()
  • focus Terminal::terminalWidget() when it still exists
  • avoid the QWidget::focusWidget() lookup on this session-raise path

This keeps the intended target as the active terminal while avoiding a fragile Qt focus-chain lookup during session switching.

Coredump notes

A local coredump from /usr/bin/yakuake 26.04.0-1 showed a SIGSEGV while Qt was processing focus events. The relevant top frames were:

#4  QWidget::focusWidget() const
#5  yakuake + 0x4ab91
#16 QCoreApplicationPrivate::sendThroughObjectEventFilters(...)
#19 QApplicationPrivate::setFocusWidget(...)
#20 QWidget::setFocus(Qt::FocusReason)
#23 QGuiApplicationPrivate::processFocusWindowEvent(...)

The installed binary disassembly maps yakuake + 0x4ab91 to the first focusWidget() call in SessionStack::raiseSession(), immediately after setCurrentWidget(session->widget()):

call QStackedWidget::setCurrentWidget(QWidget*)
call QWidget::focusWidget() const
4ab91: test %rax,%rax
...
call QWidget::focusWidget() const
call QWidget::setFocus(Qt::FocusReason)

So this is not a case where focusWidget() returned a widget, the checked widget disappeared, and the second call crashed. The crash happened inside the first QWidget::focusWidget() call, before the null check could protect anything.

The outer session->widget() was present. What this avoids is asking Qt to rediscover the focused child through its internal focus-chain state at this point. Yakuake already tracks the active terminal for the session, so using that terminal widget is a narrower and better-owned focus target for this path.

This is a targeted mitigation for the observed crash site, not a claim that the crash is fully reproduced or that every possible Qt/Konsole focus-chain issue is fixed.

Validation

  • cmake -S . -B build-fix -G Ninja
  • cmake --build build-fix --target yakuake
  • ctest --test-dir build-fix --output-on-failure
  • QT_QPA_PLATFORM=offscreen build-fix/bin/yakuake --help
  • dbus-run-session -- sh -c 'QT_QPA_PLATFORM=offscreen timeout 10s ./build-fix/bin/yakuake' reached the timeout without crashing; it could not fully exercise global shortcuts in the isolated session because kglobalaccel was unavailable.
Edited by Darafei Praliaskouski

Merge request reports

Loading
Loading