ウィンドウ管理

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

PWA ウィンドウ

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 イベントを使用して検出できます。ウィンドウの移動をキャプチャするイベントはないため、位置を頻繁にクエリする方法があります。

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

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

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

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

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

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

ウィンドウのタイトル

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

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

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

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

タブモード

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

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

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

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

この機能の詳細については、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 による完全な制御をご覧ください。

リソース