ウィンドウ管理

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

PWA ウィンドウ

PWA によって管理される独自のウィンドウで実行する場合、そのオペレーティング システムのすべてのウィンドウについて、次のような利点と責任があります。

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

ウィンドウの移動とサイズ変更

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

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

マニフェスト内で 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 イベントを使用して検出できます。ウィンドウの移動をキャプチャするイベントがないため、位置を頻繁にクエリすることをおすすめします。

他のサイトへのブラウジング

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

現在、どのブラウザでも、PWA がインストールされている場合、マニフェストの範囲外の URL にアクセスすると、PWA のブラウザ エンジンによってウィンドウのコンテキスト内でアプリ内ブラウザがレンダリングされます。

アプリ内ブラウザの機能は次のとおりです。

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

サポート範囲外の 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. エンジンは、PWA のメイン ウィンドウのナビゲーションを、アプリ内ブラウザでの認証サーバーの URL にリダイレクトします。
  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 の新しいアプリ内ブラウザが作成されます。URL が PWA のスコープ内にある場合でも、通常は外部ブラウジング エクスペリエンスはトリガーされません。

ウィンドウのタイトル

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

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

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

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

タブモード

タブモードと呼ばれる試験運用版機能を使用すると、PWA をウェブブラウザに似たタブベースのデザインにできます。この場合、ユーザーは同じ PWA から複数のタブを開くことができますが、すべて同じオペレーティング システム ウィンドウに関連付けられます。次の動画をご覧ください。

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

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

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

この機能の詳細については、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 に設定して、仮想キーボードを自分で閉じることをブラウザに伝えます。
  • navigator.virtualKeyboard のイベント geometrychange で、キーボードが表示されたり消えたりすることを把握する。
  • virtualkeyboardpolicy HTML 属性を使用して、ホスト要素の編集(contenteditable を使用)で仮想キーボード ポリシーを設定します。ポリシーを使用すると、auto 値を使用して仮想キーボードをブラウザで自動的に処理するか、manual 値を使用してスクリプトで処理するかを決定できます。
  • CSS 環境変数を使用して、keyboard-inset-heightkeyboard-inset-top などの仮想キーボードの外観に関する情報を取得する。

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

リソース