The issue prior to this commit would be observable when using the
GlyphArrangement functions e.g. addFittedText.
This is a fix for a regression introduced in
9223805b9c.
Previously, the vblank's thread loop would block on each iteration until
the current async callback had finished, at which point a new async
callback would be immediately triggered.
The new implementation only waits on the vblank event. If a vblank
callback is still in progress the next time the vblank event is
signalled, we assume the last frame is overrunning and avoid sending a
new async update.
The intention of this change is to avoid saturating the message thread
with expensive vblank callbacks. It's also nice to remove a lock,
although that's just an incidental change.
This issue could be observed in the GraphicsDemo's SVG pane, when the
"rotation" option was enabled.
Drawables internally enable the unclipped painting flag, which normally
prevents slow clipping when drawing subcomponents of the drawable.
The Direct2D graphics context was using the frame area as the default
area, used to signal that no clipping should be applied. However, when
non-axis-aligned transform was active, this area was incorrectly applied
as a geometric clipping region. D2D geometric clips are relatively slow,
so this caused large slowdowns.
This solution adds a flag that is set whenever a clip is explicitly
requested. If no clip is explicitly requested, then clipping will be
entirely bypassed. This can make rendering of Drawables significantly
faster.
When building in C++23 mode for iOS with Xcode 16.1 and Ninja, this
symbol could not be found, presumably because it is no longer included
transitively via other standard headers.
Prior to this a soft break could occur between two characters printed in
different fonts, even though there was no break opportunity there in the
Unicode string.
Previously, if the very first call to
MidiDeviceListConnectionBroadcaster::get() happened on a background
thread (which could happen on macOS in response to a MIDI setup
configuration change), then MessageManager::getInstance and
getAvailableDevices could be called on that same thread.
With this change in place, midi change notifications will be ignored if
there's no message manager available, and getAvailableDevices will only
be called on the message thread.
When two monitors are available, both with different scale factors, then
the drag-image may 'detach' from the mouse while the image's top-left
coordinate was on one display, and the mouse cursor was on the other
display.
This happened because, on Windows, the mouse cursor moves continuously
in physical (not logical!) space. In other words, the mouse may not move
continuously in logical space, and the discontinuity becomes visible
when components are positioned relative to the mouse in logical space.
In order to display consistently, the top-left position of the image
must be set relative to the physical position of the mouse.
This bug could be observed by running the WidgetsDemo Drag+Drop pane on
Windows 10, and dragging an item between two displays at different scale
factors.
This is issue is a regression introduced in
9817a2bb66. The regression was caused by
the change in mouse position calculation. The incorrect version switched
to using ClientToScreen, but the correct version used
getPointFromLocalLParam.
The function getPointFromLocalLParam was replaced by clientLParamToPoint
in 24ab3cb6a3, and is restored by this
commit.
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.