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

Ignore key-repeat events #2334

Merged
merged 5 commits into from
Nov 30, 2022
Merged

Ignore key-repeat events #2334

merged 5 commits into from
Nov 30, 2022

Conversation

palako
Copy link
Contributor

@palako palako commented Nov 22, 2022

A key can be pressed or not pressed. This is the status of the key, not an event. The InputState::keys_down attribute contains a collection of any key being held down at any given frame. InputState::key_down(Key) returns true if a key is being held down. So far so good.

A key being pressed or released is an event, i.e. the change from being pressed to not being pressed, or from not being pressed to being pressed. While InputState::key_released(Key) returns true correctly only when the key was released on a given frame, InputState::key_pressed(Key) doesn't behave that way, and instead returns true as long as the key is held down.

Besides not allowing this method to be used to detect the actual key press, another unintended consequence is that on the frame where the key is released, sometimes both events will be there, and thus both key_pressed and key_released will return true.

The example in the second commit of this PR helps seeing this. Before applying the patch to InputState, press and hold the letter A, then release. First you'll see that during the key being pressed, not only you get true from key_down() but also from key_press(). Also if you try to do this a few times, you will see that sometimes the message "pressed" is printed AFTER the message "released" (note there's no release messages in the following screenshot, they key is being held down)

Screenshot 2022-11-22 at 15 20 13

The root of the problem is the difference in meaning between pressed/released events in egui/eframe and egui-winit. For egui-winit, keyboard events mean something different, as implemented on State::on_keyboard_input. Keys pressed are added as Event::Key with pressed true (and this applies while the key is held down).

The patch on the first commit is very simple, and it just removes from the raw input events the key press if this key was already in the set of keys pressed from the previous frame. It of course leaves the keys_pressed set unaltered, so that the key can still be queried for being held down (there are only "held" messages in between a "pressed" and a "released" message in the following screenshot)

Screenshot 2022-11-22 at 15 13 43

The API to the user doesn't change, but with this fix key_pressed will change behaviour. If someone was using key_pressed to detect if a key was being held down, this will stop working. The fix would be trivial though, just changing the API call from key_pressed() to key_down(); the parameters are all the same.

@palako palako changed the title Fix keypress event Fix key pressed event Nov 22, 2022
Copy link
Owner

@emilk emilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to push an improvement to this PR but failed - perhaps you can git cherrypick it?

a646c12

crates/egui/src/input_state.rs Outdated Show resolved Hide resolved
@palako
Copy link
Contributor Author

palako commented Nov 30, 2022

I've pushed a commit with all the requested improvements.
Not sure what the formatting problem was. When I tried to cargo format as you explain in the doc, I got cargo suggesting hundreds of format changes all over the place in files I was not touching, so I thought better to leave it alone. Let me know if you want me to adjust something.
Cheers!

CHANGELOG.md Outdated Show resolved Hide resolved
@emilk emilk merged commit 85f8eeb into emilk:master Nov 30, 2022
@emilk
Copy link
Owner

emilk commented Nov 30, 2022

Thanks!

@palako palako deleted the fix_keypress_event branch November 30, 2022 22:44
emilk added a commit that referenced this pull request Dec 2, 2022
* Fix key press event

* Add example with key presses

* Changelog line for key_press fix

* PR review improvements

* Add PR link in changelog

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
@emilk emilk changed the title Fix key pressed event Ignore key-repeat events Dec 5, 2022
JohannesProgrammiert pushed a commit to JohannesProgrammiert/egui that referenced this pull request Jan 21, 2023
* Fix key press event

* Add example with key presses

* Changelog line for key_press fix

* PR review improvements

* Add PR link in changelog

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants