mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +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,
|
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
|
||||||
ServerDndGrabHandler,
|
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;
|
use crate::Niri;
|
||||||
|
|
||||||
@@ -36,6 +39,7 @@ impl SeatHandler for Niri {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate_seat!(Niri);
|
delegate_seat!(Niri);
|
||||||
|
delegate_tablet_manager!(Niri);
|
||||||
|
|
||||||
impl DataDeviceHandler for Niri {
|
impl DataDeviceHandler for Niri {
|
||||||
type SelectionUserData = ();
|
type SelectionUserData = ();
|
||||||
|
|||||||
+130
-12
@@ -1,14 +1,16 @@
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use smithay::backend::input::{
|
use smithay::backend::input::{
|
||||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
|
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event,
|
||||||
KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent,
|
InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent,
|
||||||
TabletToolEvent, TabletToolTipEvent, TabletToolTipState,
|
PointerMotionEvent, ProximityState, TabletToolButtonEvent, TabletToolEvent,
|
||||||
|
TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState,
|
||||||
};
|
};
|
||||||
use smithay::backend::libinput::LibinputInputBackend;
|
use smithay::backend::libinput::LibinputInputBackend;
|
||||||
use smithay::input::keyboard::{keysyms, FilterResult, KeysymHandle, ModifiersState};
|
use smithay::input::keyboard::{keysyms, FilterResult, KeysymHandle, ModifiersState};
|
||||||
use smithay::input::pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent};
|
use smithay::input::pointer::{AxisFrame, ButtonEvent, MotionEvent, RelativeMotionEvent};
|
||||||
use smithay::utils::SERIAL_COUNTER;
|
use smithay::utils::SERIAL_COUNTER;
|
||||||
|
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait};
|
||||||
|
|
||||||
use crate::niri::Niri;
|
use crate::niri::Niri;
|
||||||
use crate::utils::get_monotonic_time;
|
use crate::utils::get_monotonic_time;
|
||||||
@@ -457,7 +459,7 @@ impl Niri {
|
|||||||
|
|
||||||
pointer.motion(
|
pointer.motion(
|
||||||
self,
|
self,
|
||||||
under,
|
under.clone(),
|
||||||
&MotionEvent {
|
&MotionEvent {
|
||||||
location: pos,
|
location: pos,
|
||||||
serial,
|
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.
|
// Redraw to update the cursor position.
|
||||||
// FIXME: redraw only outputs overlapping the cursor.
|
// FIXME: redraw only outputs overlapping the cursor.
|
||||||
self.queue_redraw_all();
|
self.queue_redraw_all();
|
||||||
}
|
}
|
||||||
InputEvent::TabletToolTip { event, .. } => {
|
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();
|
let pointer = self.seat.get_pointer().unwrap();
|
||||||
|
|
||||||
if event.tip_state() == TabletToolTipState::Down && !pointer.is_grabbed() {
|
let under = self.surface_under_and_global_space(pos);
|
||||||
if let Some(window) = self.window_under_cursor() {
|
|
||||||
let window = window.clone();
|
pointer.motion(
|
||||||
self.monitor_set.activate_window(&window);
|
self,
|
||||||
} else {
|
under.clone(),
|
||||||
let output = self.output_under_cursor().unwrap();
|
&MotionEvent {
|
||||||
self.monitor_set.activate_output(&output);
|
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::shell::xdg::XdgShellState;
|
||||||
use smithay::wayland::shm::ShmState;
|
use smithay::wayland::shm::ShmState;
|
||||||
use smithay::wayland::socket::ListeningSocketSource;
|
use smithay::wayland::socket::ListeningSocketSource;
|
||||||
|
use smithay::wayland::tablet_manager::TabletManagerState;
|
||||||
|
|
||||||
use crate::backend::Backend;
|
use crate::backend::Backend;
|
||||||
use crate::frame_clock::FrameClock;
|
use crate::frame_clock::FrameClock;
|
||||||
@@ -72,6 +73,7 @@ pub struct Niri {
|
|||||||
pub shm_state: ShmState,
|
pub shm_state: ShmState,
|
||||||
pub output_manager_state: OutputManagerState,
|
pub output_manager_state: OutputManagerState,
|
||||||
pub seat_state: SeatState<Self>,
|
pub seat_state: SeatState<Self>,
|
||||||
|
pub tablet_state: TabletManagerState,
|
||||||
pub data_device_state: DataDeviceState,
|
pub data_device_state: DataDeviceState,
|
||||||
pub popups: PopupManager,
|
pub popups: PopupManager,
|
||||||
pub presentation_state: PresentationState,
|
pub presentation_state: PresentationState,
|
||||||
@@ -114,6 +116,7 @@ impl Niri {
|
|||||||
let shm_state = ShmState::new::<Self>(&display_handle, vec![]);
|
let shm_state = ShmState::new::<Self>(&display_handle, vec![]);
|
||||||
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
|
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
|
||||||
let mut seat_state = SeatState::new();
|
let mut seat_state = SeatState::new();
|
||||||
|
let tablet_state = TabletManagerState::new::<Self>(&display_handle);
|
||||||
let data_device_state = DataDeviceState::new::<Self>(&display_handle);
|
let data_device_state = DataDeviceState::new::<Self>(&display_handle);
|
||||||
let presentation_state =
|
let presentation_state =
|
||||||
PresentationState::new::<Self>(&display_handle, CLOCK_MONOTONIC as u32);
|
PresentationState::new::<Self>(&display_handle, CLOCK_MONOTONIC as u32);
|
||||||
@@ -175,6 +178,7 @@ impl Niri {
|
|||||||
shm_state,
|
shm_state,
|
||||||
output_manager_state,
|
output_manager_state,
|
||||||
seat_state,
|
seat_state,
|
||||||
|
tablet_state,
|
||||||
data_device_state,
|
data_device_state,
|
||||||
popups: PopupManager::default(),
|
popups: PopupManager::default(),
|
||||||
presentation_state,
|
presentation_state,
|
||||||
|
|||||||
Reference in New Issue
Block a user