shell: Populate focus_stack when unstacking
This commit is contained in:
parent
dc882ffc36
commit
b9a323c9ff
4 changed files with 61 additions and 18 deletions
|
|
@ -18,7 +18,7 @@ use super::{Item, ResizeEdge};
|
||||||
fn toggle_stacking(state: &mut State, mapped: &CosmicMapped) {
|
fn toggle_stacking(state: &mut State, mapped: &CosmicMapped) {
|
||||||
let mut shell = state.common.shell.write().unwrap();
|
let mut shell = state.common.shell.write().unwrap();
|
||||||
let seat = shell.seats.last_active().clone();
|
let seat = shell.seats.last_active().clone();
|
||||||
if let Some(new_focus) = shell.toggle_stacking(mapped) {
|
if let Some(new_focus) = shell.toggle_stacking(&seat, mapped) {
|
||||||
std::mem::drop(shell);
|
std::mem::drop(shell);
|
||||||
Shell::set_focus(state, Some(&new_focus), &seat, None);
|
Shell::set_focus(state, Some(&new_focus), &seat, None);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -882,7 +882,11 @@ impl FloatingLayout {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_stacking(&mut self, mapped: &CosmicMapped) -> Option<KeyboardFocusTarget> {
|
pub fn toggle_stacking(
|
||||||
|
&mut self,
|
||||||
|
mapped: &CosmicMapped,
|
||||||
|
mut focus_stack: FocusStackMut,
|
||||||
|
) -> Option<KeyboardFocusTarget> {
|
||||||
if !self.space.elements().any(|m| m == mapped) {
|
if !self.space.elements().any(|m| m == mapped) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -902,20 +906,24 @@ impl FloatingLayout {
|
||||||
Some(geo.size),
|
Some(geo.size),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
focus_stack.append(&mapped);
|
||||||
Some(KeyboardFocusTarget::Element(mapped))
|
Some(KeyboardFocusTarget::Element(mapped))
|
||||||
} else {
|
} else {
|
||||||
// if we have a stack
|
// if we have a stack
|
||||||
let mut surfaces = mapped.windows().map(|(s, _)| s).collect::<VecDeque<_>>();
|
let mut surfaces = mapped.windows().map(|(s, _)| s).collect::<VecDeque<_>>();
|
||||||
let first = surfaces.pop_front().expect("Stack without a window?");
|
let first = surfaces.pop_front().expect("Stack without a window?");
|
||||||
|
let focused = mapped.active_window();
|
||||||
|
|
||||||
self.space.unmap_elem(&mapped);
|
self.space.unmap_elem(&mapped);
|
||||||
let handle = mapped.loop_handle();
|
let handle = mapped.loop_handle();
|
||||||
mapped.convert_to_surface(first, (&output, mapped.bbox()), self.theme.clone());
|
mapped.convert_to_surface(first, (&output, mapped.bbox()), self.theme.clone());
|
||||||
|
let mut new_elements = vec![mapped.clone()];
|
||||||
|
|
||||||
// map the rest
|
// map the rest
|
||||||
for other in surfaces {
|
for other in surfaces {
|
||||||
other.try_force_undecorated(false);
|
other.try_force_undecorated(false);
|
||||||
other.set_tiled(false);
|
other.set_tiled(false);
|
||||||
|
let focused = other == focused;
|
||||||
let window = CosmicMapped::from(CosmicWindow::new(
|
let window = CosmicMapped::from(CosmicWindow::new(
|
||||||
other,
|
other,
|
||||||
handle.clone(),
|
handle.clone(),
|
||||||
|
|
@ -928,10 +936,19 @@ impl FloatingLayout {
|
||||||
window.set_bounds(layer_map.non_exclusive_zone().size);
|
window.set_bounds(layer_map.non_exclusive_zone().size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if focused {
|
||||||
|
new_elements.insert(0, window.clone());
|
||||||
|
} else {
|
||||||
|
new_elements.push(window.clone());
|
||||||
|
}
|
||||||
self.map(window, None);
|
self.map(window, None);
|
||||||
}
|
}
|
||||||
self.space.map_element(mapped.clone(), location, false);
|
self.space.map_element(mapped.clone(), location, false);
|
||||||
|
|
||||||
|
for elem in new_elements.into_iter().rev() {
|
||||||
|
focus_stack.append(&elem);
|
||||||
|
}
|
||||||
|
|
||||||
Some(KeyboardFocusTarget::Element(mapped))
|
Some(KeyboardFocusTarget::Element(mapped))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -939,16 +956,14 @@ impl FloatingLayout {
|
||||||
pub fn toggle_stacking_focused<'a>(
|
pub fn toggle_stacking_focused<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
seat: &Seat<State>,
|
seat: &Seat<State>,
|
||||||
mut focus_stack: FocusStackMut,
|
focus_stack: FocusStackMut,
|
||||||
) -> Option<KeyboardFocusTarget> {
|
) -> Option<KeyboardFocusTarget> {
|
||||||
let Some(KeyboardFocusTarget::Element(elem)) = seat.get_keyboard().unwrap().current_focus()
|
let Some(KeyboardFocusTarget::Element(elem)) = seat.get_keyboard().unwrap().current_focus()
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = self.toggle_stacking(&elem);
|
self.toggle_stacking(&elem, focus_stack)
|
||||||
focus_stack.append(&elem);
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_element<'a>(
|
pub fn move_element<'a>(
|
||||||
|
|
|
||||||
|
|
@ -2108,7 +2108,11 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_stacking(&mut self, mapped: &CosmicMapped) -> Option<KeyboardFocusTarget> {
|
pub fn toggle_stacking(
|
||||||
|
&mut self,
|
||||||
|
mapped: &CosmicMapped,
|
||||||
|
mut focus_stack: FocusStackMut,
|
||||||
|
) -> Option<KeyboardFocusTarget> {
|
||||||
let gaps = self.gaps();
|
let gaps = self.gaps();
|
||||||
|
|
||||||
let Some(node_id) = mapped.tiling_node_id.lock().unwrap().clone() else {
|
let Some(node_id) = mapped.tiling_node_id.lock().unwrap().clone() else {
|
||||||
|
|
@ -2125,6 +2129,7 @@ impl TilingLayout {
|
||||||
match tree.get_mut(&node_id).unwrap().data_mut() {
|
match tree.get_mut(&node_id).unwrap().data_mut() {
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone());
|
mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone());
|
||||||
|
focus_stack.append(&mapped);
|
||||||
KeyboardFocusTarget::Element(mapped.clone())
|
KeyboardFocusTarget::Element(mapped.clone())
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
@ -2133,6 +2138,9 @@ impl TilingLayout {
|
||||||
// if we have a stack
|
// if we have a stack
|
||||||
let mut surfaces = mapped.windows().map(|(s, _)| s);
|
let mut surfaces = mapped.windows().map(|(s, _)| s);
|
||||||
let first = surfaces.next().expect("Stack without a window?");
|
let first = surfaces.next().expect("Stack without a window?");
|
||||||
|
let focused = mapped.active_window();
|
||||||
|
|
||||||
|
let mut new_elements = Vec::new();
|
||||||
|
|
||||||
let handle = match tree.get_mut(&node_id).unwrap().data_mut() {
|
let handle = match tree.get_mut(&node_id).unwrap().data_mut() {
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
|
|
@ -2142,6 +2150,7 @@ impl TilingLayout {
|
||||||
(&self.output, mapped.bbox()),
|
(&self.output, mapped.bbox()),
|
||||||
self.theme.clone(),
|
self.theme.clone(),
|
||||||
);
|
);
|
||||||
|
new_elements.push(mapped.clone());
|
||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
@ -2152,6 +2161,7 @@ impl TilingLayout {
|
||||||
for other in surfaces {
|
for other in surfaces {
|
||||||
other.try_force_undecorated(false);
|
other.try_force_undecorated(false);
|
||||||
other.set_tiled(false);
|
other.set_tiled(false);
|
||||||
|
let focused = other == focused;
|
||||||
let window = CosmicMapped::from(CosmicWindow::new(
|
let window = CosmicMapped::from(CosmicWindow::new(
|
||||||
other,
|
other,
|
||||||
handle.clone(),
|
handle.clone(),
|
||||||
|
|
@ -2174,6 +2184,11 @@ impl TilingLayout {
|
||||||
);
|
);
|
||||||
|
|
||||||
let node = window.tiling_node_id.lock().unwrap().clone().unwrap();
|
let node = window.tiling_node_id.lock().unwrap().clone().unwrap();
|
||||||
|
if focused {
|
||||||
|
new_elements.insert(0, window);
|
||||||
|
} else {
|
||||||
|
new_elements.push(window);
|
||||||
|
}
|
||||||
current_node = node;
|
current_node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2184,15 +2199,20 @@ impl TilingLayout {
|
||||||
node_id
|
node_id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for elem in new_elements.iter().rev() {
|
||||||
|
focus_stack.append(elem);
|
||||||
|
}
|
||||||
|
|
||||||
match tree.get(&node_id).unwrap().data() {
|
match tree.get(&node_id).unwrap().data() {
|
||||||
Data::Group { alive, .. } => KeyboardFocusTarget::Group(WindowGroup {
|
Data::Group { alive, .. } => KeyboardFocusTarget::Group(WindowGroup {
|
||||||
node: node_id.clone(),
|
node: node_id.clone(),
|
||||||
alive: Arc::downgrade(alive),
|
alive: Arc::downgrade(alive),
|
||||||
focus_stack: tree
|
focus_stack: vec![new_elements[0]
|
||||||
.children_ids(&node_id)
|
.tiling_node_id
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.cloned()
|
.clone()
|
||||||
.collect::<Vec<_>>(),
|
.unwrap()],
|
||||||
}),
|
}),
|
||||||
Data::Mapped { mapped, .. } => KeyboardFocusTarget::Element(mapped.clone()),
|
Data::Mapped { mapped, .. } => KeyboardFocusTarget::Element(mapped.clone()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
@ -2222,9 +2242,7 @@ impl TilingLayout {
|
||||||
{
|
{
|
||||||
match last_active_data {
|
match last_active_data {
|
||||||
FocusedNodeData::Window(mapped) => {
|
FocusedNodeData::Window(mapped) => {
|
||||||
let res = self.toggle_stacking(&mapped);
|
return self.toggle_stacking(&mapped, focus_stack);
|
||||||
focus_stack.append(&mapped);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
FocusedNodeData::Group(_, _) => {
|
FocusedNodeData::Group(_, _) => {
|
||||||
let mut handle = None;
|
let mut handle = None;
|
||||||
|
|
|
||||||
|
|
@ -3076,19 +3076,29 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn toggle_stacking(&mut self, window: &CosmicMapped) -> Option<KeyboardFocusTarget> {
|
pub fn toggle_stacking(
|
||||||
|
&mut self,
|
||||||
|
seat: &Seat<State>,
|
||||||
|
window: &CosmicMapped,
|
||||||
|
) -> Option<KeyboardFocusTarget> {
|
||||||
if let Some(set) = self
|
if let Some(set) = self
|
||||||
.workspaces
|
.workspaces
|
||||||
.sets
|
.sets
|
||||||
.values_mut()
|
.values_mut()
|
||||||
.find(|set| set.sticky_layer.mapped().any(|m| m == window))
|
.find(|set| set.sticky_layer.mapped().any(|m| m == window))
|
||||||
{
|
{
|
||||||
set.sticky_layer.toggle_stacking(window)
|
let workspace = &mut set.workspaces[set.active];
|
||||||
|
set.sticky_layer
|
||||||
|
.toggle_stacking(window, workspace.focus_stack.get_mut(seat))
|
||||||
} else if let Some(workspace) = self.space_for_mut(window) {
|
} else if let Some(workspace) = self.space_for_mut(window) {
|
||||||
if workspace.tiling_layer.mapped().any(|(m, _)| m == window) {
|
if workspace.tiling_layer.mapped().any(|(m, _)| m == window) {
|
||||||
workspace.tiling_layer.toggle_stacking(window)
|
workspace
|
||||||
|
.tiling_layer
|
||||||
|
.toggle_stacking(window, workspace.focus_stack.get_mut(seat))
|
||||||
} else if workspace.floating_layer.mapped().any(|w| w == window) {
|
} else if workspace.floating_layer.mapped().any(|w| w == window) {
|
||||||
workspace.floating_layer.toggle_stacking(window)
|
workspace
|
||||||
|
.floating_layer
|
||||||
|
.toggle_stacking(window, workspace.focus_stack.get_mut(seat))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue