You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ruby在终端捕获鼠标事件?

解决Ruby终端鼠标事件读取问题

你的代码存在两个核心问题:终端默认的规范模式会缓冲输入并回显,且STDIN默认处于阻塞状态,导致read_nonblock无法捕获鼠标事件数据。以下是修复方案:

关键修改点

  • 将终端切换为原始模式:关闭输入缓冲与回显,让鼠标事件直接传递到程序,而非显示在终端界面。
  • 设置STDIN为非阻塞模式:适配read_nonblock的调用要求。
  • 使用IO.select等待输入:避免空循环占用CPU资源。

修复后的代码

begin
  # 启用终端原始模式,关闭缓冲与回显
  IO.console.raw!
  # 将STDIN设置为非阻塞模式
  STDIN.nonblock = true
  # 启用鼠标按下/释放事件报告,可追加1002启用移动事件报告
  print "\e[?1003h\e[?1002h"

  loop do
    # 等待STDIN有可读数据,超时1秒避免死循环
    if IO.select([STDIN], nil, nil, 1)
      begin
        input = STDIN.read_nonblock(1024)
        puts "捕获到输入: #{input.inspect}"
      rescue IO::EAGAINWaitReadable
        # 无数据时跳过,继续循环
      end
    end
  end
ensure
  # 关闭鼠标事件报告
  print "\e[?1003l\e[?1002l"
  # 恢复终端为规范模式
  IO.console.cooked!
  # 恢复STDIN为阻塞模式
  STDIN.nonblock = false
end

说明

  1. 原始模式:IO.console.raw!禁用终端的行缓冲、回显和特殊字符处理,让鼠标转义序列直接被程序读取,不会在终端显示。
  2. 非阻塞STDIN:STDIN.nonblock = true让read_nonblock在无数据时抛出异常而非阻塞,配合IO.select可高效等待输入。
  3. 鼠标事件参数:\e[?1002h用于启用鼠标移动时的事件报告,若仅需捕获按下/释放动作,保留1003即可。
  4. 终端状态恢复:ensure块必须恢复终端模式,否则退出程序后终端会出现输入不显示、无法正常换行等异常。

测试时移动或点击鼠标,程序会输出捕获到的鼠标转义序列,不会再出现终端直接显示序列却读不到数据的情况。

内容的提问来源于stack exchange,提问作者Scoobie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:15:24