MacOS中第三方鼠标的SensibleSideButton侧导航

2020-09-06 22:17:21

如果你在Mac电脑上使用第三方鼠标,你肯定会注意到侧键有多没用。默认情况下,它们充当某种残缺的中间点击,委托在您最意想不到的时候从您的下方打开新的链接。与Windows相比,在Windows中,同样的按钮允许您在几乎任何有历史记录的窗口中流畅地向前和向后导航。一旦你习惯了这个功能,没有它就很难过得去。

下面是MacOS中侧键默认工作方式的演示。彩色圆圈代表按钮点击,橙色代表底部/背面按钮(M4),蓝色代表顶部/正面按钮(M5)。四个窗口中的每个窗口都已有历史记录。

如您所见,此绑定完全无用。除了在浏览器中打开新链接外,所有应用程序都没有响应。(与实际的鼠标中键点击不同,你甚至不能在之后点击来关闭标签。)。坦率地说,我不清楚为什么这些按钮会有任何作用!

对于这种愚蠢的行为,最常见的修复方法是将侧键重新绑定到⌘+[和⌘+]-标准的操作系统范围的历史导航快捷键。此行为不能在系统首选项中进行本机配置,但它用于从Logitech的鼠标软件到USB Overdrive等第三方工具的所有方面。不幸的是,虽然这在大多数应用程序中运行良好,但感觉还是不太自然。每当你点击其中一个侧边按钮时,你要么会看到令人分心的菜单栏闪烁,要么会听到令人讨厌的警报声。与其他鼠标功能不同的是,每次侧击都会发送到整个前台应用程序,而不是光标下的特定视图。行为在某些上下文中可能不可预测,具体取决于前台应用程序如何配置其键盘快捷键。换句话说,你不能依赖这种方法。

肯定没那么没用,但仍然经常令人困惑。例如:如果您在一个应用程序中打开了许多窗口,您如何一目了然地知道您的导航点击将转到哪个窗口?在视频中,您可以看到,即使光标悬停在不同的窗口上,导航命令也会转到Finder。或者,如果你不熟悉一款应用程序,你怎么能确定侧键不会像Xcode中的缩进那样触发一些改变状态的快捷键呢?键盘快捷键是不可预测的,这使得侧键在实践中感觉不安全。除非有必要,否则你要学会避开它们。

与上述两种方法不同,SensibleSideButton使您的侧边按钮表现得像真正的导航键。导航现在几乎可以在任何有历史记录的应用程序中工作,即使没有任何快捷键可以向前和向后绑定。导航命令直接发送到光标下的视图,减少了错误,甚至(假设)允许单独控制单个窗口中的多个可导航部分。没有闪烁的菜单栏,没有烦人的噪音,不用担心错误的键盘快捷键会扰乱你的工作流程。最棒的是,代码是原生的、干净的,并且非常简单。我们正在做的就是清理一些稍微被遗忘的MacOS部分。

非常完美!包括Xcode和Documentation在内的所有四个窗口的性能都完全符合人们的期望。而且,当单击侧边按钮时,如果光标位于不可导航或失焦的窗口上,就不会再有混淆:该命令只会解析为空,而不是触发应用程序范围的快捷方式。

敏感的侧边按钮位于您的菜单栏中。就是这样:当它在那里的时候,你会得到明智的后退/前进行为,当它离开那里时,没有任何行为的痕迹。(您也可以打开应用程序菜单,根据需要有选择地启用或禁用它。)。没有CPU开销,也没有任何奇怪的轮询--只要点击M4或M5,就会发出一些系统范围的事件。

多年来,我所有的第三方MacOS鼠标上的侧键都表现不佳,以至于我以为这个问题是无法解决的。但后来我拿到了一台罗技MX Master,我惊讶地发现这款鼠标上的侧键(没有其他鼠标!)。以那种理想的、通用的、类似Windows的方式运行。没有闪烁的菜单栏。导航已本地化到您光标下的视图...。几乎在每个应用程序中都有一致的行为。这是我第一次在Mac电脑上看到它!

对这种不寻常的行为感到好奇,我拿出Xcode,编写了一个快速应用程序来捕获鼠标单击事件并进行一些分析。第一个问题:普通小鼠侧键的标准预期MacOS行为是什么?测试了几个型号,我发现侧键发出标准的M4和M5命令,就像它们在Windows中所做的那样。碰巧MacOS不想用这些命令做太多事情,而且它们也不能以任何本机方式反弹。

于是,我推断师父正在用它的侧面按钮做一些特殊的事情,于是我也试着捕捉它们。令我惊讶的是,它们似乎什么都没有排放!我猜想也许罗技的司机正在做一些有趣的事情,让他们以这种方式工作。但是秘诀是什么呢?Master的侧键在我的所有软件中的行为完全一致,所以它很可能不是某个特殊用途的Logitech代码。(尽管我不能排除这一可能性。)。这些按钮绝对不会发出键盘快捷键,因为它们缺少商标菜单栏的闪烁,并且只影响光标下的视图。在MacOS中必须有一组全球性的后退/转发事件在这里发出,但苦涩的谷歌搜索数小时也找不到此类事件存在的证据。我还研究了AppleScript技巧,但这些技巧导致了类似的死胡同。

有点困惑,我决定捕捉所有从MX大师发出的事件。然后就有了一场轰动一时的比赛!侧键根本不会被操作系统视为点击,而是假的三指滑动手势。

几年来,MacOS的标准导航手势一直是两个手指拖动:时髦,但大多仅限于Safari和其他几个应用程序。不过,传统的三指轻扫功能可以在触控板偏好中额外启用,虽然它不像它的弟弟那样华丽,但它在整个操作系统上的通用性要强得多。在幕后,这个手势基本上是可以自由实现的:你所要做的就是在你的视图控制器或响应器中加入一个swpeWithEvent:选择器,你就可以开始工作了。然后,如果用户在光标位于您的视图上时执行三指滑动,则会触发选择器,并可能导航到相应的方向。

换句话说,此手势与MacOS中存在的全局后退/前进事件一样接近。遗憾的是,它发出的事件类型-NSEventTypeSwipe-不能以编程方式生成。

我真的很想把这个行为移植到我自己的第三方鼠标上,但是MacOS顽固地阻碍了我!罗技是如何创建这些活动的?他们有权访问一些私有框架吗?有没有涉及到一些反向工程?我认为我必须要么捕获二进制事件数据并克隆它以供我自己使用,要么向正在处理此行为的Logitech进程发送违禁品消息。(我认为是Logitech Options守护进程,因为在混搭侧边按钮时,CPU使用率会显著增加。)。但我很幸运,因为已经有人在这方面做了艰苦的工作。

为了为一个名为Sesamouse的应用程序创建手势代码,开发人员Nathan Vander Wilt对基于手势的NSEvent的数据结构进行了逆向工程,并将其工作作为开源发布。在玩弄他的功能时,我很快发现了获胜的组合,这将使我获得与大师发出的相同的手势事件。Swipe事件甚至不需要鼠标位置,因此没有必要对坐标进行推理。它就像NSEventPhaseBegan事件和紧跟其后的NSEventPhaseEnded事件一样简单。

拼图的另一半是扼杀M4和M5命令,并用这个伪造的手势取而代之。幸运的是,MacOS通过使用事件点击提供了一种非常简单的方法。通过对CGEventTapCreate的简单调用以及kCGEventOtherMouseUp和kCGEventOtherMouseUp和kCGEventOtherMouseDown的筛选器,将为每次编号的鼠标按键单击安排一个回调。回调被允许返回默认事件以外的事件,所以我简单地返回了M4和M5的NULL,然后发送了我的假事件。据我所知,活动水龙头几乎没有开销。

您可以在Github或压缩文件中获得SensibleSideButton的源代码(GPLv2)。

敏感的侧面按钮是由我做的-阿列克谢·巴布列维奇(Alexei Baboulevitch)。你可以在twitter@archagon上找到我,并给我发电子邮件到[email protected]。我的博客目前可以在http://beta-blog.archagon.net.上找到。

非常感谢Nathan Vander Wilt在MacOS中的逆向工程事件处理方面所做的大量工作。如果他的“触摸”项目不存在,我肯定会放弃的!

SensibleSideButton是免费的,因为我相信它是解决MacOS长期问题的最佳解决方案。我宁愿把它当作补丁,而不是产品,让任何人都可以下载和享受!然而,如果你发现这款应用程序提高了你的工作效率,就像我认为的那样,请考虑留下一小笔捐款,或者通过我的亚马逊会员链接购买一些东西。我将非常感谢它,它将帮助资助这个项目和许多其他有用的软件项目。