- Improve default performance when components check if they are opaque
- Allows all components to take advantage of setPaintingIsUnclipped
- Give more control to opt out of opaque checks separate from setPaintingIsUnclipped
In the DemoRunner, switching to and fro between the Settings tab and
the Demo tab displaying the OpenGL demo could lead to
GL_INVALID_OPERATION errors. This is because closing the demo shuts
down the GL context, destroying resources such as framebuffers. If any
Image objects backed by framebuffers outlive the context, they will be
invalidated. Component effect images are especially likely to hold onto
invalid framebuffer references.
With this change in place, images cached by Components will be
invalidated when the attached GL context goes out of scope, and will be
recreated when the new context is created.
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 change makes it slightly easier to audit invariants of
ModalComponentManager, as we can now be certain that only member
functions of ModalComponentManager can access its data members.
- Created a new detail namespace
- Moved shared module implementation details into the detail namespace
- Split dependencies so source files only rely on details in the detail namespace
- Removed all code from the juce_gui_basics.cpp file
Previously, individual components had to ask the peer to hide and show
the keyboard, by calling textInputRequired() and
dismissPendingTextInput() respectively. When an onscreen keyboard (OSK)
was required, most Peer implementation would directly hide/show the OSK
inside these function. However, the iOS ComponentPeer implementation
instead listened to the application's global keyboard focus, and only
opened the OSK when the focused component was also a TextInputTarget
with active input.
The iOS scheme seems like a better design, as it enforces that the OSK
hiding and showing is synced with the keyboard focus of the application.
In the other implementations, it was possible for a Component to call
textInputRequired even when it didn't have the keyboard focus, putting
the application into an inconsistent state. The iOS scheme also makes
the TextInputTarget interface more useful, as it enforces that the OSK
will only display for components that implement TextInputTarget, and
return true from isTextInputActive().
This patch changes all Peer implementations to match the iOS
implementation, improving consistency. Each time the global keyboard
focus changes, refreshTextInputTarget is called automatically, and the
OSK is shown if the focused component is a TextInputTarget that returns
true from isTextInputActive, and hidden otherwise. Components can also
call refreshTextInputTarget manually. This should be done whenever the
component updates the return value of isTextInputActive(). Effectively,
the Peer is now responsible for keeping track of the focused
TextInputTarget, rather than allowing individual components to hide and
show the OSK at will.
Additionally, this patch adds an option to the TextEditor to
automatically dismiss the OSK when the mouse is clicked outside of the
editor. This should improve user experience on mobile platforms, where
touches on sibling components may cause a TextEditor to gain keyboard
focus and unnecessarily display the OSK.
The previous implementation would pass the mouse wheel event up to the
component's parent, as long as the parent was enabled. This meant that a
wheel event on the innermost component of a hierarchy such as
"[[disabled] enabled]" would send the event to the parent, but a wheel
event on the innermost component of a hierarchy such as
"[[[disabled] disabled] enabled]" would 'eat' the event and prevent it
from propagating.
After this change, unhandled mouse wheel events will always be passed to
the nearest enabled parent. This behaviour is more consistent and
intuitive.
The bug was triggered on Monterey where a pressure of 1 is reported
while a mouse button is being held down. This caused an extra drag
event being triggered between mouse down and up events, even if no
movement occurred.
This change allows mouse events (including enter and exit events) to
reach unfocused views on macOS. This matches the behaviour of unfocused
windows on Linux and Windows, where components paint in their "hovered"
states even when the application window is in the background.
As a byproduct of using tracking areas on macOS, we can remove the fake
mouse move generator.