mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-18 14:32:36 +00:00
The field now owns the keyboard; what it does not yet own is the characters
Measured, not reasoned. A per-frame trace of the ImGui state is what finally named the mechanism,
and it is a deadlock, not a focus problem:
[UX] frame want_text=0 want_kb=0 active=0 buf=158.74 <- frame 1: the widget is not active yet
[UX] frame want_text=0 want_kb=0 active=1 buf=158.74 <- frame 2: now it is
(nothing further) <- and the canvas stops
This canvas repaints ON DEMAND. ImGui decides whether it wants the keyboard at the END of a frame,
from the active item; GLCanvas3D::on_char only calls render() when update_key_data() says ImGui
wants it. So: no frames -> WantTextInput never turns on -> no render on a keystroke -> still no
frames. The characters sit in ImGui's input queue and the field is exactly as deaf as the window
it replaced, for a completely different reason.
request_frame breaks the circle, and the same trace says so:
[UX] frame want_text=1 want_kb=1 active=1
That is the first time in this file's history that the value field has owned the keyboard without
asking a window manager for it.
STILL OPEN: the typed characters do not reach the buffer (buf stays at the prefill) and the frames
stop after nine. The pump is the suspect — on software GL request_repaint() calls m_canvas->render()
SYNCHRONOUSLY, so this asks for a render from inside a render; it needs to schedule one instead.
That is the next thing to measure, not to guess.
The deployed binary on behemoth is restored to 00d6c191dc (md5 0eeb9a58cef5), byte-identical to
the last good build. Nothing from this branch is installed.
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
5ab3072b9f
commit
d82c8b59c2
@@ -87,6 +87,7 @@ DesignCanvas::DesignCanvas(wxWindow* parent)
|
||||
// The tool draws it: it owns the frame's ImGui pass and the render scale. Handing it a raw
|
||||
// pointer rather than the unique_ptr keeps the ownership where it was.
|
||||
m_sketch_tool.inline_editor = m_inline_editor.get();
|
||||
m_inline_editor->request_frame = [this] { request_repaint(); };
|
||||
m_sketch_tool.on_inline_edit = [this](wxPoint screen_px, double current,
|
||||
const std::string& title,
|
||||
std::function<void(double)> commit,
|
||||
|
||||
@@ -170,11 +170,27 @@ bool SketchInlineEditor::render(ImGuiWrapper& imgui, float scale)
|
||||
ImGuiInputTextFlags_EnterReturnsTrue
|
||||
| ImGuiInputTextFlags_AutoSelectAll
|
||||
| ImGuiInputTextFlags_CharsDecimal);
|
||||
// MEASUREMENT, not a fix: one line per frame saying whether ImGui believes it owns the
|
||||
// keyboard and whether our widget is the active one. "Typing does not arrive" has two very
|
||||
// different causes — no FRAMES (this canvas repaints on demand only, so an idle canvas never
|
||||
// processes ImGui's queued characters) versus frames that run while the input is not active —
|
||||
// and they are indistinguishable from outside.
|
||||
if (std::getenv("SNAPORCA_UXTRACE")) {
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
std::fprintf(stderr, "[UX] frame title=%s want_text=%d want_kb=%d active=%d buf=%s\n",
|
||||
m_title.c_str(), (int) io.WantTextInput, (int) io.WantCaptureKeyboard,
|
||||
(int) ImGui::IsItemActive(), m_buf);
|
||||
std::fflush(stderr);
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
imgui.end();
|
||||
ImGui::PopStyleVar();
|
||||
ImGuiWrapper::pop_common_window_style();
|
||||
|
||||
// Keep the frames coming while the field is up — see request_frame's note in the header.
|
||||
if (m_open && request_frame)
|
||||
request_frame();
|
||||
|
||||
// Act AFTER end(): do_commit can reopen the field for the next queued dimension, and that
|
||||
// must not happen inside this frame's window.
|
||||
if (entered)
|
||||
|
||||
@@ -54,6 +54,21 @@ public:
|
||||
// frame's ImGui pass; `scale` is the tool's m_render_scale. Returns true if it drew.
|
||||
bool render(ImGuiWrapper& imgui, float scale);
|
||||
|
||||
// Ask for another frame. THE FIELD DOES NOT WORK WITHOUT THIS, and the reason is a deadlock
|
||||
// that only a per-frame trace shows:
|
||||
//
|
||||
// [UX] frame want_text=0 want_kb=0 active=0 <- frame 1: the widget is not active yet
|
||||
// [UX] frame want_text=0 want_kb=0 active=1 <- frame 2: it is now
|
||||
// (nothing further) <- the canvas has nothing to redraw, so it stops
|
||||
//
|
||||
// This canvas repaints ON DEMAND. ImGui decides whether it wants the keyboard at the END of a
|
||||
// frame, from the active item, and GLCanvas3D::on_char only calls render() when
|
||||
// update_key_data() says ImGui wants it. No frames -> WantTextInput never turns on -> no
|
||||
// render on a keystroke -> still no frames. The characters sit in ImGui's queue and the field
|
||||
// looks exactly as deaf as the window it replaced. One repaint per frame while it is open
|
||||
// breaks the circle.
|
||||
std::function<void()> request_frame;
|
||||
|
||||
// Kept because callers ask them, but there is no longer any difference to report: with no
|
||||
// window there is no state where the field is on screen but logically closed, and no state
|
||||
// where it is open but somebody else holds the keyboard.
|
||||
|
||||
Reference in New Issue
Block a user