Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
- `RedrawEventsCleared` is issued after each set of `RedrawRequested` events.
- Implement synthetic window focus key events on Windows.
- **Breaking**: Change `ModifiersState` to a `bitflags` struct.
- On Windows, implement `VirtualKeyCode` translation for `LWin` and `RWin`.
- On Windows, fix closing the last opened window causing `DeviceEvent`s to stop getting emitted.
- On Windows, fix `Window::set_visible` not setting internal flags correctly. This resulted in some weird behavior.
- Add `DeviceEvent::ModifiersChanged`.
- Deprecate `modifiers` fields in other events in favor of `ModifiersChanged`.

# 0.20.0 Alpha 5 (2019-12-09)

Expand Down
6 changes: 4 additions & 2 deletions examples/cursor_grab.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use winit::{
event::{DeviceEvent, ElementState, Event, KeyboardInput, WindowEvent},
event::{DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
Expand All @@ -12,6 +12,8 @@ fn main() {
.build(&event_loop)
.unwrap();

let mut modifiers = ModifiersState::default();

event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Expand All @@ -22,7 +24,6 @@ fn main() {
KeyboardInput {
state: ElementState::Released,
virtual_keycode: Some(key),
modifiers,
..
},
..
Expand All @@ -43,6 +44,7 @@ fn main() {
ElementState::Pressed => println!("mouse button {} pressed", button),
ElementState::Released => println!("mouse button {} released", button),
},
DeviceEvent::ModifiersChanged(m) => modifiers = m,
_ => (),
},
_ => (),
Expand Down
18 changes: 13 additions & 5 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ pub enum WindowEvent {
/// limited by the display area and it may have been transformed by the OS to implement effects such as cursor
/// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control.
position: LogicalPosition,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
modifiers: ModifiersState,
},

Expand All @@ -181,6 +182,7 @@ pub enum WindowEvent {
device_id: DeviceId,
delta: MouseScrollDelta,
phase: TouchPhase,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
modifiers: ModifiersState,
},

Expand All @@ -189,6 +191,7 @@ pub enum WindowEvent {
device_id: DeviceId,
state: ElementState,
button: MouseButton,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
modifiers: ModifiersState,
},

Expand Down Expand Up @@ -295,11 +298,15 @@ pub enum DeviceEvent {

Key(KeyboardInput),

/// Keyboard modifiers have changed
#[doc(hidden)]
ModifiersChanged {
modifiers: ModifiersState,
},
/// The keyboard modifiers have changed.
///
/// This is tracked internally to avoid tracking errors arising from modifier key state changes when events from
/// this device are not being delivered to the application, e.g. due to keyboard focus being elsewhere.
///
/// Platform-specific behavior:
/// - **Web**: This API is currently unimplemented on the web. This isn't by design - it's an
/// issue, and it should get fixed - but it's the current state of the API.
ModifiersChanged(ModifiersState),

Text {
codepoint: char,
Expand Down Expand Up @@ -329,6 +336,7 @@ pub struct KeyboardInput {
///
/// This is tracked internally to avoid tracking errors arising from modifier key state changes when events from
/// this device are not being delivered to the application, e.g. due to keyboard focus being elsewhere.
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
pub modifiers: ModifiersState,
}

Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/linux/wayland/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub fn init_keyboard(
my_sink
.send(Event::DeviceEvent {
device_id: device_id(),
event: DeviceEvent::ModifiersChanged { modifiers },
event: DeviceEvent::ModifiersChanged(modifiers),
})
.unwrap();
}
Expand Down
6 changes: 2 additions & 4 deletions src/platform_impl/linux/x11/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl<T: 'static> EventProcessor<T> {
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD);
callback(Event::DeviceEvent {
device_id,
event: DeviceEvent::ModifiersChanged { modifiers },
event: DeviceEvent::ModifiersChanged(modifiers),
});
}
}
Expand Down Expand Up @@ -1114,9 +1114,7 @@ impl<T: 'static> EventProcessor<T> {
if modifiers != new_modifiers {
callback(Event::DeviceEvent {
device_id,
event: DeviceEvent::ModifiersChanged {
modifiers: new_modifiers,
},
event: DeviceEvent::ModifiersChanged(new_modifiers),
});
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/platform_impl/macos/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,7 @@ extern "C" fn flags_changed(this: &Object, _sel: Sel, event: id) {

AppState::queue_event(Event::DeviceEvent {
device_id: DEVICE_ID,
event: DeviceEvent::ModifiersChanged {
modifiers: state.modifiers,
},
event: DeviceEvent::ModifiersChanged(state.modifiers),
});
}
trace!("Completed `flagsChanged`");
Expand Down
53 changes: 51 additions & 2 deletions src/platform_impl/windows/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,55 @@ pub fn get_key_mods() -> ModifiersState {
mods
}

bitflags! {
#[derive(Default)]
pub struct ModifiersStateSide: u32 {
const LSHIFT = 0b010 << 0;
const RSHIFT = 0b001 << 0;

const LCTRL = 0b010 << 3;
const RCTRL = 0b001 << 3;

const LALT = 0b010 << 6;
const RALT = 0b001 << 6;

const LLOGO = 0b010 << 9;
const RLOGO = 0b001 << 9;
}
}

impl ModifiersStateSide {
pub fn filter_out_altgr(&self) -> ModifiersStateSide {
match layout_uses_altgr() && self.contains(Self::RALT) {
false => *self,
true => *self & !(Self::LCTRL | Self::RCTRL | Self::LALT | Self::RALT),
}
}
}

impl From<ModifiersStateSide> for ModifiersState {
fn from(side: ModifiersStateSide) -> Self {
let mut state = ModifiersState::default();
state.set(
Self::SHIFT,
side.intersects(ModifiersStateSide::LSHIFT | ModifiersStateSide::RSHIFT),
);
state.set(
Self::CTRL,
side.intersects(ModifiersStateSide::LCTRL | ModifiersStateSide::RCTRL),
);
state.set(
Self::ALT,
side.intersects(ModifiersStateSide::LALT | ModifiersStateSide::RALT),
);
state.set(
Self::LOGO,
side.intersects(ModifiersStateSide::LLOGO | ModifiersStateSide::RLOGO),
);
state
}
}

pub fn get_pressed_keys() -> impl Iterator<Item = c_int> {
let mut keyboard_state = vec![0u8; 256];
unsafe { winuser::GetKeyboardState(keyboard_state.as_mut_ptr()) };
Expand Down Expand Up @@ -196,8 +245,8 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option<VirtualKeyCode> {
0x58 => Some(VirtualKeyCode::X),
0x59 => Some(VirtualKeyCode::Y),
0x5A => Some(VirtualKeyCode::Z),
//winuser::VK_LWIN => Some(VirtualKeyCode::Lwin),
//winuser::VK_RWIN => Some(VirtualKeyCode::Rwin),
winuser::VK_LWIN => Some(VirtualKeyCode::LWin),
winuser::VK_RWIN => Some(VirtualKeyCode::RWin),
winuser::VK_APPS => Some(VirtualKeyCode::Apps),
winuser::VK_SLEEP => Some(VirtualKeyCode::Sleep),
winuser::VK_NUMPAD0 => Some(VirtualKeyCode::Numpad0),
Expand Down
Loading