mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-12 05:31:31 +11:00
Merge pull request #112 from rigtorp/keyboard-mods
Add keyboard modifiers to input event
This commit is contained in:
commit
4c6e4e827a
|
@ -13,7 +13,7 @@ fn main() {
|
||||||
|
|
||||||
events_loop.run_forever(|event| {
|
events_loop.run_forever(|event| {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event: WindowEvent::KeyboardInput(ElementState::Pressed, _, _), .. } => {
|
Event::WindowEvent { event: WindowEvent::KeyboardInput(ElementState::Pressed, _, _, _), .. } => {
|
||||||
println!("Setting cursor to \"{:?}\"", cursors[cursor_idx]);
|
println!("Setting cursor to \"{:?}\"", cursors[cursor_idx]);
|
||||||
window.set_cursor(cursors[cursor_idx]);
|
window.set_cursor(cursors[cursor_idx]);
|
||||||
if cursor_idx < cursors.len() - 1 {
|
if cursor_idx < cursors.len() - 1 {
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn main() {
|
||||||
winit::Event::WindowEvent { event, .. } => {
|
winit::Event::WindowEvent { event, .. } => {
|
||||||
match event {
|
match event {
|
||||||
winit::WindowEvent::Closed => events_loop.interrupt(),
|
winit::WindowEvent::Closed => events_loop.interrupt(),
|
||||||
winit::WindowEvent::KeyboardInput(_, _, Some(winit::VirtualKeyCode::Escape)) => events_loop.interrupt(),
|
winit::WindowEvent::KeyboardInput(_, _, Some(winit::VirtualKeyCode::Escape), _) => events_loop.interrupt(),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,7 @@ fn main() {
|
||||||
match event {
|
match event {
|
||||||
winit::Event::WindowEvent { event, .. } => {
|
winit::Event::WindowEvent { event, .. } => {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::KeyboardInput(ElementState::Pressed, _, _) => {
|
WindowEvent::KeyboardInput(ElementState::Pressed, _, _, _) => {
|
||||||
if grabbed {
|
if grabbed {
|
||||||
grabbed = false;
|
grabbed = false;
|
||||||
window.set_cursor_state(winit::CursorState::Normal)
|
window.set_cursor_state(winit::CursorState::Normal)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase};
|
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase};
|
||||||
|
|
||||||
|
use events::ModifiersState;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
@ -627,10 +629,12 @@ impl wl_keyboard::Handler for WaylandEnv {
|
||||||
wl_keyboard::KeyState::Released => ElementState::Released,
|
wl_keyboard::KeyState::Released => ElementState::Released,
|
||||||
};
|
};
|
||||||
let mut guard = eviter.lock().unwrap();
|
let mut guard = eviter.lock().unwrap();
|
||||||
|
// TODO implement ModifiersState
|
||||||
guard.push_back(Event::KeyboardInput(
|
guard.push_back(Event::KeyboardInput(
|
||||||
state,
|
state,
|
||||||
key as u8,
|
key as u8,
|
||||||
None
|
None,
|
||||||
|
ModifiersState::default()
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
KbdType::Plain(None) => ()
|
KbdType::Plain(None) => ()
|
||||||
|
|
|
@ -3,6 +3,8 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use {VirtualKeyCode, ElementState, WindowEvent as Event};
|
use {VirtualKeyCode, ElementState, WindowEvent as Event};
|
||||||
|
|
||||||
|
use events::ModifiersState;
|
||||||
|
|
||||||
use super::wayland_kbd;
|
use super::wayland_kbd;
|
||||||
use wayland_client::EventQueueHandle;
|
use wayland_client::EventQueueHandle;
|
||||||
use wayland_client::protocol::wl_keyboard;
|
use wayland_client::protocol::wl_keyboard;
|
||||||
|
@ -35,7 +37,8 @@ impl wayland_kbd::Handler for KbdHandler {
|
||||||
};
|
};
|
||||||
let vkcode = key_to_vkey(rawkey, keysym);
|
let vkcode = key_to_vkey(rawkey, keysym);
|
||||||
let mut guard = eviter.lock().unwrap();
|
let mut guard = eviter.lock().unwrap();
|
||||||
guard.push_back(Event::KeyboardInput(state, rawkey as u8, vkcode));
|
// TODO implement ModifiersState
|
||||||
|
guard.push_back(Event::KeyboardInput(state, rawkey as u8, vkcode, ModifiersState::default()));
|
||||||
// send char event only on key press, not release
|
// send char event only on key press, not release
|
||||||
if let ElementState::Released = state { return }
|
if let ElementState::Released = state { return }
|
||||||
if let Some(txt) = utf8 {
|
if let Some(txt) = utf8 {
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::slice::from_raw_parts;
|
||||||
use WindowAttributes;
|
use WindowAttributes;
|
||||||
|
|
||||||
use events::WindowEvent as Event;
|
use events::WindowEvent as Event;
|
||||||
|
use events::ModifiersState;
|
||||||
|
|
||||||
use super::{events, ffi};
|
use super::{events, ffi};
|
||||||
use super::XConnection;
|
use super::XConnection;
|
||||||
|
@ -139,6 +140,8 @@ impl XInputEventHandler {
|
||||||
|
|
||||||
let mut kp_keysym = 0;
|
let mut kp_keysym = 0;
|
||||||
|
|
||||||
|
let mut ev_mods = ModifiersState::default();
|
||||||
|
|
||||||
let written = unsafe {
|
let written = unsafe {
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
|
@ -148,6 +151,26 @@ impl XInputEventHandler {
|
||||||
mem::transmute(buffer.as_mut_ptr()),
|
mem::transmute(buffer.as_mut_ptr()),
|
||||||
buffer.len() as libc::c_int, &mut kp_keysym, ptr::null_mut());
|
buffer.len() as libc::c_int, &mut kp_keysym, ptr::null_mut());
|
||||||
|
|
||||||
|
{
|
||||||
|
// Translate x event state to mods
|
||||||
|
let state = event.state;
|
||||||
|
if (state & ffi::Mod1Mask) != 0 {
|
||||||
|
ev_mods.alt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state & ffi::ShiftMask) != 0 {
|
||||||
|
ev_mods.shift = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state & ffi::ControlMask) != 0 {
|
||||||
|
ev_mods.ctrl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state & ffi::Mod4Mask) != 0 {
|
||||||
|
ev_mods.logo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
str::from_utf8(&buffer[..count as usize]).unwrap_or("").to_string()
|
str::from_utf8(&buffer[..count as usize]).unwrap_or("").to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,7 +188,7 @@ impl XInputEventHandler {
|
||||||
|
|
||||||
let vkey = events::keycode_to_element(keysym as libc::c_uint);
|
let vkey = events::keycode_to_element(keysym as libc::c_uint);
|
||||||
|
|
||||||
translated_events.push(KeyboardInput(state, event.keycode as u8, vkey));
|
translated_events.push(KeyboardInput(state, event.keycode as u8, vkey, ev_mods));
|
||||||
translated_events
|
translated_events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub enum WindowEvent {
|
||||||
Focused(bool),
|
Focused(bool),
|
||||||
|
|
||||||
/// An event from the keyboard has been received.
|
/// An event from the keyboard has been received.
|
||||||
KeyboardInput(ElementState, ScanCode, Option<VirtualKeyCode>),
|
KeyboardInput(ElementState, ScanCode, Option<VirtualKeyCode>, ModifiersState),
|
||||||
|
|
||||||
/// The cursor has moved on the window.
|
/// The cursor has moved on the window.
|
||||||
///
|
///
|
||||||
|
@ -320,3 +320,20 @@ pub enum VirtualKeyCode {
|
||||||
WebStop,
|
WebStop,
|
||||||
Yen,
|
Yen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the current state of the keyboard modifiers
|
||||||
|
///
|
||||||
|
/// Each field of this struct represents a modifier and is `true` if this modifier is active.
|
||||||
|
#[derive(Default, Debug, Clone, Copy)]
|
||||||
|
pub struct ModifiersState {
|
||||||
|
/// The "shift" key
|
||||||
|
pub shift: bool,
|
||||||
|
/// The "control" key
|
||||||
|
pub ctrl: bool,
|
||||||
|
/// The "alt" key
|
||||||
|
pub alt: bool,
|
||||||
|
/// The "logo" key
|
||||||
|
///
|
||||||
|
/// This is the "windows" key on PC and "command" key on Mac.
|
||||||
|
pub logo: bool
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use cocoa::{self, appkit, foundation};
|
use cocoa::{self, appkit, foundation};
|
||||||
use cocoa::appkit::{NSApplication, NSEvent, NSView, NSWindow};
|
use cocoa::appkit::{NSApplication, NSEvent, NSView, NSWindow};
|
||||||
use events::{self, ElementState, Event, MouseButton, TouchPhase, WindowEvent};
|
use events::{self, ElementState, Event, MouseButton, TouchPhase, WindowEvent, ModifiersState};
|
||||||
use super::window::Window;
|
use super::window::Window;
|
||||||
use std;
|
use std;
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ impl EventsLoop {
|
||||||
let vkey = to_virtual_key_code(NSEvent::keyCode(ns_event));
|
let vkey = to_virtual_key_code(NSEvent::keyCode(ns_event));
|
||||||
let state = ElementState::Pressed;
|
let state = ElementState::Pressed;
|
||||||
let code = NSEvent::keyCode(ns_event) as u8;
|
let code = NSEvent::keyCode(ns_event) as u8;
|
||||||
let window_event = WindowEvent::KeyboardInput(state, code, vkey);
|
let window_event = WindowEvent::KeyboardInput(state, code, vkey, event_mods(ns_event));
|
||||||
events.push_back(into_event(window_event));
|
events.push_back(into_event(window_event));
|
||||||
let event = events.pop_front();
|
let event = events.pop_front();
|
||||||
self.pending_events.lock().unwrap().extend(events.into_iter());
|
self.pending_events.lock().unwrap().extend(events.into_iter());
|
||||||
|
@ -283,7 +283,7 @@ impl EventsLoop {
|
||||||
|
|
||||||
let state = ElementState::Released;
|
let state = ElementState::Released;
|
||||||
let code = NSEvent::keyCode(ns_event) as u8;
|
let code = NSEvent::keyCode(ns_event) as u8;
|
||||||
let window_event = WindowEvent::KeyboardInput(state, code, vkey);
|
let window_event = WindowEvent::KeyboardInput(state, code, vkey, event_mods(ns_event));
|
||||||
Some(into_event(window_event))
|
Some(into_event(window_event))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -298,13 +298,13 @@ impl EventsLoop {
|
||||||
if !key_pressed && NSEvent::modifierFlags(event).contains(keymask) {
|
if !key_pressed && NSEvent::modifierFlags(event).contains(keymask) {
|
||||||
let state = ElementState::Pressed;
|
let state = ElementState::Pressed;
|
||||||
let code = NSEvent::keyCode(event) as u8;
|
let code = NSEvent::keyCode(event) as u8;
|
||||||
let window_event = WindowEvent::KeyboardInput(state, code, Some(key));
|
let window_event = WindowEvent::KeyboardInput(state, code, Some(key), event_mods(event));
|
||||||
Some(window_event)
|
Some(window_event)
|
||||||
|
|
||||||
} else if key_pressed && !NSEvent::modifierFlags(event).contains(keymask) {
|
} else if key_pressed && !NSEvent::modifierFlags(event).contains(keymask) {
|
||||||
let state = ElementState::Released;
|
let state = ElementState::Released;
|
||||||
let code = NSEvent::keyCode(event) as u8;
|
let code = NSEvent::keyCode(event) as u8;
|
||||||
let window_event = WindowEvent::KeyboardInput(state, code, Some(key));
|
let window_event = WindowEvent::KeyboardInput(state, code, Some(key), event_mods(event));
|
||||||
Some(window_event)
|
Some(window_event)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -575,3 +575,15 @@ fn to_virtual_key_code(code: u16) -> Option<events::VirtualKeyCode> {
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn event_mods(event: cocoa::base::id) -> ModifiersState {
|
||||||
|
let flags = unsafe {
|
||||||
|
NSEvent::modifierFlags(event)
|
||||||
|
};
|
||||||
|
ModifiersState {
|
||||||
|
shift: flags.contains(appkit::NSShiftKeyMask),
|
||||||
|
ctrl: flags.contains(appkit::NSControlKeyMask),
|
||||||
|
alt: flags.contains(appkit::NSAlternateKeyMask),
|
||||||
|
logo: flags.contains(appkit::NSCommandKeyMask),
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ use std::os::windows::ffi::OsStringExt;
|
||||||
|
|
||||||
use CursorState;
|
use CursorState;
|
||||||
use WindowEvent as Event;
|
use WindowEvent as Event;
|
||||||
|
use events::ModifiersState;
|
||||||
use super::event;
|
use super::event;
|
||||||
use super::WindowState;
|
use super::WindowState;
|
||||||
|
|
||||||
|
@ -200,7 +201,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
|
||||||
user32::DefWindowProcW(window, msg, wparam, lparam)
|
user32::DefWindowProcW(window, msg, wparam, lparam)
|
||||||
} else {
|
} else {
|
||||||
let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam);
|
let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam);
|
||||||
send_event(window, KeyboardInput(Pressed, scancode, vkey));
|
send_event(window, KeyboardInput(Pressed, scancode, vkey, event::get_key_mods()));
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -209,7 +210,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
|
||||||
use events::WindowEvent::KeyboardInput;
|
use events::WindowEvent::KeyboardInput;
|
||||||
use events::ElementState::Released;
|
use events::ElementState::Released;
|
||||||
let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam);
|
let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam);
|
||||||
send_event(window, KeyboardInput(Released, scancode, vkey));
|
send_event(window, KeyboardInput(Released, scancode, vkey, event::get_key_mods()));
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,30 @@
|
||||||
use events::VirtualKeyCode;
|
use events::VirtualKeyCode;
|
||||||
|
use events::ModifiersState;
|
||||||
use winapi;
|
use winapi;
|
||||||
use user32;
|
use user32;
|
||||||
use ScanCode;
|
use ScanCode;
|
||||||
|
|
||||||
const MAPVK_VSC_TO_VK_EX: u32 = 3;
|
const MAPVK_VSC_TO_VK_EX: u32 = 3;
|
||||||
|
|
||||||
|
pub fn get_key_mods() -> ModifiersState {
|
||||||
|
let mut mods = ModifiersState::default();
|
||||||
|
unsafe {
|
||||||
|
if user32::GetKeyState(winapi::VK_SHIFT) & (1 << 15) == (1 << 15) {
|
||||||
|
mods.shift = true;
|
||||||
|
}
|
||||||
|
if user32::GetKeyState(winapi::VK_CONTROL) & (1 << 15) == (1 << 15) {
|
||||||
|
mods.ctrl = true;
|
||||||
|
}
|
||||||
|
if user32::GetKeyState(winapi::VK_MENU) & (1 << 15) == (1 << 15) {
|
||||||
|
mods.alt = true;
|
||||||
|
}
|
||||||
|
if (user32::GetKeyState(winapi::VK_LWIN) | user32::GetKeyState(winapi::VK_RWIN)) & (1 << 15) == (1 << 15) {
|
||||||
|
mods.logo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mods
|
||||||
|
}
|
||||||
|
|
||||||
pub fn vkeycode_to_element(wparam: winapi::WPARAM, lparam: winapi::LPARAM) -> (ScanCode, Option<VirtualKeyCode>) {
|
pub fn vkeycode_to_element(wparam: winapi::WPARAM, lparam: winapi::LPARAM) -> (ScanCode, Option<VirtualKeyCode>) {
|
||||||
let scancode = ((lparam >> 16) & 0xff) as u8;
|
let scancode = ((lparam >> 16) & 0xff) as u8;
|
||||||
let extended = (lparam & 0x01000000) != 0;
|
let extended = (lparam & 0x01000000) != 0;
|
||||||
|
|
Loading…
Reference in a new issue