Skip to content

fix(displays): keep a monitor's rotation in the layout backup - #108

Merged
lippdev merged 1 commit into
mainfrom
fix/layout-keeps-orientation
Sep 29, 2026
Merged

lippdev merged 1 commit into
mainfrom
fix/layout-keeps-orientation

Conversation

@lippdev

@lippdev lippdev commented Sep 29, 2026

Copy link
Copy Markdown
Owner

Problem

The native layout code (1.6 alpha, #91) wrote DisplayOrientation=0 for every monitor and never applied the saved value. A monitor turned to portrait (e.g. 1080×1920 at 90°) would come back in landscape after restoring the desk. MultiMonitorTool saved and restored it.

How it was found

Ran the alpha's own code (ConsoleMode.dll, by reflection) against the real 1.5 data of a machine with a portrait monitor:

  • config.json monitor IDs → matched the native StableId (3/3).
  • backup_monitores.cfg written by MultiMonitorTool → parsed fine, and RemapLayoutNames mapped the renamed \.\DISPLAYn correctly.
  • FormatLayout(ParseLayout(backup)) vs the original file: 1 of 36 lines differed, DisplayOrientation=1 became 0.
  • QueryDisplayConfig reports rotation=1 (identity) for the inactive path of that monitor, so re-enabling it gives landscape; nothing put the rotation back.

Fix

  • LayoutEntry gets Orientation (default 0, so existing callers compile); FormatLayout writes it.
  • DisplayBackend.SaveLayout reads DEVMODE.dmDisplayOrientation (new NativeWindows.GetCurrentOrientation) for active monitors.
  • LoadLayout passes the saved orientation to NativeDisplays.QueueMode, which sets DM_DISPLAYORIENTATION only when it differs from the current one: setups that never rotate make exactly the same call as before. A backup without the key leaves the rotation alone.

Tests

  • 3 new unit tests; the strongest one writes back a 1.5-shaped backup (portrait side monitor + a TV that was off) and requires it to be identical line by line. Red before the fix (Expected "1" / Actual "0"), green after. 147 pass.
  • Ran the real SaveLayout on the dev machine: same output as before for an unrotated screen.

Not verified on hardware

Applying a rotation needs a rotatable physical monitor and changes the desktop, which I couldn't do on this machine (only a virtual display is active). Added the check to docs/TESTING.md: monitor girado volta girado, mesma posição e resolução.

🤖 Generated with Claude Code

The native layout code wrote DisplayOrientation=0 for every monitor and never applied the
saved value, so a monitor turned to portrait (e.g. 1080x1920 at 90 degrees) came back in
landscape after restoring the desk. MultiMonitorTool saved and restored it.

- LayoutEntry gets Orientation (default 0); FormatLayout writes it.
- SaveLayout reads DEVMODE.dmDisplayOrientation for active monitors.
- LoadLayout passes the saved orientation to QueueMode, which sets DM_DISPLAYORIENTATION
  only when it differs from the current one, so setups that never rotate make the same call.
- A backup without the key leaves the rotation alone.

Found by running the alpha against the real 1.5 config and backup of a machine with a
portrait monitor: a saved-and-rewritten backup differed in exactly that one line.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes The review covered the rotation backup/restore path, related docs and changelogs, and the new serialization tests.

  • Persist display rotation Save and serialize each active monitor's orientation while preserving the existing .cfg layout format.
  • Restore rotation Apply the saved orientation only when it differs from the current mode, and leave rotation unchanged when older backups omit the key.
  • Add coverage and manual check Verify orientation serialization and legacy backup fidelity; document the rotated-monitor hardware check.

Pullfrog  | View workflow run | Using GPT Luna | 𝕏

@lippdev
lippdev merged commit af9b39d into main Sep 29, 2026
5 checks passed
@lippdev
lippdev deleted the fix/layout-keeps-orientation branch September 29, 2026 13:12
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.

1 participant