shell: Add tablet grabs
This commit is contained in:
parent
ca9dd27350
commit
6467f79025
18 changed files with 2262 additions and 391 deletions
|
|
@ -1,22 +1,34 @@
|
|||
use smithay::{
|
||||
backend::input::{InputTime, TabletToolDescriptor},
|
||||
input::{
|
||||
Seat, SeatHandler,
|
||||
pointer::{
|
||||
AxisFrame, ButtonEvent, Focus, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
|
||||
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
|
||||
GrabStartData as PointerGrabStartData, MotionEvent as PointerMotionEvent, PointerGrab,
|
||||
PointerInnerHandle, RelativeMotionEvent,
|
||||
AxisFrame as PointerAxisFrame, ButtonEvent as PointerButtonEvent, Focus,
|
||||
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
|
||||
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent,
|
||||
GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData,
|
||||
MotionEvent as PointerMotionEvent, PointerGrab, PointerInnerHandle,
|
||||
RelativeMotionEvent,
|
||||
},
|
||||
tablet::{
|
||||
TabletSeatHandler, TabletSeatTrait,
|
||||
tool::{
|
||||
AxisFrame as TabletAxisFrame, ButtonEvent as TabletButtonEvent,
|
||||
DownEvent as TabletDownEvent, GrabStartData as TabletGrabStartData,
|
||||
MotionEvent as TabletMotionEvent, ProximityInEvent, ProximityOutEvent,
|
||||
TabletToolGrab, TabletToolInnerHandle, UpEvent as TabletUpEvent,
|
||||
},
|
||||
},
|
||||
touch::{
|
||||
DownEvent, GrabStartData as TouchGrabStartData, MotionEvent as TouchMotionEvent,
|
||||
OrientationEvent, ShapeEvent, TouchGrab, TouchInnerHandle, UpEvent,
|
||||
DownEvent as TouchDownEvent, GrabStartData as TouchGrabStartData,
|
||||
MotionEvent as TouchMotionEvent, OrientationEvent, ShapeEvent, TouchGrab,
|
||||
TouchInnerHandle, UpEvent as TouchUpEvent,
|
||||
},
|
||||
},
|
||||
utils::{Logical, Point, SERIAL_COUNTER, Serial},
|
||||
};
|
||||
|
||||
use crate::state::State;
|
||||
use crate::{shell::grabs::GrabType, state::State};
|
||||
|
||||
use super::GrabStartData;
|
||||
|
||||
|
|
@ -44,10 +56,15 @@ impl<G> DelayGrab<G> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_touch_grab(&self) -> bool {
|
||||
match self.start_data {
|
||||
GrabStartData::Touch(_) => true,
|
||||
GrabStartData::Pointer(_) => false,
|
||||
pub fn grab_type(&self) -> GrabType {
|
||||
self.start_data.type_()
|
||||
}
|
||||
|
||||
pub fn tool(&self) -> Option<&TabletToolDescriptor> {
|
||||
if let GrabStartData::TabletTool { tool, .. } = &self.start_data {
|
||||
Some(tool)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -92,7 +109,7 @@ impl<G: PointerGrab<State>> PointerGrab<State> for DelayGrab<G> {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &ButtonEvent,
|
||||
event: &PointerButtonEvent,
|
||||
) {
|
||||
handle.button(data, event);
|
||||
if handle.current_pressed().is_empty() {
|
||||
|
|
@ -104,7 +121,7 @@ impl<G: PointerGrab<State>> PointerGrab<State> for DelayGrab<G> {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
details: AxisFrame,
|
||||
details: PointerAxisFrame,
|
||||
) {
|
||||
handle.axis(data, details);
|
||||
}
|
||||
|
|
@ -201,12 +218,17 @@ impl<G: TouchGrab<State>> TouchGrab<State> for DelayGrab<G> {
|
|||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
focus: Option<(<State as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
|
||||
event: &DownEvent,
|
||||
event: &TouchDownEvent,
|
||||
) {
|
||||
handle.down(data, focus, event);
|
||||
}
|
||||
|
||||
fn up(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, event: &UpEvent) {
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &TouchUpEvent,
|
||||
) {
|
||||
handle.up(data, event);
|
||||
|
||||
if event.slot == TouchGrab::start_data(self).slot {
|
||||
|
|
@ -273,3 +295,110 @@ impl<G: TouchGrab<State>> TouchGrab<State> for DelayGrab<G> {
|
|||
|
||||
fn unset(&mut self, _data: &mut State) {}
|
||||
}
|
||||
|
||||
impl<G: TabletToolGrab<State>> TabletToolGrab<State> for DelayGrab<G> {
|
||||
fn start_data(&self) -> &TabletGrabStartData<State> {
|
||||
match &self.start_data {
|
||||
GrabStartData::TabletTool { data, .. } => data,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn proximity_out(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &ProximityOutEvent,
|
||||
) {
|
||||
handle.proximity_out(data, event);
|
||||
}
|
||||
|
||||
fn motion(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
focus: Option<(<State as TabletSeatHandler>::ToolFocus, Point<f64, Logical>)>,
|
||||
event: &TabletMotionEvent,
|
||||
) {
|
||||
handle.motion(data, focus, event);
|
||||
|
||||
let distance = self.start_data.distance(event.location);
|
||||
if distance >= 1.
|
||||
&& let Some(factory) = self.grab_factory.take()
|
||||
{
|
||||
let seat = self.seat.clone();
|
||||
let serial = self.serial.unwrap_or_else(|| SERIAL_COUNTER.next_serial());
|
||||
let time = InputTime::now();
|
||||
let Some(tool) = self.tool().cloned() else {
|
||||
handle.unset_grab(self, data, serial, time, true);
|
||||
return;
|
||||
};
|
||||
data.common.event_loop_handle.insert_idle(move |data| {
|
||||
if let Some((grab, focus)) = factory(data) {
|
||||
seat.tablet_seat()
|
||||
.get_tool(&tool)
|
||||
.unwrap()
|
||||
.set_grab(data, grab, time, serial, focus);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn down(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletDownEvent,
|
||||
) {
|
||||
handle.down(data, event)
|
||||
}
|
||||
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletUpEvent,
|
||||
) {
|
||||
handle.up(data, event);
|
||||
handle.unset_grab(self, data, event.serial, event.time, false);
|
||||
}
|
||||
|
||||
fn button(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletButtonEvent,
|
||||
) {
|
||||
handle.button(data, event);
|
||||
}
|
||||
|
||||
fn axis(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
frame: TabletAxisFrame,
|
||||
) {
|
||||
handle.axis(data, frame)
|
||||
}
|
||||
|
||||
fn frame(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
time: InputTime,
|
||||
) {
|
||||
handle.frame(data, time)
|
||||
}
|
||||
|
||||
fn unset(&mut self, _data: &mut State) {}
|
||||
|
||||
fn proximity_in(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
focus: Option<(<State as TabletSeatHandler>::ToolFocus, Point<f64, Logical>)>,
|
||||
event: &ProximityInEvent,
|
||||
) {
|
||||
handle.proximity_in(data, focus, event);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use cosmic_settings_config::shortcuts::Action;
|
||||
use smithay::{
|
||||
backend::input::InputTime, input::pointer::MotionEvent,
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface, utils::SERIAL_COUNTER,
|
||||
backend::input::InputTime,
|
||||
input::{pointer::MotionEvent, tablet::TabletSeatTrait},
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
utils::SERIAL_COUNTER,
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
|
||||
|
|
@ -11,7 +13,7 @@ use crate::{
|
|||
shell::{
|
||||
CosmicSurface, PointGlobalExt, Shell,
|
||||
element::{CosmicMapped, CosmicWindow},
|
||||
grabs::ReleaseMode,
|
||||
grabs::{GrabType, ReleaseMode},
|
||||
},
|
||||
state::State,
|
||||
utils::{prelude::SeatExt, screenshot::screenshot_window},
|
||||
|
|
@ -353,19 +355,20 @@ pub fn window_items(
|
|||
|
||||
std::mem::drop(shell);
|
||||
if let Some((grab, focus)) = res {
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(
|
||||
state,
|
||||
grab,
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
)
|
||||
} else {
|
||||
seat.get_pointer().unwrap().set_grab(
|
||||
state,
|
||||
grab,
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
focus,
|
||||
);
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
match grab.grab_type() {
|
||||
GrabType::Touch => {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial)
|
||||
}
|
||||
GrabType::Pointer => seat
|
||||
.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(state, grab, serial, focus),
|
||||
GrabType::TabletTool => seat
|
||||
.tablet_seat()
|
||||
.get_tool(grab.tool().unwrap())
|
||||
.unwrap()
|
||||
.set_grab(state, grab, InputTime::now(), serial, focus),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -389,21 +392,29 @@ pub fn window_items(
|
|||
std::mem::drop(shell);
|
||||
if let Some(((target, loc), (grab, focus))) = res {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial);
|
||||
} else {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
match grab.grab_type() {
|
||||
GrabType::Touch => {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial)
|
||||
}
|
||||
GrabType::TabletTool => seat
|
||||
.tablet_seat()
|
||||
.get_tool(grab.tool().unwrap())
|
||||
.unwrap()
|
||||
.set_grab(state, grab, InputTime::now(), serial, focus),
|
||||
GrabType::Pointer => {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -424,21 +435,30 @@ pub fn window_items(
|
|||
std::mem::drop(shell);
|
||||
if let Some(((target, loc), (grab, focus))) = res {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial);
|
||||
} else {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
match grab.grab_type() {
|
||||
GrabType::Touch => {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial)
|
||||
}
|
||||
GrabType::Pointer => {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
}
|
||||
GrabType::TabletTool => {
|
||||
seat.tablet_seat()
|
||||
.get_tool(grab.tool().unwrap())
|
||||
.unwrap()
|
||||
.set_grab(state, grab, InputTime::now(), serial, focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -459,21 +479,30 @@ pub fn window_items(
|
|||
std::mem::drop(shell);
|
||||
if let Some(((target, loc), (grab, focus))) = res {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial);
|
||||
} else {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
match grab.grab_type() {
|
||||
GrabType::Touch => {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial)
|
||||
}
|
||||
GrabType::Pointer => {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
}
|
||||
GrabType::TabletTool => {
|
||||
seat.tablet_seat()
|
||||
.get_tool(grab.tool().unwrap())
|
||||
.unwrap()
|
||||
.set_grab(state, grab, InputTime::now(), serial, focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -494,21 +523,29 @@ pub fn window_items(
|
|||
std::mem::drop(shell);
|
||||
if let Some(((target, loc), (grab, focus))) = res {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial);
|
||||
} else {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
match grab.grab_type() {
|
||||
GrabType::Touch => {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial)
|
||||
}
|
||||
GrabType::Pointer => {
|
||||
let pointer = seat.get_pointer().unwrap();
|
||||
pointer.motion(
|
||||
state,
|
||||
target,
|
||||
&MotionEvent {
|
||||
location: loc.as_logical().to_f64(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
},
|
||||
);
|
||||
pointer.frame(state);
|
||||
pointer.set_grab(state, grab, serial, focus);
|
||||
}
|
||||
GrabType::TabletTool => seat
|
||||
.tablet_seat()
|
||||
.get_tool(grab.tool().unwrap())
|
||||
.unwrap()
|
||||
.set_grab(state, grab, InputTime::now(), serial, focus),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -628,19 +665,20 @@ pub fn fullscreen_items(window: &CosmicSurface, config: &Config) -> impl Iterato
|
|||
|
||||
std::mem::drop(shell);
|
||||
if let Some((grab, focus)) = res {
|
||||
if grab.is_touch_grab() {
|
||||
seat.get_touch().unwrap().set_grab(
|
||||
state,
|
||||
grab,
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
)
|
||||
} else {
|
||||
seat.get_pointer().unwrap().set_grab(
|
||||
state,
|
||||
grab,
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
focus,
|
||||
);
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
match grab.grab_type() {
|
||||
GrabType::Touch => {
|
||||
seat.get_touch().unwrap().set_grab(state, grab, serial)
|
||||
}
|
||||
GrabType::Pointer => seat
|
||||
.get_pointer()
|
||||
.unwrap()
|
||||
.set_grab(state, grab, serial, focus),
|
||||
GrabType::TabletTool => seat
|
||||
.tablet_seat()
|
||||
.get_tool(grab.tool().unwrap())
|
||||
.unwrap()
|
||||
.set_grab(state, grab, InputTime::now(), serial, focus),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,22 +19,33 @@ use cosmic::{
|
|||
};
|
||||
use smithay::{
|
||||
backend::{
|
||||
input::{ButtonState, TouchSlot},
|
||||
input::{ButtonState, InputTime, TabletToolDescriptor, TouchSlot},
|
||||
renderer::ImportMem,
|
||||
},
|
||||
desktop::space::SpaceElement,
|
||||
input::{
|
||||
Seat,
|
||||
pointer::{
|
||||
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
|
||||
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
|
||||
GrabStartData as PointerGrabStartData, MotionEvent as PointerMotionEvent, PointerGrab,
|
||||
PointerInnerHandle, PointerTarget, RelativeMotionEvent,
|
||||
AxisFrame as PointerAxisFrame, ButtonEvent as PointerButtonEvent,
|
||||
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
|
||||
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent,
|
||||
GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData,
|
||||
MotionEvent as PointerMotionEvent, PointerGrab, PointerInnerHandle, PointerTarget,
|
||||
RelativeMotionEvent,
|
||||
},
|
||||
tablet::{
|
||||
TabletSeatHandler,
|
||||
tool::{
|
||||
AxisFrame as TabletAxisFrame, ButtonEvent as TabletButtonEvent,
|
||||
DownEvent as TabletDownEvent, GrabStartData as TabletGrabStartData,
|
||||
MotionEvent as TabletMotionEvent, ProximityInEvent, ProximityOutEvent,
|
||||
TabletToolGrab, TabletToolInnerHandle, TabletToolTarget, UpEvent as TabletUpEvent,
|
||||
},
|
||||
},
|
||||
touch::{
|
||||
DownEvent, GrabStartData as TouchGrabStartData, MotionEvent as TouchMotionEvent,
|
||||
TouchGrab, TouchInnerHandle, TouchTarget, UpEvent,
|
||||
DownEvent as TouchDownEvent, GrabStartData as TouchGrabStartData,
|
||||
MotionEvent as TouchMotionEvent, TouchGrab, TouchInnerHandle, TouchTarget,
|
||||
UpEvent as TouchUpEvent,
|
||||
},
|
||||
},
|
||||
output::Output,
|
||||
|
|
@ -43,7 +54,7 @@ use smithay::{
|
|||
|
||||
use crate::{
|
||||
backend::render::element::AsGlowRenderer,
|
||||
shell::{SeatExt, focus::target::PointerFocusTarget},
|
||||
shell::{SeatExt, focus::target::PointerFocusTarget, grabs::GrabType},
|
||||
state::State,
|
||||
utils::{
|
||||
iced::{IcedElement, IcedRenderElement, Program},
|
||||
|
|
@ -350,6 +361,7 @@ impl Program for ContextMenu {
|
|||
position,
|
||||
pointer_entered: false,
|
||||
touch_entered: None,
|
||||
tablet_entered: None,
|
||||
})
|
||||
}
|
||||
});
|
||||
|
|
@ -508,6 +520,7 @@ pub struct Element {
|
|||
position: Point<i32, Global>,
|
||||
pointer_entered: bool,
|
||||
touch_entered: Option<TouchSlot>,
|
||||
tablet_entered: Option<TabletToolDescriptor>,
|
||||
}
|
||||
|
||||
pub struct MenuGrab {
|
||||
|
|
@ -516,6 +529,7 @@ pub struct MenuGrab {
|
|||
seat: Seat<State>,
|
||||
screen_space_relative: Option<Output>,
|
||||
scale: Arc<Mutex<f64>>,
|
||||
last_tablet_idx: Option<usize>,
|
||||
}
|
||||
|
||||
impl PointerGrab<State> for MenuGrab {
|
||||
|
|
@ -598,7 +612,7 @@ impl PointerGrab<State> for MenuGrab {
|
|||
&mut self,
|
||||
state: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &ButtonEvent,
|
||||
event: &PointerButtonEvent,
|
||||
) {
|
||||
let any_entered = self
|
||||
.elements
|
||||
|
|
@ -632,7 +646,7 @@ impl PointerGrab<State> for MenuGrab {
|
|||
&mut self,
|
||||
state: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
details: AxisFrame,
|
||||
details: PointerAxisFrame,
|
||||
) {
|
||||
handle.axis(state, details);
|
||||
}
|
||||
|
|
@ -729,7 +743,7 @@ impl TouchGrab<State> for MenuGrab {
|
|||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
_focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &DownEvent,
|
||||
event: &TouchDownEvent,
|
||||
) {
|
||||
{
|
||||
let mut guard = self.elements.lock().unwrap();
|
||||
|
|
@ -757,7 +771,7 @@ impl TouchGrab<State> for MenuGrab {
|
|||
}) {
|
||||
let element = &mut elements[i];
|
||||
|
||||
let new_event = DownEvent {
|
||||
let new_event = TouchDownEvent {
|
||||
slot: event.slot,
|
||||
location: event_location - element.position.as_logical().to_f64(),
|
||||
serial: event.serial,
|
||||
|
|
@ -772,7 +786,12 @@ impl TouchGrab<State> for MenuGrab {
|
|||
handle.down(data, None, event);
|
||||
}
|
||||
|
||||
fn up(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, event: &UpEvent) {
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &TouchUpEvent,
|
||||
) {
|
||||
{
|
||||
let elements = self.elements.lock().unwrap();
|
||||
for element in elements.iter().filter(|elem| {
|
||||
|
|
@ -848,6 +867,248 @@ impl TouchGrab<State> for MenuGrab {
|
|||
fn unset(&mut self, _data: &mut State) {}
|
||||
}
|
||||
|
||||
impl TabletToolGrab<State> for MenuGrab {
|
||||
fn start_data(&self) -> &TabletGrabStartData<State> {
|
||||
match &self.start_data {
|
||||
GrabStartData::TabletTool { data, .. } => data,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn proximity_in(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
_focus: Option<(<State as TabletSeatHandler>::ToolFocus, Point<f64, Logical>)>,
|
||||
event: &ProximityInEvent,
|
||||
) {
|
||||
{
|
||||
let location = if let Some(output) = self.screen_space_relative.as_ref() {
|
||||
if data.common.shell.read().zoom_state().is_some() {
|
||||
event
|
||||
.location
|
||||
.as_global()
|
||||
.to_zoomed(output)
|
||||
.to_global(output)
|
||||
.as_logical()
|
||||
} else {
|
||||
event.location
|
||||
}
|
||||
} else {
|
||||
event.location
|
||||
};
|
||||
|
||||
let mut elements = self.elements.lock().unwrap();
|
||||
if let Some(i) = elements.iter().position(|elem| {
|
||||
let mut bbox = elem.iced.bbox();
|
||||
bbox.loc = elem.position.as_logical();
|
||||
|
||||
bbox.contains(location.to_i32_floor())
|
||||
}) {
|
||||
let element = &mut elements[i];
|
||||
|
||||
let new_event = TabletMotionEvent {
|
||||
location: location - element.position.as_logical().to_f64(),
|
||||
serial: event.serial,
|
||||
time: event.time,
|
||||
};
|
||||
|
||||
TabletToolTarget::proximity_in(
|
||||
&element.iced,
|
||||
&self.seat,
|
||||
data,
|
||||
handle.descriptor(),
|
||||
&handle.current_tablet(),
|
||||
event.serial,
|
||||
);
|
||||
element.tablet_entered = Some(handle.descriptor().clone());
|
||||
TabletToolTarget::motion(
|
||||
&element.iced,
|
||||
&self.seat,
|
||||
data,
|
||||
handle.descriptor(),
|
||||
&new_event,
|
||||
);
|
||||
self.last_tablet_idx = Some(i);
|
||||
}
|
||||
}
|
||||
handle.proximity_in(data, None, event);
|
||||
}
|
||||
|
||||
fn proximity_out(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &ProximityOutEvent,
|
||||
) {
|
||||
{
|
||||
let mut elements = self.elements.lock().unwrap();
|
||||
for element in elements.iter_mut().filter(|elem| {
|
||||
elem.tablet_entered
|
||||
.as_ref()
|
||||
.is_some_and(|tool| tool == handle.descriptor())
|
||||
}) {
|
||||
TabletToolTarget::proximity_out(
|
||||
&element.iced,
|
||||
&self.seat,
|
||||
data,
|
||||
handle.descriptor(),
|
||||
);
|
||||
element.tablet_entered.take();
|
||||
}
|
||||
self.last_tablet_idx.take();
|
||||
}
|
||||
handle.unset_grab(self, data, event.serial, event.time, true);
|
||||
}
|
||||
|
||||
fn motion(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
_focus: Option<(<State as TabletSeatHandler>::ToolFocus, Point<f64, Logical>)>,
|
||||
event: &TabletMotionEvent,
|
||||
) {
|
||||
{
|
||||
let location = if let Some(output) = self.screen_space_relative.as_ref() {
|
||||
if data.common.shell.read().zoom_state().is_some() {
|
||||
event
|
||||
.location
|
||||
.as_global()
|
||||
.to_zoomed(output)
|
||||
.to_global(output)
|
||||
.as_logical()
|
||||
} else {
|
||||
event.location
|
||||
}
|
||||
} else {
|
||||
event.location
|
||||
};
|
||||
|
||||
let mut elements = self.elements.lock().unwrap();
|
||||
if let Some(i) = elements.iter().position(|elem| {
|
||||
let mut bbox = elem.iced.bbox();
|
||||
bbox.loc = elem.position.as_logical();
|
||||
|
||||
bbox.contains(location.to_i32_floor())
|
||||
}) {
|
||||
let element = &mut elements[i];
|
||||
|
||||
let new_event = TabletMotionEvent {
|
||||
location: location - element.position.as_logical().to_f64(),
|
||||
serial: event.serial,
|
||||
time: event.time,
|
||||
};
|
||||
|
||||
if element.tablet_entered.is_none() {
|
||||
TabletToolTarget::proximity_in(
|
||||
&element.iced,
|
||||
&self.seat,
|
||||
data,
|
||||
handle.descriptor(),
|
||||
&handle.current_tablet(),
|
||||
event.serial,
|
||||
);
|
||||
element.tablet_entered = Some(handle.descriptor().clone());
|
||||
}
|
||||
TabletToolTarget::motion(
|
||||
&element.iced,
|
||||
&self.seat,
|
||||
data,
|
||||
handle.descriptor(),
|
||||
&new_event,
|
||||
);
|
||||
self.last_tablet_idx = Some(i);
|
||||
} else {
|
||||
elements
|
||||
.iter_mut()
|
||||
.filter(|element| element.tablet_entered.is_some())
|
||||
.skip(1)
|
||||
.for_each(|element| {
|
||||
TabletToolTarget::proximity_out(
|
||||
&element.iced,
|
||||
&self.seat,
|
||||
data,
|
||||
handle.descriptor(),
|
||||
);
|
||||
});
|
||||
self.last_tablet_idx.take();
|
||||
}
|
||||
}
|
||||
handle.motion(data, None, event);
|
||||
}
|
||||
|
||||
fn down(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletDownEvent,
|
||||
) {
|
||||
let mut guard = self.elements.lock().unwrap();
|
||||
let elements = &mut *guard;
|
||||
|
||||
if let Some(elem) = self.last_tablet_idx.and_then(|i| elements.get_mut(i))
|
||||
&& elem
|
||||
.tablet_entered
|
||||
.as_ref()
|
||||
.is_some_and(|desc| desc == handle.descriptor())
|
||||
{
|
||||
TabletToolTarget::down(&elem.iced, &self.seat, data, handle.descriptor(), event);
|
||||
} else {
|
||||
handle.down(data, event);
|
||||
}
|
||||
}
|
||||
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletUpEvent,
|
||||
) {
|
||||
let mut guard = self.elements.lock().unwrap();
|
||||
let elements = &mut *guard;
|
||||
|
||||
if let Some(elem) = self.last_tablet_idx.and_then(|i| elements.get_mut(i))
|
||||
&& elem
|
||||
.tablet_entered
|
||||
.as_ref()
|
||||
.is_some_and(|desc| desc == handle.descriptor())
|
||||
{
|
||||
TabletToolTarget::up(&elem.iced, &self.seat, data, handle.descriptor(), event);
|
||||
} else {
|
||||
handle.up(data, event);
|
||||
}
|
||||
}
|
||||
|
||||
fn button(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletButtonEvent,
|
||||
) {
|
||||
handle.button(data, event);
|
||||
}
|
||||
|
||||
fn axis(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
frame: TabletAxisFrame,
|
||||
) {
|
||||
handle.axis(data, frame);
|
||||
}
|
||||
|
||||
fn frame(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
time: InputTime,
|
||||
) {
|
||||
handle.frame(data, time);
|
||||
}
|
||||
|
||||
fn unset(&mut self, _data: &mut State) {}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct MenuAlignment {
|
||||
pub x: AxisAlignment,
|
||||
|
|
@ -1051,6 +1312,7 @@ impl MenuGrab {
|
|||
position,
|
||||
pointer_entered: false,
|
||||
touch_entered: None,
|
||||
tablet_entered: None,
|
||||
}]));
|
||||
|
||||
let scale = Arc::new(Mutex::new(screen_space_relative.unwrap_or(1.)));
|
||||
|
|
@ -1075,6 +1337,7 @@ impl MenuGrab {
|
|||
seat: seat.clone(),
|
||||
screen_space_relative,
|
||||
scale,
|
||||
last_tablet_idx: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1085,10 +1348,15 @@ impl MenuGrab {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_touch_grab(&self) -> bool {
|
||||
match self.start_data {
|
||||
GrabStartData::Touch(_) => true,
|
||||
GrabStartData::Pointer(_) => false,
|
||||
pub fn grab_type(&self) -> GrabType {
|
||||
self.start_data.type_()
|
||||
}
|
||||
|
||||
pub fn tool(&self) -> Option<&TabletToolDescriptor> {
|
||||
if let GrabStartData::TabletTool { tool, .. } = &self.start_data {
|
||||
Some(tool)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,26 @@
|
|||
use calloop::LoopHandle;
|
||||
use cosmic_settings_config::shortcuts;
|
||||
use smithay::{
|
||||
backend::input::{InputTime, TabletToolDescriptor},
|
||||
input::{
|
||||
Seat,
|
||||
pointer::{
|
||||
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
|
||||
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
|
||||
GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, PointerInnerHandle,
|
||||
RelativeMotionEvent,
|
||||
AxisFrame as PointerAxisFrame, ButtonEvent as PointerButtonEvent,
|
||||
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
|
||||
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent,
|
||||
GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData,
|
||||
MotionEvent, PointerGrab, PointerInnerHandle, RelativeMotionEvent,
|
||||
},
|
||||
tablet::tool::{
|
||||
AxisFrame as TabletAxisFrame, ButtonEvent as TabletButtonEvent,
|
||||
DownEvent as TabletDownEvent, GrabStartData as TabletGrabStartData,
|
||||
MotionEvent as TabletMotionEvent, ProximityOutEvent, TabletToolGrab,
|
||||
TabletToolInnerHandle, UpEvent as TabletUpEvent,
|
||||
},
|
||||
touch::{
|
||||
DownEvent, GrabStartData as TouchGrabStartData, MotionEvent as TouchMotionEvent,
|
||||
OrientationEvent, ShapeEvent, TouchGrab, TouchInnerHandle, UpEvent,
|
||||
DownEvent as TouchDownEvent, GrabStartData as TouchGrabStartData,
|
||||
MotionEvent as TouchMotionEvent, OrientationEvent, ShapeEvent, TouchGrab,
|
||||
TouchInnerHandle, UpEvent as TouchUpEvent,
|
||||
},
|
||||
},
|
||||
output::Output,
|
||||
|
|
@ -39,6 +47,17 @@ use super::{
|
|||
pub enum GrabStartData {
|
||||
Touch(TouchGrabStartData<State>),
|
||||
Pointer(PointerGrabStartData<State>),
|
||||
TabletTool {
|
||||
tool: TabletToolDescriptor,
|
||||
data: TabletGrabStartData<State>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum GrabType {
|
||||
Touch,
|
||||
Pointer,
|
||||
TabletTool,
|
||||
}
|
||||
|
||||
impl GrabStartData {
|
||||
|
|
@ -46,6 +65,7 @@ impl GrabStartData {
|
|||
match self {
|
||||
Self::Touch(touch) => touch.focus.as_ref(),
|
||||
Self::Pointer(pointer) => pointer.focus.as_ref(),
|
||||
Self::TabletTool { data, .. } => data.focus.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +73,7 @@ impl GrabStartData {
|
|||
match self {
|
||||
Self::Touch(touch) => touch.focus = focus,
|
||||
Self::Pointer(pointer) => pointer.focus = focus,
|
||||
Self::TabletTool { data, .. } => data.focus = focus,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +81,7 @@ impl GrabStartData {
|
|||
match self {
|
||||
Self::Touch(touch) => touch.location,
|
||||
Self::Pointer(pointer) => pointer.location,
|
||||
Self::TabletTool { data, .. } => data.location,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +89,7 @@ impl GrabStartData {
|
|||
match self {
|
||||
Self::Touch(touch) => touch.location = location,
|
||||
Self::Pointer(pointer) => pointer.location = location,
|
||||
Self::TabletTool { data, .. } => data.location = location,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +99,14 @@ impl GrabStartData {
|
|||
|
||||
((new.x - old.x).powi(2) + (new.y - old.y).powi(2)).sqrt()
|
||||
}
|
||||
|
||||
pub fn type_(&self) -> GrabType {
|
||||
match self {
|
||||
Self::Pointer(_) => GrabType::Pointer,
|
||||
Self::Touch(_) => GrabType::Touch,
|
||||
Self::TabletTool { .. } => GrabType::TabletTool,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
@ -203,10 +234,17 @@ impl From<ResizeForkGrab> for ResizeGrab {
|
|||
}
|
||||
|
||||
impl ResizeGrab {
|
||||
pub fn is_touch_grab(&self) -> bool {
|
||||
pub fn grab_type(&self) -> GrabType {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => grab.is_touch_grab(),
|
||||
ResizeGrab::Tiling(grab) => grab.is_touch_grab(),
|
||||
ResizeGrab::Floating(grab) => grab.grab_type(),
|
||||
ResizeGrab::Tiling(grab) => grab.grab_type(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tool(&self) -> Option<&TabletToolDescriptor> {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => grab.tool(),
|
||||
ResizeGrab::Tiling(grab) => grab.tool(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -242,11 +280,11 @@ impl PointerGrab<State> for ResizeGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &ButtonEvent,
|
||||
event: &PointerButtonEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => grab.button(data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => grab.button(data, handle, event),
|
||||
ResizeGrab::Floating(grab) => PointerGrab::button(grab, data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => PointerGrab::button(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,11 +292,11 @@ impl PointerGrab<State> for ResizeGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
details: AxisFrame,
|
||||
details: PointerAxisFrame,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => grab.axis(data, handle, details),
|
||||
ResizeGrab::Tiling(grab) => grab.axis(data, handle, details),
|
||||
ResizeGrab::Floating(grab) => PointerGrab::axis(grab, data, handle, details),
|
||||
ResizeGrab::Tiling(grab) => PointerGrab::axis(grab, data, handle, details),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +424,7 @@ impl TouchGrab<State> for ResizeGrab {
|
|||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &DownEvent,
|
||||
event: &TouchDownEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TouchGrab::down(grab, data, handle, focus, event),
|
||||
|
|
@ -394,7 +432,12 @@ impl TouchGrab<State> for ResizeGrab {
|
|||
}
|
||||
}
|
||||
|
||||
fn up(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, event: &UpEvent) {
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &TouchUpEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TouchGrab::up(grab, data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => TouchGrab::up(grab, data, handle, event),
|
||||
|
|
@ -467,6 +510,107 @@ impl TouchGrab<State> for ResizeGrab {
|
|||
}
|
||||
}
|
||||
|
||||
impl TabletToolGrab<State> for ResizeGrab {
|
||||
fn down(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletDownEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::down(grab, data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::down(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletUpEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::up(grab, data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::up(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn motion(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &TabletMotionEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::motion(grab, data, handle, focus, event),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::motion(grab, data, handle, focus, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn frame(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
serial: InputTime,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::frame(grab, data, handle, serial),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::frame(grab, data, handle, serial),
|
||||
}
|
||||
}
|
||||
|
||||
fn button(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletButtonEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::button(grab, data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::button(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn axis(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
details: TabletAxisFrame,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::axis(grab, data, handle, details),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::axis(grab, data, handle, details),
|
||||
}
|
||||
}
|
||||
|
||||
fn proximity_out(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &ProximityOutEvent,
|
||||
) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::proximity_out(grab, data, handle, event),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::proximity_out(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn start_data(&self) -> &TabletGrabStartData<State> {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::start_data(grab),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::start_data(grab),
|
||||
}
|
||||
}
|
||||
|
||||
fn unset(&mut self, data: &mut State) {
|
||||
match self {
|
||||
ResizeGrab::Floating(grab) => TabletToolGrab::unset(grab, data),
|
||||
ResizeGrab::Tiling(grab) => TabletToolGrab::unset(grab, data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum MoveGrab {
|
||||
Move(moving::MoveGrab),
|
||||
Delayed(delay::DelayGrab<MoveGrab>),
|
||||
|
|
@ -536,10 +680,17 @@ impl MoveGrab {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_touch_grab(&self) -> bool {
|
||||
pub fn grab_type(&self) -> GrabType {
|
||||
match self {
|
||||
MoveGrab::Move(m) => m.is_touch_grab(),
|
||||
MoveGrab::Delayed(d) => d.is_touch_grab(),
|
||||
MoveGrab::Move(m) => m.grab_type(),
|
||||
MoveGrab::Delayed(d) => d.grab_type(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tool(&self) -> Option<&TabletToolDescriptor> {
|
||||
match self {
|
||||
MoveGrab::Move(m) => m.tool(),
|
||||
MoveGrab::Delayed(d) => d.tool(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -574,11 +725,11 @@ impl PointerGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &ButtonEvent,
|
||||
event: &PointerButtonEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => grab.button(data, handle, event),
|
||||
MoveGrab::Delayed(grab) => grab.button(data, handle, event),
|
||||
MoveGrab::Move(grab) => PointerGrab::button(grab, data, handle, event),
|
||||
MoveGrab::Delayed(grab) => PointerGrab::button(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -586,11 +737,11 @@ impl PointerGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
details: AxisFrame,
|
||||
details: PointerAxisFrame,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => grab.axis(data, handle, details),
|
||||
MoveGrab::Delayed(grab) => grab.axis(data, handle, details),
|
||||
MoveGrab::Move(grab) => PointerGrab::axis(grab, data, handle, details),
|
||||
MoveGrab::Delayed(grab) => PointerGrab::axis(grab, data, handle, details),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -718,7 +869,7 @@ impl TouchGrab<State> for MoveGrab {
|
|||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &DownEvent,
|
||||
event: &TouchDownEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TouchGrab::down(grab, data, handle, focus, event),
|
||||
|
|
@ -726,7 +877,12 @@ impl TouchGrab<State> for MoveGrab {
|
|||
}
|
||||
}
|
||||
|
||||
fn up(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, event: &UpEvent) {
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &TouchUpEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TouchGrab::up(grab, data, handle, event),
|
||||
MoveGrab::Delayed(grab) => TouchGrab::up(grab, data, handle, event),
|
||||
|
|
@ -798,3 +954,104 @@ impl TouchGrab<State> for MoveGrab {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TabletToolGrab<State> for MoveGrab {
|
||||
fn down(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletDownEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::down(grab, data, handle, event),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::down(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletUpEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::up(grab, data, handle, event),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::up(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn motion(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &TabletMotionEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::motion(grab, data, handle, focus, event),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::motion(grab, data, handle, focus, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn frame(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
serial: InputTime,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::frame(grab, data, handle, serial),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::frame(grab, data, handle, serial),
|
||||
}
|
||||
}
|
||||
|
||||
fn button(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletButtonEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::button(grab, data, handle, event),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::button(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn axis(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
details: TabletAxisFrame,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::axis(grab, data, handle, details),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::axis(grab, data, handle, details),
|
||||
}
|
||||
}
|
||||
|
||||
fn proximity_out(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &ProximityOutEvent,
|
||||
) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::proximity_out(grab, data, handle, event),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::proximity_out(grab, data, handle, event),
|
||||
}
|
||||
}
|
||||
|
||||
fn start_data(&self) -> &TabletGrabStartData<State> {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::start_data(grab),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::start_data(grab),
|
||||
}
|
||||
}
|
||||
|
||||
fn unset(&mut self, data: &mut State) {
|
||||
match self {
|
||||
MoveGrab::Move(grab) => TabletToolGrab::unset(grab, data),
|
||||
MoveGrab::Delayed(grab) => TabletToolGrab::unset(grab, data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
CosmicMapped, CosmicSurface, Direction, ManagedLayer,
|
||||
element::{CosmicMappedRenderElement, stack_hover::StackHover},
|
||||
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
|
||||
grabs::GrabType,
|
||||
layout::floating::TiledCorners,
|
||||
},
|
||||
utils::prelude::*,
|
||||
|
|
@ -20,7 +21,7 @@ use smallvec::SmallVec;
|
|||
use smithay::{
|
||||
backend::{
|
||||
drm::DrmNode,
|
||||
input::{ButtonState, InputTime},
|
||||
input::{ButtonState, InputTime, TabletToolDescriptor},
|
||||
renderer::{
|
||||
ImportAll, ImportMem,
|
||||
element::{RenderElement, utils::RescaleRenderElement},
|
||||
|
|
@ -30,13 +31,27 @@ use smithay::{
|
|||
input::{
|
||||
Seat,
|
||||
pointer::{
|
||||
AxisFrame, ButtonEvent, CursorIcon, GestureHoldBeginEvent, GestureHoldEndEvent,
|
||||
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
|
||||
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
|
||||
GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, PointerInnerHandle,
|
||||
AxisFrame as PointerAxisFrame, ButtonEvent as PointerButtonEvent, CursorIcon,
|
||||
GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
|
||||
GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent,
|
||||
GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData,
|
||||
MotionEvent as PointerMotionEvent, PointerGrab, PointerInnerHandle,
|
||||
RelativeMotionEvent,
|
||||
},
|
||||
touch::{self, GrabStartData as TouchGrabStartData, TouchGrab, TouchInnerHandle},
|
||||
tablet::{
|
||||
TabletSeatHandler,
|
||||
tool::{
|
||||
AxisFrame as TabletAxisFrame, ButtonEvent as TabletButtonEvent,
|
||||
DownEvent as TabletDownEvent, GrabStartData as TabletGrabStartData,
|
||||
MotionEvent as TabletMotionEvent, ProximityInEvent, ProximityOutEvent,
|
||||
TabletToolGrab, TabletToolInnerHandle, UpEvent as TabletUpEvent,
|
||||
},
|
||||
},
|
||||
touch::{
|
||||
DownEvent as TouchDownEvent, GrabStartData as TouchGrabStartData,
|
||||
MotionEvent as TouchMotionEvent, OrientationEvent, ShapeEvent, TouchGrab,
|
||||
TouchInnerHandle, UpEvent as TouchUpEvent,
|
||||
},
|
||||
},
|
||||
output::Output,
|
||||
utils::{IsAlive, Logical, Point, Rectangle, SERIAL_COUNTER, Scale},
|
||||
|
|
@ -503,7 +518,7 @@ impl PointerGrab<State> for MoveGrab {
|
|||
state: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
_focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &MotionEvent,
|
||||
event: &PointerMotionEvent,
|
||||
) {
|
||||
self.update_location(state, event.location);
|
||||
|
||||
|
|
@ -529,7 +544,7 @@ impl PointerGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
state: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
event: &ButtonEvent,
|
||||
event: &PointerButtonEvent,
|
||||
) {
|
||||
handle.button(state, event);
|
||||
match self.release {
|
||||
|
|
@ -550,7 +565,7 @@ impl PointerGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
state: &mut State,
|
||||
handle: &mut PointerInnerHandle<'_, State>,
|
||||
details: AxisFrame,
|
||||
details: PointerAxisFrame,
|
||||
) {
|
||||
handle.axis(state, details);
|
||||
}
|
||||
|
|
@ -647,7 +662,7 @@ impl TouchGrab<State> for MoveGrab {
|
|||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
_focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &touch::DownEvent,
|
||||
event: &TouchDownEvent,
|
||||
) {
|
||||
handle.down(data, None, event)
|
||||
}
|
||||
|
|
@ -656,7 +671,7 @@ impl TouchGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &touch::UpEvent,
|
||||
event: &TouchUpEvent,
|
||||
) {
|
||||
if event.slot == <Self as TouchGrab<State>>::start_data(self).slot {
|
||||
handle.unset_grab(self, data);
|
||||
|
|
@ -670,7 +685,7 @@ impl TouchGrab<State> for MoveGrab {
|
|||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
_focus: Option<(PointerFocusTarget, Point<f64, Logical>)>,
|
||||
event: &touch::MotionEvent,
|
||||
event: &TouchMotionEvent,
|
||||
) {
|
||||
if event.slot == <Self as TouchGrab<State>>::start_data(self).slot {
|
||||
self.update_location(data, event.location);
|
||||
|
|
@ -691,7 +706,7 @@ impl TouchGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &touch::ShapeEvent,
|
||||
event: &ShapeEvent,
|
||||
) {
|
||||
handle.shape(data, event)
|
||||
}
|
||||
|
|
@ -700,7 +715,7 @@ impl TouchGrab<State> for MoveGrab {
|
|||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TouchInnerHandle<'_, State>,
|
||||
event: &touch::OrientationEvent,
|
||||
event: &OrientationEvent,
|
||||
) {
|
||||
handle.orientation(data, event)
|
||||
}
|
||||
|
|
@ -715,6 +730,100 @@ impl TouchGrab<State> for MoveGrab {
|
|||
fn unset(&mut self, _data: &mut State) {}
|
||||
}
|
||||
|
||||
impl TabletToolGrab<State> for MoveGrab {
|
||||
fn start_data(&self) -> &TabletGrabStartData<State> {
|
||||
match &self.start_data {
|
||||
GrabStartData::TabletTool { data, .. } => data,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn proximity_out(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &ProximityOutEvent,
|
||||
) {
|
||||
handle.proximity_out(data, event);
|
||||
}
|
||||
|
||||
fn motion(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
_focus: Option<(<State as TabletSeatHandler>::ToolFocus, Point<f64, Logical>)>,
|
||||
event: &TabletMotionEvent,
|
||||
) {
|
||||
handle.motion(data, None, event);
|
||||
|
||||
self.update_location(data, event.location);
|
||||
if !self.window.alive() {
|
||||
handle.unset_grab(self, data, event.serial, event.time, true);
|
||||
}
|
||||
}
|
||||
|
||||
fn down(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletDownEvent,
|
||||
) {
|
||||
handle.down(data, event)
|
||||
}
|
||||
|
||||
fn up(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletUpEvent,
|
||||
) {
|
||||
if self.tool().is_some_and(|tool| tool == handle.descriptor()) {
|
||||
handle.unset_grab(self, data, event.serial, event.time, false);
|
||||
}
|
||||
|
||||
handle.up(data, event);
|
||||
}
|
||||
|
||||
fn button(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
event: &TabletButtonEvent,
|
||||
) {
|
||||
handle.button(data, event)
|
||||
}
|
||||
|
||||
fn axis(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
frame: TabletAxisFrame,
|
||||
) {
|
||||
handle.axis(data, frame)
|
||||
}
|
||||
|
||||
fn frame(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
time: InputTime,
|
||||
) {
|
||||
handle.frame(data, time)
|
||||
}
|
||||
|
||||
fn proximity_in(
|
||||
&mut self,
|
||||
data: &mut State,
|
||||
handle: &mut TabletToolInnerHandle<'_, State>,
|
||||
focus: Option<(<State as TabletSeatHandler>::ToolFocus, Point<f64, Logical>)>,
|
||||
event: &ProximityInEvent,
|
||||
) {
|
||||
handle.proximity_in(data, focus, event);
|
||||
}
|
||||
|
||||
fn unset(&mut self, _data: &mut State) {}
|
||||
}
|
||||
|
||||
impl MoveGrab {
|
||||
pub fn new(
|
||||
start_data: GrabStartData,
|
||||
|
|
@ -778,10 +887,15 @@ impl MoveGrab {
|
|||
self.previous == ManagedLayer::Tiling
|
||||
}
|
||||
|
||||
pub fn is_touch_grab(&self) -> bool {
|
||||
match self.start_data {
|
||||
GrabStartData::Touch(_) => true,
|
||||
GrabStartData::Pointer(_) => false,
|
||||
pub fn grab_type(&self) -> GrabType {
|
||||
self.start_data.type_()
|
||||
}
|
||||
|
||||
pub fn tool(&self) -> Option<&TabletToolDescriptor> {
|
||||
if let GrabStartData::TabletTool { tool, .. } = &self.start_data {
|
||||
Some(tool)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -953,7 +1067,7 @@ impl Drop for MoveGrab {
|
|||
position.as_logical().to_f64() - window.geometry().loc.to_f64()
|
||||
+ offset,
|
||||
)),
|
||||
&MotionEvent {
|
||||
&PointerMotionEvent {
|
||||
location: pointer.current_location(),
|
||||
serial,
|
||||
time: InputTime::now(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue