通过 tmux 传递鼠标事件

通过 tmux 传递鼠标事件

我注意到在 tmux 中滚动很麻烦,并想知道是否可以让 tmux 将它们传递给应用程序或终端。

我可能理解错了,但我注意到,我可以在 Terminology(我的终端仿真器)中滚动手册页,但在 tmux 运行时却不行。即使 tmux 未运行,xterm 中也无法使用鼠标滚动手册页,这让我认为终端处理鼠标事件,然后将其发送给应用程序。

所以我目前对鼠标事件流程的理解是这样的:

terminal -> tmux

因此,问题似乎是 tmux 阻止事件到达底层应用程序。需要的是:

terminal -> tmux -> application

理想情况下,我会将 Terminology 的原生滚动与 tmux 的复制模式结合起来(假设鼠标模式已启用并且它自动进入和退出复制模式),但这似乎不可能,因为 tmux 可以自行处理滚动。

已经接近我想要的效果了。鼠标滚动可以工作,并自动进入和退出复制模式,但在诸如此类的应用程序中,man它会从应用程序滚动到旧的终端历史记录。此外,该解决方案包括一个非官方补丁,这使得可移植性成为一个问题。

那么,是否可以让 tmux 完全忽略鼠标信号并将其发送到底层终端或应用程序?

答案1

如果您直接以术语形式查看手册页,则会发生以下情况:

less(手动分页器)将终端切换到所谓的备用屏幕,该屏幕没有回滚缓冲区,当您退出应用程序时,您将从该屏幕返回到终端的先前内容。此模式通常由全屏应用程序(查看器、编辑器、文件管理器等)使用。

less根本无法处理鼠标,并且terminology完全知道内部运行的应用程序对鼠标事件不感兴趣。

terminology(事实上大多数终端仿真器)意识到满足这两个条件时(即交替屏幕,对鼠标不感兴趣),它会将滚动事件转换为上下击键。因此less看不到任何鼠标事件,它只看到按键。


现在让我们将其置于tmux中间。

tmux一方面,只是终端中运行的一个应用程序。根据其配置,它可能会或可能不会请求鼠标事件;我假设您已启用它,因为这是默认设置。内部运行的应用程序根本不需要任何鼠标支持。tmux还可以切换到备用屏幕。

tmux另一方面, 本身就是一个终端仿真器,就像 一样terminology。它会跟踪(对于每个窗口/窗格)正在运行的应用程序是否对鼠标感兴趣,以及应用程序是否已切换到备用屏幕。这些状态不会反映到terminology,这是tmux的私事。

理论上,没有什么可以阻止 tmux 像图形模拟器那样运行,并将其获取的这些鼠标滚动事件转换为在内部运行terminology的向上/向下按键less,因为tmux它完全知道在内部运行的应用程序正在使用备用屏幕并且对鼠标事件不感兴趣。

这可能是所缺少的功能tmux,我建议您向他们提交功能请求。


如果你对细节感兴趣,我们可以把事情弄得更复杂一些。tmux现在先把它取出来。

这里有一个小问题需要注意。使用传统鼠标时,滚轮通常会产生超过 1 次按键,大概 3-5 次,因为否则滚动速度会太慢。触摸板能够报告更平滑的坐标,一些终端仿真器(包括terminology)确实可以识别这些坐标,因此会逐个报告向上/向下按键(假设每滚动 1/3 个单位后按一次按键,单位表示鼠标滚轮一次会执行的操作)。(我现在没有鼠标,所以我无法验证terminology鼠标是否确实会跳过多行,但我认为是这样。)

在某些情况下,一次报告多个按键是没有意义的,例如,在的搜索提示下,less它一次可能返回 3 个历史记录条目,这完全没用,并且很好地证明了这确实是幕后发生的事情。使用像这样的终端仿真器terminology加上触摸板,如果应用程序不关心鼠标,这不是问题,因此您可以在例如中逐行滚动less。但是,如果应用程序关心鼠标,那么您将回到粗糙的滚动体验,因为终端内的鼠标协议无法报告细粒度,只能报告老式的鼠标滚动单位。例如,mcview您无法平滑滚动,只能一次滚动多行。

让我们tmux重新开始游戏。它是一个可感知鼠标的备用屏幕应用程序,就像一样mcview,因此它只能接收老式大型单元的鼠标滚动事件。它应该一次发送多个向上/向下击键,就像实际的终端仿真器对老式鼠标滚动所做的那样,否则滚动会慢得令人难以忍受。因此,即使tmux开发人员继续实现此功能,您也会失去滚动的流畅度。

我已经打开了错误https://bugzilla.gnome.org/show_bug.cgi?id=755183努力改善这一点,但迄今为止尚未开展任何实际工作。

答案2

这个 tmux 问题有一个.tmux.conf对我来说非常有效的解决方法(我将其修改为发送三个向上/向下信号而不是每个滚动事件发送一个):

# Emulate scrolling by sending up and down keys if these commands are running in the pane
tmux_commands_with_legacy_scroll="nano less more man"

bind-key -T root WheelUpPane \
    if-shell -Ft= '#{?mouse_any_flag,1,#{pane_in_mode}}' \
        'send -Mt=' \
        'if-shell -t= "#{?alternate_on,true,false} || echo \"#{tmux_commands_with_legacy_scroll}\" | grep -q \"#{pane_current_command}\"" \
            "send -t= Up Up Up" "copy-mode -et="'

bind-key -T root WheelDownPane \
    if-shell -Ft = '#{?pane_in_mode,1,#{mouse_any_flag}}' \
        'send -Mt=' \
        'if-shell -t= "#{?alternate_on,true,false} || echo \"#{tmux_commands_with_legacy_scroll}\" | grep -q \"#{pane_current_command}\"" \
            "send -t= Down Down Down" "send -Mt="'

egmont 的回答是正确的,并引导我找到了这个解决方法。

我又打开了tmux 问题请求与其他终端仿真器类似的功能。

答案3

如果有人来这里尝试寻找在鼠标感知和鼠标未知的控制台应用程序中滚动的实用解决方案,请参考以下答案:https://superuser.com/a/1154016/438273

答案4

如果您在 OS X 中工作,请使用 SIMBL(简单插件加载器)安装 MouseTerm。

然后按如下方式配置 .tmux.conf(对于 Tmux 2.0,较新的版本会有所不同):

  • 设置-g模式鼠标开启
  • 设置 -g 鼠标调整窗格大小
  • 设置 -g 鼠标选择窗格
  • 设置-g鼠标选择窗口

我发现在运行 Yosemite 的 Macbook Pro 上使用选项键可以启用选择剪切/粘贴功能。

这是一篇有关该过程/陷阱的好文章:

在 OS X 上的 Tmux 中启用鼠标支持

相关内容