mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Make interactive move keep in the same layout (floating/tiling)
This commit is contained in:
+25
-4
@@ -327,6 +327,8 @@ struct InteractiveMoveData<W: LayoutElement> {
|
||||
pub(self) width: ColumnWidth,
|
||||
/// Whether the window column was full-width.
|
||||
pub(self) is_full_width: bool,
|
||||
/// Whether the window targets the floating layout.
|
||||
pub(self) is_floating: bool,
|
||||
/// Pointer location within the visual window geometry as ratio from geometry size.
|
||||
///
|
||||
/// This helps the pointer remain inside the window as it resizes.
|
||||
@@ -2451,6 +2453,12 @@ impl<W: LayoutElement> Layout<W> {
|
||||
return;
|
||||
}
|
||||
|
||||
// No insert hint when targeting floating.
|
||||
if move_.is_floating {
|
||||
self.interactive_move = Some(InteractiveMoveState::Moving(move_));
|
||||
return;
|
||||
}
|
||||
|
||||
let _span = tracy_client::span!("Layout::update_insert_hint::update");
|
||||
|
||||
if let Some(mon) = self.monitor_for_output_mut(&move_.output) {
|
||||
@@ -2661,6 +2669,7 @@ impl<W: LayoutElement> Layout<W> {
|
||||
pub fn toggle_window_floating(&mut self, window: Option<&W::Id>) {
|
||||
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
|
||||
if window.is_none() || window == Some(move_.tile.window().id()) {
|
||||
move_.is_floating = !move_.is_floating;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3193,7 +3202,7 @@ impl<W: LayoutElement> Layout<W> {
|
||||
mut tile,
|
||||
width,
|
||||
is_full_width,
|
||||
is_floating: _,
|
||||
is_floating,
|
||||
} = self.remove_window(window, Transaction::new()).unwrap();
|
||||
|
||||
tile.stop_move_animations();
|
||||
@@ -3242,6 +3251,7 @@ impl<W: LayoutElement> Layout<W> {
|
||||
pointer_pos_within_output,
|
||||
width,
|
||||
is_full_width,
|
||||
is_floating,
|
||||
pointer_ratio_within_window,
|
||||
};
|
||||
|
||||
@@ -3345,14 +3355,25 @@ impl<W: LayoutElement> Layout<W> {
|
||||
.position(|ws| ws.id() == ws_id)
|
||||
.unwrap();
|
||||
|
||||
let ws = &mut mon.workspaces[ws_idx];
|
||||
let position = ws.get_insert_position(move_.pointer_pos_within_output - offset);
|
||||
let position = if move_.is_floating {
|
||||
InsertPosition::Floating
|
||||
} else {
|
||||
let ws = &mut mon.workspaces[ws_idx];
|
||||
ws.get_insert_position(move_.pointer_pos_within_output - offset)
|
||||
};
|
||||
|
||||
(mon, ws_idx, position, offset)
|
||||
} else {
|
||||
let mon = &mut monitors[*active_monitor_idx];
|
||||
// No point in trying to use the pointer position on the wrong output.
|
||||
let (ws, offset) = mon.workspaces_with_render_positions().next().unwrap();
|
||||
let position = ws.get_insert_position(Point::from((0., 0.)));
|
||||
|
||||
let position = if move_.is_floating {
|
||||
InsertPosition::Floating
|
||||
} else {
|
||||
ws.get_insert_position(Point::from((0., 0.)))
|
||||
};
|
||||
|
||||
let ws_id = ws.id();
|
||||
let ws_idx = mon
|
||||
.workspaces
|
||||
|
||||
+6
-23
@@ -26,11 +26,6 @@ use crate::window::ResolvedWindowRules;
|
||||
/// Amount of touchpad movement to scroll the view for the width of one working area.
|
||||
const VIEW_GESTURE_WORKING_AREA_MOVEMENT: f64 = 1200.;
|
||||
|
||||
/// Maximum distance to the target position for an interactively moved window.
|
||||
///
|
||||
/// If the distance is higher than this, the window will instead remain floating.
|
||||
const WINDOW_INSERT_MAX_DISTANCE: f64 = 50.;
|
||||
|
||||
/// A scrollable-tiling space for windows.
|
||||
#[derive(Debug)]
|
||||
pub struct ScrollingSpace<W: LayoutElement> {
|
||||
@@ -662,9 +657,9 @@ impl<W: LayoutElement> ScrollingSpace<W> {
|
||||
self.insert_hint = None;
|
||||
}
|
||||
|
||||
fn compute_insert_position(&self, pos: Point<f64, Logical>) -> (InsertPosition, f64) {
|
||||
pub fn get_insert_position(&self, pos: Point<f64, Logical>) -> InsertPosition {
|
||||
if self.columns.is_empty() {
|
||||
return (InsertPosition::NewColumn(0), pos.x.abs());
|
||||
return InsertPosition::NewColumn(0);
|
||||
}
|
||||
|
||||
let x = pos.x + self.view_pos();
|
||||
@@ -675,7 +670,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
|
||||
|
||||
// Insert position is before the first column.
|
||||
if x < 0. {
|
||||
return (InsertPosition::NewColumn(0), -x);
|
||||
return InsertPosition::NewColumn(0);
|
||||
}
|
||||
|
||||
// Find the closest gap between columns.
|
||||
@@ -695,8 +690,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
|
||||
|
||||
// Insert position is past the last column.
|
||||
if col_idx == self.columns.len() {
|
||||
// col_x should be what we expect if pos.x is past the last column.
|
||||
return (InsertPosition::NewColumn(closest_col_idx), x - col_x);
|
||||
return InsertPosition::NewColumn(closest_col_idx);
|
||||
}
|
||||
|
||||
// Find the closest gap between tiles.
|
||||
@@ -711,23 +705,12 @@ impl<W: LayoutElement> ScrollingSpace<W> {
|
||||
let vert_dist = (col_x - x).abs();
|
||||
let hor_dist = (tile_off.y - y).abs();
|
||||
if vert_dist <= hor_dist {
|
||||
(InsertPosition::NewColumn(closest_col_idx), vert_dist)
|
||||
InsertPosition::NewColumn(closest_col_idx)
|
||||
} else {
|
||||
(
|
||||
InsertPosition::InColumn(col_idx, closest_tile_idx),
|
||||
hor_dist,
|
||||
)
|
||||
InsertPosition::InColumn(col_idx, closest_tile_idx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_insert_position(&self, pos: Point<f64, Logical>) -> InsertPosition {
|
||||
let (position, distance) = self.compute_insert_position(pos);
|
||||
if distance > WINDOW_INSERT_MAX_DISTANCE {
|
||||
return InsertPosition::Floating;
|
||||
}
|
||||
position
|
||||
}
|
||||
|
||||
pub fn add_tile(
|
||||
&mut self,
|
||||
col_idx: Option<usize>,
|
||||
|
||||
Reference in New Issue
Block a user