tiling: Add proper output_enter/leave events

This commit is contained in:
Victoria Brekenfeld 2022-11-14 11:54:22 +01:00
parent 77858d3628
commit 7e45e51781
3 changed files with 90 additions and 60 deletions

View file

@ -291,6 +291,7 @@ impl TilingLayout {
focus_stack: impl Iterator<Item = &'a CosmicMapped> + 'a, focus_stack: impl Iterator<Item = &'a CosmicMapped> + 'a,
) { ) {
let output = seat.active_output(); let output = seat.active_output();
window.output_enter(&output, window.bbox());
self.map_internal(window, &output, Some(focus_stack)); self.map_internal(window, &output, Some(focus_stack));
self.refresh(); self.refresh();
} }
@ -345,17 +346,27 @@ impl TilingLayout {
*window.tiling_node_id.lock().unwrap() = Some(window_id); *window.tiling_node_id.lock().unwrap() = Some(window_id);
} }
pub fn unmap(&mut self, window: &CosmicMapped) -> bool { pub fn unmap(&mut self, window: &CosmicMapped) -> Option<Output> {
if self.unmap_window_internal(window) { let output = {
let node_id = window.tiling_node_id.lock().unwrap().clone()?;
self.trees
.iter()
.find(|(_, tree)| {
tree.get(&node_id)
.map(|node| node.data().is_mapped(Some(window)))
.unwrap_or(false)
})
.map(|(o, _)| o.output.clone())?
};
self.unmap_window_internal(window);
window.output_leave(&output);
window.set_tiled(false); window.set_tiled(false);
self.refresh(); self.refresh();
true Some(output)
} else {
false
}
} }
fn unmap_window_internal(&mut self, mapped: &CosmicMapped) -> bool { fn unmap_window_internal(&mut self, mapped: &CosmicMapped) {
if let Some(node_id) = mapped.tiling_node_id.lock().unwrap().as_ref() { if let Some(node_id) = mapped.tiling_node_id.lock().unwrap().as_ref() {
if let Some(tree) = self.trees.values_mut().find(|tree| { if let Some(tree) = self.trees.values_mut().find(|tree| {
tree.get(node_id) tree.get(node_id)
@ -415,11 +426,8 @@ impl TilingLayout {
} }
None => {} // root None => {} // root
} }
return true;
} }
} }
false
} }
pub fn output_for_element(&self, elem: &CosmicMapped) -> Option<&Output> { pub fn output_for_element(&self, elem: &CosmicMapped) -> Option<&Output> {

View file

@ -1006,10 +1006,8 @@ impl Shell {
let from_workspace = state.common.shell.workspaces.active_mut(from_output); let from_workspace = state.common.shell.workspaces.active_mut(from_output);
let maybe_window = from_workspace.focus_stack.get(seat).last().cloned(); let maybe_window = from_workspace.focus_stack.get(seat).last().cloned();
if let Some(mapped) = maybe_window { let Some(mapped) = maybe_window else { return; };
let was_floating = from_workspace.floating_layer.unmap(&mapped); let Some(window_state) = from_workspace.unmap(&mapped) else { return; };
let was_tiling = from_workspace.tiling_layer.unmap(&mapped);
assert!(was_floating != was_tiling);
for (toplevel, _) in mapped.windows() { for (toplevel, _) in mapped.windows() {
state state
@ -1031,7 +1029,7 @@ impl Shell {
.get_mut(to_idx, to_output) .get_mut(to_idx, to_output)
.unwrap(); // checked above .unwrap(); // checked above
let focus_stack = to_workspace.focus_stack.get(&seat); let focus_stack = to_workspace.focus_stack.get(&seat);
if was_floating { if window_state == ManagedState::Floating {
to_workspace.floating_layer.map(mapped.clone(), &seat, None); to_workspace.floating_layer.map(mapped.clone(), &seat, None);
} else { } else {
to_workspace to_workspace
@ -1058,7 +1056,6 @@ impl Shell {
state.common.shell.activate(to_output, to_idx); state.common.shell.activate(to_output, to_idx);
Common::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None); Common::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None);
} }
}
pub fn update_reactive_popups(&self, mapped: &CosmicMapped) { pub fn update_reactive_popups(&self, mapped: &CosmicMapped) {
if let Some(workspace) = self.space_for(mapped) { if let Some(workspace) = self.space_for(mapped) {

View file

@ -55,6 +55,12 @@ pub struct Workspace {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct FocusStacks(HashMap<Seat<State>, IndexSet<CosmicMapped>>); pub struct FocusStacks(HashMap<Seat<State>, IndexSet<CosmicMapped>>);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ManagedState {
Tiling,
Floating,
}
impl Workspace { impl Workspace {
pub fn new(handle: WorkspaceHandle) -> Workspace { pub fn new(handle: WorkspaceHandle) -> Workspace {
Workspace { Workspace {
@ -100,6 +106,25 @@ impl Workspace {
self.refresh(); self.refresh();
} }
pub fn unmap(&mut self, mapped: &CosmicMapped) -> Option<ManagedState> {
let was_floating = self.floating_layer.unmap(&mapped);
let was_tiling = self.tiling_layer.unmap(&mapped).is_some();
if was_floating || was_tiling {
assert!(was_floating != was_tiling);
}
self.focus_stack
.0
.values_mut()
.for_each(|set| set.retain(|m| m != mapped));
if was_floating {
Some(ManagedState::Floating)
} else if was_tiling {
Some(ManagedState::Tiling)
} else {
None
}
}
pub fn element_for_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> { pub fn element_for_surface(&self, surface: &WlSurface) -> Option<&CosmicMapped> {
self.floating_layer self.floating_layer
.mapped() .mapped()