fix: window position drift on Windows multi-monitor setups#93
Closed
edospadoni wants to merge 1 commit intomainfrom
Closed
fix: window position drift on Windows multi-monitor setups#93edospadoni wants to merge 1 commit intomainfrom
edospadoni wants to merge 1 commit intomainfrom
Conversation
bfe8d04 to
f402081
Compare
f402081 to
7dbee76
Compare
7dbee76 to
5c1e803
Compare
5c1e803 to
08ec0f0
Compare
08ec0f0 to
bda77ec
Compare
bda77ec to
e54489f
Compare
On Windows with mixed DPI monitors (e.g. laptop at 125% + external at
100%), the PhoneIsland window drifted progressively on each call cycle,
eventually disappearing off-screen.
Root cause confirmed via diagnostic logging: calling setBounds() with
zero dimensions ({width:0, height:0}) causes Chromium on Windows to
multiply the window position by the primary display's scaleFactor.
Each resize(0,0) at call end shifted coordinates by exactly 1.25x:
x=150 → 187 → 233 → 291 → 363 → 453 (×1.25 each cycle)
Additionally, showPhoneIsland() called resize() first (showing the
window at the wrong position) then repositioned with a second
setBounds(), causing a visible "trail" artifact.
Changes:
- PhoneIslandController.resize(): skip setBounds entirely when
dimensions are 0x0, just hide directly. Always pass full rect
{x, y, width, height} for non-zero resizes.
- PhoneIslandController.showPhoneIsland(): set position and size in a
single setBounds() call BEFORE show(), eliminating the visual trail.
Only fall back to resize()+center() when no saved position exists.
- ipcEvents.ts drag handler: use getBounds() instead of
getContentSize() to get correct outer window dimensions.
e54489f to
f43dbe4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes NethLink and PhoneIsland windows gradually drifting off-position on Windows with multiple monitors:
This only occurred on Windows multi-monitor setups — macOS, Linux, and single-monitor Windows were unaffected.
Root causes
PhoneIsland double
setBounds()calls:showPhoneIsland()first calledresize()which didsetBounds({ width, height })(no x/y), then separately calledsetBounds({ x, y })(no width/height). On Windows with per-monitor DPI awareness, each partial call triggers coordinate rounding, and the omitted fields get filled from the current (already-rounded) state — accumulating drift on every cycle.NethLink DPI rounding accumulation: The
getBounds()→ save →setBounds()cycle introduces fractional pixel rounding errors when Windows converts between logical and physical coordinates at non-100% scale factors (e.g., 125%, 150%).Drag handler size mismatch:
updateWindowPosition()usedgetContentSize()(inner area, excluding title bar and window frame) but passed the result tosetBounds()which expects outer window dimensions — causing the window to effectively shrink each drag.Changes
setBounds()calls into a singlesetBounds({ x, y, width, height })with the full rectangle. AddedMath.round()when saving position inhidePhoneIsland().Math.round()on all coordinate values insaveBounds()to prevent rounding error accumulation.getContentSize()withgetBounds()in the drag handler for non-PhoneIsland windows.