Skip to content

Commit

Permalink
Merge pull request imgui-rs#710 from dbr/modfix
Browse files Browse the repository at this point in the history
Fix handling of modifier keys in winit-support
  • Loading branch information
dbr authored Mar 3, 2023
2 parents 52820db + b495728 commit 9ff2eab
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 23 deletions.
26 changes: 19 additions & 7 deletions imgui-glow-renderer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,10 @@ impl Renderer {
#[cfg(feature = "bind_vertex_array_support")]
if self.gl_version.bind_vertex_array_support() {
unsafe {
self.vertex_array_object = Some(gl
.create_vertex_array()
.map_err(|err| format!("Error creating vertex array object: {}", err))?);
self.vertex_array_object = Some(
gl.create_vertex_array()
.map_err(|err| format!("Error creating vertex array object: {}", err))?,
);
gl.bind_vertex_array(self.vertex_array_object);
}
}
Expand Down Expand Up @@ -572,7 +573,9 @@ impl TextureMap for SimpleTextureMap {
#[inline(always)]
fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option<glow::Texture> {
#[allow(clippy::cast_possible_truncation)]
Some(glow::NativeTexture(NonZeroU32::new(imgui_texture.id() as _).unwrap()))
Some(glow::NativeTexture(
NonZeroU32::new(imgui_texture.id() as _).unwrap(),
))
}
}

Expand Down Expand Up @@ -646,7 +649,10 @@ impl GlStateBackup {
fn post_init(&mut self, gl: &Context) {
#[allow(clippy::cast_sign_loss)]
unsafe {
gl.bind_texture(glow::TEXTURE_2D, to_native_gl(self.texture, glow::NativeTexture));
gl.bind_texture(
glow::TEXTURE_2D,
to_native_gl(self.texture, glow::NativeTexture),
);
}
}

Expand Down Expand Up @@ -705,7 +711,10 @@ impl GlStateBackup {
#![allow(clippy::cast_sign_loss)]
unsafe {
gl.use_program(to_native_gl(self.program, glow::NativeProgram));
gl.bind_texture(glow::TEXTURE_2D, to_native_gl(self.texture, glow::NativeTexture));
gl.bind_texture(
glow::TEXTURE_2D,
to_native_gl(self.texture, glow::NativeTexture),
);
#[cfg(feature = "bind_sampler_support")]
if let Some(sampler) = self.sampler {
gl.bind_sampler(0, to_native_gl(sampler, glow::NativeSampler));
Expand All @@ -715,7 +724,10 @@ impl GlStateBackup {
if let Some(vao) = self.vertex_array_object {
gl.bind_vertex_array(to_native_gl(vao, glow::NativeVertexArray));
}
gl.bind_buffer(glow::ARRAY_BUFFER, to_native_gl(self.array_buffer, glow::NativeBuffer));
gl.bind_buffer(
glow::ARRAY_BUFFER,
to_native_gl(self.array_buffer, glow::NativeBuffer),
);
gl.blend_equation_separate(
self.blend_equation_rgb as _,
self.blend_equation_alpha as _,
Expand Down
42 changes: 37 additions & 5 deletions imgui-winit-glow-renderer-viewports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,19 @@ impl GlStateBackup {

context.bind_vertex_array(to_native_gl(self.vao, glow::NativeVertexArray));

context.bind_buffer(glow::ARRAY_BUFFER, to_native_gl(self.vbo, glow::NativeBuffer));
context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, to_native_gl(self.ibo, glow::NativeBuffer));
context.bind_buffer(
glow::ARRAY_BUFFER,
to_native_gl(self.vbo, glow::NativeBuffer),
);
context.bind_buffer(
glow::ELEMENT_ARRAY_BUFFER,
to_native_gl(self.ibo, glow::NativeBuffer),
);

context.bind_texture(glow::TEXTURE_2D, to_native_gl(self.texture, glow::NativeTexture));
context.bind_texture(
glow::TEXTURE_2D,
to_native_gl(self.texture, glow::NativeTexture),
);
context.active_texture(self.active_texture);

context.use_program(to_native_gl(self.program, glow::NativeProgram));
Expand Down Expand Up @@ -488,13 +497,24 @@ impl Renderer {
input:
KeyboardInput {
virtual_keycode: Some(key),
state: ElementState::Pressed,
state,
..
},
..
} => {
let pressed = state == ElementState::Pressed;

// We map both left and right ctrl to `ModCtrl`, etc.
// imgui is told both "left control is pressed" and
// "consider the control key is pressed". Allows
// applications to use either general "ctrl" or a
// specific key. Same applies to other modifiers.
// https://github.com/ocornut/imgui/issues/5047
handle_key_modifier(imgui.io_mut(), key, pressed);

// Add main key event
if let Some(key) = to_imgui_key(key) {
imgui.io_mut().add_key_event(key, true);
imgui.io_mut().add_key_event(key, pressed);
}
}
winit::event::WindowEvent::ModifiersChanged(modifiers) => {
Expand Down Expand Up @@ -891,6 +911,18 @@ struct PlatformBackend {
event_queue: Rc<RefCell<VecDeque<ViewportEvent>>>,
}

fn handle_key_modifier(io: &mut imgui::Io, key: VirtualKeyCode, down: bool) {
if key == VirtualKeyCode::LShift || key == VirtualKeyCode::RShift {
io.add_key_event(imgui::Key::ModShift, down);
} else if key == VirtualKeyCode::LControl || key == VirtualKeyCode::RControl {
io.add_key_event(imgui::Key::ModCtrl, down);
} else if key == VirtualKeyCode::LAlt || key == VirtualKeyCode::RAlt {
io.add_key_event(imgui::Key::ModAlt, down);
} else if key == VirtualKeyCode::LWin || key == VirtualKeyCode::RWin {
io.add_key_event(imgui::Key::ModSuper, down);
}
}

impl imgui::PlatformViewportBackend for PlatformBackend {
fn create_window(&mut self, viewport: &mut imgui::Viewport) {
viewport.platform_user_data = Box::into_raw(Box::new(ViewportData {
Expand Down
43 changes: 32 additions & 11 deletions imgui-winit-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,18 @@ fn to_imgui_key(keycode: VirtualKeyCode) -> Option<Key> {
}
}

fn handle_key_modifier(io: &mut Io, key: VirtualKeyCode, down: bool) {
if key == VirtualKeyCode::LShift || key == VirtualKeyCode::RShift {
io.add_key_event(imgui::Key::ModShift, down);
} else if key == VirtualKeyCode::LControl || key == VirtualKeyCode::RControl {
io.add_key_event(imgui::Key::ModCtrl, down);
} else if key == VirtualKeyCode::LAlt || key == VirtualKeyCode::RAlt {
io.add_key_event(imgui::Key::ModAlt, down);
} else if key == VirtualKeyCode::LWin || key == VirtualKeyCode::RWin {
io.add_key_event(imgui::Key::ModSuper, down);
}
}

impl WinitPlatform {
/// Initializes a winit platform instance and configures imgui.
///
Expand Down Expand Up @@ -395,16 +407,6 @@ impl WinitPlatform {
window_id,
ref event,
} if window_id == window.id() => {
// We need to track modifiers separately because some system like macOS, will
// not reliably send modifier states during certain events like ScreenCapture.
// Gotta let the people show off their pretty imgui widgets!
if let WindowEvent::ModifiersChanged(modifiers) = event {
io.add_key_event(Key::ModShift, modifiers.shift());
io.add_key_event(Key::ModCtrl, modifiers.ctrl());
io.add_key_event(Key::ModAlt, modifiers.alt());
io.add_key_event(Key::ModSuper, modifiers.logo());
}

self.handle_window_event(io, window, event);
}
// Track key release events outside our window. If we don't do this,
Expand Down Expand Up @@ -453,6 +455,15 @@ impl WinitPlatform {
let logical_size = self.scale_size_from_winit(window, logical_size);
io.display_size = [logical_size.width as f32, logical_size.height as f32];
}
WindowEvent::ModifiersChanged(modifiers) => {
// We need to track modifiers separately because some system like macOS, will
// not reliably send modifier states during certain events like ScreenCapture.
// Gotta let the people show off their pretty imgui widgets!
io.add_key_event(Key::ModShift, modifiers.shift());
io.add_key_event(Key::ModCtrl, modifiers.ctrl());
io.add_key_event(Key::ModAlt, modifiers.alt());
io.add_key_event(Key::ModSuper, modifiers.logo());
}
WindowEvent::KeyboardInput {
input:
KeyboardInput {
Expand All @@ -462,8 +473,18 @@ impl WinitPlatform {
},
..
} => {
let pressed = state == ElementState::Pressed;

// We map both left and right ctrl to `ModCtrl`, etc.
// imgui is told both "left control is pressed" and
// "consider the control key is pressed". Allows
// applications to use either general "ctrl" or a
// specific key. Same applies to other modifiers.
// https://github.com/ocornut/imgui/issues/5047
handle_key_modifier(io, key, pressed);

// Add main key event
if let Some(key) = to_imgui_key(key) {
let pressed = state == ElementState::Pressed;
io.add_key_event(key, pressed);
}
}
Expand Down

0 comments on commit 9ff2eab

Please sign in to comment.