ollama - 💡(How to fix) Fix 对话框焦点不恢复:切换程序后光标不在输入行内 [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
ollama/ollama#16089Fetched 2026-05-11 03:13:16
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

Error Message

func (i *Instance) Readline() (string, error) { func handleCharCtrlZ(fd uintptr, termios any) (string, error) { func handleCharCtrlZ(fd uintptr, state any) (string, error) {

Code Example

scanner, err := readline.New(readline.Prompt{
    Prompt:         ">>> ",
    AltPrompt:      "... ",
    Placeholder:    "Send a message (/? for help)",
    AltPlaceholder: "Press Enter to send",
})

---

func (i *Instance) Readline() (string, error) {
    // ...
    i.SetRawModeOn()   // 进入 raw mode
    defer i.SetRawModeOff()
    // 逐字符循环读取,无 focus/blur 处理
    for {
        r, err := i.Terminal.Read()
        // 处理字符...
    }
}

---

func handleCharCtrlZ(fd uintptr, termios any) (string, error) {
    t := termios.(*Termios)
    if err := UnsetRawMode(fd, t); err != nil {
        return "", err
    }
    _ = syscall.Kill(0, syscall.SIGSTOP)
    // on resume...  ← 恢复后无任何焦点重设逻辑
    return "", nil
}

---

func handleCharCtrlZ(fd uintptr, state any) (string, error) {
    // not supported
    return "", nil
}

---

// Update() 方法中无 tea.FocusMsg 或 tea.BlurMsg 处理
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.WindowSizeMsg:
        // ...
    case tea.KeyMsg:
        // ...
    }
    return m, nil
}
RAW_BUFFERClick to expand / collapse

问题描述

当鼠标点击本程序对话框以外的界面,此时切换到其他程序以后,再返回本程序,鼠标停留位置不是对话框以内。

这是一个重大缺陷,会造成用户每次都要多点一次对话框才能继续输入,操作非常繁琐。

复现步骤

  1. ollama run <model> 的交互式对话框内输入内容
  2. 鼠标点击终端内对话框以外的区域(如历史输出区域)
  3. 切换到其他程序(如浏览器)
  4. 再切回本程序
  5. 此时光标不在对话框输入行内 → 需额外点击一次才能继续打字

根因分析

ollama run 的交互式聊天通过 cmd/interactive.go 中的 generateInteractive() 实现,底层使用 readline 包处理终端原始输入。

cmd/interactive.go:107-113 — readline 初始化:

scanner, err := readline.New(readline.Prompt{
    Prompt:         ">>> ",
    AltPrompt:      "... ",
    Placeholder:    "Send a message (/? for help)",
    AltPlaceholder: "Press Enter to send",
})

readline/readline.goReadline() 进入 raw mode,逐字符读取输入。没有终端焦点事件监听

func (i *Instance) Readline() (string, error) {
    // ...
    i.SetRawModeOn()   // 进入 raw mode
    defer i.SetRawModeOff()
    // 逐字符循环读取,无 focus/blur 处理
    for {
        r, err := i.Terminal.Read()
        // 处理字符...
    }
}

readline/readline_unix.go:9-15 — Unix Ctrl+Z 挂起恢复:

func handleCharCtrlZ(fd uintptr, termios any) (string, error) {
    t := termios.(*Termios)
    if err := UnsetRawMode(fd, t); err != nil {
        return "", err
    }
    _ = syscall.Kill(0, syscall.SIGSTOP)
    // on resume...  ← 恢复后无任何焦点重设逻辑
    return "", nil
}

readline/readline_windows.go:3-5 — Windows 下 Ctrl+Z 为空操作:

func handleCharCtrlZ(fd uintptr, state any) (string, error) {
    // not supported
    return "", nil
}

cmd/tui/tui.gocmd/tui/selector.go — Bubble Tea TUI 主菜单:

// Update() 方法中无 tea.FocusMsg 或 tea.BlurMsg 处理
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.WindowSizeMsg:
        // ...
    case tea.KeyMsg:
        // ...
    }
    return m, nil
}

总结:readline 循环只在进入时设置一次 raw mode,退出时恢复。切换程序再切回时,raw mode 仍然有效,键盘输入会正常接收,但 如果用户在切出前点击了终端中的其他区域(非输入行),光标位置不会被记住,切回后也不会自动恢复到输入行

建议修复

  1. 在终端恢复/重新获得焦点时,重绘 prompt 并将光标定位到输入行末尾
  2. Bubble Tea TUI 界面应实现 tea.FocusMsg 处理,在焦点恢复时保持当前输入状态
  3. 可考虑启用终端 focus-reporting (?1004h),在检测到焦点恢复事件时主动重绘 prompt 区域

CC @rick-github

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING