Skip to content

Fixed Incorrect Window.Y and Window.Height values when closing a maximized window - #29253

Merged
kubaflo merged 19 commits into
dotnet:inflight/currentfrom
Dhivya-SF4094:fix-29066
Jun 4, 2026
Merged

Fixed Incorrect Window.Y and Window.Height values when closing a maximized window#29253
kubaflo merged 19 commits into
dotnet:inflight/currentfrom
Dhivya-SF4094:fix-29066

Conversation

@Dhivya-SF4094

@Dhivya-SF4094 Dhivya-SF4094 commented Apr 29, 2025

Copy link
Copy Markdown
Contributor

Issue Detail:

On the Windows platform, if the application window is maximized, the main window X,Y values are in negative (-7, -7). For a non-maximized window, values are correct.

Root Cause

On Windows, when the application window is maximized, the values of Window.Y and Window.Height reported during Window_Destroying are offset by 8 pixels. This occurs because the default window bounds include the non-client area (e.g., title bar and borders), which is excluded by the OS when maximizing the window. As a result, the bounds do not accurately reflect the actual client area used by the application, leading to incorrect frame values being reported to the virtual view.

Description of Change

To resolve this, the implementation now uses the Windows Desktop Window Manager (DWM) API to retrieve the extended frame bounds via DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute. These bounds reflect the full screen-space dimensions of the window, even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal state, the position and size reported by AppWindow are used directly. When the window is maximized, the logic switches to use the bounds provided by the DWM API. This ensures that the virtual view receives accurate and consistent frame data (X, Y, Width, and Height) regardless of the window state.

Validated the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Issues Fixed:

Fixes #29066

Screenshots

Before  After 
     

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Apr 29, 2025
Comment thread src/Core/src/Platform/Windows/WindowExtensions.cs Outdated
Comment thread src/Core/src/Platform/Windows/WindowExtensions.cs Outdated
Comment thread src/Core/src/Handlers/Window/WindowHandler.Windows.cs Outdated
@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jsuarezruiz jsuarezruiz 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.

The test SizeChangedOnlyFiresWhenSizeChanges is failing on Windows:

Assert.That(initialValue, Is.EqualTo(finalValue))
String lengths are both 15. Strings differ at index 8.
Expected: "resized 3 times"
But was:  "resized 1 times"
-------------------^

Is depending on Window size changes, could you verify if is related with the changes?

Comment thread src/Core/src/Platform/Windows/WindowExtensions.cs Outdated
@Dhivya-SF4094

Copy link
Copy Markdown
Contributor Author

The test SizeChangedOnlyFiresWhenSizeChanges is failing on Windows:

Assert.That(initialValue, Is.EqualTo(finalValue))
String lengths are both 15. Strings differ at index 8.
Expected: "resized 3 times"
But was:  "resized 1 times"
-------------------^

Is depending on Window size changes, could you verify if is related with the changes?

@jsuarezruiz Currently looking into the SizeChangedOnlyFiresWhenSizeChanges test failure on Windows.

@Dhivya-SF4094

Copy link
Copy Markdown
Contributor Author

The test SizeChangedOnlyFiresWhenSizeChanges is failing on Windows:

Assert.That(initialValue, Is.EqualTo(finalValue))
String lengths are both 15. Strings differ at index 8.
Expected: "resized 3 times"
But was:  "resized 1 times"
-------------------^

Is depending on Window size changes, could you verify if is related with the changes?

@jsuarezruiz Fixed CI failure. Could you please review it once.

@Dhivya-SF4094
Dhivya-SF4094 marked this pull request as ready for review May 8, 2025 09:37
@Dhivya-SF4094
Dhivya-SF4094 requested a review from a team as a code owner May 8, 2025 09:37
@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Comment thread src/Core/src/Handlers/Window/WindowHandler.Windows.cs Outdated
@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 3 pipeline(s).

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-failed AI could not verify tests catch the bug s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Mar 22, 2026

@kubaflo kubaflo 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.

Could you please review the AI's summary?

MauiBot

This comment was marked as outdated.

@kubaflo kubaflo 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.

Could you please check the ai's suggestions?

@Dhivya-SF4094

Copy link
Copy Markdown
Contributor Author

Reviewed and validated the AI summary findings, and addressed the concern.

@kubaflo

kubaflo commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 3 findings

See inline comments for details.

{
// Use the HWND cached at ConnectHandler — it never changes and this method
// runs on every move/resize event, so avoid the COM round-trip each time.
if (_hwnd == IntPtr.Zero)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[moderate] Logic and Correctness — The _hwnd == IntPtr.Zero guard exits UpdateVirtualViewFrame entirely, silently suppressing the pre-existing appWindow.Size / appWindow.Position -> VirtualView.FrameChanged() path that does not use _hwnd at all. The code comment only justifies skipping the DWM P/Invoke; blocking the non-DWM frame update is an unintended side effect.

In practice this never fires today: _hwnd is assigned in ConnectHandler before UpdateVirtualViewFrame is first called and before appWindow.Changed is subscribed, and it is only zeroed after appWindow.Changed is unsubscribed in DisconnectHandler. However, if GetWindowHandle() ever returned IntPtr.Zero at connect time, every subsequent AppWindow.Changed event would silently drop the frame update instead of falling back to appWindow.Size / appWindow.Position.

Scope the HWND check to the DWM branch only so normal frame updates still use the existing AppWindow fallback when no HWND is available.


int hr = DwmGetWindowAttribute(hWnd, DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS,
out bounds, Marshal.SizeOf<RECT>());
return hr == 0 && (bounds.Right - bounds.Left) > 0 && (bounds.Bottom - bounds.Top) > 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[minor] Windows Platform SpecificsTryGetExtendedFrameBounds correctly requires hr == 0 and a non-empty RECT before using DWM bounds. Consider documenting why the non-zero-size guard exists: it is defensive fallback behavior for unavailable or transitional DWM bounds, not a guard against negative monitor coordinates.

// Assert that the bounds reported at Destroying time match the monitor work area,
// using the same < 2 tolerance as WindowsBoundsWhenMaximized. This catches
// regressions where Y or Height is off by ~8 pixels when closing a maximized window.
Assert.False(double.IsNaN(destroyingHeight), "Window.Destroying event was not raised");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[minor] Regression PreventionWindowsYAndHeightCorrectWhenClosingMaximizedWindow checks destroyingHeight for NaN to prove Destroying fired. Add the same sentinel check for destroyingY so a missing or malformed captured Y value reports the lifecycle problem directly instead of falling through to the tolerance assertion.

MauiBot

This comment was marked as outdated.

@kubaflo

kubaflo commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@Dhivya-SF4094 — new AI review results are available based on this last commit: 623fd3e.
Updated WindowsTests.Windows.cs To request a fresh review after new comments or commits, comment /review rerun.

Gate Unknown Code Review In Review Confidence Medium Platform Windows

Review Sessions — click to expand
Gate — Test Before & After Fix

Gate Result: ⚠️ ENV ERROR

Platform: WINDOWS · Base: main · Merge base: e904e900

Test Without Fix (expect FAIL) With Fix (expect PASS)
📱 WindowTests (WindowsBoundsWhenMaximized, WindowsYAndHeightCorrectWhenClosingMaximizedWindow) Category=Window ⚠️ ENV ERROR ⚠️ ENV ERROR
🔴 Without fix — 📱 WindowTests (WindowsBoundsWhenMaximized, WindowsYAndHeightCorrectWhenClosingMaximizedWindow): ⚠️ ENV ERROR · 234s

No log file found

🟢 With fix — 📱 WindowTests (WindowsBoundsWhenMaximized, WindowsYAndHeightCorrectWhenClosingMaximizedWindow): ⚠️ ENV ERROR · 231s

No log file found

⚠️ Failure Details

  • ⚠️ WindowTests (WindowsBoundsWhenMaximized, WindowsYAndHeightCorrectWhenClosingMaximizedWindow) without fix: Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32".
  • ⚠️ WindowTests (WindowsBoundsWhenMaximized, WindowsYAndHeightCorrectWhenClosingMaximizedWindow) with fix: Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32".
📁 Fix files reverted (3 files)
  • eng/pipelines/ci-copilot.yml
  • src/Core/src/Handlers/Window/WindowHandler.Windows.cs
  • src/Essentials/src/Platform/PlatformMethods.windows.cs

UI Tests — Essentials,ViewBaseTests,Window

Detected UI test categories: Essentials,ViewBaseTests,Window

Deep UI tests — 131 passed, 1 failed across 3 categories on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
Essentials 0/1 (1 ❌)
ViewBaseTests 115/115 ✓
Window 16/16 ✓
Essentials — 1 failed test
MicrophonePermissionCheckDoesNotCrash
System.TimeoutException : Timed out waiting for element...
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests.Issues.Issue32989.MicrophonePermissionCheckDoesNotCrash() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32989.cs:line 17
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at Sy
...

📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)


Pre-Flight — Context & Validation

Issue: #29066 - Incorrect Window.Y and Window.Height values when closing a maximized window
PR: #29253 - Fixed Incorrect Window.Y and Window.Height values when closing a maximized window
Platforms Affected: Windows
Files Changed: 2 implementation, 1 test

Key Findings

  • The issue reports Windows-only Window.Destroying values where maximized Window.Y is about 8 px too low and Window.Height about 8 px too high; non-maximized values are correct.
  • The PR's current fix caches the HWND in WindowHandler.Windows, uses DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS) only when the OverlappedPresenter state is maximized, and falls back to AppWindow.Position/Size if DWM bounds are unavailable or invalid.
  • Added Windows device tests compare maximized MAUI window bounds against DisplayArea.WorkArea with density conversion and include a Destroying-time regression test.
  • Prior discussion/reviews focused on invalid HWND handling, empty DWM bounds fallback, using Presenter.State rather than IsMaximizable, avoiding hard-coded DWM constants, multi-monitor negative coordinates, and ensuring the tests actually wait for maximized work-area bounds and catch the Destroying-time off-by-8 regression.
  • Test type: Windows Controls device tests. Relevant category: Window. Target command for try-fix: pwsh .github\skills\run-device-tests\scripts\Run-DeviceTests.ps1 -Project Controls -Platform windows -TestFilter "Category=Window".
  • Gate result supplied by caller: Gate failed; do not re-run gate verification. Treat test validation in try-fix as attempted candidate validation only.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: medium
Errors: 0 | Warnings: 1 | Suggestions: 0

Key code review findings:

  • Warning: Required CI/gate status is not green/fully verifiable in this environment; the code-review sub-agent found no actionable code defects in the modified lines.

Failure-mode probes and blast radius:

  • If DWM returns an empty/invalid rectangle, the current PR falls back to AppWindow.Position/Size via TryGetExtendedFrameBounds returning false.
  • If the HWND is not available, the current PR returns early from UpdateVirtualViewFrame; this avoids a DWM call but risks skipping frame updates if the cached handle was not set.
  • Maximized detection is limited to OverlappedPresenterState.Maximized, so normal/minimized/restored window bounds continue to use the existing AppWindow path.
  • Multi-monitor setups can have negative work-area X/Y; tests should compare against work-area bounds rather than assume zero/non-negative coordinates.
  • Blast radius is Windows-only WindowHandler frame reporting for move/resize events and Destroying-time cached frame reads; non-Windows platforms are unaffected.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #29253 Use cached HWND and DWM extended frame bounds for maximized Windows windows, with fallback to AppWindow bounds, plus Windows device tests for live and Destroying maximized bounds. FAILED (Gate, supplied by caller) src/Core/src/Handlers/Window/WindowHandler.Windows.cs, src/Essentials/src/Platform/PlatformMethods.windows.cs, src/Controls/tests/DeviceTests/Elements/Window/WindowTests.Windows.cs Original PR

Code Review — Deep Analysis

Code Review PR #29253

Independent Assessment

What this changes: Windows WindowHandler now caches the HWND at connect time and, while the AppWindow is maximized, reports IWindow.FrameChanged from DWM extended frame bounds instead of AppWindow.Position/Size. It also adds Windows device coverage for maximized window bounds and destroy-time bounds.
Inferred motivation: Avoid reporting the invisible resize-border offsets included in maximized AppWindow bounds, especially when Window.Destroying reads Window.Y/Window.Height.

Reconciliation with PR Narrative

Author claims: The PR fixes incorrect Windows Window.Y/Window.Height values when closing a maximized window by using DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS) for maximized windows and adds validation tests.
Agreement/disagreement: This matches the code. Current implementation also incorporates prior review feedback: nonzero HWND guard, DWM failure fallback to AppWindow bounds, and no DWM use for non-maximized windows.

Findings

Warning Required CI currently failing

GitHub checks for head 623fd3eadb6a0317ccde5bc8a9df911a2cd19f09 show maui-pr and Build Analysis failing with Microsoft.Maui.Essentials.AI.UnitTests failures (StreamingJsonDeserializerTests+FileBasedTests.ProcessChunk_TxtFile_UpdateRate / Helix BadExit). These do not appear related to the Windows window-handler changes, but the PR should not be considered green until CI is resolved or accepted as unrelated infrastructure/flakiness.

No code errors found in the modified lines.

Devil's Advocate

The main risk is Windows/DWM behavior varying across DPI/multi-monitor configurations, but the code only switches to DWM when maximized, validates nonzero returned bounds, divides by current display density consistently with the existing AppWindow path, and adds tests that compare against the monitor work area including negative coordinates. I did not run Windows device tests locally, and CI is not green.

Verdict: NEEDS_DISCUSSION

Confidence: medium
Summary: Code review found no actionable code defects; the implementation is targeted and follows handler lifecycle cleanup by resetting the cached HWND and unsubscribing events. Verdict is not LGTM because required CI is currently failing and needs human/CI-owner disposition.


Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Replace maximized AppWindow frame with DisplayArea.WorkArea. Fail 1 file XML/test-agent evidence indicated Window tests passed, but the device-test command failed during result-summary aggregation, so this is not a clean full-command pass. Simpler than the PR because it avoids HWND caching and native interop.
2 try-fix Keep AppWindow bounds and subtract the Win32 maximized phantom border from GetSystemMetricsForDpi(SM_CXSIZEFRAME + SM_CXPADDEDBORDER). Fail 2 files XML result files showed 28/28 Window and 1/1 WindowOverlay tests passed, but the device-test command failed during result-summary aggregation. Self-review found one moderate borderless-maximized edge case.
PR PR #29253 Use cached HWND and DWM extended frame bounds for maximized Windows windows, with fallback to AppWindow bounds, plus Windows device tests. Failed (Gate, supplied by caller) 3 files Original PR.

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 1 Yes Candidate 1: use managed WinUI DisplayArea.WorkArea instead of DWM.
claude-opus-4.7 1 Yes Candidate 2: mathematically subtract the Win32 maximized phantom border instead of querying DWM or substituting work area.

Candidate Results

Candidate 1: The DisplayArea approach is the strongest alternative by design: it is Windows-only, avoids new P/Invoke, avoids HWND caching, naturally supports negative monitor coordinates, and directly matches what a maximized window should expose to MAUI. The run was not recorded as a clean pass because Run-DeviceTests.ps1 failed after running the categories with Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32".

Candidate 2: The system-metric correction also produced passing XML test results for the issue-specific tests, but it is less attractive than the PR and candidate 1. It adds more Win32 interop, uses a broader mathematical correction, and self-review identified a moderate borderless-maximized edge case where subtracting the standard chrome border could over-correct.

Failure / Blocker Analysis

Both candidates hit the same Windows device-test runner post-processing failure after the categories executed:

Get-WindowsDeviceTestResultSummary: .github\skills\run-device-tests\scripts\Run-DeviceTests.ps1:350
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32".

Candidate 2 additionally parsed XML result files showing all executed tests passed (Window: 28/28, WindowOverlay: 1/1). Because the provided test command itself did not complete cleanly, neither alternative is recorded as a full-command pass.

Selection

Exhausted: Yes

Selected Fix: None as a clean replacement. Candidate 1 is the best alternative design if the runner-summary blocker is disregarded, but the requested stop condition requires a candidate that passes all validation and is demonstrably better than the PR. Candidate 2 has stronger XML evidence but is not demonstrably better due to extra interop and the borderless-maximized self-review concern.


Report — Final Recommendation

Comparative Analysis

Candidates Compared

Rank Candidate Regression status Assessment
1 pr-plus-reviewer Failed / not cleanly verified Same implementation as pr; MAUI expert review found no actionable defects, so no reviewer changes were applied. The design is targeted to maximized Windows windows, uses DWM visible frame bounds only for the affected state, and falls back to AppWindow bounds when DWM data is unavailable or invalid.
2 pr Failed / not cleanly verified The raw PR fix is code-equivalent to pr-plus-reviewer. It is ranked slightly below only because the reviewed candidate explicitly incorporates the expert-review pass, even though that pass produced no diff.
3 try-fix-1 Failed full command Uses DisplayArea.WorkArea for maximized windows. This is the simplest alternative and avoids HWND caching/native DWM interop, but the recorded validation command failed during result-summary aggregation, so it cannot outrank the PR candidates. It also substitutes the whole work area rather than measuring the actual visible window frame.
4 try-fix-2 Failed full command; XML tests passed Subtracts Win32 maximized phantom border via system metrics. XML result files show the relevant tests passed, but the full command still failed and self-review found a moderate borderless-maximized over-correction risk. It adds broader Win32 interop and more assumptions than the PR fix.

Regression-Test Rule

No candidate is recorded as a clean full-command regression-test pass. The PR/gate artifact failed due to the supplied gate result, and both try-fix candidates failed under the try-fix rules because the device-test command exited with the Windows result-summary conversion error. Candidate 2 has stronger test evidence than candidate 1 because XML results showed all executed Window tests passed, but it is still not a clean pass and has a design risk.

Decision

Winner: pr-plus-reviewer

The winning candidate is the reviewed PR fix. It has no actionable expert-review findings, preserves the submitted PR's focused Windows-only DWM approach, and avoids the broader assumptions in both alternatives. Since all candidates failed clean validation, the deciding factors are implementation correctness, blast radius, and reviewer findings; on those criteria, pr-plus-reviewer is strongest.


Future Action — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@kubaflo
kubaflo changed the base branch from main to inflight/current June 4, 2026 21:11
@kubaflo
kubaflo merged commit 17b34c3 into dotnet:inflight/current Jun 4, 2026
36 of 39 checks passed
@github-actions github-actions Bot added this to the .NET 10.0 SR8 milestone Jun 4, 2026
PureWeen pushed a commit that referenced this pull request Jun 11, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
@sheiksyedm sheiksyedm modified the milestones: .NET 10 SR8, .NET 10 SR9 Jun 18, 2026
PureWeen pushed a commit that referenced this pull request Jun 22, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
kubaflo pushed a commit that referenced this pull request Jun 25, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
kubaflo pushed a commit that referenced this pull request Jul 3, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
@kubaflo kubaflo mentioned this pull request Jul 6, 2026
kubaflo pushed a commit that referenced this pull request Jul 6, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
PureWeen pushed a commit that referenced this pull request Jul 7, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
PureWeen pushed a commit that referenced this pull request Jul 7, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
kubaflo pushed a commit that referenced this pull request Jul 10, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
kubaflo pushed a commit that referenced this pull request Jul 15, 2026
…mized window (#29253)

### Issue Detail:
 
On the Windows platform, if the application window is maximized, the
main window X,Y values are in negative (-7, -7). For a non-maximized
window, values are correct.
 
### Root Cause
On Windows, when the application window is maximized, the values of
Window.Y and Window.Height reported during Window_Destroying are offset
by 8 pixels. This occurs because the default window bounds include the
non-client area (e.g., title bar and borders), which is excluded by the
OS when maximizing the window. As a result, the bounds do not accurately
reflect the actual client area used by the application, leading to
incorrect frame values being reported to the virtual view.
 
### Description of Change
To resolve this, the implementation now uses the Windows Desktop Window
Manager (DWM) API to retrieve the extended frame bounds via
DwmGetWindowAttribute with the DWMWA_EXTENDED_FRAME_BOUNDS attribute.
These bounds reflect the full screen-space dimensions of the window,
even when maximized.

In the UpdateVirtualViewFrame method, when the window is in a normal
state, the position and size reported by AppWindow are used directly.
When the window is maximized, the logic switches to use the bounds
provided by the DWM API. This ensures that the virtual view receives
accurate and consistent frame data (X, Y, Width, and Height) regardless
of the window state.

### Validated the behaviour in the following platforms
- [ ] Android
- [x] Windows
- [ ] iOS
- [ ] Mac
### Issues Fixed:
Fixes #29066
 
### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/3d5c192f-b681-491f-971a-6d6c0822ad12">
|  <img
src="https://github.com/user-attachments/assets/255b3ea5-c147-414d-9bce-6dbe119b4b2b"> 
|
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-window Window community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/windows s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-failed AI could not verify tests catch the bug s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Window.Y and Window.Height values when closing a maximized window

9 participants