mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 10:51:22 +00:00
Sketch value fields: content-based key arbiter + the gate that can judge it
The reported defect: sketch dimension labels are "not editable" — you draw a
rectangle, its Width field opens, you type, and the as-drawn number is committed
instead. It affects every sketch tool, not just the rounded rectangle.
WHAT THIS ADDS
1. The arbiter (DesignPanel CHAR_HOOK -> DesignCanvas::inline_type_char ->
SketchInlineEditor::type_char). Routes a key by what it IS, not by who the
window manager focused: digits, sign, decimal separator and Backspace/Delete
go to the open value field, Enter/Tab commit, letters stay tool shortcuts.
This is FreeCAD Sketcher's rule (DrawSketchKeyboardManager::
detectKeyboardEventHandlingMode), and the reason its sketcher behaves the same
on every desktop: it never asks who has focus.
2. The [UX] trace (SNAPORCA_UXTRACE) in SketchInlineEditor: open/commit/refused/
cancel, with the prefill and what the control actually held at Enter. It did
not exist — the ladder below was written against a surface no build emitted,
so it could only ever report "nothing opened". typed == prefill on a commit is
the defect's signature and nothing else makes it visible.
3. A draw-then-edit trace in DesignSketchTool: four early returns can swallow the
value-field chain and from outside they are indistinguishable.
4. scripts/CAD/check-gui-click-edit.py — types WITHOUT clicking the field, as a
person does, across Line/Rectangle/Circle/Slot/Polygon/Ellipse/Arc plus label
click-to-edit, and asserts committed == typed != prefill.
5. scripts/CAD/focus-loop.sh — sync/build/assert on behemoth. NOT the orcacad-gui
rig: its image pins deps 216 non-CAD files behind cad-mainline, so today's CAD
sources cannot build there without a deps rebuild.
WHAT IS PROVEN, AND WHAT IS NOT
Green under openbox: 28 checks, every tool, committed == typed != prefill.
But openbox CANNOT adjudicate this bug and the ladder says so in place. There the
field always wins the keyboard, so the same ladder also passes against a binary
with the arbiter compiled out — measured twice. Two ways of removing the keyboard
were tried and both are recorded as dead ends: XSetInputFocus loses to the field's
own re-focus CallAfter, and XSendEvent (xdotool --window) is dropped by GTK, which
made every run red regardless of the code.
Under metacity — same focus-stealing-prevention lineage as the user's mutter — the
mechanism appears in the WM's own log:
Buggy client sent a _NET_ACTIVE_WINDOW message with a timestamp of 0
That is the activation being refused, which is exactly the reported symptom.
present_toplevel() already asks for a server timestamp, so a path is still falling
through to frame->Raise(), which sends time 0. That is the next thing to fix, and
it is tracked; the arbiter alone does not close it. metacity also aborts on this
window (frames.c:1239), so the gate needs a WM that survives before it can return
a verdict.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FbJKJAJxxkhDTs9XdZzKA
This commit is contained in:
co-authored by
Claude Opus 5
parent
af4bbe0217
commit
9134299233
@@ -4205,6 +4205,25 @@ DesignPanel::DesignPanel(wxWindow* parent)
|
||||
m_viewport->inline_commit();
|
||||
return;
|
||||
}
|
||||
// THE ARBITER. Route by what the key IS, not by who the window manager focused.
|
||||
//
|
||||
// This is FreeCAD's rule, from Sketcher's DrawSketchKeyboardManager::
|
||||
// detectKeyboardEventHandlingMode: a digit, a sign, a decimal separator or a
|
||||
// Backspace/Delete is unambiguously meant for the number the user is entering; a
|
||||
// letter is unambiguously a tool shortcut; Enter/Tab hand control back to the view.
|
||||
// FreeCAD never queries focus anywhere in that decision, and that is precisely why
|
||||
// its sketcher behaves the same on every desktop.
|
||||
//
|
||||
// Ours asked "who has focus?" instead — a question whose answer is the window
|
||||
// manager's opinion. openbox grants this borderless top-level the keyboard, mutter
|
||||
// refuses it, so the same binary took typed values on one machine and silently
|
||||
// committed the pre-filled as-drawn number on another. Seven workarounds fought that
|
||||
// and one of them cost a macOS regression. The question was wrong, not the answers.
|
||||
//
|
||||
// The has_focus() guard above keeps this from double-typing where the toolkit DID
|
||||
// give the field the keyboard: there the field's own binding will get the key too.
|
||||
if (!ctrl && m_viewport->inline_type_char(key))
|
||||
return;
|
||||
// Esc is NOT special-cased here any more: escape() routes it, and the open field is
|
||||
// exactly what CadLevel::Transient means, so it closes the field and stops there.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user