diff --git a/src/api.rs b/src/api.rs index 499c7cc..5e96b94 100644 --- a/src/api.rs +++ b/src/api.rs @@ -52,7 +52,7 @@ use tracing::{error, warn}; use crate::{ config::ConnectorSavedState, - focus::FocusTarget, + focus::keyboard::KeyboardFocusTarget, input::ModifierMask, output::OutputName, state::{State, WithState}, @@ -1379,7 +1379,7 @@ impl window_service_server::WindowService for WindowService { if let Some(keyboard) = state.seat.get_keyboard() { keyboard.set_focus( state, - Some(FocusTarget::Window(window)), + Some(KeyboardFocusTarget::Window(window)), SERIAL_COUNTER.next_serial(), ); } @@ -1407,7 +1407,7 @@ impl window_service_server::WindowService for WindowService { if let Some(keyboard) = state.seat.get_keyboard() { keyboard.set_focus( state, - Some(FocusTarget::Window(window)), + Some(KeyboardFocusTarget::Window(window)), SERIAL_COUNTER.next_serial(), ); } @@ -1518,12 +1518,17 @@ impl window_service_server::WindowService for WindowService { .ok_or_else(|| Status::invalid_argument("no button specified"))?; run_unary_no_response(&self.sender, move |state| { - let Some((FocusTarget::Window(window), _)) = - state.focus_target_under(state.pointer_location) + let Some((pointer_focus, _)) = state.pointer_focus_target_under(state.pointer_location) else { return; }; - let Some(wl_surf) = window.wl_surface() else { return }; + let Some(window) = pointer_focus.window_for(state) else { + tracing::info!("Move grabs are currently not implemented for non-windows"); + return; + }; + let Some(wl_surf) = window.wl_surface() else { + return; + }; let seat = state.seat.clone(); crate::grab::move_grab::move_request_server( @@ -1549,12 +1554,17 @@ impl window_service_server::WindowService for WindowService { run_unary_no_response(&self.sender, move |state| { let pointer_loc = state.pointer_location; - let Some((FocusTarget::Window(window), window_loc)) = - state.focus_target_under(pointer_loc) + let Some((pointer_focus, window_loc)) = state.pointer_focus_target_under(pointer_loc) else { return; }; - let Some(wl_surf) = window.wl_surface() else { return }; + let Some(window) = pointer_focus.window_for(state) else { + tracing::info!("Move grabs are currently not implemented for non-windows"); + return; + }; + let Some(wl_surf) = window.wl_surface() else { + return; + }; let window_geometry = window.geometry(); let window_x = window_loc.x as f64; diff --git a/src/focus.rs b/src/focus.rs index 62fb430..ad6f46b 100644 --- a/src/focus.rs +++ b/src/focus.rs @@ -1,24 +1,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later -use smithay::{ - desktop::{LayerSurface, PopupKind}, - input::{ - keyboard::KeyboardTarget, - pointer::{MotionEvent, PointerTarget}, - touch::{self, TouchTarget}, - Seat, - }, - output::Output, - reexports::wayland_server::{protocol::wl_surface::WlSurface, Resource}, - utils::{IsAlive, Serial, SERIAL_COUNTER}, - wayland::seat::WaylandFocus, -}; +use smithay::{output::Output, utils::SERIAL_COUNTER}; use crate::{ state::{State, WithState}, window::WindowElement, }; +pub mod keyboard; +pub mod pointer; + impl State { /// Get the currently focused window on `output` /// that isn't an override redirect window, if any. @@ -111,353 +102,3 @@ impl FocusStack { self.focused.then(|| self.stack.last())? } } - -/// Different focusable objects. -#[derive(Debug, Clone, PartialEq)] -pub enum FocusTarget { - Window(WindowElement), - Popup(PopupKind), - LayerSurface(LayerSurface), -} - -impl IsAlive for FocusTarget { - fn alive(&self) -> bool { - match self { - FocusTarget::Window(window) => window.alive(), - FocusTarget::Popup(popup) => popup.alive(), - FocusTarget::LayerSurface(surf) => surf.alive(), - } - } -} - -impl TryFrom for WlSurface { - type Error = (); - - fn try_from(value: FocusTarget) -> Result { - value.wl_surface().ok_or(()) - } -} - -impl PointerTarget for FocusTarget { - fn frame(&self, seat: &Seat, data: &mut State) { - match self { - FocusTarget::Window(window) => PointerTarget::frame(window, seat, data), - FocusTarget::Popup(popup) => PointerTarget::frame(popup.wl_surface(), seat, data), - FocusTarget::LayerSurface(surf) => PointerTarget::frame(surf.wl_surface(), seat, data), - } - } - - fn enter(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { - match self { - FocusTarget::Window(window) => PointerTarget::enter(window, seat, data, event), - FocusTarget::Popup(popup) => { - PointerTarget::enter(popup.wl_surface(), seat, data, event); - } - FocusTarget::LayerSurface(surf) => { - PointerTarget::enter(surf.wl_surface(), seat, data, event) - } - } - } - - fn motion(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { - match self { - FocusTarget::Window(window) => PointerTarget::motion(window, seat, data, event), - FocusTarget::Popup(popup) => { - PointerTarget::motion(popup.wl_surface(), seat, data, event); - } - FocusTarget::LayerSurface(surf) => { - PointerTarget::motion(surf.wl_surface(), seat, data, event) - } - } - } - - fn relative_motion( - &self, - seat: &Seat, - data: &mut State, - event: &smithay::input::pointer::RelativeMotionEvent, - ) { - match self { - FocusTarget::Window(window) => { - PointerTarget::relative_motion(window, seat, data, event); - } - FocusTarget::Popup(popup) => { - PointerTarget::relative_motion(popup.wl_surface(), seat, data, event); - } - FocusTarget::LayerSurface(surf) => { - PointerTarget::relative_motion(surf.wl_surface(), seat, data, event); - } - } - } - - fn button( - &self, - seat: &Seat, - data: &mut State, - event: &smithay::input::pointer::ButtonEvent, - ) { - match self { - FocusTarget::Window(window) => PointerTarget::button(window, seat, data, event), - FocusTarget::Popup(popup) => { - PointerTarget::button(popup.wl_surface(), seat, data, event); - } - FocusTarget::LayerSurface(surf) => { - PointerTarget::button(surf.wl_surface(), seat, data, event) - } - } - } - - fn axis( - &self, - seat: &Seat, - data: &mut State, - frame: smithay::input::pointer::AxisFrame, - ) { - match self { - FocusTarget::Window(window) => PointerTarget::axis(window, seat, data, frame), - FocusTarget::Popup(popup) => PointerTarget::axis(popup.wl_surface(), seat, data, frame), - FocusTarget::LayerSurface(surf) => { - PointerTarget::axis(surf.wl_surface(), seat, data, frame) - } - } - } - - fn leave(&self, seat: &Seat, data: &mut State, serial: Serial, time: u32) { - match self { - FocusTarget::Window(window) => PointerTarget::leave(window, seat, data, serial, time), - FocusTarget::Popup(popup) => { - PointerTarget::leave(popup.wl_surface(), seat, data, serial, time); - } - FocusTarget::LayerSurface(surf) => { - PointerTarget::leave(surf.wl_surface(), seat, data, serial, time) - } - } - } - - fn gesture_swipe_begin( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GestureSwipeBeginEvent, - ) { - todo!() - } - - fn gesture_swipe_update( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GestureSwipeUpdateEvent, - ) { - todo!() - } - - fn gesture_swipe_end( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GestureSwipeEndEvent, - ) { - todo!() - } - - fn gesture_pinch_begin( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GesturePinchBeginEvent, - ) { - todo!() - } - - fn gesture_pinch_update( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GesturePinchUpdateEvent, - ) { - todo!() - } - - fn gesture_pinch_end( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GesturePinchEndEvent, - ) { - todo!() - } - - fn gesture_hold_begin( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GestureHoldBeginEvent, - ) { - todo!() - } - - fn gesture_hold_end( - &self, - _seat: &Seat, - _data: &mut State, - _event: &smithay::input::pointer::GestureHoldEndEvent, - ) { - todo!() - } -} - -impl KeyboardTarget for FocusTarget { - fn enter( - &self, - seat: &Seat, - data: &mut State, - keys: Vec>, - serial: Serial, - ) { - match self { - FocusTarget::Window(window) => KeyboardTarget::enter(window, seat, data, keys, serial), - FocusTarget::Popup(popup) => { - KeyboardTarget::enter(popup.wl_surface(), seat, data, keys, serial); - } - FocusTarget::LayerSurface(surf) => { - KeyboardTarget::enter(surf.wl_surface(), seat, data, keys, serial); - } - } - } - - fn leave(&self, seat: &Seat, data: &mut State, serial: Serial) { - match self { - FocusTarget::Window(window) => KeyboardTarget::leave(window, seat, data, serial), - FocusTarget::Popup(popup) => { - KeyboardTarget::leave(popup.wl_surface(), seat, data, serial); - } - FocusTarget::LayerSurface(surf) => { - KeyboardTarget::leave(surf.wl_surface(), seat, data, serial) - } - } - } - - fn key( - &self, - seat: &Seat, - data: &mut State, - key: smithay::input::keyboard::KeysymHandle<'_>, - state: smithay::backend::input::KeyState, - serial: Serial, - time: u32, - ) { - match self { - FocusTarget::Window(window) => { - KeyboardTarget::key(window, seat, data, key, state, serial, time); - } - FocusTarget::Popup(popup) => { - KeyboardTarget::key(popup.wl_surface(), seat, data, key, state, serial, time); - } - FocusTarget::LayerSurface(surf) => { - KeyboardTarget::key(surf.wl_surface(), seat, data, key, state, serial, time); - } - } - } - - fn modifiers( - &self, - seat: &Seat, - data: &mut State, - modifiers: smithay::input::keyboard::ModifiersState, - serial: Serial, - ) { - match self { - FocusTarget::Window(window) => { - KeyboardTarget::modifiers(window, seat, data, modifiers, serial); - } - FocusTarget::Popup(popup) => { - KeyboardTarget::modifiers(popup.wl_surface(), seat, data, modifiers, serial); - } - FocusTarget::LayerSurface(surf) => { - KeyboardTarget::modifiers(surf.wl_surface(), seat, data, modifiers, serial); - } - } - } -} - -impl TouchTarget for FocusTarget { - fn down(&self, seat: &Seat, data: &mut State, event: &touch::DownEvent, seq: Serial) { - todo!() - } - - fn up(&self, seat: &Seat, data: &mut State, event: &touch::UpEvent, seq: Serial) { - todo!() - } - - fn motion( - &self, - seat: &Seat, - data: &mut State, - event: &touch::MotionEvent, - seq: Serial, - ) { - todo!() - } - - fn frame(&self, seat: &Seat, data: &mut State, seq: Serial) { - todo!() - } - - fn cancel(&self, seat: &Seat, data: &mut State, seq: Serial) { - todo!() - } - - fn shape(&self, seat: &Seat, data: &mut State, event: &touch::ShapeEvent, seq: Serial) { - todo!() - } - - fn orientation( - &self, - seat: &Seat, - data: &mut State, - event: &touch::OrientationEvent, - seq: Serial, - ) { - todo!() - } -} - -impl WaylandFocus for FocusTarget { - fn wl_surface(&self) -> Option { - match self { - FocusTarget::Window(window) => window.wl_surface(), - FocusTarget::Popup(popup) => Some(popup.wl_surface().clone()), - FocusTarget::LayerSurface(surf) => Some(surf.wl_surface().clone()), - } - } - - fn same_client_as( - &self, - object_id: &smithay::reexports::wayland_server::backend::ObjectId, - ) -> bool { - match self { - FocusTarget::Window(window) => window.same_client_as(object_id), - FocusTarget::Popup(popup) => popup.wl_surface().id().same_client_as(object_id), - FocusTarget::LayerSurface(surf) => surf.wl_surface().id().same_client_as(object_id), - } - } -} - -impl From for FocusTarget { - fn from(value: WindowElement) -> Self { - FocusTarget::Window(value) - } -} - -impl From for FocusTarget { - fn from(value: PopupKind) -> Self { - FocusTarget::Popup(value) - } -} - -impl From for FocusTarget { - fn from(value: LayerSurface) -> Self { - FocusTarget::LayerSurface(value) - } -} diff --git a/src/focus/keyboard.rs b/src/focus/keyboard.rs new file mode 100644 index 0000000..63363e9 --- /dev/null +++ b/src/focus/keyboard.rs @@ -0,0 +1,230 @@ +use smithay::{ + backend::input::KeyState, + desktop::{LayerSurface, PopupKind, WindowSurface}, + input::{ + keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, + Seat, + }, + reexports::wayland_server::{protocol::wl_surface::WlSurface, Resource}, + utils::{IsAlive, Serial}, + wayland::seat::WaylandFocus, +}; + +use crate::{state::State, window::WindowElement}; + +/// Keyboard focusable objects +#[derive(Debug, Clone, PartialEq)] +pub enum KeyboardFocusTarget { + Window(WindowElement), + Popup(PopupKind), + LayerSurface(LayerSurface), +} + +impl KeyboardTarget for KeyboardFocusTarget { + fn enter( + &self, + seat: &Seat, + data: &mut State, + keys: Vec>, + serial: Serial, + ) { + match self { + KeyboardFocusTarget::Window(window) => { + KeyboardTarget::enter(window, seat, data, keys, serial) + } + KeyboardFocusTarget::Popup(popup) => { + KeyboardTarget::enter(popup.wl_surface(), seat, data, keys, serial); + } + KeyboardFocusTarget::LayerSurface(surf) => { + KeyboardTarget::enter(surf.wl_surface(), seat, data, keys, serial); + } + } + } + + fn leave(&self, seat: &Seat, data: &mut State, serial: Serial) { + match self { + KeyboardFocusTarget::Window(window) => { + KeyboardTarget::leave(window, seat, data, serial) + } + KeyboardFocusTarget::Popup(popup) => { + KeyboardTarget::leave(popup.wl_surface(), seat, data, serial); + } + KeyboardFocusTarget::LayerSurface(surf) => { + KeyboardTarget::leave(surf.wl_surface(), seat, data, serial) + } + } + } + + fn key( + &self, + seat: &Seat, + data: &mut State, + key: KeysymHandle<'_>, + state: smithay::backend::input::KeyState, + serial: Serial, + time: u32, + ) { + match self { + KeyboardFocusTarget::Window(window) => { + KeyboardTarget::key(window, seat, data, key, state, serial, time); + } + KeyboardFocusTarget::Popup(popup) => { + KeyboardTarget::key(popup.wl_surface(), seat, data, key, state, serial, time); + } + KeyboardFocusTarget::LayerSurface(surf) => { + KeyboardTarget::key(surf.wl_surface(), seat, data, key, state, serial, time); + } + } + } + + fn modifiers( + &self, + seat: &Seat, + data: &mut State, + modifiers: smithay::input::keyboard::ModifiersState, + serial: Serial, + ) { + match self { + KeyboardFocusTarget::Window(window) => { + KeyboardTarget::modifiers(window, seat, data, modifiers, serial); + } + KeyboardFocusTarget::Popup(popup) => { + KeyboardTarget::modifiers(popup.wl_surface(), seat, data, modifiers, serial); + } + KeyboardFocusTarget::LayerSurface(surf) => { + KeyboardTarget::modifiers(surf.wl_surface(), seat, data, modifiers, serial); + } + } + } +} + +impl IsAlive for KeyboardFocusTarget { + fn alive(&self) -> bool { + match self { + KeyboardFocusTarget::Window(window) => window.alive(), + KeyboardFocusTarget::Popup(popup) => popup.alive(), + KeyboardFocusTarget::LayerSurface(surf) => surf.alive(), + } + } +} + +impl WaylandFocus for KeyboardFocusTarget { + fn wl_surface(&self) -> Option { + match self { + KeyboardFocusTarget::Window(window) => window.wl_surface(), + KeyboardFocusTarget::Popup(popup) => Some(popup.wl_surface().clone()), + KeyboardFocusTarget::LayerSurface(surf) => Some(surf.wl_surface().clone()), + } + } + + fn same_client_as( + &self, + object_id: &smithay::reexports::wayland_server::backend::ObjectId, + ) -> bool { + match self { + KeyboardFocusTarget::Window(window) => window.same_client_as(object_id), + KeyboardFocusTarget::Popup(popup) => popup.wl_surface().id().same_client_as(object_id), + KeyboardFocusTarget::LayerSurface(surf) => { + surf.wl_surface().id().same_client_as(object_id) + } + } + } +} + +impl TryFrom for WlSurface { + type Error = (); + + fn try_from(value: KeyboardFocusTarget) -> Result { + value.wl_surface().ok_or(()) + } +} + +impl From for KeyboardFocusTarget { + fn from(value: WindowElement) -> Self { + KeyboardFocusTarget::Window(value) + } +} + +impl From for KeyboardFocusTarget { + fn from(value: PopupKind) -> Self { + KeyboardFocusTarget::Popup(value) + } +} + +impl From for KeyboardFocusTarget { + fn from(value: LayerSurface) -> Self { + KeyboardFocusTarget::LayerSurface(value) + } +} + +impl KeyboardTarget for WindowElement { + fn enter( + &self, + seat: &Seat, + state: &mut State, + keys: Vec>, + serial: Serial, + ) { + match self.underlying_surface() { + WindowSurface::Wayland(toplevel) => { + KeyboardTarget::enter(toplevel.wl_surface(), seat, state, keys, serial); + } + WindowSurface::X11(surface) => { + KeyboardTarget::enter(surface, seat, state, keys, serial); + } + } + } + + fn leave(&self, seat: &Seat, state: &mut State, serial: Serial) { + match self.underlying_surface() { + WindowSurface::Wayland(toplevel) => { + KeyboardTarget::leave(toplevel.wl_surface(), seat, state, serial); + } + WindowSurface::X11(surface) => KeyboardTarget::leave(surface, seat, state, serial), + } + } + + fn key( + &self, + seat: &Seat, + state: &mut State, + key: KeysymHandle<'_>, + key_state: KeyState, + serial: Serial, + time: u32, + ) { + match self.underlying_surface() { + WindowSurface::Wayland(toplevel) => { + KeyboardTarget::key( + toplevel.wl_surface(), + seat, + state, + key, + key_state, + serial, + time, + ); + } + WindowSurface::X11(surface) => { + KeyboardTarget::key(surface, seat, state, key, key_state, serial, time); + } + } + } + + fn modifiers( + &self, + seat: &Seat, + state: &mut State, + modifiers: ModifiersState, + serial: Serial, + ) { + match self.underlying_surface() { + WindowSurface::Wayland(toplevel) => { + KeyboardTarget::modifiers(toplevel.wl_surface(), seat, state, modifiers, serial); + } + WindowSurface::X11(surface) => { + KeyboardTarget::modifiers(surface, seat, state, modifiers, serial); + } + } + } +} diff --git a/src/focus/pointer.rs b/src/focus/pointer.rs new file mode 100644 index 0000000..b507782 --- /dev/null +++ b/src/focus/pointer.rs @@ -0,0 +1,428 @@ +use pinnacle_api_defs::pinnacle::signal::v0alpha1::{ + WindowPointerEnterResponse, WindowPointerLeaveResponse, +}; +use smithay::{ + desktop::{ + layer_map_for_output, utils::with_surfaces_surface_tree, LayerSurface, PopupKind, + WindowSurface, + }, + input::{ + pointer::{self, PointerTarget}, + touch::{self, TouchTarget}, + Seat, + }, + reexports::wayland_server::{backend::ObjectId, protocol::wl_surface::WlSurface}, + utils::{IsAlive, Serial}, + wayland::seat::WaylandFocus, + xwayland::X11Surface, +}; + +use crate::{ + state::{State, WithState}, + window::WindowElement, +}; + +use super::keyboard::KeyboardFocusTarget; + +#[derive(Debug, Clone, PartialEq)] +pub enum PointerFocusTarget { + WlSurface(WlSurface), + X11Surface(X11Surface), +} + +impl PointerFocusTarget { + /// If the pointer focus's surface is owned by a window, get that window. + pub fn window_for(&self, state: &State) -> Option { + match self { + PointerFocusTarget::WlSurface(surf) => state + .windows + .iter() + .find(|win| { + let Some(surface) = win.wl_surface() else { + return false; + }; + let mut found = false; + with_surfaces_surface_tree(&surface, |surface, _| { + if surface == surf { + found = true; + } + }); + found + }) + .cloned(), + PointerFocusTarget::X11Surface(surf) => state + .windows + .iter() + .find(|win| win.x11_surface() == Some(surf)) + .cloned(), + } + } + + pub fn layer_for(&self, state: &State) -> Option { + match self { + PointerFocusTarget::WlSurface(surf) => { + for output in state.space.outputs() { + let map = layer_map_for_output(output); + for layer in map.layers() { + let mut found = false; + with_surfaces_surface_tree(layer.wl_surface(), |surface, _| { + if surface == surf { + found = true; + } + }); + if found { + return Some(layer.clone()); + } + } + } + None + } + PointerFocusTarget::X11Surface(_) => None, + } + } + + pub fn popup_for(&self, state: &State) -> Option { + match self { + PointerFocusTarget::WlSurface(surf) => state.popup_manager.find_popup(surf), + PointerFocusTarget::X11Surface(_) => None, + } + } + + pub fn to_keyboard_focus_target(&self, state: &State) -> Option { + #[allow(clippy::manual_map)] // screw off clippy + if let Some(window) = self.window_for(state) { + Some(KeyboardFocusTarget::Window(window)) + } else if let Some(layer) = self.layer_for(state) { + Some(KeyboardFocusTarget::LayerSurface(layer)) + } else if let Some(popup) = self.popup_for(state) { + Some(KeyboardFocusTarget::Popup(popup)) + } else { + None + } + } +} + +impl IsAlive for PointerFocusTarget { + fn alive(&self) -> bool { + match self { + PointerFocusTarget::WlSurface(surf) => surf.alive(), + PointerFocusTarget::X11Surface(surf) => surf.alive(), + } + } +} + +impl PointerTarget for PointerFocusTarget { + fn enter(&self, seat: &Seat, data: &mut State, event: &pointer::MotionEvent) { + match self { + PointerFocusTarget::WlSurface(surf) => PointerTarget::enter(surf, seat, data, event), + PointerFocusTarget::X11Surface(surf) => PointerTarget::enter(surf, seat, data, event), + } + + if let Some(window) = self.window_for(data) { + let window_id = Some(window.with_state(|state| state.id.0)); + + data.signal_state + .window_pointer_enter + .signal(|buffer| buffer.push_back(WindowPointerEnterResponse { window_id })); + } + } + + fn motion(&self, seat: &Seat, data: &mut State, event: &pointer::MotionEvent) { + match self { + PointerFocusTarget::WlSurface(surf) => PointerTarget::motion(surf, seat, data, event), + PointerFocusTarget::X11Surface(surf) => PointerTarget::motion(surf, seat, data, event), + } + } + + fn relative_motion( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::RelativeMotionEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::relative_motion(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::relative_motion(surf, seat, data, event); + } + } + } + + fn button(&self, seat: &Seat, data: &mut State, event: &pointer::ButtonEvent) { + match self { + PointerFocusTarget::WlSurface(surf) => PointerTarget::button(surf, seat, data, event), + PointerFocusTarget::X11Surface(surf) => PointerTarget::button(surf, seat, data, event), + } + } + + fn axis(&self, seat: &Seat, data: &mut State, frame: pointer::AxisFrame) { + match self { + PointerFocusTarget::WlSurface(surf) => PointerTarget::axis(surf, seat, data, frame), + PointerFocusTarget::X11Surface(surf) => PointerTarget::axis(surf, seat, data, frame), + } + } + + fn frame(&self, seat: &Seat, data: &mut State) { + match self { + PointerFocusTarget::WlSurface(surf) => PointerTarget::frame(surf, seat, data), + PointerFocusTarget::X11Surface(surf) => PointerTarget::frame(surf, seat, data), + } + } + + fn gesture_swipe_begin( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GestureSwipeBeginEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_swipe_begin(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_swipe_begin(surf, seat, data, event); + } + } + } + + fn gesture_swipe_update( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GestureSwipeUpdateEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_swipe_update(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_swipe_update(surf, seat, data, event); + } + } + } + + fn gesture_swipe_end( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GestureSwipeEndEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_swipe_end(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_swipe_end(surf, seat, data, event); + } + } + } + + fn gesture_pinch_begin( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GesturePinchBeginEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_pinch_begin(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_pinch_begin(surf, seat, data, event); + } + } + } + + fn gesture_pinch_update( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GesturePinchUpdateEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_pinch_update(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_pinch_update(surf, seat, data, event); + } + } + } + + fn gesture_pinch_end( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GesturePinchEndEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_pinch_end(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_pinch_end(surf, seat, data, event); + } + } + } + + fn gesture_hold_begin( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GestureHoldBeginEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_hold_begin(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_hold_begin(surf, seat, data, event); + } + } + } + + fn gesture_hold_end( + &self, + seat: &Seat, + data: &mut State, + event: &pointer::GestureHoldEndEvent, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::gesture_hold_end(surf, seat, data, event); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::gesture_hold_end(surf, seat, data, event); + } + } + } + + fn leave(&self, seat: &Seat, data: &mut State, serial: Serial, time: u32) { + match self { + PointerFocusTarget::WlSurface(surf) => { + PointerTarget::leave(surf, seat, data, serial, time); + } + PointerFocusTarget::X11Surface(surf) => { + PointerTarget::leave(surf, seat, data, serial, time); + } + } + + if let Some(window) = self.window_for(data) { + let window_id = Some(window.with_state(|state| state.id.0)); + + data.signal_state + .window_pointer_leave + .signal(|buffer| buffer.push_back(WindowPointerLeaveResponse { window_id })); + } + } +} + +impl TouchTarget for PointerFocusTarget { + fn down(&self, seat: &Seat, data: &mut State, event: &touch::DownEvent, seq: Serial) { + match self { + PointerFocusTarget::WlSurface(surf) => TouchTarget::down(surf, seat, data, event, seq), + PointerFocusTarget::X11Surface(surf) => TouchTarget::down(surf, seat, data, event, seq), + } + } + + fn up(&self, seat: &Seat, data: &mut State, event: &touch::UpEvent, seq: Serial) { + match self { + PointerFocusTarget::WlSurface(surf) => TouchTarget::up(surf, seat, data, event, seq), + PointerFocusTarget::X11Surface(surf) => TouchTarget::up(surf, seat, data, event, seq), + } + } + + fn motion( + &self, + seat: &Seat, + data: &mut State, + event: &touch::MotionEvent, + seq: Serial, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + TouchTarget::motion(surf, seat, data, event, seq); + } + PointerFocusTarget::X11Surface(surf) => { + TouchTarget::motion(surf, seat, data, event, seq); + } + } + } + + fn frame(&self, seat: &Seat, data: &mut State, seq: Serial) { + match self { + PointerFocusTarget::WlSurface(surf) => TouchTarget::frame(surf, seat, data, seq), + PointerFocusTarget::X11Surface(surf) => TouchTarget::frame(surf, seat, data, seq), + } + } + + fn cancel(&self, seat: &Seat, data: &mut State, seq: Serial) { + match self { + PointerFocusTarget::WlSurface(surf) => TouchTarget::cancel(surf, seat, data, seq), + PointerFocusTarget::X11Surface(surf) => TouchTarget::cancel(surf, seat, data, seq), + } + } + + fn shape(&self, seat: &Seat, data: &mut State, event: &touch::ShapeEvent, seq: Serial) { + match self { + PointerFocusTarget::WlSurface(surf) => TouchTarget::shape(surf, seat, data, event, seq), + PointerFocusTarget::X11Surface(surf) => { + TouchTarget::shape(surf, seat, data, event, seq); + } + } + } + + fn orientation( + &self, + seat: &Seat, + data: &mut State, + event: &touch::OrientationEvent, + seq: Serial, + ) { + match self { + PointerFocusTarget::WlSurface(surf) => { + TouchTarget::orientation(surf, seat, data, event, seq); + } + PointerFocusTarget::X11Surface(surf) => { + TouchTarget::orientation(surf, seat, data, event, seq); + } + } + } +} + +impl WaylandFocus for PointerFocusTarget { + fn wl_surface(&self) -> Option { + match self { + PointerFocusTarget::WlSurface(surf) => Some(surf.clone()), + PointerFocusTarget::X11Surface(surf) => surf.wl_surface(), + } + } + + fn same_client_as(&self, object_id: &ObjectId) -> bool { + match self { + PointerFocusTarget::WlSurface(surf) => surf.same_client_as(object_id), + PointerFocusTarget::X11Surface(surf) => surf.same_client_as(object_id), + } + } +} + +impl From for PointerFocusTarget { + fn from(target: KeyboardFocusTarget) -> Self { + match target { + KeyboardFocusTarget::Window(window) => match window.underlying_surface() { + WindowSurface::Wayland(toplevel) => { + PointerFocusTarget::WlSurface(toplevel.wl_surface().clone()) + } + WindowSurface::X11(surface) => PointerFocusTarget::X11Surface(surface.clone()), + }, + KeyboardFocusTarget::Popup(popup) => { + PointerFocusTarget::WlSurface(popup.wl_surface().clone()) + } + KeyboardFocusTarget::LayerSurface(layer) => { + PointerFocusTarget::WlSurface(layer.wl_surface().clone()) + } + } + } +} diff --git a/src/grab.rs b/src/grab.rs index 2aa97f5..4cd5117 100644 --- a/src/grab.rs +++ b/src/grab.rs @@ -4,26 +4,20 @@ pub mod move_grab; pub mod resize_grab; use smithay::{ - input::{ - pointer::{GrabStartData, PointerHandle}, - SeatHandler, - }, + input::pointer::{GrabStartData, PointerHandle}, reexports::wayland_server::{protocol::wl_surface::WlSurface, Resource}, utils::Serial, wayland::seat::WaylandFocus, }; -use crate::focus::FocusTarget; +use crate::state::State; /// Returns the [GrabStartData] from a pointer grab, if any. -pub fn pointer_grab_start_data( - pointer: &PointerHandle, +pub fn pointer_grab_start_data( + pointer: &PointerHandle, surface: &WlSurface, serial: Serial, -) -> Option> -where - S: SeatHandler + 'static, -{ +) -> Option> { tracing::debug!("start of pointer_grab_start_data"); if !pointer.has_grab(serial) { tracing::debug!("pointer doesn't have grab"); diff --git a/src/grab/move_grab.rs b/src/grab/move_grab.rs index 579b767..5aa2aa2 100644 --- a/src/grab/move_grab.rs +++ b/src/grab/move_grab.rs @@ -6,14 +6,13 @@ use smithay::{ // | input::keyboard input::{ pointer::{ - AxisFrame, ButtonEvent, GrabStartData, MotionEvent, PointerInnerHandle, - RelativeMotionEvent, + AxisFrame, ButtonEvent, Focus, GrabStartData, MotionEvent, PointerGrab, + PointerInnerHandle, RelativeMotionEvent, }, - pointer::{Focus, PointerGrab}, Seat, SeatHandler, }, reexports::wayland_server::protocol::wl_surface::WlSurface, - utils::{IsAlive, Logical, Point, Rectangle}, + utils::{IsAlive, Logical, Point, Rectangle, Serial}, }; use crate::{ @@ -270,7 +269,7 @@ pub fn move_request_client( state: &mut State, surface: &WlSurface, seat: &Seat, - serial: smithay::utils::Serial, + serial: Serial, button_used: u32, ) { let pointer = seat.get_pointer().expect("seat had no pointer"); @@ -303,7 +302,7 @@ pub fn move_request_server( state: &mut State, surface: &WlSurface, seat: &Seat, - serial: smithay::utils::Serial, + serial: Serial, button_used: u32, ) { let pointer = seat.get_pointer().expect("seat had no pointer"); diff --git a/src/grab/resize_grab.rs b/src/grab/resize_grab.rs index 09d9552..3516e0f 100644 --- a/src/grab/resize_grab.rs +++ b/src/grab/resize_grab.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later use smithay::{ - desktop::{space::SpaceElement, utils::bbox_from_surface_tree, WindowSurface}, + desktop::{space::SpaceElement, WindowSurface}, input::{ pointer::{AxisFrame, ButtonEvent, Focus, GrabStartData, PointerGrab, PointerInnerHandle}, Seat, SeatHandler, diff --git a/src/handlers.rs b/src/handlers.rs index e7177f2..1f5903a 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -58,7 +58,7 @@ use smithay::{ }; use crate::{ - focus::FocusTarget, + focus::{keyboard::KeyboardFocusTarget, pointer::PointerFocusTarget}, state::{ClientState, State, WithState}, }; @@ -176,7 +176,7 @@ impl CompositorHandler for State { .expect("Seat had no keyboard") // FIXME: actually handle error .set_focus( state, - Some(FocusTarget::Window(new_window)), + Some(KeyboardFocusTarget::Window(new_window)), SERIAL_COUNTER.next_serial(), ); }); @@ -394,9 +394,9 @@ impl DataControlHandler for State { delegate_data_control!(State); impl SeatHandler for State { - type KeyboardFocus = FocusTarget; - type PointerFocus = FocusTarget; - type TouchFocus = FocusTarget; + type KeyboardFocus = KeyboardFocusTarget; + type PointerFocus = PointerFocusTarget; + type TouchFocus = PointerFocusTarget; fn seat_state(&mut self) -> &mut SeatState { &mut self.seat_state diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index c0dd80a..e9714e9 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -26,7 +26,7 @@ use smithay::{ }; use crate::{ - focus::FocusTarget, + focus::keyboard::KeyboardFocusTarget, state::{State, WithState}, window::WindowElement, }; @@ -78,8 +78,10 @@ impl XdgShellHandler for State { if let Some(output) = window.output(self) { self.update_windows(&output); - let focus = self.focused_window(&output).map(FocusTarget::Window); - if let Some(FocusTarget::Window(win)) = &focus { + let focus = self + .focused_window(&output) + .map(KeyboardFocusTarget::Window); + if let Some(KeyboardFocusTarget::Window(win)) = &focus { tracing::debug!("Focusing on prev win"); // TODO: self.space.raise_element(win, true); @@ -638,13 +640,13 @@ impl XdgShellHandler for State { let popup_kind = PopupKind::Xdg(surface); if let Some(root) = find_popup_root_surface(&popup_kind).ok().and_then(|root| { self.window_for_surface(&root) - .map(FocusTarget::Window) + .map(KeyboardFocusTarget::Window) .or_else(|| { self.space.outputs().find_map(|op| { layer_map_for_output(op) .layer_for_surface(&root, WindowSurfaceType::TOPLEVEL) .cloned() - .map(FocusTarget::LayerSurface) + .map(KeyboardFocusTarget::LayerSurface) }) }) }) { diff --git a/src/handlers/xwayland.rs b/src/handlers/xwayland.rs index 37f4c78..04ef4b2 100644 --- a/src/handlers/xwayland.rs +++ b/src/handlers/xwayland.rs @@ -24,7 +24,7 @@ use smithay::{ }; use crate::{ - focus::FocusTarget, + focus::keyboard::KeyboardFocusTarget, state::{State, WithState}, window::{window_state::FloatingOrTiled, WindowElement}, }; @@ -118,7 +118,7 @@ impl XwmHandler for State { .expect("Seat had no keyboard") // FIXME: actually handle error .set_focus( state, - Some(FocusTarget::Window(window)), + Some(KeyboardFocusTarget::Window(window)), SERIAL_COUNTER.next_serial(), ); }); @@ -177,9 +177,11 @@ impl XwmHandler for State { if let Some(output) = win.output(self) { self.update_windows(&output); - let focus = self.focused_window(&output).map(FocusTarget::Window); + let focus = self + .focused_window(&output) + .map(KeyboardFocusTarget::Window); - if let Some(FocusTarget::Window(win)) = &focus { + if let Some(KeyboardFocusTarget::Window(win)) = &focus { self.space.raise_element(win, true); self.z_index_stack.set_focus(win.clone()); if let Some(toplevel) = win.toplevel() { @@ -238,9 +240,11 @@ impl XwmHandler for State { if let Some(output) = win.output(self) { self.update_windows(&output); - let focus = self.focused_window(&output).map(FocusTarget::Window); + let focus = self + .focused_window(&output) + .map(KeyboardFocusTarget::Window); - if let Some(FocusTarget::Window(win)) = &focus { + if let Some(KeyboardFocusTarget::Window(win)) = &focus { self.space.raise_element(win, true); self.z_index_stack.set_focus(win.clone()); if let Some(toplevel) = win.toplevel() { @@ -411,7 +415,7 @@ impl XwmHandler for State { .get_keyboard() .and_then(|kb| kb.current_focus()) .is_some_and(|focus| { - if let FocusTarget::Window(window) = focus { + if let KeyboardFocusTarget::Window(window) = focus { if let Some(surface) = window.x11_surface() { return surface.xwm_id().expect("x11surface had no xwm id") == xwm; } diff --git a/src/input.rs b/src/input.rs index d669aff..e8a1fb4 100644 --- a/src/input.rs +++ b/src/input.rs @@ -4,7 +4,7 @@ pub mod libinput; use std::{collections::HashMap, mem::Discriminant}; -use crate::{focus::FocusTarget, state::WithState}; +use crate::{focus::pointer::PointerFocusTarget, state::WithState}; use pinnacle_api_defs::pinnacle::input::v0alpha1::{ set_libinput_setting_request::Setting, set_mousebind_request, SetKeybindResponse, SetMousebindResponse, @@ -14,7 +14,7 @@ use smithay::{ AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent, }, - desktop::{layer_map_for_output, space::SpaceElement}, + desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType}, input::{ keyboard::{keysyms, FilterResult, ModifiersState}, pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent}, @@ -148,8 +148,11 @@ impl State { } } - /// Get the [`FocusTarget`] under `point`. - pub fn focus_target_under

(&self, point: P) -> Option<(FocusTarget, Point)> + /// Get the [`PointerFocusTarget`] under `point` along with its origin in the global space. + pub fn pointer_focus_target_under

( + &self, + point: P, + ) -> Option<(PointerFocusTarget, Point)> where P: Into>, { @@ -185,14 +188,33 @@ impl State { }); if let Some(window) = top_fullscreen_window { - Some((FocusTarget::from(window.clone()), output_geo.loc)) + let loc = self + .space + .element_location(&window) + .expect("called elem loc on unmapped win") + - window.geometry().loc; + + window + .surface_under(point - loc.to_f64(), WindowSurfaceType::ALL) + .map(|(surf, surf_loc)| (PointerFocusTarget::WlSurface(surf), surf_loc + loc)) } else if let (Some(layer), _) | (None, Some(layer)) = ( layers.layer_under(wlr_layer::Layer::Overlay, point), layers.layer_under(wlr_layer::Layer::Top, point), ) { let layer_loc = layers.layer_geometry(layer).expect("no layer geo").loc; - Some((FocusTarget::from(layer.clone()), output_geo.loc + layer_loc)) - } else if let Some(ret) = self + + layer + .surface_under( + point - layer_loc.to_f64() - output_geo.loc.to_f64(), + WindowSurfaceType::ALL, + ) + .map(|(surf, surf_loc)| { + ( + PointerFocusTarget::WlSurface(surf), + surf_loc + layer_loc + output_geo.loc, + ) + }) + } else if let Some((surface, loc)) = self .space .elements() .rev() @@ -204,17 +226,28 @@ impl State { .expect("called elem loc on unmapped win") - win.geometry().loc; - win.is_in_input_region(&(point - loc.to_f64())) - .then(|| (win.clone().into(), loc)) + win.surface_under(point - loc.to_f64(), WindowSurfaceType::ALL) + .map(|(surf, surf_loc)| (surf, surf_loc + loc)) }) { - Some(ret) + Some((PointerFocusTarget::WlSurface(surface), loc)) } else if let (Some(layer), _) | (None, Some(layer)) = ( layers.layer_under(wlr_layer::Layer::Overlay, point), layers.layer_under(wlr_layer::Layer::Top, point), ) { let layer_loc = layers.layer_geometry(layer).expect("no layer geo").loc; - Some((FocusTarget::from(layer.clone()), output_geo.loc + layer_loc)) + + layer + .surface_under( + point - layer_loc.to_f64() - output_geo.loc.to_f64(), + WindowSurfaceType::ALL, + ) + .map(|(surf, surf_loc)| { + ( + PointerFocusTarget::WlSurface(surf), + surf_loc + layer_loc + output_geo.loc, + ) + }) } else { None } @@ -334,15 +367,15 @@ impl State { // If the button was clicked, focus on the window below if exists, else // unfocus on windows. if button_state == ButtonState::Pressed { - if let Some((focus, _)) = self.focus_target_under(pointer_loc) { + if let Some((focus, _)) = self.pointer_focus_target_under(pointer_loc) { // NOTE: *Do not* set keyboard focus to an override redirect window. This leads // | to wonky things like right-click menus not correctly getting pointer // | clicks or showing up at all. // TODO: use update_keyboard_focus from anvil - if let FocusTarget::Window(window) = &focus { - self.space.raise_element(window, true); + if let Some(window) = focus.window_for(self) { + self.space.raise_element(&window, true); self.z_index_stack.set_focus(window.clone()); if let Some(output) = window.output(self) { output.with_state(|state| state.focus_stack.set_focus(window.clone())); @@ -350,10 +383,10 @@ impl State { } if !matches!( - &focus, - FocusTarget::Window(window) if window.is_x11_override_redirect() + focus.window_for(self), + Some(window) if window.is_x11_override_redirect() ) { - keyboard.set_focus(self, Some(focus.clone()), serial); + keyboard.set_focus(self, focus.to_keyboard_focus_target(self), serial); } for window in self.space.elements() { @@ -496,7 +529,7 @@ impl State { pointer.motion( self, - self.focus_target_under(pointer_loc), + self.pointer_focus_target_under(pointer_loc), &MotionEvent { location: pointer_loc, serial, @@ -533,7 +566,7 @@ impl State { } } - let surface_under = self.focus_target_under(self.pointer_location); + let surface_under = self.pointer_focus_target_under(self.pointer_location); if let Some(pointer) = self.seat.get_pointer() { pointer.motion( diff --git a/src/window.rs b/src/window.rs index 149cee6..78554a7 100644 --- a/src/window.rs +++ b/src/window.rs @@ -4,20 +4,11 @@ pub mod rules; use std::{cell::RefCell, ops::Deref}; -use pinnacle_api_defs::pinnacle::signal::v0alpha1::{ - WindowPointerEnterResponse, WindowPointerLeaveResponse, -}; use smithay::{ - backend::input::KeyState, desktop::{space::SpaceElement, Window, WindowSurface}, - input::{ - keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, - pointer::{AxisFrame, MotionEvent, PointerTarget}, - Seat, - }, output::Output, reexports::wayland_server::protocol::wl_surface::WlSurface, - utils::{IsAlive, Logical, Point, Rectangle, Serial}, + utils::{IsAlive, Logical, Point, Rectangle}, wayland::{compositor, seat::WaylandFocus, shell::xdg::XdgToplevelSurfaceData}, }; @@ -202,241 +193,6 @@ impl IsAlive for WindowElement { } } -impl PointerTarget for WindowElement { - fn frame(&self, seat: &Seat, state: &mut State) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::frame(toplevel.wl_surface(), seat, state); - } - WindowSurface::X11(surface) => PointerTarget::frame(surface, seat, state), - } - } - - fn enter(&self, seat: &Seat, state: &mut State, event: &MotionEvent) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::enter(toplevel.wl_surface(), seat, state, event); - } - WindowSurface::X11(surface) => PointerTarget::enter(surface, seat, state, event), - } - - let window_id = Some(self.with_state(|state| state.id.0)); - - state - .signal_state - .window_pointer_enter - .signal(|buffer| buffer.push_back(WindowPointerEnterResponse { window_id })); - } - - fn motion(&self, seat: &Seat, state: &mut State, event: &MotionEvent) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::motion(toplevel.wl_surface(), seat, state, event); - } - WindowSurface::X11(surface) => PointerTarget::motion(surface, seat, state, event), - } - } - - fn relative_motion( - &self, - seat: &Seat, - state: &mut State, - event: &smithay::input::pointer::RelativeMotionEvent, - ) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::relative_motion(toplevel.wl_surface(), seat, state, event); - } - WindowSurface::X11(surface) => { - PointerTarget::relative_motion(surface, seat, state, event); - } - } - } - - fn button( - &self, - seat: &Seat, - state: &mut State, - event: &smithay::input::pointer::ButtonEvent, - ) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::button(toplevel.wl_surface(), seat, state, event); - } - WindowSurface::X11(surface) => PointerTarget::button(surface, seat, state, event), - } - } - - fn axis(&self, seat: &Seat, state: &mut State, frame: AxisFrame) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::axis(toplevel.wl_surface(), seat, state, frame); - } - WindowSurface::X11(surface) => PointerTarget::axis(surface, seat, state, frame), - } - } - - fn leave(&self, seat: &Seat, state: &mut State, serial: Serial, time: u32) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - PointerTarget::leave(toplevel.wl_surface(), seat, state, serial, time); - } - WindowSurface::X11(surface) => PointerTarget::leave(surface, seat, state, serial, time), - } - - let window_id = Some(self.with_state(|state| state.id.0)); - - state - .signal_state - .window_pointer_leave - .signal(|buffer| buffer.push_back(WindowPointerLeaveResponse { window_id })); - } - - fn gesture_swipe_begin( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GestureSwipeBeginEvent, - ) { - todo!() - } - - fn gesture_swipe_update( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GestureSwipeUpdateEvent, - ) { - todo!() - } - - fn gesture_swipe_end( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GestureSwipeEndEvent, - ) { - todo!() - } - - fn gesture_pinch_begin( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GesturePinchBeginEvent, - ) { - todo!() - } - - fn gesture_pinch_update( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GesturePinchUpdateEvent, - ) { - todo!() - } - - fn gesture_pinch_end( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GesturePinchEndEvent, - ) { - todo!() - } - - fn gesture_hold_begin( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GestureHoldBeginEvent, - ) { - todo!() - } - - fn gesture_hold_end( - &self, - _seat: &Seat, - _state: &mut State, - _event: &smithay::input::pointer::GestureHoldEndEvent, - ) { - todo!() - } -} - -impl KeyboardTarget for WindowElement { - fn enter( - &self, - seat: &Seat, - state: &mut State, - keys: Vec>, - serial: Serial, - ) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - KeyboardTarget::enter(toplevel.wl_surface(), seat, state, keys, serial); - } - WindowSurface::X11(surface) => { - KeyboardTarget::enter(surface, seat, state, keys, serial); - } - } - } - - fn leave(&self, seat: &Seat, state: &mut State, serial: Serial) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - KeyboardTarget::leave(toplevel.wl_surface(), seat, state, serial); - } - WindowSurface::X11(surface) => KeyboardTarget::leave(surface, seat, state, serial), - } - } - - fn key( - &self, - seat: &Seat, - state: &mut State, - key: KeysymHandle<'_>, - key_state: KeyState, - serial: Serial, - time: u32, - ) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - KeyboardTarget::key( - toplevel.wl_surface(), - seat, - state, - key, - key_state, - serial, - time, - ); - } - WindowSurface::X11(surface) => { - KeyboardTarget::key(surface, seat, state, key, key_state, serial, time); - } - } - } - - fn modifiers( - &self, - seat: &Seat, - state: &mut State, - modifiers: ModifiersState, - serial: Serial, - ) { - match self.underlying_surface() { - WindowSurface::Wayland(toplevel) => { - KeyboardTarget::modifiers(toplevel.wl_surface(), seat, state, modifiers, serial); - } - WindowSurface::X11(surface) => { - KeyboardTarget::modifiers(surface, seat, state, modifiers, serial); - } - } - } -} - impl WithState for WindowElement { type State = WindowElementState;