tiling: Allow orientation of active container to be swapped

This commit is contained in:
Victoria Brekenfeld 2022-03-29 14:41:09 +02:00
parent 2c311c67d1
commit b3ff2a7ca3
9 changed files with 105 additions and 18 deletions

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::{input::active_output, state::State, utils::SurfaceDropNotifier};
use crate::{config::Config, input::active_output, state::State, utils::SurfaceDropNotifier};
use smithay::{
backend::renderer::utils::on_commit_buffer_handler,
desktop::{
@ -27,7 +27,7 @@ use smithay::{
};
use std::{cell::Cell, rc::Rc, sync::Mutex};
pub fn init_shell(display: &mut Display) -> super::Shell {
pub fn init_shell(config: &Config, display: &mut Display) -> super::Shell {
compositor_init(
display,
move |surface, mut ddata| {
@ -234,7 +234,7 @@ pub fn init_shell(display: &mut Display) -> super::Shell {
None,
);
super::Shell::new(popup_grab)
super::Shell::new(config, popup_grab)
}
fn check_grab_preconditions(

View file

@ -14,6 +14,12 @@ pub mod combined;
pub mod floating;
pub mod tiling;
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Orientation {
Horizontal,
Vertical,
}
pub trait Layout {
fn map_window<'a>(
&mut self,
@ -25,6 +31,15 @@ pub trait Layout {
fn refresh(&mut self, space: &mut Space);
//fn unmap_window(&mut self, space: &mut Space, window: &Window);
fn update_orientation<'a>(
&mut self,
orientation: Orientation,
seat: &Seat,
space: &mut Space,
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
) {
let _ = (orientation, seat, space, focus_stack);
}
fn maximize_request(&mut self, space: &mut Space, window: &Window, output: &Output) {
let _ = (space, window, output);
}

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::shell::layout::Layout;
use crate::shell::layout::{Layout, Orientation};
use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree};
use smithay::{
desktop::{layer_map_for_output, Kind, Space, Window},
@ -16,12 +16,6 @@ pub struct TilingLayout {
gaps: (i32, i32),
}
#[derive(Debug)]
pub enum Orientation {
Horizontal,
Vertical,
}
#[derive(Debug)]
pub enum Data {
Fork {
@ -143,6 +137,50 @@ impl Layout for TilingLayout {
self.refresh(space);
}
fn update_orientation<'a>(
&mut self,
new_orientation: Orientation,
seat: &Seat,
space: &mut Space,
mut focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
) {
{
let output = super::output_from_seat(seat, space);
output
.user_data()
.insert_if_missing(|| RefCell::new(OutputInfo::default()));
let mut output_info = output
.user_data()
.get::<RefCell<OutputInfo>>()
.unwrap()
.borrow_mut();
let tree = &mut output_info.trees.entry(self.idx).or_insert_with(Tree::new);
let last_active = focus_stack
.find_map(|window| tree.root_node_id()
.and_then(|root| tree.traverse_pre_order_ids(root).unwrap()
.find(|id| matches!(tree.get(id).map(|n| n.data()), Ok(Data::Window(w)) if w == window))
)
);
if let Some(ref node_id) = last_active {
let mut node_id = node_id.clone();
while let Some(parent_id) = tree.get(&node_id).unwrap().parent().cloned() {
if let &mut Data::Fork {
ref mut orientation,
..
} = tree.get_mut(&parent_id).unwrap().data_mut()
{
*orientation = new_orientation;
break;
}
node_id = parent_id;
}
}
}
self.refresh(space);
}
fn refresh(&mut self, space: &mut Space) {
while let Some(dead_windows) =
Some(update_space_positions(self.idx, space, self.gaps)).filter(|v| !v.is_empty())

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::config::Config;
pub use smithay::{
desktop::{PopupGrab, PopupManager, PopupUngrabStrategy, Space, Window},
reexports::wayland_server::protocol::wl_surface::WlSurface,
@ -33,10 +34,13 @@ impl ActiveWorkspace {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[derive(Debug, serde::Deserialize, PartialEq, Eq, Clone, Copy)]
pub enum Mode {
OutputBound,
Global { active: usize },
Global {
#[serde(default)]
active: usize,
},
}
impl Mode {
@ -60,11 +64,11 @@ pub struct Shell {
const UNINIT_SPACE: MaybeUninit<Workspace> = MaybeUninit::uninit();
impl Shell {
fn new(popup_grab: Rc<Cell<Option<PopupGrab>>>) -> Self {
fn new(config: &Config, popup_grab: Rc<Cell<Option<PopupGrab>>>) -> Self {
Shell {
popups: PopupManager::new(None),
popup_grab,
mode: Mode::global(),
mode: config.workspace_mode,
outputs: Vec::new(),
spaces: unsafe {
let mut spaces = [UNINIT_SPACE; MAX_WORKSPACES];
@ -392,4 +396,14 @@ impl Shell {
}
}
}
pub fn set_orientation(
&mut self,
seat: &Seat,
output: &Output,
orientation: layout::Orientation,
) {
self.active_space_mut(output)
.update_orientation(seat, orientation)
}
}

View file

@ -63,6 +63,11 @@ impl Workspace {
self.space.refresh();
}
pub fn update_orientation(&mut self, seat: &Seat, orientation: layout::Orientation) {
self.layout
.update_orientation(orientation, seat, &mut self.space, self.focus_stack.iter())
}
pub fn maximize_request(&mut self, window: &Window, output: &Output) {
self.layout
.maximize_request(&mut self.space, window, output)