shell: Handle removed output state better

This commit is contained in:
Victoria Brekenfeld 2023-01-24 21:01:11 +01:00
parent e7be9d6abf
commit 58f196d638
4 changed files with 76 additions and 10 deletions

View file

@ -18,6 +18,7 @@ use crate::{
},
state::State,
utils::prelude::*,
wayland::protocols::toplevel_info::ToplevelInfoState,
};
mod grabs;
@ -45,9 +46,30 @@ impl FloatingLayout {
self.space.map_output(output, location)
}
pub fn unmap_output(&mut self, output: &Output) {
pub fn unmap_output(
&mut self,
output: &Output,
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
) {
let windows = self
.space
.elements_for_output(output)
.cloned()
.collect::<Vec<_>>();
for window in &windows {
for (toplevel, _) in window.windows() {
toplevel_info.toplevel_leave_output(&toplevel, output);
}
}
self.space.unmap_output(output);
self.refresh();
for window in &windows {
for output in self.space.outputs_for_element(&window) {
for (toplevel, _) in window.windows() {
toplevel_info.toplevel_enter_output(&toplevel, &output);
}
}
}
}
pub fn map(

View file

@ -13,7 +13,9 @@ use crate::{
CosmicSurface, OutputNotMapped,
},
utils::prelude::*,
wayland::handlers::xdg_shell::popup::get_popup_toplevel,
wayland::{
handlers::xdg_shell::popup::get_popup_toplevel, protocols::toplevel_info::ToplevelInfoState,
},
};
use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree};
@ -275,14 +277,37 @@ impl TilingLayout {
}
}
pub fn unmap_output(&mut self, output: &Output) {
pub fn unmap_output(
&mut self,
output: &Output,
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
) {
if let Some(src) = self.trees.remove(output) {
// TODO: expects last remaining output
let Some((output, dst)) = self.trees.iter_mut().next() else { return; };
let orientation = match output.output.geometry().size {
let Some((new_output, dst)) = self.trees.iter_mut().next() else { return; };
let orientation = match new_output.output.geometry().size {
x if x.w >= x.h => Orientation::Vertical,
_ => Orientation::Horizontal,
};
for node in src
.root_node_id()
.and_then(|root_id| src.traverse_pre_order(root_id).ok())
.into_iter()
.flatten()
{
if let Data::Mapped {
mapped,
last_geometry: _,
} = node.data()
{
for (toplevel, _) in mapped.windows() {
toplevel_info.toplevel_leave_output(&toplevel, output);
toplevel_info.toplevel_enter_output(&toplevel, &new_output.output);
}
mapped.output_leave(output);
mapped.output_enter(&new_output.output, mapped.bbox());
}
}
TilingLayout::merge_trees(src, dst, orientation);
self.refresh()
}