Skip to content

Fix Settings window off-screen after disconnecting high-DPI monitor#4342

Closed
Copilot wants to merge 3 commits intodevfrom
copilot/fix-settings-window-issue
Closed

Fix Settings window off-screen after disconnecting high-DPI monitor#4342
Copilot wants to merge 3 commits intodevfrom
copilot/fix-settings-window-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 10, 2026

  • Analyze issue: Settings window goes off-screen when disconnecting 4K monitor
  • Fix IsPositionValid to use DIP-based SystemParameters.VirtualScreen* instead of physical pixel MonitorInfo.WorkingArea (DPI mismatch)
  • Fix AdjustWindowPosition max boundary: VirtualScreenTop + VirtualScreenHeight - ActualHeight (not just VirtualScreenHeight - ActualHeight)
  • Fix SetWindowPosition max boundary the same way
  • Build verified (no C# compilation errors)
  • Code review passed
  • Security scan: 0 alerts
Original prompt

This section details on the original issue you should resolve

<issue_title>when i disconnect from 4K monitor, my 2K screen is not opening "Settings"</issue_title>
<issue_description>Flow launcher is not opening the "Settings" when i disconnect from my 4K monitor. I'm using a 2K laptop on school and i can't access to settings. I tried every possible solution on yhe internet like move option on window but doesnt works unless i reinstall</issue_description>

Comments on the Issue (you are @copilot in this section)

@onesounds Hi, You mean, Setting Window? 1. Can you see flow's setting window when press Win+Tab in that situation? 2. Select Flow Setting window -> Press Win+Arrow(Left or right) multiple time or right click in Win+Tab Screen.

Please check if the window returns normally from another place. It is necessary to check if the problem is solved in the same way as above.

Because the window location in the Flow is remembered, the window location may not be displayed if the monitor has changed (if the resolution is also significantly different).

I also use several monitors (with connect/disconnect...), and I usually solve them in the same way as above. If the problem I'm expecting is right, I'll consider 'reset position'(setting window) option. </comment_new>
<comment_new>@jjw24
I don't think it's got anything with installation, will be something to do with how flow handles the settings.

Closing this for now since no longer an issue, feel free to reopen if not the case.</comment_new>
<comment_new>@VictoriousRaptor
Closing the settings window on a high-res monitor, then reopening it on a low-res one may put the window out of the monitor, depending on the window position on the high-res monitor.</comment_new>
<comment_new>@taooceros
Maybe it is because we save the setting window position?</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.


Summary by cubic

Prevents the Settings window from opening off-screen after disconnecting a high‑DPI monitor. Normalizes window math to DIP, clamps within the full virtual screen (including negative origins), and saves display metrics to recover safely after DPI/resolution changes.

  • Summary of changes
    • Changed: Use SystemParameters.VirtualScreen* (DIP) for position validation and clamping in Settings window; fix max bounds to VirtualScreenTop/Left + VirtualScreenHeight/Width - ActualHeight/Width to handle non‑zero virtual origins.
    • Changed: Replace Win32Helper.TransformPixelsToDIP call sites with per‑monitor MonitorInfo.TransformPixelsToDIP in Main/Settings windows; Win32Helper.TransformPixelsToDIP now returns doubles (no rounding).
    • Changed: Persist window Top/Left with PreviousScreenWidth/Height and new PreviousDpiX/Y; adjust position on startup when screen size or DPI changed; AdjustPositionForResolutionChange now scales by virtual screen ratios only (removed DPI factor).
    • Changed: All positioning helpers (center/left/right/top/bottom, dialog anchor) now use monitor‑aware DIP transforms.
    • Added: MonitorInfo.TransformPixelsToDIP (point/rect) using GetDpiForMonitor (Effective DPI) and helpers SaveWindowPositionAndDisplayMetrics/SaveCurrentDisplayMetrics.
    • Removed: Physical‑pixel monitor checks in IsPositionValid; integer rounding in pixel→DIP conversion; DPI ratio scaling in resolution adjustment.
    • Memory impact: None.
    • Security risks: None.
    • Unit tests: None. Manually verified on mixed‑DPI and multi‑monitor setups.

Written for commit 386f2b4. Summary will update on new commits.

@prlabeler prlabeler bot added the bug Something isn't working label Mar 10, 2026
Copilot AI changed the title [WIP] Fix Settings window not opening after disconnecting 4K monitor Fix Settings window off-screen after disconnecting high-DPI monitor Mar 10, 2026
Base automatically changed from fix-settings-window-issue to dev March 10, 2026 14:50
- Fix IsPositionValid to use SystemParameters.VirtualScreen* (DIP units)
  instead of MonitorInfo.WorkingArea (physical pixels) to avoid DPI
  coordinate mismatch on high-DPI and mixed-DPI multi-monitor setups.

- Fix AdjustWindowPosition and SetWindowPosition to correctly calculate
  the max boundary as VirtualScreenTop + VirtualScreenHeight - ActualHeight
  (was VirtualScreenHeight - ActualHeight), which incorrectly allowed
  windows to extend beyond the bottom/right edge when VirtualScreenTop
  or VirtualScreenLeft were non-zero (e.g., monitors above/left of primary).

Co-authored-by: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
@VictoriousRaptor VictoriousRaptor force-pushed the copilot/fix-settings-window-issue branch from 31c47e6 to a8e755e Compare March 10, 2026 14:52
@jjw24 jjw24 marked this pull request as ready for review April 7, 2026 00:47
@gitstream-cm
Copy link
Copy Markdown

gitstream-cm bot commented Apr 7, 2026

🥷 Code experts: Jack251970

Jack251970 has most 👩‍💻 activity in the files.
Jack251970 has most 🧠 knowledge in the files.

See details

.gitignore

Activity based on git-commit:

Jack251970
APR
MAR
FEB
JAN
DEC
NOV

Knowledge based on git-blame:
Jack251970: 100%

Flow.Launcher.Infrastructure/Win32Helper.cs

Activity based on git-commit:

Jack251970
APR
MAR
FEB
JAN
DEC
NOV

Knowledge based on git-blame:
Jack251970: 97%

Flow.Launcher.Plugin/SharedModels/MonitorInfo.cs

Activity based on git-commit:

Jack251970
APR
MAR
FEB
JAN
DEC
NOV

Knowledge based on git-blame:
Jack251970: 100%

Flow.Launcher/MainWindow.xaml.cs

Activity based on git-commit:

Jack251970
APR
MAR 5 additions & 3 deletions
FEB
JAN
DEC
NOV 1 additions & 1 deletions

Knowledge based on git-blame:
Jack251970: 100%

Flow.Launcher/SettingWindow.xaml.cs

Activity based on git-commit:

Jack251970
APR
MAR
FEB
JAN
DEC
NOV

Knowledge based on git-blame:
Jack251970: 99%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

@gitstream-cm
Copy link
Copy Markdown

gitstream-cm bot commented Apr 7, 2026

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@jjw24 jjw24 marked this pull request as draft April 7, 2026 00:49
@jjw24
Copy link
Copy Markdown
Member

jjw24 commented Apr 7, 2026

Please reopen PR under your name when ready to go.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Flow.Launcher.Plugin/SharedModels/MonitorInfo.cs">

<violation number="1" location="Flow.Launcher.Plugin/SharedModels/MonitorInfo.cs:197">
P1: DPI scale uses integer division, truncating non-100%/200% scaling and producing incorrect DIP coordinates.</violation>
</file>

<file name="Flow.Launcher/SettingWindow.xaml.cs">

<violation number="1" location="Flow.Launcher/SettingWindow.xaml.cs:203">
P2: `IsPositionValid` now validates against the virtual-screen bounding box, which can mark coordinates in non-visible gaps between monitors as valid. That can still restore Settings off-screen on irregular multi-monitor layouts.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

{
if (GetDpiForMonitor(_monitor, MonitorDpiType.EffectiveDpi, out var dpiX, out var dpiY) == 0 && dpiX != 0 && dpiY != 0)
{
return (dpiX / 96, dpiY / 96);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P1: DPI scale uses integer division, truncating non-100%/200% scaling and producing incorrect DIP coordinates.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Flow.Launcher.Plugin/SharedModels/MonitorInfo.cs, line 197:

<comment>DPI scale uses integer division, truncating non-100%/200% scaling and producing incorrect DIP coordinates.</comment>

<file context>
@@ -171,6 +190,24 @@ internal unsafe MonitorInfo(HMONITOR monitor, RECT* rect)
+    {
+        if (GetDpiForMonitor(_monitor, MonitorDpiType.EffectiveDpi, out var dpiX, out var dpiY) == 0 && dpiX != 0 && dpiY != 0)
+        {
+            return (dpiX / 96, dpiY / 96);
+        }
+
</file context>
Suggested change
return (dpiX / 96, dpiY / 96);
return (dpiX / 96d, dpiY / 96d);
Fix with Cubic

Comment on lines +203 to +206
return left >= SystemParameters.VirtualScreenLeft &&
left < SystemParameters.VirtualScreenLeft + SystemParameters.VirtualScreenWidth &&
top >= SystemParameters.VirtualScreenTop &&
top < SystemParameters.VirtualScreenTop + SystemParameters.VirtualScreenHeight;
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: IsPositionValid now validates against the virtual-screen bounding box, which can mark coordinates in non-visible gaps between monitors as valid. That can still restore Settings off-screen on irregular multi-monitor layouts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Flow.Launcher/SettingWindow.xaml.cs, line 203:

<comment>`IsPositionValid` now validates against the virtual-screen bounding box, which can mark coordinates in non-visible gaps between monitors as valid. That can still restore Settings off-screen on irregular multi-monitor layouts.</comment>

<file context>
@@ -191,39 +191,35 @@ private void AdjustWindowPosition(ref double top, ref double left)
+        // Use SystemParameters (DIP units) to match the coordinate system of Window.Top/Left.
+        // MonitorInfo.WorkingArea uses physical pixels which can differ from DIP units when DPI
+        // scaling is active, leading to incorrect results on high-DPI or mixed-DPI setups.
+        return left >= SystemParameters.VirtualScreenLeft &&
+               left < SystemParameters.VirtualScreenLeft + SystemParameters.VirtualScreenWidth &&
+               top >= SystemParameters.VirtualScreenTop &&
</file context>
Suggested change
return left >= SystemParameters.VirtualScreenLeft &&
left < SystemParameters.VirtualScreenLeft + SystemParameters.VirtualScreenWidth &&
top >= SystemParameters.VirtualScreenTop &&
top < SystemParameters.VirtualScreenTop + SystemParameters.VirtualScreenHeight;
foreach (var screen in MonitorInfo.GetDisplayMonitors())
{
var origin = screen.TransformPixelsToDIP(screen.WorkingArea.X, screen.WorkingArea.Y);
var size = screen.TransformPixelsToDIP(screen.WorkingArea.Width, screen.WorkingArea.Height);
if (left >= origin.X && left < origin.X + size.X &&
top >= origin.Y && top < origin.Y + size.Y)
{
return true;
}
}
return false;
Fix with Cubic

@VictoriousRaptor
Copy link
Copy Markdown
Contributor

Please reopen PR under your name when ready to go.

it's more about testing what copilot can do and found a lot of issues in this pr. and i don't have a dual screen setup for testing. closing this pr for now

@jjw24
Copy link
Copy Markdown
Member

jjw24 commented Apr 7, 2026

Ok no worries.

@jjw24 jjw24 deleted the copilot/fix-settings-window-issue branch April 7, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10 min review bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

when i disconnect from 4K monitor, my 2K screen is not opening "Settings"

3 participants