Skip to content

Commit 8553f79

Browse files
committed
focus-stack: Keep dragged surface in focus stack in move_request()
Replacement for #1687, that works correctly with multiple outputs. We don't want another window to show a focus indicator while a window is being dragged, so keep the window in the focus stack. If a window is being moved out of a stack, change the focus from the stack to the window. `refresh_focus_stack()` doesn't seem to be called here, but for good measure, make sure that calling that function also won't remove a `CosmicMapped` from the focus stack if it is currently part of a move grab for the seat.
1 parent de7c341 commit 8553f79

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

src/shell/focus/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ impl FocusStackMut<'_> {
129129
self.0.insert(target);
130130
}
131131

132-
pub fn remove<T>(&mut self, target: &T)
132+
pub fn remove<T>(&mut self, target: &T) -> bool
133133
where
134134
T: Hash + indexmap::Equivalent<FocusTarget>,
135135
{
136-
self.0.shift_remove(target);
136+
self.0.shift_remove(target)
137137
}
138138

139139
pub fn last(&self) -> Option<&FocusTarget> {

src/shell/mod.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,15 +3415,6 @@ impl Shell {
34153415
return None;
34163416
}
34173417

3418-
if !move_out_of_stack {
3419-
for workspace in self.workspaces.spaces_mut() {
3420-
for seat in self.seats.iter() {
3421-
let mut stack = workspace.focus_stack.get_mut(seat);
3422-
stack.remove(&old_mapped);
3423-
}
3424-
}
3425-
}
3426-
34273418
let (window, _) = old_mapped
34283419
.windows()
34293420
.find(|(w, _)| w.wl_surface().as_deref() == Some(surface))
@@ -3441,6 +3432,20 @@ impl Shell {
34413432
old_mapped.clone()
34423433
};
34433434

3435+
if move_out_of_stack {
3436+
// Update focus stack to set focus to the window being dragged out of
3437+
// the stack.
3438+
for workspace in self.workspaces.spaces_mut() {
3439+
for seat in self.seats.iter() {
3440+
let mut stack = workspace.focus_stack.get_mut(seat);
3441+
// XXX Not finding CosmicStack in focus stack?
3442+
if stack.remove(&old_mapped) {
3443+
stack.append(mapped.clone());
3444+
}
3445+
}
3446+
}
3447+
}
3448+
34443449
let trigger = match &start_data {
34453450
GrabStartData::Pointer(start_data) => Trigger::Pointer(start_data.button),
34463451
GrabStartData::Touch(start_data) => Trigger::Touch(start_data.slot),

src/shell/workspace.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
element::{AsGlowRenderer, FromGlesError},
88
},
99
shell::{
10-
ANIMATION_DURATION, OverviewMode,
10+
ANIMATION_DURATION, OverviewMode, SeatMoveGrabState,
1111
layout::{floating::FloatingLayout, tiling::TilingLayout},
1212
},
1313
state::State,
@@ -455,17 +455,33 @@ impl Workspace {
455455
}
456456

457457
pub fn refresh_focus_stack(&mut self) {
458-
for stack in self.focus_stack.0.values_mut() {
458+
for (seat, stack) in self.focus_stack.0.iter_mut() {
459459
let fullscreen = self
460460
.fullscreen
461461
.as_ref()
462462
.filter(|f| f.alive())
463463
.filter(|f| f.ended_at.is_none())
464464
.map(|f| &f.surface);
465+
466+
// Move grab is treated as focused, so don't change focus to a
467+
// window while grab exists.
468+
let move_grab_state = seat
469+
.user_data()
470+
.get::<SeatMoveGrabState>()
471+
.unwrap()
472+
.lock()
473+
.unwrap();
474+
let move_mapped = if let Some(move_grab_state) = &*move_grab_state {
475+
Some(move_grab_state.element())
476+
} else {
477+
None
478+
};
479+
465480
let mapped = || {
466481
self.floating_layer
467482
.mapped()
468483
.chain(self.tiling_layer.mapped().map(|(w, _)| w))
484+
.chain(move_mapped.iter())
469485
};
470486
stack.retain(|w| match w {
471487
FocusTarget::Fullscreen(s) => fullscreen.is_some_and(|f| f == s),

0 commit comments

Comments
 (0)