Bağlı ekranlar hakkında bilgi edinin ve pencereleri bu ekranlara göre konumlandırın.
Window Management API
Pencere Yönetimi API'si, makinenize bağlı ekranları saymanıza 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 işlem masaları, pazar trendlerini birden fazla pencerede gösterebilir. Bu pencerelerin her biri tam ekran modunda görüntülenebilir.
- Slayt gösterisi uygulamaları, konuşmacı notlarını dahili birincil ekranda ve sunuyu harici bir projektörde gösterebilir.
Window Management API'yi kullanma
Sorun
Pencereleri kontrol etmek için zaman içinde kanıtlanmış bir yaklaşım olan Window.open()
, maalesef ek ekranları hesaba katmaz. Bu API'nin bazı yönleri (ör. windowFeatures
DOMString
parametresi) biraz eski görünse de yıllar boyunca 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 mesafede 400x300 boyutunda bir pencere açmak için şu kodu kullanabilirsiniz:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
Screen
nesnesi döndüren window.screen
mülküne bakarak geçerli ekran hakkında bilgi edinebilirsiniz. MacBook Pro 13 inç cihazımdaki çıkış şu şekildedir:
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 yeni çalışma koşullarına uyum sağlamak ve kişisel ev ofisimi kurmak zorunda kaldım. Benimki aşağıdaki fotoğraftaki gibi görünüyor (İsterseniz kurulumumla ilgili tüm ayrıntıları okuyabilirsiniz). MacBook'ımın yanındaki iPad, Sidecar aracılığıyla dizüstü bilgisayara bağlı. Böylece, gerektiğinde iPad'i hızlıca ikinci ekrana dönüştürebiliyorum.
Daha büyük ekrandan yararlanmak isterseniz yukarıdaki kod örneğindeki pop-up'ı ikinci ekrana yerleştirebilirsiniz. Bunu şu şekilde yapıyorum:
popup.moveTo(2500, 50);
İkinci ekranın boyutlarını bilmenin bir yolu olmadığından bu tahmin yaklaşıktır. window.screen
'ten alınan bilgiler yalnızca yerleşik ekranı kapsar, iPad ekranını kapsamaz. Yerleşik ekranın bildirilen width
değeri 1680
piksel olduğundan, 2500
piksele geçmek pencereyi iPad'e taşımak için işe yarayabilir. Bunun MacBook'ımın sağ tarafında olduğunu biliyorum. Bunu genel olarak nasıl yapabilirim? Tahmin etmekten daha iyi bir yöntem olduğu ortaya çıktı. Bu yöntem, Window Management API'dir.
Özellik algılama
Window Management API'nin desteklenip desteklenmediğini kontrol etmek için:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
window-management
izni
Window Management API'yi kullanabilmek için kullanıcıdan izin istemem gerekir. window-management
izni, Permissions API ile aşağıdaki gibi 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ın kullanıldığı tarayıcılarda izin isterken aşağıdaki örnekte gösterildiği 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 kullanmaya ilk girişimde izin istemini dinamik olarak göstermeyi seçebilir. Daha fazla bilgi için okumaya devam edin.
window.screen.isExtended
mülkü
Cihazıma birden fazla ekranın bağlı olup olmadığını öğrenmek için window.screen.isExtended
mülküne erişiyorum. true
veya false
döndürür. Benim kurulumumda true
döndürülüyor.
window.screen.isExtended;
// Returns `true` or `false`.
getScreenDetails()
yöntemi
Mevcut kurulumun çok ekranlı olduğunu bildiğim için Window.getScreenDetails()
kullanarak ikinci ekran hakkında daha fazla bilgi edinebilirim. Bu işlevi çağırdığımda, sitenin ekranımda pencere açıp yerleştirip yerleştiremeyeceğini soran bir izin istemi gösterilir. İşlev, ScreenDetailed
nesnesi ile çözülen bir promise döndürür. iPad'in bağlı olduğ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 bulunur. iPad için left
değerinin 1680
ile başladığını, bunun da tam olarak yerleşik ekranın width
değeri olduğunu unutmayın. Bu sayede ekranların mantıksal olarak nasıl düzenlendiğini (yan yana, üst üste vb.) tam olarak belirleyebilirim. Artık her ekran için isInternal
ekranı mı yoksa isPrimary
ekranı mı olduğunu gösteren veriler de mevcuttur. Yerleşik ekranın mutlaka birincil ekran olmayabileceğini unutmayın.
currentScreen
alanı, mevcut window.screen
'a karşılık gelen canlı bir nesnedir. Nesne, ekranlar arası pencere yerleşimlerinde veya cihaz değişikliklerinde güncellenir.
screenschange
etkinliği
Ekran kurulumum değiştiğinde bunu algılamanın bir yolunu bulmak istiyorum. Yeni bir etkinlik olan screenschange
tam da bunu yapar: Ekran takımyıldızı değiştirildiğinde tetiklenir. ("screens" ifadesinin etkinlik adında çoğul olduğunu unutmayın.) Bu, yeni bir ekran veya mevcut bir ekran (Sidecar'da fiziksel olarak ya da sanal olarak) her takıldığında ya da prizden çekildiğinde 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ği bu verileri sağlamaz. Ekran ayrıntılarını görüntülemek için önbelleğe alınmış bir Screens
arayüzündeki 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 geçerli ekrandaki değişikliklerle (yani canlı nesnenin currentScreen
değeri) 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 söz konusu 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, uygun şekilde adlandırılmış requestFullScreen()
yöntemi aracılığıyla öğelerin tam ekran modunda gösterilmesini isteyebilirdiniz. Yöntem, FullscreenOptions
iletmenizi sağlayan bir options
parametresi alır. Şimdiye kadar tek mülkü navigationUI
olmuştur.
Window Management API, tam ekran görünümün hangi ekranda başlatılacağını belirlemenize olanak tanıyan yeni bir screen
mülkü 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);
}
Çoklu dolgu
Window Management API'yi polyfill olarak doldurmak mümkün değildir ancak yalnızca yeni API'ye göre kod yazabilmek için şeklini değiştirebilirsiniz:
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 (ör. çeşitli ekran değiştirme etkinlikleri ve FullscreenOptions
nesnesinin screen
mülkü) 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 edersiniz. (Aslında bu gezegeni sevdiğim için çok da istemiyorum ama bu makale için bunu yaptığımı varsayın.) Sahip olduğum kripto para birimlerini takip etmek için, piyasaları tüm yaşam durumlarımda (ör. iyi bir tek ekranlı kurulumun bulunduğu yatağımın rahatlığında) izlememe olanak tanıyan bir web uygulaması geliştirdim.
Kripto para birimleri söz konusu olduğunda piyasalar her an hareketli olabilir. Böyle bir durumda, çok ekranlı kurulumun bulunduğu masama hızlıca geçebilirim. Herhangi bir para biriminin penceresini tıklayıp tam ekran görünümünde tüm ayrıntıları hızlıca görebilirim. Aşağıda, son YCY kan banyosu sırasında çekilmiş bir fotoğrafımı görebilirsiniz. Bu durum beni tamamen hazırlıksız yakaladı ve ellerimi yüzüme kapatmama neden oldu.
Aşağıya yerleştirilmiş demo ile oynayabilir veya glitch'te kaynak kodunu görebilirsiniz.
Güvenlik ve izinler
Chrome ekibi, Window Management API'yi tasarlarken ve uygularken kullanıcı kontrolü, şeffaflık ve ergonomi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme başlıklı makalede belirtilen temel ilkeleri temel almıştır. Pencere Yönetimi API'si, bir cihaza bağlı ekranlarla ilgili yeni bilgiler sunarak kullanıcıların (özellikle de cihazlarına sürekli olarak bağlı birden fazla ekranı olan kullanıcıların) parmak izi yüzeyini artırır. Bu gizlilik endişesini azaltmak 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 bilgilerini alması ve diğer ekranlara pencere yerleştirmesi için kullanıcı izni gerekir. Chromium ayrıntılı ekran etiketleri döndürür ancak tarayıcıların daha az açıklayıcı (veya hatta boş etiketler) döndürmesi serbesttir.
Kullanıcı denetimi
Kullanıcı, kurulumunun pozlamasını tamamen kontrol eder. Kullanıcılar izin istemlerini kabul edebilir veya reddedebilir ve daha önce verilen izinleri tarayıcıdaki site bilgileri özelliği aracılığıyla iptal edebilir.
Kurumsal kontrol
Chrome Enterprise kullanıcıları, Atomik Politika Grupları ayarlarının ilgili bölümünde belirtildiği gibi Window Management API'nin çeşitli yönlerini kontrol edebilir.
Şeffaflık
Pencere Yönetimi API'sinin kullanım izninin verilip verilmediği, tarayıcının site bilgilerinde gösterilir ve ayrıca İzinler API'si aracılığıyla sorgulanabilir.
İzin kalıcılığı
Tarayıcı, izin verme işlemlerini devam ettirir. İzin, tarayıcının site bilgileri üzerinden iptal edilebilir.
Geri bildirim
Chrome ekibi, Window Management API ile ilgili deneyimlerinizi öğrenmek istiyor.
API tasarımı hakkında bilgi verin
API ile ilgili olarak beklediğiniz gibi çalışmayan bir şey var mı? Yoksa fikrinizi uygulamak için ihtiyaç duyduğunuz yöntemler veya özellikler eksik mi? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var?
- İlgili GitHub deposunda özellik sorunu gönderin veya düşüncelerinizi mevcut bir soruna ekleyin.
Uygulamayla ilgili sorunları bildirme
Chrome'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?
- new.crbug.com adresinden hata kaydı oluşturun. Mümkün olduğunca fazla ayrıntı ekleyin, hatayı yeniden oluşturmayla ilgili basit talimatlar verin ve Bileşenler kutusuna
Blink>Screen>MultiScreen
yazın. Glitch, hızlı ve kolay yeniden oluşturma işlemlerini paylaşmak için idealdir.
API'yi destekleme
Window Management API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı tedarikçi firmalarına bu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.
- WICG Discourse mesaj dizisinde bu özelliği nasıl kullanmayı planladığınızı paylaşın.
#WindowManagement
hashtag'ini kullanarak @ChromiumDev hesabına tweet gönderin ve bu özelliği nerede ve nasıl kullandığınızı bize bildirin.- Diğer tarayıcı tedarikçilerinden API'yi uygulamalarını isteyin.
Faydalı bağlantılar
- Özellik taslağı
- 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 İncelemesi
- Deneme yapma niyeti
Teşekkür ederiz
Window Management API spesifikasyonu Victor Costan, Joshua Bell ve Mike Wasserman tarafından düzenlenmiştir. API, Mike Wasserman ve Adrienne Walker tarafından uygulanmıştır. Bu makale; Joe Medley, François Beaufort ve Kayce Basques tarafından incelendi. Fotoğraflar için Laura Torrent Puig'e teşekkürler.