Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flush key_input cache when Bevy loses focus (Adopted) #13678

Merged
merged 1 commit into from
Jun 5, 2024

Conversation

ramirezmike
Copy link
Contributor

This was adopted from #12878. I rebased the changes resolved the following merge conflicts:

  • moved over the changes originally done in bevy_winit/src/lib.rs's handle_winit_event into bevy_winit/src/state.rs's window_event function
  • moved WinitEvent::KeyboardFocusLost event forwarding originally done in bevy_winit/src/winit_event.rs to the equivalent in bevy_winit/src/state.rs

Tested this by following the modified keyboard_input example from the original PR.

First, I verified I could reproduce the issue without the changes. Then, after applying the changes, I verified that when I Alt+Tabbed away from the running example that the log showed I released Alt and when I tabbed back it didn't behave like Alt was stuck.

The following is from the original pull request by @gavlig

Objective

This helps avoiding stuck key presses after switching from and back to Bevy window. Key press event gets stuck because window loses focus before receiving a key release event thus we end up with false positive in ButtonInput.

Solution

I saw two ways to fix this:

 1. add bevy_window as dependency and read WindowFocus events

 2. add a KeyboardFocusLost event specifically for this.

I chose the latter because adding another dependency felt wrong, but if that is more preferable changing this pr won't be a problem. Also if someone sees another way please let me know.

To test the bug use this small modification over examples/keyboard_input.rs: (it will work only if you have Alt-Tab combination for switching between windows in your OS, otherwise change AltLeft accordingly)

//! Demonstrates handling a key press/release.

use bevy::{prelude::*, input::keyboard::KeyboardInput};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, keyboard_input_system)
        .run();
}

/// This system prints 'Alt' key state
fn keyboard_input_system(keyboard_input: Res<ButtonInput<KeyCode>>, mut keyboard_input_events: EventReader<KeyboardInput>) {
    for event in keyboard_input_events.read() {
        info!("{:?}", event);
    }

    if keyboard_input.pressed(KeyCode::AltLeft) {
        info!("'Alt' currently pressed");
    }

    if keyboard_input.just_pressed(KeyCode::AltLeft) {
        info!("'Alt' just pressed");
    }
    if keyboard_input.just_released(KeyCode::AltLeft) {
        info!("'Alt' just released");
    }
}

Here i made a quick video with demo of the fix: https://youtu.be/qTvUCk4IHvo In first part i press Alt and Alt+Tab to switch back and forth from example app, logs will indicate that too. In second part I applied fix and you'll see that Alt will no longer be pressed when window gets unfocused

Migration Guide

WinitEvent has a new enum variant: WinitEvent::KeyboardFocusLost.

This helps avoiding stuck key presses after switching from and then back to Bevy
@ramirezmike
Copy link
Contributor Author

clip-2024-06-04_21.24.36.mp4

Here's a clip of testing it. You can see it output and then stop once I alt tab and when I grab the focus again the key isn't stuck (since it was released).

@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Input Player input via keyboard, mouse, gamepad, and more A-Windowing Platform-agnostic interface layer to run your app in S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it labels Jun 5, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jun 5, 2024
@alice-i-cecile alice-i-cecile added this to the 0.14 milestone Jun 5, 2024
Merged via the queue into bevyengine:main with commit bd6acc6 Jun 5, 2024
32 checks passed
@ramirezmike ramirezmike deleted the stuck_keypress_fix branch June 5, 2024 02:23
@gavlig
Copy link
Contributor

gavlig commented Jun 5, 2024

Thanks for handling this 👍 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Input Player input via keyboard, mouse, gamepad, and more A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants