We don't want to do the work of the layout mode detection and conversion
every time we read the monitors.xml file.
Instead, when the detection logic is used, set a flag to automatically
update the config files after the parsing is finished.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3596>
Introduce some "best effort" conversion code to migrate monitor configurations
from PHYSICAL (the old default) to LOGICAL (the new default on wayland)
layout mode.
This conversion will only be used when the old PHYSICAL layout-mode
configuration is not compatible with the new LOGICAL layout-mode one.
This only applies if 1) there's a monitor that needs scaling in the
layout, and 2) the scaled monitor comes before other monitors in the
coordinate system (ie. it's not the rightmost or bottommost monitor).
There are two algorithms added here to convert monitor layouts:
- One for "simple" 1-dimensional monitor layouts, where all monitors are
aligned on a vertical or horizontal strip.
Here's a few (inaccurate) examples of how this would look with different
layouts (left side is PHYSICAL, right side is LOGICAL, x is the origin of
the coordinate system, the numbers are scales of the monitors):
```
x──────┬──────┬──────┐ x ┌──────┐
│ 2 │ 1 │ 2 │ 2┌──┤ 1 ├──┐2
│ │ │ │ ──► └──┤ ├──┘
└──────┴──────┴──────┘ └──────┘
x ┌──────┐ x ┌──────┐
┌────┤ 1 │ ┌──┤ 1 │
│ 2 │ │ ──► └──┤ │
└────┴──────┘ 2 └──────┘
x ┌────┐
┌──────┤ │ x──────┐
│ │ │ │ ├─┬────┐
│ 1 │ 3 │ ──► │ 1 │3│ 1 │
│ │ │ │ ├─┴────┘
└──────┤ │ └──────┘
│ ├────┐
│ │ 1 │
└────┴────┘
```
- A second more complex algorithm for 2-dimensional monitor layouts with
a common baseline that all monitors are aligned to.
And examples for this one:
```
x ┌──────┐
┌──────┤ │
│ 1 │ 2 │ x──────┐
│ │ │ │ 1 ├────┐
└──┬───┴───┬──┘ ──► │ │ 2 │
│ 3 │ ├──┬───┴────┘
│ │ └──┘3
└───────┘
x ┌──────┬──────┐
│ 1 │ │
│ │ │ x──────┬──────┐
┌─────┴──────┤ 1 │ │ 1 │ │
│ │ │ │ │ │
│ │ │ ──► └──┬───┤ 1 │
│ 3 │ │ │ 3 │ │
│ ├──────┘ └───┤ │
│ │ │ │
│ │ └──────┘
└────────────┘
x ┌───────┐
┌──────┐ │ │ x ┌───────┐
│ 2 │ ┌──────┤ 1 │ │ │
│ │ │ 1 │ │ 2 ┌──────┤ 1 │
└────┬─┴────┴─┬────┴───────┘ ──► ┌──┤ 1 │ │
│ │ ├──┴┬─────┴───────┘
│ 2 │ │ 2 │
│ │ └───┘
└────────┘
```
These algorithms will fail for any more complex 2d monitor layout, eg.
```
x ┌───┬────┐
│ 2 │ 1 │
│ ├────┘
┌───┴┬──┘
│ 1 │
└────┘
x───┬───┬───┐
│ 1 │ 2 │ 1 │
├───┼───┼───┤
│ 1 │ 1 │ 1 │
├───┼───┼───┤
│ 1 │ 1 │ 1 │
└───┴───┴───┘
```
In those cases where the conversion failed, we fall back to aligning
the monitors on a horizontal line, preserving the scale, the primary
monitor and the disabled monitors.
Note that we also need to convert the scale factor in some cases,
because LOGICAL layout mode also behaves different here:
When the scale results in a fractional logical monitor size (eg.
the native monitor width is 2560px, and a scale of 3 is set =>
2560px / 3 = 853.333px), in LOGICAL mode we won't use that scale.
Instead we have an algorithm (see
meta_monitor_get_closest_scale_factor_for_resolution()) to find
the nearest fractional scale factor which doesn't result in
fractional logical monitor size. We reuse this algorithm here for
the conversion.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3596>
When there is no layout mode set in a logical monitor config, we currently just
assume the configuration matches the mode that the system expects. This blows
up when the layout mode expected by the system changes (eg. by turning on
"scale-monitor-framebuffers" in mutter): Suddenly configs fail the validation
check and get thrown away.
Since we now can add one configuration for each layout mode to the config store,
we can do better here: Let's only add configurations to the store where we
verified beforehand that the monitor layout is compatible with that mode, either
because we set it ourselves using the <layout_mode> key, or by detecting which
modes the layout is compatible with.
Also update monitor config ifiles to adjust for the new layout_mode, as
they all are assumed to be "logical".
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3596>
Store and load the layout mode for each logical monitor configuration in
monitors.xml by introducing a new <layoutmode> element. The value of the
element can be either "logical" or "physical". The layout mode is also
made part of the monitor configuration key.
Right now this isn't doing a lot:
When no <layoutmode> is found on the config (this is the case with all
existing configs), we'll keep using the layout mode expected by the system,
without updating the config file.
When changing an existing, or introducing a new configuration, we'll now
store the current layout mode with the config though, and load it again
on the next start of mutter. This is still not problematic as long as
mutters expected layout mode doesn't change (eg. by turning on/off
"scale-monitor-framebuffers").
When the expected layout mode of mutter switches between
restarts, the monitor config is now still loaded but remains unused,
and mutter will create (and store) a new one with the other layout mode.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3596>
We'll introduce some new migration code with the next few commits to introduce
a layout_mode property in monitors.xml. This will be significantly easier
without keeping around the old monitor migration code, so drop it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3596>
When a configuration has a fractional scale, but we're using a physical
monitor layout, we can't use the scale, but if we do, we end up with
wierd issues down the line. Just discard the config if we run into this.
Eventually we probably want to store the layout mode in the
configuration so we can handle more seamless switching between physical
and logical layout mode, but first do this.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3057
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3299>
Dropped obsolete Free Software Foundation address pointing
to the FSF website instead as suggested by
https://www.gnu.org/licenses/gpl-howto.html
keeping intact the important part of the historical notice
as requested by the license.
Resolving rpmlint reported issue E: incorrect-fsf-address.
Signed-off-by: Sandro Bonazzola <sbonazzo@redhat.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3155>
Adding a <dbus/> element containing a boolean (yes/no) determines
whether org.gnome.Mutter.DisplayConfig ApplyMonitorsConfig will be
callable. The state is also introspectable via the
ApplyMonitorsConfigAllowed property on the same interface.
For example
<monitors version="2">
<policy>
<dbus>no</dbus>
</policy>
</monitors>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2030>
This adds a way to define a way, at the system level, to define a policy
of how monitor configuration files are loaded.
The intended use case is to e.g. either prefer system level monitor
configurations before user levels, or only allow system level
configurations.
Examples:
Prefer system over user level configurations:
<monitors version="2">
<policy>
<stores>
<store>system</store>
<store>user</store>
</stores>
</policy>
<configuration>
...
</configuration>
</monitors>
Only allow system level configurations:
<monitors version="2">
<policy>
<stores>
<store>system</store>
</stores>
</policy>
<configuration>
...
</configuration>
</monitors>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2030>
strncmp() always return 0 if the passed length is 0. What this means is
that whatever the first string check happens to be, if the parsed XML
cdata was empty (e.g. if we got <element></element>), the first
condition would evaluate to true, which is rather unexpected.
Fix this by making sure the string length is correct first. Also move it
into a helper so we don't need to repeat the same strlen() check every
time.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2030>
Makes sure that monitor specs which may be read from EDID data do not
contain characters that are invalid in XML. Makes it possible to restore
monitor configs of monitor models with characters such as '&' in them.
To make this change not break any tests, the sample monitor configs need
to be adjusted as well. Apostrophes don't strictly have to be escaped in
XML text elements. However, we now do escape the elements in
`<monitorspec>` specifically.
Closes: <https://gitlab.gnome.org/GNOME/mutter/-/issues/1011>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1685>
When saving and restoring monitor configurations, we must take disabled
monitors into account, as otherwise one cannot store/restore a
configuration where one or more monitors are explicitly disabled. Make
this possible by adding a <disabled> element to the <configure> element
which lists the monitors that are explicitly disabled. These ones are
included when generating the configuration key, meaning they'll be
picked up correctly.
https://bugzilla.gnome.org/show_bug.cgi?id=787629
We currently only save synchronously when running the test suite, but
should still not leak the generated config buffer. We also created the
cancellable but never used it if we saved synchronously, so lets stop
doing that too.
https://bugzilla.gnome.org/show_bug.cgi?id=787477
The cancellable should only be cleared if we weren't cancelled, as if
we were cancelled, the path cancelling have already cleared the
cancellable.
https://bugzilla.gnome.org/show_bug.cgi?id=787477
This commit changes the new configuration system to use monitors.xml
instead of monitors-experimental.xml. When starting up and the
monitors.xml file is loaded, if a legacy monitors.xml file is
discovered (it has the version number 1), an attempt is made to migrate
the stored configuration onto the new system.
This is done in two steps:
1) Parsing and translation of the old configuration. This works by
parsing file using the mostly the old parser, but then translating the
resulting configuration structs into the new configuration system. As
the legacy configuration system doesn't carry over some state (such as
tiling and scale used), some things are not available. For tiling, the
migration paths makes an attempt to discover tiled monitors by
comparing EDID data, and guessing what the main tile is. Determination
of the scale of a migrated configuration is postponed until the
configuration is actually applied. This works by flagging the
configuration as 'migrated'.
2) Finishing the migration when applying. When a configuration with the
'migrated' flag is retrieved from the configuration store, the final
step of the migration is taken place. This involves calculating the
preferred scale given the mode configured, while making sure this
doesn't result in any overlapping logical monitor regions etc.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
Differentiate between non-interlaced and interlaced modes. This is done
by appending an "i" after the resolution part of the mode ID, and
adding a 'is-interlaced' (b) property to the mode properties.
https://bugzilla.gnome.org/show_bug.cgi?id=765011
When calculating sizes given some size and a fractional logical monitor
scale with precision loss, round the result of the floating point
calculation to the closest integer, as otherwise we might end up with
result smaller by 1 if there was a loss of precision when calculating
the scale.
https://bugzilla.gnome.org/show_bug.cgi?id=765011
When the logical layout mode is used, allow configuring the scaling to
be non-integer. Supported scales are so far hard coded to include at
most 1, 1.5 and 2, and scales that doesn't result in non-fractional
logical monitor sizes are discarded.
Wayland outputs are set to have scale ceil(actual_scale) meaning well
behaving Wayland clients will provide buffers with buffer scale 2, thus
being scaled down to the fractional scale.
https://bugzilla.gnome.org/show_bug.cgi?id=765011
This commit makes it possible to configure logical monitor scale also
when running on top of an X11 server using Xrandr. An extra property
'requires-globla-scale' is added to the D-Bus API is added to instruct
a configuration application to only allow setting a global logical
monitor scale.
This is needed to let gsd-xsettings use the configured state to set a
XSettings state that respects the explicit monitor configuration.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
g_hash_table_insert() doesn't replace the key. This was a problem
because the key was owned by the value inserted into the hash table, so
when a value was removed, the key was freed, meaning that the key in
the hash table was no pointing to freed memory. Fix this by using
g_hash_table_replace() instead, which work the same except that it
replaces the key with the one passed. This means that the key of a
value in the hash table is always the key owned by the value.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
When told to, MetaMonitorConfigStore will save the current
configuration state by replacing the monitors-experimental.xml file
(while backing a backup).
https://bugzilla.gnome.org/show_bug.cgi?id=777732
Adds a <transform> element to <logicalmonitor>. It has two possible sub
elemenst: <rotation> which can be normal, right, left or upside_down,
and <flipped> which can either be true or false.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
The logical monitor config array ownership was transferred to the
config object when it was created, but was not unset when the config
verification failed, causing the clean up path for invalid configs to
try to clean up the same list again.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit adds support for rendering onto enlarged per logical
monitor framebuffers, using the scaled clutter stage views, for HiDPI
enabled logical monitors.
This works by scaling the mode of the monitors in a logical monitors by
the scale, no longer relying on scaling the window actors and window
geometry for making windows have the correct size on HiDPI monitors.
It is disabled by default, as in automatically created configurations
will still use the old mode. This is partly because Xwayland clients
will not yet work good enough to make it feasible.
To enable, add the 'scale-monitor-framebuffer' keyword to the
org.gnome.mutter.experimental-features gsettings array.
It is still possible to specify the mode via the new D-Bus API, which
has been adapted.
The adaptations to the D-Bus API means the caller need to be aware of
how to position logical monitors on the stage grid. This depends on the
'layout-mode' property that is used (see the DisplayConfig D-Bus
documentation).
https://bugzilla.gnome.org/show_bug.cgi?id=777732