Mendapatkan informasi tentang layar yang terhubung dan memosisikan jendela relatif terhadap layar tersebut.
Window Management API
Window Management API memungkinkan Anda menghitung layar yang terhubung ke komputer dan menempatkan jendela di layar tertentu.
Kasus penggunaan yang disarankan
Contoh situs yang dapat menggunakan API ini meliputi:
- Editor grafis multi-aplikasi seperti Gimp dapat menempatkan berbagai alat pengeditan di jendela yang diposisikan secara akurat.
- Virtual trading desk dapat menampilkan tren pasar di beberapa jendela yang dapat dilihat dalam mode layar penuh.
- Aplikasi slideshow dapat menampilkan catatan pembicara di layar utama internal dan presentasi di proyektor eksternal.
Cara menggunakan Window Management API
Permasalahan
Pendekatan yang telah teruji waktu untuk mengontrol jendela,
Window.open()
, sayangnya tidak mengetahui layar tambahan. Meskipun beberapa aspek API ini tampak sedikit kuno, seperti parameter
windowFeatures
DOMString
, API ini telah melayani kami dengan baik selama bertahun-tahun. Untuk menentukan
posisi jendela, Anda dapat meneruskan
koordinat sebagai left
dan top
(atau screenX
dan screenY
masing-masing) serta meneruskan
ukuran yang diinginkan sebagai
width
dan height
(atau innerWidth
dan innerHeight
masing-masing). Misalnya, untuk membuka jendela
400×300 pada 50 piksel dari kiri dan 50 piksel dari atas, berikut kode yang dapat Anda
gunakan:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
Anda bisa mendapatkan informasi tentang layar saat ini dengan melihat properti window.screen
, yang menampilkan objek Screen
. Berikut adalah
output di MacBook Pro 13″ saya:
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
*/
Seperti kebanyakan orang yang bekerja di bidang teknologi, saya harus beradaptasi dengan realitas kerja baru dan menyiapkan kantor pribadi di rumah. Tampilan saya seperti pada foto di bawah (jika tertarik, Anda dapat membaca detail lengkap tentang penyiapan saya). iPad di samping MacBook saya terhubung ke laptop melalui Sidecar, jadi kapan pun saya perlu, saya dapat dengan cepat mengubah iPad menjadi layar kedua.

Jika ingin memanfaatkan layar yang lebih besar, saya dapat menempatkan pop-up dari contoh kode di atas ke layar kedua. Saya melakukannya seperti ini:
popup.moveTo(2500, 50);
Ini adalah perkiraan kasar, karena tidak ada cara untuk mengetahui dimensi layar kedua. Info
dari window.screen
hanya mencakup layar bawaan, bukan layar iPad. width
layar bawaan yang dilaporkan adalah 1680
piksel, jadi beralih ke 2500
piksel mungkin akan memindahkan
jendela ke iPad, karena saya tahu bahwa jendela tersebut berada di sebelah kanan MacBook saya. Bagaimana
cara melakukannya dalam kasus umum? Ternyata, ada cara yang lebih baik daripada menebak. Cara tersebut adalah
Window Management API.
Deteksi fitur
Untuk memeriksa apakah Window Management API didukung, gunakan:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
Izin window-management
Sebelum dapat menggunakan Window Management API, saya harus meminta izin pengguna untuk melakukannya.
Izin window-management
dapat dikueri dengan
Permissions API seperti berikut:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
Saat browser dengan nama izin lama dan baru sedang digunakan, pastikan untuk menggunakan kode defensif saat meminta izin, seperti dalam contoh di bawah.
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;
});
Browser dapat memilih untuk menampilkan dialog izin secara dinamis pada upaya pertama untuk menggunakan salah satu metode API baru. Baca terus untuk mempelajari lebih lanjut.
Properti window.screen.isExtended
Untuk mengetahui apakah lebih dari satu layar terhubung ke perangkat saya, saya mengakses properti
window.screen.isExtended
. Fungsi ini menampilkan true
atau false
. Untuk penyiapan saya, metode ini menampilkan true
.
window.screen.isExtended;
// Returns `true` or `false`.
Metode getScreenDetails()
Sekarang setelah mengetahui bahwa penyiapan saat ini adalah multi-layar, saya bisa mendapatkan informasi selengkapnya tentang layar kedua menggunakan Window.getScreenDetails()
. Memanggil fungsi ini akan menampilkan dialog izin yang
menanyakan apakah situs dapat membuka dan menempatkan jendela di layar saya. Fungsi ini menampilkan promise
yang diselesaikan dengan objek ScreenDetailed
. Di MacBook Pro 13 saya dengan iPad yang terhubung,
ini mencakup kolom screens
dengan dua objek ScreenDetailed
:
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
}]
}
*/
Informasi tentang layar yang terhubung tersedia di array screens
. Perhatikan bagaimana nilai
left
untuk iPad dimulai dari 1680
, yang persis sama dengan width
layar bawaan. Hal ini memungkinkan saya menentukan secara persis bagaimana susunan layar secara logis (berdampingan, di atas satu sama lain, dll.). Sekarang ada juga data untuk setiap layar guna menunjukkan apakah layar tersebut merupakan isInternal
dan apakah layar tersebut merupakan isPrimary
. Perhatikan bahwa layar bawaan
tidak harus menjadi layar utama.
Kolom currentScreen
adalah objek aktif yang sesuai dengan window.screen
saat ini. Objek diperbarui pada penempatan jendela lintas layar atau perubahan perangkat.
Acara screenschange
Satu-satunya hal yang belum ada sekarang adalah cara untuk mendeteksi saat konfigurasi layar saya berubah. Peristiwa baru, screenschange
, melakukan hal itu: peristiwa ini diaktifkan setiap kali konstelasi layar diubah. (Perhatikan
bahwa "screens" berbentuk jamak dalam nama peristiwa.) Artinya, peristiwa dipicu setiap kali layar baru atau layar yang sudah ada (secara fisik atau virtual dalam kasus Sidecar) dicolokkan atau dicabut.
Perhatikan bahwa Anda perlu mencari detail layar baru secara asinkron, peristiwa screenschange
itu sendiri tidak memberikan data ini. Untuk mencari detail layar, gunakan objek aktif dari antarmuka Screens
yang di-cache.
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;
}
});
Acara currentscreenchange
Jika hanya tertarik dengan perubahan pada layar saat ini (yaitu, nilai objek live
currentScreen
), saya dapat memproses peristiwa currentscreenchange
.
const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
const details = screenDetails.currentScreen;
console.log('The current screen has changed.', event, details);
});
Acara change
Terakhir, jika hanya tertarik dengan perubahan pada layar tertentu, saya dapat memproses peristiwa
change
layar tersebut.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Opsi layar penuh baru
Hingga saat ini, Anda dapat meminta agar elemen ditampilkan dalam mode layar penuh melalui metode
requestFullScreen()
yang dinamai dengan tepat. Metode ini menggunakan parameter options
tempat Anda dapat meneruskan
FullscreenOptions
. Sejauh ini,
satu-satunya propertinya adalah
navigationUI
.
Window Management API menambahkan properti screen
baru yang memungkinkan Anda menentukan
layar mana yang akan memulai tampilan layar penuh. Misalnya, jika Anda ingin membuat layar utama
layar penuh:
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);
}
Polyfill
Window Management API tidak dapat diisi dengan polyfill, tetapi Anda dapat membuat shim bentuknya sehingga Anda dapat membuat kode secara eksklusif terhadap API baru:
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;
}
Aspek lain dari API, yaitu berbagai peristiwa perubahan layar dan properti screen
dari
FullscreenOptions
, tidak akan pernah dipicu atau diabaikan secara diam-diam oleh
browser yang tidak mendukung.
Demo
Jika Anda seperti saya, Anda akan terus memantau perkembangan berbagai mata uang kripto. (Padahal, saya tidak melakukannya karena saya mencintai planet ini, tetapi demi artikel ini, anggap saja saya melakukannya.) Untuk melacak mata uang kripto yang saya miliki, saya telah mengembangkan aplikasi web yang memungkinkan saya memantau pasar dalam segala situasi kehidupan, seperti dari kenyamanan tempat tidur saya, tempat saya memiliki penyiapan satu layar yang layak.

Karena ini terkait dengan kripto, pasar bisa menjadi kacau kapan saja. Jika hal ini terjadi, saya dapat dengan cepat berpindah ke meja kerja saya yang memiliki konfigurasi multi-layar. Saya dapat mengklik jendela mata uang apa pun dan dengan cepat melihat detail lengkap dalam tampilan layar penuh di layar yang berlawanan. Di bawah ini adalah foto terbaru saya yang diambil selama pertumpahan darah YCY terakhir. Hal itu membuatku benar-benar terkejut dan membuatku menutup wajah dengan kedua tangan.

Anda dapat mencoba demo yang disematkan di bawah, atau melihat kode sumbernya di GitHub.
Keamanan dan izin
Tim Chrome telah mendesain dan menerapkan Window Management API menggunakan prinsip inti yang ditentukan dalam Mengontrol Akses ke Fitur Platform Web yang Canggih, termasuk kontrol pengguna, transparansi, dan ergonomi. Window Management API mengekspos informasi baru tentang layar yang terhubung ke perangkat, sehingga meningkatkan permukaan sidik jari pengguna, terutama pengguna yang memiliki beberapa layar yang terhubung secara konsisten ke perangkat mereka. Sebagai salah satu mitigasi masalah privasi ini, properti layar yang diekspos dibatasi hingga minimum yang diperlukan untuk kasus penggunaan penempatan umum. Izin pengguna diperlukan agar situs mendapatkan informasi multi-layar dan menempatkan jendela di layar lain. Meskipun Chromium menampilkan label layar yang mendetail, browser bebas menampilkan label yang kurang deskriptif (atau bahkan label kosong).
Kontrol pengguna
Pengguna memiliki kontrol penuh atas eksposur penyiapannya. Pengguna dapat menyetujui atau menolak dialog izin, dan mencabut izin yang diberikan sebelumnya melalui fitur informasi situs di browser.
Kontrol perusahaan
Pengguna Chrome Enterprise dapat mengontrol beberapa aspek Window Management API seperti yang diuraikan di bagian yang relevan dalam setelan Grup Kebijakan Atomik.
Transparansi
Fakta apakah izin untuk menggunakan Window Management API telah diberikan atau tidak ditampilkan di informasi situs browser dan juga dapat dikueri melalui Permissions API.
Persistensi izin
Browser mempertahankan pemberian izin. Izin dapat dicabut melalui informasi situs browser.
Masukan
Tim Chrome ingin mengetahui pengalaman Anda dengan Window Management API.
Beri tahu kami tentang desain API
Apakah ada sesuatu tentang API yang tidak berfungsi seperti yang Anda harapkan? Atau, apakah ada metode atau properti yang tidak ada dan perlu Anda terapkan untuk mewujudkan ide Anda? Ada pertanyaan atau komentar tentang model keamanan?
- Laporkan masalah spesifikasi di repo GitHub yang sesuai, atau tambahkan pendapat Anda ke masalah yang sudah ada.
Melaporkan masalah terkait penerapan
Apakah Anda menemukan bug pada penerapan Chrome? Atau apakah implementasinya berbeda dengan spesifikasi?
- Laporkan bug di new.crbug.com. Pastikan untuk menyertakan detail sebanyak mungkin, petunjuk sederhana untuk mereproduksi, dan masukkan
Blink>Screen>MultiScreen
di kotak Komponen.
Menunjukkan dukungan untuk API
Apakah Anda berencana menggunakan Window Management API? Dukungan publik Anda membantu tim Chrome memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya dukungan untuk fitur tersebut.
- Bagikan rencana penggunaan Anda di thread WICG Discourse.
- Kirim tweet ke @ChromiumDev menggunakan hashtag
#WindowManagement
dan beri tahu kami di mana dan bagaimana Anda menggunakannya. - Minta vendor browser lain untuk menerapkan API.
Link bermanfaat
- Draf spesifikasi
- Penjelasan publik
- Demo Window Management API | Demo Window Management API source
- Bug pelacakan Chromium
- Entri ChromeStatus.com
- Komponen Blink:
Blink>Screen>MultiScreen
- Ulasan TAG
- Niat untuk Bereksperimen
Ucapan terima kasih
Spesifikasi Window Management API diedit oleh Victor Costan, Joshua Bell, dan Mike Wasserman. API ini diimplementasikan oleh Mike Wasserman dan Adrienne Walker. Artikel ini ditinjau oleh Joe Medley, François Beaufort, dan Kayce Basques. Terima kasih kepada Laura Torrent Puig atas fotonya.