April 15, 2025

Multiple monitors support

Here is a short blog entry just to explain the newly added multiple monitor support to View engine.

Screen faces

Each connected monitor gets associated with a screen face in system/view/screens list. You can check that all monitors have been detected correctly using (two monitors in this case):

    >> length? system/view/screens
    == 2

Each screen's /offset indicates the screen position using virtual screen coordinates. The main screen gets a (0, 0) offset. All other screens are positioned relatively to that, in the same virtual space. Screen sizes are also expressed in virtual coordinates. Screen's scaling factor is exposed in the /data facet as a float value.

A simple display-geometry.red script is provided to show how screen faces reflect the monitors topology in that virtual space:


That script will also output the screen details in the console:

    >> do %tests/displays-geometry.red
    1 - offset: (0, 0) size: (3840, 2160) scaling: 150%
    2 - offset: (1165, 2160) size: (1480, 320) scaling: 100%
NB: I am using a little 11.9inch screen below my main display for developing this specific feature, as it takes very little extra space on my desk.


Red apps on multiple screens

You can now launch Red consoles and apps on any display, the app will open on the screen it was launched from, using the specific scaling value of that screen.

A get-current-screen function has been provided to return the current screen (where the mouse cursor is currently located).

When displays have different scaling factor or DPI, View will adjust the window and its content to fit that scaling factor. This also works when dragging a View window between displays with different DPI, the window and its content will resize accordingly.

On Windows, the API View requires, are not supported on pre-Windows8 platforms. So a new  Windows7 compilation target has been added to fallback on an older API that is less accurate and may produce sizing issues.


Known limitations

- Screen offsets are using virtual coordinates, but window offsets are in scaled coordinates (using scaling factor). This is a current implementation constraint and a semantics problem, as we express windows content in a DPI-independent coordinate system, which also affects windows geometry.

- Opening a child window from one screen to another one is currently not supported. It could be achieved manually by forcing a window offset to another virtual space, though the scaled coordinates would make the target offset calculation more complex and will create sizing issues (unless you write a routine that will recalculate all face sizes on the fly).

Fork me on GitHub