Release pressed input state whenever app or embedder focus changes so editor hover tooltips are not blocked by stale keyboard input while preserving the unfocused joypad behavior in Input.
Adds implicit conversion from `RequiredResult<T_Other>` to `RequiredParam<T>` (where
`T_Other` derives from `T`). This allows passing a `RequiredResult` directly to a
`RequiredParam` without an intermediate variable.
Also changes `SceneTree::get_root()` to return `RequiredResult<Window>`. It is used in a
conversion as described above.
Why non-null: The root window is created in the `SceneTree` constructor and only set to
null in the destructor, so it is always valid during normal use. The function is no longer
`_FORCE_INLINE_` because `RequiredResult<Window>` requires Window to be a complete type.
This property mirrors `custom_minimum_size` and enables the user to set a size the `Control`. Enabling `propagate_maximum_size` forces all children to respect this node's maximum_size.
Not all `Control` types handle this gracefully, which may result in content clipping.
This is useful for 3D games with a pixel art appearance, or when
using a resolution scale of `0.5` to improve performance without
compromising crispness too much when not using FSR 1.0.
The property hints now allow decreasing the scale further to accomodate
for pixel art use cases, as well as increased precision in the value
(useful for a scale of `0.3333`).
Co-authored-by: Daniel Savage <dansvg@gmail.com>
Co-authored-by: Kaleb Reid <78945904+Kaleb-Reid@users.noreply.github.com>
I believe the crash is a stale-lifetime bug in 3D picking.
Viewport::_process_picking() caches last_object / last_id for multiple queued
input events at the same pointer position. If the first _input_event callback
removes the picked CollisionObject3D or current Camera3D from the tree, the next
queued event can still reuse that cached target and call
_collision_object_3d_input_event(), which immediately does get_global_transform
on an object that is no longer safe to query.
The patch does four things:
1. It rejects captured 3D pick targets that are no longer is_inside_tree()
before reuse at viewport.cpp (similar changes exist in the code):
2. It re-fetches the cached same-position object from ObjectDB, verifies it
still matches the cached pointer, and verifies it is still in the tree before
dispatching.
3. It skips _mouse_exit() for a hovered 3D object that has already left the tree
at viewport.cpp.
4. It adds a final guard inside _collision_object_3d_input_event() so even a
future caller cannot query transforms on removed nodes or cameras at
viewport.cpp.
When changing scenes via button click with a touchscreen, nodes can be removed
from the tree during input event processing. The ERR_FAIL_COND_V assertion in
can_process() would trigger an error when called on nodes already removed from
the tree. Changed to return false instead of asserting, which is the correct
behavior for nodes not in the tree.
Fixes#115376