الحصول على معلومات حول الشاشات المتصلة وتحديد مواضع النوافذ بالنسبة إلى تلك الشاشات
تاريخ النشر: 14 أيلول (سبتمبر) 2020
Window Management API
تتيح لك واجهة برمجة التطبيقات Window Management API إدراج الشاشات المتصلة بجهازك ووضع النوافذ على شاشات محدّدة.
حالات الاستخدام المقترَحة
في ما يلي أمثلة على المواقع الإلكترونية التي قد تستخدم واجهة برمجة التطبيقات هذه:
- يمكن لمحرّرات الرسومات المتعددة النوافذ، مثل Gimp، وضع أدوات التعديل المختلفة في نوافذ موضوعة بدقة.
- يمكن أن تعرض منصات التداول الافتراضية مؤشرات السوق في نوافذ متعددة، ويمكن عرض أي منها في وضع ملء الشاشة.
- يمكن لتطبيقات العروض التقديمية عرض ملاحظات المحاضر على الشاشة الأساسية الداخلية والعرض التقديمي على جهاز عرض خارجي.
كيفية استخدام Window Management API
إنّ الطريقة المجربة والمختبرة للتحكّم في النوافذ،
Window.open()، لا تتعرّف للأسف على الشاشات الإضافية. على الرغم من أنّ بعض جوانب واجهة برمجة التطبيقات هذه تبدو قديمة بعض الشيء، مثل المَعلمة
windowFeatures
DOMString، إلا أنّها كانت مفيدة لنا على مر السنين. لتحديد موضع نافذة، يمكنك تمرير الإحداثيات كـ left وtop (أو screenX وscreenY على التوالي) وتمرير الحجم المطلوب كـ width وheight (أو innerWidth وinnerHeight على التوالي). على سبيل المثال، لفتح نافذة بحجم 400×300 بكسل على بُعد 50 بكسل من اليسار و50 بكسل من الأعلى، يمكنك استخدام الرمز التالي:
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، وإعداد مكتبي المنزلي الشخصي. يبدو مظهري كما في الصورة (إذا كنت مهتمًا، يمكنك الاطّلاع على التفاصيل الكاملة حول إعداداتي). يتم توصيل جهاز iPad بجهاز MacBook من خلال ميزة Sidecar، لذا يمكنني تحويل جهاز 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 متصل،
يتضمّن ذلك حقل screens يحتوي على عنصرَين من النوع ScreenDetailed:
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. لاحظ كيف تبدأ قيمة
left لجهاز iPad عند 1680، وهي width لشاشة العرض المضمّنة. يتيح لي ذلك تحديد طريقة ترتيب الشاشات منطقيًا (بجانب بعضها البعض أو فوق بعضها البعض وما إلى ذلك). تتوفّر الآن أيضًا بيانات لكل شاشة توضّح ما إذا كانت شاشة isInternal أو isPrimary. يُرجى العِلم أنّ الشاشة المضمّنة
ليست بالضرورة الشاشة الأساسية.
الحقل currentScreen هو عنصر مباشر يتوافق مع window.screen الحالي. يتم تعديل العنصر
عند تغيير موضع النافذة على الشاشات المختلفة أو تغيير الجهاز.
حدث screenschange
الشيء الوحيد الذي ينقصني الآن هو طريقة لرصد التغييرات في إعدادات الشاشة. يؤدي حدث جديد، وهو screenschange، هذا الإجراء بالضبط: يتم تنشيطه كلما تم تعديل مجموعة النجوم على الشاشة. (يُرجى العِلم أنّ كلمة "شاشات" هي صيغة الجمع في اسم الحدث). وهذا يعني أنّ الحدث يتم تشغيله كلّما تم توصيل شاشة جديدة أو شاشة حالية (سواء كانت شاشة فعلية أو افتراضية في حالة 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);
}
Polyfill
لا يمكن توفير وظائف بديلة لواجهة برمجة التطبيقات 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;
}
لن يتم تشغيل الجوانب الأخرى من واجهة برمجة التطبيقات، أي أحداث تغيير الشاشة المختلفة والسمة screen الخاصة بالعنصر FullscreenOptions، أو سيتم تجاهلها بدون تنبيه من قِبل المتصفحات غير المتوافقة.
عرض توضيحي
إذا كنت تتابع عن كثب تطوّر العملات المشفّرة المختلفة، يمكنك مراقبة الأسواق وأنت مسترخٍ في سريرك من خلال إعداد شاشة واحدة في تطبيقي. (لا أوافق على ذلك إطلاقًا لأنني أحب هذا الكوكب، ولكن لأغراض هذه المقالة، افترض أنّني أوافق على ذلك).
بما أنّ هذا الموضوع يتعلّق بالعملات المشفّرة، يمكن أن تصبح الأسواق محمومة في أي وقت. في حال حدوث ذلك، يمكنني الانتقال بسرعة إلى مكتبي حيث أستخدم شاشات متعددة. يمكنني النقر على نافذة أي عملة والاطّلاع بسرعة على التفاصيل الكاملة في عرض ملء الشاشة على الشاشة المقابلة. إليك صورة حديثة لي تم التقاطها خلال مذبحة YCY الأخيرة. لقد فاجأني ذلك تمامًا، فوضعت يدي على وجهي.
يمكنك تجربة العرض التوضيحي أو الاطّلاع على الرمز المصدر على GitHub.
الأمان والأذونات
صمّم فريق Chrome واجهة برمجة التطبيقات Window Management API ونفّذها باستخدام المبادئ الأساسية المحدّدة في التحكّم في الوصول إلى الميزات الفعّالة لمنصة الويب، بما في ذلك تحكّم المستخدم والشفافية وبيئة العمل المريحة. تعرض واجهة برمجة التطبيقات Window Management API معلومات جديدة حول الشاشات المتصلة بجهاز، ما يزيد من مساحة تحديد بصمة المستخدمين، خاصةً أولئك الذين لديهم شاشات متعددة متصلة بأجهزتهم بشكل دائم. وللحدّ من هذه المخاوف بشأن الخصوصية، تقتصر خصائص الشاشة المعروضة على الحدّ الأدنى المطلوب لحالات الاستخدام الشائعة لموضع الإعلان.
يجب الحصول على إذن المستخدم لكي تتمكّن المواقع الإلكترونية من الحصول على معلومات حول الشاشات المتعدّدة وتحديد مواضع النوافذ على الشاشات الأخرى. في حين يعرض Chromium تصنيفات مفصّلة للشاشة، يمكن للمتصفّحات عرض تصنيفات أقل وصفًا (أو حتى تصنيفات فارغة).
تحكّم المستخدم
يتحكّم المستخدم بشكل كامل في مستوى عرض إعداداته. ويمكنهم قبول طلب الإذن أو رفضه، وإبطال إذن تم منحه سابقًا من خلال ميزة معلومات الموقع الإلكتروني في المتصفّح.
تحكّم المؤسسة
يمكن لمستخدمي Chrome Enterprise التحكّم في العديد من جوانب Window Management API كما هو موضّح في القسم ذي الصلة من إعدادات مجموعات السياسات الذرية.
الشفافية
تتوفّر معلومات حول ما إذا تم منح الإذن باستخدام Window Management API في معلومات الموقع الإلكتروني للمتصفّح، ويمكن أيضًا الاستعلام عنها باستخدام Permissions API.
استمرار الإذن
يحتفظ المتصفّح بأذونات الوصول. يمكن إلغاء الإذن من خلال معلومات الموقع الإلكتروني في المتصفّح.
الملاحظات
هل هناك أي شيء في واجهة برمجة التطبيقات لا يعمل على النحو المتوقّع؟ أو هل هناك طرق أو سمات ناقصة تحتاج إلى تنفيذ فكرتك؟ هل لديك سؤال أو تعليق حول نموذج الأمان؟
- يمكنك الإبلاغ عن مشكلة في المواصفات في مستودع GitHub ذي الصلة، أو إضافة أفكارك إلى مشكلة حالية.
- الإبلاغ عن خطأ في تنفيذ Chrome احرص على تضمين أكبر قدر ممكن من التفاصيل والتعليمات اللازمة لإعادة إنتاج المشكلة، وأدخِل
Blink>Screen>MultiScreenفي مربّع المكوّنات.
إظهار الدعم لواجهة برمجة التطبيقات
هل تخطّط لاستخدام Window Management API؟ يساعد دعمك العلني فريق Chrome في تحديد أولويات الميزات، كما يوضّح لمورّدي المتصفّحات الآخرين مدى أهمية توفيرها.
- شارِك كيف تخطّط لاستخدامه في سلسلة محادثات WICG Discourse.
- يمكنك إرسال تغريدة إلى @ChromiumDev باستخدام الهاشتاغ
#WindowManagementوإخبارنا بمكان استخدامك لهذه الميزة وكيفية استخدامها. - اطلب من مورّدي المتصفحات الآخرين تنفيذ واجهة برمجة التطبيقات.
الموارد
- مسودة المواصفات
- شرح علني
- عرض توضيحي لواجهة Window Management API | عرض توضيحي لواجهة Window Management API source
- خطأ التتبُّع في Chromium
- إدخال ChromeStatus.com
- مكوّن Blink:
Blink>Screen>MultiScreen - مراجعة TAG
- النية في إجراء تجربة
الإقرارات
تم تعديل مواصفات Window Management API من قِبل فيكتور كوستان و جوشوا بيل و مايك واسرمان. تم تنفيذ واجهة برمجة التطبيقات من قِبل مايك واسرمان و أدريان ووكر. راجع هذا المستند جو ميدلي وفرانسوا بوفورت وكايسي باسكس. نشكر "لورا تورنت بويغ" على الصور.