4
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Barrierを使ってMacの気持ちのままWindowsで気持ちよくなる

キーボード共有機能に沸く2021年6月

WWDCから結構経っちゃいましたが、WWDC2021の最高潮のポイントはUniversal Controlだったのではないかと思います。

おおーと思ったものの、多くの人はこうも思ったと思うのです。
「iPadよりも隣に置いてあるWindowsやLinuxマシンとのキーボード共有がしたいんだけれど」
奥さん、できますよそれ

Barrier

本題です。KVMソフトBarrierを使ってMacをホストにしつつ、WindowsマシンでMagic KeyboardやMagic Mouseをそのまま使って気持ちよくなろうというのがこの記事です。
Windows-Mac間で使えるKVMソフトとしてはSynergyやSharemouseなどが有名だとは思いますが、これらは有料ライセンス販売のソフトになります。僕もちょっと前から存在は知っていましたが、有料であることと、JIS対応がどうやらイマイチっぽいような話を小耳に挟んでいたのであんまり試す気にはなれずに放置していました。WWDCをきっかけに再びKVMへの気持ちが湧き上がってきて調べていたところ、Barrierに出会いました。
BarrierはSynergyがオープンソースだった頃のソースコードからフォークされたプロジェクトで、UI部分も含めた状態で全て公開されています。
無料なら一旦使ってみるかという気持ちで導入してみました。

導入環境

本記事では以下のような環境への導入を行っています
サーバー: macOS 10.15(Mac mini 2018)
クライアント: Windows 10 20H2(AMD環境)
Barrierは現時点で最新のリリースビルドのv2.3.3をそれぞれの環境にインストールしています

できること・問題点

ざっと試してみてクリティカルなものから軽微なものまでいくつかぶつかった問題があったのでまとめていきます。

できる事

  • Mac-Windows間のマウス・キーボードの共有
  • サーバーから送信する修飾キー(Ctrl, Meta, Super, Alt)のカスタマイズ
  • クリップボード共有、またそれぞれのクリップボード拡張アプリにヒストリーが蓄積される
  • Windowsクライアント上でのAHKなどを用いたキー入力の上書き
  • Macサーバー上でのKarabinerなどを用いて上書きしたキー入力の送信(一部ソフトでの結果は反映されず)
  • Windowsクライアント上でのMagic Mouseの慣性スクロール
  • Windowsクライアントへのボタン付きマウスのボタンの送信

思ったよりもしっかり動いてて感動しました。それぞれ有線LANに繋いでいる環境下ではありますが、遅延もほぼなく、日常動作では困らなさそうな精度を保っています。サーバー、クライアントそれぞれでキーバインドの変更などを行なっていることもあると思いますが、Karabiner・AHK・PowerToysは自分の環境では問題なく動作しています。ただ、Hammmerspoonやエレコムのマウスユーティリティはもう少し上のレイヤーで動作しているためかクライアントまでキーコードが伝播しませんでした。

サーバーから送信する修飾キー(Ctrl, Meta, Super)のカスタマイズ

これが個人的には結構大きかったところなのですが、Barrierではコード弄らなくてもアプリケーション側から送信するキーをカスタマイズできます。
どういう事かというと通常Magic KeyboardなどMac配列のキーボードをそのままWindowsで使うとCommand(⌘)キーWindowsキーに当たってしまって大変厳しい思いをするのですが、アプリケーションサイドで送信するキーをカスタマイズできるため、Windowsのレジストリなどを弄らなくても修飾キーの配列を変えることができます。ただし、修飾キーは全て左側のキーとして認識されるため、左右で動作を変えるようにAHKを組むときなどは少し工夫が必要です。自分の環境ではControlキー左ControlCommandキー右Controlとして扱ってAHKを書いているので、Commandから送信されるキーを右側にする修正を入れています。

できない事

軽微な問題

  • かな・英数キーが飛ばずにスペースが飛ぶ
  • ctrl+alt+delがクライアントのWindows上で実行されない
  • capslockの挙動が怪しい(日本語入力モードでcapslockを入れると入力を受け付けなくなるなど)
  • Super,Controlなどの装飾キーが全て左側のキーとして送信される
  • Macサーバーにおいてクライアント側操作時でも、Barrierよりも上のレイヤーで動いているキーカスタマイズソフトを使っている場合はキー入力などがMac側に反映されてしまう

クリティカルな問題

  • JISキーボードの¥(|)キーが飛ばない
  • Mac同士を繋いだときにキーボード共有が効かない
  • keystrokeでクライアントに送るキーコードをオーバーライドするとサーバー側で該当するキーが効かなくなる

JIS配列のキーがいくつか飛ばないなどの問題は事前にある程度情報を見ていたため、予想通りなところはあったのですが、Mac同士で繋ぐとそもそもキーが一切飛ばないのはちょっとびっくりしました。ここはUniversal Controlに期待ですね・・・

ctrl+alt+delがクライアントのWindows上で実行されない

これに関しては困る人は困るかもしれませんが、僕の環境だとあんまり使うこともないのでそのままにしています。一応ソースコード上にはfakeCtrlAltDelなる関数があり、何やら実装されてそうな雰囲気がありますが、自分の環境では現状こいつは効いてなさそうでした。issueにも上がっていたのですが、ちょっと不思議なワークアラウンドを残してクローズされてしまっていました。こちらのワークアラウンドは実際に自分の環境でも再現できたので、修飾キーの送信で何か問題が起きているのかもしれませんが、デバッグログを見る限りはfakeCtrlAltDelは通っていそうなので権限回りで弾かれてそうな感じもします。

capslockの挙動が怪しい

英数入力だと問題ありませんが、日本語入力時に効かなくなります。
これの解決は簡単ですね。CapsLockを無効化してしまえば解決です。使わないキーは潰してしまいましょう。

...OSXKeyState.cppのキーモディファイア周りを触っていたときに正しく動作したりしていたので、この辺りの条件判定を弄くり回せば直りそうですが、そこまでの気持ちはなかったので放置しています。

JISキーボードの¥キーが飛ばない

これはまぁまぁ厳しいです。
まず、MacのJISキーボードの¥は実はWindowsのようにバックスラッシュのキーコードを上書きしているとかいう動作ではなく、international3という独自のキーコードが割り当てられています。現在最新のBarrier(v2.3.3)ではこのinternational3のキーコードからWindows上での¥にマッピングするコードがなく、そのままキーコードを送るとマッピングをすり抜けてキーコードが何も実行されないという状態になります。
これを解決するために

  1. OSXKetState.cpp内で0x005ckVK_JIS_Yen(¥キーのキーコード)をマッピングする
  2. サーバーのコンフィグにkeystroke(Shift+Backspace) = keystroke(Bar)を追記する

といったワークアラウンドを紹介されているブログがあり、こちらの方法を試してはみたのですが、これでは完璧に解決には至りませんでした。
まず、なぜ上記のような手順になっているかというと、1のように¥キーに直接Windowsにおける¥キーのコード0x005cを割り当てているのですが、 この0x005cが厄介で、Barrierからこのキーコードを送信すると、¥(|)のキーではなく、_(ろ)から入力される¥キー、すなわちWin+_(アンダーバー)のキーコードが送信されます。なのでこのままShift+¥を入力しても|(Bar)が入力されないという状況になります。
これをなんとか|(Bar)が入力されるようにするため行っているのが2の設定です。Barrier(Synergy)のサーバーコンフィグにはキー入力を上書きする設定、keystrokeがあるのですが、これを使うとクライアント側では設定が上書きされてちゃんと入力できるようになるものの、サーバーサイドでShift+¥を入力したときに何も反応しなくなってしまいます。この問題はissueも立っているのですが、本家Synergyでは長年放置されている状態でいつ対応されるかわからないので一旦この方法は忘れて違う方向性で修正していくことにしました。

ということで以下の

  • かな・英数キーが飛ばずにスペースが飛ぶ
  • Super,Controlなどの装飾キーが全て左側のキーとして送信される
  • JISキーボードの¥(|)キーが飛ばない

3つの問題について修正するコードを用意しました。

修正コード

修正ブランチ(Compare)

OSXKeyState.cpp
...略

    { kKeyBrightnessDown, s_brightnessDown },

    // JIS keyboards only
-   { kKeyEisuToggle, kVK_JIS_Eisu },
-   { kKeyKana, kVK_JIS_Kana }
+   { kKeyMuhenkan, kVK_JIS_Eisu },
+   { kKeyHenkan, kVK_JIS_Kana }
};

...略

    if ((changed & KeyModifierSuper) != 0) {
-       handleModifierKey(target, s_superVK, kKeySuper_L,
+       handleModifierKey(target, s_superVK, kKeySuper_R,
                            (newMask & KeyModifierSuper) != 0, newMask);
    }
    if ((changed & KeyModifierCapsLock) != 0) {

ここでは

  1. かな・英数キーにWindowsの変換・無変換キーを当てる
  2. Commandキーを左から右に変える

ということをやっています。1.に関してはどうもバグらしく、修正PRが今立っていますが、こちらを試しても自分の環境ではあんまりうまくいかなかったので、変換・無変換キーにマップすることにしました。
2.は単純にLRに置き換えただけです。ちなみにここからBarrier側の設定でSuperControlに当てるということをやっていますが、右Controlとして当てられていました。Altキーに設定しても同様に右Altとして割り当てられます。

key_state.h
static const KeyID      kKeyMissionControl  = 0xE0C0;
static const KeyID      kKeyLaunchpad       = 0xE0C1;


+ // for mac jis keyboard
+ static const KeyID        kKeyMacJISYen       = 0x00A5;
//@}

struct KeyNameMapEntry {
KeyState.cpp
    kKeyKP_6,            0x0036,
    kKeyKP_7,            0x0037,
    kKeyKP_8,            0x0038,
-   kKeyKP_9,            0x0039
+   kKeyKP_9,            0x0039,
+   kKeyMacJISYen,       0x005c // keyremap for Mac JIS keyboard
};

ここでは

  1. key_state.hへのMacJISキーボードの¥キーコード定義の追加
  2. KeyState.cppでは追加したMacJISキーボードの¥キーコードへのWinでの¥キーコードのマッピング

を行っています。
このKeyState.cppはサーバーから受け取ったキーコードの解決に使われていますが、該当コード内に適切なキーコード置き換えブロックがなかったため、とりあえずキーパッド(テンキー)の置き換え箇所の中にねじ込んでいます。この方法においてはMacからの入力を別のキーコードに差し替えたりせず、クライアント側でのリマップに委ねているため、Shift+¥はそのまま|になります
Mac->Win間において0x00A5に当たっているキーコードはなかったようなのでこのような実装にしてみましたが、他のOS環境下でぶつかるキーコードがあったら悪さをする可能性もあるのでご注意ください。

あとがき

これらの修正コードをビルドしてそれぞれの環境にインストールすればMacJIS環境とWindowsの快適なキーボード・マウス共有環境が出来上がります。
Barrierを導入するまでは複数デバイス切り替え機能つきのBluetoothキーボードにてそれぞれのデバイス間のキーボードの切り替えを行っていましたが、操作したいデバイスにキーボードを切り替え忘れていて、事故りそうになるなどが頻発していました。Barrierではマウスの位置にキーボードが追従するため、自然と見ている画面への入力ができるようになります。またBarrierとともにAutoHotKeyなどを併用することで、Windows上でそこそこMacに近いキーバインドも再現できています。
Windowsアレルギーだという方もこの環境であれば少しは気持ちよくWindowsを使えるようになるのではないかと思います。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
4
Help us understand the problem. What are the problem?