本文适用于已经可以正常使用随航,只是希望省去每次手动连接步骤的情况。

我平时会把 iPad 当作 Mac 的第二块屏幕。系统自带的“随航”很好用,但每次解锁 Mac 后都要从“屏幕镜像”菜单重新连接,次数多了还是有点麻烦。

下面这套配置会在 Mac 解锁几秒后自动连接指定的 iPad。它只是替我完成“连接”这一步,画面传输仍然使用 macOS 自带的随航。

开始前,先手动连接一次 iPad:打开 Mac 的“系统设置 → 显示器”,添加 iPad,然后把“用作”设为“扩展显示器”。macOS 会记住这个选择,之后自动连接时通常会继续使用扩展模式。

准备 SidecarLauncher

从 SidecarLauncher Releases 下载最新版,将解压得到的 SidecarLauncher 放到:

~/.local/bin/SidecarLauncher

没有这个目录的话,可以在终端执行:

mkdir -p "$HOME/.local/bin"
mv "$HOME/Downloads/SidecarLauncher" "$HOME/.local/bin/SidecarLauncher"
chmod +x "$HOME/.local/bin/SidecarLauncher"

查看当前能识别到的 iPad:

"$HOME/.local/bin/SidecarLauncher" devices

例如我的设备名是 iPad (2)。先手动测试一次:

"$HOME/.local/bin/SidecarLauncher" connect "iPad (2)"

如果提示 SidecarErrorServiceAlreadyInUse,意思是随航本来就已连接,不是故障。

让 Hammerspoon 在解锁后执行连接

安装 Hammerspoon,第一次打开时按提示授予“辅助功能”权限。

然后创建配置文件:

mkdir -p "$HOME/.hammerspoon"
touch "$HOME/.hammerspoon/init.lua"
open -e "$HOME/.hammerspoon/init.lua"

把下面内容粘贴进去。ipadName 要改成前面查到的设备名:

local sidecarPath = os.getenv("HOME") .. "/.local/bin/SidecarLauncher"
local ipadName = "iPad (2)"

local sidecarTask = nil
local retryTimer = nil

function connectIPadSidecar(attempt)
    attempt = attempt or 1

    if sidecarTask and sidecarTask:isRunning() then
        return
    end

    sidecarTask = hs.task.new(
        sidecarPath,
        function(exitCode, stdOut, stdErr)
            sidecarTask = nil
            local output = (stdOut or "") .. (stdErr or "")

            if exitCode == 0 or output:find(
                "SidecarErrorServiceAlreadyInUse",
                1,
                true
            ) then
                return
            end

            if attempt < 2 then
                retryTimer = hs.timer.doAfter(3, function()
                    connectIPadSidecar(attempt + 1)
                end)
            end
        end,
        {"connect", ipadName}
    )

    if sidecarTask then
        sidecarTask:start()
    end
end

unlockWatcher = hs.caffeinate.watcher.new(function(event)
    if event == hs.caffeinate.watcher.screensDidUnlock then
        retryTimer = hs.timer.doAfter(3, function()
            connectIPadSidecar(1)
        end)
    end
end)

unlockWatcher:start()

-- 手动连接备用快捷键:Control + Option + Command + I
hs.hotkey.bind({"ctrl", "alt", "cmd"}, "I", function()
    connectIPadSidecar(1)
end)

hs.autoLaunch(true)

保存后,点击菜单栏里的 Hammerspoon 图标,选择 Reload Config。可以先按 Control + Option + Command + I 测试;确认能连接后,锁定并重新解锁 Mac 再试一次。

如果要换另一台 iPad,运行 SidecarLauncher devices 查看名称,再修改配置里的 ipadName 即可。

有两个限制需要注意:iPad 最好保持唤醒和解锁,否则连接可能超时;SidecarLauncher 使用了 Apple 的非公开接口,macOS 大版本更新后有可能需要升级工具。无线连接方便,USB 直连则更稳定,还能顺便给 iPad 充电。