Skip to content

Introduce Monitor Layout Manager#423

Open
leonardo-lemos wants to merge 22 commits into
mainfrom
introduce-layout-manager
Open

Introduce Monitor Layout Manager#423
leonardo-lemos wants to merge 22 commits into
mainfrom
introduce-layout-manager

Conversation

@leonardo-lemos
Copy link
Copy Markdown
Collaborator

@leonardo-lemos leonardo-lemos commented May 30, 2025

Fixes #418
Closes #412
Resolves #424

This PR introduces the MonitorLayoutManager class to persist and restore monitor arrangements when changes occur.

We rely on Mutter's DisplayConfig D-Bus interface to detect monitor changes and retrieve the current monitor layout configuration (i.e., virtual monitors or CRTCs). However, there are some edge cases that cause layout issues:

  • Clone Mode (Mirror Mode): When clone mode is enabled, Settings creates a single virtual monitor encompassing all physical monitors with identical coordinates (x=0, y=0). When clone mode is disabled, Settings has no memory of the previous layout and falls back to overlapping display widgets, since all monitors share the same coordinates.

  • Disabling Monitors: When a monitor is disabled, Mutter still reports its existence but omits its coordinates, as it’s no longer part of the active layout. This results in the disabled monitor’s widget overlapping another widget in the UI.

To address these issues, this PR introduces a GSetting to persist monitor layout data, including each monitor's position and transformation. This allows us to restore previous layouts accurately, even after mode toggles or monitor disable events.

Additionally, this PR modifies when the display overlay updates its widgets — now triggered only when monitor changes are detected, ensuring a more stable and consistent display configuration.

@leonardo-lemos leonardo-lemos marked this pull request as ready for review May 31, 2025 23:12
@danirabbit
Copy link
Copy Markdown
Member

I think @jeremypw has some experience in this codebase?

@jeremypw
Copy link
Copy Markdown
Collaborator

jeremypw commented Jun 6, 2025

Its been quite a while since I looked at this plug but I'll try to test this out this weekend.

Copy link
Copy Markdown

@Marukesu Marukesu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some simplifications suggestions.

Comment thread meson.build
Comment thread src/Objects/MonitorLayoutManager.vala Outdated
}

public MonitorLayoutProfile? find_match_layout (string key) {
// Layouts format are 'a{sa{sa{sv}}}'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"a{sa{s(iiu)}}" should be simpler, we don't need the monitor properties be extensible, nor the extra boxing of using variant values.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we want to persist addition properties in future?

Comment thread src/Objects/MonitorLayoutManager.vala Outdated
Comment thread src/Objects/MonitorLayoutManager.vala Outdated
Comment thread src/Objects/MonitorLayoutManager.vala
Comment thread src/Objects/MonitorLayoutManager.vala Outdated
Comment thread src/Objects/MonitorLayoutManager.vala Outdated
Comment thread src/Objects/MonitorLayoutManager.vala
Comment thread src/Objects/MonitorManager.vala Outdated
@flodavid
Copy link
Copy Markdown
Contributor

I have the following error:

(io.elementary.settings:37137): GLib-GIO-CRITICAL **: 03:12:23.570: g_settings_set_value: key 'preferred-display-layouts' in 'io.elementary.settings.display' expects type 'a{sa{sa{sv}}}', but a GVariant of type 'a{s{sa{sa{sv}}}}' was given

It is because you are trying to handle multiple layouts, each with its own hash. Hence {s is missing from the gschema type.

I also have the following error:

(io.elementary.settings:37137): GLib-CRITICAL **: 03:12:23.570: g_variant_builder_add_value: assertion '!GVSB(builder)->prev_item_type || g_variant_is_of_type (value, GVSB(builder)->prev_item_type)' failed

Disabled monitor still overlap active ones. And once the mirror mode was activated, I could no longer deactivate it, as an error window alerting of bad configuration appeared and prevented validating.

@jeremypw
Copy link
Copy Markdown
Collaborator

@leonardo-lemos Hi, if you're still interested in pursuing this, I suggest you break out the code cleanups in order to reduce the diff. I think you are going in the right direction - personally I do not have a problem with a separate class to encompass the layout/settings management - the existing manager is complicated enough as it is. If you prefer, I am willing to work on this as this plug needs some attention.

@leonardo-lemos
Copy link
Copy Markdown
Collaborator Author

@leonardo-lemos Hi, if you're still interested in pursuing this, I suggest you break out the code cleanups in order to reduce the diff. I think you are going in the right direction - personally I do not have a problem with a separate class to encompass the layout/settings management - the existing manager is complicated enough as it is. If you prefer, I am willing to work on this as this plug needs some attention.

@jeremypw Would you mind working on this? I have a newborn right now and don't have much time to dedicate to it.

@jeremypw
Copy link
Copy Markdown
Collaborator

@leonardo-lemos Very understandable! I'll see what I can do to progress this.

@jeremypw jeremypw self-assigned this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

6 participants