Merge branch 'feature/tiling_toggle' into master_jammy
This commit is contained in:
commit
b2572e05ad
5 changed files with 75 additions and 6 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
key_bindings: {
|
key_bindings: {
|
||||||
(modifiers: [Logo, Shift], key: "Escape"): Terminate,
|
(modifiers: [Logo, Shift], key: "Escape"): Terminate,
|
||||||
(modifiers: [Logo], key: "Escape"): Debug,
|
(modifiers: [Logo], key: "Escape"): Debug,
|
||||||
(modifiers: [Logo], key: "Q"): Close,
|
(modifiers: [Logo], key: "q"): Close,
|
||||||
(modifiers: [Logo], key: "1"): Workspace(1),
|
(modifiers: [Logo], key: "1"): Workspace(1),
|
||||||
(modifiers: [Logo], key: "2"): Workspace(2),
|
(modifiers: [Logo], key: "2"): Workspace(2),
|
||||||
(modifiers: [Logo], key: "3"): Workspace(3),
|
(modifiers: [Logo], key: "3"): Workspace(3),
|
||||||
|
|
@ -31,9 +31,11 @@
|
||||||
(modifiers: [Logo], key: "j"): Focus(Down),
|
(modifiers: [Logo], key: "j"): Focus(Down),
|
||||||
(modifiers: [Logo], key: "k"): Focus(Up),
|
(modifiers: [Logo], key: "k"): Focus(Up),
|
||||||
(modifiers: [Logo], key: "l"): Focus(Right),
|
(modifiers: [Logo], key: "l"): Focus(Right),
|
||||||
//TODO: automatic orientation with Logo+o toggling
|
//TODO: automatic orientation with Logo+o toggling
|
||||||
(modifiers: [Logo], key: "v"): Orientation(Vertical),
|
(modifiers: [Logo], key: "v"): Orientation(Vertical),
|
||||||
(modifiers: [Logo], key: "o"): Orientation(Horizontal),
|
(modifiers: [Logo], key: "o"): Orientation(Horizontal),
|
||||||
|
(modifiers: [Logo], key: "y"): ToggleTiling,
|
||||||
|
(modifiers: [Logo], key: "g"): ToggleWindowFloating,
|
||||||
(modifiers: [Logo, Shift], key: "f"): Fullscreen,
|
(modifiers: [Logo, Shift], key: "f"): Fullscreen,
|
||||||
//TODO: ability to select default web browser
|
//TODO: ability to select default web browser
|
||||||
(modifiers: [Logo], key: "b"): Spawn("firefox"),
|
(modifiers: [Logo], key: "b"): Spawn("firefox"),
|
||||||
|
|
@ -42,7 +44,7 @@
|
||||||
//TODO: ability to select default terminal
|
//TODO: ability to select default terminal
|
||||||
(modifiers: [Logo], key: "t"): Spawn("gnome-terminal"),
|
(modifiers: [Logo], key: "t"): Spawn("gnome-terminal"),
|
||||||
(modifiers: [Logo], key: "a"): Spawn("xdg-shell-wrapper cosmic-app-library"),
|
(modifiers: [Logo], key: "a"): Spawn("xdg-shell-wrapper cosmic-app-library"),
|
||||||
(modifiers: [Logo], key: "Slash"): Spawn("xdg-shell-wrapper cosmic-launcher"),
|
(modifiers: [Logo], key: "slash"): Spawn("xdg-shell-wrapper cosmic-launcher"),
|
||||||
},
|
},
|
||||||
workspace_mode: OutputBound,
|
workspace_mode: OutputBound,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -749,6 +749,8 @@ pub enum Action {
|
||||||
MoveToWorkspace(u8),
|
MoveToWorkspace(u8),
|
||||||
Focus(FocusDirection),
|
Focus(FocusDirection),
|
||||||
Orientation(crate::shell::layout::Orientation),
|
Orientation(crate::shell::layout::Orientation),
|
||||||
|
ToggleTiling,
|
||||||
|
ToggleWindowFloating,
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
Spawn(String),
|
Spawn(String),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -355,6 +355,16 @@ impl State {
|
||||||
focus_stack.iter(),
|
focus_stack.iter(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Action::ToggleTiling => {
|
||||||
|
let output = active_output(seat, &self.common);
|
||||||
|
let workspace = self.common.shell.active_space_mut(&output);
|
||||||
|
workspace.toggle_tiling(seat);
|
||||||
|
}
|
||||||
|
Action::ToggleWindowFloating => {
|
||||||
|
let output = active_output(seat, &self.common);
|
||||||
|
let workspace = self.common.shell.active_space_mut(&output);
|
||||||
|
workspace.toggle_floating_window(seat);
|
||||||
|
}
|
||||||
Action::Spawn(command) => {
|
Action::Spawn(command) => {
|
||||||
if let Err(err) = std::process::Command::new("/bin/sh")
|
if let Err(err) = std::process::Command::new("/bin/sh")
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use smithay::{
|
||||||
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{
|
reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{
|
||||||
ResizeEdge, State as XdgState,
|
ResizeEdge, State as XdgState,
|
||||||
},
|
},
|
||||||
utils::IsAlive,
|
utils::{IsAlive, Rectangle, Logical},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::with_states,
|
||||||
output::Output,
|
output::Output,
|
||||||
|
|
@ -29,6 +29,12 @@ pub struct FloatingLayout {
|
||||||
pub windows: HashSet<Window>,
|
pub windows: HashSet<Window>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WindowUserDataInner {
|
||||||
|
last_geometry: Rectangle<i32, Logical>,
|
||||||
|
}
|
||||||
|
pub type WindowUserData = Mutex<WindowUserDataInner>;
|
||||||
|
|
||||||
impl FloatingLayout {
|
impl FloatingLayout {
|
||||||
pub fn new() -> FloatingLayout {
|
pub fn new() -> FloatingLayout {
|
||||||
Default::default()
|
Default::default()
|
||||||
|
|
@ -53,11 +59,17 @@ impl FloatingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_window_internal(&mut self, space: &mut Space, window: Window, output: &Output) {
|
fn map_window_internal(&mut self, space: &mut Space, window: Window, output: &Output) {
|
||||||
|
let last_geometry = window.user_data().get::<WindowUserData>().map(|u| u.lock().unwrap().last_geometry);
|
||||||
let mut win_geo = window.geometry();
|
let mut win_geo = window.geometry();
|
||||||
|
|
||||||
let layers = layer_map_for_output(&output);
|
let layers = layer_map_for_output(&output);
|
||||||
let geometry = layers.non_exclusive_zone();
|
let geometry = layers.non_exclusive_zone();
|
||||||
|
|
||||||
let mut geo_updated = false;
|
let mut geo_updated = false;
|
||||||
|
if let Some(size) = last_geometry.clone().map(|g| g.size) {
|
||||||
|
geo_updated = win_geo.size == size;
|
||||||
|
win_geo.size = size;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
let (min_size, max_size) = with_states(window.toplevel().wl_surface(), |states| {
|
let (min_size, max_size) = with_states(window.toplevel().wl_surface(), |states| {
|
||||||
let attrs = states
|
let attrs = states
|
||||||
|
|
@ -100,10 +112,10 @@ impl FloatingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let position = (
|
let position = last_geometry.map(|g| g.loc).unwrap_or_else(|| (
|
||||||
geometry.loc.x + (geometry.size.w / 2) - (win_geo.size.w / 2) + win_geo.loc.x,
|
geometry.loc.x + (geometry.size.w / 2) - (win_geo.size.w / 2) + win_geo.loc.x,
|
||||||
geometry.loc.y + (geometry.size.h / 2) - (win_geo.size.h / 2) + win_geo.loc.y,
|
geometry.loc.y + (geometry.size.h / 2) - (win_geo.size.h / 2) + win_geo.loc.y,
|
||||||
);
|
).into());
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||||
|
|
@ -124,6 +136,15 @@ impl FloatingLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmap_window(&mut self, space: &mut Space, window: &Window) {
|
pub fn unmap_window(&mut self, space: &mut Space, window: &Window) {
|
||||||
|
if let Some(location) = space.window_location(window) {
|
||||||
|
let user_data = window.user_data();
|
||||||
|
user_data.insert_if_missing(|| WindowUserData::default());
|
||||||
|
user_data.get::<WindowUserData>().unwrap().lock().unwrap().last_geometry = Rectangle::from_loc_and_size(
|
||||||
|
location,
|
||||||
|
window.geometry().size,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
space.unmap_window(window);
|
space.unmap_window(window);
|
||||||
self.pending_windows.retain(|w| w != window);
|
self.pending_windows.retain(|w| w != window);
|
||||||
self.windows.remove(window);
|
self.windows.remove(window);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ pub struct Workspace {
|
||||||
pub space: Space,
|
pub space: Space,
|
||||||
pub tiling_layer: TilingLayout,
|
pub tiling_layer: TilingLayout,
|
||||||
pub floating_layer: FloatingLayout,
|
pub floating_layer: FloatingLayout,
|
||||||
|
tiling_enabled: bool,
|
||||||
pub fullscreen: HashMap<String, Window>,
|
pub fullscreen: HashMap<String, Window>,
|
||||||
pub handle: WorkspaceHandle,
|
pub handle: WorkspaceHandle,
|
||||||
}
|
}
|
||||||
|
|
@ -35,6 +36,7 @@ impl Workspace {
|
||||||
space: Space::new(None),
|
space: Space::new(None),
|
||||||
tiling_layer: TilingLayout::new(),
|
tiling_layer: TilingLayout::new(),
|
||||||
floating_layer: FloatingLayout::new(),
|
floating_layer: FloatingLayout::new(),
|
||||||
|
tiling_enabled: true,
|
||||||
fullscreen: HashMap::new(),
|
fullscreen: HashMap::new(),
|
||||||
handle,
|
handle,
|
||||||
}
|
}
|
||||||
|
|
@ -172,4 +174,36 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
self.fullscreen.get(&output.name()).filter(|w| w.alive())
|
self.fullscreen.get(&output.name()).filter(|w| w.alive())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
|
||||||
|
if self.tiling_enabled {
|
||||||
|
for window in self.tiling_layer.windows.clone().into_iter() {
|
||||||
|
self.tiling_layer.unmap_window(&mut self.space, &window);
|
||||||
|
self.floating_layer.map_window(&mut self.space, window, seat);
|
||||||
|
}
|
||||||
|
self.tiling_enabled = false;
|
||||||
|
} else {
|
||||||
|
let focus_stack = self.focus_stack(seat);
|
||||||
|
for window in self.floating_layer.windows.clone().into_iter() {
|
||||||
|
self.floating_layer.unmap_window(&mut self.space, &window);
|
||||||
|
self.tiling_layer.map_window(&mut self.space, window, seat, focus_stack.iter())
|
||||||
|
}
|
||||||
|
self.tiling_enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toggle_floating_window(&mut self, seat: &Seat<State>) {
|
||||||
|
if self.tiling_enabled {
|
||||||
|
if let Some(window) = self.focus_stack(seat).iter().next().cloned() {
|
||||||
|
if self.tiling_layer.windows.contains(&window) {
|
||||||
|
self.tiling_layer.unmap_window(&mut self.space, &window);
|
||||||
|
self.floating_layer.map_window(&mut self.space, window, seat);
|
||||||
|
} else if self.floating_layer.windows.contains(&window) {
|
||||||
|
let focus_stack = self.focus_stack(seat);
|
||||||
|
self.floating_layer.unmap_window(&mut self.space, &window);
|
||||||
|
self.tiling_layer.map_window(&mut self.space, window, seat, focus_stack.iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue