From cfaf4927ac84236abd0ff0c8e97dbacd1e693c85 Mon Sep 17 00:00:00 2001 From: Greg Pomerantz Date: Thu, 20 Aug 2026 12:24:01 -0400 Subject: [PATCH] Give the find bar's input focus and the keyboard when it opens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tapping the search icon set FocusedElementID to find_bar (so the editor stopped its IME sync), but the main-owned widget.Editor only grabs key focus on its own click — the icon tap never touches it, so neither focus nor the soft keyboard moved to the search input. Main now watches the frame's FocusedElementID and, on the transition into find_bar, issues key.FocusCmd{Tag: &findEditor} (once per open). The widget's FocusEvent handler raises the soft keyboard on focus gain (gioui.org/widget/editor.go), so the keyboard follows automatically; w.Invalidate guarantees the frame in which the widget sees the FocusEvent. Close needs no inverse action: the editor's TextField re-issues its own FocusCmd because the renderer clears the focus dedup on frames where no logic field is focused. --- cmd/pad/main.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/pad/main.go b/cmd/pad/main.go index 6347fb5..1bb9457 100644 --- a/cmd/pad/main.go +++ b/cmd/pad/main.go @@ -128,6 +128,10 @@ func run(w *app.Window) error { // the set changes — the rects move every frame while a selection is // visible/scrolling, but identical repeats are skipped. var lastExcl [][4]int + // findBarFocused tracks whether the previous frame focused the find bar's + // main-owned input, so main hands key focus to it exactly once per open + // (see the focus handoff below). + var findBarFocused bool for { switch e := w.Event().(type) { @@ -233,6 +237,19 @@ func run(w *app.Window) error { // Gather key events focusedID := frame.FocusedElementID + // Hand key focus to the find bar's main-owned input the moment the + // find bar opens: the search-icon tap never touches the widget, and + // widget.Editor only grabs key focus on its own click (gioui.org/ + // widget/editor.go). The widget's FocusEvent handler raises the soft + // keyboard on focus gain, so the keyboard follows automatically. On + // the inverse transition the editor's TextField re-issues its own + // key.FocusCmd (the renderer clears the focus dedup on frames where + // no logic field is focused), so nothing is needed on close. + if focusedID == "find_bar" && !findBarFocused { + gtx.Execute(key.FocusCmd{Tag: &findEditor}) + w.Invalidate() // next frame: the widget sees the FocusEvent + } + findBarFocused = focusedID == "find_bar" if focusedID == "" { // No focused input: drop any stale shift state (a release event // for a key held across focus loss may never arrive).