tiling: Add proper output_enter/leave events
This commit is contained in:
parent
77858d3628
commit
7e45e51781
3 changed files with 90 additions and 60 deletions
|
|
@ -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 = {
|
||||||
window.set_tiled(false);
|
let node_id = window.tiling_node_id.lock().unwrap().clone()?;
|
||||||
self.refresh();
|
self.trees
|
||||||
true
|
.iter()
|
||||||
} else {
|
.find(|(_, tree)| {
|
||||||
false
|
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);
|
||||||
|
self.refresh();
|
||||||
|
Some(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
|
|
|
||||||
|
|
@ -1006,58 +1006,55 @@ 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
|
||||||
.common
|
|
||||||
.shell
|
|
||||||
.toplevel_info_state
|
|
||||||
.toplevel_leave_workspace(&toplevel, &from_workspace.handle);
|
|
||||||
}
|
|
||||||
let elements = from_workspace.mapped().cloned().collect::<Vec<_>>();
|
|
||||||
std::mem::drop(from_workspace);
|
|
||||||
for mapped in elements.into_iter() {
|
|
||||||
state.common.shell.update_reactive_popups(&mapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
let to_workspace = state
|
|
||||||
.common
|
.common
|
||||||
.shell
|
.shell
|
||||||
.workspaces
|
.toplevel_info_state
|
||||||
.get_mut(to_idx, to_output)
|
.toplevel_leave_workspace(&toplevel, &from_workspace.handle);
|
||||||
.unwrap(); // checked above
|
|
||||||
let focus_stack = to_workspace.focus_stack.get(&seat);
|
|
||||||
if was_floating {
|
|
||||||
to_workspace.floating_layer.map(mapped.clone(), &seat, None);
|
|
||||||
} else {
|
|
||||||
to_workspace
|
|
||||||
.tiling_layer
|
|
||||||
.map(mapped.clone(), &seat, focus_stack.iter());
|
|
||||||
}
|
|
||||||
for (toplevel, _) in mapped.windows() {
|
|
||||||
state
|
|
||||||
.common
|
|
||||||
.shell
|
|
||||||
.toplevel_info_state
|
|
||||||
.toplevel_enter_workspace(&toplevel, &to_workspace.handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
for mapped in to_workspace
|
|
||||||
.mapped()
|
|
||||||
.cloned()
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.into_iter()
|
|
||||||
{
|
|
||||||
state.common.shell.update_reactive_popups(&mapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.common.shell.activate(to_output, to_idx);
|
|
||||||
Common::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None);
|
|
||||||
}
|
}
|
||||||
|
let elements = from_workspace.mapped().cloned().collect::<Vec<_>>();
|
||||||
|
std::mem::drop(from_workspace);
|
||||||
|
for mapped in elements.into_iter() {
|
||||||
|
state.common.shell.update_reactive_popups(&mapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
let to_workspace = state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.workspaces
|
||||||
|
.get_mut(to_idx, to_output)
|
||||||
|
.unwrap(); // checked above
|
||||||
|
let focus_stack = to_workspace.focus_stack.get(&seat);
|
||||||
|
if window_state == ManagedState::Floating {
|
||||||
|
to_workspace.floating_layer.map(mapped.clone(), &seat, None);
|
||||||
|
} else {
|
||||||
|
to_workspace
|
||||||
|
.tiling_layer
|
||||||
|
.map(mapped.clone(), &seat, focus_stack.iter());
|
||||||
|
}
|
||||||
|
for (toplevel, _) in mapped.windows() {
|
||||||
|
state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.toplevel_info_state
|
||||||
|
.toplevel_enter_workspace(&toplevel, &to_workspace.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
for mapped in to_workspace
|
||||||
|
.mapped()
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
{
|
||||||
|
state.common.shell.update_reactive_popups(&mapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.common.shell.activate(to_output, to_idx);
|
||||||
|
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) {
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue