aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-10-30 08:35:19 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-11-21 09:15:18 +0300
commit0cd8484bdce68fa3eae493dcb220abeb440ab5cd (patch)
tree4653f9ce21015efdde7cc9ddce7e2d239964c72f /src
parent9d522ed51e75d1253793f9f5ec42b8faf36e47e7 (diff)
downloadniri-0cd8484bdce68fa3eae493dcb220abeb440ab5cd.tar.gz
niri-0cd8484bdce68fa3eae493dcb220abeb440ab5cd.tar.bz2
niri-0cd8484bdce68fa3eae493dcb220abeb440ab5cd.zip
Unify pointer & touch move grab, add view offset to it
Diffstat (limited to 'src')
-rw-r--r--src/handlers/xdg_shell.rs35
-rw-r--r--src/input/mod.rs81
-rw-r--r--src/input/move_grab.rs392
-rw-r--r--src/input/touch_move_grab.rs136
-rw-r--r--src/layout/mod.rs30
5 files changed, 386 insertions, 288 deletions
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs
index 20f348ba..171b65fd 100644
--- a/src/handlers/xdg_shell.rs
+++ b/src/handlers/xdg_shell.rs
@@ -40,7 +40,6 @@ use tracing::field::Empty;
use crate::input::move_grab::MoveGrab;
use crate::input::resize_grab::ResizeGrab;
-use crate::input::touch_move_grab::TouchMoveGrab;
use crate::input::touch_resize_grab::TouchResizeGrab;
use crate::input::{PointerOrTouchStartData, DOUBLE_CLICK_TIME};
use crate::layout::ActivateWindow;
@@ -133,33 +132,17 @@ impl XdgShellHandler for State {
let window = mapped.window.clone();
let output = output.clone();
- let output_pos = self
- .niri
- .global_space
- .output_geometry(&output)
- .unwrap()
- .loc
- .to_f64();
-
- let pos_within_output = start_data.location() - output_pos;
-
- if !self
- .niri
- .layout
- .interactive_move_begin(window.clone(), &output, pos_within_output)
- {
- return;
- }
-
- match start_data {
- PointerOrTouchStartData::Pointer(start_data) => {
- let grab = MoveGrab::new(start_data, window, false);
- pointer.set_grab(self, grab, serial, Focus::Clear);
+ match &start_data {
+ PointerOrTouchStartData::Pointer(_) => {
+ if let Some(grab) = MoveGrab::new(self, start_data, window.clone(), true) {
+ pointer.set_grab(self, grab, serial, Focus::Clear);
+ }
}
- PointerOrTouchStartData::Touch(start_data) => {
+ PointerOrTouchStartData::Touch(_) => {
let touch = self.niri.seat.get_touch().unwrap();
- let grab = TouchMoveGrab::new(start_data, window);
- touch.set_grab(self, grab, serial);
+ if let Some(grab) = MoveGrab::new(self, start_data, window.clone(), true) {
+ touch.set_grab(self, grab, serial);
+ }
}
}
diff --git a/src/input/mod.rs b/src/input/mod.rs
index e8a4c5ee..d584c940 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -36,7 +36,6 @@ use smithay::wayland::keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitor;
use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraint};
use smithay::wayland::selection::data_device::DnDGrab;
use smithay::wayland::tablet_manager::{TabletDescriptor, TabletSeatTrait};
-use touch_move_grab::TouchMoveGrab;
use touch_overview_grab::TouchOverviewGrab;
use self::move_grab::MoveGrab;
@@ -59,7 +58,6 @@ pub mod scroll_swipe_gesture;
pub mod scroll_tracker;
pub mod spatial_movement_grab;
pub mod swipe_tracker;
-pub mod touch_move_grab;
pub mod touch_overview_grab;
pub mod touch_resize_grab;
@@ -84,6 +82,28 @@ impl<D: SeatHandler> PointerOrTouchStartData<D> {
PointerOrTouchStartData::Touch(x) => x.location,
}
}
+
+ pub fn unwrap_pointer(&self) -> &PointerGrabStartData<D> {
+ match self {
+ PointerOrTouchStartData::Pointer(x) => x,
+ PointerOrTouchStartData::Touch(_) => panic!("start_data is not Pointer"),
+ }
+ }
+
+ pub fn unwrap_touch(&self) -> &TouchGrabStartData<D> {
+ match self {
+ PointerOrTouchStartData::Pointer(_) => panic!("start_data is not Touch"),
+ PointerOrTouchStartData::Touch(x) => x,
+ }
+ }
+
+ pub fn is_pointer(&self) -> bool {
+ matches!(self, Self::Pointer(_))
+ }
+
+ pub fn is_touch(&self) -> bool {
+ matches!(self, Self::Touch(_))
+ }
}
impl State {
@@ -2773,31 +2793,19 @@ impl State {
let mod_down = modifiers_from_state(mods).contains(mod_key.to_modifiers());
if is_overview_open || mod_down {
let location = pointer.current_location();
- let (output, pos_within_output) = self.niri.output_under(location).unwrap();
- let output = output.clone();
if !is_overview_open {
self.niri.layout.activate_window(&window);
}
- if self.niri.layout.interactive_move_begin(
- window.clone(),
- &output,
- pos_within_output,
- ) {
- let start_data = PointerGrabStartData {
- focus: None,
- button: button_code,
- location,
- };
- let grab = MoveGrab::new(start_data, window.clone(), is_overview_open);
+ let start_data = PointerGrabStartData {
+ focus: None,
+ button: button_code,
+ location,
+ };
+ let start_data = PointerOrTouchStartData::Pointer(start_data);
+ if let Some(grab) = MoveGrab::new(self, start_data, window.clone(), false) {
pointer.set_grab(self, grab, serial, Focus::Clear);
-
- if !is_overview_open {
- self.niri
- .cursor_manager
- .set_cursor_image(CursorImageStatus::Named(CursorIcon::Move));
- }
}
}
}
@@ -4037,22 +4045,15 @@ impl State {
} else if let Some((window, _)) = under.window {
self.niri.layout.activate_window(&window);
- // Check if we need to start an interactive move.
+ // Check if we need to start a touch move grab.
if mod_down {
- let (output, pos_within_output) = self.niri.output_under(pos).unwrap();
- let output = output.clone();
-
- if self.niri.layout.interactive_move_begin(
- window.clone(),
- &output,
- pos_within_output,
- ) {
- let start_data = TouchGrabStartData {
- focus: None,
- slot,
- location: pos,
- };
- let grab = TouchMoveGrab::new(start_data, window.clone());
+ let start_data = TouchGrabStartData {
+ focus: None,
+ slot,
+ location: pos,
+ };
+ let start_data = PointerOrTouchStartData::Touch(start_data);
+ if let Some(grab) = MoveGrab::new(self, start_data, window.clone(), true) {
handle.set_grab(self, grab, serial);
}
}
@@ -4908,13 +4909,19 @@ fn grab_allows_hot_corner(grab: &(dyn PointerGrab<State> + 'static)) -> bool {
//
// Some notable grabs not mentioned here:
// - DnDGrab allows hot corner to DnD across workspaces.
- // - MoveGrab allows hot corner to DnD across workspaces.
// - ClickGrab keeps pointer focus on the window, so the hot corner doesn't trigger.
// - Touch grabs: touch doesn't trigger the hot corner.
if grab.is::<ResizeGrab>() || grab.is::<SpatialMovementGrab>() {
return false;
}
+ if let Some(grab) = grab.downcast_ref::<MoveGrab>() {
+ // Window move allows hot corner to DnD across workspaces.
+ if !grab.is_move() {
+ return false;
+ }
+ }
+
true
}
diff --git a/src/input/move_grab.rs b/src/input/move_grab.rs
index e939696b..c78b796e 100644
--- a/src/input/move_grab.rs
+++ b/src/input/move_grab.rs
@@ -1,3 +1,5 @@
+use std::time::Duration;
+
use smithay::backend::input::ButtonState;
use smithay::desktop::Window;
use smithay::input::pointer::{
@@ -7,107 +9,279 @@ use smithay::input::pointer::{
GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, PointerInnerHandle,
RelativeMotionEvent,
};
+use smithay::input::touch::{
+ self, GrabStartData as TouchGrabStartData, TouchGrab, TouchInnerHandle,
+};
use smithay::input::SeatHandler;
-use smithay::utils::{IsAlive, Logical, Point};
+use smithay::output::Output;
+use smithay::utils::{IsAlive, Logical, Point, Serial};
+use crate::input::PointerOrTouchStartData;
use crate::niri::State;
pub struct MoveGrab {
- start_data: PointerGrabStartData<State>,
+ start_data: PointerOrTouchStartData<State>,
+ start_output: Output,
+ start_pos_within_output: Point<f64, Logical>,
last_location: Point<f64, Logical>,
window: Window,
gesture: GestureState,
+ enable_view_offset: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum GestureState {
Recognizing,
Move,
+ ViewOffset,
}
impl MoveGrab {
pub fn new(
- start_data: PointerGrabStartData<State>,
+ state: &mut State,
+ start_data: PointerOrTouchStartData<State>,
window: Window,
- use_threshold: bool,
- ) -> Self {
- let gesture = if use_threshold {
- GestureState::Recognizing
- } else {
- GestureState::Move
- };
+ enable_view_offset: bool,
+ ) -> Option<Self> {
+ let (output, pos_within_output) = state.niri.output_under(start_data.location())?;
- Self {
- last_location: start_data.location,
+ Some(Self {
+ last_location: start_data.location(),
start_data,
+ start_output: output.clone(),
+ start_pos_within_output: pos_within_output,
window,
- gesture,
- }
+ gesture: GestureState::Recognizing,
+ enable_view_offset,
+ })
}
- fn on_ungrab(&mut self, state: &mut State) {
- state.niri.layout.interactive_move_end(&self.window);
+ pub fn is_move(&self) -> bool {
+ self.gesture == GestureState::Move
+ }
+
+ fn on_ungrab(&mut self, data: &mut State) {
+ let layout = &mut data.niri.layout;
+ match self.gesture {
+ GestureState::Recognizing => {
+ // Activate the window on release. This is most prominent in the overview where
+ // windows are not activated on click. In the overview, we also try to do a nice
+ // synchronized workspace animation.
+ if layout.is_overview_open() {
+ let res = layout.workspaces().find_map(|(mon, ws_idx, ws)| {
+ ws.windows()
+ .any(|w| w.window == self.window)
+ .then(|| (mon.map(|mon| mon.output().clone()), ws_idx))
+ });
+ if let Some((Some(output), ws_idx)) = res {
+ layout.focus_output(&output);
+ layout.toggle_overview_to_workspace(ws_idx);
+ }
+ }
+
+ layout.activate_window(&self.window);
+ }
+ GestureState::Move => layout.interactive_move_end(&self.window),
+ GestureState::ViewOffset => {
+ layout.view_offset_gesture_end(Some(false));
+ }
+ }
+
+ if self.start_data.is_pointer() {
+ data.niri
+ .cursor_manager
+ .set_cursor_image(CursorImageStatus::default_named());
+ }
+
// FIXME: only redraw the window output.
- state.niri.queue_redraw_all();
- state
- .niri
- .cursor_manager
- .set_cursor_image(CursorImageStatus::default_named());
+ data.niri.queue_redraw_all();
}
-}
-impl PointerGrab<State> for MoveGrab {
- fn motion(
+ fn begin_move(&mut self, data: &mut State) -> bool {
+ if !data.niri.layout.interactive_move_begin(
+ self.window.clone(),
+ &self.start_output,
+ self.start_pos_within_output,
+ ) {
+ // Can no longer start the move.
+ return false;
+ }
+
+ self.gesture = GestureState::Move;
+
+ if self.start_data.is_pointer() {
+ data.niri
+ .cursor_manager
+ .set_cursor_image(CursorImageStatus::Named(CursorIcon::Move));
+ }
+
+ true
+ }
+
+ fn begin_view_offset(&mut self, data: &mut State) -> bool {
+ let layout = &mut data.niri.layout;
+ let Some((output, ws_idx)) = layout.workspaces().find_map(|(mon, ws_idx, ws)| {
+ let ws_idx = ws
+ .windows()
+ .any(|w| w.window == self.window)
+ .then_some(ws_idx)?;
+ let output = mon?.output().clone();
+ Some((output, ws_idx))
+ }) else {
+ // Can no longer start the gesture.
+ return false;
+ };
+
+ layout.view_offset_gesture_begin(&output, Some(ws_idx), false);
+
+ self.gesture = GestureState::ViewOffset;
+
+ if self.start_data.is_pointer() {
+ data.niri
+ .cursor_manager
+ .set_cursor_image(CursorImageStatus::Named(CursorIcon::AllScroll));
+ }
+
+ true
+ }
+
+ fn on_motion(
&mut self,
data: &mut State,
- handle: &mut PointerInnerHandle<'_, State>,
- _focus: Option<(<State as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
- event: &MotionEvent,
- ) {
- // While the grab is active, no client has pointer focus.
- handle.motion(data, None, event);
+ location: Point<f64, Logical>,
+ timestamp: Duration,
+ ) -> bool {
+ let mut delta = location - self.last_location;
+ self.last_location = location;
- if self.window.alive() {
- if let Some((output, pos_within_output)) = data.niri.output_under(event.location) {
- let output = output.clone();
- let event_delta = event.location - self.last_location;
- self.last_location = event.location;
+ // Try to recognize the gesture.
+ if self.gesture == GestureState::Recognizing {
+ // Check if the window has closed.
+ if !self.window.alive() {
+ return false;
+ }
- if self.gesture == GestureState::Recognizing {
- let c = event.location - self.start_data.location;
+ // Check if the gesture moved far enough to decide.
+ let c = location - self.start_data.location();
+ if c.x * c.x + c.y * c.y >= 8. * 8. {
+ let is_floating = data
+ .niri
+ .layout
+ .workspaces()
+ .find_map(|(_, _, ws)| {
+ ws.windows()
+ .any(|w| w.window == self.window)
+ .then(|| ws.is_floating(&self.window))
+ })
+ .unwrap_or(false);
- // Check if the gesture moved far enough to decide.
- if c.x * c.x + c.y * c.y >= 8. * 8. {
- self.gesture = GestureState::Move;
+ let is_view_offset =
+ self.enable_view_offset && !is_floating && c.x.abs() > c.y.abs();
- data.niri
- .cursor_manager
- .set_cursor_image(CursorImageStatus::Named(CursorIcon::Move));
- }
+ let started = if is_view_offset {
+ self.begin_view_offset(data)
+ } else {
+ self.begin_move(data)
+ };
+ if !started {
+ return false;
}
- if self.gesture != GestureState::Move {
- return;
- }
+ // Apply the whole delta that accumulated during recognizing.
+ delta = c;
+ }
+ }
+
+ match self.gesture {
+ GestureState::Recognizing => return true,
+ GestureState::Move => {
+ let Some((output, pos_within_output)) = data.niri.output_under(self.last_location)
+ else {
+ return true;
+ };
+ let output = output.clone();
let ongoing = data.niri.layout.interactive_move_update(
&self.window,
- event_delta,
+ delta,
output,
pos_within_output,
);
if ongoing {
// FIXME: only redraw the previous and the new output.
data.niri.queue_redraw_all();
- return;
+ return true;
}
- } else {
- return;
+ }
+ GestureState::ViewOffset => {
+ let res = data
+ .niri
+ .layout
+ .view_offset_gesture_update(-delta.x, timestamp, false);
+ if let Some(output) = res {
+ if let Some(output) = output {
+ data.niri.queue_redraw(&output);
+ }
+ return true;
+ }
+ }
+ }
+
+ false
+ }
+
+ fn on_toggle_floating(&mut self, data: &mut State) -> bool {
+ if self.gesture == GestureState::ViewOffset {
+ return true;
+ }
+
+ // Start move if still recognizing.
+ if self.gesture == GestureState::Recognizing {
+ let Some((output, pos_within_output)) = data.niri.output_under(self.last_location)
+ else {
+ return false;
+ };
+ let output = output.clone();
+
+ if !self.begin_move(data) {
+ return false;
+ }
+
+ // Apply the delta accumulated during recognizing.
+ let ongoing = data.niri.layout.interactive_move_update(
+ &self.window,
+ self.last_location - self.start_data.location(),
+ output,
+ pos_within_output,
+ );
+ if !ongoing {
+ return false;
}
}
- // The move is no longer ongoing.
- handle.unset_grab(self, data, event.serial, event.time, true);
+ data.niri.layout.toggle_window_floating(Some(&self.window));
+ data.niri.queue_redraw_all();
+
+ true
+ }
+}
+
+impl PointerGrab<State> for MoveGrab {
+ fn motion(
+ &mut self,
+ data: &mut State,
+ handle: &mut PointerInnerHandle<'_, State>,
+ _focus: Option<(<State as SeatHandler>::PointerFocus, Point<f64, Logical>)>,
+ event: &MotionEvent,
+ ) {
+ // While the grab is active, no client has pointer focus.
+ handle.motion(data, None, event);
+
+ let timestamp = Duration::from_millis(u64::from(event.time));
+ if !self.on_motion(data, event.location, timestamp) {
+ // The gesture is no longer ongoing.
+ handle.unset_grab(self, data, event.serial, event.time, true);
+ }
}
fn relative_motion(
@@ -129,18 +303,25 @@ impl PointerGrab<State> for MoveGrab {
) {
handle.button(data, event);
+ let start_data = self.start_data.unwrap_pointer();
+
+ if !handle.current_pressed().contains(&start_data.button) {
+ // The button that initiated the grab was released.
+ handle.unset_grab(self, data, event.serial, event.time, true);
+ return;
+ }
+
// When moving with the left button, right toggles floating, and vice versa.
- let toggle_floating_button = if self.start_data.button == 0x110 {
+ let toggle_floating_button = if start_data.button == 0x110 {
0x111
} else {
0x110
};
- if event.button == toggle_floating_button && event.state == ButtonState::Pressed {
- data.niri.layout.toggle_window_floating(Some(&self.window));
+ if event.state != ButtonState::Pressed || event.button != toggle_floating_button {
+ return;
}
- if !handle.current_pressed().contains(&self.start_data.button) {
- // The button that initiated the grab was released.
+ if !self.on_toggle_floating(data) {
handle.unset_grab(self, data, event.serial, event.time, true);
}
}
@@ -231,7 +412,100 @@ impl PointerGrab<State> for MoveGrab {
}
fn start_data(&self) -> &PointerGrabStartData<State> {
- &self.start_data
+ self.start_data.unwrap_pointer()
+ }
+
+ fn unset(&mut self, data: &mut State) {
+ self.on_ungrab(data);
+ }
+}
+
+impl TouchGrab<State> for MoveGrab {
+ fn down(
+ &mut self,
+ data: &mut State,
+ handle: &mut TouchInnerHandle<'_, State>,
+ _focus: Option<(<State as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
+ event: &touch::DownEvent,
+ seq: Serial,
+ ) {
+ handle.down(data, None, event, seq);
+
+ if event.slot == self.start_data.unwrap_touch().slot {
+ return;
+ }
+
+ if !self.on_toggle_floating(data) {
+ handle.unset_grab(self, data);
+ }
+ }
+
+ fn up(
+ &mut self,
+ data: &mut State,
+ handle: &mut TouchInnerHandle<'_, State>,
+ event: &touch::UpEvent,
+ seq: Serial,
+ ) {
+ handle.up(data, event, seq);
+
+ if event.slot == self.start_data.unwrap_touch().slot {
+ handle.unset_grab(self, data);
+ }
+ }
+
+ fn motion(
+ &mut self,
+ data: &mut State,
+ handle: &mut TouchInnerHandle<'_, State>,
+ _focus: Option<(<State as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
+ event: &touch::MotionEvent,
+ seq: Serial,
+ ) {
+ handle.motion(data, None, event, seq);
+
+ if event.slot != self.start_data.unwrap_touch().slot {
+ return;
+ }
+
+ let timestamp = Duration::from_millis(u64::from(event.time));
+ if !self.on_motion(data, event.location, timestamp) {
+ // The gesture is no longer ongoing.
+ handle.unset_grab(self, data);
+ }
+ }
+
+ fn frame(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, seq: Serial) {
+ handle.frame(data, seq);
+ }
+
+ fn cancel(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, seq: Serial) {
+ handle.cancel(data, seq);
+ handle.unset_grab(self, data);
+ }
+
+ fn shape(
+ &mut self,
+ data: &mut State,
+ handle: &mut TouchInnerHandle<'_, State>,
+ event: &touch::ShapeEvent,
+ seq: Serial,
+ ) {
+ handle.shape(data, event, seq);
+ }
+
+ fn orientation(
+ &mut self,
+ data: &mut State,
+ handle: &mut TouchInnerHandle<'_, State>,
+ event: &touch::OrientationEvent,
+ seq: Serial,
+ ) {
+ handle.orientation(data, event, seq);
+ }
+
+ fn start_data(&self) -> &TouchGrabStartData<State> {
+ self.start_data.unwrap_touch()
}
fn unset(&mut self, data: &mut State) {
diff --git a/src/input/touch_move_grab.rs b/src/input/touch_move_grab.rs
deleted file mode 100644
index e69f4c6e..00000000
--- a/src/input/touch_move_grab.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-use smithay::desktop::Window;
-use smithay::input::touch::{
- DownEvent, GrabStartData as TouchGrabStartData, MotionEvent, OrientationEvent, ShapeEvent,
- TouchGrab, TouchInnerHandle, UpEvent,
-};
-use smithay::input::SeatHandler;
-use smithay::utils::{IsAlive, Logical, Point, Serial};
-
-use crate::niri::State;
-
-pub struct TouchMoveGrab {
- start_data: TouchGrabStartData<State>,
- last_location: Point<f64, Logical>,
- window: Window,
-}
-
-impl TouchMoveGrab {
- pub fn new(start_data: TouchGrabStartData<State>, window: Window) -> Self {
- Self {
- last_location: start_data.location,
- start_data,
- window,
- }
- }
-
- fn on_ungrab(&mut self, state: &mut State) {
- state.niri.layout.interactive_move_end(&self.window);
- // FIXME: only redraw the window output.
- state.niri.queue_redraw_all();
- }
-}
-
-impl TouchGrab<State> for TouchMoveGrab {
- fn down(
- &mut self,
- data: &mut State,
- handle: &mut TouchInnerHandle<'_, State>,
- _focus: Option<(<State as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
- event: &DownEvent,
- seq: Serial,
- ) {
- handle.down(data, None, event, seq);
- }
-
- fn up(
- &mut self,
- data: &mut State,
- handle: &mut TouchInnerHandle<'_, State>,
- event: &UpEvent,
- seq: Serial,
- ) {
- handle.up(data, event, seq);
-
- if event.slot != self.start_data.slot {
- return;
- }
-
- handle.unset_grab(self, data);
- }
-
- fn motion(
- &mut self,
- data: &mut State,
- handle: &mut TouchInnerHandle<'_, State>,
- _focus: Option<(<State as SeatHandler>::TouchFocus, Point<f64, Logical>)>,
- event: &MotionEvent,
- seq: Serial,
- ) {
- handle.motion(data, None, event, seq);
-
- if event.slot != self.start_data.slot {
- return;
- }
-
- if self.window.alive() {
- if let Some((output, pos_within_output)) = data.niri.output_under(event.location) {
- let output = output.clone();
- let event_delta = event.location - self.last_location;
- self.last_location = event.location;
- let ongoing = data.niri.layout.interactive_move_update(
- &self.window,
- event_delta,
- output,
- pos_within_output,
- );
- if ongoing {
- // FIXME: only redraw the previous and the new output.
- data.niri.queue_redraw_all();
- return;
- }
- } else {
- return;
- }
- }
-
- // The move is no longer ongoing.
- handle.unset_grab(self, data);
- }
-
- fn frame(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, seq: Serial) {
- handle.frame(data, seq);
- }
-
- fn cancel(&mut self, data: &mut State, handle: &mut TouchInnerHandle<'_, State>, seq: Serial) {
- handle.cancel(data, seq);
- handle.unset_grab(self, data);
- }
-
- fn shape(
- &mut self,
- data: &mut State,
- handle: &mut TouchInnerHandle<'_, State>,
- event: &ShapeEvent,
- seq: Serial,
- ) {
- handle.shape(data, event, seq);
- }
-
- fn orientation(
- &mut self,
- data: &mut State,
- handle: &mut TouchInnerHandle<'_, State>,
- event: &OrientationEvent,
- seq: Serial,
- ) {
- handle.orientation(data, event, seq);
- }
-
- fn start_data(&self) -> &TouchGrabStartData<State> {
- &self.start_data
- }
-
- fn unset(&mut self, data: &mut State) {
- self.on_ungrab(data);
- }
-}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 8761c0e3..9fd99a32 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -4040,16 +4040,12 @@ impl<W: LayoutElement> Layout<W> {
mon.dnd_scroll_gesture_end();
}
- let mut ws_id = None;
for ws in self.workspaces_mut() {
- let id = ws.id();
if let Some(tile) = ws.tiles_mut().find(|tile| *tile.window().id() == window_id)
{
let offset = tile.interactive_move_offset;
tile.interactive_move_offset = Point::from((0., 0.));
tile.animate_move_from(offset);
-
- ws_id = Some(id);
}
// Unlock the view on the workspaces, but if the moved window was active,
@@ -4064,32 +4060,6 @@ impl<W: LayoutElement> Layout<W> {
}
}
- // In the overview, we want to click on a window to focus it, and also to
- // click-and-drag to move the window. The way we handle this is by always starting
- // the interactive move (to get frozen view), then, when in the overview, *not*
- // calling interactive_move_update() until the cursor moves far enough. This means
- // that if we "just click" then we end up in this branch with state == Starting.
- // Close the overview in this case.
- if self.overview_open {
- let ws_id = ws_id.unwrap();
- if let MonitorSet::Normal { monitors, .. } = &mut self.monitor_set {
- for mon in monitors {
- if let Some(ws_idx) =
- mon.workspaces.iter().position(|ws| ws.id() == ws_id)
- {
- mon.activate_workspace_with_anim_config(
- ws_idx,
- Some(self.options.animations.overview_open_close.0),
- );
- break;
- }
- }
- }
-
- self.activate_window(&window_id);
- self.close_overview();
- }
-
return;
}
InteractiveMoveState::Moving(move_) => move_,