الحصول على معلومات عن الشاشات المتّصلة وتحديد مواضع النوافذ بالنسبة إلى هذه الشاشات
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
*/
مثل معظم العاملين في مجال التكنولوجيا، اضطررت إلى التأقلم مع واقع العمل الجديد وإعداد مكتبي الشخصي في المنزل. يبدو جهازي كما هو موضّح في الصورة أدناه (إذا أردت، يمكنك قراءة التفاصيل الكاملة حول الإعداد). إنّ جهاز 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);
}
حشو بوليستر
لا يمكن استخدام تقنية الملء البيني لواجهة برمجة التطبيقات 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 الأخيرة. لقد فاجأني تمامًا وتركني أضع يدي على وجهي.
يمكنك تشغيل الإصدار التجريبي المضمّن أدناه، أو الاطّلاع على رمز المصدر على glitch.
الأمان والأذونات
لقد صمم فريق Chrome واجهة برمجة التطبيقات Window Management API ونفّذها باستخدام مبادئ أساسية تم تحديدها في مقالة التحكّم في الوصول إلى ميزات فعّالة لمنصّة الويب، بما في ذلك عناصر التحكّم التي يستخدمها المستخدم والشفافية وسهولة الاستخدام. تعرض واجهة برمجة التطبيقات Window Management API معلومات جديدة عن الشاشات المتصلة بالجهاز، ما يزيد من مساحة جمع معلومات بصمة المستخدمين، خاصةً أولئك الذين لديهم شاشات متعددة متصلة بأجهزة باستمرار. وكأحد الحلول للتخفيف من هذه المخاوف المتعلّقة بالخصوصية، تقتصر خصائص الشاشة المعروضة على الحد الأدنى المطلوب لحالات استخدام مواضع الإعلان الشائعة. يجب الحصول على إذن المستخدم لكي تتمكّن المواقع الإلكترونية من الحصول على معلومات عن الشاشات المتعدّدة ووضع النوافذ على شاشات أخرى. في حين أنّ Chromium يعرض تصنيفات تفصيلية للشاشة، يمكن للمتصفّحات عرض تصنيفات أقل وصفًا (أو حتى تصنيفات فارغة).
التحكّم في المستخدم
يمكن للمستخدم التحكّم بشكل كامل في مستوى ظهور الإعداد. يمكنهم قبول طلب منح الإذن أو رفضه، وإبطال إذن سبق منحه من خلال ميزة معلومات الموقع الإلكتروني في المتصفّح.
التحكّم في المؤسسة
يمكن لمستخدمي Chrome Enterprise التحكّم في عدة جوانب من واجهة برمجة التطبيقات Window Management API كما هو موضح في القسم ذي الصلة من إعدادات مجموعات السياسات الأساسية.
الشفافية
يتم عرض ما إذا تم منح الإذن لاستخدام واجهة برمجة التطبيقات Window Management API في معلومات الموقع الإلكتروني للمتصفّح، ويمكن أيضًا إجراء طلب بحث من خلال واجهة برمجة التطبيقات Permissions API.
الاحتفاظ بالأذونات
يحفظ المتصفّح أذونات الاستخدام الممنوحة. يمكن إلغاء الإذن من خلال معلومات الموقع الإلكتروني في المتصفّح.
ملاحظات
يريد فريق Chrome معرفة تجاربك مع واجهة برمجة التطبيقات Window Management API.
أخبِرنا عن تصميم واجهة برمجة التطبيقات.
هل هناك مشكلة في واجهة برمجة التطبيقات لا تعمل على النحو المتوقّع؟ هل هناك طُرق أو سمات مفقودة تحتاجها لتنفيذ فكرتك؟ هل لديك سؤال أو تعليق حول ملف أمان الحساب؟
- يمكنك إرسال مشكلة في المواصفات إلى مستودع GitHub المقابل، أو إضافة أفكارك إلى مشكلة حالية.
الإبلاغ عن مشكلة في التنفيذ
هل رصدت خطأ في عملية تنفيذ Chrome؟ أم أنّ عملية التنفيذ مختلفة عن المواصفات؟
- يمكنك إرسال بلاغ عن خلل على الرابط new.crbug.com. احرص على تضمين أكبر قدر ممكن من التفاصيل، وتعليمات بسيطة لإعادة إنتاج الخلل، وأدخِل
Blink>Screen>MultiScreen
في مربّع المكوّنات. يُعدّ تطبيق Glitch مثاليًا لمشاركة عمليات إعادة الإنتاج بسرعة وسهولة.
إظهار الدعم لواجهة برمجة التطبيقات
هل تخطّط لاستخدام واجهة برمجة التطبيقات Window Management API؟ يساعد دعمك العلني فريق Chrome في تحديد أولويات الميزات ويُظهر لموفّري المتصفّحات الآخرين مدى أهمية توفير هذه الميزات.
- شارِك كيفية استخدامك له في سلسلة محادثات Discourse في WICG.
- أرسِل تغريدة إلى @ChromiumDev باستخدام الهاشتاغ
#WindowManagement
و أخبِرنا بالمكان الذي تستخدم فيه هذه الميزة وطريقة استخدامك لها. - اطلب من مورّدي المتصفّحات الآخرين تنفيذ واجهة برمجة التطبيقات.
روابط مفيدة
- مسودة المواصفات
- شرح موجز للجمهور العام
- العرض التجريبي لواجهة برمجة التطبيقات Window Management API | العرض التجريبي لواجهة برمجة التطبيقات Window Management API source
- خطأ في تتبُّع Chromium
- إدخال ChromeStatus.com
- عنصر Blink:
Blink>Screen>MultiScreen
- مراجعة العلامة
- الهدف من التجربة
الشكر والتقدير
تم تعديل مواصفات Window Management API من قِبل Victor Costan و Joshua Bell و Mike Wasserman. نفَّذ واجهة برمجة التطبيقات كلّ من مايك واسرمان و أدريان ووكر. تمت مراجعة هذه المقالة من قِبل جو ميديل وفرنسوا بافوي وكايسي باسكيز. نشكر Laura Torrent Puig على الصور.