tiling: Add explicit toggle_stacking/_focused
This commit is contained in:
parent
9ecfa8bfda
commit
6ac8fd2f90
1 changed files with 116 additions and 79 deletions
|
|
@ -382,7 +382,9 @@ impl TilingLayout {
|
||||||
let gaps = self.gaps();
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
TilingLayout::map_to_tree(&mut tree, window, &self.output, focus_stack, direction);
|
let last_active = focus_stack
|
||||||
|
.and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack));
|
||||||
|
TilingLayout::map_to_tree(&mut tree, window, &self.output, last_active, direction);
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
}
|
}
|
||||||
|
|
@ -391,7 +393,7 @@ impl TilingLayout {
|
||||||
mut tree: &mut Tree<Data>,
|
mut tree: &mut Tree<Data>,
|
||||||
window: impl Into<CosmicMapped>,
|
window: impl Into<CosmicMapped>,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
focus_stack: Option<impl Iterator<Item = &'a CosmicMapped> + 'a>,
|
node: Option<(NodeId, CosmicMapped)>,
|
||||||
direction: Option<Direction>,
|
direction: Option<Direction>,
|
||||||
) {
|
) {
|
||||||
let window = window.into();
|
let window = window.into();
|
||||||
|
|
@ -422,10 +424,7 @@ impl TilingLayout {
|
||||||
tree.insert(new_window, InsertBehavior::AsRoot).unwrap()
|
tree.insert(new_window, InsertBehavior::AsRoot).unwrap()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let last_active = focus_stack
|
if let Some((ref node_id, mut last_active_window)) = node {
|
||||||
.and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack));
|
|
||||||
|
|
||||||
if let Some((ref node_id, mut last_active_window)) = last_active {
|
|
||||||
if window.is_window() && last_active_window.is_stack() {
|
if window.is_window() && last_active_window.is_stack() {
|
||||||
let surface = window.active_window();
|
let surface = window.active_window();
|
||||||
last_active_window
|
last_active_window
|
||||||
|
|
@ -1902,11 +1901,107 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_stacking<'a>(&mut self, seat: &Seat<State>, mut focus_stack: FocusStackMut) {
|
pub fn toggle_stacking(&mut self, mapped: &CosmicMapped) -> Option<KeyboardFocusTarget> {
|
||||||
|
let gaps = self.gaps();
|
||||||
|
|
||||||
|
let Some(node_id) = mapped.tiling_node_id.lock().unwrap().clone() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
if tree.get(&node_id).is_err() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = if mapped.is_window() {
|
||||||
|
// if it is just a window
|
||||||
|
match tree.get_mut(&node_id).unwrap().data_mut() {
|
||||||
|
Data::Mapped { mapped, .. } => {
|
||||||
|
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone());
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyboardFocusTarget::Element(mapped.clone())
|
||||||
|
} else {
|
||||||
|
// if we have a stack
|
||||||
|
let mut surfaces = mapped.windows().map(|(s, _)| s);
|
||||||
|
let first = surfaces.next().expect("Stack without a window?");
|
||||||
|
|
||||||
|
let handle = match tree.get_mut(&node_id).unwrap().data_mut() {
|
||||||
|
Data::Mapped { mapped, .. } => {
|
||||||
|
let handle = mapped.loop_handle();
|
||||||
|
mapped.convert_to_surface(
|
||||||
|
first,
|
||||||
|
(&self.output, mapped.bbox()),
|
||||||
|
self.theme.clone(),
|
||||||
|
);
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// map the rest
|
||||||
|
let mut current_node = (node_id.clone(), mapped.clone());
|
||||||
|
for other in surfaces {
|
||||||
|
other.try_force_undecorated(false);
|
||||||
|
other.set_tiled(false);
|
||||||
|
let window = CosmicMapped::from(CosmicWindow::new(
|
||||||
|
other,
|
||||||
|
handle.clone(),
|
||||||
|
self.theme.clone(),
|
||||||
|
));
|
||||||
|
window.output_enter(&self.output, window.bbox());
|
||||||
|
|
||||||
|
{
|
||||||
|
let layer_map = layer_map_for_output(&self.output);
|
||||||
|
window.set_bounds(layer_map.non_exclusive_zone().size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TilingLayout::map_to_tree(
|
||||||
|
&mut tree,
|
||||||
|
window.clone(),
|
||||||
|
&self.output,
|
||||||
|
Some(current_node),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let node = window.tiling_node_id.lock().unwrap().clone().unwrap();
|
||||||
|
current_node = (node, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Focus the new group
|
||||||
|
if let Some(parent) = tree.get(&node_id).unwrap().parent() {
|
||||||
|
let Data::Group { alive, .. } = tree.get(&parent).unwrap().data() else { unreachable!() };
|
||||||
|
KeyboardFocusTarget::Group(WindowGroup {
|
||||||
|
node: parent.clone(),
|
||||||
|
alive: Arc::downgrade(alive),
|
||||||
|
focus_stack: tree
|
||||||
|
.children_ids(parent)
|
||||||
|
.unwrap()
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
KeyboardFocusTarget::Element(mapped.clone())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toggle_stacking_focused<'a>(
|
||||||
|
&mut self,
|
||||||
|
seat: &Seat<State>,
|
||||||
|
mut focus_stack: FocusStackMut,
|
||||||
|
) -> Option<KeyboardFocusTarget> {
|
||||||
let gaps = self.gaps();
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
let Some(target) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
return;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
let mut tree = self.queue.trees.back().unwrap().0.copy_clone();
|
||||||
|
|
@ -1915,64 +2010,9 @@ impl TilingLayout {
|
||||||
{
|
{
|
||||||
match last_active_data {
|
match last_active_data {
|
||||||
FocusedNodeData::Window(mapped) => {
|
FocusedNodeData::Window(mapped) => {
|
||||||
if mapped.is_window() {
|
let res = self.toggle_stacking(&mapped);
|
||||||
// if it is just a window
|
focus_stack.append(&mapped);
|
||||||
match tree.get_mut(&last_active).unwrap().data_mut() {
|
return res;
|
||||||
Data::Mapped { mapped, .. } => {
|
|
||||||
mapped.convert_to_stack(
|
|
||||||
(&self.output, mapped.bbox()),
|
|
||||||
self.theme.clone(),
|
|
||||||
);
|
|
||||||
focus_stack.append(&mapped);
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// if we have a stack
|
|
||||||
let mut surfaces = mapped.windows().map(|(s, _)| s);
|
|
||||||
let first = surfaces.next().expect("Stack without a window?");
|
|
||||||
|
|
||||||
let handle = match tree.get_mut(&last_active).unwrap().data_mut() {
|
|
||||||
Data::Mapped { mapped, .. } => {
|
|
||||||
let handle = mapped.loop_handle();
|
|
||||||
mapped.convert_to_surface(
|
|
||||||
first,
|
|
||||||
(&self.output, mapped.bbox()),
|
|
||||||
self.theme.clone(),
|
|
||||||
);
|
|
||||||
focus_stack.append(&mapped);
|
|
||||||
handle
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// map the rest
|
|
||||||
for other in surfaces {
|
|
||||||
other.try_force_undecorated(false);
|
|
||||||
other.set_tiled(false);
|
|
||||||
let window = CosmicMapped::from(CosmicWindow::new(
|
|
||||||
other,
|
|
||||||
handle.clone(),
|
|
||||||
self.theme.clone(),
|
|
||||||
));
|
|
||||||
window.output_enter(&self.output, window.bbox());
|
|
||||||
|
|
||||||
{
|
|
||||||
let layer_map = layer_map_for_output(&self.output);
|
|
||||||
window.set_bounds(layer_map.non_exclusive_zone().size);
|
|
||||||
}
|
|
||||||
|
|
||||||
TilingLayout::map_to_tree(
|
|
||||||
&mut tree,
|
|
||||||
window,
|
|
||||||
&self.output,
|
|
||||||
Some(focus_stack.iter()),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Focus the new group
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FocusedNodeData::Group(_, _) => {
|
FocusedNodeData::Group(_, _) => {
|
||||||
let mut handle = None;
|
let mut handle = None;
|
||||||
|
|
@ -1992,7 +2032,7 @@ impl TilingLayout {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if surfaces.is_empty() {
|
if surfaces.is_empty() {
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
let handle = handle.unwrap();
|
let handle = handle.unwrap();
|
||||||
let stack = CosmicStack::new(surfaces.into_iter(), handle, self.theme.clone());
|
let stack = CosmicStack::new(surfaces.into_iter(), handle, self.theme.clone());
|
||||||
|
|
@ -2010,7 +2050,6 @@ impl TilingLayout {
|
||||||
let data = tree.get_mut(&last_active).unwrap().data_mut();
|
let data = tree.get_mut(&last_active).unwrap().data_mut();
|
||||||
|
|
||||||
let geo = *data.geometry();
|
let geo = *data.geometry();
|
||||||
//stack.set_geometry(geo.as_local());
|
|
||||||
stack.output_enter(&self.output, stack.bbox());
|
stack.output_enter(&self.output, stack.bbox());
|
||||||
stack.set_activate(true);
|
stack.set_activate(true);
|
||||||
stack.active().send_configure();
|
stack.active().send_configure();
|
||||||
|
|
@ -2021,15 +2060,19 @@ impl TilingLayout {
|
||||||
*mapped.tiling_node_id.lock().unwrap() = Some(last_active);
|
*mapped.tiling_node_id.lock().unwrap() = Some(last_active);
|
||||||
focus_stack.append(&mapped);
|
focus_stack.append(&mapped);
|
||||||
*data = Data::Mapped {
|
*data = Data::Mapped {
|
||||||
mapped,
|
mapped: mapped.clone(),
|
||||||
last_geometry: geo,
|
last_geometry: geo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
||||||
|
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
||||||
|
|
||||||
|
return Some(KeyboardFocusTarget::Element(mapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps);
|
|
||||||
self.queue.push_tree(tree, ANIMATION_DURATION, blocker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recalculate(&mut self) {
|
pub fn recalculate(&mut self) {
|
||||||
|
|
@ -2414,13 +2457,7 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
TilingLayout::map_to_tree(
|
TilingLayout::map_to_tree(&mut tree, window.clone(), &self.output, None, None);
|
||||||
&mut tree,
|
|
||||||
window.clone(),
|
|
||||||
&self.output,
|
|
||||||
Option::<std::iter::Empty<_>>::None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
window
|
window
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue