ウィンドウ管理

ブラウザ外の 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 など、PWA のオリジンに戻るトークンを取得するために、ユーザーを別のオリジンの別の URL にリダイレクトする必要があります。

このような場合、アプリ内ブラウザは次のプロセスに沿って動作します。

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

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

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

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

新しいウィンドウを開く

デスクトップでは、同じ PWA の複数のウィンドウを開くことができます。同じ URL の 2 つのブラウザタブを開いている場合と同様に、各ウィンドウには同じ start_url の異なるナビゲーションが設定されます。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、画像を使用してタイトルバーをデザインできるとしたらどうでしょう。デスクトップ PWA 向けの Microsoft Edge と Google Chrome の試験運用版機能である Window Controls Overlay が役に立つ場合があります。

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

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

ウィンドウ管理

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

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

Window Management API を使用すると、PWA でそれ以上のことができます。

画面の詳細を取得する

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

返されたオブジェクトは、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 による完全な制御をご覧ください。