// SPDX-License-Identifier: LGPL-2.1-only // Copyright (C) 2026 Liberux Labs, S. L. use smithay_client_toolkit::seat::pointer::{ PointerEvent, PointerEventKind }; use smithay_client_toolkit::reexports::client:: { protocol::wl_pointer::WlPointer, Connection, QueueHandle, }; use crate::app::App; use crate::event_loop::{ AppData, SurfaceFocus }; impl AppData { pub( super ) fn on_pointer_enter( &mut self, _conn: &Connection, _qh: &QueueHandle, _pointer: &WlPointer, event: &PointerEvent, ) { let focus = self.focus_for_surface( &event.surface ) .unwrap_or( SurfaceFocus::Main ); if let PointerEventKind::Enter { serial } = event.kind { // Pointer just entered our surface — capture the // serial that wp_cursor_shape_device_v1::set_shape // requires, then push the initial cursor shape // *unconditionally*. Resetting `current_cursor_shape` // to `None` is what forces the dispatch: the // compositor was showing whatever the previous // client asked for (e.g. a text I-beam from a // terminal under our window), and we must claim // the cursor for our surface even when the target // equals what we last pushed. self.last_pointer_enter_serial = serial; self.current_cursor_shape = None; self.dispatch_cursor_shape( focus ); } } }