Support touch drag for SSD toplevels, and stacks

We already direct touch events to Iced, and the Cosmic `HeaderBar`
widget already recognizes drags from touch events. So it seems updating
`last_seat` is all that was needed for windows SSDs.

For stacks, the same works, plus moving using the same logic for
detecting drags that is used for mouse events.
This commit is contained in:
Ian Douglas Scott 2024-04-18 21:19:05 -07:00 committed by Victoria Brekenfeld
parent 5e61ce1ff8
commit 8cee91c88f
2 changed files with 54 additions and 39 deletions

View file

@ -596,6 +596,45 @@ impl CosmicStack {
pub(crate) fn force_redraw(&self) {
self.0.force_redraw();
}
fn start_drag(&self, data: &mut State, seat: &Seat<State>, serial: Serial) {
if let Some(dragged_out) = self
.0
.with_program(|p| p.potential_drag.lock().unwrap().take())
{
if let Some(surface) = self
.0
.with_program(|p| p.windows.lock().unwrap().get(dragged_out).cloned())
{
let seat = seat.clone();
surface.try_force_undecorated(false);
surface.send_configure();
if let Some(surface) = surface.wl_surface() {
let _ = data.common.event_loop_handle.insert_idle(move |state| {
let res = state.common.shell.write().unwrap().move_request(
&surface,
&seat,
serial,
ReleaseMode::NoMouseButtons,
true,
&state.common.config,
&state.common.event_loop_handle,
&state.common.xdg_activation_state,
);
if let Some((grab, focus)) = res {
if grab.is_touch_grab() {
seat.get_touch().unwrap().set_grab(state, grab, serial);
} else {
seat.get_pointer()
.unwrap()
.set_grab(state, grab, serial, focus);
}
}
});
}
}
}
}
}
#[derive(Debug, Clone, Copy)]
@ -1196,43 +1235,7 @@ impl PointerTarget<State> for CosmicStack {
|| event.location.x < 64.0
|| event.location.x > (active_window_geo.size.w as f64 - 64.0)
{
if let Some(dragged_out) = self
.0
.with_program(|p| p.potential_drag.lock().unwrap().take())
{
if let Some(surface) = self
.0
.with_program(|p| p.windows.lock().unwrap().get(dragged_out).cloned())
{
let seat = seat.clone();
let serial = event.serial;
surface.try_force_undecorated(false);
surface.send_configure();
if let Some(surface) = surface.wl_surface() {
let _ = data.common.event_loop_handle.insert_idle(move |state| {
let res = state.common.shell.write().unwrap().move_request(
&surface,
&seat,
serial,
ReleaseMode::NoMouseButtons,
true,
&state.common.config,
&state.common.event_loop_handle,
&state.common.xdg_activation_state,
);
if let Some((grab, focus)) = res {
if grab.is_touch_grab() {
seat.get_touch().unwrap().set_grab(state, grab, serial);
} else {
seat.get_pointer()
.unwrap()
.set_grab(state, grab, serial, focus);
}
}
});
}
}
}
self.start_drag(data, seat, event.serial);
}
}
@ -1423,6 +1426,7 @@ impl TouchTarget<State> for CosmicStack {
fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {
let mut event = event.clone();
let active_window_geo = self.0.with_program(|p| {
*p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial));
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].geometry()
});
event.location -= active_window_geo.loc.to_f64();
@ -1439,7 +1443,15 @@ impl TouchTarget<State> for CosmicStack {
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].geometry()
});
event.location -= active_window_geo.loc.to_f64();
TouchTarget::motion(&self.0, seat, data, &event, seq)
TouchTarget::motion(&self.0, seat, data, &event, seq);
if event.location.y < 0.0
|| event.location.y > TAB_HEIGHT as f64
|| event.location.x < 64.0
|| event.location.x > (active_window_geo.size.w as f64 - 64.0)
{
self.start_drag(data, seat, seq);
}
}
fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {

View file

@ -866,7 +866,10 @@ impl PointerTarget<State> for CosmicWindow {
impl TouchTarget<State> for CosmicWindow {
fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {
let mut event = event.clone();
event.location -= self.0.with_program(|p| p.window.geometry().loc.to_f64());
self.0.with_program(|p| {
event.location -= p.window.geometry().loc.to_f64();
*p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial));
});
TouchTarget::down(&self.0, seat, data, &event, seq)
}