DeskHop – 高速デスクトップ切り替え機能
(github.com/hrvach)- DeskHopは、2台のコンピューターで1つのキーボード/マウスを共有する際に、ボタン式USBスイッチの代わりにショートカットキーとマウスポインター移動で入力先を素早く切り替えるオープンソースのハードウェアプロジェクト
- デバイスはキーボード/マウスと2台のコンピューターの間で USB Host/Device として動作し、両側の接続を同時に維持したうえで、選択された出力へマウス移動とキー入力を渡す
- マウス切り替えはHIDレポートディスクリプターを 絶対座標 に変更し、内部で相対移動量を累積することで、画面境界を越えると同じ高さにある別のコンピューター画面へカーソルが現れるようにしている
- 主な特徴は、体感遅延なし、ソフトウェアのインストール不要、Linux/macOS/Windows対応、15€未満の部品、3Dプリントケース、出力間の ガルバニック絶縁
- 制約も明確で、Windows 10 KB5003637以降はマルチディスプレイの絶対座標に問題があり、macOSのマルチディスプレイは実験的な回避策が必要で、高機能キーボード・多ボタンマウス・さまざまなデバイスとの互換性は保証されない
2台のコンピューター間を素早く行き来するハードウェアスイッチ
- DeskHopは、毎日2台のコンピューターを使いながら1つのキーボード/マウスを共有したいというユースケースから始まったプロジェクト
- 既存のUSB切り替えボックスは切り替えに時間がかかり、ボタンを探すのも不便という問題を解決しようとしている
- 求める動作は2つ
- キーボードショートカット で出力を切り替える
- マウスポインターをモニター間へドラッグすると自動で切り替わる
- 異なるOSを使うコンピューター同士でも動作するよう設計されている
- User Manual が提供されている
主な機能
- 完全に 無料のオープンソース であり、Open Source Hardware認証を取得
- 切り替え時に体感できる遅延がない
- マウスポインターをコンピューター間でドラッグして移動できる
- コンピューターに追加ソフトウェアをインストールしない
- 部品コストは 15€未満 とされている
- 3Dプリント可能なスナップフィットケースを採用
- 出力間で完全な ガルバニック絶縁 を提供
- Linux、macOS、Windowsで動作
動作方式
- デバイスはキーボード/マウスとコンピューターの間に入る 中間デバイス として動作する
- 2台のコンピューターとの接続を同時に確立し、維持する
- 現在の選択状態に応じて、マウス移動とキー入力をどちらのコンピューターへ渡すかを決定する
- キーボードはマウスに追従し、マウスもキーボードの切り替え状態に追従する
- マウスを別のデスクトップへドラッグすると、キーボード入力先も一緒に切り替わる
マウス切り替えの実装
- マウスカーソルが画面間を移動する感覚を作るため、HIDレポートディスクリプターを 絶対座標 方式に変更
- 実際のマウスレポートは引き続き相対移動量として入り、デバイス内部でそれを累積して現在位置を管理する
- 別のモニター方向へ現在の画面領域を出ようとした場合、Y座標を維持したままX座標を反対側境界へ変更してから出力を切り替える
- これにより、カーソルは別のコンピューター画面の同じ高さに現れ、切り替えが自然に見える
- 実際の切り替えは、片側の矢印が止まり、もう片側の矢印が動き始める瞬間に発生する
キーボード切り替えとLED状態
- デバイスは USB Host として動作し、キーボードを定期的にポーリングする
- HIDレポート内で事前設定したショートカットを見つけると、その後の文字を別の出力へ送る
- 使用例は
Ctrl + Caps Lock
- 使用例は
- どの出力を使っているかを示すために、キーボードLEDを再利用できる
- 各コンピューターごとのLED状態を記憶するため、以前の状態をそのまま引き継げる
ビルドとファームウェア更新
- バージョン不一致やパス問題を減らし、大きなSDKダウンロードを避けるため、最小限の pico sdk と tinyusb が同梱されている
- Debian/Ubuntuでは
build-essential,cmake,gcc-arm-none-eabi,libnewlib-arm-none-eabi,python3のインストールが必要 - 基本ビルドは次のコマンドで実行する
cmake -S . -B buildcmake --build build
- Dockerを使った再現可能なビルドも提供される
docker-compose -f misc/docker.yml run --rm build_container
- pre-built images を使うこともできる
- バージョン0.6からは単一の汎用イメージが提供される
.uf2ファイルをデバイスにコピーして使う
ファームウェアのアップグレード方法
- Option 1: firmware 0.6以上では
left ctrl + right shift + c + oでconfig modeに入る- キーボードが接続された側のデバイスが再起動し、
DESKHOPというUSBドライブとして現れる .uf2ファイルをコピーすると、イメージ検証後にフラッシュと再起動が行われ、もう一方のボードのアップグレードも続けて実施される- このドライブは通常のUSBストレージではないため、ファイルコピー用途には使えない
- キーボードが接続された側のデバイスが再起動し、
- Option 2: ROM bootloaderを使い、各Picoのボードボタンを押したまま接続し、現れたフラッシュドライブへ
.uf2をコピーする - Option 3: デバッグビルドで
DH_DEBUG_CDC_FLASH=ONを指定してビルドした場合、CDCシリアルコマンドでbootloader modeに入れるecho -n 'flash' > /dev/tty.usbmodem11104
追加機能
-
Mouse slowdown
right CTRL + right ALTで低速マウスモードを切り替える- 精密な位置調整が必要なときにポインター速度を大きく下げる
-
Switch Lock
RIGHT CTRL + Kで現在の画面に固定する- 誤って別の画面へ移動してしまうのを防ぐ
-
Lock Both Screens
RIGHT CTRL + Lで2台のコンピューターを同時にロックできる- 各出力のOSを設定しておく必要がある
-
Gaming Mode
LEFT CTRL + RIGHT SHIFT + Gで切り替える- 現在の画面に固定され、マウスは標準的な相対座標マウスのように動作する
- 絶対マウスモードに合わないゲーム、仮想マシン、現時点で未対応のOS向けのモード
-
Screensaver
- デフォルトでは無効
- 有効にすると、一定時間操作がない後でマウスポインターがPongのボールのように画面内を跳ね回る
- その画面に入力を送ると自動で無効になる
ハードウェア構成
- 回路 は2枚の Raspberry Pi Pico ボードをベースにしている
- Picoは1枚4.10€と安価で、手はんだが可能で入手しやすいことから選ばれた
- 2枚のPicoはUARTで接続される
- 両側はデジタルアイソレーターで分離される
- Analog Devices
ADuM1201は約3€ - TI
ISO7721DRは約1.5€で、より安く高速かつピン互換のため好まれている
- Analog Devices
- RP2040は標準ではdual USBをサポートしないが、Pico-PIO-USB によりPIOでUSBを実装し、USB HostとDeviceの両方の役割を果たす
PCBとケース
- DIY制作を容易にするため、PCBトレースは片面にまとめ、部品点数を最小限にしている
- USB D+/D-差動線は本来同じ長さであるべきだが、Pico PCB上のGPIOトレース長の差を補正するため、意図的にやや非対称に設計されている
- 差動インピーダンスの目標は 90Ω で、実測では約107Ωを達成
- PCB厚はスナップフィットケースに合わせて 1.6mm に設計されている
- PCB v1.1ではv1.0に対して次を追加
- ESD保護
TPD4E1U06DBVR - キーボード/マウスコネクター用VBUSコンデンサー
- シルクスクリーンの向き表示
- ヘッダーがあらかじめはんだ付けされたクローンボード向けの穴と位置合わせ改善
- USB 27Ω抵抗
- ESD保護
- v1.1は小型TVS ICと0805抵抗のため、手はんだの難易度がやや高い
- ケースは case で提供され、約 33g filament を使用し、数時間で出力できる
- ネジ不要のスナップフィット構造で固定され、ふたにはドライバーで開けられるスロットがある
コストと部品
- PCB v1.1 BOM総額は 11.22€ とされている
- 主な部品は次のとおり
- Raspberry Pi Pico 2枚: 8.20€
- USB-A PCBコネクター 2個: 0.40€
- TI ISO7721DR 1個: 1.40€
- 100nFコンデンサー 2個: 0.18€
- 27Ω抵抗 4個: 0.12€
- TPD4E1U06DBVR 2個: 0.62€
- 4.7uFコンデンサー 2個: 0.14€
- 2.54mm 1x03ヘッダー 2個: 0.16€
- 追加でPCB製造が必要で、Gerber が提供されている
- 3Dプリント用の STLファイル も提供されている
使用ショートカットと設定
- firmware 0.68以上の主要ショートカットは次のとおり
Left Ctrl + Right Shift + C + O: config modeに入るRight Shift + F12 + D: フラッシュ設定を削除Right Shift + F12 + Y: 画面切り替えオフセットを保存Right CTRL + Right ALT: 低速マウスモード切り替えRight CTRL + K: マウスのデスクトップ切り替えをロック/解除Right CTRL + L: 2つの出力を同時にロックLeft CTRL + Right Shift + G: gaming mode切り替えLeft CTRL + Right Shift + S: screensaverを有効化Left CTRL + Right Shift + X: screensaverを無効化Left CTRL + Caps Lock: 出力切り替え
- 一部のキーボードが両方のShift同時入力を正しく送れないため、ショートカットが変更されている
Web設定モード
- firmware 0.6から改善された configuration mode が導入された
Left Ctrl + Right Shift + C + Oを押すとデバイスが再起動し、設定モードに入るDESKHOPというUSBドライブが現れ、その中にconfig.htmファイルが1つある- このファイルはChromiumまたはChromeで開く必要がある
- FirefoxはWebHID実装を避けているため、現在は対応していない
- 接続を許可した後、オプションを設定して保存するとデバイスに書き込まれる
- オンライン設定ページではなくローカルファイル方式を使う理由は、入力デバイスとやり取りするJavaScriptを任意のオンライン場所から読み込むことが潜在的なセキュリティリスクになるため
- 設定Webページは保存領域の制約から自己展開方式になっており、ソース全体はリポジトリに含まれている
セキュリティと安全設計
- システム間の コピー/貼り付け や情報共有機能はない
- 情報漏えいを防ぐための意図的な制限
- 出力側コンピューターから入ってくる接続はない
- 例外は標準キーボードLEDのon/offメッセージのみで、1バイトのデータに制限される
- 出力側コンピューターからファームウェア更新をトリガーすることはできない
- 特別なキーボードショートカットによる明示的なユーザー操作のみ許可される
- 接続されたキーボード/マウスのカスタムエンドポイントを公開したり、その情報をデバイス側へ渡したりしない
- 入力記録を保存しない
- デバイスが任意にキー入力を生成しない
- ユーザーが入力またはトリガーしたものだけが出力される
- 出力は物理的に分離され、最低 2kV絶縁耐圧 のガルバニック絶縁を使用する
- デバイス間パケットは固定長で、送信される設定オプションは短い一覧に限定される
- Bluetooth、Wi-Fi、ネットワーキング、インターネットアクセスはない
- 接続されたコンピューターはいかなる場合も信頼対象とみなされない
- 設定モードは一定時間の無操作後に自動で終了する
- コードはバイナリブロブなしでオープンソース提供される
FAQと互換性
- PCBとアイソレーターがなくても2枚のPicoだけで動作は可能だが、アイソレーターの使用が推奨される
- 異なるモニター解像度でも、マウス移動は抽象座標空間で処理され、コンピューター側が物理画面に対応付けるため動作するはず
- 販売用製品ではなく、個人の非商用ホビープロジェクト
- Elecrow でPCB、実装済みPCB、完成デバイスを1台単位で注文できるという更新がある
- ユーザー報告によると、ボードは空の状態で届き、ファームウェアは自分で書き込む必要がある
- Logitech Unifyingのようなキーボード/マウス用コンボドングルは、最近のファームウェア更新以降サポートが改善したという
- 個別の無線レシーバーを使うワイヤレスマウスとキーボードは、Ankerのワイヤレスマウステストで正常動作した
- ビルド問題は Troubleshooting Wiki を参照できる
ソフトウェア代替
- Barrier: 無料、オープンソース
- Input Leap: 無料、オープンソース
- Synergy: 商用
- Mouse Without Borders: 無料、Windows専用
- Universal Control: Apple機能
既知の制約と計画
- Windows 10
KB5003637以降、HID絶対座標の動作が壊れ、Windowsでは2画面以上を使えない- マウスはメイン画面に留まり、実験的な回避策があり、より良い回避策を開発中
- コードには整理とリファクタリングが必要
- さまざまなデバイスで十分にテストされておらず、ハードウェアによってはそのまま動作しない可能性がある
- ノブ、追加ボタン、スライダー付きの高機能キーボードでは、それら追加ハードウェアが動作しない場合がある
- ボタン数が非常に多い最新マウスでは、一部ボタンが期待どおり動作しない場合がある
- 両方のコンピューターが接続されUSB電源を供給していないと動作しない
- 各ボードが接続先コンピューターから給電されるため
- macOSは2画面以上で問題があり、最新ファームウェアではそのための実験的回避策が提供される
- 計画中の機能には、Windows/macOSマルチディスプレイ回避策の改善、transparent/gaming mode、2台超の出力対応、設定UI改善などがある
- 単一のPico Wボードだけで基本機能を提供する lite version も進行中
- マウスポーリングは現在 1000Hz で動作可能
1件のコメント
Hacker News の意見
クライアントソフトウェアなしで画面の端を検知できる点がよい
マウスカーソルを自然に移動させるために、マウス HID レポートディスクリプタを絶対座標に変更し、実際には相対移動として入ってくるマウスレポートを内部で累積して正確な位置を維持する方式
そのため、クリップボード機能とクライアントソフトウェアのない synergykm / Barrier のように動作する
例えば自動化スクリプトや、カーソルを画面中央に固定するゲームのような場合がある
YouTube では、別途ハードウェアがなくても
,と.キーで動画をフレーム単位で移動できるタッチインターフェースで細かい選択をスライダーで行うのは本当にひどい
どちらが先だったのかは分からないが、mpv で知って、YouTube で偶然押してみたら動作した
Windows では、Microsoft Garage が開発し、現在は Windows PowerToys に含まれている Mouse Without Borders を使える
リンク:
https://www.microsoft.com/en-us/garage/profiles/mouse-without-borders
https://github.com/microsoft/PowerToys
ただし今見るとメンテナンスは停止しており、後継は Input Leap である
https://github.com/debauchee/barrier
https://github.com/input-leap/input-leap
特にコンピュータ間でファイルをドラッグ&ドロップしてコピーしやすくなる
キーボードとマウスを切り替えるために USB ハブを4個も買ったが、ほとんどの機器があまりにひどくていら立つ
1日に何度もハブを物理的に抜き差ししなければならないことがあり、ウェブカメラや USB マイクまで接続するとさらに悪くなる
Synergy はうまく使っているが、ウェブカメラ、マイク、オーディオまで適切に扱えて、キーボードショートカットで接続されたデバイスのまとまりだけを移せるちゃんとした KVMが必要だ
KVM ユーザーは明らかに十分にサポートされていない
DisplayPort 入力ごとに USB ポートが付いており、USB-C は周辺機器とディスプレイ入力、そしてかなり良い電源出力まで担当する
机の上の小さなスイッチで切り替えるが、表示していない入力にもモニターが接続されたままのように見せるので、Windows が再配置するために点滅することがなく、切り替えがずっと速く滑らかだ
よくあるユースケースだと思うので残念
先にドックで取り出すこともできるが、使っているモニターの解像度が高いため、ほとんどのドックは荷が重いか 30Hz しか対応しない
Mac は Thunderbolt 4 ケーブル1本で、PC は HDMI 2.1 と USB3 10Gbps でアップストリームを接続する
モニターにはイーサネットとキーボード/マウスを接続し、ショートカットキーまたはモニターの OSD で正しい機器に切り替わる
PIP 機能で2台の機器を同時に見ることもできる
限界は USB 2 ホストコントローラーだけなので、一部のウェブカメラのような高速デバイスは切り替えにくい点だ
Apple 製品を混ぜる必要があるなら、Apple が MST を嫌うため、ディスプレイチャネル2本を区別するために Mac で物理的な USB3 ケーブル2本を使う必要がある
ファイルを素早く移すために USB ドライブを挿して使っているが、USB 電源で動作するデバイスならたいてい使える
USB 3+、DP などを選ぶと高価だが、USB だけを切り替える安価なモデルもある
ただし特殊キーのある一部のマウスとキーボードは100%動作しないという大きな欠点がある
この用途で Synergy を10年以上使っている
https://symless.com/synergyで、高速で、Wi-Fiでも即座に切り替わり、Windows/Mac/Linuxのすべてに対応している
後者2つは無料のオープンソースで、Synergyはデバイス間の境界を構成する方法が良い
ただ、どの解決策でも カスタムのモニター配置 をきちんとサポートしてくれるといい
自分の環境ではモニターが一直線ではなく、各モニターがそれぞれ独立して各デバイスに切り替えられるので、モニター別・デバイス別に境界を指定できれば素晴らしいのだが、ソフトウェアにもハードウェアにも見当たらない
最近Synergyに問い合わせたところ、人気の機能要望としてロードマップに入っているとのことで、近いうちに出てくれるといい
先にコンピューターへログインする必要がなく、画面端を越えるかキー入力の組み合わせで切り替えられる
接続されたUSBデバイスも、キーボード・マウスとは独立して切り替え可能
こうした製品はboundless、borderless、roaming KM switchと呼ばれることもある
https://www.cdw.com/product/siig-4-port-roaming-km-switch-wi...
個人的にはSynergyよりずっとよく動作した
Synergyの開発者たちが何年も前からあるバグに反応せず、もう使えなくなった後に乗り換えた
例: https://github.com/symless/synergy-core/issues/5992
欠点は、1年後もアップデートを受けるには「メンテナンス更新」が必要な点だが、まだ更新していなくても問題なく使えている
確認してみると、設定は 4〜5年間問題なく 動作しており、有料ソフトウェアの中でも価値が高い部類に入る
セキュリティはあらゆるものの基本で無料であるべきで、贅沢ではなく最低条件
それでも試してみて良ければ、コピー&ペースト機能のためにプレミアムライセンスを買うつもりではある
似たプロジェクトである https://github.com/jfedor2/screen-hopper に触発されて作ったプロジェクトがある
自作版は2つのプログラムで構成される
1つはLinuxデスクトップ上で実行され、Linux入力サブシステムであるevdevの入力イベントを待ち受け、特定のキーを押すとすべてのイベントを消費してUSBシリアル経由でRPI Picoへ送る
もう一度押すと手動リスニングモードに戻る
RPI Picoはシリアルで受け取ったLinux evdevイベントをUSB HIDイベントに変換し、別のWindows PCへ送る
結果として、Linux PCと任意のOSが動くPCの間を即座に切り替えられるKMスイッチになる
配線写真: https://ibb.co/m0zhzgz
もう1つのPicoをUSBシリアルアダプターとして使っており、ハードウェア初心者としてはワイヤー2本だけで済むのが大きな安心材料だった
2つのプログラムはいずれも100行未満で、Linux evdevを待ち受けるRustクレートやPythonパッケージは多い
Pico側も大きなswitch文のあるループに近く、USB HIDイベントを送るRustクレートがある
COBSを使えば、フレーミングを気にせずシリアルで送れる
USBシリアルのバグのため結局オープンソース公開はしなかったが、接続が切れた後にLinuxデスクトップへ正しく再接続されなかった
LinuxのせいなのかPicoのせいなのかは分からず、ケーブルを抜かないので今も問題なく使っている
FPSゲームをよくするので絶対座標機能はあえて外し、切り替えキーをマウスのサイドボタンに割り当てて、キーボードに触れずにシステムを切り替えられるようにしている
screen-hopperプロジェクトを昨日ようやく知ったのだが、何かを作ろうとしても、より賢い誰かがすでにもっと上手く作っているという説を確認した気分だ
ゲームはまったくしないので絶対座標でも問題ないが、ToDoリストにはこれを設定可能にする項目が入っている
誰かがバグを起こしている微妙な部分を掘り下げるよう ナードスナイピング できるかもしれない
そのまま提供するソースはここにある: https://github.com/null-dev/picokvm
USB 3.0スイッチで2台のPC間のマウスとキーボード入力を切り替えるのは、大きな不満の1つだった
Teams会議であまり話すことがないときに誰かが名前を呼んだりメッセージを送ってきたりすると、Teamsが開いているPCへ入力を戻そうとしてボタンを探して慌てることになる
ESP32やRpi Pico WとフォトカプラをいくつかUSBスイッチのボタンピンに接続し、HTTPエンドポイントを公開してAutoHotkeyスクリプトとショートカットキーで2台の入力をトグルする構想を立てていた
ただし 現在アクティブな入力を判別する方法 が思い浮かばず断念したが、この解決策は気に入っている
会社から支給されたLogitechのヘッドセットにはケーブルに音量、通話終了、ミュートのボタンがあり、マルチタスク中でもミュート解除がずっと楽になった
Synergy はこの用途を純粋なソフトウェアでうまく処理している
無料でもオープンソースでもないが、比較的安価
https://symless.com/synergy
どちらもオープンソース
[0] https://github.com/debauchee/barrier
[1] https://github.com/input-leap/input-leap
1.9 版から分岐したオープンソースのフォークもある: https://github.com/debauchee/barrier#what-is-it
例えば macOS ホストを使うと、Windows/Linux クライアントでカーソル位置の計算には macOS の加速カーブを使うが、実際のカーソル移動には使わない
そのため、ホストに近い Windows 画面の 3 分の 1 ほどの領域で作業しようとすると、意図せずまた戻ってしまう
どの解決策もデスクトップ OS でしか動かないように見える
この手の技術で安定しているものは一つもなく、Synergy は接続していた複数のキーボードまで何度も止めてしまい、コンピューターの電源を入れ直さないと反応しない状態にしたことがある
本当にすごい
少なくとも 20 年間、左から Linux-Mac-Windows の箱を並べたデスクトップ構成を使ってきた立場としては、特にそう感じる
プログラミング言語に多言語話者がいるなら、ハードウェアにはマルチプラットフォーム構成がある
幸い、ここ数年でシステムオンチップ(SoC)設計が増え、より簡単になった
現在の構成は、深圳から来た 250 ドルの Ryzen SoC Mac mini クローン 2 台と M1 MBP
かつて堅牢だった Synergy のようなオープンソース KVM ソリューションの世界が、フォークの再帰的な悪夢に変わり、無料で動くマルチプラットフォームのオープンソース・ソフトウェア KVM を手に入れにくくなったのは残念
今は結局、従来の KVM スイッチを使っているが、ボタンを押す行為が集中をそぐ
いつかこういうものをまた試してみたい
これを商用化しようという人がいれば、プラスチック射出成形、マーケティング、大量組み立て、その他必要な作業の費用を負担して引き受ける用意がある
メールアドレスはプロフィールにある
自分にとっては取引不成立になる条件
boundless、borderless、roaming KM switch で検索すればよい