diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-12-05 10:24:41 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-12-05 10:24:41 +0400 |
| commit | cb1e5d6c192d58c33229c32e34628ecadf84c02f (patch) | |
| tree | a5878bdfe02444386264d555037c242b102a87e1 /src/niri.rs | |
| parent | 11ae17b220dfb454c524fff800f97bc11c3a56dd (diff) | |
| download | niri-cb1e5d6c192d58c33229c32e34628ecadf84c02f.tar.gz niri-cb1e5d6c192d58c33229c32e34628ecadf84c02f.tar.bz2 niri-cb1e5d6c192d58c33229c32e34628ecadf84c02f.zip | |
Track tablet pointer separately, don't sent wl_pointer events
Tablets are not supposed to send wl_pointer events. This unbreaks GTK 4
clients for example.
Diffstat (limited to 'src/niri.rs')
| -rw-r--r-- | src/niri.rs | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src/niri.rs b/src/niri.rs index 544ae16d..45b1d4f4 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -74,7 +74,7 @@ use smithay::wayland::shell::xdg::decoration::XdgDecorationState; use smithay::wayland::shell::xdg::XdgShellState; use smithay::wayland::shm::ShmState; use smithay::wayland::socket::ListeningSocketSource; -use smithay::wayland::tablet_manager::TabletManagerState; +use smithay::wayland::tablet_manager::{TabletManagerState, TabletSeatTrait}; use smithay::wayland::text_input::TextInputManagerState; use smithay::wayland::virtual_keyboard::VirtualKeyboardManagerState; @@ -157,6 +157,7 @@ pub struct Niri { pub cursor_shape_manager_state: CursorShapeManagerState, pub dnd_icon: Option<WlSurface>, pub pointer_focus: Option<PointerFocus>, + pub tablet_cursor_location: Option<Point<f64, Logical>>, pub lock_state: LockState, @@ -645,6 +646,23 @@ impl Niri { let cursor_manager = CursorManager::new(&config_.cursor.xcursor_theme, config_.cursor.xcursor_size); + let (tx, rx) = calloop::channel::channel(); + event_loop + .insert_source(rx, move |event, _, state| { + if let calloop::channel::Event::Msg(image) = event { + state.niri.cursor_manager.set_cursor_image(image); + // FIXME: granular. + state.niri.queue_redraw_all(); + } + }) + .unwrap(); + seat.tablet_seat() + .on_cursor_surface(move |_tool, new_image| { + if let Err(err) = tx.send(new_image) { + warn!("error sending new tablet cursor image: {err:?}"); + }; + }); + let screenshot_ui = ScreenshotUi::new(); let socket_source = ListeningSocketSource::new_auto().unwrap(); @@ -724,6 +742,7 @@ impl Niri { cursor_shape_manager_state, dnd_icon: None, pointer_focus: None, + tablet_cursor_location: None, lock_state: LockState::Unlocked, @@ -980,17 +999,21 @@ impl Niri { Some((output, pos_within_output)) } - pub fn window_under_cursor(&self) -> Option<&Window> { + pub fn window_under(&self, pos: Point<f64, Logical>) -> Option<&Window> { if self.is_locked() || self.screenshot_ui.is_open() { return None; } - let pos = self.seat.get_pointer().unwrap().current_location(); let (output, pos_within_output) = self.output_under(pos)?; let (window, _loc) = self.layout.window_under(output, pos_within_output)?; Some(window) } + pub fn window_under_cursor(&self) -> Option<&Window> { + let pos = self.seat.get_pointer().unwrap().current_location(); + self.window_under(pos) + } + /// Returns the surface under cursor and its position in the global space. /// /// Pointer needs location in global space, and focused window location compatible with that @@ -1223,7 +1246,12 @@ impl Niri { let _span = tracy_client::span!("Niri::pointer_element"); let output_scale = output.current_scale(); let output_pos = self.global_space.output_geometry(output).unwrap().loc; - let pointer_pos = self.seat.get_pointer().unwrap().current_location() - output_pos.to_f64(); + + // Check whether we need to draw the tablet cursor or the regular cursor. + let pointer_pos = self + .tablet_cursor_location + .unwrap_or_else(|| self.seat.get_pointer().unwrap().current_location()); + let pointer_pos = pointer_pos - output_pos.to_f64(); // Get the render cursor to draw. let cursor_scale = output_scale.integer_scale(); @@ -1294,6 +1322,11 @@ impl Niri { pub fn refresh_pointer_outputs(&mut self) { let _span = tracy_client::span!("Niri::refresh_pointer_outputs"); + // Check whether we need to draw the tablet cursor or the regular cursor. + let pointer_pos = self + .tablet_cursor_location + .unwrap_or_else(|| self.seat.get_pointer().unwrap().current_location()); + match self.cursor_manager.cursor_image().clone() { CursorImageStatus::Surface(ref surface) => { let hotspot = with_states(surface, |states| { @@ -1306,7 +1339,6 @@ impl Niri { .hotspot }); - let pointer_pos = self.seat.get_pointer().unwrap().current_location(); let surface_pos = pointer_pos.to_i32_round() - hotspot; let bbox = bbox_from_surface_tree(surface, surface_pos); @@ -1364,8 +1396,6 @@ impl Niri { Default::default() }; - let pointer_pos = self.seat.get_pointer().unwrap().current_location(); - let mut dnd_scale = 1; for output in self.global_space.outputs() { let geo = self.global_space.output_geometry(output).unwrap(); |
