Window Management API ile birkaç ekranı yönetme

Bağlı ekranlar ve konum pencereleri hakkında bilgi edinin.

Pencere Yönetim API'si

Window Management API, makinenize bağlı ekranları numaralandırmanıza ve belirli ekranlara pencereler yerleştirmenize olanak tanır.

olarak biliniyordu.

Önerilen kullanım alanları

Bu API'yi kullanabilecek sitelere örnek olarak aşağıdakiler verilebilir:

  • Gimp gibi çok pencereli grafik düzenleyiciler, doğru şekilde konumlandırılmış pencerelere çeşitli düzenleme araçları yerleştirebilir.
  • Sanal işlem masaları, pazar eğilimlerini birden fazla pencerede gösterebilir. Bu pencerelerden herhangi biri tam ekran modunda görüntülenebilir.
  • Slayt gösterisi uygulamaları, konuşmacı notlarını dahili birincil ekranda, sunuyu ise harici projektörde gösterebilir.

Window Management API'yi kullanma

Sorun

Pencereleri kontrol etmek için zamana dayalı bir yaklaşım olan Window.open() maalesef ek ekranların farkında değil. Bu API'nin windowFeatures DOMString parametresi gibi bazı özellikleri biraz eski görünse de yıllardır bize iyi hizmet vermiştir. Bir pencerenin konumunu belirtmek için koordinatları left ve top (veya sırasıyla screenX ve screenY) olarak iletebilir ve istediğiniz boyutuwidth ve height (ya da sırasıyla innerWidth ve innerHeight) olarak geçirebilirsiniz. Örneğin, soldan 50 piksel ve üstten 50 pikselde 400×300 piksellik bir pencere açmak için aşağıdaki kodu kullanabilirsiniz:

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

Bir Screen nesnesi döndüren window.screen özelliğine bakarak geçerli ekran hakkında bilgi edinebilirsiniz. MacBook Pro 13 inç bilgisayarımdaki çıkış şöyle:

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 alanında çalışan çoğu insan gibi ben de iş hayatındaki yeni gerçekliğe uyum sağlamak zorunda kaldım ve kişisel ev ofisimi kurdum. Benimkiler aşağıdaki fotoğrafta görünüyor (İlginizi çekiyorsa kurulumla ilgili tüm ayrıntıları okuyabilirsiniz). MacBook'umun yanındaki iPad dizüstü bilgisayara Yardımcı Dosya aracılığıyla bağlanıyor. Böylece, gerektiğinde iPad'i hızlıca ikinci bir ekrana dönüştürebiliyorum.

İki sandalyede okul bankı. Okul bankının tepesinde, bir dizüstü bilgisayarı ve etrafındaki iki iPad'i destekleyen ayakkabı kutuları bulunuyor.
Çok ekranlı kurulum.

Daha büyük ekrandan yararlanmak isterse yukarıdaki kod örneğinde bulunan pop-up'ı ikinci ekrana yerleştirebilirim. Şöyle yapıyorum:

popup.moveTo(2500, 50);

İkinci ekranın boyutlarını bilmenin bir yolu olmadığından bu kaba bir tahmindir. window.screen hizmetinden alınan bilgiler yalnızca yerleşik ekranı kapsar, iPad ekranını kapsamaz. Yerleşik ekranda width 1680 piksel idi. Dolayısıyla, MacBook'umun sağ tarafında yer bulunduğunu bildiğimiz için 2500 piksele geçmek pencereyi iPad'e kaydırmak için işe yarayabilir. Genel durumda bunu nasıl yapabilirim? Görünüşe göre tahminde bulunmaktan daha iyi bir yol var. Window Management API budur.

Ö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

Window Management API'yi kullanabilmek için 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 adlarına sahip tarayıcılar kullanılırken, aşağıdaki örnekte olduğu gibi izin isterken savunma kodu 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 kullanmayı ilk denemede izin istemini dinamik olarak gösterebilir. Daha fazla bilgi edinmek için okumaya devam edin.

window.screen.isExtended özelliği

Cihazıma birden fazla ekranın bağlı olup olmadığını öğrenmek için window.screen.isExtended özelliğine erişiyorum. true veya false değerini döndürür. Kurulumumda true değerini döndürüyor.

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

getScreenDetails() yöntemi

Artık mevcut kurulumun birden çok ekranlı olduğunu bildiğime göre, Window.getScreenDetails() kullanarak ikinci ekran hakkında daha fazla bilgi edinebilirim. Bu işlevi çağırdığımda, sitenin ekranıma pencere açıp yerleştirip yerleştiremeyeceğini soran bir izin istemi görüntülenir. İşlev, ScreenDetailed nesnesiyle çözümlenen bir söz döndürür. Bağlı bir iPad olan MacBook Pro 13'ümde, iki ScreenDetailed nesne içeren bir screens alanı mevcut:

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 bilgileri screens dizisinde bulabilirsiniz. iPad için left değerinin nasıl başladığına dikkat edin: 1680. Bu, tam olarak yerleşik ekranın width değeridir. Bu, ekranların mantıksal olarak nasıl düzenleneceğini tam olarak belirlememi sağlıyor (birbirlerinin yanında, üst üste vb.). Ayrıca artık her bir ekran için, isInternal olup olmadığını ve isPrimary olup olmadığını gösteren veriler de bulunmaktadır. Yerleşik ekranın her zaman birincil ekran olmayabileceğini unutmayın.

currentScreen alanı, geçerli window.screen değerine karşılık gelen 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 ne zaman değiştiğini algılamanın bir yolu. Yeni bir etkinlik olan screenschange tam olarak bunu yapıyor: Ekran takımyıldızında değişiklik yapıldığında etkinleşir. ("Ekranların" etkinlik adında çoğul olduğuna dikkat edin.) Bu, etkinliğin yeni bir ekran veya mevcut bir ekran (fiziksel ya da sanal olarak Yardımcı Araç'ta olduğu gibi) fişe takılı ya da fişe takılı olmadığı durumlarda etkinleşeceği anlamına gelir.

Yeni ekran ayrıntılarını eşzamansız olarak aramanız gerektiğini, screenschange etkinliğinin kendisinin bu verileri sağlamadığını unutmayın. Ekran ayrıntılarını aramak için önbelleğe alınmış 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ğeriyle) 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 somut bir ekranda değişiklik yapmak istersem 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, öğelerin tam ekran modunda görüntülenmesini, uygun şekilde adlandırılmış requestFullScreen() yöntemini kullanarak isteyebilirsiniz. Yöntem, FullscreenOptions değerini iletebileceğiniz bir options parametresi alır. Şimdiye kadar tek özelliği navigationUI. Window Management API, tam ekran görünümünün hangi ekranda başlatılacağını belirlemenizi sağlayan 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);
}

Polyester Lifi

Window Management API'ye çoklu dolgu yapmak mümkün değildir. Ancak yalnızca yeni API'ye göre kod yapabilmek için şeklini daraltabilirsiniz:

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 özellikleri, yani çeşitli ekran değişikliği etkinlikleri ve FullscreenOptions öğesinin screen özelliği hiçbir zaman etkinleşmez veya bunları desteklemeyen tarayıcılar tarafından sessizce yoksayılır.

Demo

Siz de benim gibiyseniz çeşitli kripto para birimlerinin gelişimini yakından takip edersiniz. (Aslında bu gezegeni sevdiğim için sevmiyorum, ancak bu makale olsun, öyleyse sadece yaptığımı varsayalım.) Sahip olduğum kripto para birimlerini takip etmek için, yatağımın rahatlığında veya iyi bir tek ekran kurulumuna sahip olduğum gibi yaşamın her aşamasında pazarları izlememe olanak sağlayan bir web uygulaması geliştirdim.

Yazarın bacaklarının kısmen göründüğü, bir yatağın ucundaki devasa TV ekranı. Ekranda sahte bir kripto para birimi alım satım masası görünüyor.
Rahatlama ve piyasaları izleme.

Kripto parayla ilgili olan bu konuda, piyasalar her an hareketli geçebilir. Böyle bir durumda, birden çok ekran kurulumu yaptığım masama hızlıca geçebilirim. Herhangi bir para birimi penceresini tıklayıp tüm ayrıntıları karşıdaki ekranda tam ekran olarak görebiliyorum. Aşağıda son YCY katliamında çekilmiş yakın zamanlı bir fotoğrafımı görebilirsiniz. Tamamen hazırlıksız yakaladım ve ellerimi yüzüme koydum.

Yazar, ellerini paniklemiş yüzüyle sahte kripto para birimi alım satım masasına bakıyor.
Panicky, YCY katliamına tanıklık ediyor.

Aşağıya yerleştirilmiş demo ile oynayabilir veya hatada demonun kaynak kodunu görebilirsiniz.

Güvenlik ve izinler

Chrome ekibi, Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme bölümünde tanımlanan temel ilkeleri (kullanıcı denetimi, şeffaflık ve ergonomi dahil) kullanarak Window Management API'yi tasarladı ve uyguladı. Window Management API, bir cihaza bağlı ekranlarla ilgili yeni bilgiler göstererek, özellikle cihazlarına sürekli olarak bağlı birden çok ekran kullanan kullanıcıların dijital parmak izi yüzeyini artırır. Bu gizlilik endişesini hafifletmek amacıyla, açığa çıkan ekran özellikleri, yaygın yerleşim kullanım alanları için gereken minimum değerle sınırlıdır. Sitelerin çok ekranlı bilgiler alması ve diğer ekranlara pencere yerleştirmesi için kullanıcı izni gereklidir. Chromium ayrıntılı ekran etiketleri döndürse de tarayıcılar daha az açıklayıcı (ve hatta boş etiketler) döndürebilir.

Kullanıcı denetimi

Ayarların ne kadar görünür olacağı tamamen kullanıcının kontrolündedir. İzin istemini kabul edebilir veya reddedebilir ve daha önce verilmiş bir izni tarayıcıdaki site bilgileri özelliği üzerinden iptal edebilirler.

Kurumsal denetim

Chrome Enterprise kullanıcıları, Atomic Policy Groups ayarlarının ilgili bölümünde açıklandığı gibi, Window Management API'nin çeşitli özelliklerini kontrol edebilir.

Şeffaflık

Window Management API'yi kullanma izninin verilip verilmediği, tarayıcının site bilgilerinde gösterilir ve Permissions API tarafından da sorgulanabilir.

İzin kalıcılığı

Tarayıcı, verilen izin izinlerini korur. İzin, tarayıcının site bilgilerinden iptal edilebilir.

Geri bildirim

Chrome ekibi, Window Management API ile ilgili deneyimlerinizi öğrenmek ister.

Bize API tasarımı hakkında bilgi verin

API'de beklediğiniz gibi çalışmayan bir durum mu var? Fikrinizi uygulamak için gereken yöntem veya özellikler eksik mi? Güvenlik modeliyle ilgili bir sorunuz veya yorumunuz mu var?

  • İlgili GitHub deposuna özellik sorunu bildirin veya düşüncelerinizi mevcut bir soruna ekleyin.

Uygulamayla ilgili bir sorunu bildirin

Chrome'un uygulamasında bir hata buldunuz mu? Yoksa uygulama, spesifikasyondan farklı mı?

  • new.crbug.com adresinde hata bildiriminde bulunun. Mümkün olduğunca fazla ayrıntı eklediğinizden ve basit yeniden oluşturma talimatlarını eklediğinizden emin olun ve Bileşenler kutusuna Blink>Screen>MultiScreen ifadesini girin. Glitch, hızlı ve kolay yeniden oluşturmalar paylaşmak için idealdir.

API'ye desteği gösterin

Window Management API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özellikleri öncelik sırasına koymasına yardımcı olur ve diğer tarayıcı satıcılarına onları desteklemenin ne kadar kritik olduğunu gösterir.

  • Bu bilgiyi nasıl kullanmayı planladığınızı WICG Discourse ileti dizisinde paylaşın.
  • #WindowManagement hashtag'ini kullanarak @ChromiumDev adresine tweet gönderip bu tweet'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

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ürler.