ウィンドウ管理

ブラウザ外の PWA は、独自のウィンドウを管理します。オペレーティング システム内のウィンドウを管理するための API と機能について説明します。

PWA によって管理され、独自のウィンドウで実行されるため、そのオペレーティング システムのウィンドウと同様の利点と責任があります。たとえば、次のようなものがあります。

  • Windows や ChromeOS などのマルチ ウィンドウ オペレーティング システムでウィンドウを移動したりサイズを変更したりする機能。
  • iPadOS の分割モードや Android の分割画面モードのように、他のアプリ ウィンドウと画面を共有する。
  • パソコンのドック、タスクバー、Alt+Tab メニュー、モバイル デバイスのマルチタスク ウィンドウ リストに表示されます。
  • ウィンドウを最小化したり、画面やデスクトップ間で移動したり、いつでも閉じたりできる。

ウィンドウを移動、サイズ変更する

PWA ウィンドウは、デスクトップ オペレーティング システムの画面上の任意の場所に任意のサイズで配置できます。デフォルトでは、ユーザーがインストール後に初めて PWA を開くと、PWA は現在の画面の割合でデフォルトのウィンドウ サイズを取得します。最大解像度は 1920x1080 で、画面の左上隅に配置されます。

ユーザーはウィンドウを移動したり、サイズを変更したりできます。ブラウザは最後に設定した設定を記憶します。ユーザーが次回アプリを開いたとき、ウィンドウは前回使用時のサイズと位置を保持します。

マニフェスト内で PWA の推奨サイズと位置を定義する方法はありません。JavaScript API を使用してのみ、ウィンドウの位置変更とサイズ変更を行うことができます。コードから、window オブジェクトの moveTo(x, y) 関数と resizeTo(x, y) 関数を使用して、独自の PWA ウィンドウを移動したりサイズを変更したりできます。

たとえば、PWA の読み込み時に PWA ウィンドウのサイズを変更して移動するには、次のコードを使用します。

document.addEventListener("DOMContentLoaded", event => {
   // we can move only if we are not in a browser's tab
   isBrowser = matchMedia("(display-mode: browser)").matches;
   if (!isBrowser) {
      window.moveTo(16, 16);
      window.resizeTo(800, 600);
   }
});

window.screen オブジェクトを使用して現在の画面サイズと位置をクエリできます。window オブジェクトの resize イベントを使用して、ウィンドウのサイズ変更を検出できます。ウィンドウの移動をキャプチャするイベントがないため、位置を頻繁にクエリするしかありません。

ウィンドウを絶対的に移動してサイズ変更する代わりに、moveBy()resizeBy() を使用して相対的に移動してサイズ変更できます。

他のサイトを閲覧する

ユーザーを PWA の範囲外の外部サイトに送信する場合は、標準の <a href> HTML 要素を使用します。location.href を使用するか、対応プラットフォームで新しいウィンドウを開きます。

マニフェストのスコープ外の URL にアクセスすると、PWA のブラウザ エンジンはウィンドウのコンテキスト内でアプリ内ブラウザをレンダリングします。

スコープ外の URL を閲覧しているときのデスクトップ PWA のアプリ内ブラウザ。

アプリ内ブラウザには次のような機能があります。

  • コンテンツの上に表示されます。
  • 静的なアドレスバーには、現在のオリジン、ウィンドウのタイトル、メニューが表示されます。通常、これらはマニフェストの theme_color でテーマ設定されます。
  • コンテキスト メニューから、その URL をブラウザで開くことができます。
  • ユーザーはブラウザを閉じるか、戻ることができます。

アプリ内ブラウザが画面に表示されている間、PWA は別のウィンドウに隠されているかのようにバックグラウンドで待機しています。

スタンドアロン PWA 内で範囲外の URL を閲覧しているときの iPhone のアプリ内ブラウザ。
スタンドアロン PWA 内で範囲外の URL を閲覧している場合の Android のアプリ内ブラウザ。

認可フロー

多くのウェブ認証と認可フローでは、OAuth 2.0 などを使用して、ユーザーを別のオリジンの別の URL にリダイレクトして、PWA のオリジンに戻るトークンを取得する必要があります。

このような場合、アプリ内ブラウザは次のプロセスに従います。

  1. ユーザーが PWA を開き、ログインをクリックします。
  2. PWA は、PWA の範囲外の URL にユーザーをリダイレクトするため、レンダリング エンジンは PWA 内でアプリ内ブラウザを開きます。
  3. ユーザーはいつでもアプリ内ブラウザをキャンセルして PWA に戻ることができます。
  4. ユーザーがアプリ内ブラウザにログインします。認証サーバーがユーザーを PWA オリジンにリダイレクトし、トークンを引数として送信します。
  5. アプリ内ブラウザは、PWA のスコープの一部である URL を検出すると、自動的に閉じます。
  6. エンジンは、メインの PWA ウィンドウのナビゲーションを、アプリ内ブラウザで認証サーバーがアクセスした URL にリダイレクトします。
  7. PWA はトークンを取得して保存し、PWA をレンダリングします。

ブラウザのナビゲーションを強制する

アプリ内ブラウザではなく、URL を使用してブラウザを強制的に開く場合は、<a href> 要素の _blank ターゲットを使用できます。これはパソコンの PWA でのみ機能します。モバイル デバイスでは、URL を指定してブラウザを開くオプションはありません。

function openBrowser(url) {
    window.open("url", "_blank", "");
}

新しいウィンドウを開く

パソコンでは、同じ PWA のウィンドウを複数開くことができます。各ウィンドウには、同じ start_url の異なるナビゲーションが表示されます。これは、同じ URL のブラウザタブを 2 つ開いた場合と同じです。PWA のメニューから、[ファイル]、[新しいウィンドウ] の順に選択できます。PWA コードから open() 関数を使用して新しいウィンドウを開くことができます。

function openNewWindow() {
    window.open("/", "new-window", "width=600,height=600");
}

同じインストール済み PWA で、デスクトップ オペレーティング システムで複数のウィンドウが開いている状態。

iOS または iPadOS の PWA ウィンドウ内で open() を呼び出すと、null が返され、ウィンドウは開きません。Android で新しいウィンドウを開くと、URL が PWA のスコープ内にある場合でも、その URL の新しいアプリ内ブラウザが作成されます。通常、これにより外部ブラウジング エクスペリエンスはトリガーされません。

ウィンドウのタイトル

<title> 要素は、主に SEO を目的として使用されていました。ブラウザタブ内のスペースが限られているためです。ブラウザから PWA のウィンドウに移動すると、タイトルバーのスペースをすべて使用できます。

タイトルバーの内容を定義できます。

  • HTML の <title> 要素に静的に配置します。
  • document.title 文字列プロパティをいつでも動的に変更できます。

デスクトップ PWA では、タイトルは不可欠であり、ウィンドウのタイトルバーで使用され、タスク マネージャーやマルチタスク選択で使用されることもあります。シングルページ アプリケーションの場合は、すべてのルートでタイトルを更新することをおすすめします。

タブモード

タブモードは、PWA をウェブブラウザのようなタブベースのデザインにできる試験運用版の機能です。この場合、ユーザーは同じ PWA で複数のタブを開くことができますが、すべて同じオペレーティング システム ウィンドウにまとめられます。

この試験運用版機能について詳しくは、PWA のタブ付きアプリケーション モードをご覧ください。

ウィンドウ コントロール オーバーレイ

<title> 要素または document.title プロパティの値を定義することで、ウィンドウのタイトルを変更できることはすでに説明しました。ただし、常に文字列値です。タイトルバーを HTML、CSS、画像でデザインできたらどうでしょうか?Microsoft Edge と Google Chrome のデスクトップ PWA の試験運用版機能である Window Controls Overlay が役立つ可能性があります。

この機能について詳しくは、PWA のタイトルバーのウィンドウ コントロール オーバーレイをカスタマイズするをご覧ください。

ウィンドウ コントロール オーバーレイを使用すると、タイトルバーにコンテンツをレンダリングできます。

ウィンドウ管理

複数の画面を使用する場合、ユーザーは利用可能なすべてのスペースを使用したいと考えています。次に例を示します。

  • Gimp などのマルチウィンドウ グラフィック エディタでは、さまざまな編集ツールを正確な位置に配置できます。
  • 仮想取引デスクでは、複数のウィンドウで市場の動向を表示できます。これらのウィンドウは、いずれも全画面モードで表示できます。
  • スライドショー アプリでは、内部のメイン画面にスピーカー ノートを表示し、外部のプロジェクターにプレゼンテーションを表示できます。

Window Management API を使用すると、PWA でこのような操作が可能になります。

画面の詳細を取得する

Window Management API に、接続された画面の不変配列として画面を含むオブジェクトを返す新しいメソッド window.getScreenDetails() が追加されます。現在の window.screen に対応する、ScreenDetails.currentScreen からアクセス可能なライブ オブジェクトもあります。

返されたオブジェクトは、screens 配列が変更されたときに screenschange イベントも発生させます。(個々の画面の属性が変更された場合は、この処理は行われません)。個々の画面(window.screen または screens 配列内の画面)も、属性が変更されると change イベントをトリガーします。

// Request an object with a screen objects
const screenDetails = await window.getScreenDetails();
screenDetails.screens[0].isPrimary;  // e.g. true
screenDetails.screens[0].isInternal;  // e.g. true
screenDetails.screens[0].label;  // e.g. 'Samsung Electric Company 28"'

// Access the live object corresponding to the current `window.screen`.
// The object is updated on cross-screen window placements or device changes.
screenDetails.currentScreen;
screenDetails.addEventListener('screenschange', function() {
 // NOTE: Does not fire on changes to attributes of individual screens.
  const screenCount = screenDetails.screens.length;
  const currentScreen screenDetails.currentScreen.id;
});

ユーザーまたはオペレーティング システムが PWA のウィンドウをある画面から別の画面に移動すると、画面の詳細オブジェクトから currentscreenchange イベントも発生します。

画面の wake lock

想像してみてください。キッチンでタブレットのレシピを見ながら調理している。食材の準備が完了しました。手が汚れてしまったので、次の手順を確認するためにデバイスに戻ります。みなさんに画面が真っ黒になった!Screen Wake Lock API を使用すると、PWA で画面が暗くなったり、スリープ状態になったり、ロックされたりするのを防ぐことができます。これにより、ユーザーは安心して停止、開始、離脱、復帰を行うことができます。

// Request a screen wake lock
const wakeLock = await navigator.wakeLock.request();

// Listen for wake lock release
wakeLock.addEventListener('release', () => {
 console.log(`Screen Wake Lock released: ${wakeLock.released}`);
});
// Manually release the wake lock
wakeLock.release();

仮想キーボード

スマートフォンやタブレットなどのタッチベースのデバイスでは、PWA のフォーム要素がフォーカスされているときにユーザーが入力できるように、仮想の画面キーボードが提供されます。

VirtualKeyboard API を使用すると、PWA は navigator.virtualKeyboard インターフェースを使用して、互換性のあるプラットフォームのキーボードをより詳細に制御できます。

  • navigator.virtualKeyboard.show()navigator.virtualKeyboard.hide() を使用して仮想キーボードの表示と非表示を切り替えます。
  • navigator.virtualKeyboard.overlaysContenttrue に設定して、仮想キーボードを自分で閉じていることをブラウザに伝えます。
  • geometrychange イベントを使用して、キーボードの表示と非表示のタイミングを把握します。
  • virtualkeyboardpolicy HTML 属性を使用して、contenteditableauto または manual に設定することで、ホスト要素の編集時に仮想キーボードのポリシーを設定します。ポリシーを使用すると、仮想キーボードをブラウザで自動的に処理するか(auto)、スクリプトで処理するか(manual)を決定できます。
  • CSS 環境変数を使用して、keyboard-inset-heightkeyboard-inset-top などの仮想キーボードの外観に関する情報を取得します。

この API の詳細については、VirtualKeyboard API による完全な制御をご覧ください。