stack: Remember position during continuous move action

This commit is contained in:
Victoria Brekenfeld 2025-02-26 15:31:06 +01:00 committed by Victoria Brekenfeld
parent e116f20396
commit 638684642c
4 changed files with 30 additions and 10 deletions

View file

@ -165,11 +165,22 @@ impl CosmicStack {
))
}
pub fn add_window(&self, window: impl Into<CosmicSurface>, idx: Option<usize>) {
pub fn add_window(
&self,
window: impl Into<CosmicSurface>,
idx: Option<usize>,
moved_into: Option<&Seat<State>>,
) {
let window = window.into();
window.try_force_undecorated(true);
window.set_tiled(true);
self.0.with_program(|p| {
let last_mod_serial = moved_into.and_then(|seat| seat.last_modifier_change());
let mut prev_idx = p.previous_index.lock().unwrap();
if !prev_idx.is_some_and(|(serial, _)| Some(serial) == last_mod_serial) {
*prev_idx = last_mod_serial.map(|s| (s, p.active.load(Ordering::SeqCst)));
}
if let Some(mut geo) = p.geometry.lock().unwrap().clone() {
geo.loc.y += TAB_HEIGHT;
geo.size.h -= TAB_HEIGHT;
@ -362,7 +373,7 @@ impl CosmicStack {
} else {
(false, false)
}
},
}
_ => (false, false),
}
});
@ -379,6 +390,8 @@ impl CosmicStack {
pub fn handle_move(&self, direction: Direction) -> MoveResult {
let loop_handle = self.0.loop_handle();
let result = self.0.with_program(|p| {
let prev_idx = p.previous_index.lock().unwrap();
if p.group_focused.load(Ordering::SeqCst) {
return MoveResult::Default;
}
@ -403,7 +416,13 @@ impl CosmicStack {
return MoveResult::Default;
}
let window = windows.remove(active);
if active == windows.len() {
if let Some(prev_idx) = prev_idx
.map(|(_, idx)| idx)
.filter(|idx| *idx < windows.len())
{
p.active.store(prev_idx, Ordering::SeqCst);
p.scroll_to_focus.store(true, Ordering::SeqCst);
} else if active == windows.len() {
p.active.store(active - 1, Ordering::SeqCst);
p.scroll_to_focus.store(true, Ordering::SeqCst);
}

View file

@ -714,7 +714,7 @@ impl FloatingLayout {
if let Some((mapped, geo)) = self.hovered_stack.take() {
let stack = mapped.stack_ref().unwrap();
for surface in window.windows().map(|s| s.0) {
stack.add_window(surface, None);
stack.add_window(surface, None, None);
}
(mapped, geo.loc)
} else {

View file

@ -1051,7 +1051,7 @@ impl TilingLayout {
toplevel_leave_workspace(&surface, &other_desc.handle);
toplevel_enter_workspace(&surface, &this_desc.handle);
}
this_stack.add_window(surface, Some(this_idx + i));
this_stack.add_window(surface, Some(this_idx + i), None);
}
if this.output != other_output {
this_surface.output_leave(&this.output);
@ -1138,7 +1138,7 @@ impl TilingLayout {
toplevel_leave_workspace(&surface, &this_desc.handle);
toplevel_enter_workspace(&surface, &other_desc.handle);
}
other_stack.add_window(surface, Some(other_idx + i));
other_stack.add_window(surface, Some(other_idx + i), None);
}
if this.output != other_output {
other_surface.output_leave(&other_output);
@ -1209,9 +1209,9 @@ impl TilingLayout {
.unwrap();
let this_was_active = &this_stack.active() == this_surface;
let other_was_active = &other_stack.active() == other_surface;
this_stack.add_window(other_surface.clone(), Some(this_idx));
this_stack.add_window(other_surface.clone(), Some(this_idx), None);
this_stack.remove_window(&this_surface);
other_stack.add_window(this_surface.clone(), Some(other_idx));
other_stack.add_window(this_surface.clone(), Some(other_idx), None);
if this.output != other_output {
toplevel_leave_output(this_surface, &this.output);
@ -1681,6 +1681,7 @@ impl TilingLayout {
Direction::Right => Some(0),
_ => None,
},
Some(seat),
);
tree.get_mut(&og_parent)
.unwrap()
@ -2738,7 +2739,7 @@ impl TilingLayout {
unreachable!()
};
for surface in window.windows().map(|s| s.0) {
stack.add_window(surface, None);
stack.add_window(surface, None, None);
}
mapped.clone()
}

View file

@ -2349,7 +2349,7 @@ impl Shell {
if (focused.is_stack() && !is_dialog && !should_be_fullscreen && !should_be_maximized)
&& !(workspace.is_tiled(&focused) && floating_exception)
{
focused.stack_ref().unwrap().add_window(window, None);
focused.stack_ref().unwrap().add_window(window, None, None);
if was_activated {
workspace_state.add_workspace_state(&workspace_handle, WState::Urgent);
}