Add a bounded recursive fallback to find the focused editable node - #144
Add a bounded recursive fallback to find the focused editable node#144guoxpeng wants to merge 1 commit into
Conversation
findFocus(FOCUS_INPUT) stays the first choice and keeps precedence, but some hosts expose the editable input deeper in the tree than findFocus reaches. When findFocus reports nothing, walk the tree for the node that is both editable and focused. The walk is bounded (500-node budget, depth cap 32) so a deep tree cannot spike the main thread, and recycles every visited node on every exit path — including when an accessor throws mid-walk — except the returned match. Extracted behind a FocusNode seam so it is unit-tested with a fake tree. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
|
Thanks for the focused fallback implementation. I validated this PR head in a temporary worktree. |
Build & Release's preview-apk job uploads a debug-signed side-by-side APK (com.musheer360.swiftslate.preview) but the artifact was buried under Actions > run > Artifacts, requiring multiple clicks and a login. This adds Comment Preview APK — a workflow_run trigger that runs on the base repo after Build & Release succeeds. It resolves the PR number robustly (pull_requests array for same-repo PRs, commits/sha/pulls, and pulls?head=owner:branch for forks like #144), fetches the SwiftSlate-preview-pr* artifact, and upserts a single <!-- preview-apk --> comment with a one-click run link, size/commit, and install notes via peter-evans/find-comment+create-or-update-comment (pinned SHAs). workflow_dispatch with run_id is kept for manual recovery and temporary testing. Safe for forks: workflow_run runs on master context with pull-requests:write, never executes fork code with write token.
…c, double-recycle clarity, expanded tests
flawless: harden PR #144 — bounded fallback (isPassword, MainThread, tests)
|
Thanks, and thanks for folding this into #147. On the smoke test: I did exercise this on a real device against two hosts (WeChat and the system Notes app) — normal text entry worked fine in both. Since the fallback is intentionally log-free, I couldn't instrument which branch was hit or observe recycling directly, so "fallback taken + no node leak" is inferred from correct behavior rather than verified via logs. Happy to add targeted logging and re-test if you'd like harder evidence before relying on it. |
Re-submission of the focused-editable node search from #139, scoped down to just the refinement the maintainer requested.
What changed
findFocusedEditableSource()now runs in two stages:findFocus(FOCUS_INPUT)first — unchanged, keeps precedence (its non-null result is returned as-is).findFocusreports nothing, a bounded depth-first search walks the tree for the node that is bothisEditableandisFocused.This helps hosts that expose the editable input deeper in the tree than
findFocusreaches, without disturbing any source the stage-1 already accepts.Guardrails (from the #139 review)
findFocusresult keeps precedence.handleAccessibilityEvent.finally), including when an accessor throws mid-walk; only the returned match is kept for the caller.Log.ediagnostics, no proguard changes — this PR touches onlyAssistantService.ktplus two new files.Structure
FocusedEditableFinder.kt— aFocusNodeseam plus the bounded, recycling walk, so the logic is unit-testable with a fake tree.AssistantService.kt— wires the two-stage fallback throughAccessibilityFocusNode.FocusedEditableFinderTest.kt— 6 tests: match-at-root, deep match, miss recycles everything, budget cap, depth cap, exception path../gradlew testDebugUnitTestand./gradlew lintDebugpass locally.