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).