Initial wl_touch support
`builtin_output` is similar to `get_builtin_output_name` in Sway. For full support, we need support for touch targets/grabs, touch support for SSDs, and a way to configure what output is mapped to what input. But this is usable for apps that support touch on a laptop with a touchscreen.
This commit is contained in:
parent
144f8cbf69
commit
70bb9b9a2e
2 changed files with 103 additions and 4 deletions
100
src/input/mod.rs
100
src/input/mod.rs
|
|
@ -25,9 +25,9 @@ use cosmic_comp_config::workspace::WorkspaceLayout;
|
|||
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
|
||||
use smithay::{
|
||||
backend::input::{
|
||||
Axis, AxisSource, Device, DeviceCapability, GestureBeginEvent, GestureEndEvent,
|
||||
GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _, InputBackend, InputEvent,
|
||||
KeyState, PointerAxisEvent,
|
||||
AbsolutePositionEvent, Axis, AxisSource, Device, DeviceCapability, GestureBeginEvent,
|
||||
GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _, InputBackend,
|
||||
InputEvent, KeyState, PointerAxisEvent, TouchEvent,
|
||||
},
|
||||
desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType},
|
||||
input::{
|
||||
|
|
@ -205,6 +205,7 @@ pub fn add_seat(
|
|||
.expect("Failed to load xkb configuration files");
|
||||
}
|
||||
seat.add_pointer();
|
||||
seat.add_touch();
|
||||
|
||||
seat
|
||||
}
|
||||
|
|
@ -1164,7 +1165,98 @@ impl State {
|
|||
);
|
||||
}
|
||||
}
|
||||
_ => { /* TODO e.g. tablet or touch events */ }
|
||||
InputEvent::TouchDown { event, .. } => {
|
||||
if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
|
||||
// TODO: Configuration option for mapping touch device to output
|
||||
// Is it possible to determine mapping for external touchscreen?
|
||||
let Some(output) = self.common.shell.builtin_output().cloned() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let geometry = output.geometry();
|
||||
|
||||
let position = geometry.loc.to_f64()
|
||||
+ event
|
||||
.position_transformed(geometry.size.as_logical())
|
||||
.as_global();
|
||||
|
||||
let overview = self.common.shell.overview_mode();
|
||||
let workspace = self.common.shell.workspaces.active_mut(&output);
|
||||
let under = State::surface_under(
|
||||
position,
|
||||
&output,
|
||||
&self.common.shell.override_redirect_windows,
|
||||
overview.0.clone(),
|
||||
workspace,
|
||||
self.common.shell.session_lock.as_ref(),
|
||||
)
|
||||
.map(|(target, pos)| (target, pos.as_logical()));
|
||||
|
||||
if let Some((target, pos)) = under {
|
||||
if let Some(wl_surface) = target.wl_surface() {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let touch = seat.get_touch().unwrap();
|
||||
touch.down(
|
||||
serial,
|
||||
event.time_msec(),
|
||||
&wl_surface,
|
||||
position.as_logical() - pos.to_f64(),
|
||||
event.slot(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
InputEvent::TouchMotion { event, .. } => {
|
||||
if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
|
||||
let Some(output) = self.common.shell.builtin_output().cloned() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let geometry = output.geometry();
|
||||
|
||||
let position = geometry.loc.to_f64()
|
||||
+ event
|
||||
.position_transformed(geometry.size.as_logical())
|
||||
.as_global();
|
||||
|
||||
let overview = self.common.shell.overview_mode();
|
||||
let workspace = self.common.shell.workspaces.active_mut(&output);
|
||||
let under = State::surface_under(
|
||||
position,
|
||||
&output,
|
||||
&self.common.shell.override_redirect_windows,
|
||||
overview.0.clone(),
|
||||
workspace,
|
||||
self.common.shell.session_lock.as_ref(),
|
||||
)
|
||||
.map(|(target, pos)| (target, pos.as_logical()));
|
||||
|
||||
if let Some((_target, pos)) = under {
|
||||
let touch = seat.get_touch().unwrap();
|
||||
touch.motion(
|
||||
event.time_msec(),
|
||||
event.slot(),
|
||||
position.as_logical() - pos.to_f64(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
InputEvent::TouchUp { event, .. } => {
|
||||
if let Some(seat) = self.common.seat_with_device(&event.device()) {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let touch = seat.get_touch().unwrap();
|
||||
touch.up(serial, event.time_msec(), event.slot());
|
||||
}
|
||||
}
|
||||
InputEvent::TouchCancel { event, .. } => {
|
||||
if let Some(seat) = self.common.seat_with_device(&event.device()) {
|
||||
let touch = seat.get_touch().unwrap();
|
||||
touch.cancel();
|
||||
}
|
||||
}
|
||||
InputEvent::TouchFrame { event: _, .. } => {}
|
||||
_ => { /* TODO e.g. tablet events */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1326,6 +1326,13 @@ impl Shell {
|
|||
.map(|(o, _)| o)
|
||||
}
|
||||
|
||||
pub fn builtin_output(&self) -> Option<&Output> {
|
||||
self.outputs().find(|output| {
|
||||
let name = output.name();
|
||||
name.starts_with("eDP-") || name.starts_with("LVDS-") || name.starts_with("DSI-")
|
||||
})
|
||||
}
|
||||
|
||||
pub fn global_space(&self) -> Rectangle<i32, Global> {
|
||||
self.outputs()
|
||||
.fold(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue