pub struct PointerFocusPlugin;bevy_picking only.Expand description
Plugin which focuses (or blurs) entities in response to pointer clicks.
On a pointer press this hides the focus indicator (InputFocusVisible) and triggers a
bubbling AcquireFocus on the clicked entity. That request is then resolved by the focus
observers this plugin installs:
acquire_focus_tab_indexfocuses the target if it carries aTabIndex, stopping the request, or- the generalized
on_window_acquire_focus_clearobserver (installed byInputFocusPlugin) clears focus once the request bubbles up to the window (this is “click outside to unfocus”).
Registering acquire_focus_tab_index here is a temporary bridge: it lets pointer clicks
actually acquire focus on focusable targets even when TabNavigationPlugin is not installed
(previously that observer only existed inside TabNavigationPlugin, so clicking back into a
focusable element without tab navigation could only ever clear focus, never grant it). This
re-uses the TabIndex infrastructure until a dedicated,
navigation-agnostic pointer-focus target component (a PointerFocusable analog to TabIndex)
is designed in a future PR. See https://github.com/bevyengine/bevy/pull/24757.
It is safe to register acquire_focus_tab_index here even when TabNavigationPlugin also
registers it: App::add_observer does not deduplicate, so the observer runs twice per request,
but it is idempotent — it stops propagation and only mutates InputFocus
when the focus target actually changes, so the second run is a no-op.
Because that AcquireFocus event is shared across widgets and focus
schemes, be deliberate when changing anything in this pathway — a change here can have
engine-wide focus consequences. Individual widgets may also intercept the event and stop its
propagation to implement custom behavior (e.g. the number-input scrubber focuses on pointer
release rather than press). See the docs on on_window_acquire_focus_clear and
acquire_focus_tab_index.
This is intentionally independent of any navigation scheme: it works with tab navigation,
directional navigation, or on its own (e.g. an app with only text input). This whole module is
gated behind the bevy_picking feature.
Trait Implementations§
Source§impl Plugin for PointerFocusPlugin
impl Plugin for PointerFocusPlugin
Source§fn ready(&self, _app: &App) -> bool
fn ready(&self, _app: &App) -> bool
finish should be called.Source§fn finish(&self, _app: &mut App)
fn finish(&self, _app: &mut App)
App, once all plugins registered are ready. This can
be useful for plugins that depends on another plugin asynchronous setup, like the renderer.Source§fn cleanup(&self, _app: &mut App)
fn cleanup(&self, _app: &mut App)
Auto Trait Implementations§
impl Freeze for PointerFocusPlugin
impl RefUnwindSafe for PointerFocusPlugin
impl Send for PointerFocusPlugin
impl Sync for PointerFocusPlugin
impl Unpin for PointerFocusPlugin
impl UnsafeUnpin for PointerFocusPlugin
impl UnwindSafe for PointerFocusPlugin
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ConditionalSend for Twhere
T: Send,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more