你是否曾注意到,在瘋狂的科技世界裡,總有一個古怪的小專案試圖解決一個極其小眾的問題,而它唯一的競爭對手可能是左手螺絲起子或會自動隱藏的鬧鐘?

我在日常工作流程中使用兩台不同的電腦,並共用同一組鍵盤/滑鼠。嘗試過 Amazon 上幾款 USB 切換盒後,我發現它們都有類似的問題——切換需要一段時間、按鈕操作相當笨拙,而且隨著時間過去也沒有任何改善。

我真正想要的,是能用鍵盤快速切換輸出,並且能藉由滑鼠游標在螢幕間移動來達到相同效果。這個專案讓你同時享有兩種方式,即使你的電腦執行不同的作業系統也沒問題!

DeskHop case and board

特色

  • 完全自由且開源
  • 切換時無明顯延遲
  • 只需將滑鼠游標拖曳至另一台電腦即可切換
  • 無需安裝任何軟體
  • 零件平價易購(低於 15 歐元)
  • 3D 列印卡扣式機殼
  • 輸出端之間具完整電氣隔離
  • 支援 Linux、macOS 與 Windows

現在已提供使用者手冊

Open Source Hardware Logo


運作原理

本裝置作為鍵盤/滑鼠與電腦之間的中介,同時建立並維持與兩台電腦的連線。接著依據你的選擇,決定將滑鼠與按鍵輸入轉發至哪一台電腦。鍵盤會跟隨滑鼠,反之亦然,只要將滑鼠拖曳到另一台桌面,即可切換兩者。

滑鼠

為了讓滑鼠游標能神奇地跨越桌面,滑鼠 HID 報告描述子改為使用絕對座標,接著將仍以相對位移傳來的滑鼠報告在內部累加,持續精準追蹤位置。

當你試圖將游標移出螢幕邊緣朝向另一台螢幕時,裝置會保留 Y 座標,並將最大 X 值替換為最小 X 值,隨即切換輸出端。這能確保游標以相同高度無縫出現在另一台螢幕,提升切換的順暢感。

DeskHop Mouse Demo

從 Mac 拖曳滑鼠至 Linux 會自動切換輸出。


實際切換發生在其中一隻箭頭停止移動、另一隻箭頭開始移動的那一刻。

鍵盤

裝置以 USB Host 角色定期查詢鍵盤,尋找 HID 報告中預先設定的熱鍵(例如我常用的 Ctrl + Caps Lock)。一旦偵測到,即將後續所有字元轉發至另一個輸出端。

為了讓你隨時清楚目前使用哪個輸出端,可重複利用鍵盤 LED 提供視覺回饋。

它也會記住每台電腦的 LED 狀態,讓你能接續上次的設定。

DeskHop Typing Demo

如何建置

為避免建置時出現版本不相容與路徑問題,以及省去下載大型 SDK 的麻煩,本專案已內建最小化的 Pico SDK 與 TinyUSB。

在 Debian/Ubuntu 系統上,請先安裝以下套件:

apt update
apt install \
    build-essential \
    cmake \
    gcc-arm-none-eabi \
    libnewlib-arm-none-eabi \
    python3

接著執行以下指令即可建置:

cmake -S . -B build
cmake --build build

此外,若要重新建置網頁 UI,請查看 webconfig/ 目錄並執行 ./render.py(需安裝 jinja2)。

另一種方式是透過 Docker 執行「docker compose」或「docker-compose」:

docker-compose -f misc/docker.yml run --rm build_container

此方式可確保建置結果可重製。

若要重新建立磁碟映像,請查看 disk/ 目錄並執行 ./create.sh,必要時可依系統調整。你需要 dosfstools(提供 mkdosfs)。

使用預先建置的映像檔

或者,你也可以使用預先建置的映像檔。從 0.6 版開始僅提供單一通用映像檔。你需要 .uf2 檔案,只需將其複製到裝置即可,方式如下:

韌體升級

選項 1(韌體 0.6 及以上)— 同時按下 左 Ctrl + 右 Shift + c + o 進入「設定模式」。鍵盤插入的那端裝置會重新啟動並顯示為名為「DESKHOP」的 USB 磁碟。將 .uf2 檔案複製至該磁碟即可。映像檔驗證完成後,裝置會燒錄並重新啟動,隨即升級另一塊板子。升級期間 LED 會閃爍。完成後會寫入快閃記憶體並重新啟動,結束程序。

注意 — 這不是一般 USB 磁碟,無法用來複製檔案。

選項 2 — 使用 ROM 開機載入程式 — 按住板載按鈕後連接每個 Pico,並將 uf2 複製到出現的快閃磁碟。0.6 版以後的映像檔支援按住按鈕而無需斷電,但「按住按鈕再插電」始終有效。

選項 3 — CDC 快閃指令(僅限偵錯建置)— 若韌體編譯時啟用 DH_DEBUG_CDC_FLASH=ON,可透過 CDC 序列埠指令觸發開機載入程式模式:

echo -n 'flash' > /dev/tty.usbmodem11104

這會立即將裝置重設至開機載入程式模式,顯示為「RPI-RP2」磁碟。此功能僅供開發流程使用。

其他功能

滑鼠減速

你是否曾想精準調整 YouTube 影片滑桿,卻因滑鼠移動太跳而必須像五歲小孩玩「Operation」遊戲一樣小心翼翼?

按下 右 CTRL + 右 ALT 可切換滑鼠減速模式。滑鼠游標會明顯變慢,讓你完成精細工作;再次快速按下相同按鍵即可恢復正常速度。

切換鎖定

若想鎖定在單一螢幕,使用 RIGHT CTRL + K。 這能避免你不小心切換到其他螢幕。再次按下相同組合即可解除。

同時鎖定兩台螢幕

使用 RIGHT CTRL + L 可同時鎖定兩台電腦。 要使用此功能,請先在設定中為每個輸出端指定作業系統(因為快捷鍵不同)。

遊戲模式

若你在玩遊戲,遊戲可能無法與絕對滑鼠模式相容。為此,新增了遊戲模式,可透過 LEFT CTRL + RIGHT SHIFT + G 切換。進入遊戲模式後,滑鼠會鎖定在目前螢幕,並以標準相對座標模式運作。這也能解決各種虛擬機器、尚未支援的作業系統等問題。

螢幕保護程式

本功能據稱可防止電腦進入待機,但說真的——它只是好玩。預設關閉,會讓滑鼠游標像乒乓球一樣在螢幕上彈跳。啟用後,當滑鼠在使用者設定的時間內無動作時啟動;一旦你對該螢幕送出任何輸入,即自動關閉。

潛在用途範例:我有一個有問題的 USB 擴充座,無法從待機恢復影像,因此不讓它進入睡眠是個實用的 workaround。

硬體

電路以兩塊 Raspberry Pi Pico 為基礎,選擇它的原因是價格低廉(每片 4.10 歐元)、可手焊,且大多數供應商都有現貨。

兩塊 Pico 透過 UART 連接,並以 Analog Devices ADuM1201 雙通道數位隔離器(約 3 歐元)或更便宜、更快且腳位相容的 TI ISO7721DR(約 1.5 歐元)隔開;後者為首選。

雖然它們原本不支援雙 USB,但透過一個令人驚嘆的專案——利用 RP2040 的可程式化 IO 奇技實作 USB——現在可以同時作為 USB 主機與裝置。

PCB[已更新]

為讓 DIY 組裝盡可能簡單,走線保留在單面,零件數量也降到最低。

PCB Image

USB D+/D- 差動線應等長,但刻意做成略微不對稱,以補償 Pico PCB 本身對應 GPIO 走線的長度差異,使整體長度匹配。

目標差動阻抗(Zd)為 90 歐姆(實際約 107 歐姆,已足夠接近)。

板厚設計為 1.6 mm,以符合卡扣式機構需求。

PCB 有兩個版本(對使用者而言差異不大)。原始版(v1.0)較易焊接與組裝;v1.1 版則新增以下升級:

  • 新增 ESD 保護(TPD4E1U06DBVR)

  • 新增鍵盤/滑鼠連接器的 VBUS 電容

  • 絲印方向標記

  • 為已預焊接頭的相容板提供定位孔

  • USB 27 歐姆電阻

    此版本因需焊接小型瞬態電壓抑制 IC 與 0805 電阻,手焊難度略高,但仍可完成。理論上可省略 TVS(不建議),裝置仍可運作。

即將推出——使用裸 RP2040、無需 Pico、體積更小、更方便的版本。

機殼

由於我對 3D 建模不太擅長,機殼簡單樸實但能完成任務。它易於列印,耗材約 33 克,需數小時。

水平方向的 PCB 移動由穿過孔洞的定位柱限制,垂直方向則由側邊的卡扣凸耳固定——無需螺絲。機殼已重新設計,加入 Logo 與兩個額外卡扣凸耳,提供更好的密封性。

兩塊板子的 Micro USB 連接器從機殼側邊偏移,因此孔洞需稍大,以便插頭插入。

上蓋採用卡扣式設計,附螺絲起子槽方便開啟。頂部標記為凹陷式,可用蠟筆填色增加對比(或直接保留原狀)。

DeskHop with 3D Printed Case

零件清單

點擊此處查看原始 PCB v1.0 零件清單
元件 數量 單價 / 歐元 總價 / 歐元
Raspberry Pi Pico 2 4.10 8.20
ADuM1201BRZ 1 2.59 2.59
1206 SMD 100nF 電容 2 0.09 0.18
USB-A PCB 連接器 2 0.20 0.40
2.54 1x03 接頭 2 0.08 0.16
總計 11.53

可使用 TI ISO7721DR 取代 ADuM——腳位相容、價格更低、規格更佳。

PCB v1.1

元件 零件 數量 單價 / 歐元 總價 / 歐元
U1, U2 Raspberry Pi Pico 2 4.10 8.20
J1, J4 USB-A PCB 連接器 2 0.20 0.40
U4 TI ISO7721DR 1 1.40 1.40
ADuM1201BRZ)
C1, C2 0805 SMD 100nF 電容 2 0.09 0.18
R1, R2, R3, R4 0805 SMD 27ohm 電阻 4 0.03 0.12
U3, U5 TPD4E1U06DBVR 2 0.31 0.62
C3, C4 4.7uF SMD 0805 電容 2 0.07 0.14
J2, J3 2.54 1x03 接頭 2 0.08 0.16
總計 11.22

USB-A 連接器可選 Molex MX-67643-0910 或尺寸相容的平價替代品。

額外步驟:

組裝指南

如果你有電子組裝經驗,可能不需要這份指南。但若你沒有經驗,這段影片或許能幫助你完成流程。請注意,焊接後應清除 PCB 上的助焊劑,以防腐蝕。

標準清除方式是使用異丙醇與舊牙刷。但猜怎麼著?我不會把我的舊牙刷放到網路上,所以你得自己想辦法 :)

PCB Assembly Guide

[注意] 本影片組裝指南涵蓋 PCB v1.0。修訂版 v1.1 非常相似,流程基本相同。

使用指南

鍵盤快捷鍵 —(韌體 0.68 版及以上)

設定

  • 左 Shift 左 Ctrl + 右 Shift + C + O — 進入設定模式
  • 右 Shift + F12 + D — 清除快閃記憶體設定
  • 右 Shift + F12 + Y — 儲存螢幕切換偏移量

使用

  • 右 CTRL + 右 ALT — 切換滑鼠減速模式
  • 右 CTRL + K — 鎖定/解鎖滑鼠桌面切換
  • 右 CTRL + L — 同時鎖定兩端輸出(請先在設定中指定輸出作業系統)
  • 左 Shift 左 CTRL + 右 Shift + G — 切換遊戲模式(鎖定在目前螢幕,作為標準滑鼠)
  • 左 CTRL + 右 Shift + S — 啟用螢幕保護程式
  • 左 CTRL + 右 Shift + X — 停用螢幕保護程式
  • 左 CTRL + Caps Lock — 切換輸出端

注意:部分鍵盤無法同時正確傳送兩個 Shift,因此快捷鍵已更改為適用於所有人。造成困擾敬請見諒。

游標高度校正

此步驟非必要,但若你的螢幕未完全對齊或尺寸不同,會很有用。目標是讓滑鼠游標以完全相同的高度出現。

Border height difference

將滑鼠停在較大螢幕、與較小/較低螢幕相同高度的位置(圖示),然後按下 右 Shift + F12 + Y。LED(與 Caps Lock)應閃爍確認。

若較小螢幕下緣高於較大螢幕下緣,請重複相同步驟於底部邊界。此設定會儲存至快閃記憶體,並從此保留校正值。

單一輸出端多螢幕

Windows 與 Mac 在多螢幕搭配絕對定位時會出現問題,因此需要 workaround(仍在實驗階段)。目前有一個更好的 workaround 正在開發中,但目前你必須為每個輸出端設定作業系統與螢幕數量。

主要螢幕需置中,次要螢幕置於邊緣。若要設定實際選項,請開啟裝置的網頁設定頁面。

Multiple screens per output

網頁設定模式

從韌體 0.6 版開始,引入了改進的設定模式。請依照以下步驟設定裝置:

  1. 按下左 Ctrl + 右 Shift + C + O — 裝置會重新啟動並進入設定模式(鍵盤插入的那一端)。設定期間 LED 會持續閃爍。

  2. 新的 USB 磁碟「DESKHOP」會出現,內含單一檔案 config.htm

  3. 使用 Chromium / Chrome 開啟該檔案。目前不支援 Firefox,因為它未實作 WebHID。

  4. 點擊「連接」並允許 DeskHop 裝置配對。

    Web Browser with URL

  5. 依需求設定選項,然後點擊「儲存」寫入裝置。

  6. 點擊選單中的「離開」以安全離開設定模式。

    Web Config

Linux 看不到裝置?點擊這裡。

問題:Chromium 在 Linux 上無法運作。

解答:你可能需要調整 /dev 權限,或建立對應的 udev rules 檔案,並確認你的使用者屬於正確的群組,例如:

/etc/udev/rules.d/99-deskhop.rules

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="c000", GROUP="plugdev", MODE="0660"

問題:為什麼不直接像 Via 一樣做一個漂亮的線上網頁,而是採用這個奇怪的 USB 磁碟方式?

解答:從隨機線上位置載入 JavaScript 與你的輸入裝置互動存在潛在安全風險。設定網頁僅限本地,且絕不從外部載入任何內容。

請注意,設定網頁並非刻意混淆而「奇怪」——它是因儲存空間極為有限而自我解壓縮。完整原始碼 100% 開源且為本儲存庫的一部分,歡迎自行重建。

功能驗證

當你連接新的 USB 週邊裝置時,板子會閃爍 LED 兩次,並指示另一塊板子做相同動作。這樣你可以測試每塊板子的 USB 與對外通訊是否正常。

請先在一側插入鍵盤,再換另一側進行測試。若一切正常,兩種情況下 LED 都會快速來回閃爍。

安全性與安全性

部分功能刻意省略,儘管它們能讓裝置更容易使用或設定。以下是這些決定的快速說明:

  • 系統之間沒有複製貼上或任何資訊共享。這能防止資訊外洩。
  • 未經使用者明確同意,不允許 WebHID 裝置管理。輸出端電腦無法主動連線,唯一例外是標準鍵盤 LED 開/關訊息,且嚴格限制為 1 位元組資料。
  • 無法從輸出端觸發韌體升級。僅能透過特殊鍵盤快捷鍵,由使用者明確且刻意操作。
  • 已插入的鍵盤/滑鼠自訂端點不會被暴露,也不會將資訊轉發至這些裝置。它們的潛在漏洞能有效與電腦隔離。
  • 不允許保留輸入歷史。
  • 裝置不會主動發送按鍵輸入。唯一送出的內容是你自行輸入/觸發的內容。
  • 輸出端以實體分離,並以至少 2kV 的最小隔離電壓進行電氣隔離。
  • 裝置之間交換的所有封包皆為固定長度,設定的選項僅限於短清單。大多數選項為唯讀。跨裝置韌體升級可停用。
  • 沒有藍牙、Wi-Fi、網路或網際網路存取等功能。
  • 在任何情況下都不視任何已連接的電腦為可信任對象。
  • 設定模式在一段時間無操作後會自動停用。
  • 全部程式碼皆為開源,無任何二進位 blob,並有詳細註解說明其用途。我鼓勵你永遠不要信任任何人,並透過手動稽核確認你執行的內容。

這仍無法保證任何事情,但我相信這是一套合理的基礎規則,能讓你保持安全與保護。

常見問題

  1. 我只有兩塊 Pico,可以不用 PCB 與隔離器嗎?

    當然可以。建議使用隔離器,但沒有它應該也能運作。

  2. 如果我的螢幕解析度不同,會發生什麼事?

    滑鼠移動在抽象座標空間中進行,電腦會自行計算與實體螢幕的對應關係,因此應該能正常運作。

  3. 我可以在哪裡購買?

    我沒有販售任何東西,這只是個人的非商業興趣專案。

    更新 1:你似乎可以從 Elecrow 以單件數量訂購(PCB、已組裝 PCB 或完整裝置)。 據使用者回報,板子送達時是空白的,你必須自行燒寫韌體。

    更新 2:我從未向 Elecrow 要求任何東西,但幾天前他們主動提供小額預算贊助本專案,用於未來的板子原型製作。由於我的目標是開發支援更多輸出的更好板子,我相信原型服務對專案會有幫助。

  4. 透過滑鼠切換作用中螢幕時,鍵盤是否會跟隨(反之亦然)?

    是的,設計目標就是讓它像單一台電腦一樣運作。

  5. 這是否支援鍵盤/滑鼠組合接收器,例如 Logitech Unifying receiver?

    應該支援。最近的韌體更新後,對組合接收器的支援已大幅改善。

  6. 這是否支援無線滑鼠與鍵盤使用各自的無線接收器(滑鼠一個、鍵盤另一個)?

    應該支援——我已測試過 Anker 無線滑鼠搭配獨立接收器,運作正常。

  7. 我在建置或編譯時遇到問題

    請查看 疑難排解 Wiki,可能有解答。

軟體替代方案

如果你在特定情境下可以使用軟體方案,以下是幾個替代方案。

  1. Barrier — 免費、開源
  2. Input Leap — 免費、開源
  3. Synergy — 商業軟體
  4. Mouse Without Borders — 免費,僅限 Windows
  5. Universal Control — 免費,Apple 產品

限制

  • Windows 10 在 KB5003637 更新中破壞了 HID 絕對座標行為,因此在 Windows 上無法使用超過 1 個螢幕(滑鼠會停留在主螢幕)。目前有一個實驗性 workaround,更好的方案正在開發中。
  • 程式碼需要清理與重構。
  • 尚未在廣泛的裝置上測試,我不知道它在你的硬體上是否能正常運作。有合理的機會可能無法立即開箱即用。
  • 進階鍵盤(帶有旋鈕、額外按鈕或滑桿)可能會遇到這些額外硬體無法運作的問題。
  • 擁有 300 個按鈕的超現代滑鼠可能會看到部分按鈕無法如預期運作。
  • 注意:兩台電腦都必須連接並為 USB 供電,本裝置才能運作(每塊板子由它所插入的電腦供電)。如今許多桌上型電腦與筆記型電腦即使關機仍會提供電源。若你需要在單塊板子完全斷電的情況下運作,應該可以使用 USB 集線器將鍵盤與滑鼠都插入單一埠。
  • macOS 在多於一個螢幕時會出現問題,最新韌體提供了一個實驗性 workaround 來修正此問題。

進度

那麼,這麼多熱情是怎麼回事?我不敢相信——請允許我向大家致謝!我從未預期一個簡單的個人專案會引起這種關注,因此初始功能相當基本(就像我的烹飪技巧),主要涵蓋我自己的使用情境。敬請期待未來的韌體更新,它們將帶來更廣泛的裝置相容性、更多功能與更少的錯誤。由於這是興趣專案,我感謝你對時間限制的理解,並承諾盡我所能做到最好。

計劃中的功能:

  • 改善 Windows 與 macOS 多螢幕的 workaround
  • 透明/遊戲模式
  • 支援超過 2 個輸出端
  • 設定 UI 改善
  • ……以及更多!

正在開發精簡版,僅需單塊 Pico W 板即可提供基本功能,大幅降低成本,讓你即使沒有額外硬體或 PCB 也能嘗試。

滑鼠輪詢現在應可達 1000 Hz(圖表中的低點是我手臂因不斷移動而感到疼痛 :-)):

Mouse polling rate

贊助/捐款

我做這個專案不是為了獲利或其他任何原因,只是想透過為大家創造更好的工作環境來幫助人們。 如果你想進一步支持本專案,請考慮向無國界醫生等慈善機構捐款。

Donate to Doctors Without Borders, with PayPal

請允許我向所有曾經或考慮幫助過的人致謝!

免責聲明

我誠懇地請求任何嘗試建置本專案的人理解並承認,我對任何傷害、損害或其他後果概不負責。你的安全很重要,我鼓勵你謹慎進行本專案,在整個過程中採取必要的預防措施,並為自己的健康承擔個人責任。請不要觸電、燒傷、感到壓力或生氣。祝你玩得開心!

快樂切換!