Window Management API を使用して複数のディスプレイを管理する

接続されているディスプレイに関する情報を取得し、それらのディスプレイに対してウィンドウの位置を調整します。

ウィンドウ管理 API

Window Management API を使用すると、マシンに接続されているディスプレイを列挙できる 特定の画面にウィンドウを配置できます

推奨されるユースケース

この API を使用するサイトには、たとえば次のようなものがあります。

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

Window Management API の使用方法

問題

ウィンドウを制御するための Window.open() は、残念ながら 追加の画面を認識しません。API の一部の機能は少し古いようですが、 windowFeatures DOMString パラメータはそれにもかかわらず、長年にわたって有効に機能してきました。ウィンドウの position では、 座標を lefttop(またはそれぞれ screenXscreenY)として指定し、目的の size: widthheight(またはそれぞれ innerWidthinnerHeight)。たとえば、 400×300 のウィンドウを左から 50 ピクセル、上から 50 ピクセルに配置します。これが、 次のコマンドを使用できます。

const popup = window.open(
  'https://example.com/',
  'My Popup',
  'left=50,top=50,width=400,height=300',
);

現在の画面に関する情報は、 window.screen プロパティは、 Screen オブジェクトを返します。これが 出力を MacBook Pro 13 インチ:

window.screen;
/* Output from my MacBook Pro 13″:
  availHeight: 969
  availLeft: 0
  availTop: 25
  availWidth: 1680
  colorDepth: 30
  height: 1050
  isExtended: true
  onchange: null
  orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
  pixelDepth: 30
  width: 1680
*/

テクノロジー業界で働くほとんどの人と同じように、新しい現実の働き方に適応し、 個人ホームオフィスです私の顔は下の写真のようです(ご興味のある方は、 設定に関する詳細情報)。 MacBook の隣にある iPad は、 Sidecar。必要なときはいつでも、 iPad を第 2 の画面に。

<ph type="x-smartling-placeholder">
</ph> 2 つの椅子に置かれた学校のベンチ。学校のベンチの上部には、ノートパソコンとそれを取り囲む 2 台の iPad を支える靴収納がある。
マルチスクリーン設定。

大きな画面を活用したい場合は、 上記のコードサンプルを 2 番目の画面に配置します。する 例:

popup.moveTo(2500, 50);

2 つ目の画面の寸法を知る方法はないため、これは大まかな推測です。情報 window.screen では、内蔵画面のみがカバーされ、iPad 画面はカバーされません。報告された width 1680 ピクセルであるため、2500 ピクセルに移動すると場合に MacBook の右側に置いてあるとわかったので、iPad にウィンドウを表示します。方法 一般的なケースで可能か?答えを推測するよりよい方法があります。こうすることで、 Window Management API です。

機能検出

Window Management API がサポートされているかどうかを確認するには、次のコマンドを使用します。

if ('getScreenDetails' in window) {
  // The Window Management API is supported.
}

window-management 権限

Window Management API を使用する前に、ユーザーに許可を求める必要があります。 window-management 権限は、 Permissions API を使用しています。

let granted = false;
try {
  const { state } = await navigator.permissions.query({ name: 'window-management' });
  granted = state === 'granted';
} catch {
  // Nothing.
}

古い名前と新しい権限名のブラウザが使用されている間は、以下の例のように、権限をリクエストするときに防御コードを使用するようにしてください。

async function getWindowManagementPermissionState() {
  let state;
  // The new permission name.
  try {
    ({ state } = await navigator.permissions.query({
      name: "window-management",
    }));
  } catch (err) {
    return `${err.name}: ${err.message}`;
  }
  return state;
}

document.querySelector("button").addEventListener("click", async () => {
  const state = await getWindowManagementPermissionState();
  document.querySelector("pre").textContent = state;
});

ブラウザ できる のメソッドのいずれかを最初に使用しようとしたときに、権限プロンプトを動的に表示するかを選択します。 説明します。詳しくは以下をご覧ください。

window.screen.isExtended プロパティ

複数の画面がデバイスに接続されているかどうかを確認するには、 window.screen.isExtended プロパティ。true または false が返されます。今回の設定では、true が返されます。

window.screen.isExtended;
// Returns `true` or `false`.

getScreenDetails() メソッド

現在の設定がマルチスクリーンだとわかったので Window.getScreenDetails() を使用した 2 番目の画面。この関数を呼び出すと、権限プロンプトが表示され、 サイトが開いてウィンドウを配置するかどうかを尋ねられます。この関数は Promise を返します。 ScreenDetailed オブジェクトで解決されます。iPad を接続した MacBook Pro 13 では、 これには、2 つの ScreenDetailed オブジェクトを含む screens フィールドが含まれます。

await window.getScreenDetails();
/* Output from my MacBook Pro 13″ with the iPad attached:
{
  currentScreen: ScreenDetailed {left: 0, top: 0, isPrimary: true, isInternal: true, devicePixelRatio: 2, …}
  oncurrentscreenchange: null
  onscreenschange: null
  screens: [{
    // The MacBook Pro
    availHeight: 969
    availLeft: 0
    availTop: 25
    availWidth: 1680
    colorDepth: 30
    devicePixelRatio: 2
    height: 1050
    isExtended: true
    isInternal: true
    isPrimary: true
    label: "Built-in Retina Display"
    left: 0
    onchange: null
    orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
    pixelDepth: 30
    top: 0
    width: 1680
  },
  {
    // The iPad
    availHeight: 999
    availLeft: 1680
    availTop: 25
    availWidth: 1366
    colorDepth: 24
    devicePixelRatio: 2
    height: 1024
    isExtended: true
    isInternal: false
    isPrimary: false
    label: "Sidecar Display (AirPlay)"
    left: 1680
    onchange: null
    orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
    pixelDepth: 24
    top: 0
    width: 1366
  }]
}
*/

接続されているスクリーンに関する情報は、screens 配列で確認できます。指標の値がどのように iPad の left1680(内蔵ディスプレイの width)から始まります。この 画面が論理的にどのように配置されているか(互いに並べて、上に表示されている 相互に通信できません。各スクリーンが isInternal かどうかを示すデータもあります。 それが isPrimary であるかどうかを判定します。組み込みの画面は メイン画面ではない場合があります

currentScreen フィールドは、現在の window.screen に対応するライブ オブジェクトです。オブジェクト クロススクリーンのウィンドウ プレースメントやデバイスが変更されたときに更新されます。

screenschange イベント

今不足しているのが、画面設定が変更されたときを検出する方法だけです。新しいイベント、 screenschange は、まさにそのとおりです。画面コンステレーションが変更されると起動されます。(注: 「スクリーン」イベント名に複数形を使用します)。つまり、新しい画面やイベントが発生したときにイベントが 既存の画面が(サイドカーの場合、物理的または仮想的に)電源に接続されているか、電源から外されていること。

なお、新しい画面の詳細を非同期で調べる必要があります(screenschange イベント)。 そのデータは提供されません。画面の詳細を検索するには、キャッシュに保存された Screens インターフェース。

const screenDetails = await window.getScreenDetails();
let cachedScreensLength = screenDetails.screens.length;
screenDetails.addEventListener('screenschange', (event) => {
  if (screenDetails.screens.length !== cachedScreensLength) {
    console.log(
      `The screen count changed from ${cachedScreensLength} to ${screenDetails.screens.length}`,
    );
    cachedScreensLength = screenDetails.screens.length;
  }
});

currentscreenchange イベント

現在の画面(つまりライブ オブジェクトの値)の変更のみに関心がある場合 currentScreen)、currentscreenchange イベントをリッスンできます。

const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
  const details = screenDetails.currentScreen;
  console.log('The current screen has changed.', event, details);
});

change イベント

最後に、コンクリート画面への変更のみに関心がある場合は、その画面の変更を change イベント。

const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
  console.log('The first screen has changed.', event, firstScreen);
});

新しい全画面表示オプション

これまでは、要素が全画面モードで表示されるようにリクエストするには、次のように適切な名前を付けた requestFullScreen() メソッドを呼び出します。このメソッドは options パラメータを受け取ります。このパラメータには、 FullscreenOptions。ここまで、 その唯一のプロパティが navigationUI。 Window Management API では、新たに screen プロパティが追加されています。これにより、 全画面表示を開始する画面を指定しますたとえば、メイン画面を 1 つのスペースに fullscreen:

try {
  const primaryScreen = (await getScreenDetails()).screens.filter((screen) => screen.isPrimary)[0];
  await document.body.requestFullscreen({ screen: primaryScreen });
} catch (err) {
  console.error(err.name, err.message);
}

ポリフィル

Window Management API をポリフィルすることはできませんが、その形状をシミングすることで、 新しい API に対してのみコーディングできます。

if (!('getScreenDetails' in window)) {
  // Returning a one-element array with the current screen,
  // noting that there might be more.
  window.getScreenDetails = async () => [window.screen];
  // Set to `false`, noting that this might be a lie.
  window.screen.isExtended = false;
}

API のその他の側面、つまり、さまざまな画面変更イベントと、screen プロパティ FullscreenOptions は単に起動しないか、何も通知せずに無視します 対応していないブラウザもあります。

デモ

私みたいな方がいれば、さまざまなニュース メディアの 保護します。(現実には、このわく星が大好きなからといって、あまりそう思わないんですが、 ここでは例として、 did.)所有する暗号通貨を追跡するために、 生活のあらゆる場面で市場を観ることができます。たとえば、 1 画面設定だけです。

<ph type="x-smartling-placeholder">
</ph> ベッドの端に設置された大型のテレビ画面。著者の脚の一部が見えている。画面には、偽の暗号通貨取引デスクが映っている。
リラックスして市場を眺めている。

暗号資産についてですから、市場はいつでも慌ただしくなります。こうなったら、 マルチスクリーン環境が整っているデスクに向かいます任意の通貨のウィンドウをクリックすると 反対側の画面の全画面表示で細部をすばやく確認できます。以下の最近の写真: 過去 YCY の流血のときに撮影された私の写真です。気に入った まったく不意打ちで放置された 顔に手を当てて

<ph type="x-smartling-placeholder">
</ph> 偽の暗号通貨取引デスクを見つめながら、パニックした顔に手を当てた作成者。
YCY の流血を目撃するパニッキー。

以下に埋め込まれたデモを試すか、不具合のあるソースコードを確認できます。

セキュリティと権限

Chrome チームは、コア 強力なウェブ プラットフォーム機能へのアクセスの制御で定義されている原則 あらゆる側面に関与しています。Window Management API は、 デバイスに接続されている画面に関する新しい情報を取得できるため、デバイスのフィンガープリント サーフェスが 特に、複数の画面が常にデバイスに接続されているユーザーがいるためです。1 つ このプライバシーに関する懸念を緩和するために、公開される画面プロパティは必要最小限に制限されている 一般的なプレースメントのユースケースに 適していますサイトをマルチスクリーン対応にするには、ユーザーの権限が必要です 他の画面にウィンドウを配置することもできます詳細な画面ラベルが返されますが ブラウザは、より簡潔なもの(または空のラベル)を返すことがあります。

ユーザー コントロール

ユーザーは露出を完全に制御できます。招待に応じるか拒否するかを Google Chat のサイト情報機能を使用して、以前に許可した許可を取り消すことができます。 アクセスできます。

エンタープライズ コントロール

Chrome Enterprise ユーザーは、次のように Window Management API のいくつかの機能を制御できます。 このモジュールの関連するセクションに ポリシーの最小単位グループ 設定。

透明性

Window Management API を使用する権限が付与されているかどうかは、 ブラウザのサイト情報で公開されます。また、Permissions API を介してクエリを実行することもできます。

権限の永続性

ブラウザは権限の付与を永続化します。ブラウザのサイトから権限を取り消すことができます 情報です。

フィードバック

Chrome チームでは、Window Management API の感想をお聞かせください。

API 設計について教えてください

API について、想定どおりに機能していないものはありますか?あるいは不足しているメソッドがあるか アイデアを実現するために必要なものやプロパティは?セキュリティに関する質問またはコメント どうすればよいでしょうか。

  • 対応する GitHub リポジトリで仕様に関する問題を報告するか、既存の あります。

実装に関する問題を報告する

Chrome の実装にバグは見つかりましたか?または、実装が仕様と異なっていますか?

  • new.crbug.com でバグを報告します。できるだけ多くの詳細を 簡単な再現手順を実行して、Blink>Screen>MultiScreen を [コンポーネント] ボックス。Glitch は、すばやく簡単に再現を共有するのに最適です。

API のサポートを表示する

Window Management API を使用する予定はありますか。皆様の公開サポートは、Chrome を 他のブラウザ ベンダーがそれらの機能をサポートすることの重要性を説明します。

  • どのように使用する予定なのかを WICG の談話スレッドで共有してください。
  • ハッシュタグを使用して @ChromiumDev にツイートしてください #WindowManagement、 どこで、どのように使用されているかをお知らせください。
  • 他のブラウザ ベンダーに API の実装を依頼する。

関連情報

謝辞

Window Management API 仕様の編集 Victor Costan Joshua BellMike Wasserman API の実装 Mike Wasserman Adrienne Walker。この記事をレビューしたユーザー: Joe MedleyFrançois Beaufort、 および Kayce BasquesLaura Torrent Puig 氏に写真を提供してくださいました。