focus-stack: Keep dragged surface in focus stack in move_request()
Replacement for https://github.com/pop-os/cosmic-comp/pull/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.
This commit is contained in:
parent
e09fcec9f3
commit
7fd033295f
3 changed files with 29 additions and 13 deletions
|
|
@ -129,11 +129,11 @@ impl FocusStackMut<'_> {
|
|||
self.0.insert(target);
|
||||
}
|
||||
|
||||
pub fn remove<T>(&mut self, target: &T)
|
||||
pub fn remove<T>(&mut self, target: &T) -> bool
|
||||
where
|
||||
T: Hash + indexmap::Equivalent<FocusTarget>,
|
||||
{
|
||||
self.0.shift_remove(target);
|
||||
self.0.shift_remove(target)
|
||||
}
|
||||
|
||||
pub fn last(&self) -> Option<&FocusTarget> {
|
||||
|
|
|
|||
|
|
@ -3415,15 +3415,6 @@ impl Shell {
|
|||
return None;
|
||||
}
|
||||
|
||||
if !move_out_of_stack {
|
||||
for workspace in self.workspaces.spaces_mut() {
|
||||
for seat in self.seats.iter() {
|
||||
let mut stack = workspace.focus_stack.get_mut(seat);
|
||||
stack.remove(&old_mapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (window, _) = old_mapped
|
||||
.windows()
|
||||
.find(|(w, _)| w.wl_surface().as_deref() == Some(surface))
|
||||
|
|
@ -3441,6 +3432,15 @@ impl Shell {
|
|||
old_mapped.clone()
|
||||
};
|
||||
|
||||
if move_out_of_stack {
|
||||
// Update focus stack to set focus to the window being dragged out of
|
||||
// the stack.
|
||||
if let Some(workspace) = self.space_for_mut(&old_mapped) {
|
||||
let mut stack = workspace.focus_stack.get_mut(seat);
|
||||
stack.append(mapped.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let trigger = match &start_data {
|
||||
GrabStartData::Pointer(start_data) => Trigger::Pointer(start_data.button),
|
||||
GrabStartData::Touch(start_data) => Trigger::Touch(start_data.slot),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
element::{AsGlowRenderer, FromGlesError},
|
||||
},
|
||||
shell::{
|
||||
ANIMATION_DURATION, OverviewMode,
|
||||
ANIMATION_DURATION, OverviewMode, SeatMoveGrabState,
|
||||
layout::{floating::FloatingLayout, tiling::TilingLayout},
|
||||
},
|
||||
state::State,
|
||||
|
|
@ -455,17 +455,33 @@ impl Workspace {
|
|||
}
|
||||
|
||||
pub fn refresh_focus_stack(&mut self) {
|
||||
for stack in self.focus_stack.0.values_mut() {
|
||||
for (seat, stack) in self.focus_stack.0.iter_mut() {
|
||||
let fullscreen = self
|
||||
.fullscreen
|
||||
.as_ref()
|
||||
.filter(|f| f.alive())
|
||||
.filter(|f| f.ended_at.is_none())
|
||||
.map(|f| &f.surface);
|
||||
|
||||
// Move grab is treated as focused, so don't change focus to a
|
||||
// window while grab exists.
|
||||
let move_grab_state = seat
|
||||
.user_data()
|
||||
.get::<SeatMoveGrabState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
let move_mapped = if let Some(move_grab_state) = &*move_grab_state {
|
||||
Some(move_grab_state.element())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mapped = || {
|
||||
self.floating_layer
|
||||
.mapped()
|
||||
.chain(self.tiling_layer.mapped().map(|(w, _)| w))
|
||||
.chain(move_mapped.iter())
|
||||
};
|
||||
stack.retain(|w| match w {
|
||||
FocusTarget::Fullscreen(s) => fullscreen.is_some_and(|f| f == s),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue