Blog
All Blog Posts | Next Post | Previous PostManaging displays with the Multi-Screen Window Placement API
Tuesday, April 19, 2022
With the release of Google Chrome 100 came the new Multi-Screen Window Placement API. This API allows you to enumerate the displays connected to your machine and to place windows on specific screens. We've wrapped this API with TMS WEB Core, so that you can use this inside your Web Applications with minimal effort.
Before we had this API, we could use the window.open() to control windows. This method however, is unaware of additional screens. We can specify the position by passing the coordinates as left and top and pass the size as width and height. To get the information about the current screen we could check the window.screen property.
How to use
First of all we have to check if the API is supported. we can simply do this by calling the GetScreenAvailability function. this will return true if it is supported.
screens := await(TJSScreeninfo, GetScreensInfo); screens.OnCurrentScreenChange := DoCurrentScreensChange; screens.OnScreensChange := DoScreensChanged;
The Screens object also has 2 events:
- OnCurrentScreenChange: This event updates the screens object when the web application changes screen.
- OnScreenChange: This event updates the screens object when the browser detects that the displays have been changed.(i.e. adding/removing a display)
The Screens object looks like this on my machine. As you can see I have to 2 Displays connected to my machine. And my CurrentScreen is "External Display 2" which is not my primary screen. Using the left and top properties of the TJSScreenDetails object, we can accurately position our window wherever we want on the display that you want.
Before we can use the Multi-Screen Window Placement API we must ask the user for permission to use it. To do this, we can call the GetPermissions function. Be aware that this function is asynchronous. so you'll have to await it. you can use it like this:
allowed := await(boolean, GetPermissions);
Weather around the world!
Using this API we made a demo application that let's you check the weather in several locations all around the world. If you have a multi display setup the weather popups will be shown on the screen the web application is not currently on.
The result will be something like this when clicking the button.
Screen 1:
Screen 2:
And a screenshot from both screens together:
To make this possible, we simply calculate how large the windows can be if we want to show a 5 x 2 table of windows.
w := Math.floor((screens.screens[i].availableWidth - FColumns * 1) / FColumns); h := Math.floor((screens.screens[i].availableHeight - FRows * 51) / FRows);
for j := 0 to FColumns -1 do begin for k := 0 to FRows -1 do begin x := j * w + screens.screens[i].availableLeft + j * 1; y := k * h + screens.screens[i].availableTop + k * 51; Features := '' + 'screenX=' + IntToStr(x)+ ',' + 'screenY=' + IntToStr(y)+ ',' + 'width=' + IntToStr(w)+ ',' + 'height=' + IntToStr(h)+ ',' + 'menubar=' + BoolToStr(false)+ ',' + 'toolbar=' + BoolToStr(false)+ ',' + 'location=' + BoolToStr(false)+ ',' + 'status=' + BoolToStr(false)+ ',' + 'resizable=' + BoolToStr(true)+ ',' + 'scrollbars=' + BoolToStr(false) + ''; Popup := createPopup(Features, FCountrys[CountryIndex]); if Popup = nil then begin CloseAllPopups; window.alert('It looks like you are blocking popup windows. Please allow them as outlined at https://goo.gle/allow-popups.'); exit; end; Popup.addEventListener('beforeunload',@DoClosePopUp); Popups.push(PopUp); inc(CountryIndex); end; end;
try the live demo here and download the source code here!
Bradley Velghe
This blog post has received 1 comment.
All Blog Posts | Next Post | Previous Post
jeffam70