bevyengine / bevyengine/bevy

Interaction state not resetting after switching window modes

Open
#17,944 1 comment 0 reactions 0 assignees View on GitHub
A-Picking A-UI A-Windowing C-Bug S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

0.15.2

## Relevant system information

macOS 15.2 (24C101)

## What you did

```rust
use bevy::{
prelude::*,
window::{PrimaryWindow, WindowMode},
};

fn main() -> AppExit {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, trigger_on_press)
.run()
}

fn setup(mut commands: Commands) {
commands.spawn(Camera2d);

commands
.spawn(Button)
.with_child(Text::new("Toggle Window Mode"))
.observe(toggle_window_mode);
}

fn toggle_window_mode(
_trigger: Trigger,
mut window_query: Query<&mut Window, With>,
) {
let mut window = window_query.single_mut();

window.mode = match window.mode {
WindowMode::Windowed => WindowMode::BorderlessFullscreen(MonitorSelection::Primary),
_ => WindowMode::Windowed,
};
}

fn trigger_on_press(
interaction_query: Query<(Entity, &Interaction), Changed>,
mut commands: Commands,
) {
for (entity, interaction) in &interaction_query {
if matches!(interaction, Interaction::Pressed) {
commands.trigger_targets(OnPress, entity);
}
}
}

#[derive(Event)]
struct OnPress;
```

## What went wrong

Interactions temporarily "break" when switching between windowed mode and fullscreen mode.

1. Press and release the button. The window switches to fullscreen mode.
2. Press and release the button. Nothing happens.
3. Press and release the button. The window switches to windowed mode.
4. Press and release the button. Nothing happens.
5. Repeat.

As a "workaround":

1. Press and hold the button. The window switches to fullscreen mode. Release the button.
2. Press and hold the button. The window switches to windowed mode. Release the button.
3. Repeat.

## Additional information

I checked for related issues and I could not find anything related to this problem. The `Interaction` component does not change from `Interaction::Pressed` to `Interaction::None` until the window is interacted with after switching modes. I believe the following is the relevant source code.

`crates/bevy_ui/src/focus.rs`:
```rust
let mut iter = node_query.iter_many_mut(hovered_nodes.by_ref());
while let Some(node) = iter.fetch_next() {
if let Some(mut interaction) = node.interaction {
if mouse_clicked {
// only consider nodes with Interaction "pressed"
if *interaction != Interaction::Pressed {
*interaction = Interaction::Pressed;
// if the mouse was simultaneously released, reset this Interaction in the next
// frame
if mouse_released {
state.entities_to_reset.push(node.entity);
}
}
} else if *interaction == Interaction::None {
*interaction = Interaction::Hovered;
}
}

match node.focus_policy.unwrap_or(&FocusPolicy::Block) {
FocusPolicy::Block => {
break;
}
FocusPolicy::Pass => { /* allow the next node to be hovered/pressed */ }
}
}
```

Since the `Interaction` component is stuck on `Interaction::Pressed` after switching modes neither branch is reached.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.