Reviewed closed GitHub IME positioning bug.
UnderstandIdentified fix and examined code changes.
UnderstandAdded documentation on focus propagation pattern.
EditCommitted and pushed documentation updates.
VerifyAnalyze GitHub issue(s): https://github.com/badlogic/pi-mono/issues/827
For each issue:
Read the issue in full, including all comments and linked issues/PRs.
For bugs:
For feature requests:
Do NOT implement unless explicitly asked. Analyze and propose only.
The user wants me to analyze GitHub issue #827. Let me fetch the issue details first.
>gh issue view 827 --repo badlogic/pi-mono --json title,body,comments,labels,stateThe issue is about IME (Input Method Editor) candidate window appearing in the wrong position when typing with Chinese IME in pi's menu filtering. The issue is already CLOSED.
This is a bug related to the TUI (Terminal User Interface) component, specifically the menu filtering functionality. The IME candidate window position is typically controlled by the cursor position in the terminal.
Let me check if this issue was fixed by looking at recent commits or related code. First, let me understand the architecture by looking at relevant files.
The issue involves:
/ command menu/model model selectorLet me look at the TUI code to understand how menus work and where cursor positioning happens.
The issue is already CLOSED, but let me analyze it anyway to understand what was involved.
Issue #827: IME candidate window appears in wrong position when filtering menu options
Problem: When using Chinese IME to filter menu options (via / command or /model selector), the IME candidate window appears in the wrong position on screen.
Let me check how this was resolved and understand the relevant code:
>cd /Users/badlogic/workspaces/pi-mono && git log --oneline --all --grep="827" | head -20>cd /Users/badlogic/workspaces/pi-mono && git log --oneline --all --grep="IME" | head -20>cd /Users/badlogic/workspaces/pi-mono && git log --oneline --all --grep="candidate" | head -20Found it. Commit b4f833c2 fixed this issue. Let me look at what was changed.
Found the fix. Let me examine what was changed:
>cd /Users/badlogic/workspaces/pi-mono && git show b4f833c2 --stat>cd /Users/badlogic/workspaces/pi-mono && git show b4f833c2 --no-statLet me get the actual diff.
>cd /Users/badlogic/workspaces/pi-mono && git show b4f833c2 -pNow I have a clear picture of the issue and its fix.
Issue #827 Analysis
Problem: When using IME (Input Method Editor) like Chinese IME to filter menu options in pi's TUI, the IME candidate window appeared in the wrong position on screen. This affected:
/ command menu/model model selectorRoot Cause: The Focusable interface in pi-tui controls hardware cursor positioning for IME support. When a component has an embedded Input component (search field), the focus state needs to propagate from the parent container to the child Input so the cursor is positioned at the actual text input location.
The affected components were:
ModelSelectorComponent - model pickerScopedModelsSelectorComponent - Ctrl+P model cycling selectorSessionSelectorComponent (and internal SessionList) - session pickerExtensionInputComponent - extension text inputsLoginDialogComponent - OAuth login flowTreeSelectorComponent (and internal LabelInput) - session tree navigationThese components contained Input children but didn't implement the Focusable interface or propagate focus state to their inputs.
Fix Applied: Each affected component now:
Focusable interface from @mariozechner/pi-tui_focused field with getter/setterfocused state to its child Input component(s)This ensures the hardware cursor is positioned correctly at the actual text input position, allowing the terminal/OS to display the IME candidate window in the correct location.
The issue is already closed and fixed in commit b4f833c2.
Issue #827: IME candidate window appears in wrong position when filtering menus
Status: Already CLOSED and fixed in commit b4f833c2
The Focusable interface in pi-tui controls hardware cursor positioning for IME support. Components with embedded Input children (search fields) weren't propagating the focused state to their child inputs. Without this propagation, the hardware cursor remained at the wrong position, causing IME candidate windows to appear misplaced.
Each affected component now:
Focusable interface from @mariozechner/pi-tui_focused field with getter/setterfocused state to child Input componentsAffected components:
ModelSelectorComponent - model pickerScopedModelsSelectorComponent - Ctrl+P model cycling selectorSessionSelectorComponent (and internal SessionList) - session pickerExtensionInputComponent - extension text inputsLoginDialogComponent - OAuth login flowTreeSelectorComponent (and internal LabelInput) - session tree navigationPattern used (example from ModelSelectorComponent):
export class ModelSelectorComponent extends Container implements Focusable { private searchInput: Input; // Focusable implementation - propagate to searchInput for IME cursor positioning private _focused = false; get focused(): boolean { return this._focused; } set focused(value: boolean) { this._focused = value; this.searchInput.focused = value; } // ...}This issue is resolved. No further action needed.
>git statusok, we should likely also update @packages/coding-agent/docs/tui.md and @packages/tui/README.md to describe this pattern
The user wants me to update the documentation in two files to describe the pattern of implementing Focusable interface for components with embedded Input children. Let me read both files first to understand their current content and structure.
Now I understand both files. I need to add documentation about the pattern for components with embedded Input children that need to propagate focus state for IME cursor positioning.
Looking at the existing content:
packages/coding-agent/docs/tui.md already has a "Focusable Interface (IME Support)" section that explains the basic Focusable interface. I need to add a subsection about Container Components with Embedded Inputs that explains the pattern of propagating focus state.
packages/tui/README.md doesn't mention the Focusable interface at all. I should add a section about it, including the pattern for container components.
Let me add the documentation for both files.
I'll add documentation about the focus propagation pattern to both files.
Now let me add the Focusable interface documentation to packages/tui/README.md. I'll add it after the Component Interface section since it's a related interface.
I've added the documentation to both files. Let me run a check to make sure everything is good.
>cd /Users/badlogic/workspaces/pi-mono && npm run check 2>&1 | head -50All checks pass. Let me summarize what I did.
Done. Added documentation about the focus propagation pattern to both files:
packages/coding-agent/docs/tui.md - Added a new subsection "Container Components with Embedded Inputs" under the existing "Focusable Interface (IME Support)" section, with a code example showing how to implement the pattern.
packages/tui/README.md - Added a new "Focusable Interface (IME Support)" section after the Component Interface section, explaining both the basic interface and the container propagation pattern.
Both include:
focused statecommit and push
The user wants me to commit and push the changes. I need to commit only the files I modified, which are the two documentation files.
>cd /Users/badlogic/workspaces/pi-mono && git add packages/coding-agent/docs/tui.md packages/tui/README.md && git commit -m "docs: document Focusable interface propagation pattern for IME support
Container components with embedded Input/Editor children must implement
Focusable and propagate focus state to enable correct IME candidate
window positioning.
Related to #827"Good, commit succeeded. Now push.
>cd /Users/badlogic/workspaces/pi-mono && git pushDone. Successfully committed and pushed the documentation changes.
Pushed ad337e30 - documentation for the Focusable interface propagation pattern added to both packages/coding-agent/docs/tui.md and packages/tui/README.md.
export class ModelSelectorComponent extends Container implements Focusable { private searchInput: Input; // Focusable implementation - propagate to searchInput for IME cursor positioning private _focused = false; get focused(): boolean { return this._focused; } set focused(value: boolean) { this._focused = value; this.searchInput.focused = value; } // ...}