Merge pull request #156 from pop-os/pointer-gestures_jammy

Update smithay, add pointer gestures and security context
This commit is contained in:
Victoria Brekenfeld 2023-09-05 22:58:49 +02:00 committed by GitHub
commit 5fb2feaf4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1607 additions and 429 deletions

31
Cargo.lock generated
View file

@ -1063,17 +1063,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.2" version = "0.3.2"
@ -2230,13 +2219,13 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]] [[package]]
name = "libseat" name = "libseat"
version = "0.1.7" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "845e5c255462c9bc7c71c17b996766b76e3c66f2ddd5846bfbc83f18382aa648" checksum = "54a0adf8d8607a73a5b74cbe4132f57cb349e4bf860103cd089461bbcbc9907e"
dependencies = [ dependencies = [
"errno 0.2.8", "errno",
"libseat-sys", "libseat-sys",
"slog", "log",
] ]
[[package]] [[package]]
@ -3579,7 +3568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"errno 0.3.2", "errno",
"io-lifetimes", "io-lifetimes",
"libc", "libc",
"linux-raw-sys 0.3.8", "linux-raw-sys 0.3.8",
@ -3593,7 +3582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5"
dependencies = [ dependencies = [
"bitflags 2.3.3", "bitflags 2.3.3",
"errno 0.3.2", "errno",
"libc", "libc",
"linux-raw-sys 0.4.3", "linux-raw-sys 0.4.3",
"windows-sys 0.48.0", "windows-sys 0.48.0",
@ -3754,12 +3743,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "slog"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
[[package]] [[package]]
name = "slotmap" name = "slotmap"
version = "1.0.6" version = "1.0.6"
@ -3778,7 +3761,7 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]] [[package]]
name = "smithay" name = "smithay"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/smithay//smithay?rev=02ccc8ca17#02ccc8ca17fbc655d2247124fe628d276cb5179a" source = "git+https://github.com/smithay//smithay?rev=36a0ec69b1#36a0ec69b1a2331b1a2d0e046b026cb85d7d132c"
dependencies = [ dependencies = [
"appendlist", "appendlist",
"ash", "ash",

View file

@ -87,4 +87,4 @@ debug = true
lto = "fat" lto = "fat"
[patch."https://github.com/Smithay/smithay.git"] [patch."https://github.com/Smithay/smithay.git"]
smithay = { git = "https://github.com/smithay//smithay", rev = "02ccc8ca17" } smithay = { git = "https://github.com/smithay//smithay", rev = "36a0ec69b1" }

View file

@ -507,7 +507,11 @@ impl State {
surface surface
.output .output
.current_mode() .current_mode()
.map(|mode| mode.refresh as u32) .map(|mode| {
Duration::from_secs_f64(
1_000.0 / mode.refresh as f64,
)
})
.unwrap_or_default(), .unwrap_or_default(),
seq as u64, seq as u64,
flags, flags,
@ -1002,19 +1006,20 @@ fn get_surface_dmabuf_feedback(
.collect::<HashSet<_>>(); .collect::<HashSet<_>>();
let surface = compositor.surface(); let surface = compositor.surface();
let planes = surface.planes().unwrap(); let planes = surface.planes();
// We limit the scan-out trache to formats we can also render from // We limit the scan-out trache to formats we can also render from
// so that there is always a fallback render path available in case // so that there is always a fallback render path available in case
// the supplied buffer can not be scanned out directly // the supplied buffer can not be scanned out directly
let planes_formats = surface let planes_formats = planes
.supported_formats(planes.primary.handle) .primary
.unwrap() .formats
.into_iter() .iter()
.cloned()
.chain( .chain(
planes planes
.overlay .overlay
.iter() .iter()
.flat_map(|p| surface.supported_formats(p.handle).unwrap()), .flat_map(|p| p.formats.iter().cloned()),
) )
.collect::<HashSet<_>>() .collect::<HashSet<_>>()
.intersection(&combined_formats) .intersection(&combined_formats)
@ -1330,9 +1335,7 @@ impl KmsState {
let driver = drm let driver = drm
.get_driver() .get_driver()
.with_context(|| "Failed to query drm driver")?; .with_context(|| "Failed to query drm driver")?;
let mut planes = drm_surface let mut planes = drm_surface.planes().clone();
.planes()
.with_context(|| "Failed to query drm planes")?;
// QUIRK: Using an overlay plane on a nvidia card breaks the display controller (wtf...) // QUIRK: Using an overlay plane on a nvidia card breaks the display controller (wtf...)
if driver if driver
.name() .name()

View file

@ -30,7 +30,7 @@ use smithay::{
utils::Transform, utils::Transform,
wayland::dmabuf::DmabufFeedbackBuilder, wayland::dmabuf::DmabufFeedbackBuilder,
}; };
use std::cell::RefCell; use std::{cell::RefCell, time::Duration};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
@ -94,7 +94,7 @@ impl WinitState {
state.clock.now(), state.clock.now(),
self.output self.output
.current_mode() .current_mode()
.map(|mode| mode.refresh as u32) .map(|mode| Duration::from_secs_f64(1_000.0 / mode.refresh as f64))
.unwrap_or_default(), .unwrap_or_default(),
0, 0,
wp_presentation_feedback::Kind::Vsync, wp_presentation_feedback::Kind::Vsync,

View file

@ -39,7 +39,7 @@ use smithay::{
utils::{DeviceFd, Transform}, utils::{DeviceFd, Transform},
wayland::dmabuf::DmabufFeedbackBuilder, wayland::dmabuf::DmabufFeedbackBuilder,
}; };
use std::{cell::RefCell, os::unix::io::OwnedFd}; use std::{cell::RefCell, os::unix::io::OwnedFd, time::Duration};
use tracing::{debug, error, info, warn}; use tracing::{debug, error, info, warn};
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
@ -260,7 +260,7 @@ impl Surface {
state.clock.now(), state.clock.now(),
self.output self.output
.current_mode() .current_mode()
.map(|mode| mode.refresh as u32) .map(|mode| Duration::from_secs_f64(1_000.0 / mode.refresh as f64))
.unwrap_or_default(), .unwrap_or_default(),
0, 0,
wp_presentation_feedback::Kind::Vsync, wp_presentation_feedback::Kind::Vsync,

View file

@ -18,13 +18,19 @@ use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::Inp
#[allow(deprecated)] #[allow(deprecated)]
use smithay::{ use smithay::{
backend::input::{ backend::input::{
Axis, AxisSource, Device, DeviceCapability, InputBackend, InputEvent, KeyState, Axis, AxisSource, Device, DeviceCapability, GestureBeginEvent, GestureEndEvent,
PointerAxisEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _, InputBackend, InputEvent,
KeyState, PointerAxisEvent,
}, },
desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType}, desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType},
input::{ input::{
keyboard::{keysyms, FilterResult, KeysymHandle, XkbConfig}, keyboard::{keysyms, FilterResult, KeysymHandle, XkbConfig},
pointer::{AxisFrame, ButtonEvent, CursorImageStatus, MotionEvent, RelativeMotionEvent}, pointer::{
AxisFrame, ButtonEvent, CursorImageStatus, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent,
RelativeMotionEvent,
},
Seat, SeatState, Seat, SeatState,
}, },
output::Output, output::Output,
@ -220,14 +226,15 @@ impl State {
use smithay::backend::input::KeyboardKeyEvent; use smithay::backend::input::KeyboardKeyEvent;
let loop_handle = self.common.event_loop_handle.clone(); let loop_handle = self.common.event_loop_handle.clone();
let device = event.device();
for seat in self.common.seats().cloned().collect::<Vec<_>>().iter() { if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
let userdata = seat.user_data();
let current_output = seat.active_output(); let current_output = seat.active_output();
let workspace = self.common.shell.active_space_mut(&current_output); let workspace = self.common.shell.active_space_mut(&current_output);
let shortcuts_inhibited = workspace let shortcuts_inhibited = workspace
.focus_stack .focus_stack
.get(seat) .get(&seat)
.last() .last()
.and_then(|window| { .and_then(|window| {
window.wl_surface().and_then(|surface| { window.wl_surface().and_then(|surface| {
@ -237,16 +244,13 @@ impl State {
.map(|inhibitor| inhibitor.is_active()) .map(|inhibitor| inhibitor.is_active())
.unwrap_or(false); .unwrap_or(false);
let userdata = seat.user_data(); let keycode = event.key_code();
let devices = userdata.get::<Devices>().unwrap(); let state = event.state();
if devices.has_device(&device) { trace!(?keycode, ?state, "key");
let keycode = event.key_code();
let state = event.state();
trace!(?keycode, ?state, "key");
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
let time = Event::time_msec(&event); let time = Event::time_msec(&event);
if let Some((action, pattern)) = seat if let Some((action, pattern)) = seat
.get_keyboard() .get_keyboard()
.unwrap() .unwrap()
.input( .input(
@ -366,7 +370,7 @@ impl State {
// Pass keys to debug interface, if it has focus // Pass keys to debug interface, if it has focus
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
{ {
if data.common.seats().position(|x| x == seat).unwrap() == 0 if data.common.seats().position(|x| x == &seat).unwrap() == 0
&& data.common.egui.active && data.common.egui.active
{ {
if data.common.egui.state.wants_keyboard() { if data.common.egui.state.wants_keyboard() {
@ -427,223 +431,224 @@ impl State {
) )
.flatten() .flatten()
{ {
self.handle_action(action, seat, serial, time, pattern, None) self.handle_action(action, &seat, serial, time, pattern, None)
} }
break;
}
} }
} }
InputEvent::PointerMotion { event, .. } => { InputEvent::PointerMotion { event, .. } => {
use smithay::backend::input::PointerMotionEvent; use smithay::backend::input::PointerMotionEvent;
let device = event.device(); if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
for seat in self.common.seats().cloned().collect::<Vec<_>>().iter() { let current_output = seat.active_output();
let userdata = seat.user_data();
let devices = userdata.get::<Devices>().unwrap();
if devices.has_device(&device) {
let current_output = seat.active_output();
let mut position = seat.get_pointer().unwrap().current_location(); let mut position = seat.get_pointer().unwrap().current_location();
position += event.delta(); position += event.delta();
let output = self let output = self
.common .common
.shell .shell
.outputs() .outputs()
.find(|output| output.geometry().to_f64().contains(position)) .find(|output| output.geometry().to_f64().contains(position))
.cloned() .cloned()
.unwrap_or(current_output.clone()); .unwrap_or(current_output.clone());
if output != current_output { if output != current_output {
for session in sessions_for_output(&self.common, &current_output) { for session in sessions_for_output(&self.common, &current_output) {
session.cursor_leave(seat, InputType::Pointer); session.cursor_leave(&seat, InputType::Pointer);
}
for session in sessions_for_output(&self.common, &output) {
session.cursor_enter(seat, InputType::Pointer);
}
seat.set_active_output(&output);
} }
let output_geometry = output.geometry();
position.x = (output_geometry.loc.x as f64)
.max(position.x)
.min((output_geometry.loc.x + output_geometry.size.w) as f64);
position.y = (output_geometry.loc.y as f64)
.max(position.y)
.min((output_geometry.loc.y + output_geometry.size.h) as f64);
let serial = SERIAL_COUNTER.next_serial();
let relative_pos = self.common.shell.map_global_to_space(position, &output);
let overview = self.common.shell.overview_mode();
let workspace = self.common.shell.workspaces.active_mut(&output);
let under = State::surface_under(
position,
relative_pos,
&output,
output_geometry,
&self.common.shell.override_redirect_windows,
overview,
workspace,
);
for session in sessions_for_output(&self.common, &output) { for session in sessions_for_output(&self.common, &output) {
if let Some((geometry, offset)) = seat.cursor_geometry( session.cursor_enter(&seat, InputType::Pointer);
position.to_buffer(
output.current_scale().fractional_scale(),
output.current_transform(),
&output.geometry().size.to_f64(),
),
self.common.clock.now(),
) {
session.cursor_info(seat, InputType::Pointer, geometry, offset);
}
} }
let ptr = seat.get_pointer().unwrap();
ptr.motion( seat.set_active_output(&output);
self, }
under.clone(), let output_geometry = output.geometry();
&MotionEvent {
location: position, position.x = (output_geometry.loc.x as f64)
serial, .max(position.x)
time: event.time_msec(), .min((output_geometry.loc.x + output_geometry.size.w) as f64);
}, position.y = (output_geometry.loc.y as f64)
); .max(position.y)
ptr.relative_motion( .min((output_geometry.loc.y + output_geometry.size.h) as f64);
self,
under, let serial = SERIAL_COUNTER.next_serial();
&RelativeMotionEvent { let relative_pos = self.common.shell.map_global_to_space(position, &output);
delta: event.delta(), let overview = self.common.shell.overview_mode();
delta_unaccel: event.delta_unaccel(), let workspace = self.common.shell.workspaces.active_mut(&output);
utime: event.time(), let under = State::surface_under(
}, position,
); relative_pos,
#[cfg(feature = "debug")] &output,
if self.common.seats().position(|x| x == seat).unwrap() == 0 { output_geometry,
let location = if let Some(output) = self.common.shell.outputs.first() { &self.common.shell.override_redirect_windows,
self.common overview,
.shell workspace,
.map_global_to_space(position, output) );
.to_i32_round()
} else { for session in sessions_for_output(&self.common, &output) {
position.to_i32_round() if let Some((geometry, offset)) = seat.cursor_geometry(
}; position.to_buffer(
self.common.egui.state.handle_pointer_motion(location); output.current_scale().fractional_scale(),
output.current_transform(),
&output.geometry().size.to_f64(),
),
self.common.clock.now(),
) {
session.cursor_info(&seat, InputType::Pointer, geometry, offset);
} }
break; }
let ptr = seat.get_pointer().unwrap();
ptr.motion(
self,
under.clone(),
&MotionEvent {
location: position,
serial,
time: event.time_msec(),
},
);
ptr.relative_motion(
self,
under,
&RelativeMotionEvent {
delta: event.delta(),
delta_unaccel: event.delta_unaccel(),
utime: event.time(),
},
);
#[cfg(feature = "debug")]
if self.common.seats().position(|x| x == &seat).unwrap() == 0 {
let location = if let Some(output) = self.common.shell.outputs.first() {
self.common
.shell
.map_global_to_space(position, output)
.to_i32_round()
} else {
position.to_i32_round()
};
self.common.egui.state.handle_pointer_motion(location);
} }
} }
} }
InputEvent::PointerMotionAbsolute { event, .. } => { InputEvent::PointerMotionAbsolute { event, .. } => {
let device = event.device(); if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
for seat in self.common.seats().cloned().collect::<Vec<_>>().iter() { let output = seat.active_output();
let userdata = seat.user_data(); let geometry = output.geometry();
let devices = userdata.get::<Devices>().unwrap(); let position = geometry.loc.to_f64()
if devices.has_device(&device) { + smithay::backend::input::AbsolutePositionEvent::position_transformed(
let output = seat.active_output(); &event,
let geometry = output.geometry(); geometry.size,
let position = geometry.loc.to_f64()
+ smithay::backend::input::AbsolutePositionEvent::position_transformed(
&event,
geometry.size,
);
let relative_pos = self.common.shell.map_global_to_space(position, &output);
let overview = self.common.shell.overview_mode();
let workspace = self.common.shell.workspaces.active_mut(&output);
let serial = SERIAL_COUNTER.next_serial();
let under = State::surface_under(
position,
relative_pos,
&output,
geometry,
&self.common.shell.override_redirect_windows,
overview,
workspace,
); );
let relative_pos = self.common.shell.map_global_to_space(position, &output);
let overview = self.common.shell.overview_mode();
let workspace = self.common.shell.workspaces.active_mut(&output);
let serial = SERIAL_COUNTER.next_serial();
let under = State::surface_under(
position,
relative_pos,
&output,
geometry,
&self.common.shell.override_redirect_windows,
overview,
workspace,
);
for session in sessions_for_output(&self.common, &output) { for session in sessions_for_output(&self.common, &output) {
if let Some((geometry, offset)) = seat.cursor_geometry( if let Some((geometry, offset)) = seat.cursor_geometry(
position.to_buffer( position.to_buffer(
output.current_scale().fractional_scale(), output.current_scale().fractional_scale(),
output.current_transform(), output.current_transform(),
&output.geometry().size.to_f64(), &output.geometry().size.to_f64(),
), ),
self.common.clock.now(), self.common.clock.now(),
) { ) {
session.cursor_info(seat, InputType::Pointer, geometry, offset); session.cursor_info(&seat, InputType::Pointer, geometry, offset);
}
} }
seat.get_pointer().unwrap().motion( }
self, seat.get_pointer().unwrap().motion(
under, self,
&MotionEvent { under,
location: position, &MotionEvent {
serial, location: position,
time: event.time_msec(), serial,
}, time: event.time_msec(),
); },
#[cfg(feature = "debug")] );
if self.common.seats().position(|x| x == seat).unwrap() == 0 { #[cfg(feature = "debug")]
let location = if let Some(output) = self.common.shell.outputs.first() { if self.common.seats().position(|x| x == &seat).unwrap() == 0 {
self.common let location = if let Some(output) = self.common.shell.outputs.first() {
.shell self.common
.map_global_to_space(position, output) .shell
.to_i32_round() .map_global_to_space(position, output)
} else { .to_i32_round()
position.to_i32_round() } else {
}; position.to_i32_round()
self.common.egui.state.handle_pointer_motion(location); };
} self.common.egui.state.handle_pointer_motion(location);
break;
} }
} }
} }
InputEvent::PointerButton { event, .. } => { InputEvent::PointerButton { event, .. } => {
use smithay::backend::input::{ButtonState, PointerButtonEvent}; use smithay::backend::input::{ButtonState, PointerButtonEvent};
let device = event.device(); if let Some(seat) = self.common.seat_with_device(&event.device()).cloned() {
for seat in self.common.seats().cloned().collect::<Vec<_>>().iter() { #[cfg(feature = "debug")]
let userdata = seat.user_data(); if self.common.seats().position(|x| x == &seat).unwrap() == 0
let devices = userdata.get::<Devices>().unwrap(); && self.common.egui.active
if devices.has_device(&device) { {
#[cfg(feature = "debug")] if self.common.egui.state.wants_pointer() {
if self.common.seats().position(|x| x == seat).unwrap() == 0 if let Some(button) = event.button() {
&& self.common.egui.active self.common.egui.state.handle_pointer_button(
{ button,
if self.common.egui.state.wants_pointer() { event.state() == ButtonState::Pressed,
if let Some(button) = event.button() { );
self.common.egui.state.handle_pointer_button(
button,
event.state() == ButtonState::Pressed,
);
}
break;
} }
return;
} }
}
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
let button = event.button_code(); let button = event.button_code();
if event.state() == ButtonState::Pressed { if event.state() == ButtonState::Pressed {
// change the keyboard focus unless the pointer or keyboard is grabbed // change the keyboard focus unless the pointer or keyboard is grabbed
// We test for any matching surface type here but always use the root // We test for any matching surface type here but always use the root
// (in case of a window the toplevel) surface for the focus. // (in case of a window the toplevel) surface for the focus.
// see: https://gitlab.freedesktop.org/wayland/wayland/-/issues/294 // see: https://gitlab.freedesktop.org/wayland/wayland/-/issues/294
if !seat.get_pointer().unwrap().is_grabbed() if !seat.get_pointer().unwrap().is_grabbed()
&& !seat.get_keyboard().map(|k| k.is_grabbed()).unwrap_or(false) && !seat.get_keyboard().map(|k| k.is_grabbed()).unwrap_or(false)
{ {
let output = seat.active_output(); let output = seat.active_output();
let pos = seat.get_pointer().unwrap().current_location(); let pos = seat.get_pointer().unwrap().current_location();
let relative_pos = let relative_pos = self.common.shell.map_global_to_space(pos, &output);
self.common.shell.map_global_to_space(pos, &output); let overview = self.common.shell.overview_mode();
let overview = self.common.shell.overview_mode(); let workspace = self.common.shell.active_space_mut(&output);
let workspace = self.common.shell.active_space_mut(&output); let mut under = None;
let mut under = None;
if let Some(window) = workspace.get_fullscreen(&output) { if let Some(window) = workspace.get_fullscreen(&output) {
let layers = layer_map_for_output(&output);
if let Some(layer) =
layers.layer_under(WlrLayer::Overlay, relative_pos)
{
let layer_loc = layers.layer_geometry(layer).unwrap().loc;
if layer.can_receive_keyboard_focus()
&& layer
.surface_under(
relative_pos - layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.is_some()
{
under = Some(layer.clone().into());
}
} else {
under = Some(window.clone().into());
}
} else {
let done = {
let layers = layer_map_for_output(&output); let layers = layer_map_for_output(&output);
if let Some(layer) = if let Some(layer) = layers
layers.layer_under(WlrLayer::Overlay, relative_pos) .layer_under(WlrLayer::Overlay, relative_pos)
.or_else(|| layers.layer_under(WlrLayer::Top, relative_pos))
{ {
let layer_loc = layers.layer_geometry(layer).unwrap().loc; let layer_loc = layers.layer_geometry(layer).unwrap().loc;
if layer.can_receive_keyboard_focus() if layer.can_receive_keyboard_focus()
@ -656,17 +661,22 @@ impl State {
{ {
under = Some(layer.clone().into()); under = Some(layer.clone().into());
} }
true
} else { } else {
under = Some(window.clone().into()); false
} }
} else { };
let done = { if !done {
if let Some((target, _)) =
workspace.element_under(relative_pos, overview)
{
under = Some(target);
} else {
let layers = layer_map_for_output(&output); let layers = layer_map_for_output(&output);
if let Some(layer) = layers if let Some(layer) =
.layer_under(WlrLayer::Overlay, relative_pos) layers.layer_under(WlrLayer::Bottom, pos).or_else(
.or_else(|| { || layers.layer_under(WlrLayer::Background, pos),
layers.layer_under(WlrLayer::Top, relative_pos) )
})
{ {
let layer_loc = let layer_loc =
layers.layer_geometry(layer).unwrap().loc; layers.layer_geometry(layer).unwrap().loc;
@ -680,67 +690,35 @@ impl State {
{ {
under = Some(layer.clone().into()); under = Some(layer.clone().into());
} }
true };
} else {
false
}
};
if !done {
if let Some((target, _)) =
workspace.element_under(relative_pos, overview)
{
under = Some(target);
} else {
let layers = layer_map_for_output(&output);
if let Some(layer) = layers
.layer_under(WlrLayer::Bottom, pos)
.or_else(|| {
layers.layer_under(WlrLayer::Background, pos)
})
{
let layer_loc =
layers.layer_geometry(layer).unwrap().loc;
if layer.can_receive_keyboard_focus()
&& layer
.surface_under(
relative_pos - layer_loc.to_f64(),
WindowSurfaceType::ALL,
)
.is_some()
{
under = Some(layer.clone().into());
}
};
}
} }
} }
Common::set_focus(
self,
under.and_then(|target| target.try_into().ok()).as_ref(),
seat,
Some(serial),
);
} }
} else { Common::set_focus(
if let OverviewMode::Started(Trigger::Pointer(action_button), _) = self,
self.common.shell.overview_mode() under.and_then(|target| target.try_into().ok()).as_ref(),
{ &seat,
if action_button == button { Some(serial),
self.common.shell.set_overview_mode(None); );
} }
} else {
if let OverviewMode::Started(Trigger::Pointer(action_button), _) =
self.common.shell.overview_mode()
{
if action_button == button {
self.common.shell.set_overview_mode(None);
} }
}; }
seat.get_pointer().unwrap().button( };
self, seat.get_pointer().unwrap().button(
&ButtonEvent { self,
button, &ButtonEvent {
state: event.state(), button,
serial, state: event.state(),
time: event.time_msec(), serial,
}, time: event.time_msec(),
); },
break; );
}
} }
} }
InputEvent::PointerAxis { event, .. } => { InputEvent::PointerAxis { event, .. } => {
@ -753,8 +731,7 @@ impl State {
1.0 1.0
}; };
let device = event.device(); if let Some(seat) = self.common.seat_with_device(&event.device()) {
for seat in self.common.seats().cloned().collect::<Vec<_>>().iter() {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
if self.common.seats().position(|x| x == seat).unwrap() == 0 if self.common.seats().position(|x| x == seat).unwrap() == 0
&& self.common.egui.active && self.common.egui.active
@ -770,50 +747,152 @@ impl State {
.or_else(|| event.amount(Axis::Vertical).map(|x| x * 3.0)) .or_else(|| event.amount(Axis::Vertical).map(|x| x * 3.0))
.unwrap_or(0.0), .unwrap_or(0.0),
); );
break; return;
} }
} }
let userdata = seat.user_data(); let horizontal_amount = event.amount(Axis::Horizontal).unwrap_or_else(|| {
let devices = userdata.get::<Devices>().unwrap(); event.amount_discrete(Axis::Horizontal).unwrap_or(0.0) * 3.0
if devices.has_device(&device) { });
let horizontal_amount = let vertical_amount = event.amount(Axis::Vertical).unwrap_or_else(|| {
event.amount(Axis::Horizontal).unwrap_or_else(|| { event.amount_discrete(Axis::Vertical).unwrap_or(0.0) * 3.0
event.amount_discrete(Axis::Horizontal).unwrap_or(0.0) * 3.0 });
}); let horizontal_amount_discrete = event.amount_discrete(Axis::Horizontal);
let vertical_amount = event.amount(Axis::Vertical).unwrap_or_else(|| { let vertical_amount_discrete = event.amount_discrete(Axis::Vertical);
event.amount_discrete(Axis::Vertical).unwrap_or(0.0) * 3.0
});
let horizontal_amount_discrete = event.amount_discrete(Axis::Horizontal);
let vertical_amount_discrete = event.amount_discrete(Axis::Vertical);
{ {
let mut frame = let mut frame = AxisFrame::new(event.time_msec()).source(event.source());
AxisFrame::new(event.time_msec()).source(event.source()); if horizontal_amount != 0.0 {
if horizontal_amount != 0.0 { frame =
frame = frame frame.value(Axis::Horizontal, scroll_factor * horizontal_amount);
.value(Axis::Horizontal, scroll_factor * horizontal_amount); if let Some(discrete) = horizontal_amount_discrete {
if let Some(discrete) = horizontal_amount_discrete { frame = frame.discrete(Axis::Horizontal, discrete as i32);
frame = frame.discrete(Axis::Horizontal, discrete as i32);
}
} else if event.source() == AxisSource::Finger {
frame = frame.stop(Axis::Horizontal);
} }
if vertical_amount != 0.0 { } else if event.source() == AxisSource::Finger {
frame = frame = frame.stop(Axis::Horizontal);
frame.value(Axis::Vertical, scroll_factor * vertical_amount);
if let Some(discrete) = vertical_amount_discrete {
frame = frame.discrete(Axis::Vertical, discrete as i32);
}
} else if event.source() == AxisSource::Finger {
frame = frame.stop(Axis::Vertical);
}
seat.get_pointer().unwrap().axis(self, frame);
} }
break; if vertical_amount != 0.0 {
frame = frame.value(Axis::Vertical, scroll_factor * vertical_amount);
if let Some(discrete) = vertical_amount_discrete {
frame = frame.discrete(Axis::Vertical, discrete as i32);
}
} else if event.source() == AxisSource::Finger {
frame = frame.stop(Axis::Vertical);
}
seat.get_pointer().unwrap().axis(self, frame);
} }
} }
} }
InputEvent::GestureSwipeBegin { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let serial = SERIAL_COUNTER.next_serial();
let pointer = seat.get_pointer().unwrap();
pointer.gesture_swipe_begin(
self,
&GestureSwipeBeginEvent {
serial,
time: event.time_msec(),
fingers: event.fingers(),
},
);
}
}
InputEvent::GestureSwipeUpdate { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let pointer = seat.get_pointer().unwrap();
pointer.gesture_swipe_update(
self,
&GestureSwipeUpdateEvent {
time: event.time_msec(),
delta: event.delta(),
},
);
}
}
InputEvent::GestureSwipeEnd { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let serial = SERIAL_COUNTER.next_serial();
let pointer = seat.get_pointer().unwrap();
pointer.gesture_swipe_end(
self,
&GestureSwipeEndEvent {
serial,
time: event.time_msec(),
cancelled: event.cancelled(),
},
);
}
}
InputEvent::GesturePinchBegin { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let serial = SERIAL_COUNTER.next_serial();
let pointer = seat.get_pointer().unwrap();
pointer.gesture_pinch_begin(
self,
&GesturePinchBeginEvent {
serial,
time: event.time_msec(),
fingers: event.fingers(),
},
);
}
}
InputEvent::GesturePinchUpdate { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let pointer = seat.get_pointer().unwrap();
pointer.gesture_pinch_update(
self,
&GesturePinchUpdateEvent {
time: event.time_msec(),
delta: event.delta(),
scale: event.scale(),
rotation: event.rotation(),
},
);
}
}
InputEvent::GesturePinchEnd { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let serial = SERIAL_COUNTER.next_serial();
let pointer = seat.get_pointer().unwrap();
pointer.gesture_pinch_end(
self,
&GesturePinchEndEvent {
serial,
time: event.time_msec(),
cancelled: event.cancelled(),
},
);
}
}
InputEvent::GestureHoldBegin { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let serial = SERIAL_COUNTER.next_serial();
let pointer = seat.get_pointer().unwrap();
pointer.gesture_hold_begin(
self,
&GestureHoldBeginEvent {
serial,
time: event.time_msec(),
fingers: event.fingers(),
},
);
}
}
InputEvent::GestureHoldEnd { event, .. } => {
if let Some(seat) = self.common.seat_with_device(&event.device()) {
let serial = SERIAL_COUNTER.next_serial();
let pointer = seat.get_pointer().unwrap();
pointer.gesture_hold_end(
self,
&GestureHoldEndEvent {
serial,
time: event.time_msec(),
cancelled: event.cancelled(),
},
);
}
}
_ => { /* TODO e.g. tablet or touch events */ } _ => { /* TODO e.g. tablet or touch events */ }
} }
} }

View file

@ -25,7 +25,12 @@ use smithay::{
desktop::{space::SpaceElement, PopupManager, WindowSurfaceType}, desktop::{space::SpaceElement, PopupManager, WindowSurfaceType},
input::{ input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{AxisFrame, ButtonEvent, MotionEvent, PointerTarget, RelativeMotionEvent}, pointer::{
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent,
PointerTarget, RelativeMotionEvent,
},
Seat, Seat,
}, },
output::Output, output::Output,
@ -909,6 +914,127 @@ impl PointerTarget<State> for CosmicMapped {
_ => {} _ => {}
} }
} }
fn gesture_swipe_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeBeginEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_swipe_begin(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_swipe_begin(w, seat, data, event)
}
_ => {}
}
}
fn gesture_swipe_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeUpdateEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_swipe_update(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_swipe_update(w, seat, data, event)
}
_ => {}
}
}
fn gesture_swipe_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeEndEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_swipe_end(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_swipe_end(w, seat, data, event)
}
_ => {}
}
}
fn gesture_pinch_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchBeginEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_pinch_begin(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_pinch_begin(w, seat, data, event)
}
_ => {}
}
}
fn gesture_pinch_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchUpdateEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_pinch_update(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_pinch_update(w, seat, data, event)
}
_ => {}
}
}
fn gesture_pinch_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchEndEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_pinch_end(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_pinch_end(w, seat, data, event)
}
_ => {}
}
}
fn gesture_hold_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureHoldBeginEvent,
) {
match &self.element {
CosmicMappedInternal::Stack(s) => {
PointerTarget::gesture_hold_begin(s, seat, data, event)
}
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_hold_begin(w, seat, data, event)
}
_ => {}
}
}
fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {
match &self.element {
CosmicMappedInternal::Stack(s) => PointerTarget::gesture_hold_end(s, seat, data, event),
CosmicMappedInternal::Window(w) => {
PointerTarget::gesture_hold_end(w, seat, data, event)
}
_ => {}
}
}
} }
impl WaylandFocus for CosmicMapped { impl WaylandFocus for CosmicMapped {

View file

@ -32,8 +32,10 @@ use smithay::{
input::{ input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{ pointer::{
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
PointerTarget, RelativeMotionEvent, GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
GrabStartData as PointerGrabStartData, MotionEvent, PointerTarget, RelativeMotionEvent,
}, },
Seat, Seat,
}, },
@ -1179,6 +1181,113 @@ impl PointerTarget<State> for CosmicStack {
_ => {} _ => {}
} }
} }
fn gesture_swipe_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeBeginEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_swipe_begin(seat, data, event)
}
})
}
fn gesture_swipe_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeUpdateEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_swipe_update(seat, data, event)
}
})
}
fn gesture_swipe_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeEndEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_swipe_end(seat, data, event)
}
})
}
fn gesture_pinch_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchBeginEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_pinch_begin(seat, data, event)
}
})
}
fn gesture_pinch_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchUpdateEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_pinch_update(seat, data, event)
}
})
}
fn gesture_pinch_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchEndEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_pinch_end(seat, data, event)
}
})
}
fn gesture_hold_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureHoldBeginEvent,
) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_hold_begin(seat, data, event)
}
})
}
fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {
self.0.with_program(|p| {
if p.current_focus() == Focus::Window {
let window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
window.gesture_hold_end(seat, data, event)
}
})
}
} }
render_elements! { render_elements! {

View file

@ -17,7 +17,16 @@ use smithay::{
}, },
PopupManager, Window, PopupManager, Window,
}, },
input::{keyboard::KeyboardTarget, pointer::PointerTarget}, input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent,
PointerTarget, RelativeMotionEvent,
},
Seat,
},
output::Output, output::Output,
reexports::{ reexports::{
wayland_protocols::{ wayland_protocols::{
@ -34,12 +43,15 @@ use smithay::{
wayland::{ wayland::{
compositor::{with_states, SurfaceData}, compositor::{with_states, SurfaceData},
seat::WaylandFocus, seat::WaylandFocus,
shell::xdg::{ToplevelSurface, XdgToplevelSurfaceData}, shell::xdg::{SurfaceCachedState, ToplevelSurface, XdgToplevelSurfaceData},
}, },
xwayland::{xwm::X11Relatable, X11Surface}, xwayland::{xwm::X11Relatable, X11Surface},
}; };
use crate::{state::SurfaceDmabufFeedback, wayland::handlers::decoration::PreferredDecorationMode}; use crate::{
state::{State, SurfaceDmabufFeedback},
wayland::handlers::decoration::PreferredDecorationMode,
};
space_elements! { space_elements! {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -363,13 +375,7 @@ impl CosmicSurface {
match self { match self {
CosmicSurface::Wayland(window) => { CosmicSurface::Wayland(window) => {
Some(with_states(window.toplevel().wl_surface(), |states| { Some(with_states(window.toplevel().wl_surface(), |states| {
let attrs = states states.cached_state.current::<SurfaceCachedState>().min_size
.data_map
.get::<XdgToplevelSurfaceData>()
.unwrap()
.lock()
.unwrap();
attrs.min_size
})) }))
.filter(|size| !(size.w == 0 && size.h == 0)) .filter(|size| !(size.w == 0 && size.h == 0))
} }
@ -389,13 +395,7 @@ impl CosmicSurface {
match self { match self {
CosmicSurface::Wayland(window) => { CosmicSurface::Wayland(window) => {
Some(with_states(window.toplevel().wl_surface(), |states| { Some(with_states(window.toplevel().wl_surface(), |states| {
let attrs = states states.cached_state.current::<SurfaceCachedState>().max_size
.data_map
.get::<XdgToplevelSurfaceData>()
.unwrap()
.lock()
.unwrap();
attrs.max_size
})) }))
.filter(|size| !(size.w == 0 && size.h == 0)) .filter(|size| !(size.w == 0 && size.h == 0))
} }
@ -638,12 +638,12 @@ impl CosmicSurface {
} }
} }
impl KeyboardTarget<crate::state::State> for CosmicSurface { impl KeyboardTarget<State> for CosmicSurface {
fn enter( fn enter(
&self, &self,
seat: &smithay::input::Seat<crate::state::State>, seat: &Seat<State>,
data: &mut crate::state::State, data: &mut State,
keys: Vec<smithay::input::keyboard::KeysymHandle<'_>>, keys: Vec<KeysymHandle<'_>>,
serial: smithay::utils::Serial, serial: smithay::utils::Serial,
) { ) {
match self { match self {
@ -657,12 +657,7 @@ impl KeyboardTarget<crate::state::State> for CosmicSurface {
} }
} }
fn leave( fn leave(&self, seat: &Seat<State>, data: &mut State, serial: smithay::utils::Serial) {
&self,
seat: &smithay::input::Seat<crate::state::State>,
data: &mut crate::state::State,
serial: smithay::utils::Serial,
) {
match self { match self {
CosmicSurface::Wayland(window) => KeyboardTarget::leave(window, seat, data, serial), CosmicSurface::Wayland(window) => KeyboardTarget::leave(window, seat, data, serial),
CosmicSurface::X11(surface) => KeyboardTarget::leave(surface, seat, data, serial), CosmicSurface::X11(surface) => KeyboardTarget::leave(surface, seat, data, serial),
@ -672,9 +667,9 @@ impl KeyboardTarget<crate::state::State> for CosmicSurface {
fn key( fn key(
&self, &self,
seat: &smithay::input::Seat<crate::state::State>, seat: &Seat<State>,
data: &mut crate::state::State, data: &mut State,
key: smithay::input::keyboard::KeysymHandle<'_>, key: KeysymHandle<'_>,
state: smithay::backend::input::KeyState, state: smithay::backend::input::KeyState,
serial: smithay::utils::Serial, serial: smithay::utils::Serial,
time: u32, time: u32,
@ -692,9 +687,9 @@ impl KeyboardTarget<crate::state::State> for CosmicSurface {
fn modifiers( fn modifiers(
&self, &self,
seat: &smithay::input::Seat<crate::state::State>, seat: &Seat<State>,
data: &mut crate::state::State, data: &mut State,
modifiers: smithay::input::keyboard::ModifiersState, modifiers: ModifiersState,
serial: smithay::utils::Serial, serial: smithay::utils::Serial,
) { ) {
match self { match self {
@ -709,13 +704,8 @@ impl KeyboardTarget<crate::state::State> for CosmicSurface {
} }
} }
impl PointerTarget<crate::state::State> for CosmicSurface { impl PointerTarget<State> for CosmicSurface {
fn enter( fn enter(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {
&self,
seat: &smithay::input::Seat<crate::state::State>,
data: &mut crate::state::State,
event: &smithay::input::pointer::MotionEvent,
) {
match self { match self {
CosmicSurface::Wayland(window) => PointerTarget::enter(window, seat, data, event), CosmicSurface::Wayland(window) => PointerTarget::enter(window, seat, data, event),
CosmicSurface::X11(surface) => PointerTarget::enter(surface, seat, data, event), CosmicSurface::X11(surface) => PointerTarget::enter(surface, seat, data, event),
@ -723,12 +713,7 @@ impl PointerTarget<crate::state::State> for CosmicSurface {
} }
} }
fn motion( fn motion(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {
&self,
seat: &smithay::input::Seat<crate::state::State>,
data: &mut crate::state::State,
event: &smithay::input::pointer::MotionEvent,
) {
match self { match self {
CosmicSurface::Wayland(window) => PointerTarget::motion(window, seat, data, event), CosmicSurface::Wayland(window) => PointerTarget::motion(window, seat, data, event),
CosmicSurface::X11(surface) => PointerTarget::motion(surface, seat, data, event), CosmicSurface::X11(surface) => PointerTarget::motion(surface, seat, data, event),
@ -736,12 +721,7 @@ impl PointerTarget<crate::state::State> for CosmicSurface {
} }
} }
fn relative_motion( fn relative_motion(&self, seat: &Seat<State>, data: &mut State, event: &RelativeMotionEvent) {
&self,
seat: &smithay::input::Seat<crate::state::State>,
data: &mut crate::state::State,
event: &smithay::input::pointer::RelativeMotionEvent,
) {
match self { match self {
CosmicSurface::Wayland(window) => { CosmicSurface::Wayland(window) => {
PointerTarget::relative_motion(window, seat, data, event) PointerTarget::relative_motion(window, seat, data, event)
@ -753,12 +733,7 @@ impl PointerTarget<crate::state::State> for CosmicSurface {
} }
} }
fn button( fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {
&self,
seat: &smithay::input::Seat<crate::state::State>,
data: &mut crate::state::State,
event: &smithay::input::pointer::ButtonEvent,
) {
match self { match self {
CosmicSurface::Wayland(window) => PointerTarget::button(window, seat, data, event), CosmicSurface::Wayland(window) => PointerTarget::button(window, seat, data, event),
CosmicSurface::X11(surface) => PointerTarget::button(surface, seat, data, event), CosmicSurface::X11(surface) => PointerTarget::button(surface, seat, data, event),
@ -766,12 +741,7 @@ impl PointerTarget<crate::state::State> for CosmicSurface {
} }
} }
fn axis( fn axis(&self, seat: &Seat<State>, data: &mut State, frame: AxisFrame) {
&self,
seat: &smithay::input::Seat<crate::state::State>,
data: &mut crate::state::State,
frame: smithay::input::pointer::AxisFrame,
) {
match self { match self {
CosmicSurface::Wayland(window) => PointerTarget::axis(window, seat, data, frame), CosmicSurface::Wayland(window) => PointerTarget::axis(window, seat, data, frame),
CosmicSurface::X11(surface) => PointerTarget::axis(surface, seat, data, frame), CosmicSurface::X11(surface) => PointerTarget::axis(surface, seat, data, frame),
@ -781,8 +751,8 @@ impl PointerTarget<crate::state::State> for CosmicSurface {
fn leave( fn leave(
&self, &self,
seat: &smithay::input::Seat<crate::state::State>, seat: &Seat<State>,
data: &mut crate::state::State, data: &mut State,
serial: smithay::utils::Serial, serial: smithay::utils::Serial,
time: u32, time: u32,
) { ) {
@ -794,6 +764,137 @@ impl PointerTarget<crate::state::State> for CosmicSurface {
_ => unreachable!(), _ => unreachable!(),
} }
} }
fn gesture_swipe_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeBeginEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_swipe_begin(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_swipe_begin(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_swipe_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeUpdateEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_swipe_update(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_swipe_update(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_swipe_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeEndEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_swipe_end(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_swipe_end(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_pinch_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchBeginEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_pinch_begin(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_pinch_begin(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_pinch_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchUpdateEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_pinch_update(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_pinch_update(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_pinch_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchEndEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_pinch_end(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_pinch_end(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_hold_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureHoldBeginEvent,
) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_hold_begin(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_hold_begin(surface, seat, data, event)
}
_ => unreachable!(),
}
}
fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {
match self {
CosmicSurface::Wayland(window) => {
PointerTarget::gesture_hold_end(window, seat, data, event)
}
CosmicSurface::X11(surface) => {
PointerTarget::gesture_hold_end(surface, seat, data, event)
}
_ => unreachable!(),
}
}
} }
impl WaylandFocus for CosmicSurface { impl WaylandFocus for CosmicSurface {

View file

@ -24,7 +24,12 @@ use smithay::{
desktop::space::SpaceElement, desktop::space::SpaceElement,
input::{ input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{AxisFrame, ButtonEvent, MotionEvent, PointerTarget, RelativeMotionEvent}, pointer::{
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent,
PointerTarget, RelativeMotionEvent,
},
Seat, Seat,
}, },
output::Output, output::Output,
@ -590,6 +595,105 @@ impl PointerTarget<State> for CosmicWindow {
_ => {} _ => {}
} }
} }
fn gesture_swipe_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeBeginEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_swipe_begin(&p.window, seat, data, event)
}
})
}
fn gesture_swipe_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeUpdateEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_swipe_update(&p.window, seat, data, event)
}
})
}
fn gesture_swipe_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeEndEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_swipe_end(&p.window, seat, data, event)
}
})
}
fn gesture_pinch_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchBeginEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_pinch_begin(&p.window, seat, data, event)
}
})
}
fn gesture_pinch_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchUpdateEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_pinch_update(&p.window, seat, data, event)
}
})
}
fn gesture_pinch_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchEndEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_pinch_end(&p.window, seat, data, event)
}
})
}
fn gesture_hold_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureHoldBeginEvent,
) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_hold_begin(&p.window, seat, data, event)
}
})
}
fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {
self.0.with_program(|p| {
if !p.has_ssd(false) || p.current_focus() == Focus::Window {
PointerTarget::gesture_hold_end(&p.window, seat, data, event)
}
})
}
} }
render_elements! { render_elements! {

View file

@ -11,7 +11,12 @@ use smithay::{
desktop::{LayerSurface, PopupKind}, desktop::{LayerSurface, PopupKind},
input::{ input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{AxisFrame, ButtonEvent, MotionEvent, PointerTarget, RelativeMotionEvent}, pointer::{
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent,
PointerTarget, RelativeMotionEvent,
},
Seat, Seat,
}, },
output::WeakOutput, output::WeakOutput,
@ -198,6 +203,215 @@ impl PointerTarget<State> for PointerFocusTarget {
PointerFocusTarget::ResizeFork(f) => PointerTarget::leave(f, seat, data, serial, time), PointerFocusTarget::ResizeFork(f) => PointerTarget::leave(f, seat, data, serial, time),
} }
} }
fn gesture_swipe_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeBeginEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_swipe_begin(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_swipe_begin(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_swipe_begin(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_swipe_begin(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_swipe_begin(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_swipe_begin(f, seat, data, event)
}
}
}
fn gesture_swipe_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeUpdateEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_swipe_update(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_swipe_update(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_swipe_update(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_swipe_update(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_swipe_update(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_swipe_update(f, seat, data, event)
}
}
}
fn gesture_swipe_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureSwipeEndEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_swipe_end(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_swipe_end(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_swipe_end(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_swipe_end(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_swipe_end(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_swipe_end(f, seat, data, event)
}
}
}
fn gesture_pinch_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchBeginEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_pinch_begin(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_pinch_begin(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_pinch_begin(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_pinch_begin(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_pinch_begin(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_pinch_begin(f, seat, data, event)
}
}
}
fn gesture_pinch_update(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchUpdateEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_pinch_update(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_pinch_update(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_pinch_update(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_pinch_update(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_pinch_update(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_pinch_update(f, seat, data, event)
}
}
}
fn gesture_pinch_end(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GesturePinchEndEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_pinch_end(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_pinch_end(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_pinch_end(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_pinch_end(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_pinch_end(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_pinch_end(f, seat, data, event)
}
}
}
fn gesture_hold_begin(
&self,
seat: &Seat<State>,
data: &mut State,
event: &GestureHoldBeginEvent,
) {
match self {
PointerFocusTarget::Element(w) => {
PointerTarget::gesture_hold_begin(w, seat, data, event)
}
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_hold_begin(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_hold_begin(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_hold_begin(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_hold_begin(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_hold_begin(f, seat, data, event)
}
}
}
fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {
match self {
PointerFocusTarget::Element(w) => PointerTarget::gesture_hold_end(w, seat, data, event),
PointerFocusTarget::Fullscreen(w) => {
PointerTarget::gesture_hold_end(w, seat, data, event)
}
PointerFocusTarget::LayerSurface(l) => {
PointerTarget::gesture_hold_end(l, seat, data, event)
}
PointerFocusTarget::Popup(p) => {
PointerTarget::gesture_hold_end(p.wl_surface(), seat, data, event)
}
PointerFocusTarget::OverrideRedirect(s) => {
PointerTarget::gesture_hold_end(s, seat, data, event)
}
PointerFocusTarget::ResizeFork(f) => {
PointerTarget::gesture_hold_end(f, seat, data, event)
}
}
}
} }
impl KeyboardTarget<State> for KeyboardFocusTarget { impl KeyboardTarget<State> for KeyboardFocusTarget {

View file

@ -1,7 +1,9 @@
use smithay::{ use smithay::{
input::pointer::{ input::pointer::{
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
PointerInnerHandle, RelativeMotionEvent, GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent,
GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData,
MotionEvent, PointerGrab, PointerInnerHandle, RelativeMotionEvent,
}, },
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel, reexports::wayland_protocols::xdg::shell::server::xdg_toplevel,
utils::{Logical, Point}, utils::{Logical, Point},
@ -150,6 +152,102 @@ impl PointerGrab<State> for ResizeGrab {
} }
} }
fn gesture_swipe_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeBeginEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_swipe_begin(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_swipe_begin(data, handle, event),
}
}
fn gesture_swipe_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeUpdateEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_swipe_update(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_swipe_update(data, handle, event),
}
}
fn gesture_swipe_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeEndEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_swipe_end(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_swipe_end(data, handle, event),
}
}
fn gesture_pinch_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchBeginEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_pinch_begin(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_pinch_begin(data, handle, event),
}
}
fn gesture_pinch_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchUpdateEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_pinch_update(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_pinch_update(data, handle, event),
}
}
fn gesture_pinch_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchEndEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_pinch_end(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_pinch_end(data, handle, event),
}
}
fn gesture_hold_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldBeginEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_hold_begin(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_hold_begin(data, handle, event),
}
}
fn gesture_hold_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldEndEvent,
) {
match self {
ResizeGrab::Floating(grab) => grab.gesture_hold_end(data, handle, event),
ResizeGrab::Tiling(grab) => grab.gesture_hold_end(data, handle, event),
}
}
fn start_data(&self) -> &PointerGrabStartData<State> { fn start_data(&self) -> &PointerGrabStartData<State> {
match self { match self {
ResizeGrab::Floating(grab) => grab.start_data(), ResizeGrab::Floating(grab) => grab.start_data(),

View file

@ -25,8 +25,11 @@ use smithay::{
desktop::space::SpaceElement, desktop::space::SpaceElement,
input::{ input::{
pointer::{ pointer::{
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
PointerGrab, PointerInnerHandle, RelativeMotionEvent, GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, PointerInnerHandle,
RelativeMotionEvent,
}, },
Seat, Seat,
}, },
@ -308,6 +311,78 @@ impl PointerGrab<State> for MoveGrab {
handle.axis(state, details); handle.axis(state, details);
} }
fn gesture_swipe_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event)
}
fn gesture_swipe_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event)
}
fn gesture_swipe_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event)
}
fn gesture_pinch_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event)
}
fn gesture_pinch_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event)
}
fn gesture_pinch_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event)
}
fn gesture_hold_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event)
}
fn gesture_hold_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event)
}
fn start_data(&self) -> &PointerGrabStartData<State> { fn start_data(&self) -> &PointerGrabStartData<State> {
&self.start_data &self.start_data
} }

View file

@ -9,8 +9,10 @@ use crate::{
use smithay::{ use smithay::{
desktop::space::SpaceElement, desktop::space::SpaceElement,
input::pointer::{ input::pointer::{
AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent,
PointerInnerHandle, RelativeMotionEvent, GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent,
GestureSwipeEndEvent, GestureSwipeUpdateEvent, GrabStartData as PointerGrabStartData,
MotionEvent, PointerGrab, PointerInnerHandle, RelativeMotionEvent,
}, },
utils::{IsAlive, Logical, Point, Rectangle, Size}, utils::{IsAlive, Logical, Point, Rectangle, Size},
}; };
@ -162,6 +164,78 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
handle.axis(data, details) handle.axis(data, details)
} }
fn gesture_swipe_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event)
}
fn gesture_swipe_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event)
}
fn gesture_swipe_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event)
}
fn gesture_pinch_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event)
}
fn gesture_pinch_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event)
}
fn gesture_pinch_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event)
}
fn gesture_hold_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event)
}
fn gesture_hold_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event)
}
fn start_data(&self) -> &PointerGrabStartData<State> { fn start_data(&self) -> &PointerGrabStartData<State> {
&self.start_data &self.start_data
} }

View file

@ -10,8 +10,11 @@ use smithay::{
backend::input::ButtonState, backend::input::ButtonState,
input::{ input::{
pointer::{ pointer::{
AxisFrame, ButtonEvent, Focus, GrabStartData as PointerGrabStartData, MotionEvent, AxisFrame, ButtonEvent, Focus, GestureHoldBeginEvent, GestureHoldEndEvent,
PointerGrab, PointerInnerHandle, PointerTarget, RelativeMotionEvent, GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent,
GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, PointerInnerHandle,
PointerTarget, RelativeMotionEvent,
}, },
Seat, Seat,
}, },
@ -99,6 +102,14 @@ impl PointerTarget<State> for ResizeForkTarget {
) { ) {
} }
fn axis(&self, _seat: &Seat<State>, _data: &mut State, _frame: AxisFrame) {} fn axis(&self, _seat: &Seat<State>, _data: &mut State, _frame: AxisFrame) {}
fn gesture_swipe_begin(&self, _: &Seat<State>, _: &mut State, _: &GestureSwipeBeginEvent) {}
fn gesture_swipe_update(&self, _: &Seat<State>, _: &mut State, _: &GestureSwipeUpdateEvent) {}
fn gesture_swipe_end(&self, _: &Seat<State>, _: &mut State, _: &GestureSwipeEndEvent) {}
fn gesture_pinch_begin(&self, _: &Seat<State>, _: &mut State, _: &GesturePinchBeginEvent) {}
fn gesture_pinch_update(&self, _: &Seat<State>, _: &mut State, _: &GesturePinchUpdateEvent) {}
fn gesture_pinch_end(&self, _: &Seat<State>, _: &mut State, _: &GesturePinchEndEvent) {}
fn gesture_hold_begin(&self, _: &Seat<State>, _: &mut State, _: &GestureHoldBeginEvent) {}
fn gesture_hold_end(&self, _: &Seat<State>, _: &mut State, _: &GestureHoldEndEvent) {}
} }
pub struct ResizeForkGrab { pub struct ResizeForkGrab {
@ -223,6 +234,78 @@ impl PointerGrab<State> for ResizeForkGrab {
handle.axis(data, details) handle.axis(data, details)
} }
fn gesture_swipe_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event)
}
fn gesture_swipe_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event)
}
fn gesture_swipe_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event)
}
fn gesture_pinch_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event)
}
fn gesture_pinch_update(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event)
}
fn gesture_pinch_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event)
}
fn gesture_hold_begin(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event)
}
fn gesture_hold_end(
&mut self,
data: &mut State,
handle: &mut PointerInnerHandle<'_, State>,
event: &GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event)
}
fn start_data(&self) -> &PointerGrabStartData<State> { fn start_data(&self) -> &PointerGrabStartData<State> {
&self.start_data &self.start_data
} }

View file

@ -37,6 +37,7 @@ use smithay::{
use crate::{ use crate::{
config::{Config, KeyModifiers, KeyPattern, OutputConfig, WorkspaceMode as ConfigMode}, config::{Config, KeyModifiers, KeyPattern, OutputConfig, WorkspaceMode as ConfigMode},
state::client_has_security_context,
utils::prelude::*, utils::prelude::*,
wayland::protocols::{ wayland::protocols::{
toplevel_info::ToplevelInfoState, toplevel_info::ToplevelInfoState,
@ -583,7 +584,7 @@ impl Shell {
let toplevel_info_state = ToplevelInfoState::new( let toplevel_info_state = ToplevelInfoState::new(
dh, dh,
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged), //|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|_| true, client_has_security_context,
); );
let toplevel_management_state = ToplevelManagementState::new::<State, _>( let toplevel_management_state = ToplevelManagementState::new::<State, _>(
dh, dh,
@ -592,12 +593,12 @@ impl Shell {
ManagementCapabilities::Activate, ManagementCapabilities::Activate,
], ],
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged), //|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|_| true, client_has_security_context,
); );
let mut workspace_state = WorkspaceState::new( let mut workspace_state = WorkspaceState::new(
dh, dh,
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged), //|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|_| true, client_has_security_context,
); );
let tiling_enabled = config.static_conf.tiling_enabled; let tiling_enabled = config.static_conf.tiling_enabled;

View file

@ -7,6 +7,7 @@ use crate::{
x11::X11State, x11::X11State,
}, },
config::{Config, OutputConfig}, config::{Config, OutputConfig},
input::Devices,
shell::{grabs::SeatMoveGrabState, Shell}, shell::{grabs::SeatMoveGrabState, Shell},
utils::prelude::*, utils::prelude::*,
wayland::protocols::{ wayland::protocols::{
@ -30,6 +31,7 @@ use smithay::utils::Rectangle;
use smithay::{ use smithay::{
backend::{ backend::{
drm::DrmNode, drm::DrmNode,
input::Device,
renderer::{ renderer::{
element::{ element::{
default_primary_scanout_output_compare, utils::select_dmabuf_feedback, default_primary_scanout_output_compare, utils::select_dmabuf_feedback,
@ -52,7 +54,7 @@ use smithay::{
wayland_server::{ wayland_server::{
backend::{ClientData, ClientId, DisconnectReason}, backend::{ClientData, ClientId, DisconnectReason},
protocol::wl_shm, protocol::wl_shm,
Display, DisplayHandle, Client, Display, DisplayHandle,
}, },
}, },
utils::{Clock, IsAlive, Monotonic}, utils::{Clock, IsAlive, Monotonic},
@ -63,9 +65,11 @@ use smithay::{
fractional_scale::{with_fractional_scale, FractionalScaleManagerState}, fractional_scale::{with_fractional_scale, FractionalScaleManagerState},
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState, keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState,
output::OutputManagerState, output::OutputManagerState,
pointer_gestures::PointerGesturesState,
presentation::PresentationState, presentation::PresentationState,
primary_selection::PrimarySelectionState, primary_selection::PrimarySelectionState,
seat::WaylandFocus, seat::WaylandFocus,
security_context::{SecurityContext, SecurityContextState},
shell::{kde::decoration::KdeDecorationState, xdg::decoration::XdgDecorationState}, shell::{kde::decoration::KdeDecorationState, xdg::decoration::XdgDecorationState},
shm::ShmState, shm::ShmState,
viewporter::ViewporterState, viewporter::ViewporterState,
@ -100,6 +104,7 @@ pub struct ClientState {
pub drm_node: Option<DrmNode>, pub drm_node: Option<DrmNode>,
pub privileged: bool, pub privileged: bool,
pub evls: LoopSignal, pub evls: LoopSignal,
pub security_context: Option<SecurityContext>,
} }
impl ClientData for ClientState { impl ClientData for ClientState {
fn initialized(&self, _client_id: ClientId) {} fn initialized(&self, _client_id: ClientId) {}
@ -265,6 +270,12 @@ impl BackendData {
} }
} }
pub fn client_has_security_context(client: &Client) -> bool {
client
.get_data::<ClientState>()
.map_or(true, |client_state| client_state.security_context.is_none())
}
impl State { impl State {
pub fn new( pub fn new(
dh: &DisplayHandle, dh: &DisplayHandle,
@ -285,13 +296,14 @@ impl State {
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh); let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh); let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh); let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
let output_configuration_state = OutputConfigurationState::new(dh, |_| true); let output_configuration_state =
OutputConfigurationState::new(dh, client_has_security_context);
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32); let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
let primary_selection_state = PrimarySelectionState::new::<Self>(dh); let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
let screencopy_state = ScreencopyState::new::<Self, _, _>( let screencopy_state = ScreencopyState::new::<Self, _, _>(
dh, dh,
vec![CursorMode::Embedded, CursorMode::Hidden], vec![CursorMode::Embedded, CursorMode::Hidden],
|_| true, client_has_security_context,
); // TODO: privileged ); // TODO: privileged
let shm_state = let shm_state =
ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]); ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]);
@ -301,6 +313,8 @@ impl State {
let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client); let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client);
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh); let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
XWaylandKeyboardGrabState::new::<Self>(&dh); XWaylandKeyboardGrabState::new::<Self>(&dh);
PointerGesturesState::new::<Self>(&dh);
SecurityContextState::new::<Self, _>(&dh, client_has_security_context);
let shell = Shell::new(&config, dh); let shell = Shell::new(&config, dh);
@ -373,6 +387,7 @@ impl State {
}, },
privileged: false, privileged: false,
evls: self.common.event_loop_signal.clone(), evls: self.common.event_loop_signal.clone(),
security_context: None,
} }
} }
@ -383,6 +398,7 @@ impl State {
drm_node: Some(drm_node), drm_node: Some(drm_node),
privileged: false, privileged: false,
evls: self.common.event_loop_signal.clone(), evls: self.common.event_loop_signal.clone(),
security_context: None,
} }
} }
@ -396,6 +412,7 @@ impl State {
}, },
privileged: true, privileged: true,
evls: self.common.event_loop_signal.clone(), evls: self.common.event_loop_signal.clone(),
security_context: None,
} }
} }
} }
@ -421,6 +438,14 @@ impl Common {
self.seats.iter() self.seats.iter()
} }
pub fn seat_with_device<D: Device>(&self, device: &D) -> Option<&Seat<State>> {
self.seats().find(|seat| {
let userdata = seat.user_data();
let devices = userdata.get::<Devices>().unwrap();
devices.has_device(device)
})
}
pub fn last_active_seat(&self) -> &Seat<State> { pub fn last_active_seat(&self) -> &Seat<State> {
self.last_active_seat.as_ref().expect("No seat?") self.last_active_seat.as_ref().expect("No seat?")
} }

View file

@ -44,7 +44,12 @@ use smithay::{
desktop::space::{RenderZindex, SpaceElement}, desktop::space::{RenderZindex, SpaceElement},
input::{ input::{
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState}, keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
pointer::{AxisFrame, ButtonEvent, MotionEvent, PointerTarget, RelativeMotionEvent}, pointer::{
AxisFrame, ButtonEvent, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, MotionEvent,
PointerTarget, RelativeMotionEvent,
},
Seat, Seat,
}, },
output::Output, output::Output,
@ -461,6 +466,63 @@ impl<P: Program + Send + 'static> PointerTarget<crate::state::State> for IcedEle
.queue_event(Event::Mouse(MouseEvent::CursorLeft)); .queue_event(Event::Mouse(MouseEvent::CursorLeft));
let _ = internal.update(true); let _ = internal.update(true);
} }
fn gesture_swipe_begin(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GestureSwipeBeginEvent,
) {
}
fn gesture_swipe_update(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GestureSwipeUpdateEvent,
) {
}
fn gesture_swipe_end(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GestureSwipeEndEvent,
) {
}
fn gesture_pinch_begin(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GesturePinchBeginEvent,
) {
}
fn gesture_pinch_update(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GesturePinchUpdateEvent,
) {
}
fn gesture_pinch_end(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GesturePinchEndEvent,
) {
}
fn gesture_hold_begin(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GestureHoldBeginEvent,
) {
}
fn gesture_hold_end(
&self,
_: &Seat<crate::state::State>,
_: &mut crate::state::State,
_: &GestureHoldEndEvent,
) {
}
} }
impl<P: Program + Send + 'static> KeyboardTarget<crate::state::State> for IcedElement<P> { impl<P: Program + Send + 'static> KeyboardTarget<crate::state::State> for IcedElement<P> {

View file

@ -10,11 +10,13 @@ pub mod keyboard_shortcuts_inhibit;
pub mod layer_shell; pub mod layer_shell;
pub mod output; pub mod output;
pub mod output_configuration; pub mod output_configuration;
pub mod pointer_gestures;
pub mod presentation; pub mod presentation;
pub mod primary_selection; pub mod primary_selection;
pub mod relative_pointer; pub mod relative_pointer;
pub mod screencopy; pub mod screencopy;
pub mod seat; pub mod seat;
pub mod security_context;
pub mod shm; pub mod shm;
pub mod toplevel_info; pub mod toplevel_info;
pub mod toplevel_management; pub mod toplevel_management;

View file

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::state::State;
use smithay::delegate_pointer_gestures;
delegate_pointer_gestures!(State);

View file

@ -0,0 +1,33 @@
use crate::state::{ClientState, State};
use smithay::{
delegate_security_context,
wayland::security_context::{
SecurityContext, SecurityContextHandler, SecurityContextListenerSource,
},
};
use std::sync::Arc;
use tracing::warn;
impl SecurityContextHandler for State {
fn context_created(
&mut self,
source: SecurityContextListenerSource,
security_context: SecurityContext,
) {
self.common
.event_loop_handle
.insert_source(source, move |client_stream, _, data| {
if let Err(err) = data.display.handle().insert_client(
client_stream,
Arc::new(ClientState {
security_context: Some(security_context.clone()),
..data.state.new_client_state()
}),
) {
warn!(?err, "Error adding wayland client");
};
})
.expect("Failed to init the wayland socket source.");
}
}
delegate_security_context!(State);