Skip to content

Commit

Permalink
Support touch drag for SSD toplevels, and stacks
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ids1024 authored and Drakulix committed Apr 19, 2024
1 parent 5e61ce1 commit 8cee91c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 39 deletions.
88 changes: 50 additions & 38 deletions src/shell/element/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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();
Expand All @@ -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) {
Expand Down
5 changes: 4 additions & 1 deletion src/shell/element/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down

0 comments on commit 8cee91c

Please sign in to comment.