A field that is logically closed can still be eating every key

Measured on the running app, not deduced. After a queued dimension chain the value field's frame
is left MAPPED on purpose (mutter refuses keyboard focus to a re-mapped window), so there is a
window in which m_open is already false and the frame is still on screen holding the X input
focus. GTK meanwhile reports that window inactive and routes nothing into the text control. Every
key then lands somewhere that cannot use it and will not give it back:

  [KEYTRACE] key=27 ui_mode=1 inline_busy=0     <- the last key the panel ever sees
  === MARK press Delete ===                     <- no trace line at all
  xdotool getwindowfocus -> 0xe00404 86x60      <- the value field, still mapped

Delete, Esc and typing all read as dead, which is exactly the report. And nothing could recover
it: close(), cancel() and do_cancel() all return early on !m_open, so the one window still
receiving keystrokes was also the one window no code could dismiss.

is_mapped() asks the question the flag cannot answer, and dismiss() tears the frame down with no
m_open guard, since m_open is precisely what lies in this state. Esc inside the field falls back
to it — while the frame holds focus that handler is the only code the keyboard can still reach,
so if it refuses, nothing else gets a turn. Every close now hands focus back to the canvas
explicitly, because hiding a window does not move the X input focus off it. And inline_busy()
reports the union of "a value is pending" and "a frame is mapped", so Esc routes to the field
whenever one is on screen at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
This commit is contained in:
Tommaso Bianchi
2026-09-05 13:00:23 +02:00
co-authored by Claude Opus 5
parent 3f52166e32
commit cf444a6ab6
3 changed files with 64 additions and 5 deletions
+6 -1
View File
@@ -1305,7 +1305,12 @@ void DesignCanvas::delete_selected_sketch_entities()
bool DesignCanvas::inline_busy() const
{
return m_sketch_tool.inline_busy();
// The TOOL's flag says a value is pending; the FRAME being mapped says a window is on screen
// holding the keyboard. Either one means "a field is up", and only the union of the two is
// safe to route Esc by: the flag alone went false while the frame was still mapped, which is
// the orphan that swallowed every key with nothing able to close it.
return m_sketch_tool.inline_busy()
|| (m_inline_editor && m_inline_editor->is_mapped());
}
bool DesignCanvas::inline_has_focus() const