feat: disambiguate same-named monitors with relative position labels - #593
Open
utahcon wants to merge 2 commits into
Open
feat: disambiguate same-named monitors with relative position labels#593utahcon wants to merge 2 commits into
utahcon wants to merge 2 commits into
Conversation
utahcon
force-pushed
the
feat/monitor-position-names
branch
from
July 27, 2026 17:37
0ed4ae6 to
6758a6e
Compare
When two or more monitors share the exact same display name, the indicator menu now appends their relative position to the name, e.g. "DELL U2720Q (left)" / "DELL U2720Q (right)", "(top)" / "(bottom)" for stacked monitors, and combined labels like "(top left)" for grids. Mirrored monitors (no distinct position) fall back to numbering, and any colliding labels are numbered so names are always unique. Positions are computed from monitor center points on both the GNOME 49+ Meta.Monitor path (now enriched with width/height from the shell's monitors) and the Gdk subprocess fallback. Position phrases are translated as whole strings so word order can differ per language.
MetaLogicalMonitor exposes no properties to GJS (only get_monitors() and get_number()), so reading logicalMonitor.x/y always yielded undefined and every monitor fell back to (0, 0). Same-named monitors then computed identical center points and were numbered (1)/(2) instead of getting directional labels like (left)/(right). Take x and y from the shell's monitor matched by index, alongside the width and height already sourced there.
utahcon
force-pushed
the
feat/monitor-position-names
branch
from
July 27, 2026 17:43
6758a6e to
5eab6b4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #81.
When two or more monitors are the same model, the indicator menu shows identical names for all of them, so there is no way to tell which layout row belongs to which monitor. This PR appends a relative position label to the name of any monitor that shares its name with another one, e.g.:
DELL U2723QE (left)/DELL U2723QE (right)LG HDR 4K (top)/LG HDR 4K (bottom)ASUS PB278 (top left)/ASUS PB278 (top right)/ASUS PB278 (bottom)Monitors with unique names are left untouched, so nothing changes for setups that aren't affected by the problem.
Why position labels instead of number suffixes
The discussion in #81 originally converged on appending the monitor's number (e.g.
LG Electronics 34" 1,LG Electronics 34" 2). This PR instead implements the relative position labels later suggested by @rloutrel in that thread, for the reason @GuillaumeAmat reported: monitor numbers get reassigned interchangeably every time a monitor is (un)plugged, so a number suffix doesn't reliably tell the user which physical screen a row refers to, while "left"/"right" does. Numbers are still used as a tie-breaker when positions can't disambiguate (e.g. mirrored displays getmiddle 1/middle 2).How it works
src/indicator/monitorNames.tsexposesdisambiguateMonitorNames(), which groups monitors by name and computes a position label only for groups with duplicates.left/middle/righthorizontally andtop/middle/bottomvertically, combined when the group spans both axes (e.g.top right).middle), the labels are numbered (middle 1,middle 2) so every entry stays unambiguous._()rather than composing translated words, since word order differs between languages.Meta.Monitor.get_display_name()path and thegjssubprocess fallback used on older shells.Since
MetaLogicalMonitorexposes no geometry properties to GJS (onlyget_monitors()andget_number()), the GNOME 49+ path now reads x/y/width/height from the shell's monitors matched by monitor index instead of the previous(logicalMonitor as any).xaccess, which silently yielded0for every monitor. Related: #142 describes row-to-monitor confusion of a similar nature, though on an older code path — this PR does not claim to fix it.Test plan
npm run lintpasses andnpm run buildsucceedsv18.0branch: no conflicts, the two files touched here lint clean, and the build succeeds — happy to retarget there if you prefer