mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Windowing: Avoid changing window bounds in WM_WINDOWPOSCHANGING
This change intends to address a bug observed only on Windows 10 with a display scale factor of 125%. When the native titlebar is enabled, and the window's border-resizer is used to resize the window slowly the with mouse, the client area of the window may move to the wrong location, or be drawn with some areas obscured/clipped. This is especially observable when resizing the WidgetsDemo to its smallest size, and then dragging the right border a single pixel to the right. On my computer, this consistently causes the client area to display at the wrong location. I haven't been able to find any obvious bug in JUCE that might cause this behaviour. In particular, it seems that the window begins displaying incorrectly *before* the window ever actually resizes. During the resize, the system sends events (WM_SIZING and WM_WINDOWPOSCHANGING) to the window, and according to the documentation, the window may modify the message parameters in order to constrain the new window size. When running on a scaled display, JUCE attempts to map the logical client area size to a sensible size in physical pixels, and uses the sizing messages to enforce this size requirement. In the case of the broken window rendering, the system requests a new window size, which JUCE rejects. The window's display state doesn't change, so the swap chain does not resize, and the swap chain does not present. Put another way, the broken rendering happens *independently* of JUCE modifying the swap chain in any way. Therefore, I believe that the bug is introduced elsewhere, potentially by Windows itself. I also checked to see whether the issue could be caused by mishandling of the NCCALCSIZE message, which is normally used to configure the relative positions of the client and nonclient areas. However, in the buggy case, NCCALCSIZE is not sent until *after* the first 'broken' frame is painted - and even then, the implementation immediately falls back to DefWindowProc. Given that the issue appears to be a bug in Windows, the proposed change is a workaround, rather than a true fix. It appears as though the problem goes away when WM_WINDOWPOSCHANGING does not modify the requested bounds. Therefore, for windows with native titlebars, we rely on the constraints to be applied in WM_SIZING only, when sizing the window in a sizemove gesture.
This commit is contained in:
parent
81a95abb3c
commit
c24d1a17a7
1 changed files with 13 additions and 1 deletions
|
|
@ -2231,7 +2231,7 @@ private:
|
||||||
uint32 lastPaintTime = 0;
|
uint32 lastPaintTime = 0;
|
||||||
ULONGLONG lastMagnifySize = 0;
|
ULONGLONG lastMagnifySize = 0;
|
||||||
bool isDragging = false, isMouseOver = false,
|
bool isDragging = false, isMouseOver = false,
|
||||||
hasCreatedCaret = false, constrainerIsResizing = false;
|
hasCreatedCaret = false, constrainerIsResizing = false, sizing = false;
|
||||||
IconConverters::IconPtr currentWindowIcon;
|
IconConverters::IconPtr currentWindowIcon;
|
||||||
FileDropTarget* dropTarget = nullptr;
|
FileDropTarget* dropTarget = nullptr;
|
||||||
UWPUIViewSettings uwpViewSettings;
|
UWPUIViewSettings uwpViewSettings;
|
||||||
|
|
@ -4010,13 +4010,25 @@ private:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
case WM_ENTERSIZEMOVE:
|
||||||
|
sizing = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_EXITSIZEMOVE:
|
||||||
|
sizing = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_SIZING:
|
case WM_SIZING:
|
||||||
|
sizing = true;
|
||||||
return handleSizeConstraining (*(RECT*) lParam, wParam);
|
return handleSizeConstraining (*(RECT*) lParam, wParam);
|
||||||
|
|
||||||
case WM_MOVING:
|
case WM_MOVING:
|
||||||
return handleSizeConstraining (*(RECT*) lParam, 0);
|
return handleSizeConstraining (*(RECT*) lParam, 0);
|
||||||
|
|
||||||
case WM_WINDOWPOSCHANGING:
|
case WM_WINDOWPOSCHANGING:
|
||||||
|
if (hasTitleBar() && sizing)
|
||||||
|
break;
|
||||||
|
|
||||||
return handlePositionChanging (*(WINDOWPOS*) lParam);
|
return handlePositionChanging (*(WINDOWPOS*) lParam);
|
||||||
|
|
||||||
case 0x2e0: /* WM_DPICHANGED */ return handleDPIChanging ((int) HIWORD (wParam), *(RECT*) lParam);
|
case 0x2e0: /* WM_DPICHANGED */ return handleDPIChanging ((int) HIWORD (wParam), *(RECT*) lParam);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue