Split FocusTarget into keyboard and pointer variants

This commit is contained in:
Ottatop 2024-03-01 00:07:01 -06:00
parent 48cd3d0df9
commit 8c429f4077
12 changed files with 768 additions and 671 deletions

View file

@ -52,7 +52,7 @@ use tracing::{error, warn};
use crate::{ use crate::{
config::ConnectorSavedState, config::ConnectorSavedState,
focus::FocusTarget, focus::keyboard::KeyboardFocusTarget,
input::ModifierMask, input::ModifierMask,
output::OutputName, output::OutputName,
state::{State, WithState}, state::{State, WithState},
@ -1379,7 +1379,7 @@ impl window_service_server::WindowService for WindowService {
if let Some(keyboard) = state.seat.get_keyboard() { if let Some(keyboard) = state.seat.get_keyboard() {
keyboard.set_focus( keyboard.set_focus(
state, state,
Some(FocusTarget::Window(window)), Some(KeyboardFocusTarget::Window(window)),
SERIAL_COUNTER.next_serial(), SERIAL_COUNTER.next_serial(),
); );
} }
@ -1407,7 +1407,7 @@ impl window_service_server::WindowService for WindowService {
if let Some(keyboard) = state.seat.get_keyboard() { if let Some(keyboard) = state.seat.get_keyboard() {
keyboard.set_focus( keyboard.set_focus(
state, state,
Some(FocusTarget::Window(window)), Some(KeyboardFocusTarget::Window(window)),
SERIAL_COUNTER.next_serial(), SERIAL_COUNTER.next_serial(),
); );
} }
@ -1518,12 +1518,17 @@ impl window_service_server::WindowService for WindowService {
.ok_or_else(|| Status::invalid_argument("no button specified"))?; .ok_or_else(|| Status::invalid_argument("no button specified"))?;
run_unary_no_response(&self.sender, move |state| { run_unary_no_response(&self.sender, move |state| {
let Some((FocusTarget::Window(window), _)) = let Some((pointer_focus, _)) = state.pointer_focus_target_under(state.pointer_location)
state.focus_target_under(state.pointer_location)
else { else {
return; 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(); let seat = state.seat.clone();
crate::grab::move_grab::move_request_server( 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| { run_unary_no_response(&self.sender, move |state| {
let pointer_loc = state.pointer_location; let pointer_loc = state.pointer_location;
let Some((FocusTarget::Window(window), window_loc)) = let Some((pointer_focus, window_loc)) = state.pointer_focus_target_under(pointer_loc)
state.focus_target_under(pointer_loc)
else { else {
return; 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_geometry = window.geometry();
let window_x = window_loc.x as f64; let window_x = window_loc.x as f64;

View file

@ -1,24 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use smithay::{ use smithay::{output::Output, utils::SERIAL_COUNTER};
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 crate::{ use crate::{
state::{State, WithState}, state::{State, WithState},
window::WindowElement, window::WindowElement,
}; };
pub mod keyboard;
pub mod pointer;
impl State { impl State {
/// Get the currently focused window on `output` /// Get the currently focused window on `output`
/// that isn't an override redirect window, if any. /// that isn't an override redirect window, if any.
@ -111,353 +102,3 @@ impl<T: PartialEq> FocusStack<T> {
self.focused.then(|| self.stack.last())? 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<FocusTarget> for WlSurface {
type Error = ();
fn try_from(value: FocusTarget) -> Result<Self, Self::Error> {
value.wl_surface().ok_or(())
}
}
impl PointerTarget<State> for FocusTarget {
fn frame(&self, seat: &Seat<State>, 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<State>, 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<State>, 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<State>,
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<State>,
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<State>,
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<State>, 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<State>,
_data: &mut State,
_event: &smithay::input::pointer::GestureSwipeBeginEvent,
) {
todo!()
}
fn gesture_swipe_update(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GestureSwipeUpdateEvent,
) {
todo!()
}
fn gesture_swipe_end(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GestureSwipeEndEvent,
) {
todo!()
}
fn gesture_pinch_begin(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GesturePinchBeginEvent,
) {
todo!()
}
fn gesture_pinch_update(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GesturePinchUpdateEvent,
) {
todo!()
}
fn gesture_pinch_end(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GesturePinchEndEvent,
) {
todo!()
}
fn gesture_hold_begin(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GestureHoldBeginEvent,
) {
todo!()
}
fn gesture_hold_end(
&self,
_seat: &Seat<State>,
_data: &mut State,
_event: &smithay::input::pointer::GestureHoldEndEvent,
) {
todo!()
}
}
impl KeyboardTarget<State> for FocusTarget {
fn enter(
&self,
seat: &Seat<State>,
data: &mut State,
keys: Vec<smithay::input::keyboard::KeysymHandle<'_>>,
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<State>, 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<State>,
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<State>,
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<State> for FocusTarget {
fn down(&self, seat: &Seat<State>, data: &mut State, event: &touch::DownEvent, seq: Serial) {
todo!()
}
fn up(&self, seat: &Seat<State>, data: &mut State, event: &touch::UpEvent, seq: Serial) {
todo!()
}
fn motion(
&self,
seat: &Seat<State>,
data: &mut State,
event: &touch::MotionEvent,
seq: Serial,
) {
todo!()
}
fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {
todo!()
}
fn cancel(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {
todo!()
}
fn shape(&self, seat: &Seat<State>, data: &mut State, event: &touch::ShapeEvent, seq: Serial) {
todo!()
}
fn orientation(
&self,
seat: &Seat<State>,
data: &mut State,
event: &touch::OrientationEvent,
seq: Serial,
) {
todo!()
}
}
impl WaylandFocus for FocusTarget {
fn wl_surface(&self) -> Option<WlSurface> {
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<WindowElement> for FocusTarget {
fn from(value: WindowElement) -> Self {
FocusTarget::Window(value)
}
}
impl From<PopupKind> for FocusTarget {
fn from(value: PopupKind) -> Self {
FocusTarget::Popup(value)
}
}
impl From<LayerSurface> for FocusTarget {
fn from(value: LayerSurface) -> Self {
FocusTarget::LayerSurface(value)
}
}

230
src/focus/keyboard.rs Normal file
View file

@ -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<State> for KeyboardFocusTarget {
fn enter(
&self,
seat: &Seat<State>,
data: &mut State,
keys: Vec<KeysymHandle<'_>>,
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<State>, 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<State>,
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<State>,
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<WlSurface> {
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<KeyboardFocusTarget> for WlSurface {
type Error = ();
fn try_from(value: KeyboardFocusTarget) -> Result<Self, Self::Error> {
value.wl_surface().ok_or(())
}
}
impl From<WindowElement> for KeyboardFocusTarget {
fn from(value: WindowElement) -> Self {
KeyboardFocusTarget::Window(value)
}
}
impl From<PopupKind> for KeyboardFocusTarget {
fn from(value: PopupKind) -> Self {
KeyboardFocusTarget::Popup(value)
}
}
impl From<LayerSurface> for KeyboardFocusTarget {
fn from(value: LayerSurface) -> Self {
KeyboardFocusTarget::LayerSurface(value)
}
}
impl KeyboardTarget<State> for WindowElement {
fn enter(
&self,
seat: &Seat<State>,
state: &mut State,
keys: Vec<KeysymHandle<'_>>,
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>, 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>,
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>,
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);
}
}
}
}

428
src/focus/pointer.rs Normal file
View file

@ -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<WindowElement> {
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<LayerSurface> {
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<PopupKind> {
match self {
PointerFocusTarget::WlSurface(surf) => state.popup_manager.find_popup(surf),
PointerFocusTarget::X11Surface(_) => None,
}
}
pub fn to_keyboard_focus_target(&self, state: &State) -> Option<KeyboardFocusTarget> {
#[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<State> for PointerFocusTarget {
fn enter(&self, seat: &Seat<State>, 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<State>, 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<State>,
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<State>, 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<State>, 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<State>, 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<State>,
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<State>,
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<State>,
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<State>,
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<State>,
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<State>,
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<State>,
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<State>,
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<State>, 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<State> for PointerFocusTarget {
fn down(&self, seat: &Seat<State>, 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<State>, 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<State>,
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<State>, 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<State>, 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<State>, 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<State>,
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<WlSurface> {
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<KeyboardFocusTarget> 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())
}
}
}
}

View file

@ -4,26 +4,20 @@ pub mod move_grab;
pub mod resize_grab; pub mod resize_grab;
use smithay::{ use smithay::{
input::{ input::pointer::{GrabStartData, PointerHandle},
pointer::{GrabStartData, PointerHandle},
SeatHandler,
},
reexports::wayland_server::{protocol::wl_surface::WlSurface, Resource}, reexports::wayland_server::{protocol::wl_surface::WlSurface, Resource},
utils::Serial, utils::Serial,
wayland::seat::WaylandFocus, wayland::seat::WaylandFocus,
}; };
use crate::focus::FocusTarget; use crate::state::State;
/// Returns the [GrabStartData] from a pointer grab, if any. /// Returns the [GrabStartData] from a pointer grab, if any.
pub fn pointer_grab_start_data<S>( pub fn pointer_grab_start_data(
pointer: &PointerHandle<S>, pointer: &PointerHandle<State>,
surface: &WlSurface, surface: &WlSurface,
serial: Serial, serial: Serial,
) -> Option<GrabStartData<S>> ) -> Option<GrabStartData<State>> {
where
S: SeatHandler<PointerFocus = FocusTarget> + 'static,
{
tracing::debug!("start of pointer_grab_start_data"); tracing::debug!("start of pointer_grab_start_data");
if !pointer.has_grab(serial) { if !pointer.has_grab(serial) {
tracing::debug!("pointer doesn't have grab"); tracing::debug!("pointer doesn't have grab");

View file

@ -6,14 +6,13 @@ use smithay::{
// | input::keyboard // | input::keyboard
input::{ input::{
pointer::{ pointer::{
AxisFrame, ButtonEvent, GrabStartData, MotionEvent, PointerInnerHandle, AxisFrame, ButtonEvent, Focus, GrabStartData, MotionEvent, PointerGrab,
RelativeMotionEvent, PointerInnerHandle, RelativeMotionEvent,
}, },
pointer::{Focus, PointerGrab},
Seat, SeatHandler, Seat, SeatHandler,
}, },
reexports::wayland_server::protocol::wl_surface::WlSurface, reexports::wayland_server::protocol::wl_surface::WlSurface,
utils::{IsAlive, Logical, Point, Rectangle}, utils::{IsAlive, Logical, Point, Rectangle, Serial},
}; };
use crate::{ use crate::{
@ -270,7 +269,7 @@ pub fn move_request_client(
state: &mut State, state: &mut State,
surface: &WlSurface, surface: &WlSurface,
seat: &Seat<State>, seat: &Seat<State>,
serial: smithay::utils::Serial, serial: Serial,
button_used: u32, button_used: u32,
) { ) {
let pointer = seat.get_pointer().expect("seat had no pointer"); let pointer = seat.get_pointer().expect("seat had no pointer");
@ -303,7 +302,7 @@ pub fn move_request_server(
state: &mut State, state: &mut State,
surface: &WlSurface, surface: &WlSurface,
seat: &Seat<State>, seat: &Seat<State>,
serial: smithay::utils::Serial, serial: Serial,
button_used: u32, button_used: u32,
) { ) {
let pointer = seat.get_pointer().expect("seat had no pointer"); let pointer = seat.get_pointer().expect("seat had no pointer");

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use smithay::{ use smithay::{
desktop::{space::SpaceElement, utils::bbox_from_surface_tree, WindowSurface}, desktop::{space::SpaceElement, WindowSurface},
input::{ input::{
pointer::{AxisFrame, ButtonEvent, Focus, GrabStartData, PointerGrab, PointerInnerHandle}, pointer::{AxisFrame, ButtonEvent, Focus, GrabStartData, PointerGrab, PointerInnerHandle},
Seat, SeatHandler, Seat, SeatHandler,

View file

@ -58,7 +58,7 @@ use smithay::{
}; };
use crate::{ use crate::{
focus::FocusTarget, focus::{keyboard::KeyboardFocusTarget, pointer::PointerFocusTarget},
state::{ClientState, State, WithState}, state::{ClientState, State, WithState},
}; };
@ -176,7 +176,7 @@ impl CompositorHandler for State {
.expect("Seat had no keyboard") // FIXME: actually handle error .expect("Seat had no keyboard") // FIXME: actually handle error
.set_focus( .set_focus(
state, state,
Some(FocusTarget::Window(new_window)), Some(KeyboardFocusTarget::Window(new_window)),
SERIAL_COUNTER.next_serial(), SERIAL_COUNTER.next_serial(),
); );
}); });
@ -394,9 +394,9 @@ impl DataControlHandler for State {
delegate_data_control!(State); delegate_data_control!(State);
impl SeatHandler for State { impl SeatHandler for State {
type KeyboardFocus = FocusTarget; type KeyboardFocus = KeyboardFocusTarget;
type PointerFocus = FocusTarget; type PointerFocus = PointerFocusTarget;
type TouchFocus = FocusTarget; type TouchFocus = PointerFocusTarget;
fn seat_state(&mut self) -> &mut SeatState<Self> { fn seat_state(&mut self) -> &mut SeatState<Self> {
&mut self.seat_state &mut self.seat_state

View file

@ -26,7 +26,7 @@ use smithay::{
}; };
use crate::{ use crate::{
focus::FocusTarget, focus::keyboard::KeyboardFocusTarget,
state::{State, WithState}, state::{State, WithState},
window::WindowElement, window::WindowElement,
}; };
@ -78,8 +78,10 @@ impl XdgShellHandler for State {
if let Some(output) = window.output(self) { if let Some(output) = window.output(self) {
self.update_windows(&output); self.update_windows(&output);
let focus = self.focused_window(&output).map(FocusTarget::Window); let focus = self
if let Some(FocusTarget::Window(win)) = &focus { .focused_window(&output)
.map(KeyboardFocusTarget::Window);
if let Some(KeyboardFocusTarget::Window(win)) = &focus {
tracing::debug!("Focusing on prev win"); tracing::debug!("Focusing on prev win");
// TODO: // TODO:
self.space.raise_element(win, true); self.space.raise_element(win, true);
@ -638,13 +640,13 @@ impl XdgShellHandler for State {
let popup_kind = PopupKind::Xdg(surface); let popup_kind = PopupKind::Xdg(surface);
if let Some(root) = find_popup_root_surface(&popup_kind).ok().and_then(|root| { if let Some(root) = find_popup_root_surface(&popup_kind).ok().and_then(|root| {
self.window_for_surface(&root) self.window_for_surface(&root)
.map(FocusTarget::Window) .map(KeyboardFocusTarget::Window)
.or_else(|| { .or_else(|| {
self.space.outputs().find_map(|op| { self.space.outputs().find_map(|op| {
layer_map_for_output(op) layer_map_for_output(op)
.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL) .layer_for_surface(&root, WindowSurfaceType::TOPLEVEL)
.cloned() .cloned()
.map(FocusTarget::LayerSurface) .map(KeyboardFocusTarget::LayerSurface)
}) })
}) })
}) { }) {

View file

@ -24,7 +24,7 @@ use smithay::{
}; };
use crate::{ use crate::{
focus::FocusTarget, focus::keyboard::KeyboardFocusTarget,
state::{State, WithState}, state::{State, WithState},
window::{window_state::FloatingOrTiled, WindowElement}, window::{window_state::FloatingOrTiled, WindowElement},
}; };
@ -118,7 +118,7 @@ impl XwmHandler for State {
.expect("Seat had no keyboard") // FIXME: actually handle error .expect("Seat had no keyboard") // FIXME: actually handle error
.set_focus( .set_focus(
state, state,
Some(FocusTarget::Window(window)), Some(KeyboardFocusTarget::Window(window)),
SERIAL_COUNTER.next_serial(), SERIAL_COUNTER.next_serial(),
); );
}); });
@ -177,9 +177,11 @@ impl XwmHandler for State {
if let Some(output) = win.output(self) { if let Some(output) = win.output(self) {
self.update_windows(&output); 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.space.raise_element(win, true);
self.z_index_stack.set_focus(win.clone()); self.z_index_stack.set_focus(win.clone());
if let Some(toplevel) = win.toplevel() { if let Some(toplevel) = win.toplevel() {
@ -238,9 +240,11 @@ impl XwmHandler for State {
if let Some(output) = win.output(self) { if let Some(output) = win.output(self) {
self.update_windows(&output); 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.space.raise_element(win, true);
self.z_index_stack.set_focus(win.clone()); self.z_index_stack.set_focus(win.clone());
if let Some(toplevel) = win.toplevel() { if let Some(toplevel) = win.toplevel() {
@ -411,7 +415,7 @@ impl XwmHandler for State {
.get_keyboard() .get_keyboard()
.and_then(|kb| kb.current_focus()) .and_then(|kb| kb.current_focus())
.is_some_and(|focus| { .is_some_and(|focus| {
if let FocusTarget::Window(window) = focus { if let KeyboardFocusTarget::Window(window) = focus {
if let Some(surface) = window.x11_surface() { if let Some(surface) = window.x11_surface() {
return surface.xwm_id().expect("x11surface had no xwm id") == xwm; return surface.xwm_id().expect("x11surface had no xwm id") == xwm;
} }

View file

@ -4,7 +4,7 @@ pub mod libinput;
use std::{collections::HashMap, mem::Discriminant}; 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::{ use pinnacle_api_defs::pinnacle::input::v0alpha1::{
set_libinput_setting_request::Setting, set_mousebind_request, SetKeybindResponse, set_libinput_setting_request::Setting, set_mousebind_request, SetKeybindResponse,
SetMousebindResponse, SetMousebindResponse,
@ -14,7 +14,7 @@ use smithay::{
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent, AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent,
}, },
desktop::{layer_map_for_output, space::SpaceElement}, desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType},
input::{ input::{
keyboard::{keysyms, FilterResult, ModifiersState}, keyboard::{keysyms, FilterResult, ModifiersState},
pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent}, pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent},
@ -148,8 +148,11 @@ impl State {
} }
} }
/// Get the [`FocusTarget`] under `point`. /// Get the [`PointerFocusTarget`] under `point` along with its origin in the global space.
pub fn focus_target_under<P>(&self, point: P) -> Option<(FocusTarget, Point<i32, Logical>)> pub fn pointer_focus_target_under<P>(
&self,
point: P,
) -> Option<(PointerFocusTarget, Point<i32, Logical>)>
where where
P: Into<Point<f64, Logical>>, P: Into<Point<f64, Logical>>,
{ {
@ -185,14 +188,33 @@ impl State {
}); });
if let Some(window) = top_fullscreen_window { 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)) = ( } else if let (Some(layer), _) | (None, Some(layer)) = (
layers.layer_under(wlr_layer::Layer::Overlay, point), layers.layer_under(wlr_layer::Layer::Overlay, point),
layers.layer_under(wlr_layer::Layer::Top, point), layers.layer_under(wlr_layer::Layer::Top, point),
) { ) {
let layer_loc = layers.layer_geometry(layer).expect("no layer geo").loc; 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 .space
.elements() .elements()
.rev() .rev()
@ -204,17 +226,28 @@ impl State {
.expect("called elem loc on unmapped win") .expect("called elem loc on unmapped win")
- win.geometry().loc; - win.geometry().loc;
win.is_in_input_region(&(point - loc.to_f64())) win.surface_under(point - loc.to_f64(), WindowSurfaceType::ALL)
.then(|| (win.clone().into(), loc)) .map(|(surf, surf_loc)| (surf, surf_loc + loc))
}) })
{ {
Some(ret) Some((PointerFocusTarget::WlSurface(surface), loc))
} else if let (Some(layer), _) | (None, Some(layer)) = ( } else if let (Some(layer), _) | (None, Some(layer)) = (
layers.layer_under(wlr_layer::Layer::Overlay, point), layers.layer_under(wlr_layer::Layer::Overlay, point),
layers.layer_under(wlr_layer::Layer::Top, point), layers.layer_under(wlr_layer::Layer::Top, point),
) { ) {
let layer_loc = layers.layer_geometry(layer).expect("no layer geo").loc; 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 { } else {
None None
} }
@ -334,15 +367,15 @@ impl State {
// If the button was clicked, focus on the window below if exists, else // If the button was clicked, focus on the window below if exists, else
// unfocus on windows. // unfocus on windows.
if button_state == ButtonState::Pressed { 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 // NOTE: *Do not* set keyboard focus to an override redirect window. This leads
// | to wonky things like right-click menus not correctly getting pointer // | to wonky things like right-click menus not correctly getting pointer
// | clicks or showing up at all. // | clicks or showing up at all.
// TODO: use update_keyboard_focus from anvil // TODO: use update_keyboard_focus from anvil
if let FocusTarget::Window(window) = &focus { if let Some(window) = focus.window_for(self) {
self.space.raise_element(window, true); self.space.raise_element(&window, true);
self.z_index_stack.set_focus(window.clone()); self.z_index_stack.set_focus(window.clone());
if let Some(output) = window.output(self) { if let Some(output) = window.output(self) {
output.with_state(|state| state.focus_stack.set_focus(window.clone())); output.with_state(|state| state.focus_stack.set_focus(window.clone()));
@ -350,10 +383,10 @@ impl State {
} }
if !matches!( if !matches!(
&focus, focus.window_for(self),
FocusTarget::Window(window) if window.is_x11_override_redirect() 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() { for window in self.space.elements() {
@ -496,7 +529,7 @@ impl State {
pointer.motion( pointer.motion(
self, self,
self.focus_target_under(pointer_loc), self.pointer_focus_target_under(pointer_loc),
&MotionEvent { &MotionEvent {
location: pointer_loc, location: pointer_loc,
serial, 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() { if let Some(pointer) = self.seat.get_pointer() {
pointer.motion( pointer.motion(

View file

@ -4,20 +4,11 @@ pub mod rules;
use std::{cell::RefCell, ops::Deref}; use std::{cell::RefCell, ops::Deref};
use pinnacle_api_defs::pinnacle::signal::v0alpha1::{
WindowPointerEnterResponse, WindowPointerLeaveResponse,
};
use smithay::{ use smithay::{
backend::input::KeyState,
desktop::{space::SpaceElement, Window, WindowSurface}, desktop::{space::SpaceElement, Window, WindowSurface},
input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{AxisFrame, MotionEvent, PointerTarget},
Seat,
},
output::Output, output::Output,
reexports::wayland_server::protocol::wl_surface::WlSurface, 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}, wayland::{compositor, seat::WaylandFocus, shell::xdg::XdgToplevelSurfaceData},
}; };
@ -202,241 +193,6 @@ impl IsAlive for WindowElement {
} }
} }
impl PointerTarget<State> for WindowElement {
fn frame(&self, seat: &Seat<State>, 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>, 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>, 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>,
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>,
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>, 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>, 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>,
_state: &mut State,
_event: &smithay::input::pointer::GestureSwipeBeginEvent,
) {
todo!()
}
fn gesture_swipe_update(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GestureSwipeUpdateEvent,
) {
todo!()
}
fn gesture_swipe_end(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GestureSwipeEndEvent,
) {
todo!()
}
fn gesture_pinch_begin(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GesturePinchBeginEvent,
) {
todo!()
}
fn gesture_pinch_update(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GesturePinchUpdateEvent,
) {
todo!()
}
fn gesture_pinch_end(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GesturePinchEndEvent,
) {
todo!()
}
fn gesture_hold_begin(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GestureHoldBeginEvent,
) {
todo!()
}
fn gesture_hold_end(
&self,
_seat: &Seat<State>,
_state: &mut State,
_event: &smithay::input::pointer::GestureHoldEndEvent,
) {
todo!()
}
}
impl KeyboardTarget<State> for WindowElement {
fn enter(
&self,
seat: &Seat<State>,
state: &mut State,
keys: Vec<KeysymHandle<'_>>,
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>, 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>,
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>,
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 { impl WithState for WindowElement {
type State = WindowElementState; type State = WindowElementState;