fix(displays): write mirror sources first in the login include #83

Merged
Breadway merged 2 commits from fix/bset-68-persist-mirror-order into main 2026-10-14 14:00:41 +08:00
Owner

Closes BSET-68

What

persist_layout wrote one hl.monitor per output into bos-settings-display-overrides.lua in the order it was given. The live apply (display_guard::plan_statements, from #67) already orders mirror sources before their mirrors. A layout handed in mirror-first was therefore saved mirror-first, so login could configure a mirror before the output it follows.

Both paths now use plan_statements, through a small overrides_lua() helper.

Tests

  • New login_include_puts_mirror_sources_first. It uses the real monitors-all fixture with DVI-I-1 (mirror of eDP-1) moved first, and asserts that eDP-1 is written before DVI-I-1. The test fails on the old code.
  • On top of current main: cargo fmt, clippy --all-targets -D warnings, cargo test (180).

Capability changes

None. The saved statements are the same, possibly in a different order.

Confidence note from the issue: it is unverified whether Hyprland actually needs the source first at login. This change makes the saved file match the order the live apply already uses.

Closes BSET-68 ## What `persist_layout` wrote one `hl.monitor` per output into `bos-settings-display-overrides.lua` in the order it was given. The live apply (`display_guard::plan_statements`, from #67) already orders mirror sources before their mirrors. A layout handed in mirror-first was therefore saved mirror-first, so login could configure a mirror before the output it follows. Both paths now use `plan_statements`, through a small `overrides_lua()` helper. ## Tests - New `login_include_puts_mirror_sources_first`. It uses the real monitors-all fixture with DVI-I-1 (mirror of eDP-1) moved first, and asserts that eDP-1 is written before DVI-I-1. The test fails on the old code. - On top of current main: cargo fmt, clippy --all-targets -D warnings, cargo test (180). ## Capability changes None. The saved statements are the same, possibly in a different order. Confidence note from the issue: it is unverified whether Hyprland actually needs the source first at login. This change makes the saved file match the order the live apply already uses.
fix(displays): write mirror sources first in the login include
All checks were successful
check / check (push) Successful in 5m55s
b730c9f927
persist_layout wrote one hl.monitor per output in the order it was given,
while the live apply (plan_statements) already puts mirror sources before
their mirrors. A layout handed in mirror-first was saved mirror-first, so
login could configure a mirror before the output it follows. Both paths now
use plan_statements. Test: a fixture layout with DVI-I-1 (mirror of eDP-1)
first is written eDP-1 first; it fails on the old order.
Merge remote-tracking branch 'origin/main' into fix/bset-68-persist-mirror-order
All checks were successful
check / check (push) Successful in 4m8s
d35f130370
Author
Owner

Review verdict: PASS for BSET-68 at exact head d35f130370 (base main d432319ac5).

Criteria

  • persist_layout writes the login include via display_guard::plan_statements: src/src/commands/hyprland.rs overrides_lua() calls plan_statements, and persist_layout passes its result to install_lua_include. PASS.
  • Regression test with mirror-first input: login_include_puts_mirror_sources_first moves DVI-I-1 (mirror of eDP-1) to the front of the real monitors-all fixture and asserts eDP-1 appears before DVI-I-1. I reverted overrides_lua to the old list-order logic locally and the test FAILED; on the PR head it passes. PASS.
  • No regressions: the same statements are emitted (plan_statements maps hyprland::lua_statement, stable sort on mirror_of), the header line is unchanged, merge_rules and write_rule_objects for monitors.json are untouched, and the lua_ident name loop in persist_layout is untouched. Single file changed (+25/-5). PASS.

Checks run in a detached scratch worktree on the exact head

  • frontend: npm ci, npm run check (0 errors, 0 warnings), npm test (all suites passed), npm run build (static site written). PASS.
  • src: cargo fmt --check clean; cargo clippy --locked --all-targets -- -D warnings clean; cargo test --locked 180 passed, 0 failed. PASS.
  • Forgejo CI: "check / check (push)" is success on d35f130 (run 167, 4m8s).
  • Reviews: none outstanding. Mergeable: true.

Note: whether Hyprland needs the source first at login is unverified live, as the issue itself states. This change aligns the saved file with the live-apply order.

Review verdict: PASS for BSET-68 at exact head d35f1303709f5d35fd3d138b26844eca9249461b (base main d432319ac559fcc7b29bb7c2df96bd4c98794bfe). Criteria - persist_layout writes the login include via display_guard::plan_statements: src/src/commands/hyprland.rs overrides_lua() calls plan_statements, and persist_layout passes its result to install_lua_include. PASS. - Regression test with mirror-first input: login_include_puts_mirror_sources_first moves DVI-I-1 (mirror of eDP-1) to the front of the real monitors-all fixture and asserts eDP-1 appears before DVI-I-1. I reverted overrides_lua to the old list-order logic locally and the test FAILED; on the PR head it passes. PASS. - No regressions: the same statements are emitted (plan_statements maps hyprland::lua_statement, stable sort on mirror_of), the header line is unchanged, merge_rules and write_rule_objects for monitors.json are untouched, and the lua_ident name loop in persist_layout is untouched. Single file changed (+25/-5). PASS. Checks run in a detached scratch worktree on the exact head - frontend: npm ci, npm run check (0 errors, 0 warnings), npm test (all suites passed), npm run build (static site written). PASS. - src: cargo fmt --check clean; cargo clippy --locked --all-targets -- -D warnings clean; cargo test --locked 180 passed, 0 failed. PASS. - Forgejo CI: "check / check (push)" is success on d35f130 (run 167, 4m8s). - Reviews: none outstanding. Mergeable: true. Note: whether Hyprland needs the source first at login is unverified live, as the issue itself states. This change aligns the saved file with the live-apply order.
Author
Owner

Merged with a merge commit at a80bdf3660 (head d35f130370 onto base 283ba6b20e). The base moved three times during review; each time I re-ran frontend check/test/build and cargo fmt/clippy/test on the head merged with the new base (183 tests passing). Awaiting verification on the integrated commit.

Merged with a merge commit at a80bdf36603247b3b207531d5c1e38d3737e9d3a (head d35f1303709f5d35fd3d138b26844eca9249461b onto base 283ba6b20ecb679df5830511914859653c9d7ee8). The base moved three times during review; each time I re-ran frontend check/test/build and cargo fmt/clippy/test on the head merged with the new base (183 tests passing). Awaiting verification on the integrated commit.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/bos-settings!83
No description provided.