w3c / window-management

Window Management API
https://www.w3.org/TR/window-management/
Other
96 stars 25 forks source link

No easy way to listen to changes to all screen attributes #51

Open quisquous opened 3 years ago

quisquous commented 3 years ago

Feedback from @cterefinko.

There is an event listener for hearing about the set of screens or changing, and there are individual event listeners per screen to find out about attribute changes. However, to hear about the set of changes to all screen attributes, listeners have to be attached/removed from all screens as they become available.

There wasn't a particular use case in mind here that this is blocking, but is just more general feedback for the api that should be considered.

michaelwasserman commented 3 years ago

IIUC, this feedback was echoed (plus coalescing) by another partner testing the API:

There are 2 types of events - 'screen.change' - that gets fired on individual screen attribute changes, & 'screenschange' event - that gets fired when the set of available screens change. I see that these events are fired as many number of times as the total number of monitors. For example, when the resolution of the screen changes where the window (say Citrix session window) is placed, screen.change event is triggered 3 times, in case 3 monitors are connected.

Would it be possible to have the event fired only once for a change event?

We should indeed try to coalesce more screen change events, but it's not always plausible; e.g. making one display bigger or smaller may cause the OS/WM to move the other displays to keep them adjacent, etc. See this logging example:

screensInterface.screens[0].addEventListener('change', (e) => { const s = e.target; console.log(screens[0].change: bounds:(${s.left},${s.top} ${s.width}x${s.height}) avail:(${s.availLeft},${s.availTop} ${s.availWidth}x${s.availHeight}) screensInterface.screens[1].addEventListener('change', (e) => { const s = e.target; console.log(screens[1].change: bounds:(${s.left},${s.top} ${s.width}x${s.height}) avail:(${s.availLeft},${s.availTop} ${s.availWidth}x${s.availHeight})

// I changed display 0's resolution: VM1286:1 screens[0].change: bounds:(0,0 1600x900) avail:(108,0 1492x900) // Windows automatically moved display 1 to be adjacent: VM1272:1 screens[1].change: bounds:(1600,0 1920x1200) avail:(1600,0 1920x1160) // Windows automatically changed display 0's available work space (for scaling?): VM1286:1 screens[0].change: bounds:(0,0 1600x900) avail:(72,0 1528x900) // Windows automatically changed display 1's available work space (temporarily?): VM1272:1 screens[1].change: bounds:(1600,0 1920x1200) avail:(1600,0 1920x1200) // Windows automatically changed display 1's available work space (reverted?): VM1272:1 screens[1].change: bounds:(1600,0 1920x1200) avail:(1600,0 1920x1160)

Windows itself seems to cause display flickering as it updates the scaling and taskbar dimensions of each display, which is unfortunate, and other OSes have similar jank.

We should strive to coalesce events that occur in rapid succession for each display, but even then, we'd still have one event for each display here, which seems correct, given the final per-screen changes that occur. IIUC, you might like a single event to be fired when any display's attributes change, which would need to coalesce events that occur for any display in rapid succession. Both types of coalescing can be poly-filled and tuned to the needs of the individual site, but this might be a reasonable request.

See also http://crbug.com/1077367