การจัดการจอแสดงผลหลายรายการด้วย Window Management API

ดูข้อมูลเกี่ยวกับจอแสดงผลที่เชื่อมต่อและจัดตำแหน่งหน้าต่างที่เกี่ยวข้องกับจอแสดงผลเหล่านั้น

API การจัดการหน้าต่าง

Window Management API ให้คุณแจกแจงการแสดงผลที่เชื่อมต่อกับเครื่องได้ และเพื่อวางหน้าต่าง บนหน้าจอที่ต้องการ

Use Case ที่แนะนำ

ตัวอย่างเว็บไซต์ที่อาจใช้ API นี้ ได้แก่

  • เครื่องมือแก้ไขกราฟิกแบบหลายหน้าต่าง Gimp สามารถวางตำแหน่ง ของเครื่องมือแก้ไขในหน้าต่างที่อยู่ในตำแหน่งที่ถูกต้อง
  • โต๊ะซื้อขายเสมือนจริงสามารถแสดงแนวโน้มตลาดในหน้าต่างหลายหน้าต่าง ซึ่งสามารถดูได้ใน โหมดเต็มหน้าจอ
  • แอปภาพสไลด์สามารถแสดงบันทึกของผู้บรรยายในหน้าจอหลักภายในและงานนำเสนอใน โปรเจ็กเตอร์ภายนอก

วิธีใช้ Window Management API

ปัญหา

วิธีการควบคุมกรอบเวลาที่ผ่านกาลเวลา Window.open() ขออภัย ไม่รู้ว่ามีหน้าจอเพิ่มเติมเข้ามา แม้ว่า API นี้จะดูเก่าเกินไปในบางแง่มุม เช่น windowFeatures DOMString แต่ยังคงใช้งานได้ดีตลอดหลายปีที่ผ่านมา หากต้องการระบุกรอบเวลา position คุณสามารถส่ง พิกัดเป็น left และ top (หรือ screenX และ screenY ตามลำดับ) และส่งผ่านค่าที่ต้องการ ขนาดเป็น width และ height (หรือ innerWidth และ innerHeight ตามลำดับ) เช่น หากต้องการเปิด หน้าต่างขนาด 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
*/

เช่นเดียวกับคนส่วนใหญ่ที่ทำงานในแวดวงเทคโนโลยี ฉันต้องปรับตัวให้เข้ากับความเป็นจริงที่ทำงานใหม่ๆ และเตรียม สำนักงานส่วนตัวที่บ้าน เหมืองดูเหมือนในรูปภาพด้านล่าง (ถ้าคุณสนใจ คุณสามารถอ่าน รายละเอียดทั้งหมดเกี่ยวกับการตั้งค่าของฉัน) iPad ที่อยู่ถัดจาก MacBook ของฉันเชื่อมต่อกับแล็ปท็อปผ่าน Sidecar ดังนั้น เมื่อใดก็ตามที่ผมต้องการ ก็สามารถเปิด iPad ไปยังหน้าจอที่ 2

วันที่ ม้านั่งโรงเรียนบนเก้าอี้ 2 ตัว บนม้านั่งของโรงเรียนมีกล่องรองเท้าที่รองรับแล็ปท็อปและ iPad 2 เครื่องที่อยู่รอบๆ
การตั้งค่าสำหรับหลายหน้าจอ

ถ้าต้องการใช้ประโยชน์จากหน้าจอที่ใหญ่ขึ้น ฉันสามารถวางป๊อปอัปจาก ตัวอย่างโค้ดด้านบนไปยังหน้าจอที่ 2 ฉันเอง ดังนี้

popup.moveTo(2500, 50);

นี่คือการคาดเดาคร่าวๆ เนื่องจากไม่มีวิธีที่จะทราบขนาดของหน้าจอที่ 2 ข้อมูล จาก window.screen ครอบคลุมเฉพาะหน้าจอในตัว แต่ไม่ครอบคลุมหน้าจอ iPad width ที่รายงาน ของหน้าจอในตัวคือ 1680 พิกเซล ดังนั้นการย้ายไปยัง 2500 พิกเซลอาจเพื่อเปลี่ยนการตั้งค่า iPad เนื่องจากฉันทราบว่าแอปอยู่ทางด้านขวาของ MacBook อย่างไร ในกรณีทั่วไปได้ไหม ปรากฏว่ามีวิธีที่ดีกว่าการเดา วิธีนี้จะทำให้ Window Management API

การตรวจหาฟีเจอร์

หากต้องการตรวจสอบว่าระบบรองรับ Window Management API หรือไม่ ให้ใช้รายการต่อไปนี้

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

สิทธิ์ window-management

ฉันต้องขออนุญาตจากผู้ใช้ก่อนจึงจะใช้ Window Management API ได้ คุณจะค้นหาสิทธิ์ window-management ได้ด้วย 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;
});

เบราว์เซอร์ ได้ เลือกแสดงข้อความแจ้งสิทธิ์แบบไดนามิกในครั้งแรกที่ใช้วิธีการ API ใหม่ อ่านต่อเพื่อดูข้อมูลเพิ่มเติม

พร็อพเพอร์ตี้ window.screen.isExtended

เพื่อดูว่ามีการเชื่อมต่อหน้าจอกับอุปกรณ์มากกว่า 1 หน้าจอไหม ฉันจึงเข้าถึง พร็อพเพอร์ตี้ window.screen.isExtended ผลการค้นหาจะแสดง true หรือ false สำหรับการตั้งค่าของฉัน จะแสดง true

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

เมธอด getScreenDetails()

เมื่อเราทราบว่าการตั้งค่าปัจจุบันสำหรับหลายหน้าจอ ฉันสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับ หน้าจอที่ 2 โดยใช้ Window.getScreenDetails() การเรียกฟังก์ชันนี้จะแสดงข้อความแจ้งสิทธิ์ที่ จะถามฉันว่าเว็บไซต์สามารถเปิดและวางหน้าต่างบนหน้าจอของฉันได้หรือไม่ ฟังก์ชันจะแสดงผลลัพธ์ ซึ่งแก้ไขด้วยออบเจ็กต์ ScreenDetailed ใน MacBook Pro 13 ที่มี iPad ที่เชื่อมต่ออยู่ ซึ่งรวมถึงช่อง screens ที่มีออบเจ็กต์ ScreenDetailed 2 รายการ ได้แก่

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 สังเกตว่าค่าของ left สำหรับ iPad เริ่มต้นที่ 1680 ซึ่งเป็น width ของจอแสดงผลในตัว ช่วงเวลานี้ ทำให้ฉันสามารถกำหนดวิธีจัดเรียงหน้าจออย่างสมเหตุสมผลได้ (นอกเหนือจาก ซึ่งกันและกัน เป็นต้น) ตอนนี้แต่ละหน้าจอมีข้อมูลให้แสดงหรือไม่ว่าเป็นแบบ isInternal และจะเป็น isPrimary หรือไม่ โปรดทราบว่าหน้าจอในตัว ไม่จำเป็นต้องเป็นหน้าจอหลัก

ฟิลด์ currentScreen เป็นออบเจ็กต์ที่เผยแพร่อยู่ซึ่งสัมพันธ์กับ window.screen ปัจจุบัน วัตถุ มีการอัปเดตเมื่อตำแหน่งหน้าต่างข้ามหน้าจอหรือการเปลี่ยนแปลงของอุปกรณ์

เหตุการณ์ screenschange

สิ่งเดียวที่ขาดหายไปตอนนี้คือวิธีตรวจหาเมื่อการตั้งค่าหน้าจอของฉันเปลี่ยนแปลง กิจกรรมใหม่ screenschange ทำหน้าที่ดังกล่าวอย่างเจาะจง นั่นคือเริ่มทำงานเมื่อมีการแก้ไขกลุ่มภาพหน้าจอ (ประกาศ "หน้าจอ" เป็นพหูพจน์ในชื่อเหตุการณ์) ซึ่งหมายความว่าเหตุการณ์จะเริ่มทำงานเมื่อมีหน้าจอใหม่หรือ หน้าจอที่มีอยู่จะเสียบปลั๊กหรือไม่ได้เสียบปลั๊กไว้ (ไม่ว่าจะจริงๆ หรือแบบเสมือนในกรณีของ Sidecar)

โปรดทราบว่าคุณต้องค้นหารายละเอียดหน้าจอใหม่แบบอะซิงโครนัส นั่นคือเหตุการณ์ 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 ใหม่เพื่อให้คุณระบุ หน้าจอที่จะเริ่มมุมมองแบบเต็มหน้าจอ เช่น ถ้าต้องการทำให้เป็นหน้าจอหลัก เต็มหน้าจอ:

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.) เพื่อติดตามคริปโตเคอเรนซีที่ฉันเป็นเจ้าของ ฉันได้พัฒนาเว็บแอปที่ช่วยให้ฉัน ดูตลาดในทุกสถานการณ์ในชีวิต เช่น นอนสบายๆ ที่ผมมี การตั้งค่าหน้าจอเดียว

วันที่ หน้าจอทีวีขนาดใหญ่ที่ปลายเตียงซึ่งมองเห็นขาของผู้เขียนบางส่วน บนหน้าจอแสดงโต๊ะซื้อขายสกุลเงินคริปโตปลอม
พักผ่อนหย่อนใจและดูตลาด

นี่เป็นเรื่องคริปโต ตลาดเริ่มมีความวุ่นวายได้ตลอดเวลา หากสิ่งนี้เกิดขึ้น เราจะดำเนินการ ย้ายไปอยู่ที่โต๊ะของผม ซึ่งผมตั้งค่าไว้สำหรับหลายหน้าจอ ฉันสามารถคลิกที่หน้าต่างของสกุลเงินใดก็ได้ และ ดูรายละเอียดทั้งหมดอย่างรวดเร็วในมุมมองแบบเต็มหน้าจอบนหน้าจอตรงข้าม ด้านล่างนี้คือรูปภาพล่าสุดของ ฉันถ่ายในระหว่างการนองเลือด YCY ครั้งล่าสุด ตามติดฉัน เพิกเฉยอย่างยิ่งและปล่อยให้ฉัน เอามือปะหน้า

วันที่ ผู้เขียนใช้มือจับหน้าตื่นตระหนกซึ่งจ้องมองไปที่โต๊ะซื้อขายสกุลเงินคริปโตปลอม
Panicky เป็นพยานเห็นการนองเลือด YCY

คุณอาจเล่นกับการสาธิตที่ฝังอยู่ด้านล่าง หรือดูซอร์สโค้ดในข้อบกพร่องก็ได้

ความปลอดภัยและสิทธิ์

ทีม Chrome ได้ออกแบบและติดตั้ง Window Management API โดยใช้ หลักการที่กำหนดไว้ในการควบคุมการเข้าถึงฟีเจอร์แพลตฟอร์มเว็บที่มีประสิทธิภาพ ซึ่งรวมถึงการควบคุมของผู้ใช้ ความโปร่งใส และการยศาสตร์ Window Management API แสดง ข้อมูลใหม่เกี่ยวกับหน้าจอที่เชื่อมต่อกับอุปกรณ์ ซึ่งเป็นการเพิ่มพื้นผิวการเก็บลายนิ้วมือของ ผู้ใช้ โดยเฉพาะผู้ใช้ที่มีหน้าจอหลายหน้าจอเชื่อมต่อกับอุปกรณ์ของตนอย่างต่อเนื่อง เป็นหนึ่งใน การลดข้อกังวลด้านความเป็นส่วนตัวนี้ทำให้คุณสมบัติของหน้าจอที่มีการเผยให้เห็นถูกจำกัดให้เหลือน้อยที่สุดเท่าที่จำเป็น สำหรับกรณีการใช้งานตำแหน่งที่พบบ่อย เว็บไซต์ต้องมีการให้สิทธิ์จากผู้ใช้เพื่อเข้าถึงหลายหน้าจอ ข้อมูลและวางหน้าต่างบนหน้าจออื่นๆ ขณะที่ Chromium แสดงป้ายกำกับหน้าจอโดยละเอียด เบราว์เซอร์สามารถแสดงผลที่ไม่ค่อยสื่อความหมาย (หรือแม้แต่ป้ายกำกับว่างเปล่า)

การควบคุมของผู้ใช้

ผู้ใช้ควบคุมการมองเห็นการตั้งค่าของตนเองได้โดยสมบูรณ์ ผู้รับสามารถยอมรับหรือปฏิเสธ คำขอสิทธิ์ และเพิกถอนการอนุญาตที่เคยให้ไว้ผ่านทางคุณลักษณะข้อมูลไซต์ใน เบราว์เซอร์

การควบคุมขององค์กร

ผู้ใช้ 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 Discourse
  • ส่งทวีตไปยัง @ChromiumDev โดยใช้แฮชแท็ก #WindowManagement และ โปรดแจ้งให้เราทราบว่าคุณใช้ผลิตภัณฑ์นี้ที่ไหนและอย่างไร
  • สอบถามผู้ให้บริการเบราว์เซอร์รายอื่นๆ เพื่อใช้ API นี้

ลิงก์ที่มีประโยชน์

กิตติกรรมประกาศ

มีการแก้ไขข้อกำหนดของ Window Management API โดย Victor Costan Joshua Bell และ Mike Wasserman API นี้มีการใช้งานโดย Mike Wasserman และ Adrienne Walker บทความนี้ได้รับการตรวจสอบโดย Joe Medley, François Beaufort และ Kayce Basques ขอขอบคุณ Laura Torrent Puig สำหรับรูปภาพ