From f366dfd12a839a18914ab489743dfd85016cbed5 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Sun, 11 Jul 2021 10:05:27 +0200 Subject: [PATCH] wlcs: pointer input handling --- anvil/src/window_map.rs | 4 ++ wlcs_anvil/src/ffi_wrappers.rs | 10 ++--- wlcs_anvil/src/lib.rs | 15 ++++--- wlcs_anvil/src/main_loop.rs | 74 ++++++++++++++++++++++++++++++++-- 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/anvil/src/window_map.rs b/anvil/src/window_map.rs index 08216c4..0ca4b4c 100644 --- a/anvil/src/window_map.rs +++ b/anvil/src/window_map.rs @@ -255,6 +255,10 @@ impl WindowMap { self.windows.insert(0, window); } + pub fn windows(&self) -> impl Iterator + '_ { + self.windows.iter().map(|w| w.toplevel.clone()) + } + pub fn insert_popup(&mut self, popup: PopupKind) { let popup = Popup { popup }; self.popups.push(popup); diff --git a/wlcs_anvil/src/ffi_wrappers.rs b/wlcs_anvil/src/ffi_wrappers.rs index 3dc7efc..c99650c 100644 --- a/wlcs_anvil/src/ffi_wrappers.rs +++ b/wlcs_anvil/src/ffi_wrappers.rs @@ -120,7 +120,7 @@ impl DisplayServerHandle { let _ = sender.send(WlcsEvent::PositionWindow { client_id, surface_id, - location: (x, y), + location: (x, y).into(), }); } } @@ -178,7 +178,7 @@ impl PointerHandle { let me = &mut *container_of!(ptr, PointerHandle, wlcs_pointer); let _ = me.sender.send(WlcsEvent::PointerMoveAbsolute { device_id: me.device_id, - location: (wl_fixed_to_double(x), wl_fixed_to_double(y)), + location: (wl_fixed_to_double(x), wl_fixed_to_double(y)).into(), }); } @@ -186,7 +186,7 @@ impl PointerHandle { let me = &mut *container_of!(ptr, PointerHandle, wlcs_pointer); let _ = me.sender.send(WlcsEvent::PointerMoveRelative { device_id: me.device_id, - delta: (wl_fixed_to_double(x), wl_fixed_to_double(y)), + delta: (wl_fixed_to_double(x), wl_fixed_to_double(y)).into(), }); } @@ -236,7 +236,7 @@ impl TouchHandle { let me = &mut *container_of!(ptr, TouchHandle, wlcs_touch); let _ = me.sender.send(WlcsEvent::TouchDown { device_id: me.device_id, - location: (wl_fixed_to_double(x), wl_fixed_to_double(y)), + location: (wl_fixed_to_double(x), wl_fixed_to_double(y)).into(), }); } @@ -244,7 +244,7 @@ impl TouchHandle { let me = &mut *container_of!(ptr, TouchHandle, wlcs_touch); let _ = me.sender.send(WlcsEvent::TouchMove { device_id: me.device_id, - location: (wl_fixed_to_double(x), wl_fixed_to_double(y)), + location: (wl_fixed_to_double(x), wl_fixed_to_double(y)).into(), }); } diff --git a/wlcs_anvil/src/lib.rs b/wlcs_anvil/src/lib.rs index fd89cf0..93d79db 100644 --- a/wlcs_anvil/src/lib.rs +++ b/wlcs_anvil/src/lib.rs @@ -5,7 +5,10 @@ mod renderer; use std::{os::unix::net::UnixStream, thread::JoinHandle}; -use smithay::reexports::calloop; +use smithay::{ + reexports::calloop, + utils::{Logical, Point}, +}; use ffi_api::{WlcsExtensionDescriptor, WlcsIntegrationDescriptor}; @@ -50,7 +53,7 @@ pub enum WlcsEvent { PositionWindow { client_id: i32, surface_id: u32, - location: (i32, i32), + location: Point, }, /* Pointer related events */ /// A new pointer device is available @@ -60,12 +63,12 @@ pub enum WlcsEvent { /// Move the pointer in absolute coordinate space PointerMoveAbsolute { device_id: u32, - location: (f64, f64), + location: Point, }, /// Move the pointer in relative coordinate space PointerMoveRelative { device_id: u32, - delta: (f64, f64), + delta: Point, }, /// Press a pointer button PointerButtonDown { @@ -89,12 +92,12 @@ pub enum WlcsEvent { /// A touch point is down TouchDown { device_id: u32, - location: (f64, f64), + location: Point, }, /// A touch point moved TouchMove { device_id: u32, - location: (f64, f64), + location: Point, }, /// A touch point is up TouchUp { diff --git a/wlcs_anvil/src/main_loop.rs b/wlcs_anvil/src/main_loop.rs index 11c805b..c067170 100644 --- a/wlcs_anvil/src/main_loop.rs +++ b/wlcs_anvil/src/main_loop.rs @@ -13,11 +13,15 @@ use smithay::{ channel::{Channel, Event as ChannelEvent}, EventLoop, }, - wayland_server::{protocol::wl_output, Client, Display}, + wayland_server::{ + protocol::{wl_output, wl_pointer}, + Client, Display, + }, }, wayland::{ output::{Mode, PhysicalProperties}, seat::CursorImageStatus, + SERIAL_COUNTER as SCOUNTER, }, }; @@ -187,9 +191,71 @@ fn handle_event(event: WlcsEvent, state: &mut AnvilState) { let client = unsafe { display.borrow_mut().create_client(stream.into_raw_fd(), state) }; state.backend_data.clients.insert(client_id, client); } - e => { - // TODO: handle the actual events - eprintln!("Unhandled event: {:?}", e); + WlcsEvent::PositionWindow { + client_id, + surface_id, + location, + } => { + // find the surface + let client = state.backend_data.clients.get(&client_id); + let mut wmap = state.window_map.borrow_mut(); + let toplevel = wmap.windows().find(|kind| { + let surface = kind.get_surface().unwrap(); + surface.as_ref().client().as_ref() == client && surface.as_ref().id() == surface_id + }); + if let Some(toplevel) = toplevel { + // set its location + wmap.set_location(&toplevel, location); + } } + // pointer inputs + WlcsEvent::NewPointer { .. } => {} + WlcsEvent::PointerMoveAbsolute { location, .. } => { + state.pointer_location = location; + let serial = SCOUNTER.next_serial(); + let under = state.window_map.borrow().get_surface_under(location); + let time = state.start_time.elapsed().as_millis() as u32; + state.pointer.motion(location, under, serial, time); + } + WlcsEvent::PointerMoveRelative { delta, .. } => { + state.pointer_location += delta; + let serial = SCOUNTER.next_serial(); + let under = state + .window_map + .borrow() + .get_surface_under(state.pointer_location); + let time = state.start_time.elapsed().as_millis() as u32; + state.pointer.motion(state.pointer_location, under, serial, time); + } + WlcsEvent::PointerButtonDown { button_id, .. } => { + let serial = SCOUNTER.next_serial(); + if !state.pointer.is_grabbed() { + let under = state + .window_map + .borrow_mut() + .get_surface_and_bring_to_top(state.pointer_location); + state + .keyboard + .set_focus(under.as_ref().map(|&(ref s, _)| s), serial); + } + let time = state.start_time.elapsed().as_millis() as u32; + state + .pointer + .button(button_id as u32, wl_pointer::ButtonState::Pressed, serial, time); + } + WlcsEvent::PointerButtonUp { button_id, .. } => { + let serial = SCOUNTER.next_serial(); + let time = state.start_time.elapsed().as_millis() as u32; + state + .pointer + .button(button_id as u32, wl_pointer::ButtonState::Released, serial, time); + } + WlcsEvent::PointerRemoved { .. } => {} + // touch inputs + WlcsEvent::NewTouch { .. } => {} + WlcsEvent::TouchDown { .. } => {} + WlcsEvent::TouchMove { .. } => {} + WlcsEvent::TouchUp { .. } => {} + WlcsEvent::TouchRemoved { .. } => {} } }