mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
Merge pull request #710 from dbr/modfix
Fix handling of modifier keys in winit-support
This commit is contained in:
commit
9ff2eabf29
@ -285,9 +285,10 @@ impl Renderer {
|
|||||||
#[cfg(feature = "bind_vertex_array_support")]
|
#[cfg(feature = "bind_vertex_array_support")]
|
||||||
if self.gl_version.bind_vertex_array_support() {
|
if self.gl_version.bind_vertex_array_support() {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.vertex_array_object = Some(gl
|
self.vertex_array_object = Some(
|
||||||
.create_vertex_array()
|
gl.create_vertex_array()
|
||||||
.map_err(|err| format!("Error creating vertex array object: {}", err))?);
|
.map_err(|err| format!("Error creating vertex array object: {}", err))?,
|
||||||
|
);
|
||||||
gl.bind_vertex_array(self.vertex_array_object);
|
gl.bind_vertex_array(self.vertex_array_object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,7 +573,9 @@ impl TextureMap for SimpleTextureMap {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option<glow::Texture> {
|
fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option<glow::Texture> {
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[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(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +649,10 @@ impl GlStateBackup {
|
|||||||
fn post_init(&mut self, gl: &Context) {
|
fn post_init(&mut self, gl: &Context) {
|
||||||
#[allow(clippy::cast_sign_loss)]
|
#[allow(clippy::cast_sign_loss)]
|
||||||
unsafe {
|
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),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,7 +711,10 @@ impl GlStateBackup {
|
|||||||
#![allow(clippy::cast_sign_loss)]
|
#![allow(clippy::cast_sign_loss)]
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.use_program(to_native_gl(self.program, glow::NativeProgram));
|
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")]
|
#[cfg(feature = "bind_sampler_support")]
|
||||||
if let Some(sampler) = self.sampler {
|
if let Some(sampler) = self.sampler {
|
||||||
gl.bind_sampler(0, to_native_gl(sampler, glow::NativeSampler));
|
gl.bind_sampler(0, to_native_gl(sampler, glow::NativeSampler));
|
||||||
@ -715,7 +724,10 @@ impl GlStateBackup {
|
|||||||
if let Some(vao) = self.vertex_array_object {
|
if let Some(vao) = self.vertex_array_object {
|
||||||
gl.bind_vertex_array(to_native_gl(vao, glow::NativeVertexArray));
|
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(
|
gl.blend_equation_separate(
|
||||||
self.blend_equation_rgb as _,
|
self.blend_equation_rgb as _,
|
||||||
self.blend_equation_alpha as _,
|
self.blend_equation_alpha as _,
|
||||||
|
|||||||
@ -305,10 +305,19 @@ impl GlStateBackup {
|
|||||||
|
|
||||||
context.bind_vertex_array(to_native_gl(self.vao, glow::NativeVertexArray));
|
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(
|
||||||
context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, to_native_gl(self.ibo, glow::NativeBuffer));
|
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.active_texture(self.active_texture);
|
||||||
|
|
||||||
context.use_program(to_native_gl(self.program, glow::NativeProgram));
|
context.use_program(to_native_gl(self.program, glow::NativeProgram));
|
||||||
@ -488,13 +497,24 @@ impl Renderer {
|
|||||||
input:
|
input:
|
||||||
KeyboardInput {
|
KeyboardInput {
|
||||||
virtual_keycode: Some(key),
|
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) {
|
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) => {
|
winit::event::WindowEvent::ModifiersChanged(modifiers) => {
|
||||||
@ -891,6 +911,18 @@ struct PlatformBackend {
|
|||||||
event_queue: Rc<RefCell<VecDeque<ViewportEvent>>>,
|
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 {
|
impl imgui::PlatformViewportBackend for PlatformBackend {
|
||||||
fn create_window(&mut self, viewport: &mut imgui::Viewport) {
|
fn create_window(&mut self, viewport: &mut imgui::Viewport) {
|
||||||
viewport.platform_user_data = Box::into_raw(Box::new(ViewportData {
|
viewport.platform_user_data = Box::into_raw(Box::new(ViewportData {
|
||||||
|
|||||||
@ -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 {
|
impl WinitPlatform {
|
||||||
/// Initializes a winit platform instance and configures imgui.
|
/// Initializes a winit platform instance and configures imgui.
|
||||||
///
|
///
|
||||||
@ -395,16 +407,6 @@ impl WinitPlatform {
|
|||||||
window_id,
|
window_id,
|
||||||
ref event,
|
ref event,
|
||||||
} if window_id == window.id() => {
|
} 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);
|
self.handle_window_event(io, window, event);
|
||||||
}
|
}
|
||||||
// Track key release events outside our window. If we don't do this,
|
// Track key release events outside our window. If we don't do this,
|
||||||
@ -453,6 +455,15 @@ impl WinitPlatform {
|
|||||||
let logical_size = self.scale_size_from_winit(window, logical_size);
|
let logical_size = self.scale_size_from_winit(window, logical_size);
|
||||||
io.display_size = [logical_size.width as f32, logical_size.height as f32];
|
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 {
|
WindowEvent::KeyboardInput {
|
||||||
input:
|
input:
|
||||||
KeyboardInput {
|
KeyboardInput {
|
||||||
@ -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) {
|
if let Some(key) = to_imgui_key(key) {
|
||||||
let pressed = state == ElementState::Pressed;
|
|
||||||
io.add_key_event(key, pressed);
|
io.add_key_event(key, pressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user