From 06a303027d936fe72bd37a5fe22c86beb59f3ad5 Mon Sep 17 00:00:00 2001 From: SMWHff Date: Thu, 9 Jul 2026 09:03:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8A=A0=E8=BD=BD=20Profile=20=E5=89=8D?= =?UTF-8?q?=E6=B8=85=E9=99=A4=E4=B8=BB=E5=B1=8F=E6=A0=87=E8=AE=B0=EF=BC=8C?= =?UTF-8?q?diff=20=E5=A2=9E=E5=8A=A0=E5=8F=96=E6=B6=88=E4=B8=BB=E5=B1=8F?= =?UTF-8?q?=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - load_profile() 开始时调用 set_noprimary() 清除旧主屏标记,防止加载 无主屏配置时保留前一个配置的主屏状态(导致多个主屏共存) - diff_profile() 添加对称检测:当配置中 is_primary=False 而当前显示器是 主屏时输出"取消主显示器" --- tests/unit/profiles/test_profiles.py | 34 +++++----- tests/unit/profiles/test_profiles_extra.py | 73 +++++++++++++++------- winrandr/profiles.py | 10 ++- 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/tests/unit/profiles/test_profiles.py b/tests/unit/profiles/test_profiles.py index dad2674..7a69d5a 100644 --- a/tests/unit/profiles/test_profiles.py +++ b/tests/unit/profiles/test_profiles.py @@ -103,14 +103,16 @@ def test_load_profile_success(temp_profiles): _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display()]): - with patch("winrandr.profiles.set_auto", return_value=True) as sa: - with patch("winrandr.profiles.set_position", return_value=True): - with patch("winrandr.profiles.set_rotation", return_value=True): - with patch("winrandr.profiles.set_resolution", return_value=True): - with patch("winrandr.profiles.set_primary", return_value=True) as sp: - assert load_profile("myprofile") is True - sa.assert_called_once_with(r"\\.\DISPLAY1") - sp.assert_called_once_with(r"\\.\DISPLAY1") + with patch("winrandr.profiles.set_noprimary", return_value=True) as snp: + with patch("winrandr.profiles.set_auto", return_value=True) as sa: + with patch("winrandr.profiles.set_position", return_value=True): + with patch("winrandr.profiles.set_rotation", return_value=True): + with patch("winrandr.profiles.set_resolution", return_value=True): + with patch("winrandr.profiles.set_primary", return_value=True) as sp: + assert load_profile("myprofile") is True + snp.assert_called_once() + sa.assert_called_once_with(r"\\.\DISPLAY1") + sp.assert_called_once_with(r"\\.\DISPLAY1") def test_load_profile_display_not_connected(temp_profiles): @@ -135,9 +137,10 @@ def test_load_profile_display_not_connected(temp_profiles): _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display("DISPLAY1")]): - with patch("winrandr.profiles.set_auto") as sa: - assert load_profile("p") is True # skips DISPLAY3, no error - sa.assert_not_called() + with patch("winrandr.profiles.set_noprimary", return_value=True): + with patch("winrandr.profiles.set_auto") as sa: + assert load_profile("p") is True # skips DISPLAY3, no error + sa.assert_not_called() def test_load_profile_set_auto_fails(temp_profiles): @@ -162,10 +165,11 @@ def test_load_profile_set_auto_fails(temp_profiles): _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display()]): - with patch("winrandr.profiles.set_auto", return_value=False): - with patch("winrandr.profiles.set_position") as sp: - assert load_profile("p") is False - sp.assert_not_called() + with patch("winrandr.profiles.set_noprimary", return_value=True): + with patch("winrandr.profiles.set_auto", return_value=False): + with patch("winrandr.profiles.set_position") as sp: + assert load_profile("p") is False + sp.assert_not_called() # ---- list_profiles / get_profile_names ---- diff --git a/tests/unit/profiles/test_profiles_extra.py b/tests/unit/profiles/test_profiles_extra.py index eb4e863..90e9613 100644 --- a/tests/unit/profiles/test_profiles_extra.py +++ b/tests/unit/profiles/test_profiles_extra.py @@ -130,6 +130,33 @@ def test_diff_profile_primary_change(temp_profiles): assert "设为主显示器" in " ".join(lines) +def test_diff_profile_primary_removal(temp_profiles): + """diff_profile 应检测配置中取消主屏的操作。""" + config = { + "p": { + "displays": [ + { + "name": r"\\.\DISPLAY1", + "x": 0, + "y": 0, + "width": 1920, + "height": 1080, + "refresh_rate": 60.0, + "rotation": 0, + "is_primary": False, + } + ], + "created": "2026-01-01T00:00:00", + "version": "0.3.6", + }, + } + _save_all(config) + cur = _make_display("DISPLAY1", 0, 0, 1920, 1080, 60.0, 0, primary=True) + with patch("winrandr.profiles.list_displays", return_value=[cur]): + lines = diff_profile("p") + assert "取消主显示器" in " ".join(lines) + + def test_load_profile_set_position_fails(temp_profiles): """load_profile 中 set_position 失败时应继续执行后续操作。""" config = { @@ -152,11 +179,12 @@ def test_load_profile_set_position_fails(temp_profiles): } _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display()]): - with patch("winrandr.profiles.set_auto", return_value=True): - with patch("winrandr.profiles.set_position", return_value=False): - with patch("winrandr.profiles.set_rotation", return_value=True): - with patch("winrandr.profiles.set_resolution", return_value=True): - assert load_profile("p") is False + with patch("winrandr.profiles.set_noprimary", return_value=True): + with patch("winrandr.profiles.set_auto", return_value=True): + with patch("winrandr.profiles.set_position", return_value=False): + with patch("winrandr.profiles.set_rotation", return_value=True): + with patch("winrandr.profiles.set_resolution", return_value=True): + assert load_profile("p") is False def test_load_profile_set_rotation_fails(temp_profiles): @@ -181,11 +209,12 @@ def test_load_profile_set_rotation_fails(temp_profiles): } _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display()]): - with patch("winrandr.profiles.set_auto", return_value=True): - with patch("winrandr.profiles.set_position", return_value=True): - with patch("winrandr.profiles.set_rotation", return_value=False): - with patch("winrandr.profiles.set_resolution", return_value=True): - assert load_profile("p") is False + with patch("winrandr.profiles.set_noprimary", return_value=True): + with patch("winrandr.profiles.set_auto", return_value=True): + with patch("winrandr.profiles.set_position", return_value=True): + with patch("winrandr.profiles.set_rotation", return_value=False): + with patch("winrandr.profiles.set_resolution", return_value=True): + assert load_profile("p") is False def test_load_profile_set_resolution_fails(temp_profiles): @@ -210,11 +239,12 @@ def test_load_profile_set_resolution_fails(temp_profiles): } _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display()]): - with patch("winrandr.profiles.set_auto", return_value=True): - with patch("winrandr.profiles.set_position", return_value=True): - with patch("winrandr.profiles.set_rotation", return_value=True): - with patch("winrandr.profiles.set_resolution", return_value=False): - assert load_profile("p") is False + with patch("winrandr.profiles.set_noprimary", return_value=True): + with patch("winrandr.profiles.set_auto", return_value=True): + with patch("winrandr.profiles.set_position", return_value=True): + with patch("winrandr.profiles.set_rotation", return_value=True): + with patch("winrandr.profiles.set_resolution", return_value=False): + assert load_profile("p") is False def test_load_profile_set_primary_fails(temp_profiles): @@ -239,12 +269,13 @@ def test_load_profile_set_primary_fails(temp_profiles): } _save_all(config) with patch("winrandr.profiles.list_displays", return_value=[_make_display()]): - with patch("winrandr.profiles.set_auto", return_value=True): - with patch("winrandr.profiles.set_position", return_value=True): - with patch("winrandr.profiles.set_rotation", return_value=True): - with patch("winrandr.profiles.set_resolution", return_value=True): - with patch("winrandr.profiles.set_primary", return_value=False): - assert load_profile("p") is False + with patch("winrandr.profiles.set_noprimary", return_value=True): + with patch("winrandr.profiles.set_auto", return_value=True): + with patch("winrandr.profiles.set_position", return_value=True): + with patch("winrandr.profiles.set_rotation", return_value=True): + with patch("winrandr.profiles.set_resolution", return_value=True): + with patch("winrandr.profiles.set_primary", return_value=False): + assert load_profile("p") is False # ---- _load_all / _save_all ---- diff --git a/winrandr/profiles.py b/winrandr/profiles.py index 083de2a..3383105 100644 --- a/winrandr/profiles.py +++ b/winrandr/profiles.py @@ -10,6 +10,7 @@ from winrandr.api import ( list_displays, set_auto, + set_noprimary, set_position, set_primary, set_resolution, @@ -98,7 +99,7 @@ def save_profile(name: str) -> bool: return True -def diff_profile(name: str) -> list[str]: +def diff_profile(name: str) -> list[str]: # noqa: C901 """比较当前配置与存档的差异,返回人类可读的变更列表。""" data = _load_all() profile = data.get(name) @@ -127,6 +128,8 @@ def diff_profile(name: str) -> list[str]: changes.append(f"分辨率 {cur.width}x{cur.height}→{dc['width']}x{dc['height']}") if dc["is_primary"] and not cur.is_primary: changes.append("设为主显示器") + if cur.is_primary and not dc["is_primary"]: + changes.append("取消主显示器") if changes: lines.append(f" {sn}: {', '.join(changes)}") else: @@ -150,6 +153,11 @@ def load_profile(name: str) -> bool: # noqa: C901 # 循环中含多条 API 调 current = {d.name for d in list_displays()} success = True + # 先清除所有主屏标记,避免加载无主屏配置时保留旧主屏 + if not set_noprimary(): + logger.warning("清除主屏标记失败") + print("警告: 清除主屏标记失败", file=sys.stderr) + for dc in configs: dn = dc["name"] if dn not in current: