Keyboard Lock API でキーをキャプチャする

インタラクティブなウェブサイト、ゲーム、リモート デスクトップやアプリケーション ストリーミングなど、さまざまなユースケースで臨場感あふれるフルスクリーン エクスペリエンスを提供します。

多くのユーザーがブラウザで多くの時間を費やすようになっているため、充実したインタラクティブなウェブサイト、ゲーム、リモート デスクトップ ストリーミング、アプリケーション ストリーミングで、没入感のある全画面表示のエクスペリエンスを提供しようと努めています。そのためには、全画面モードのときに特別なキーとキーボード ショートカットにアクセスし、ナビゲーション、メニュー、ゲームで使用できるようにする必要があります。必要になる可能性のあるキーには、EscAlt+TabCmd+`Ctrl+N などがあります。

デフォルトでは、これらのキーはブラウザまたは基盤となるオペレーティング システムによって取得されるため、ウェブ アプリケーションでは利用できません。Keyboard Lock API を使用すると、ウェブサイトでホスト OS で許可されているすべての利用可能なキーを利用できるようになります(ブラウザの互換性をご覧ください)。

macOS Chrome のブラウザタブに Ubuntu Linux がストリーミングされる(全画面モードではまだ実行されていません)。
問題: ストリーミングされた Ubuntu Linux リモート デスクトップが全画面モードで実行されておらず、キーボード ロックがアクティブではないため、システムキーが macOS ホスト オペレーティング システムによってキャプチャされ、没入感が体験されていません。

Keyboard Lock API の使用

Keyboard API の Keyboard インターフェースは、物理キーボードからのキー押下の取得を切り替える関数と、ユーザーのキーボード レイアウトに関する情報を取得する関数を提供します。

前提条件

最新のブラウザには 2 種類の全画面モードがあります。Fullscreen API で JavaScript を起動した場合と、ユーザーがキーボード ショートカットで開始する場合です。Keyboard Lock API は、JavaScript で開始される全画面表示がアクティブな場合にのみ使用できます。JavaScript によって開始される全画面の例を次に示します。

await document.documentElement.requestFullscreen();

機能検出

次のパターンを使用して、Keyboard Lock API がサポートされているかどうかを確認できます。

if ('keyboard' in navigator && 'lock' in navigator.keyboard) {
  // Supported!
}

キーボードのロック

Keyboard インターフェースの lock() メソッドは、物理キーボードの一部またはすべてのキーのキー押下を有効にすると、Promise を返します。この方法では、基盤となるオペレーティング システムによってアクセス権が付与されているキーのみをキャプチャできます。lock() メソッドは、ロックするキーコードの配列を受け取ります。キーコードを指定しない場合、すべてのキーがロックされます。有効なキーコード値の一覧については、UI イベントの KeyboardEvent コード値の仕様をご覧ください。

すべての鍵のキャプチャ

次の例では、すべてのキーの押下をキャプチャします。

navigator.keyboard.lock();

特定のキーのキャプチャ

次の例では、WASD キーをキャプチャします。キーの押下に使用された修飾子に関係なく、これらのキーをキャプチャします。米国の QWERTY レイアウトの場合、"KeyW" を登録すると、WShift+WCtrl+WCtrl+Shift+W、および W を使用した他のすべてのキー修飾の組み合わせがアプリに送信されます。"KeyA""KeyS""KeyD" についても同様です。

await navigator.keyboard.lock([
  "KeyW",
  "KeyA",
  "KeyS",
  "KeyD",
]);

キーボード イベントを使用して、キャプチャしたキーの押下に応答できます。たとえば、次のコードでは onkeydown イベントを使用します。

document.addEventListener('keydown', (event) => {
  if ((event.code === 'KeyA') && !(event.ctrlKey || event.metaKey)) {
    // Do something when the 'A' key was pressed, but only
    // when not in combination with the command or control key.
  }
});

キーボードのロック解除

unlock() メソッドは、lock() メソッドでキャプチャされたすべてのキーをロック解除し、同期的に返します。

navigator.keyboard.unlock();

ドキュメントを閉じると、ブラウザは常に暗黙的に unlock() を呼び出します。

デモ

Glitch でデモを実行すると、Keyboard Lock API をテストできます。必ずソースコードを確認してください。下の [全画面表示を開始] ボタンをクリックすると、新しいウィンドウでデモが起動し、全画面モードに切り替わります。

セキュリティ上の考慮事項

この API の懸念事項の一つは、すべてのキーを取得するために使用され、(Fullscreen API および PointerLock API とともに)ユーザーがウェブページを閉じられなくなる可能性があることです。これを防ぐために、この仕様では、API からすべてのキーが要求された場合でも、ユーザーがキーボード ロックを終了する方法をブラウザに提供する必要があります。Chrome では、Esc キーを長く(2 秒間)押すとキーボード ロックが終了します。

謝辞

この記事は、Joe MedleyKayce Basques によってレビューされました。Keyboard Lock の仕様は、Gary KacmarcikJamie Walch によって執筆されています。ヒーロー画像(作成者: Ken SuarezUnsplash