mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Implement tablet-manager
This commit is contained in:
+5
-1
@@ -11,7 +11,10 @@ use smithay::wayland::data_device::{
|
||||
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
|
||||
ServerDndGrabHandler,
|
||||
};
|
||||
use smithay::{delegate_data_device, delegate_output, delegate_presentation, delegate_seat};
|
||||
use smithay::{
|
||||
delegate_data_device, delegate_output, delegate_presentation, delegate_seat,
|
||||
delegate_tablet_manager,
|
||||
};
|
||||
|
||||
use crate::Niri;
|
||||
|
||||
@@ -36,6 +39,7 @@ impl SeatHandler for Niri {
|
||||
}
|
||||
}
|
||||
delegate_seat!(Niri);
|
||||
delegate_tablet_manager!(Niri);
|
||||
|
||||
impl DataDeviceHandler for Niri {
|
||||
type SelectionUserData = ();
|
||||
|
||||
+130
-12
@@ -1,14 +1,16 @@
|
||||
use std::process::Command;
|
||||
|
||||
use smithay::backend::input::{
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
|
||||
KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent,
|
||||
TabletToolEvent, TabletToolTipEvent, TabletToolTipState,
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
|
||||
InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent,
|
||||
PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
|
||||
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState,
|
||||
};
|
||||
use smithay::backend::libinput::LibinputInputBackend;
|
||||
use smithay::input::keyboard::{keysyms, FilterResult, KeysymHandle, ModifiersState};
|
||||
use smithay::input::pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent};
|
||||
use smithay::utils::SERIAL_COUNTER;
|
||||
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait};
|
||||
|
||||
use crate::niri::Niri;
|
||||
use crate::utils::get_monotonic_time;
|
||||
@@ -457,7 +459,7 @@ impl Niri {
|
||||
|
||||
pointer.motion(
|
||||
self,
|
||||
under,
|
||||
under.clone(),
|
||||
&MotionEvent {
|
||||
location: pos,
|
||||
serial,
|
||||
@@ -465,22 +467,138 @@ impl Niri {
|
||||
},
|
||||
);
|
||||
|
||||
let tablet_seat = self.seat.tablet_seat();
|
||||
let tablet = tablet_seat.get_tablet(&TabletDescriptor::from(&event.device()));
|
||||
let tool = tablet_seat.get_tool(&event.tool());
|
||||
if let (Some(tablet), Some(tool)) = (tablet, tool) {
|
||||
if event.pressure_has_changed() {
|
||||
tool.pressure(event.pressure());
|
||||
}
|
||||
if event.distance_has_changed() {
|
||||
tool.distance(event.distance());
|
||||
}
|
||||
if event.tilt_has_changed() {
|
||||
tool.tilt(event.tilt());
|
||||
}
|
||||
if event.slider_has_changed() {
|
||||
tool.slider_position(event.slider_position());
|
||||
}
|
||||
if event.rotation_has_changed() {
|
||||
tool.rotation(event.rotation());
|
||||
}
|
||||
if event.wheel_has_changed() {
|
||||
tool.wheel(event.wheel_delta(), event.wheel_delta_discrete());
|
||||
}
|
||||
|
||||
tool.motion(
|
||||
pos,
|
||||
under,
|
||||
&tablet,
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
event.time_msec(),
|
||||
);
|
||||
}
|
||||
|
||||
// Redraw to update the cursor position.
|
||||
// FIXME: redraw only outputs overlapping the cursor.
|
||||
self.queue_redraw_all();
|
||||
}
|
||||
InputEvent::TabletToolTip { event, .. } => {
|
||||
let tool = self.seat.tablet_seat().get_tool(&event.tool());
|
||||
|
||||
if let Some(tool) = tool {
|
||||
match event.tip_state() {
|
||||
TabletToolTipState::Down => {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
tool.tip_down(serial, event.time_msec());
|
||||
|
||||
let pointer = self.seat.get_pointer().unwrap();
|
||||
if !pointer.is_grabbed() {
|
||||
if let Some(window) = self.window_under_cursor() {
|
||||
let window = window.clone();
|
||||
self.monitor_set.activate_window(&window);
|
||||
} else {
|
||||
let output = self.output_under_cursor().unwrap();
|
||||
self.monitor_set.activate_output(&output);
|
||||
}
|
||||
};
|
||||
}
|
||||
TabletToolTipState::Up => {
|
||||
tool.tip_up(event.time_msec());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
InputEvent::TabletToolProximity { event, .. } => {
|
||||
// FIXME: allow mapping tablet to different outputs.
|
||||
let output = self.global_space.outputs().next().unwrap();
|
||||
|
||||
let output_geo = self.global_space.output_geometry(output).unwrap();
|
||||
|
||||
let pos = event.position_transformed(output_geo.size) + output_geo.loc.to_f64();
|
||||
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
|
||||
let pointer = self.seat.get_pointer().unwrap();
|
||||
|
||||
if event.tip_state() == TabletToolTipState::Down && !pointer.is_grabbed() {
|
||||
if let Some(window) = self.window_under_cursor() {
|
||||
let window = window.clone();
|
||||
self.monitor_set.activate_window(&window);
|
||||
} else {
|
||||
let output = self.output_under_cursor().unwrap();
|
||||
self.monitor_set.activate_output(&output);
|
||||
let under = self.surface_under_and_global_space(pos);
|
||||
|
||||
pointer.motion(
|
||||
self,
|
||||
under.clone(),
|
||||
&MotionEvent {
|
||||
location: pos,
|
||||
serial,
|
||||
time: event.time_msec(),
|
||||
},
|
||||
);
|
||||
|
||||
let tablet_seat = self.seat.tablet_seat();
|
||||
let tool = tablet_seat.add_tool::<Self>(&self.display_handle, &event.tool());
|
||||
let tablet = tablet_seat.get_tablet(&TabletDescriptor::from(&event.device()));
|
||||
if let (Some(under), Some(tablet)) = (under, tablet) {
|
||||
match event.state() {
|
||||
ProximityState::In => tool.proximity_in(
|
||||
pos,
|
||||
under,
|
||||
&tablet,
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
event.time_msec(),
|
||||
),
|
||||
ProximityState::Out => tool.proximity_out(event.time_msec()),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
InputEvent::TabletToolButton { event, .. } => {
|
||||
let tool = self.seat.tablet_seat().get_tool(&event.tool());
|
||||
|
||||
if let Some(tool) = tool {
|
||||
tool.button(
|
||||
event.button(),
|
||||
event.button_state(),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
event.time_msec(),
|
||||
);
|
||||
}
|
||||
}
|
||||
InputEvent::DeviceAdded { device } => {
|
||||
if device.has_capability(DeviceCapability::TabletTool) {
|
||||
self.seat
|
||||
.tablet_seat()
|
||||
.add_tablet::<Self>(&self.display_handle, &TabletDescriptor::from(&device));
|
||||
}
|
||||
}
|
||||
InputEvent::DeviceRemoved { device } => {
|
||||
if device.has_capability(DeviceCapability::TabletTool) {
|
||||
let tablet_seat = self.seat.tablet_seat();
|
||||
|
||||
tablet_seat.remove_tablet(&TabletDescriptor::from(&device));
|
||||
|
||||
// If there are no tablets in seat we can remove all tools
|
||||
if tablet_seat.count_tablets() == 0 {
|
||||
tablet_seat.clear_tools();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ use smithay::wayland::shell::wlr_layer::{Layer, WlrLayerShellState};
|
||||
use smithay::wayland::shell::xdg::XdgShellState;
|
||||
use smithay::wayland::shm::ShmState;
|
||||
use smithay::wayland::socket::ListeningSocketSource;
|
||||
use smithay::wayland::tablet_manager::TabletManagerState;
|
||||
|
||||
use crate::backend::Backend;
|
||||
use crate::frame_clock::FrameClock;
|
||||
@@ -72,6 +73,7 @@ pub struct Niri {
|
||||
pub shm_state: ShmState,
|
||||
pub output_manager_state: OutputManagerState,
|
||||
pub seat_state: SeatState<Self>,
|
||||
pub tablet_state: TabletManagerState,
|
||||
pub data_device_state: DataDeviceState,
|
||||
pub popups: PopupManager,
|
||||
pub presentation_state: PresentationState,
|
||||
@@ -114,6 +116,7 @@ impl Niri {
|
||||
let shm_state = ShmState::new::<Self>(&display_handle, vec![]);
|
||||
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
|
||||
let mut seat_state = SeatState::new();
|
||||
let tablet_state = TabletManagerState::new::<Self>(&display_handle);
|
||||
let data_device_state = DataDeviceState::new::<Self>(&display_handle);
|
||||
let presentation_state =
|
||||
PresentationState::new::<Self>(&display_handle, CLOCK_MONOTONIC as u32);
|
||||
@@ -175,6 +178,7 @@ impl Niri {
|
||||
shm_state,
|
||||
output_manager_state,
|
||||
seat_state,
|
||||
tablet_state,
|
||||
data_device_state,
|
||||
popups: PopupManager::default(),
|
||||
presentation_state,
|
||||
|
||||
Reference in New Issue
Block a user