1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 14:20:04 -04:00

Fix modifiers not working in kittest (#5693)

* Closes <https://github.com/emilk/egui/issues/5690>
* [x] I have followed the instructions in the PR template

It still isn't ideal, since you have to remember to call key_up on a
separate frame.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
lucasmerlin
2025-02-10 09:33:36 +01:00
committed by GitHub
parent 81806c4b86
commit 1c6e7b1bd0
5 changed files with 104 additions and 22 deletions

View File

@@ -4,12 +4,26 @@ use kittest::{ElementState, MouseButton, SimulatedEvent};
#[derive(Default)]
pub(crate) struct EventState {
modifiers: Modifiers,
last_mouse_pos: Pos2,
}
impl EventState {
pub fn kittest_event_to_egui(&mut self, event: kittest::Event) -> Option<egui::Event> {
/// Map the kittest events to egui events, add them to the input and update the modifiers.
/// This function accesses `egui::RawInput::modifiers`. Make sure it is not reset after each
/// frame (Since we use [`egui::RawInput::take`], this should be fine).
pub fn update(&mut self, events: Vec<kittest::Event>, input: &mut egui::RawInput) {
for event in events {
if let Some(event) = self.kittest_event_to_egui(&mut input.modifiers, event) {
input.events.push(event);
}
}
}
fn kittest_event_to_egui(
&mut self,
modifiers: &mut Modifiers,
event: kittest::Event,
) -> Option<egui::Event> {
match event {
kittest::Event::ActionRequest(e) => Some(Event::AccessKitActionRequest(e)),
kittest::Event::Simulated(e) => match e {
@@ -23,7 +37,7 @@ impl EventState {
SimulatedEvent::MouseInput { state, button } => {
pointer_button_to_egui(button).map(|button| PointerButton {
button,
modifiers: self.modifiers,
modifiers: *modifiers,
pos: self.last_mouse_pos,
pressed: matches!(state, ElementState::Pressed),
})
@@ -32,22 +46,22 @@ impl EventState {
SimulatedEvent::KeyInput { state, key } => {
match key {
kittest::Key::Alt => {
self.modifiers.alt = matches!(state, ElementState::Pressed);
modifiers.alt = matches!(state, ElementState::Pressed);
}
kittest::Key::Command => {
self.modifiers.command = matches!(state, ElementState::Pressed);
modifiers.command = matches!(state, ElementState::Pressed);
}
kittest::Key::Control => {
self.modifiers.ctrl = matches!(state, ElementState::Pressed);
modifiers.ctrl = matches!(state, ElementState::Pressed);
}
kittest::Key::Shift => {
self.modifiers.shift = matches!(state, ElementState::Pressed);
modifiers.shift = matches!(state, ElementState::Pressed);
}
_ => {}
}
kittest_key_to_egui(key).map(|key| Event::Key {
key,
modifiers: self.modifiers,
modifiers: *modifiers,
pressed: matches!(state, ElementState::Pressed),
repeat: false,
physical_key: None,
@@ -58,7 +72,7 @@ impl EventState {
}
}
pub fn kittest_key_to_egui(value: kittest::Key) -> Option<egui::Key> {
fn kittest_key_to_egui(value: kittest::Key) -> Option<egui::Key> {
use egui::Key as EKey;
use kittest::Key;
match value {
@@ -170,7 +184,7 @@ pub fn kittest_key_to_egui(value: kittest::Key) -> Option<egui::Key> {
}
}
pub fn pointer_button_to_egui(value: MouseButton) -> Option<egui::PointerButton> {
fn pointer_button_to_egui(value: MouseButton) -> Option<egui::PointerButton> {
match value {
MouseButton::Left => Some(egui::PointerButton::Primary),
MouseButton::Right => Some(egui::PointerButton::Secondary),

View File

@@ -227,11 +227,8 @@ impl<'a, State> Harness<'a, State> {
}
fn _step(&mut self, sizing_pass: bool) {
for event in self.kittest.take_events() {
if let Some(event) = self.event_state.kittest_event_to_egui(event) {
self.input.events.push(event);
}
}
self.event_state
.update(self.kittest.take_events(), &mut self.input);
self.input.predicted_dt = self.step_dt;
@@ -376,12 +373,32 @@ impl<'a, State> Harness<'a, State> {
/// Press a key.
/// This will create a key down event and a key up event.
pub fn press_key(&mut self, key: egui::Key) {
self.press_key_modifiers(Modifiers::default(), key);
self.input.events.push(egui::Event::Key {
key,
pressed: true,
modifiers: self.input.modifiers,
repeat: false,
physical_key: None,
});
self.input.events.push(egui::Event::Key {
key,
pressed: false,
modifiers: self.input.modifiers,
repeat: false,
physical_key: None,
});
}
/// Press a key with modifiers.
/// This will create a key down event and a key up event.
/// This will create a key-down event, a key-up event, and update the modifiers.
///
/// NOTE: In contrast to the event fns on [`Node`], this will call [`Harness::step`], in
/// order to properly update modifiers.
pub fn press_key_modifiers(&mut self, modifiers: Modifiers, key: egui::Key) {
// Combine the modifiers with the current modifiers
let previous_modifiers = self.input.modifiers;
self.input.modifiers |= modifiers;
self.input.events.push(egui::Event::Key {
key,
pressed: true,
@@ -389,6 +406,7 @@ impl<'a, State> Harness<'a, State> {
repeat: false,
physical_key: None,
});
self.step();
self.input.events.push(egui::Event::Key {
key,
pressed: false,
@@ -396,6 +414,8 @@ impl<'a, State> Harness<'a, State> {
repeat: false,
physical_key: None,
});
self.input.modifiers = previous_modifiers;
}
/// Render the last output to an image.