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

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

Window Management API

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

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

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

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

Window Management API इस्तेमाल करने का तरीका

समस्या

विंडो को कंट्रोल करने का पुराना तरीका, 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
*/

टेक्नोलॉजी के क्षेत्र में काम करने वाले ज़्यादातर लोगों की तरह, मुझे भी काम करने के नए तरीके के हिसाब से खुद को ढालना पड़ा. साथ ही, मैंने अपने घर में ही ऑफ़िस बना लिया. मेरा सेटअप, नीचे दी गई फ़ोटो में दिखाए गए सेटअप जैसा है. अगर आपको इसमें दिलचस्पी है, तो मेरे सेटअप के बारे में पूरी जानकारी पढ़ें. मेरे 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 = async () => [window.screen];
  // Set to `false`, noting that this might be a lie.
  window.screen.isExtended = false;
}

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

डेमो

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

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

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

लेखक ने अपने हाथों से अपना चेहरा ढका हुआ है और वह नकली क्रिप्टो करंसी ट्रेडिंग डेस्क को देख रहा है.
YCY में भारी गिरावट देखकर घबरा गया.

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

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

Chrome टीम ने Window Management API को डिज़ाइन और लागू किया है. इसके लिए, वेब प्लैटफ़ॉर्म की बेहतर सुविधाओं का ऐक्सेस कंट्रोल करना में बताए गए मुख्य सिद्धांतों का इस्तेमाल किया गया है. इनमें उपयोगकर्ता का कंट्रोल, पारदर्शिता, और एर्गोनॉमिक्स शामिल हैं. Window Management API, किसी डिवाइस से कनेक्ट की गई स्क्रीन के बारे में नई जानकारी दिखाता है. इससे उपयोगकर्ताओं के फ़िंगरप्रिंटिंग की संभावना बढ़ जाती है. खास तौर पर, उन उपयोगकर्ताओं के लिए जिनके डिवाइसों से एक से ज़्यादा स्क्रीन लगातार कनेक्ट रहती हैं. निजता से जुड़ी इस समस्या को कम करने के लिए, स्क्रीन की प्रॉपर्टी को सिर्फ़ उतना ही दिखाया जाता है जितना सामान्य प्लेसमेंट के इस्तेमाल के उदाहरणों के लिए ज़रूरी है. साइटों को मल्टी-स्क्रीन की जानकारी पाने और अन्य स्क्रीन पर विंडो प्लेस करने के लिए, उपयोगकर्ता की अनुमति ज़रूरी होती है. Chromium, स्क्रीन के बारे में पूरी जानकारी देने वाले लेबल दिखाता है. हालांकि, अन्य ब्राउज़र के पास कम जानकारी देने वाले लेबल (या खाली लेबल भी) दिखाने का विकल्प होता है.

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

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

Enterprise कंट्रोल

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

पारदर्शिता

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

अनुमति की स्थिति

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

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

Chrome टीम, Window Management API के साथ आपके अनुभवों के बारे में जानना चाहती है.

हमें एपीआई डिज़ाइन के बारे में बताएं

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

  • GitHub repo पर, स्पेसिफ़िकेशन से जुड़ी समस्या की शिकायत करें या किसी मौजूदा समस्या के बारे में अपने विचार जोड़ें.

लागू करने से जुड़ी समस्या की शिकायत करना

क्या आपको Chrome के साथ काम करने वाले किसी एक्सटेंशन में कोई गड़बड़ी मिली? या क्या लागू करने का तरीका, स्पेसिफ़िकेशन से अलग है?

  • new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. इसमें ज़्यादा से ज़्यादा जानकारी शामिल करें. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दें. इसके अलावा, कॉम्पोनेंट बॉक्स में Blink>Screen>MultiScreen डालें.

एपीआई के लिए सहायता दिखाना

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

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

काम के लिंक

Acknowledgements

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