tiling: Cleanup dragging on output/workspace switch

This commit is contained in:
Victoria Brekenfeld 2023-07-31 17:25:09 +02:00
parent 10902ff543
commit 4a53e63c28
3 changed files with 74 additions and 9 deletions

View file

@ -184,7 +184,8 @@ pub struct MoveGrab {
window: CosmicMapped,
start_data: PointerGrabStartData<State>,
seat: Seat<State>,
outputs: HashSet<Output>,
cursor_output: Output,
window_outputs: HashSet<Output>,
tiling: bool,
}
@ -196,6 +197,30 @@ impl PointerGrab<State> for MoveGrab {
_focus: Option<(PointerFocusTarget, Point<i32, Logical>)>,
event: &MotionEvent,
) {
let Some(current_output) = state
.common
.shell
.outputs()
.find(|output| {
output
.geometry()
.contains(handle.current_location().to_i32_round())
})
.cloned()
else {
return;
};
if self.cursor_output != current_output {
state
.common
.shell
.workspaces
.active_mut(&self.cursor_output)
.tiling_layer
.cleanup_drag(&self.cursor_output);
self.cursor_output = current_output.clone();
}
let mut borrow = self
.seat
.user_data()
@ -204,9 +229,9 @@ impl PointerGrab<State> for MoveGrab {
if let Some(grab_state) = borrow.as_mut().and_then(|s| s.as_mut()) {
let mut window_geo = self.window.geometry();
window_geo.loc += event.location.to_i32_round() + grab_state.window_offset;
for output in state.common.shell.outputs() {
for output in &state.common.shell.outputs {
if let Some(overlap) = output.geometry().intersection(window_geo) {
if self.outputs.insert(output.clone()) {
if self.window_outputs.insert(output.clone()) {
self.window.output_enter(output, overlap);
if let Some(indicator) =
grab_state.stacking_indicator.as_ref().map(|x| &x.0)
@ -214,7 +239,7 @@ impl PointerGrab<State> for MoveGrab {
indicator.output_enter(output, overlap);
}
}
} else if self.outputs.remove(&output) {
} else if self.window_outputs.remove(&output) {
self.window.output_leave(output);
if let Some(indicator) = grab_state.stacking_indicator.as_ref().map(|x| &x.0) {
indicator.output_leave(output);
@ -222,19 +247,18 @@ impl PointerGrab<State> for MoveGrab {
}
}
let output = state.common.last_active_seat().active_output();
if self.tiling {
let indicator_location = state
.common
.shell
.active_space(&output)
.active_space(&current_output)
.tiling_layer
.stacking_indicator();
if indicator_location.is_some() != grab_state.stacking_indicator.is_some() {
grab_state.stacking_indicator = indicator_location.map(|geo| {
let element = stack_hover(state.common.event_loop_handle.clone(), geo.size);
for output in &self.outputs {
for output in &self.window_outputs {
element.output_enter(output, output.geometry());
}
(element, geo.loc)
@ -327,7 +351,8 @@ impl MoveGrab {
window,
start_data,
seat: seat.clone(),
outputs,
window_outputs: outputs,
cursor_output: output,
tiling: was_tiled,
}
}
@ -358,7 +383,7 @@ impl MoveGrab {
+ grab_state.window_offset;
let workspace_handle = state.common.shell.active_space(&output).handle;
for old_output in self.outputs.iter().filter(|o| *o != &output) {
for old_output in self.window_outputs.iter().filter(|o| *o != &output) {
grab_state.window.output_leave(old_output);
}
for (window, _) in grab_state.window.windows() {

View file

@ -1641,6 +1641,40 @@ impl TilingLayout {
}
}
pub fn cleanup_drag(&mut self, output: &Output) {
let mut queue = self.queues.get_mut(output);
let mut owned_tree = None;
let mut tree = if let Some(queue) = queue.as_mut() {
owned_tree = queue.trees.back().map(|x| x.0.copy_clone());
owned_tree.as_mut()
} else {
self.standby_tree.as_mut()
}
.unwrap();
if let Some(root) = tree.root_node_id() {
for id in tree
.traverse_pre_order_ids(root)
.unwrap()
.collect::<Vec<_>>()
.into_iter()
{
match tree.get_mut(&id).map(|node| node.data_mut()) {
Ok(Data::Placeholder { .. }) => TilingLayout::unmap_internal(&mut tree, &id),
Ok(Data::Group { pill_indicator, .. }) if pill_indicator.is_some() => {
pill_indicator.take();
}
_ => {}
}
}
if let Some(mut tree) = owned_tree {
let blocker = TilingLayout::update_positions(output, &mut tree, self.gaps);
queue.unwrap().push_tree(tree, ANIMATION_DURATION, blocker);
}
}
}
pub fn drop_window(
&mut self,
window: CosmicMapped,

View file

@ -1003,6 +1003,12 @@ impl Shell {
if match &mut self.workspaces {
WorkspaceMode::OutputBound(sets, _) => {
if let Some(set) = sets.get_mut(output) {
if matches!(
self.overview_mode,
OverviewMode::Started(Trigger::Pointer(_), _)
) {
set.workspaces[set.active].tiling_layer.cleanup_drag(output);
}
set.activate(idx, &mut self.workspace_state.update())?
} else {
false