Fix white border artifact on maximized Form (Windows 11)#116
Fix white border artifact on maximized Form (Windows 11)#116
Conversation
Agent-Logs-Url: https://github.com/modern-forms/Modern.Forms/sessions/5ed1c64d-ba49-4a69-b431-72f7f13f8d22 Co-authored-by: jpobst <179295+jpobst@users.noreply.github.com>
|
@copilot While these are good changes, it does not fix the "border" around the maximized window. Some additional information that might help solve the issue:
|
…eiling in OnResize Two root causes are addressed: 1. DoPaint used ScaledClientSize (= (int)(ClientSize * scale)) for the DrawBorder rect and ClipRect. The float round-trip loses 1 device pixel at fractional DPI (e.g. 2576/1.5*1.5 = 2575.99 → int 2575), leaving a 1-pixel strip of form background visible at the right/bottom edges. Fix: use framebuffer.Size directly (the actual pixel count from the OS), and use fb_display_rect.Right/Bottom for the ClipRect instead of the coincidentally-correct Width+1/Height+1 formula. 2. OnResize passed (int)size.Width to adapter.SetBounds, truncating any fractional logical width. Controls ended up 1 logical pixel too narrow, so their device pixel buffers were 1-2 pixels short of the framebuffer. Fix: use Math.Ceiling(size.Width/Height) so controls always cover the full framebuffer even when the logical size is non-integer. Agent-Logs-Url: https://github.com/modern-forms/Modern.Forms/sessions/ea515327-4889-4d74-8182-1e6b64106d6c Co-authored-by: jpobst <179295+jpobst@users.noreply.github.com>
Thanks for the detailed explanation — that pointed me to two additional root causes I was missing. Root cause 1 — Border drawn even when maximized (addressed in first commit): Root cause 2 — Float precision loss in Fixes in
|
On Windows 11 (particularly at fractional DPI scaling), maximizing a
FormwithUseSystemDecorations = falseproduces empty space at the window edges where content is not drawn and the window background shows through. The content is in the correct location but is clipped, and the top/left edge is not fully drawn.Root Causes
Two separate root causes were identified and fixed:
1. Form always painted a 1px border even when maximized —
Form.DefaultStylesetsBorder.Width = 1, creating a visible colored strip at the screen edges and an offset that prevents content from filling the window corners.2. Floating-point precision loss in
DoPaintandOnResize—ScaledClientSizewas computed as(int)(ClientSize.Width * RenderScaling). BecauseClientSize.Width = GetClientRect.right / RenderScaling(a float division), the round-trippixels ÷ scale × scaleloses 1 pixel — e.g.2576 / 1.5 × 1.5 = 2575.999… → (int) = 2575. This made theDrawBorderrectangle andClipRect1 pixel too small, leaving a strip of form background at the edges and clipping the top/left content pixel.Changes
No border when maximized (
Form.cs) — Added a per-instancemaximized_style(ControlStyleinheriting dynamically from the instanceStylevia parent chain) withBorder.Width = 0.CurrentStyleis overridden to return it whenWindowState == Maximized, causingControlAdapter.OnPaintto useform_x = form_y = 0so controls fill from the very edge of the framebuffer.Disable resize handling when maximized (
Form.cs) —HandleMouseDownreturnsfalseimmediately when maximized (prevents accidental resize drags from window edges).HandleMouseMovedelegates tobasewhen maximized (suppresses resize cursors).Use actual framebuffer dimensions in
DoPaint(WindowBase.cs) — ReplacedScaledClientSizewithframebuffer.Size.Width/Heightfor bothDrawBorderandClipRect, eliminating the float round-trip precision loss. Also fixed theClipRectformula from the accidentally-correctWidth+1to the semantically correctfb_display_rect.Right/Bottom.Use
Math.CeilinginOnResize(WindowBase.cs) — Changedadapter.SetBoundsfrom(int)size.Widthto(int)Math.Ceiling(size.Width)so controls always cover the full framebuffer even when the logical window size is fractional (e.g.2576 px / 1.5 = 1717.33logical px).