Hammerspoon 自动化:Mac 和 Windows 主机高效切换显示器输入源

ROG_Strix_Scope_II_96_Wireless

MacBook 和 Win 主机共享一套键鼠和显示器,因为显示器不带 KVM 切换功能,键鼠是通过外接 USB 切换器进行切换。显示器通过 USB-C 和 Mac 连接,通过 DP 和 PC 连接。

这样切换键鼠很方便,我只要按一下线控开关就在物理上实现了 USB 键鼠上行的切换。但是这个方案有个痛点,按下线控开关切换键鼠 USB 上行的同时,无法做到显示器输入源的切换。

大致拓扑如下

Keyboard_Mouse_and_Display_Topology

因为 DELL U2720Q 上带有 USB 3.0 HUB ,所以拓扑上 USB 切换器连接 Mac 的上行是接在显示器上,这样显示器和 MacBook 只需要一根 USB-C 线连接就可以实现外接显示、键鼠控制、充电、有线网卡等功能。

DDC/CI 协议切换输入源

m1ddc 这个项目可以实现M系列芯片的 Mac 通过 DDC/CI 协议发送指令控制显示器的输入源切换,以我的 DELL U2720Q 为列。

将输入源切换至 USB-C

m1ddc set input 27

将输入源切换至 DP

m1ddc set input 15

检测 USB 设备连接状态控制输入源切换

前面也提到现在的痛点,按下线控开关切换键鼠 USB 上行的同时,无法做到显示器的切换。为了解决这个“最后一公里”的问题,我的构想是在 Mac 上检测 USB 设备连接状态的变化来实现显示器输入源切换的控制。如果某个 USB 设备连接或断开了则运行某项指令。

Hammerspoon 可以实现我上述的想法,它桥接操作系统与 Lua 脚本引擎,我们能通过 Lua 脚本高效地与系统 API 沟通。

目录大致结构如下

.
├── Spoons
├── init.lua
└── modules
    └── usb_script.lua

我们可以在 modules文件夹下创建各种功能性的 Lua 脚本,再到入口 init.lua中导入你需要的功能性脚本。

首先要确定检测的 USB 设备名称,具体信息可以到 macOS 的系统报告中查看。

usbhub_device_manager

下面是我在 modules目录下创建的usb_script.lua 脚本,作用是监听指定 USB 设备连接或断开状态,触发切换显示器输入源。

usbWatcher = nil
--m1ddc命令
local ChangeMonitorInput2USBC = "/Users/zhxchen/Documents/m1ddc/m1ddc set input 27"
local ChangeMonitorInput2DP = "/Users/zhxchen/Documents/m1ddc/m1ddc set input 15"

function usbDeviceCallback(data)
    if (data["productName"] == "USB 2.0 Hub") then--匹配的设备名
        if (data["eventType"] == "added") then
            hs.execute(ChangeMonitorInput2USBC)
        elseif (data["eventType"] == "removed") then
            hs.execute(ChangeMonitorInput2DP)
        end
    end
end
 
usbWatcher = hs.usb.watcher.new(usbDeviceCallback)
usbWatcher:start()

init.lua文件中插入以下代码

require("modules.usb_script")

上述配置都完成以后,记得在 HammerspoonReload Config

最后

在两台不同的操作系统主机切换显示器和键鼠只需要按一次 USB 切换器的线控开关,在解决这个“最后一公里”的过程中接触了开源免费的 Hammerspoon ,真的好用(括弧笑)。

comments powered by Disqus