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: