From 8b1067763961b02769ade84a6bab7d1e1f3538fd Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Mon, 4 Nov 2024 09:46:37 +0800 Subject: [PATCH 01/14] Add cycler method for cycling change the resolution and transform to replace the old gnome_randr_cycle.py. --- .../checkbox_support/dbus/gnome_monitor.py | 109 +++++++++++++++++- .../dbus/tests/test_gnome_monitor.py | 85 ++++++++++++++ 2 files changed, 192 insertions(+), 2 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index 43fb4e1ccc..e1c6da41ca 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -22,8 +22,10 @@ """ from collections import namedtuple -from typing import Dict, List, Tuple, Set +from typing import Dict, List, Tuple, Set, Callable, Any from gi.repository import GLib, Gio +from fractions import Fraction +import itertools from checkbox_support.monitor_config import MonitorConfig @@ -85,7 +87,9 @@ def set_extended_mode(self) -> Dict[str, str]: position_x = 0 for monitor, modes in state[1].items(): try: - target_mode = next(mode for mode in modes if mode.is_preferred) + target_mode = next( + mode for mode in modes if mode.is_preferred + ) except StopIteration: target_mode = self._get_mode_at_max(modes) extended_logical_monitors.append( @@ -104,6 +108,107 @@ def set_extended_mode(self) -> Dict[str, str]: self._apply_monitors_config(state[0], extended_logical_monitors) return configuration + def cycler( + self, + res: bool = True, + max_res_amount: int = 5, + trans: bool = False, + log: Callable[str, Any] = None, + action: Callable[str, Any] = None, + **kwargs + ): + """ + Cycling change the monitors configurations automatically + + Args: + res: Cycling the resolution or not. + + max_res_amount: The supported resolution might be a lot + and this could limited test amount. + + trans: Cycling the transform or not. + + log: For logging, the string is constructed by + [monitor name]_[resolution]_[transform]_. + + action: For extra steps for each cycle, + the string is constructed by + [monitor name]_[resolution]_[transform]_. + Please note that the delay is needed inside this + callback to wait the monitors to response + """ + monitors = [] + modes_list = [] + # ["normal": 0, "left": 1, "inverted": 6, "right": 3] + trans_list = [0, 1, 6, 3] if trans else [0] + + # for multiple monitors, we need to create res combination + state = self._get_current_state() + for monitor, modes in state[1].items(): + monitors.append(monitor) + modes_list.append(self._resolution_filter(modes, max_res_amount)) + mode_combination = list(itertools.product(*modes_list)) + + for mode in mode_combination: + for trans in trans_list: + logical_monitors = [] + position_x = 0 + m_list = list(mode) + uni_string = "" + for monitor in monitors: + m = m_list.pop(0) + uni_string += "{}_{}_{}_".format( + monitor, + m.resolution, + { + 0: "normal", + 1: "left", + 3: "right", + 6: "inverted", + }.get(trans), + ) + logical_monitors.append( + ( + position_x, + 0, + 1.0, + trans, + position_x == 0, # first monitor is primary + [(monitor, m.id, {})], + ) + ) + # left and right should convert x and y + xy = 1 if (trans == 1 or trans == 3) else 0 + position_x += int(m.resolution.split("x")[xy]) + self._apply_monitors_config(state[0], logical_monitors) + if log: + log(uni_string, **kwargs) + if action: + action(uni_string, **kwargs) + if not res: + break + # change back to preferred monitor configuration + self.set_extended_mode() + + def _resolution_filter(self, modes: List[Mode], max_res_amount: int): + new_modes = [] + tmp_resolution = [] + sort_modes = sorted( + modes, key=lambda m: int(m.resolution.split("x")[0]), reverse=True + ) + for m in sort_modes: + width, height = [int(x) for x in m.resolution.split("x")] + aspect = Fraction(width, height) + if width < 675 or width / aspect < 530: + continue + if m.resolution in tmp_resolution: + continue + if len(new_modes) >= max_res_amount: + break + new_modes.append(m) + tmp_resolution.append(m.resolution) + return new_modes + def _get_current_state(self) -> Tuple[str, Dict[str, List[Mode]]]: """ Using DBus signal 'GetCurrentState' to get the available monitors diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index cda56c2108..7df30abe02 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -230,3 +230,88 @@ def test_set_extended_mode(self, mock_dbus_proxy): "HDMI-1": "2560x1440", } self.assertDictEqual(configuration, expected) + + @patch("checkbox_support.dbus.gnome_monitor.Gio.DBusProxy") + def test_cycler(self, mock_dbus_proxy): + """ + Test the cycler could get the right monitors configuration + and send to ApplyMonitorsConfig. + """ + + mock_proxy = Mock() + mock_dbus_proxy.new_for_bus_sync.return_value = mock_proxy + + gnome_monitor = MonitorConfigGnome() + mock_proxy.call_sync.return_value = ( + 1, + [ + ( + ("eDP-1", "LGD", "0x06b3", "0x00000000"), + [ + ( + "1920x1200@59.950", + 1920, + 1200, + 59.950172424316406, + 1.0, + [1.0, 2.0], + { + "is-current": GLib.Variant("b", True), + "is-preferred": GLib.Variant("b", True), + }, + ) + ], + { + "is-builtin": GLib.Variant("b", True), + "display-name": GLib.Variant("s", "Built-in display"), + }, + ), + ( + ("HDMI-1", "LGD", "0x06b3", "0x00000000"), + [ + ( + "2560x1440@59.950", + 2560, + 1440, + 59.950172424316406, + 1.0, + [1.0, 2.0], + { + "is-current": GLib.Variant("b", True), + "is-preferred": GLib.Variant("b", True), + }, + ) + ], + { + "is-builtin": GLib.Variant("b", False), + "display-name": GLib.Variant("s", "External Display"), + }, + ), + ], + [], + {}, + ) + gnome_monitor.cycler() + + logical_monitors = [ + (0, 0, 1.0, 0, True, [("eDP-1", "1920x1200@59.950", {})]), + (1920, 0, 1.0, 0, False, [("HDMI-1", "2560x1440@59.950", {})]), + ] + + expected_logical_monitors = GLib.Variant( + "(uua(iiduba(ssa{sv}))a{sv})", + ( + 1, + 1, + logical_monitors, + {}, + ), + ) + + mock_proxy.call_sync.assert_called_with( + method_name="ApplyMonitorsConfig", + parameters=expected_logical_monitors, + flags=Gio.DBusCallFlags.NONE, + timeout_msec=-1, + cancellable=None, + ) From faa222b5704afb82e3c3e78aa36c7398378067dc Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Mon, 4 Nov 2024 10:27:58 +0800 Subject: [PATCH 02/14] 1. fox black error 2. try to fix TypeError --- checkbox-support/checkbox_support/dbus/gnome_monitor.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index e1c6da41ca..1a2347f56b 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -87,9 +87,7 @@ def set_extended_mode(self) -> Dict[str, str]: position_x = 0 for monitor, modes in state[1].items(): try: - target_mode = next( - mode for mode in modes if mode.is_preferred - ) + target_mode = next(mode for mode in modes if mode.is_preferred) except StopIteration: target_mode = self._get_mode_at_max(modes) extended_logical_monitors.append( @@ -113,8 +111,8 @@ def cycler( res: bool = True, max_res_amount: int = 5, trans: bool = False, - log: Callable[str, Any] = None, - action: Callable[str, Any] = None, + log: Callable[[str, ...], Any] = None, + action: Callable[[str, ...], Any] = None, **kwargs ): """ From 3a9d4c8683d2e85634d877b2a84e6ceb6ebf1b26 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Mon, 4 Nov 2024 10:33:44 +0800 Subject: [PATCH 03/14] fix Callable TypeError --- checkbox-support/checkbox_support/dbus/gnome_monitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index 1a2347f56b..3dc3b9b80e 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -111,8 +111,8 @@ def cycler( res: bool = True, max_res_amount: int = 5, trans: bool = False, - log: Callable[[str, ...], Any] = None, - action: Callable[[str, ...], Any] = None, + log: Callable[..., Any] = None, + action: Callable[..., Any] = None, **kwargs ): """ From 2b942671a7335f09c6cba84d6c07f8ee94deff90 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Mon, 4 Nov 2024 10:48:57 +0800 Subject: [PATCH 04/14] Add more unit test --- .../dbus/tests/test_gnome_monitor.py | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index 7df30abe02..06ed727194 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -315,3 +315,95 @@ def test_cycler(self, mock_dbus_proxy): timeout_msec=-1, cancellable=None, ) + + @patch("checkbox_support.dbus.gnome_monitor.Gio.DBusProxy") + def test_cycler_no_cycling(self, mock_dbus_proxy): + """ + Test the cycler could get the right monitors configuration + (without res and trans change) and send to ApplyMonitorsConfig. + """ + + mock_proxy = Mock() + mock_dbus_proxy.new_for_bus_sync.return_value = mock_proxy + + gnome_monitor = MonitorConfigGnome() + mock_proxy.call_sync.return_value = ( + 1, + [ + ( + ("eDP-1", "LGD", "0x06b3", "0x00000000"), + [ + ( + "1920x1200@59.950", + 1920, + 1200, + 59.950172424316406, + 1.0, + [1.0, 2.0], + { + "is-current": GLib.Variant("b", True), + "is-preferred": GLib.Variant("b", True), + }, + ) + ], + { + "is-builtin": GLib.Variant("b", True), + "display-name": GLib.Variant("s", "Built-in display"), + }, + ), + ( + ("HDMI-1", "LGD", "0x06b3", "0x00000000"), + [ + ( + "2560x1440@59.950", + 2560, + 1440, + 59.950172424316406, + 1.0, + [1.0, 2.0], + { + "is-current": GLib.Variant("b", True), + "is-preferred": GLib.Variant("b", True), + }, + ) + ], + { + "is-builtin": GLib.Variant("b", False), + "display-name": GLib.Variant("s", "External Display"), + }, + ), + ], + [], + {}, + ) + # mock callback + mock_callback = MagicMock() + gnome_monitor.cycler( + res=False, trans=False, log=mock_callback, action=mock_callback + ) + + logical_monitors = [ + (0, 0, 1.0, 0, True, [("eDP-1", "1920x1200@59.950", {})]), + (1920, 0, 1.0, 0, False, [("HDMI-1", "2560x1440@59.950", {})]), + ] + + expected_logical_monitors = GLib.Variant( + "(uua(iiduba(ssa{sv}))a{sv})", + ( + 1, + 1, + logical_monitors, + {}, + ), + ) + + mock_proxy.call_sync.assert_called_with( + method_name="ApplyMonitorsConfig", + parameters=expected_logical_monitors, + flags=Gio.DBusCallFlags.NONE, + timeout_msec=-1, + cancellable=None, + ) + mock_callback.assert_called_with( + "eDP-1_1920x1200_normal_HDMI-1_2560x1440_normal_" + ) From a95553cadcb4745f5477facd77fd402501aaa00a Mon Sep 17 00:00:00 2001 From: hanhsuan <32028620+hanhsuan@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:01:40 +0800 Subject: [PATCH 05/14] Apply suggestions from code review Co-authored-by: Paolo Gentili --- checkbox-support/checkbox_support/dbus/gnome_monitor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index 3dc3b9b80e..966b7cbd85 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -106,7 +106,7 @@ def set_extended_mode(self) -> Dict[str, str]: self._apply_monitors_config(state[0], extended_logical_monitors) return configuration - def cycler( + def cycle( self, res: bool = True, max_res_amount: int = 5, @@ -116,13 +116,13 @@ def cycler( **kwargs ): """ - Cycling change the monitors configurations automatically + Automatically cycle through the supported monitor configurations. Args: res: Cycling the resolution or not. - max_res_amount: The supported resolution might be a lot - and this could limited test amount. + max_res_amount: Limit the number of tested configurations + to avoid an unnecessarily large test matrix. trans: Cycling the transform or not. From bbbc266a85e523ee2e4d736a5b60043b91fe7cea Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Wed, 27 Nov 2024 13:25:06 +0800 Subject: [PATCH 06/14] change method name from cycler to cycle --- .../dbus/tests/test_gnome_monitor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index 06ed727194..c807356ee8 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -232,9 +232,9 @@ def test_set_extended_mode(self, mock_dbus_proxy): self.assertDictEqual(configuration, expected) @patch("checkbox_support.dbus.gnome_monitor.Gio.DBusProxy") - def test_cycler(self, mock_dbus_proxy): + def test_cycle(self, mock_dbus_proxy): """ - Test the cycler could get the right monitors configuration + Test the cycle could get the right monitors configuration and send to ApplyMonitorsConfig. """ @@ -291,7 +291,7 @@ def test_cycler(self, mock_dbus_proxy): [], {}, ) - gnome_monitor.cycler() + gnome_monitor.cycle() logical_monitors = [ (0, 0, 1.0, 0, True, [("eDP-1", "1920x1200@59.950", {})]), @@ -317,9 +317,9 @@ def test_cycler(self, mock_dbus_proxy): ) @patch("checkbox_support.dbus.gnome_monitor.Gio.DBusProxy") - def test_cycler_no_cycling(self, mock_dbus_proxy): + def test_cycle_no_cycling(self, mock_dbus_proxy): """ - Test the cycler could get the right monitors configuration + Test the cycle could get the right monitors configuration (without res and trans change) and send to ApplyMonitorsConfig. """ @@ -378,7 +378,7 @@ def test_cycler_no_cycling(self, mock_dbus_proxy): ) # mock callback mock_callback = MagicMock() - gnome_monitor.cycler( + gnome_monitor.cycle( res=False, trans=False, log=mock_callback, action=mock_callback ) From 9d80dc4e5cae4da33eaf4db19264255bf23745aa Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Fri, 29 Nov 2024 13:53:29 +0800 Subject: [PATCH 07/14] 1. change trans to transform 2. zip monitors and mode to make loop easier --- .../checkbox_support/dbus/gnome_monitor.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index 966b7cbd85..a220b5d96f 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -110,7 +110,7 @@ def cycle( self, res: bool = True, max_res_amount: int = 5, - trans: bool = False, + transform: bool = False, log: Callable[..., Any] = None, action: Callable[..., Any] = None, **kwargs @@ -124,7 +124,7 @@ def cycle( max_res_amount: Limit the number of tested configurations to avoid an unnecessarily large test matrix. - trans: Cycling the transform or not. + transform: Cycling the transform or not. log: For logging, the string is constructed by [monitor name]_[resolution]_[transform]_. @@ -138,7 +138,7 @@ def cycle( monitors = [] modes_list = [] # ["normal": 0, "left": 1, "inverted": 6, "right": 3] - trans_list = [0, 1, 6, 3] if trans else [0] + trans_list = [0, 1, 6, 3] if transform else [0] # for multiple monitors, we need to create res combination state = self._get_current_state() @@ -151,10 +151,8 @@ def cycle( for trans in trans_list: logical_monitors = [] position_x = 0 - m_list = list(mode) uni_string = "" - for monitor in monitors: - m = m_list.pop(0) + for monitor, m in zip(monitors, mode): uni_string += "{}_{}_{}_".format( monitor, m.resolution, From 00d16c571ed29051983bfb5236dc978af2eadf96 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Fri, 29 Nov 2024 13:55:33 +0800 Subject: [PATCH 08/14] fix test case to match trans to transform --- .../checkbox_support/dbus/tests/test_gnome_monitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index c807356ee8..2d79c1bbce 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -320,7 +320,7 @@ def test_cycle(self, mock_dbus_proxy): def test_cycle_no_cycling(self, mock_dbus_proxy): """ Test the cycle could get the right monitors configuration - (without res and trans change) and send to ApplyMonitorsConfig. + (without res and transform change) and send to ApplyMonitorsConfig. """ mock_proxy = Mock() @@ -379,7 +379,7 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): # mock callback mock_callback = MagicMock() gnome_monitor.cycle( - res=False, trans=False, log=mock_callback, action=mock_callback + res=False, transform=False, log=mock_callback, action=mock_callback ) logical_monitors = [ From 0d138fd4bd3725d98e609b85a288419030e4daaa Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Fri, 29 Nov 2024 14:58:02 +0800 Subject: [PATCH 09/14] fix test assertion error --- .../checkbox_support/dbus/tests/test_gnome_monitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index 2d79c1bbce..3e1a44aa20 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -405,5 +405,5 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): cancellable=None, ) mock_callback.assert_called_with( - "eDP-1_1920x1200_normal_HDMI-1_2560x1440_normal_" + "HDMI-1_2560x1440_normal_eDP-1_1920x1200_normal_" ) From f48541bf973328440c867b0df475bac22c26bc42 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Fri, 29 Nov 2024 15:30:57 +0800 Subject: [PATCH 10/14] zip might make the monitors order, therefore changing the assertion method --- .../checkbox_support/dbus/tests/test_gnome_monitor.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index 3e1a44aa20..dcc04c81ad 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -1,3 +1,4 @@ +import re import sys import unittest from unittest.mock import patch, Mock, MagicMock @@ -404,6 +405,6 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): timeout_msec=-1, cancellable=None, ) - mock_callback.assert_called_with( - "HDMI-1_2560x1440_normal_eDP-1_1920x1200_normal_" - ) + argument_string = mock_callback.call_args[0][0] + pattern = re.compile("HDMI-1_2560x1440_normal_eDP-1_1920x1200_normal_|eDP-1_1920x1200_normal_HDMI-1_2560x1440_normal_") + assert pattern.match(argument_string) From 009ec45acc5960cabc293617b360f7432b4e5474 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Fri, 29 Nov 2024 15:37:15 +0800 Subject: [PATCH 11/14] fix black error --- .../checkbox_support/dbus/tests/test_gnome_monitor.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index dcc04c81ad..c7abbe1c10 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -380,7 +380,10 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): # mock callback mock_callback = MagicMock() gnome_monitor.cycle( - res=False, transform=False, log=mock_callback, action=mock_callback + res=False, + transform=False, + log=mock_callback, + action=mock_callback, ) logical_monitors = [ @@ -406,5 +409,7 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): cancellable=None, ) argument_string = mock_callback.call_args[0][0] - pattern = re.compile("HDMI-1_2560x1440_normal_eDP-1_1920x1200_normal_|eDP-1_1920x1200_normal_HDMI-1_2560x1440_normal_") + p1 = "HDMI-1_2560x1440_normal_" + p2 = "eDP-1_1920x1200_normal_" + pattern = re.compile("{}{}|{}{}".format(p1, p2, p2, p1)) assert pattern.match(argument_string) From 1f117da0874656499e6395e77448d5c77b05fbfa Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Mon, 2 Dec 2024 10:58:42 +0800 Subject: [PATCH 12/14] change the resolution filter as callable to make user could use any logic as they want. --- .../checkbox_support/dbus/gnome_monitor.py | 38 ++++--------------- .../dbus/tests/test_gnome_monitor.py | 2 +- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index a220b5d96f..ea7ebc8c1f 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -24,7 +24,6 @@ from collections import namedtuple from typing import Dict, List, Tuple, Set, Callable, Any from gi.repository import GLib, Gio -from fractions import Fraction import itertools from checkbox_support.monitor_config import MonitorConfig @@ -109,9 +108,8 @@ def set_extended_mode(self) -> Dict[str, str]: def cycle( self, res: bool = True, - max_res_amount: int = 5, transform: bool = False, - log: Callable[..., Any] = None, + resolution_filter: Callable[List[Mode], List[Mode]] = None, action: Callable[..., Any] = None, **kwargs ): @@ -121,13 +119,11 @@ def cycle( Args: res: Cycling the resolution or not. - max_res_amount: Limit the number of tested configurations - to avoid an unnecessarily large test matrix. - transform: Cycling the transform or not. - log: For logging, the string is constructed by - [monitor name]_[resolution]_[transform]_. + resolution_filter: For filtering resolution then returning needed, + it will take List[Mode] as parameter and return + the same data type action: For extra steps for each cycle, the string is constructed by @@ -144,7 +140,10 @@ def cycle( state = self._get_current_state() for monitor, modes in state[1].items(): monitors.append(monitor) - modes_list.append(self._resolution_filter(modes, max_res_amount)) + if resolution_filter: + modes_list.append(resolution_filter(modes)) + else: + modes_list.append(modes) mode_combination = list(itertools.product(*modes_list)) for mode in mode_combination: @@ -177,8 +176,6 @@ def cycle( xy = 1 if (trans == 1 or trans == 3) else 0 position_x += int(m.resolution.split("x")[xy]) self._apply_monitors_config(state[0], logical_monitors) - if log: - log(uni_string, **kwargs) if action: action(uni_string, **kwargs) if not res: @@ -186,25 +183,6 @@ def cycle( # change back to preferred monitor configuration self.set_extended_mode() - def _resolution_filter(self, modes: List[Mode], max_res_amount: int): - new_modes = [] - tmp_resolution = [] - sort_modes = sorted( - modes, key=lambda m: int(m.resolution.split("x")[0]), reverse=True - ) - for m in sort_modes: - width, height = [int(x) for x in m.resolution.split("x")] - aspect = Fraction(width, height) - if width < 675 or width / aspect < 530: - continue - if m.resolution in tmp_resolution: - continue - if len(new_modes) >= max_res_amount: - break - new_modes.append(m) - tmp_resolution.append(m.resolution) - return new_modes - def _get_current_state(self) -> Tuple[str, Dict[str, List[Mode]]]: """ Using DBus signal 'GetCurrentState' to get the available monitors diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index c7abbe1c10..35b2ae0ad5 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -382,7 +382,7 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): gnome_monitor.cycle( res=False, transform=False, - log=mock_callback, + resoultion_filter=mock_callback, action=mock_callback, ) From f8423eae61e7ecfd31db1aec966889be2f79f5d6 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Mon, 2 Dec 2024 11:07:25 +0800 Subject: [PATCH 13/14] Fix TypeError --- checkbox-support/checkbox_support/dbus/gnome_monitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index ea7ebc8c1f..309e8ace07 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -109,7 +109,7 @@ def cycle( self, res: bool = True, transform: bool = False, - resolution_filter: Callable[List[Mode], List[Mode]] = None, + resolution_filter: Callable[[List[Mode]], List[Mode]] = None, action: Callable[..., Any] = None, **kwargs ): From 020c0cc43a80f9cb111f2975ae1482ef6e75f4b3 Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Tue, 3 Dec 2024 08:50:43 +0800 Subject: [PATCH 14/14] change res to resolution to make it clearer --- checkbox-support/checkbox_support/dbus/gnome_monitor.py | 8 ++++---- .../checkbox_support/dbus/tests/test_gnome_monitor.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/checkbox-support/checkbox_support/dbus/gnome_monitor.py b/checkbox-support/checkbox_support/dbus/gnome_monitor.py index 309e8ace07..ee87197e71 100644 --- a/checkbox-support/checkbox_support/dbus/gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/gnome_monitor.py @@ -107,7 +107,7 @@ def set_extended_mode(self) -> Dict[str, str]: def cycle( self, - res: bool = True, + resolution: bool = True, transform: bool = False, resolution_filter: Callable[[List[Mode]], List[Mode]] = None, action: Callable[..., Any] = None, @@ -117,7 +117,7 @@ def cycle( Automatically cycle through the supported monitor configurations. Args: - res: Cycling the resolution or not. + resolution: Cycling the resolution or not. transform: Cycling the transform or not. @@ -136,7 +136,7 @@ def cycle( # ["normal": 0, "left": 1, "inverted": 6, "right": 3] trans_list = [0, 1, 6, 3] if transform else [0] - # for multiple monitors, we need to create res combination + # for multiple monitors, we need to create resolution combination state = self._get_current_state() for monitor, modes in state[1].items(): monitors.append(monitor) @@ -178,7 +178,7 @@ def cycle( self._apply_monitors_config(state[0], logical_monitors) if action: action(uni_string, **kwargs) - if not res: + if not resolution: break # change back to preferred monitor configuration self.set_extended_mode() diff --git a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py index 35b2ae0ad5..10526ec291 100644 --- a/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py +++ b/checkbox-support/checkbox_support/dbus/tests/test_gnome_monitor.py @@ -380,7 +380,7 @@ def test_cycle_no_cycling(self, mock_dbus_proxy): # mock callback mock_callback = MagicMock() gnome_monitor.cycle( - res=False, + resolution=False, transform=False, resoultion_filter=mock_callback, action=mock_callback,