floating: Add toggle_stacking_(focused)
This commit is contained in:
parent
0147c328f9
commit
f6c28466e9
3 changed files with 74 additions and 6 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::{HashMap, VecDeque},
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
@ -31,7 +31,7 @@ use crate::{
|
||||||
window::CosmicWindowRenderElement,
|
window::CosmicWindowRenderElement,
|
||||||
CosmicMapped, CosmicMappedRenderElement, CosmicWindow,
|
CosmicMapped, CosmicMappedRenderElement, CosmicWindow,
|
||||||
},
|
},
|
||||||
focus::{target::KeyboardFocusTarget, FocusDirection},
|
focus::{target::KeyboardFocusTarget, FocusDirection, FocusStackMut},
|
||||||
grabs::ResizeEdge,
|
grabs::ResizeEdge,
|
||||||
CosmicSurface, Direction, FocusResult, MoveResult, ResizeDirection, ResizeMode,
|
CosmicSurface, Direction, FocusResult, MoveResult, ResizeDirection, ResizeMode,
|
||||||
},
|
},
|
||||||
|
|
@ -51,6 +51,7 @@ pub struct FloatingLayout {
|
||||||
spawn_order: Vec<CosmicMapped>,
|
spawn_order: Vec<CosmicMapped>,
|
||||||
tiling_animations: HashMap<CosmicMapped, (Instant, Rectangle<i32, Local>)>,
|
tiling_animations: HashMap<CosmicMapped, (Instant, Rectangle<i32, Local>)>,
|
||||||
dirty: AtomicBool,
|
dirty: AtomicBool,
|
||||||
|
pub theme: cosmic::Theme,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
|
@ -125,8 +126,11 @@ impl TiledCorners {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FloatingLayout {
|
impl FloatingLayout {
|
||||||
pub fn new(output: &Output) -> FloatingLayout {
|
pub fn new(theme: cosmic::Theme, output: &Output) -> FloatingLayout {
|
||||||
let mut layout = Self::default();
|
let mut layout = Self {
|
||||||
|
theme,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
layout.space.map_output(output, (0, 0));
|
layout.space.map_output(output, (0, 0));
|
||||||
layout
|
layout
|
||||||
}
|
}
|
||||||
|
|
@ -632,6 +636,69 @@ impl FloatingLayout {
|
||||||
.unwrap_or(FocusResult::None)
|
.unwrap_or(FocusResult::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggle_stacking(&mut self, mapped: &CosmicMapped) -> Option<KeyboardFocusTarget> {
|
||||||
|
if !self.space.elements().any(|m| m == mapped) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = self.space.outputs().next().unwrap().clone();
|
||||||
|
let mut mapped = mapped.clone();
|
||||||
|
let geo = self.space.element_geometry(&mapped).unwrap();
|
||||||
|
let location = geo.loc;
|
||||||
|
|
||||||
|
if mapped.is_window() {
|
||||||
|
// if it is just a window
|
||||||
|
self.space.unmap_elem(&mapped);
|
||||||
|
mapped.convert_to_stack((&output, mapped.bbox()), self.theme.clone());
|
||||||
|
self.map_internal(mapped.clone(), Some(location.as_local()), Some(geo.size));
|
||||||
|
Some(KeyboardFocusTarget::Element(mapped))
|
||||||
|
} else {
|
||||||
|
// if we have a stack
|
||||||
|
let mut surfaces = mapped.windows().map(|(s, _)| s).collect::<VecDeque<_>>();
|
||||||
|
let first = surfaces.pop_front().expect("Stack without a window?");
|
||||||
|
|
||||||
|
self.space.unmap_elem(&mapped);
|
||||||
|
let handle = mapped.loop_handle();
|
||||||
|
mapped.convert_to_surface(first, (&output, mapped.bbox()), self.theme.clone());
|
||||||
|
|
||||||
|
// 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(&output, window.bbox());
|
||||||
|
|
||||||
|
{
|
||||||
|
let layer_map = layer_map_for_output(&output);
|
||||||
|
window.set_bounds(layer_map.non_exclusive_zone().size);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.map(window, None);
|
||||||
|
}
|
||||||
|
self.space.map_element(mapped.clone(), location, false);
|
||||||
|
|
||||||
|
Some(KeyboardFocusTarget::Element(mapped))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toggle_stacking_focused<'a>(
|
||||||
|
&mut self,
|
||||||
|
seat: &Seat<State>,
|
||||||
|
mut focus_stack: FocusStackMut,
|
||||||
|
) -> Option<KeyboardFocusTarget> {
|
||||||
|
let Some(KeyboardFocusTarget::Element(elem)) = seat.get_keyboard().unwrap().current_focus() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = self.toggle_stacking(&elem);
|
||||||
|
focus_stack.append(&elem);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_current_element<'a>(
|
pub fn move_current_element<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
|
|
|
||||||
|
|
@ -993,6 +993,7 @@ impl Workspaces {
|
||||||
s.theme = theme.clone();
|
s.theme = theme.clone();
|
||||||
for mut w in &mut s.workspaces {
|
for mut w in &mut s.workspaces {
|
||||||
w.tiling_layer.theme = theme.clone();
|
w.tiling_layer.theme = theme.clone();
|
||||||
|
w.floating_layer.theme = theme.clone();
|
||||||
|
|
||||||
w.mapped().for_each(|m| {
|
w.mapped().for_each(|m| {
|
||||||
m.update_theme(theme.clone());
|
m.update_theme(theme.clone());
|
||||||
|
|
|
||||||
|
|
@ -218,8 +218,8 @@ impl Workspace {
|
||||||
tiling_enabled: bool,
|
tiling_enabled: bool,
|
||||||
theme: cosmic::Theme,
|
theme: cosmic::Theme,
|
||||||
) -> Workspace {
|
) -> Workspace {
|
||||||
let tiling_layer = TilingLayout::new(theme, &output);
|
let tiling_layer = TilingLayout::new(theme.clone(), &output);
|
||||||
let floating_layer = FloatingLayout::new(&output);
|
let floating_layer = FloatingLayout::new(theme, &output);
|
||||||
let output_name = output.name();
|
let output_name = output.name();
|
||||||
|
|
||||||
Workspace {
|
Workspace {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue