Window Management API की मदद से कई डिसप्ले मैनेज करना

कनेक्ट किए गए डिसप्ले के बारे में जानकारी पाना और उन डिसप्ले के हिसाब से विंडो को व्यवस्थित करना.

पब्लिश होने की तारीख: 14 सितंबर, 2020

Window Management API

Window Management API की मदद से, आपकी मशीन से कनेक्ट किए गए डिसप्ले की सूची बनाई जा सकती है. साथ ही, विंडो को किसी खास स्क्रीन पर रखा जा सकता है.

इस्तेमाल के सुझाए गए उदाहरण

इस एपीआई का इस्तेमाल करने वाली साइटों के उदाहरण:

  • मल्टी-विंडो वाले ग्राफ़िक्स एडिटर, जैसे कि Gimp, एडिटिंग के अलग-अलग टूल को सही जगह पर मौजूद विंडो में रख सकते हैं.
  • वर्चुअल ट्रेडिंग डेस्क, एक से ज़्यादा विंडो में मार्केट के रुझान दिखा सकती हैं. इनमें से किसी भी विंडो को फ़ुलस्क्रीन मोड में देखा जा सकता है.
  • स्लाइडशो ऐप्लिकेशन, स्पीकर नोट को इंटरनल प्राइमरी स्क्रीन पर और प्रज़ेंटेशन को बाहरी प्रोजेक्टर पर दिखा सकते हैं.

विंडो मैनेजमेंट एपीआई का इस्तेमाल कैसे करें

विंडो को कंट्रोल करने का यह तरीका, Window.open(), लंबे समय से इस्तेमाल किया जा रहा है. हालांकि, यह तरीका अतिरिक्त स्क्रीन के बारे में नहीं जानता. इस एपीआई के कुछ पहलू थोड़े पुराने लगते हैं. जैसे, इसका windowFeatures DOMString पैरामीटर. हालांकि, इसने हमें पिछले कुछ सालों में काफ़ी मदद की है. किसी विंडो की जगह तय करने के लिए, left और top (या screenX और screenY) के तौर पर कोऑर्डिनेट पास किए जा सकते हैं. साथ ही, width और height (या innerWidth और innerHeight) के तौर पर मनचाहा साइज़ पास किया जा सकता है. उदाहरण के लिए, बाईं ओर से 50 पिक्सल और सबसे ऊपर से 50 पिक्सल पर 400×300 विंडो खोलने के लिए, इस कोड का इस्तेमाल किया जा सकता है:

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
*/

टेक्नोलॉजी के क्षेत्र में काम करने वाले ज़्यादातर लोगों की तरह, मुझे भी 2020 में काम करने के तरीके को अपनाना पड़ा. साथ ही, मैंने अपने घर में ही ऑफ़िस बना लिया. मेरी स्क्रीन पर, फ़ोटो में दिख रहा पेज दिखता है (अगर आपको दिलचस्पी है, तो मेरे सेटअप के बारे में पूरी जानकारी पढ़ें). मेरे MacBook के बगल में रखा iPad, लैपटॉप से Sidecar की मदद से कनेक्ट है. इसलिए, जब भी मुझे ज़रूरत होती है, मैं iPad को तुरंत दूसरी स्क्रीन के तौर पर इस्तेमाल कर सकता हूँ.

दो कुर्सियों पर रखी स्कूल की बेंच. स्कूल की बेंच पर, जूतों के बॉक्स रखे हैं. इन बॉक्स पर लैपटॉप रखा है और उसके अगल-बगल दो iPad रखे हैं.
मल्टी-स्क्रीन सेटअप.

अगर मुझे बड़ी स्क्रीन का फ़ायदा लेना है, तो मैं कोड सैंपल से पॉप-अप को दूसरी स्क्रीन पर रख सकता हूं. मैं इसे इस तरह करता/करती हूं:

popup.moveTo(2500, 50);

यह अनुमानित जानकारी है, क्योंकि दूसरी स्क्रीन के डाइमेंशन के बारे में कोई जानकारी नहीं है. 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 अनुमति के बारे में Permissions 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;
});

ब्राउज़र, नए एपीआई के किसी भी तरीके का इस्तेमाल करने के पहले प्रयास में, अनुमति का अनुरोध डाइनैमिक तौर पर दिखाने का विकल्प चुन सकता है. ज़्यादा जानने के लिए आगे पढ़ें.

window.screen.isExtended प्रॉपर्टी

मेरे डिवाइस से एक से ज़्यादा स्क्रीन कनेक्ट हैं या नहीं, यह जानने के लिए मैंने window.screen.isExtended प्रॉपर्टी को ऐक्सेस किया. यह true या false दिखाता है. मेरे सेटअप के लिए, यह true दिखाता है.

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

getScreenDetails() तरीका

अब मुझे पता है कि मौजूदा सेटअप में एक से ज़्यादा स्क्रीन हैं. इसलिए, मैं Window.getScreenDetails() का इस्तेमाल करके दूसरी स्क्रीन के बारे में ज़्यादा जानकारी पा सकता हूं. इस फ़ंक्शन को कॉल करने पर, अनुमति का एक प्रॉम्प्ट दिखेगा. इसमें मुझसे पूछा जाएगा कि क्या साइट को मेरी स्क्रीन पर विंडो खोलने और लगाने की अनुमति दी जा सकती है. यह फ़ंक्शन एक प्रॉमिस दिखाता है, जो ScreenDetailed ऑब्जेक्ट के साथ रिज़ॉल्व होता है. मेरे MacBook Pro 13 से कनेक्ट किए गए iPad पर, इसमें दो ScreenDetailed ऑब्जेक्ट वाला screens फ़ील्ड शामिल है:

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 ऐरे में उपलब्ध होती है. ध्यान दें कि iPad के लिए left की वैल्यू 1680 से शुरू होती है. यह वैल्यू, बिल्ट-इन डिसप्ले के width के बराबर होती है. इससे मुझे यह तय करने में मदद मिलती है कि स्क्रीन को लॉजिकल तरीके से कैसे व्यवस्थित किया जाए (एक-दूसरे के बगल में, एक-दूसरे के ऊपर वगैरह). अब हर स्क्रीन के लिए डेटा भी उपलब्ध है. इससे यह पता चलता है कि वह isInternal है या isPrimary है. ध्यान दें कि बिल्ट-इन स्क्रीन, प्राइमरी स्क्रीन होना ज़रूरी नहीं है.

currentScreen फ़ील्ड, मौजूदा window.screen से जुड़ा लाइव ऑब्जेक्ट है. इस ऑब्जेक्ट को क्रॉस-स्क्रीन विंडो प्लेसमेंट या डिवाइस में बदलाव होने पर अपडेट किया जाता है.

screenschange इवेंट

अब सिर्फ़ एक चीज़ की ज़रूरत है. वह यह है कि मेरे स्क्रीन सेटअप में बदलाव होने पर, उसका पता कैसे लगाया जाए. नया इवेंट, screenschange, ठीक यही काम करता है: यह स्क्रीन कॉन्स्टेलेशन में बदलाव होने पर ट्रिगर होता है. (ध्यान दें कि इवेंट के नाम में "screens" प्लूरल है.) इसका मतलब है कि जब भी कोई नई स्क्रीन या मौजूदा स्क्रीन (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 को पॉलीफ़िल नहीं किया जा सकता. हालांकि, इसके शेप को शिम किया जा सकता है, ताकि सिर्फ़ नए एपीआई के हिसाब से कोड लिखा जा सके:

if (!('getScreenDetails' in window)) {
  // Returning a one-element array with the current screen,
  // noting that there might be more.
  window.getScreenDetails = as>ync () = [window.screen];
  // Set to `false`, noting that this might be a lie.
  window.screen.isExtended = false;
}

एपीआई के अन्य पहलू, जैसे कि स्क्रीन में बदलाव के अलग-अलग इवेंट और FullscreenOptions की screen प्रॉपर्टी, काम न करने वाले ब्राउज़र में कभी ट्रिगर नहीं होगी या उन्हें अनदेखा कर दिया जाएगा.

डेमो

अगर आपको अलग-अलग क्रिप्टोकरेंसी के डेवलपमेंट पर नज़र रखनी है, तो मेरे ऐप्लिकेशन में सिंगल-स्क्रीन सेटअप की मदद से, घर बैठे ही बाज़ारों पर नज़र रखी जा सकती है. (मुझे यह ग्रह बहुत पसंद है, इसलिए मैं ऐसा नहीं चाहता. हालांकि, इस लेख के लिए मान लें कि मैंने ऐसा किया.)

बिस्तर के आखिर में बड़ी टीवी स्क्रीन है. इसमें लेखक के पैर कुछ हद तक दिख रहे हैं. स्क्रीन पर, नकली क्रिप्टो करंसी ट्रेडिंग डेस्क दिखाया गया है.
मार्केट में घूमना और वहां के नज़ारे देखना.

क्रिप्टो से जुड़ा होने की वजह से, बाज़ार में कभी भी उतार-चढ़ाव हो सकता है. अगर ऐसा होता है, तो मैं तुरंत अपनी डेस्क पर जाकर काम कर सकता हूं. वहां मेरे पास मल्टी-स्क्रीन सेटअप है. मैं किसी भी मुद्रा की विंडो पर क्लिक कर सकता हूं. साथ ही, दूसरी स्क्रीन पर फ़ुलस्क्रीन व्यू में पूरी जानकारी तुरंत देख सकता हूं. यह मेरी हाल ही की फ़ोटो है. इसे YCY के आखिरी ब्लडबाथ के दौरान लिया गया था. इसने मुझे पूरी तरह से चौंका दिया और मेरे हाथ मेरे चेहरे पर रह गए.

मैं, घबराया हुआ, YCY में भारी गिरावट देख रहा हूं.

डेमो आज़माएं या GitHub पर इसका सोर्स कोड देखें.

सुरक्षा और अनुमतियां

Chrome टीम ने Window Management API को डिज़ाइन और लागू किया है. इसके लिए, Controlling Access to Powerful Web Platform Features में बताए गए मुख्य सिद्धांतों का इस्तेमाल किया गया है. इनमें उपयोगकर्ता का कंट्रोल, पारदर्शिता, और एर्गोनॉमिक्स शामिल हैं. Window Management API, किसी डिवाइस से कनेक्ट की गई स्क्रीन के बारे में नई जानकारी दिखाता है. इससे उपयोगकर्ताओं के फ़िंगरप्रिंटिंग की संभावना बढ़ जाती है. खास तौर पर, उन लोगों के लिए जिनके डिवाइसों से एक साथ कई स्क्रीन कनेक्ट होती हैं. निजता से जुड़ी इस समस्या को कम करने के लिए, स्क्रीन की प्रॉपर्टी को सिर्फ़ उतनी जानकारी तक सीमित रखा जाता है जितनी सामान्य प्लेसमेंट के इस्तेमाल के उदाहरणों के लिए ज़रूरी होती है.

साइटों को मल्टी-स्क्रीन की जानकारी पाने और विंडो को दूसरी स्क्रीन पर प्लेस करने के लिए, उपयोगकर्ता की अनुमति ज़रूरी होती है. Chromium, स्क्रीन के लेबल के बारे में पूरी जानकारी देता है. हालांकि, ब्राउज़र के पास यह विकल्प होता है कि वे कम जानकारी वाले लेबल (या खाली लेबल भी) दिखाएं.

उपयोगकर्ता के कंट्रोल

उपयोगकर्ता के पास, अपने सेटअप को दिखाने का पूरा कंट्रोल होता है. वे अनुमति के लिए दिखने वाले प्रॉम्प्ट को स्वीकार या अस्वीकार कर सकते हैं. साथ ही, ब्राउज़र में साइट की जानकारी देने वाली सुविधा का इस्तेमाल करके, पहले दी गई अनुमति को वापस ले सकते हैं.

एंटरप्राइज़ कंट्रोल

Chrome Enterprise के उपयोगकर्ता, Window Management API के कई पहलुओं को कंट्रोल कर सकते हैं. इसके बारे में एटॉमिक नीति ग्रुप की सेटिंग के संबंधित सेक्शन में बताया गया है.

पारदर्शिता

विंडो मैनेजमेंट एपीआई का इस्तेमाल करने की अनुमति दी गई है या नहीं, यह जानकारी ब्राउज़र की साइट की जानकारी में दिखती है. साथ ही, Permissions API के साथ भी इसकी क्वेरी की जा सकती है.

अनुमति बनाए रखना

ब्राउज़र, अनुमति देने की जानकारी को सेव करके रखता है. ब्राउज़र की साइट की जानकारी में जाकर, अनुमति वापस ली जा सकती है.

सुझाव/राय दें या शिकायत करें

क्या एपीआई के बारे में कुछ ऐसा है जो आपकी उम्मीद के मुताबिक काम नहीं करता? इसके अलावा, क्या कोई ऐसा तरीका या प्रॉपर्टी है जो मौजूद नहीं है और आपको अपने आइडिया को लागू करने के लिए उसकी ज़रूरत है? क्या आपको सुरक्षा मॉडल के बारे में कोई सवाल पूछना है या कोई टिप्पणी करनी है?

एपीआई के लिए अपना सपोर्ट दिखाना

क्या आपको Window Management API का इस्तेमाल करना है? आपकी सार्वजनिक राय से Chrome टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे अन्य ब्राउज़र बनाने वाली कंपनियों को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है.

  • WICG Discourse थ्रेड पर, इसे इस्तेमाल करने की अपनी योजना शेयर करें.
  • @ChromiumDev को ट्वीट करें. इसके लिए, हैशटैग #WindowManagement का इस्तेमाल करें. साथ ही, हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.
  • अन्य ब्राउज़र वेंडर से, एपीआई लागू करने के लिए कहें.

संसाधन

Acknowledgements

Window Management API की खास बातों में विक्टर कोस्टन, जोशुआ बेल, और माइक वासरमैन ने बदलाव किया है. इस एपीआई को माइक वॉसरमैन और ऐड्रियन वॉकर ने लागू किया था. इसकी समीक्षा जो मेडली, फ़्रांस्वा बोफ़ोर्ट, और केसी बास्क ने की है. फ़ोटो के लिए, लॉरा टॉरेंट पुइग को धन्यवाद.