egui-miniquad
egui-miniquad copied to clipboard
Key modifier state after a modifier is pressed or released
The modifier key state changes are only reaching egui
on the next key event. For example, if you press and hold Ctrl
and don't press any other key, egui
will not know about it. If you then release it, egui
will now think it is being held down, until some future key event.
As I understand it, miniquad
is passing through (from X11
) key up/down events whose modifier state does not include the effect of that event itself. Next, egui-miniquad
stores that pre-event modifier state and discards the key event since egui
doesn't care about those. It then sends that incorrect state to egui
for new frames and with events where miniquad
doesn't include the modifier state (e.g. mouse events).
Test program (using egui-miniquad v0.12.0 and miniquad v0.3.13)
use {egui_miniquad as egui_mq, miniquad as mq};
struct Stage {
egui_mq: egui_mq::EguiMq,
}
impl Stage {
pub fn new(ctx: &mut mq::Context) -> Stage {
Stage {
egui_mq: egui_mq::EguiMq::new(ctx),
}
}
}
impl mq::EventHandler for Stage {
fn update(&mut self, _ctx: &mut mq::Context) {}
fn draw(&mut self, ctx: &mut mq::Context) {
self.egui_mq.run(ctx, |mq_ctx, egui_ctx| {
egui::CentralPanel::default().show(&egui_ctx, |ui| {
ui.label(format!("{:#?}",ui.input().modifiers));
});
});
self.egui_mq.draw(ctx);
ctx.commit_frame();
}
fn mouse_motion_event(&mut self, _: &mut mq::Context, x: f32, y: f32) {
self.egui_mq.mouse_motion_event(x, y);
}
fn mouse_wheel_event(&mut self, _: &mut mq::Context, dx: f32, dy: f32) {
self.egui_mq.mouse_wheel_event(dx, dy);
}
fn mouse_button_down_event(
&mut self,
ctx: &mut mq::Context,
mb: mq::MouseButton,
x: f32,
y: f32,
) {
self.egui_mq.mouse_button_down_event(ctx, mb, x, y);
}
fn mouse_button_up_event(
&mut self,
ctx: &mut mq::Context,
mb: mq::MouseButton,
x: f32,
y: f32,
) {
self.egui_mq.mouse_button_up_event(ctx, mb, x, y);
}
fn char_event(
&mut self,
_ctx: &mut mq::Context,
character: char,
_keymods: mq::KeyMods,
_repeat: bool,
) {
self.egui_mq.char_event(character);
}
fn key_down_event(
&mut self,
ctx: &mut mq::Context,
keycode: mq::KeyCode,
keymods: mq::KeyMods,
_repeat: bool,
) {
if keycode == mq::KeyCode::Q {
std::process::exit(0);
}
println!("---KEY DOWN---");
dbg!(keycode);
dbg!(keymods);
println!("calling egui_mq.key_down_event");
self.egui_mq.key_down_event(ctx, keycode, keymods);
println!("---END---");
}
fn key_up_event(&mut self, _ctx: &mut mq::Context, keycode: mq::KeyCode, keymods: mq::KeyMods) {
println!("---KEY UP---");
dbg!(keycode);
dbg!(keymods);
println!("calling egui_mq.key_up_event");
self.egui_mq.key_up_event(keycode, keymods);
println!("---END---");
}
}
fn main() {
mq::start(Default::default(), |mut ctx| Box::new(Stage::new(&mut ctx)));
}
This similar issue in glfw
has some informative discussion: https://github.com/glfw/glfw/issues/1630
I've realized I can easily work around it by changing the keymods in my event handlers, but it's not a general solution since it doesn't properly account for keymaps and likely a bunch of other cases. It now seems that this will need changes in miniquad
instead.
Workaround
fn key_down_event(
&mut self,
ctx: &mut mq::Context,
keycode: mq::KeyCode,
mut keymods: mq::KeyMods,
_repeat: bool,
) {
match keycode {
mq::KeyCode::LeftShift | mq::KeyCode::RightShift => keymods.shift = true,
mq::KeyCode::LeftControl | mq::KeyCode::RightControl => keymods.ctrl = true,
mq::KeyCode::LeftAlt /*| mq::KeyCode::RightAlt*/ => keymods.alt = true,
mq::KeyCode::LeftSuper | mq::KeyCode::RightSuper => keymods.logo = true,
_ => (),
}
self.egui_mq.key_down_event(ctx, keycode, keymods);
}
fn key_up_event(&mut self, _ctx: &mut mq::Context, keycode: mq::KeyCode, mut keymods: mq::KeyMods) {
match keycode {
mq::KeyCode::LeftShift | mq::KeyCode::RightShift => keymods.shift = false,
mq::KeyCode::LeftControl | mq::KeyCode::RightControl => keymods.ctrl = false,
mq::KeyCode::LeftAlt /*| mq::KeyCode::RightAlt*/ => keymods.alt = false,
mq::KeyCode::LeftSuper | mq::KeyCode::RightSuper => keymods.logo = false,
_ => (),
}
self.egui_mq.key_up_event(keycode, keymods);
}
use this PR https://github.com/not-fl3/miniquad/pull/313 you can capture the key modifer, @quaternic