我最近把 macOS 升级了,结果发现 UU 远程控制突然有点不对劲。
鼠标明明已经点到了另一个应用里,点击也确实生效了,可键盘输入还留在原来的应用。比如我人在 A 应用里,通过远程控制点击 B 应用的编辑区域,B 应用里的按钮能点,内容也能操作,但一敲键盘,文字还是跑到 A 应用里。
macOS 新版本似乎收紧了对模拟鼠标事件的处理,等了好久 UU 远程都没更新解决这个问题,最终是求助 AI 做了一个临时方案,以下没有任何推广成分,这是 AI 给出的方案。
我最后用 Hammerspoon 补了一层逻辑:监听鼠标左键点击,看看鼠标下面的窗口属于哪个应用。如果发现它不是当前前台应用,就主动调用 activate(),帮 macOS 把焦点切过去。
Hammerspoon 是一个 macOS 自动化工具,可以用 Lua 控制窗口、应用、鼠标、键盘和各种系统事件。用 Homebrew 安装:
brew install --cask hammerspoon
装好后去系统设置 →隐私与安全性 → 辅助功能,把 Hammerspoon 加进去并启用,否则脚本没有权限监听鼠标事件。 接着创建 ~/.hammerspoon/init.lua ,把下面这段代码放进去:
local tap = nil
local function createTap()
if tap then
pcall(function() tap:stop() end)
tap = nil
end
tap = hs.eventtap.new({hs.eventtap.event.types.leftMouseDown}, function(event)
pcall(function()
local pos = hs.mouse.absolutePosition()
local front = hs.application.frontmostApplication()
for _, win in ipairs(hs.window.orderedWindows()) do
local f = win:frame()
if pos.x >= f.x and pos.x <= f.x + f.w and
pos.y >= f.y and pos.y <= f.y + f.h then
local app = win:application()
if app and front and app:pid() ~= front:pid() then
app:activate(true)
end
break
end
end
end)
return false
end)
tap:start()
end
createTap()
-- 每 2 秒检查,僵死就整个重建
hs.timer.doEvery(2, function()
if not tap or not tap:isEnabled() then
createTap()
end
end)
-- 屏幕/空间切换时主动重建
hs.screen.watcher.new(function()
hs.timer.doAfter(0.3, createTap)
end):start()
hs.spaces.watcher.new(function()
hs.timer.doAfter(0.3, createTap)
end):start()
hs.alert.show("焦点修复已启动")
然后点击菜单栏里的 Hammerspoon 图标,选择 Reload Config 。看到"焦点修复已启动"的提示,就说明脚本已经开始工作了。 脚本做的事情不复杂:每次鼠标左键按下,先获取当前位置,找出这个位置下面的窗口,如果它属于另一个应用,就调用 app:activate(true)。最后返回 false ,原本的鼠标点击不会被拦截,还是会继续传给目标应用。