Bağlı ekranlar hakkında bilgi edinme ve pencereleri bu ekranlara göre konumlandırma
Window Management API
Pencere Yönetimi API'si, makinenize bağlı ekranları listelemenize ve pencereleri belirli ekranlara yerleştirmenize olanak tanır.
Önerilen kullanım alanları
Bu API'yi kullanabilecek sitelere örnek olarak şunlar verilebilir:
- Gimp gibi çok pencereli grafik düzenleyiciler, çeşitli düzenleme araçlarını doğru konumlandırılmış pencerelere yerleştirebilir.
- Sanal ticaret masaları, piyasa trendlerini birden fazla pencerede gösterebilir. Bu pencerelerin herhangi biri tam ekran modunda görüntülenebilir.
- Slayt gösterisi uygulamaları, konuşmacı notlarını dahili birincil ekranda, sunuyu ise harici bir projektörde gösterebilir.
Window Management API'yi kullanma
Sorun
Pencereleri kontrol etmek için denenmiş ve test edilmiş yaklaşım Window.open()
maalesef ek ekranlardan haberdar değildir. Bu API'nin bazı yönleri (ör. windowFeatures
DOMString
parametresi) biraz eski gibi görünse de yıllar içinde bize iyi hizmet etti. Bir pencerenin konumunu belirtmek için koordinatları left
ve top
(veya sırasıyla screenX
ve screenY
) olarak, istenen boyutu ise width
ve height
(veya sırasıyla innerWidth
ve innerHeight
) olarak iletebilirsiniz. Örneğin, soldan 50 piksel ve üstten 50 piksel uzaklıkta 400×300 boyutlarında bir pencere açmak için kullanabileceğiniz kod şudur:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
window.screen
özelliğine bakarak geçerli ekran hakkında bilgi edinebilirsiniz. Bu özellik, Screen
nesnesi döndürür. Bu, 13 inç MacBook Pro'mdaki çıkıştır:
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
*/
Teknoloji sektöründe çalışan çoğu kişi gibi ben de kendimi yeni çalışma şekline adapte etmek ve kişisel ev ofisimi kurmak zorunda kaldım. Benimki aşağıdaki fotoğraftaki gibi görünüyor (İlgileniyorsanız kurulumumla ilgili tüm ayrıntıları okuyabilirsiniz). MacBook'umun yanındaki iPad, Sidecar ile dizüstü bilgisayara bağlı. Bu sayede, gerektiğinde iPad'i hızlıca ikinci bir ekrana dönüştürebiliyorum.

Daha büyük ekrandan yararlanmak istiyorsam yukarıdaki kod örneğindeki pop-up'ı ikinci ekrana yerleştirebilirim. Ben şu şekilde yapıyorum:
popup.moveTo(2500, 50);
İkinci ekranın boyutlarını bilmenin bir yolu olmadığından bu, kabaca bir tahmindir. window.screen
cihazındaki bilgiler yalnızca yerleşik ekranı kapsar, iPad ekranını kapsamaz. Yerleşik ekranın bildirilen width
değeri 1680
pikseldi. Bu nedenle, pencereyi iPad'e taşımak için 2500
piksele geçmek işe yarayabilir. Çünkü ben, iPad'in MacBook'umun sağ tarafında olduğunu biliyorum. Bunu genel olarak nasıl yapabilirim? Tahmin etmek yerine daha iyi bir yöntem var. Bu yöntem, Pencere Yönetimi API'sidir.
Özellik algılama
Window Management API'nin desteklenip desteklenmediğini kontrol etmek için şunu kullanın:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
window-management
izni
Pencere Yönetimi API'sini kullanmadan önce kullanıcıdan izin istemem gerekiyor.
window-management
izni, Permissions API ile şu şekilde sorgulanabilir:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
Eski ve yeni izin adını içeren tarayıcılar kullanılırken izin isterken aşağıdaki örnekte olduğu gibi savunma amaçlı kod kullandığınızdan emin olun.
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;
});
Tarayıcı, yeni API'nin yöntemlerinden herhangi birini kullanma girişiminde izin istemini dinamik olarak göstermeyi seçebilir. Daha fazla bilgi edinmek için okumaya devam edin.
window.screen.isExtended
özelliği
Cihazıma birden fazla ekranın bağlanıp bağlanmadığını öğrenmek için window.screen.isExtended
özelliğine erişiyorum. true
veya false
döndürür. Kurulumum için true
değerini döndürüyor.
window.screen.isExtended;
// Returns `true` or `false`.
getScreenDetails()
yöntemi
Mevcut kurulumun çoklu ekran olduğunu öğrendiğime göre, Window.getScreenDetails()
kullanarak ikinci ekran hakkında daha fazla bilgi edinebilirim. Bu işlevi çağırdığımda, site ekranımda pencere açıp yerleştirebilir mi diye soran bir izin istemi gösteriliyor. İşlev, ScreenDetailed
nesnesiyle çözümlenen bir söz döndürür. Bağlı bir iPad'in bulunduğu MacBook Pro 13'ümde,
bu, iki ScreenDetailed
nesnesi içeren bir screens
alanı içerir:
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
}]
}
*/
Bağlı ekranlarla ilgili bilgiler screens
dizisinde yer alır. iPad için left
değerinin, yerleşik ekranın tam width
'si olan 1680
ile başladığını unutmayın. Bu sayede, ekranların mantıksal olarak nasıl düzenlendiğini (yan yana, üst üste vb.) tam olarak belirleyebilirim. Ayrıca, her ekranın isInternal
veya isPrimary
olup olmadığını gösteren veriler de mevcuttur. Yerleşik ekranın birincil ekran olması gerekmediğini unutmayın.
currentScreen
alanı, mevcut window.screen
ile eşleşen canlı bir nesnedir. Nesne, ekranlar arası pencere yerleşimlerinde veya cihaz değişikliklerinde güncellenir.
screenschange
etkinliği
Şu anda eksik olan tek şey, ekran kurulumumun değiştiğini algılamanın bir yoludur. Yeni bir etkinlik olan
screenschange
tam olarak bunu yapar: Ekran takımyıldızı her değiştirildiğinde tetiklenir. ("Ekranlar"ın etkinlik adında çoğul olduğuna dikkat edin.) Bu, yeni bir ekran veya mevcut bir ekran (Sidecar durumunda fiziksel ya da sanal olarak) takıldığında veya çıkarıldığında etkinliğin tetiklendiği anlamına gelir.
Yeni ekran ayrıntılarını eşzamansız olarak aramanız gerektiğini unutmayın. screenschange
etkinliğinin kendisi bu verileri sağlamaz. Ekran ayrıntılarını aramak için önbelleğe alınmış bir Screens
arayüzünden canlı nesneyi kullanın.
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
etkinliği
Yalnızca mevcut ekrandaki değişikliklerle (yani canlı nesnenin değeriyle currentScreen
) ilgileniyorsam currentscreenchange
etkinliğini dinleyebilirim.
const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
const details = screenDetails.currentScreen;
console.log('The current screen has changed.', event, details);
});
change
etkinliği
Son olarak, yalnızca belirli bir ekrandaki değişikliklerle ilgileniyorsam o ekranın change
etkinliğini dinleyebilirim.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Yeni tam ekran seçenekleri
Şimdiye kadar, requestFullScreen()
adlı yöntemle öğelerin tam ekran modunda gösterilmesini isteyebiliyordunuz. Yöntem, FullscreenOptions
değerini iletebileceğiniz bir options
parametresi alır. Şu ana kadar tek özelliği navigationUI
oldu.
Window Management API, tam ekran görünümünün hangi ekranda başlatılacağını belirlemenize olanak tanıyan yeni bir screen
özelliği ekler. Örneğin, birincil ekranı tam ekran yapmak istiyorsanız:
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'nin polyfill'i mümkün değildir ancak şeklini doldurarak yalnızca yeni API'ye karşı kod yazabilirsiniz:
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'nin diğer yönleri (yani çeşitli ekran değişikliği etkinlikleri ve screen
özelliğinin FullscreenOptions
) desteklenmeyen tarayıcılar tarafından hiçbir zaman tetiklenmez veya sessizce yoksayılır.
Demo
Benim gibiyseniz çeşitli kripto para birimlerinin gelişimini yakından takip ediyorsunuzdur. (Aslında bu gezegeni çok sevdiğim için hiç de öyle düşünmüyorum ancak bu makale için öyle düşündüğümü varsayalım.) Sahip olduğum kripto para birimlerini takip etmek için bir web uygulaması geliştirdim. Bu uygulama, tek ekranlı ve rahat bir yatakta olduğum gibi tüm yaşam koşullarında piyasaları izlememe olanak tanıyor.

Kripto para piyasalarıyla ilgili bu durum, piyasaların herhangi bir zamanda hareketlenebileceği anlamına gelir. Böyle bir durumda, çok ekranlı kurulumun bulunduğu masama hızlıca geçebilirim. Herhangi bir para biriminin penceresini tıklayarak tam ekran görünümünde tüm ayrıntıları hızlıca görebiliyorum. Aşağıda, son YCY katliamı sırasında çekilmiş yeni bir fotoğrafım var. Bu durum beni tamamen hazırlıksız yakaladı ve ellerimle yüzümü kapatmama neden oldu.

Aşağıda yerleştirilmiş demoyu deneyebilir veya GitHub'daki kaynak kodunu inceleyebilirsiniz.
Güvenlik ve izinler
Chrome Ekibi, Window Management API'yi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme'de tanımlanan temel ilkeleri (kullanıcı kontrolü, şeffaflık ve ergonomi dahil) kullanarak tasarladı ve uyguladı. Pencere Yönetimi API'si, bir cihaza bağlı ekranlarla ilgili yeni bilgiler sunarak kullanıcıların parmak izi yüzeyini artırır. Bu durum, özellikle cihazlarına sürekli olarak birden fazla ekran bağlayan kullanıcılar için geçerlidir. Bu gizlilik endişesini gidermek için, gösterilen ekran özellikleri yaygın yerleşim kullanım alanları için gereken minimum düzeyle sınırlıdır. Sitelerin çoklu ekran bilgisi alması ve pencereleri diğer ekranlara yerleştirmesi için kullanıcı izni gerekir. Chromium, ayrıntılı ekran etiketleri döndürürken tarayıcılar daha az açıklayıcı (hatta boş etiketler) döndürebilir.
Kullanıcı denetimi
Kullanıcı, kurulumunun görünürlüğü üzerinde tam denetime sahiptir. Kullanıcılar izin istemini kabul edebilir veya reddedebilir ve daha önce verilen bir izni tarayıcıdaki site bilgileri özelliği aracılığıyla iptal edebilir.
Kurumsal kontrol
Chrome Enterprise kullanıcıları, Atomic Policy Groups ayarlarının ilgili bölümünde belirtildiği gibi Pencere Yönetimi API'sinin çeşitli yönlerini kontrol edebilir.
Şeffaflık
Pencere Yönetimi API'sini kullanma izninin verilip verilmediği, tarayıcının site bilgilerinde gösterilir ve Permissions API aracılığıyla da sorgulanabilir.
İzin kalıcılığı
Tarayıcı, izinleri kalıcı olarak saklar. İzin, tarayıcının site bilgileri bölümünden iptal edilebilir.
Geri bildirim
Chrome Ekibi, Pencere Yönetimi API'si ile ilgili deneyimlerinizi öğrenmek istiyor.
API tasarımı hakkında bilgi verin.
API'nin beklentilerinizi karşılamayan bir yönü var mı? Yoksa fikrinizi uygulamak için eksik yöntemler veya özellikler mi var? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var?
- İlgili GitHub deposunda bir spesifikasyon sorunu bildirin veya düşüncelerinizi mevcut bir soruna ekleyin.
Uygulamayla ilgili sorun bildirme
Chrome'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?
- new.crbug.com adresinden hata bildirin. Mümkün olduğunca ayrıntılı bilgi vermeye, yeniden oluşturma için basit talimatlar eklemeye ve Bileşenler kutusuna
Blink>Screen>MultiScreen
girmeye dikkat edin.
API'ye desteğinizi gösterme
Pencere Yönetimi API'sini kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı satıcılarına bu özelliklerin desteklenmesinin ne kadar önemli olduğunu gösterir.
- Bu özelliği nasıl kullanmayı planladığınızı WICG Discourse iş parçacığında paylaşın.
#WindowManagement
hashtag'ini kullanarak @ChromiumDev hesabına tweet gönderin ve nerede, nasıl kullandığınızı bize bildirin.- Diğer tarayıcı sağlayıcılarından API'yi uygulamalarını isteyin.
Faydalı bağlantılar
- Spec draft
- Herkese açık açıklama
- Window Management API demosu | Window Management API demo kaynağı
- Chromium izleme hatası
- ChromeStatus.com girişi
- Blink Bileşeni:
Blink>Screen>MultiScreen
- TAG Review
- Deneme Amacı (Intent to Experiment)
Teşekkür
Window Management API spesifikasyonu Victor Costan, Joshua Bell ve Mike Wasserman tarafından düzenlendi. API, Mike Wasserman ve Adrienne Walker tarafından uygulanmıştır. Bu makale Joe Medley, François Beaufort ve Kayce Basques tarafından incelenmiştir. Fotoğraflar için Laura Torrent Puig'e teşekkür ederiz.