tiling: Cleanup dragging on output/workspace switch
This commit is contained in:
parent
10902ff543
commit
4a53e63c28
3 changed files with 74 additions and 9 deletions
|
|
@ -184,7 +184,8 @@ pub struct MoveGrab {
|
||||||
window: CosmicMapped,
|
window: CosmicMapped,
|
||||||
start_data: PointerGrabStartData<State>,
|
start_data: PointerGrabStartData<State>,
|
||||||
seat: Seat<State>,
|
seat: Seat<State>,
|
||||||
outputs: HashSet<Output>,
|
cursor_output: Output,
|
||||||
|
window_outputs: HashSet<Output>,
|
||||||
tiling: bool,
|
tiling: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,6 +197,30 @@ impl PointerGrab<State> for MoveGrab {
|
||||||
_focus: Option<(PointerFocusTarget, Point<i32, Logical>)>,
|
_focus: Option<(PointerFocusTarget, Point<i32, Logical>)>,
|
||||||
event: &MotionEvent,
|
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
|
let mut borrow = self
|
||||||
.seat
|
.seat
|
||||||
.user_data()
|
.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()) {
|
if let Some(grab_state) = borrow.as_mut().and_then(|s| s.as_mut()) {
|
||||||
let mut window_geo = self.window.geometry();
|
let mut window_geo = self.window.geometry();
|
||||||
window_geo.loc += event.location.to_i32_round() + grab_state.window_offset;
|
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 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);
|
self.window.output_enter(output, overlap);
|
||||||
if let Some(indicator) =
|
if let Some(indicator) =
|
||||||
grab_state.stacking_indicator.as_ref().map(|x| &x.0)
|
grab_state.stacking_indicator.as_ref().map(|x| &x.0)
|
||||||
|
|
@ -214,7 +239,7 @@ impl PointerGrab<State> for MoveGrab {
|
||||||
indicator.output_enter(output, overlap);
|
indicator.output_enter(output, overlap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if self.outputs.remove(&output) {
|
} else if self.window_outputs.remove(&output) {
|
||||||
self.window.output_leave(output);
|
self.window.output_leave(output);
|
||||||
if let Some(indicator) = grab_state.stacking_indicator.as_ref().map(|x| &x.0) {
|
if let Some(indicator) = grab_state.stacking_indicator.as_ref().map(|x| &x.0) {
|
||||||
indicator.output_leave(output);
|
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 {
|
if self.tiling {
|
||||||
let indicator_location = state
|
let indicator_location = state
|
||||||
.common
|
.common
|
||||||
.shell
|
.shell
|
||||||
.active_space(&output)
|
.active_space(¤t_output)
|
||||||
.tiling_layer
|
.tiling_layer
|
||||||
.stacking_indicator();
|
.stacking_indicator();
|
||||||
|
|
||||||
if indicator_location.is_some() != grab_state.stacking_indicator.is_some() {
|
if indicator_location.is_some() != grab_state.stacking_indicator.is_some() {
|
||||||
grab_state.stacking_indicator = indicator_location.map(|geo| {
|
grab_state.stacking_indicator = indicator_location.map(|geo| {
|
||||||
let element = stack_hover(state.common.event_loop_handle.clone(), geo.size);
|
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.output_enter(output, output.geometry());
|
||||||
}
|
}
|
||||||
(element, geo.loc)
|
(element, geo.loc)
|
||||||
|
|
@ -327,7 +351,8 @@ impl MoveGrab {
|
||||||
window,
|
window,
|
||||||
start_data,
|
start_data,
|
||||||
seat: seat.clone(),
|
seat: seat.clone(),
|
||||||
outputs,
|
window_outputs: outputs,
|
||||||
|
cursor_output: output,
|
||||||
tiling: was_tiled,
|
tiling: was_tiled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +383,7 @@ impl MoveGrab {
|
||||||
+ grab_state.window_offset;
|
+ grab_state.window_offset;
|
||||||
|
|
||||||
let workspace_handle = state.common.shell.active_space(&output).handle;
|
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);
|
grab_state.window.output_leave(old_output);
|
||||||
}
|
}
|
||||||
for (window, _) in grab_state.window.windows() {
|
for (window, _) in grab_state.window.windows() {
|
||||||
|
|
|
||||||
|
|
@ -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(
|
pub fn drop_window(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: CosmicMapped,
|
window: CosmicMapped,
|
||||||
|
|
|
||||||
|
|
@ -1003,6 +1003,12 @@ impl Shell {
|
||||||
if match &mut self.workspaces {
|
if match &mut self.workspaces {
|
||||||
WorkspaceMode::OutputBound(sets, _) => {
|
WorkspaceMode::OutputBound(sets, _) => {
|
||||||
if let Some(set) = sets.get_mut(output) {
|
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())?
|
set.activate(idx, &mut self.workspace_state.update())?
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue