Skip to content

Add named attribute access to gnome-monitor.py (New)#1916

Merged
fernando79513 merged 39 commits intomainfrom
typed-gnome-monitors
Jul 22, 2025
Merged

Add named attribute access to gnome-monitor.py (New)#1916
fernando79513 merged 39 commits intomainfrom
typed-gnome-monitors

Conversation

@tomli380576
Copy link
Copy Markdown
Contributor

@tomli380576 tomli380576 commented May 9, 2025

Description

This PR adds complete type annotations and named properties to the original gnome-monitors script to hopefully make it more ergonomic to use. It's not something that needs to be urgently merged so don't worry about this if you have a fire to fix xD

Basically turns this:

state = MonitorConfigGnome().get_current_state()
curr_refresh_rates = {} 

for monitor in state[1]:
    for mode in monitor[1]:
        if mode[6].get("is-current", False):
            curr_refresh_rates[monitor[0][0]] = mode[3]

print(curr_refresh_rates)

into this:

state = MonitorConfigGnome().get_current_state()
curr_refresh_rates = {}

for monitor in state.physical_monitors:
    for mode in monitor.modes:
        if mode.is_current:
            curr_refresh_rates[monitor.info.connector] = mode.refresh_rate

print(curr_refresh_rates)

with nice IDE autocomplete.

#1843 could take advantage of this to more directly access resolution numbers instead of strings

Resolved issues

In the original MonitorConfigGnome, accessing deeply nested properties from the GetCurrentState's return value was a bit awkward. If we need to get the 1st refresh rate of the 1st monitor, we need to write state[1][1][0][1][0][3] which looks like magic numbers without looking at the original dbus xml. The original MonitorConfigGnome provided nice ways to get the resolution strings but all the other properties were not included.

This PR circumvents this magic index situation by providing named attribute access for the return value of GetCurrentState, so now we can write state.physical_monitors[0].modes[0].refresh_rate and only use indices in places where there's an actual array.

Documentation

The main reference point is this xml and gnome-randr

None of the new classes (MutterDisplayConfig, PhysicalMonitor, LogicalMonitor, MonitorInfo) should be directly constructed because they assume that the input GLib.Variant has the correct type. Use MonitorConfigGnome.get_current_state() as the entry point since it asks GLib to do a deep type check first before returning.

  • Is there a way to enforce this?

Tests

Original unit tests

@tomli380576 tomli380576 changed the title Fully typed version of gnome-monitors.py (New) Add named attribute access for gnome-monitors.py (New) May 9, 2025
@tomli380576 tomli380576 force-pushed the typed-gnome-monitors branch from b37882d to 7e759db Compare May 9, 2025 07:28
@codecov
Copy link
Copy Markdown

codecov bot commented May 9, 2025

Codecov Report

❌ Patch coverage is 91.15646% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.99%. Comparing base (c5c19c7) to head (fb7d373).
⚠️ Report is 180 commits behind head on main.

Files with missing lines Patch % Lines
...box-support/checkbox_support/dbus/gnome_monitor.py 87.96% 10 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1916      +/-   ##
==========================================
+ Coverage   50.46%   50.99%   +0.53%     
==========================================
  Files         382      384       +2     
  Lines       41039    41591     +552     
  Branches     6892     7106     +214     
==========================================
+ Hits        20709    21208     +499     
- Misses      19585    19618      +33     
- Partials      745      765      +20     
Flag Coverage Δ
checkbox-support 65.06% <91.15%> (+2.55%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tomli380576 tomli380576 marked this pull request as ready for review May 14, 2025 10:29
@tomli380576 tomli380576 changed the title Add named attribute access for gnome-monitors.py (New) Add named attribute access to gnome-monitor.py (New) May 16, 2025
@fernando79513 fernando79513 self-assigned this May 27, 2025
Copy link
Copy Markdown
Contributor

@hanhsuan hanhsuan left a comment

Choose a reason for hiding this comment

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

Please let me know, if there is some misunderstanding. Thanks.

@tomli380576 tomli380576 force-pushed the typed-gnome-monitors branch from 0e0c2ce to 28ffd4a Compare July 15, 2025 03:34
@tomli380576 tomli380576 requested a review from hanhsuan July 16, 2025 05:30
Copy link
Copy Markdown
Contributor

@hanhsuan hanhsuan left a comment

Choose a reason for hiding this comment

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

LGTM.
Modify the randr_cycle.py as following

from checkbox_support.dbus.gnome_monitor import MutterDisplayMode as Mode

and

if args.cycle == "resolution":
            monitor_config.cycle(
                cycle_resolution=True,
                resolution_filter=resolution_filter,
                cycle_transform=False,
                post_cycle_action=action,
                path=screenshot_path,
            )
        elif args.cycle == "transform":
            monitor_config.cycle(
                cycle_resolution=False,
                resolution_filter=resolution_filter,
                cycle_transform=True,
                post_cycle_action=action,
                path=screenshot_path,
            )
        else:
            monitor_config.cycle(
                cycle_resolution=True,
                resolution_filter=resolution_filter,
                cycle_transform=True,
                post_cycle_action=action,
                path=screenshot_path,
            )

are working as expected.

Copy link
Copy Markdown
Collaborator

@fernando79513 fernando79513 left a comment

Choose a reason for hiding this comment

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

Thank you for this change, It looks like a really nice quality of life improvement.
I just left two small optional comments but overall it LGTM.

I think this can be merged after implementing the suggestion of hanhsuan.
Regarding #1843, should this PR be merged before?

@hanhsuan
Copy link
Copy Markdown
Contributor

I think this can be merged after implementing the suggestion of hanhsuan. Regarding #1843, should this PR be merged before?

Yes, this one could be merged first since #1843 hasn't been reviewed by anyone and the script hasn't been used by any test case. I could rebase my PR to adapt it to this one, which will simplify the process.

Copy link
Copy Markdown
Contributor

@hanhsuan hanhsuan left a comment

Choose a reason for hiding this comment

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

LGTM

@fernando79513 fernando79513 merged commit 7c13717 into main Jul 22, 2025
36 checks passed
@fernando79513 fernando79513 deleted the typed-gnome-monitors branch July 22, 2025 07:53
hanhsuan added a commit that referenced this pull request Jul 22, 2025
stanley31huang pushed a commit that referenced this pull request Aug 14, 2025
* feat: use typed namedtuple for mode and add type annotation for dbus output

* feat: fully typed tuples for getCurrentMode

* feat: add readonly properties for the propmap

* fix: remove main

* refactor: use the new classes for get resolutions and monitors

* fix: 3.5 compatibility

* feat: use native glib type checking

* fix: remove more magic numbers

* style: rename

* style: print msg during cycle(), comments

* fix: use const when possible, comments

* test: update tests for the new api

* fix: remove time.sleep

* fix: override is from typing_extensions

* style: formatting

* fix: remove override

* fix: naming

* fix: preserve 6

* fix: update transformation str

* style: minor naming tweaks

* doc: name

* fix: 1 more type check

* test: increase coverage

* fix: crappy names

* doc: comments

* style: minor name tweak and comments

* doc: annotate logicalmonitorconfig

* style: name and comments

* style: names

* fix: formatting

* doc: incomplete comment

* fix: styles

* doc: more comments

* fix: apply Fernando's suggestions

* fix: add a default post cycle action

* fix: remove debug code

* style: add a finish message

* cleanup: remove debug msg

* fix: bad patching in tests
bladernr pushed a commit that referenced this pull request Aug 28, 2025
* feat: use typed namedtuple for mode and add type annotation for dbus output

* feat: fully typed tuples for getCurrentMode

* feat: add readonly properties for the propmap

* fix: remove main

* refactor: use the new classes for get resolutions and monitors

* fix: 3.5 compatibility

* feat: use native glib type checking

* fix: remove more magic numbers

* style: rename

* style: print msg during cycle(), comments

* fix: use const when possible, comments

* test: update tests for the new api

* fix: remove time.sleep

* fix: override is from typing_extensions

* style: formatting

* fix: remove override

* fix: naming

* fix: preserve 6

* fix: update transformation str

* style: minor naming tweaks

* doc: name

* fix: 1 more type check

* test: increase coverage

* fix: crappy names

* doc: comments

* style: minor name tweak and comments

* doc: annotate logicalmonitorconfig

* style: name and comments

* style: names

* fix: formatting

* doc: incomplete comment

* fix: styles

* doc: more comments

* fix: apply Fernando's suggestions

* fix: add a default post cycle action

* fix: remove debug code

* style: add a finish message

* cleanup: remove debug msg

* fix: bad patching in tests
stanley31huang pushed a commit that referenced this pull request Oct 3, 2025
* feat: use typed namedtuple for mode and add type annotation for dbus output

* feat: fully typed tuples for getCurrentMode

* feat: add readonly properties for the propmap

* fix: remove main

* refactor: use the new classes for get resolutions and monitors

* fix: 3.5 compatibility

* feat: use native glib type checking

* fix: remove more magic numbers

* style: rename

* style: print msg during cycle(), comments

* fix: use const when possible, comments

* test: update tests for the new api

* fix: remove time.sleep

* fix: override is from typing_extensions

* style: formatting

* fix: remove override

* fix: naming

* fix: preserve 6

* fix: update transformation str

* style: minor naming tweaks

* doc: name

* fix: 1 more type check

* test: increase coverage

* fix: crappy names

* doc: comments

* style: minor name tweak and comments

* doc: annotate logicalmonitorconfig

* style: name and comments

* style: names

* fix: formatting

* doc: incomplete comment

* fix: styles

* doc: more comments

* fix: apply Fernando's suggestions

* fix: add a default post cycle action

* fix: remove debug code

* style: add a finish message

* cleanup: remove debug msg

* fix: bad patching in tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants