This fixes an issue where Direct2D will emit an error when using dirty
rects on the first full frame after resizing.
The issue isn't present on all hardware/drivers, but was observed on a
Windows 11 computer with a 890M iGPU.
Partially reverts a change made in
362a1cc070.
The factory needs to be multithreading-enabled in order to support e.g.
drawing to the screen on the main thread and drawing to an Image on a
background thread, even when no resources other than the graphics device
are shared between the two threads.
Previously, IDXGISwapChain::Present was called on a background thread,
which made it difficult to avoid race conditions. e.g. during a
live-resize of a window, we would occasionally draw old incomplete
frames instead of new frames at the correct size.
The new approach moves the Present call to the main thread via
AsyncUpdater. We attempt to present whenever the swap event wakes, and
whenever a frame is drawn. Only a single Present call may be made after
the swap event wakes. Subsequent Present calls will be ignored until the
next time the swap event wakes.
The waiting is only added on iOS 18 as this is the only platform where
seems to be an asynchronous relationship between
(1) AVAudioSession setActive:
(2) AVAudioSession setPreferredIOBufferDuration:
and (3) AVAudioSession.IOBufferDuration.
The issue is not observable in the iOS 18 emulator.
All NSUserNotification related classes have been deprecated in MacOS 11,
and this class will have to be revamped to use the new User
Notifications framework. We are suppressing the warnings for the time
being.
WebView2 can emit COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_ABORTED
errors during page navigation, even if the page navigation would happen
correctly afterwards. In such situations our internal error handler can
recursively encounter this error when trying to navigate to the error
handler page.
Prior to this commit the implementation could end up in an infinite loop
receiving the error and then navigating to the error handler page.
This reverts 515e9b9f89.
In order to avoid recursive calls through WM_NCHITTEST, we remove calls
to Component::contains in DocumentWindow::findControlAtPoint.
For some transforms, the program could get stuck in the following loop:
- The content component emits a resized/moved notification, leading to
the initial call to Viewport::updateVisibleArea.
- New positions are computed for the viewport scrollbars, and scrollbar
listeners are notified synchronously that the scrollbars have been
updated.
- The viewport itself listens to the scrollbars, so it receives a
notification and updates the position of the content component.
- The scrollbar position (quantised to an integer) resolves to a
component position (also quantised to an integer) that differs from
the existing position, so the new position is applied.
- The viewport now attempts to set the scrollbars to the correct
position in response, and notifies listeners that the scrollbars
have moved...
Normally, the recursion would exit at the point where the component position
is set to its current position. If we're unlucky, though, converting
from view pos to scrollbar pos, then scrollbar pos back to view pos may
result in a view pos that differs from the original value.
This fix adds a new exit condition from the recursion. On receiving a
scrollbar move notification, we check whether the scrollbar position
computed from the current view position matches the incoming scrollbar
position. If it does, there's no need to compute and apply a new view
position from the incoming scrollbar position.
This allows for styles other than normal/bold/italic/bold-italic to be
selected, and more closely matches the behaviour of font selection on
other platforms.
Prior to this commit we used the integral version of localAreaToGlobal
before multiplying its result by the scale factor. This multiplied the
rounding error of localAreaToGlobal<int> by the scale factor. Now we
only round after all calculations have been carried out.
The input coordinates were unnecessarily converted and truncated to
integral values before follow up calculations, and then a final
conversion back to integral values.
This partially reverts commit 555b667d22.
Using ComponentPeer::isShowing instead of ComponentPeer::isMinimised
inside Component::isShowing can cause problems when displaying OpenGL
components.
Specifically, OpenGL components use a ComponentMovementWatcher to
determine when they should be attached/detached from the parent window.
The ComponentMovementWatcher updates whenever a component visibility
change event is emitted, which happens in two cases:
- Component::setVisible is called on the OpenGL component or an ancestor
- ComponentPeer::handleMovedOrResized is called in response to a
minimisation state change
When handling either of these events, the ComponentMovementWatcher will
call Component::isShowing to determine whether or not the component is
really showing.
The problem is that the result of ComponentPeer::isShowing may change
independently of changes to the Component visiblity state or
ComponentPeer minimisation state, so the ComponentPeerWatcher might not
notify its listeners when a component is really shown/hidden.
One potential workaround would be for the ComponentPeer to send
notifications when the showing state of the window changes, so that the
ComponentMovementWatcher can forward those notifications. The main
problem with this approach is that on Windows, the window doesn't seem
to receive a message on hide/show, and it's not clear whether there
exists some other approach to detect a hide/show event.
If there were some event we could listen for on Windows, then we could
call Component::sendVisibilityChangeMessage in response to this event
and things would *likely* work at that point, but this may still have
unintended side-effect. As a result, I think the best approach to
restore the old behaviour is to revert the change to
Component::isShowing. The implementations of ComponentPeer::isShowing
have been left in place so that users can do still query the real
visibility state of native windows if necessary.
This behaviour, previously available in JUCE 7, was missing since the
JUCE 8 changes related to Unicode text drawing.
With this commit, words that are too long to fit in a line are again
broken up, with the caveat, that we can expect this approach to produce
quirks with bidirectional text. We don't expect that such a feature
could be satisfactorily provided for bidirectional text, so this is a
stopgap measure for legacy applications.