give the keyboard back when a modal closes

Hiding the layer takes the focus off whatever stood on it and leaves the
window with no focus widget at all, so the world view answered no keys
afterwards: Escape opened the menu once, closed it, and then did nothing.
Each modal now notes what held the keyboard when it opened and gives it
back on the way out -- the world view for the first of a stack, the modal
beneath for one above it, which was dead the same way.

The window's own focus guard now also catches the focus going nowhere,
rather than only landing on the wrong widget.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
This commit is contained in:
2026-08-18 22:11:04 +02:00
parent b7fe5cfcf2
commit b51a9c5c77
3 changed files with 28 additions and 3 deletions

View File

@@ -107,8 +107,11 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir,
connect(qApp, &QApplication::focusChanged, this, [this](QWidget*, QWidget* newWidget) {
// A modal holds the focus while it is open, whether it is one of ours on the
// layer or a system message box (REQ-UI-MODAL-CHROME).
if (newWidget && newWidget != m_gameWorldView && !QApplication::activeModalWidget()
// layer or a system message box (REQ-UI-MODAL-CHROME). A null widget -- the focus
// going nowhere at all -- is caught too: the world view is what answers keys when
// no modal is up, so leaving the window with no focus widget would leave the
// hotkeys dead (REQ-UI-HOTKEYS).
if (newWidget != m_gameWorldView && !QApplication::activeModalWidget()
&& !m_modalLayer->isActive())
{
m_gameWorldView->setFocus();