diff --git a/examples/cursor.rs b/examples/cursor.rs index bba013a9..0f65e10a 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -13,7 +13,7 @@ fn main() { events_loop.run_forever(|event| { match event { - Event::WindowEvent { event: WindowEvent::KeyboardInput(ElementState::Pressed, _, _), .. } => { + Event::WindowEvent { event: WindowEvent::KeyboardInput(ElementState::Pressed, _, _, _), .. } => { println!("Setting cursor to \"{:?}\"", cursors[cursor_idx]); window.set_cursor(cursors[cursor_idx]); if cursor_idx < cursors.len() - 1 { diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index bfb179e0..308d9dcf 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -37,7 +37,7 @@ fn main() { winit::Event::WindowEvent { event, .. } => { match event { 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(), _ => () } }, diff --git a/examples/grabbing.rs b/examples/grabbing.rs index ff3afb2a..d156da43 100644 --- a/examples/grabbing.rs +++ b/examples/grabbing.rs @@ -16,7 +16,7 @@ fn main() { match event { winit::Event::WindowEvent { event, .. } => { match event { - WindowEvent::KeyboardInput(ElementState::Pressed, _, _) => { + WindowEvent::KeyboardInput(ElementState::Pressed, _, _, _) => { if grabbed { grabbed = false; window.set_cursor_state(winit::CursorState::Normal) diff --git a/src/api/wayland/context.rs b/src/api/wayland/context.rs index debd5e6b..de9d21bf 100644 --- a/src/api/wayland/context.rs +++ b/src/api/wayland/context.rs @@ -1,5 +1,7 @@ use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase}; +use events::ModifiersState; + use std::collections::VecDeque; use std::sync::{Arc, Mutex}; @@ -627,10 +629,12 @@ impl wl_keyboard::Handler for WaylandEnv { wl_keyboard::KeyState::Released => ElementState::Released, }; let mut guard = eviter.lock().unwrap(); + // TODO implement ModifiersState guard.push_back(Event::KeyboardInput( state, key as u8, - None + None, + ModifiersState::default() )); }, KbdType::Plain(None) => () diff --git a/src/api/wayland/keyboard.rs b/src/api/wayland/keyboard.rs index 89186579..8b571a1a 100644 --- a/src/api/wayland/keyboard.rs +++ b/src/api/wayland/keyboard.rs @@ -3,6 +3,8 @@ use std::sync::{Arc, Mutex}; use {VirtualKeyCode, ElementState, WindowEvent as Event}; +use events::ModifiersState; + use super::wayland_kbd; use wayland_client::EventQueueHandle; use wayland_client::protocol::wl_keyboard; @@ -35,7 +37,8 @@ impl wayland_kbd::Handler for KbdHandler { }; let vkcode = key_to_vkey(rawkey, keysym); 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 if let ElementState::Released = state { return } if let Some(txt) = utf8 { diff --git a/src/api/x11/input.rs b/src/api/x11/input.rs index 7185a449..91f139f3 100644 --- a/src/api/x11/input.rs +++ b/src/api/x11/input.rs @@ -8,6 +8,7 @@ use std::slice::from_raw_parts; use WindowAttributes; use events::WindowEvent as Event; +use events::ModifiersState; use super::{events, ffi}; use super::XConnection; @@ -165,7 +166,7 @@ impl XInputEventHandler { 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, ModifiersState::default())); translated_events } diff --git a/src/events.rs b/src/events.rs index 7288ea9e..851ef0c6 100644 --- a/src/events.rs +++ b/src/events.rs @@ -35,7 +35,7 @@ pub enum WindowEvent { Focused(bool), /// An event from the keyboard has been received. - KeyboardInput(ElementState, ScanCode, Option), + KeyboardInput(ElementState, ScanCode, Option, ModifiersState), /// The cursor has moved on the window. /// @@ -320,3 +320,20 @@ pub enum VirtualKeyCode { WebStop, 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 +} diff --git a/src/platform/macos/events_loop.rs b/src/platform/macos/events_loop.rs index 458c69b5..60ece70f 100644 --- a/src/platform/macos/events_loop.rs +++ b/src/platform/macos/events_loop.rs @@ -1,6 +1,6 @@ use cocoa::{self, appkit, foundation}; use cocoa::appkit::{NSApplication, NSEvent, NSView, NSWindow}; -use events::{self, ElementState, Event, MouseButton, TouchPhase, WindowEvent}; +use events::{self, ElementState, Event, MouseButton, TouchPhase, WindowEvent, Modifiers}; use super::window::Window; use std; @@ -271,7 +271,7 @@ impl EventsLoop { let vkey = to_virtual_key_code(NSEvent::keyCode(ns_event)); let state = ElementState::Pressed; let code = NSEvent::keyCode(ns_event) as u8; - let window_event = WindowEvent::KeyboardInput(state, code, vkey); + let window_event = WindowEvent::KeyboardInput(state, code, vkey, ModifiersState::default()); events.push_back(into_event(window_event)); let event = events.pop_front(); self.pending_events.lock().unwrap().extend(events.into_iter()); @@ -283,7 +283,7 @@ impl EventsLoop { let state = ElementState::Released; let code = NSEvent::keyCode(ns_event) as u8; - let window_event = WindowEvent::KeyboardInput(state, code, vkey); + let window_event = WindowEvent::KeyboardInput(state, code, vkey, ModifiersState::default()); Some(into_event(window_event)) }, @@ -298,13 +298,13 @@ impl EventsLoop { if !key_pressed && NSEvent::modifierFlags(event).contains(keymask) { let state = ElementState::Pressed; 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), ModifiersState::default()); Some(window_event) } else if key_pressed && !NSEvent::modifierFlags(event).contains(keymask) { let state = ElementState::Released; 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), ModifiersState::default()); Some(window_event) } else { diff --git a/src/platform/windows/callback.rs b/src/platform/windows/callback.rs index de611640..53f54875 100644 --- a/src/platform/windows/callback.rs +++ b/src/platform/windows/callback.rs @@ -8,6 +8,7 @@ use std::os::windows::ffi::OsStringExt; use CursorState; use WindowEvent as Event; +use events::ModifersState; use super::event; 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) } else { let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam); - send_event(window, KeyboardInput(Pressed, scancode, vkey)); + send_event(window, KeyboardInput(Pressed, scancode, vkey, ModifersState::default())); 0 } }, @@ -209,7 +210,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, use events::WindowEvent::KeyboardInput; use events::ElementState::Released; let (scancode, vkey) = event::vkeycode_to_element(wparam, lparam); - send_event(window, KeyboardInput(Released, scancode, vkey)); + send_event(window, KeyboardInput(Released, scancode, vkey, ModifersState::default())); 0 },