ウィンドウ管理

ブラウザ外の 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 などを使用して、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 のメニューから [File] > [New window] の順に選択し、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 の新しい試験運用版機能です。

この機能について詳しくは、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].pointerTypes;  // e.g. ["touch"]
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 を使用したフル コントロールをご覧ください。

リソース