mirror of
https://github.com/CloudNebulaProject/wayray.git
synced 2026-04-10 13:10:41 +00:00
Add keyboard and pointer input handling via Smithay seat
Initialize keyboard and pointer on the Wayland seat at startup, and route Winit input events (keyboard, pointer motion, button, scroll) through process_input_event to the Smithay seat so clients can receive input. Click-to-focus raises the clicked window and sets keyboard focus.
This commit is contained in:
parent
cbfc6e95df
commit
a189c2f51b
2 changed files with 132 additions and 6 deletions
|
|
@ -128,8 +128,8 @@ fn main() -> Result<()> {
|
|||
WinitEvent::Focus(focused) => {
|
||||
info!(focused, "window focus changed");
|
||||
}
|
||||
WinitEvent::Input(_event) => {
|
||||
// Input handling is Task 7 -- ignore for now.
|
||||
WinitEvent::Input(event) => {
|
||||
data.state.process_input_event(event);
|
||||
}
|
||||
WinitEvent::Redraw => {
|
||||
render::render_output_frame(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,19 @@
|
|||
use smithay::{
|
||||
desktop::Space,
|
||||
input::{Seat, SeatState},
|
||||
backend::input::{
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event as InputEventTrait,
|
||||
InputBackend, InputEvent, KeyboardKeyEvent,
|
||||
PointerAxisEvent as JsonPointerAxisEvent,
|
||||
PointerButtonEvent as JsonPointerButtonEvent,
|
||||
},
|
||||
desktop::{Space, WindowSurfaceType},
|
||||
input::{
|
||||
Seat, SeatState,
|
||||
keyboard::FilterResult,
|
||||
pointer::{AxisFrame, ButtonEvent, MotionEvent},
|
||||
},
|
||||
output::Output,
|
||||
reexports::wayland_server::{Display, DisplayHandle},
|
||||
utils::{Clock, Monotonic},
|
||||
utils::{Clock, Monotonic, SERIAL_COUNTER},
|
||||
wayland::{
|
||||
compositor::CompositorState,
|
||||
output::OutputManagerState,
|
||||
|
|
@ -43,7 +53,11 @@ impl WayRay {
|
|||
let data_device_state = DataDeviceState::new::<Self>(&dh);
|
||||
|
||||
let mut seat_state = SeatState::new();
|
||||
let seat = seat_state.new_wl_seat(&dh, "wayray");
|
||||
let mut seat = seat_state.new_wl_seat(&dh, "wayray");
|
||||
|
||||
seat.add_keyboard(Default::default(), 200, 25)
|
||||
.expect("failed to add keyboard to seat");
|
||||
seat.add_pointer();
|
||||
|
||||
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&dh);
|
||||
|
||||
|
|
@ -63,4 +77,116 @@ impl WayRay {
|
|||
output,
|
||||
}
|
||||
}
|
||||
|
||||
/// Process an input event from the backend and forward it to the appropriate
|
||||
/// Smithay seat device (keyboard or pointer).
|
||||
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
|
||||
match event {
|
||||
InputEvent::Keyboard { event } => {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let keyboard = self.seat.get_keyboard().unwrap();
|
||||
keyboard.input::<(), _>(
|
||||
self,
|
||||
event.key_code(),
|
||||
event.state(),
|
||||
serial,
|
||||
event.time_msec(),
|
||||
|_, _, _| FilterResult::Forward,
|
||||
);
|
||||
}
|
||||
InputEvent::PointerMotionAbsolute { event } => {
|
||||
let output_size = self.output.current_mode().unwrap().size;
|
||||
let pos = event.position_transformed(output_size.to_logical(1));
|
||||
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let pointer = self.seat.get_pointer().unwrap();
|
||||
|
||||
// Find the element (window) under the pointer and get its surface.
|
||||
let under = self.space.element_under(pos).and_then(|(window, loc)| {
|
||||
window
|
||||
.surface_under(pos - loc.to_f64(), WindowSurfaceType::ALL)
|
||||
.map(|(surface, surf_loc)| (surface, (surf_loc + loc).to_f64()))
|
||||
});
|
||||
|
||||
pointer.motion(
|
||||
self,
|
||||
under,
|
||||
&MotionEvent {
|
||||
location: pos,
|
||||
serial,
|
||||
time: event.time_msec(),
|
||||
},
|
||||
);
|
||||
pointer.frame(self);
|
||||
}
|
||||
InputEvent::PointerButton { event } => {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let pointer = self.seat.get_pointer().unwrap();
|
||||
|
||||
// On button press, focus the window under the pointer.
|
||||
if event.state() == ButtonState::Pressed {
|
||||
let pos = pointer.current_location();
|
||||
if let Some((window, _loc)) = self.space.element_under(pos) {
|
||||
let window = window.clone();
|
||||
self.space.raise_element(&window, true);
|
||||
|
||||
let keyboard = self.seat.get_keyboard().unwrap();
|
||||
let wl_surface = window.toplevel().map(|t| t.wl_surface().clone());
|
||||
keyboard.set_focus(self, wl_surface, serial);
|
||||
}
|
||||
}
|
||||
|
||||
pointer.button(
|
||||
self,
|
||||
&ButtonEvent {
|
||||
serial,
|
||||
time: event.time_msec(),
|
||||
button: event.button_code(),
|
||||
state: event.state(),
|
||||
},
|
||||
);
|
||||
pointer.frame(self);
|
||||
}
|
||||
InputEvent::PointerAxis { event } => {
|
||||
let pointer = self.seat.get_pointer().unwrap();
|
||||
|
||||
let source = event.source();
|
||||
|
||||
let horizontal_amount = event
|
||||
.amount(Axis::Horizontal)
|
||||
.unwrap_or_else(|| event.amount_v120(Axis::Horizontal).unwrap_or(0.0) * 3.0 / 120.0);
|
||||
let vertical_amount = event
|
||||
.amount(Axis::Vertical)
|
||||
.unwrap_or_else(|| event.amount_v120(Axis::Vertical).unwrap_or(0.0) * 3.0 / 120.0);
|
||||
|
||||
let mut frame = AxisFrame::new(event.time_msec()).source(source);
|
||||
|
||||
if horizontal_amount != 0.0 {
|
||||
frame = frame.value(Axis::Horizontal, horizontal_amount);
|
||||
if let Some(v120) = event.amount_v120(Axis::Horizontal) {
|
||||
frame = frame.v120(Axis::Horizontal, v120 as i32);
|
||||
}
|
||||
}
|
||||
if vertical_amount != 0.0 {
|
||||
frame = frame.value(Axis::Vertical, vertical_amount);
|
||||
if let Some(v120) = event.amount_v120(Axis::Vertical) {
|
||||
frame = frame.v120(Axis::Vertical, v120 as i32);
|
||||
}
|
||||
}
|
||||
|
||||
if source == AxisSource::Finger {
|
||||
if horizontal_amount == 0.0 {
|
||||
frame = frame.stop(Axis::Horizontal);
|
||||
}
|
||||
if vertical_amount == 0.0 {
|
||||
frame = frame.stop(Axis::Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
pointer.axis(self, frame);
|
||||
pointer.frame(self);
|
||||
}
|
||||
_ => {} // Ignore other events
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue