Skip to content

Move ModifiersChanged variant to WindowEvent #1381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ed348f2
Move `ModifiersChanged` variant to `WindowEvent`
murarth Jan 9, 2020
f489ca5
Merge branch 'master' into modifiers-changed-window-event
goddessfreya Jan 13, 2020
e518931
macos: Fix flags_changed for ModifiersChanged variant move
rye Jan 22, 2020
f79f216
macos: Fire a ModifiersChanged event on window_did_resign_key
rye Jan 22, 2020
92e10dd
windows: Fix build
rye Jan 22, 2020
785d83e
Merge pull request #2 from rye/modifiers-changed-window-event-macos
murarth Jan 22, 2020
eb1c08d
Merge pull request #3 from rye/fix-windows-build
murarth Jan 22, 2020
88aab18
windows: Send ModifiersChanged(ModifiersState::empty) on KILLFOCUS
rye Jan 22, 2020
b28fd6b
Merge pull request #4 from rye/windows-send-empty-modifiers-when-lose…
murarth Jan 22, 2020
ac78bab
macos: Add a hook to update stale modifiers
rye Jan 22, 2020
4a8d78f
Merge pull request #5 from rye/macos-update-stale-modifiers
murarth Jan 22, 2020
3b970d6
Only call event_mods once when determining whether to update state
rye Jan 26, 2020
216aae2
flags_changed: Memoize window_id collection
rye Jan 26, 2020
496fe4c
Merge pull request #6 from rye/cleanup-modifiers-changed-window-event
murarth Jan 26, 2020
354b603
window_did_resign_key: Remove synthetic ModifiersChanged event
rye Jan 26, 2020
7189d02
mouse_motion: Add a call to update_potentially_stale_modifiers
rye Jan 26, 2020
40ab31e
key_up: Add a call to update_potentially_stale_modifiers
rye Jan 26, 2020
c322c8f
Merge pull request #7 from rye/more-state-checking
murarth Jan 26, 2020
c3a010f
mouse_motion: Remove update_potentially_stale_modifiers invocation
rye Jan 27, 2020
dfc23fe
Merge pull request #8 from rye/remove-mouse-motion-checks
murarth Jan 27, 2020
080336d
Retry CI
murarth Feb 5, 2020
201aed9
ViewState: Promote visibility of modifiers to the macos impl
rye Feb 10, 2020
c136b9c
window_delegate: Synthetically set modifiers state to empty on resignKey
rye Feb 10, 2020
1227701
Merge pull request #9 from rye/macos-synthetic-empty-on-resignkey
murarth Feb 10, 2020
f18bfeb
Check for modifiers change in window events
chrisduerr Feb 22, 2020
f81cf6b
Merge pull request #10 from chrisduerr/modifiers-changed-window-event
murarth Feb 23, 2020
a2142ac
Merge branch 'master' into modifiers-changed-window-event
murarth Feb 25, 2020
3d6dcda
Fix modifier changed on macOS
chrisduerr Mar 1, 2020
cf5792f
Merge pull request #11 from chrisduerr/modifiers-changed-window-event
murarth Mar 2, 2020
be23235
Fix unused variable warning
murarth Mar 6, 2020
d7c54b2
Move changelog entry into `Unreleased` section
murarth Mar 6, 2020
75e6e96
Merge branch 'master' into modifiers-changed-window-event
murarth Mar 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Fix `Event::to_static` returning `None` for user events.
- On Wayland, Hide CSD for fullscreen windows.
- On Windows, ignore spurious mouse move messages.
- **Breaking:** Move `ModifiersChanged` variant from `DeviceEvent` to `WindowEvent`.

# 0.21.0 (2020-02-04)

Expand Down
2 changes: 1 addition & 1 deletion examples/cursor_grab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ fn main() {
_ => (),
}
}
WindowEvent::ModifiersChanged(m) => modifiers = m,
_ => (),
},
Event::DeviceEvent { event, .. } => match event {
Expand All @@ -46,7 +47,6 @@ fn main() {
ElementState::Pressed => println!("mouse button {} pressed", button),
ElementState::Released => println!("mouse button {} released", button),
},
DeviceEvent::ModifiersChanged(m) => modifiers = m,
_ => (),
},
_ => (),
Expand Down
26 changes: 12 additions & 14 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ pub enum WindowEvent<'a> {
is_synthetic: bool,
},

/// The keyboard modifiers have changed.
///
/// 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),

/// The cursor has moved on the window.
CursorMoved {
device_id: DeviceId,
Expand All @@ -243,7 +250,7 @@ pub enum WindowEvent<'a> {
/// 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: PhysicalPosition<f64>,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
modifiers: ModifiersState,
},

Expand All @@ -258,7 +265,7 @@ pub enum WindowEvent<'a> {
device_id: DeviceId,
delta: MouseScrollDelta,
phase: TouchPhase,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
modifiers: ModifiersState,
},

Expand All @@ -267,7 +274,7 @@ pub enum WindowEvent<'a> {
device_id: DeviceId,
state: ElementState,
button: MouseButton,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
modifiers: ModifiersState,
},

Expand Down Expand Up @@ -341,6 +348,7 @@ impl<'a> WindowEvent<'a> {
input,
is_synthetic,
}),
ModifiersChanged(modifiers) => Some(ModifiersChanged(modifiers)),
#[allow(deprecated)]
CursorMoved {
device_id,
Expand Down Expand Up @@ -464,16 +472,6 @@ pub enum DeviceEvent {

Key(KeyboardInput),

/// 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 @@ -502,7 +500,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"]
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
pub modifiers: ModifiersState,
}

Expand Down
23 changes: 19 additions & 4 deletions src/platform_impl/linux/wayland/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ use smithay_client_toolkit::{
reexports::client::protocol::{wl_keyboard, wl_seat},
};

use crate::event::{
DeviceEvent, ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent,
};
use crate::event::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};

pub fn init_keyboard(
seat: &wl_seat::WlSeat,
Expand All @@ -33,9 +31,24 @@ pub fn init_keyboard(
let wid = make_wid(&surface);
my_sink.send_window_event(WindowEvent::Focused(true), wid);
*target.lock().unwrap() = Some(wid);

let modifiers = *modifiers_tracker.lock().unwrap();

if !modifiers.is_empty() {
my_sink.send_window_event(WindowEvent::ModifiersChanged(modifiers), wid);
}
}
KbEvent::Leave { surface, .. } => {
let wid = make_wid(&surface);
let modifiers = *modifiers_tracker.lock().unwrap();

if !modifiers.is_empty() {
my_sink.send_window_event(
WindowEvent::ModifiersChanged(ModifiersState::empty()),
wid,
);
}

my_sink.send_window_event(WindowEvent::Focused(false), wid);
*target.lock().unwrap() = None;
}
Expand Down Expand Up @@ -88,7 +101,9 @@ pub fn init_keyboard(

*modifiers_tracker.lock().unwrap() = modifiers;

my_sink.send_device_event(DeviceEvent::ModifiersChanged(modifiers), DeviceId);
if let Some(wid) = *target.lock().unwrap() {
my_sink.send_window_event(WindowEvent::ModifiersChanged(modifiers), wid);
}
}
}
},
Expand Down
116 changes: 73 additions & 43 deletions src/platform_impl/linux/x11/event_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub(super) struct EventProcessor<T: 'static> {
// Number of touch events currently in progress
pub(super) num_touch: u32,
pub(super) first_touch: Option<u64>,
// Currently focused window belonging to this process
pub(super) active_window: Option<ffi::Window>,
}

impl<T: 'static> EventProcessor<T> {
Expand Down Expand Up @@ -136,11 +138,12 @@ impl<T: 'static> EventProcessor<T> {
if let Some(modifiers) =
self.device_mod_state.update_state(&state, modifier)
{
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD);
callback(Event::DeviceEvent {
device_id,
event: DeviceEvent::ModifiersChanged(modifiers),
});
if let Some(window_id) = self.active_window {
callback(Event::WindowEvent {
window_id: mkwid(window_id),
event: WindowEvent::ModifiersChanged(modifiers),
});
}
}
}
}
Expand Down Expand Up @@ -872,44 +875,58 @@ impl<T: 'static> EventProcessor<T> {
ffi::XI_FocusIn => {
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };

let window_id = mkwid(xev.event);

wt.ime
.borrow_mut()
.focus(xev.event)
.expect("Failed to focus input context");

callback(Event::WindowEvent {
window_id,
event: Focused(true),
});

let modifiers = ModifiersState::from_x11(&xev.mods);

update_modifiers!(modifiers, None);
self.device_mod_state.update_state(&modifiers, None);

// The deviceid for this event is for a keyboard instead of a pointer,
// so we have to do a little extra work.
let pointer_id = self
.devices
.borrow()
.get(&DeviceId(xev.deviceid))
.map(|device| device.attachment)
.unwrap_or(2);
if self.active_window != Some(xev.event) {
self.active_window = Some(xev.event);

let position = PhysicalPosition::new(xev.event_x, xev.event_y);
let window_id = mkwid(xev.event);
let position = PhysicalPosition::new(xev.event_x, xev.event_y);

callback(Event::WindowEvent {
window_id,
event: CursorMoved {
device_id: mkdid(pointer_id),
position,
modifiers,
},
});
callback(Event::WindowEvent {
window_id,
event: Focused(true),
});

if !modifiers.is_empty() {
callback(Event::WindowEvent {
window_id,
event: WindowEvent::ModifiersChanged(modifiers),
});
}

// Issue key press events for all pressed keys
self.handle_pressed_keys(window_id, ElementState::Pressed, &mut callback);
// The deviceid for this event is for a keyboard instead of a pointer,
// so we have to do a little extra work.
let pointer_id = self
.devices
.borrow()
.get(&DeviceId(xev.deviceid))
.map(|device| device.attachment)
.unwrap_or(2);

callback(Event::WindowEvent {
window_id,
event: CursorMoved {
device_id: mkdid(pointer_id),
position,
modifiers,
},
});

// Issue key press events for all pressed keys
self.handle_pressed_keys(
window_id,
ElementState::Pressed,
&mut callback,
);
}
}
ffi::XI_FocusOut => {
let xev: &ffi::XIFocusOutEvent = unsafe { &*(xev.data as *const _) };
Expand All @@ -921,15 +938,26 @@ impl<T: 'static> EventProcessor<T> {
.unfocus(xev.event)
.expect("Failed to unfocus input context");

let window_id = mkwid(xev.event);
if self.active_window.take() == Some(xev.event) {
let window_id = mkwid(xev.event);

// Issue key release events for all pressed keys
self.handle_pressed_keys(window_id, ElementState::Released, &mut callback);
// Issue key release events for all pressed keys
self.handle_pressed_keys(
window_id,
ElementState::Released,
&mut callback,
);

callback(Event::WindowEvent {
window_id,
event: Focused(false),
})
callback(Event::WindowEvent {
window_id,
event: WindowEvent::ModifiersChanged(ModifiersState::empty()),
});

callback(Event::WindowEvent {
window_id,
event: Focused(false),
})
}
}

ffi::XI_TouchBegin | ffi::XI_TouchUpdate | ffi::XI_TouchEnd => {
Expand Down Expand Up @@ -1084,10 +1112,12 @@ impl<T: 'static> EventProcessor<T> {
let new_modifiers = self.device_mod_state.modifiers();

if modifiers != new_modifiers {
callback(Event::DeviceEvent {
device_id,
event: DeviceEvent::ModifiersChanged(new_modifiers),
});
if let Some(window_id) = self.active_window {
callback(Event::WindowEvent {
window_id: mkwid(window_id),
event: WindowEvent::ModifiersChanged(new_modifiers),
});
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/platform_impl/linux/x11/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ impl<T: 'static> EventLoop<T> {
device_mod_state: Default::default(),
num_touch: 0,
first_touch: None,
active_window: None,
};

// Register for device hotplug events
Expand Down
Loading