Skip to content

fix: store monitor borders per-monitor instead of per-model#470

Closed
funnything1 wants to merge 1 commit into
mgth:masterfrom
funnything1:fix/monitor-borders-per-monitor
Closed

fix: store monitor borders per-monitor instead of per-model#470
funnything1 wants to merge 1 commit into
mgth:masterfrom
funnything1:fix/monitor-borders-per-monitor

Conversation

@funnything1

@funnything1 funnything1 commented Jul 5, 2026

Copy link
Copy Markdown

Borders are saved under monitors{PnpCode}\Borders* — a registry key shared by all monitors of the same make/model. Users with two identical monitors had one monitor''s borders overwrite the other''s on every save, causing wrong values (left/right swapped) to reload after restart.

Borders are now saved/loaded under
Layouts{layoutId}\PhysicalMonitors{Id}\Borders*, the same per-monitor key already used for position, depth ratio, and border resistance.

pissibly related #309, #419

Note: existing saved border values will not carry over; users need to re-enter borders once after updating.

broken:
broken

fixed:
fixed

Borders were saved under monitors\{PnpCode}\Borders\* — a registry key
shared by all monitors of the same make/model. Users with two identical
monitors had one monitor''s borders overwrite the other''s on every save,
causing wrong values (left/right swapped) to reload after restart.

Borders are now saved/loaded under
Layouts\{layoutId}\PhysicalMonitors\{Id}\Borders\*, the same per-monitor
key already used for position, depth ratio, and border resistance.

Note: existing saved border values will not carry over; users need to
re-enter borders once after updating.
mgth added a commit that referenced this pull request Jul 9, 2026
Border values: per model | per monitor option (#470 redesign)
@mgth

mgth commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Thanks a lot for this, @funnything1 — you correctly spotted that two identical monitors were clobbering each other's borders (nice before/after screenshots too 👌).

Digging in, the root cause turned out to be a model-cache bug: GetOrAddPhysicalMonitorModel recreated the model on every call instead of returning the cached one, so identical monitors ended up with separate PhysicalMonitorModel instances and one's save overwrote the other's monitors\{PnpCode} key. That's fixed in #497.

For the borders themselves we kept per-model as the default — bezel size is a property of the make/model, and a planned online border database keys on the model, so per-model spares owners of 3 identical screens from entering the same values three times. To still cover your case, we added a "Border values: per model | per monitor" option (per-monitor opt-in) in #499, on top of the #498 geometry seam.

So this is superseded by #497 + #498 + #499 and I'm closing it — but the fix is entirely thanks to you flagging the issue. Much appreciated 🙏

@mgth mgth closed this Jul 9, 2026
mgth pushed a commit to funnything1/LittleBigMouseGameFix that referenced this pull request Jul 9, 2026
Bezel borders are per-model by design (a property of the make/model), shared by
all monitors of the same PnpCode — and the future online border database keys on
the model. mgth#470 wanted them per-monitor; instead of changing the default, add an
option so users who want it can opt in without forcing triple-identical-screen
users to enter the same values three times.

- ILayoutOptions/LbmOptions: `BorderValues` ("PerModel" default | "PerMonitor"),
  persisted on the main registry key.
- DisplayBorderOverride: a size decorator keeping width/height/position from the
  shared per-model size but taking the four borders from a per-monitor holder.
- PhysicalMonitor: `EffectivePhysicalSize` (the Phase-2 geometry seam) is now
  reactive on the option — PerMonitor roots the chain at the override, else at the
  model. A `Borders` (DisplayBorders) holds the per-monitor values; a mirror keeps
  it aligned with the model while NOT in PerMonitor, so switching modes doesn't
  jump.
- Persistence: PerMonitor borders load/save under the monitor key
  (Layouts\{id}\PhysicalMonitors\{Id}\Borders\*); PerModel keeps the existing
  per-model key untouched. Absent per-monitor key seeds from the model.
- UI: a "Border values" choice card in the Layout options.

Default is PerModel, so existing behaviour and stored values are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
funnything1 pushed a commit to funnything1/LittleBigMouseGameFix that referenced this pull request Jul 14, 2026
Three bugs fixed (closes mgth#470):

1. Border edits in PerMonitor mode did not update the monitor frame visual.
   Root cause: ToProperty wraps the observable in DistinctUntilChanged using
   value-based Equals (IDisplaySize : IEquatable<IDisplaySize>). The origin
   monitor at X=0,Y=0 always matched the new object by value, silently
   suppressing the update. Fix: replaced the OAPH with Subscribe through a
   ReferenceEquals-gated setter (same pattern as PhysicalRotated).

2. Switching back from PerMonitor to PerModel collapsed monitors to 0,0.
   Root cause: every mode switch creates a fresh DisplayLocate at X=0,Y=0,
   losing the layout-calculated positions. Fix: the DepthProjection setter
   copies X and Y from the outgoing object to the incoming one.

3. Switching PerMonitor -> PerModel -> PerMonitor required a full restart.
   Root cause: a mirror subscription overwrote Borders with model values on
   every non-PerMonitor mode, and Load() only read per-monitor borders when
   already in PerMonitor mode at startup. Fix: removed the mirror; made
   Load() and Save() unconditional for per-monitor borders.
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.

2 participants