tiling: Allow orientation of active container to be swapped
This commit is contained in:
parent
2c311c67d1
commit
b3ff2a7ca3
9 changed files with 105 additions and 18 deletions
|
|
@ -27,6 +27,9 @@
|
|||
(modifiers: [Logo], key: "Right"): Focus(Right),
|
||||
(modifiers: [Logo], key: "Up"): Focus(Up),
|
||||
(modifiers: [Logo], key: "Down"): Focus(Down),
|
||||
(modifiers: [Logo], key: "v"): Orientation(Vertical),
|
||||
(modifiers: [Logo], key: "h"): Orientation(Horizontal),
|
||||
(modifiers: [Ctrl], key: "Return"): Spawn("gnome-terminal"),
|
||||
}
|
||||
},
|
||||
workspace_mode: OutputBound,
|
||||
)
|
||||
|
|
@ -12,6 +12,7 @@ use xkbcommon::xkb;
|
|||
#[derive(Debug, Deserialize)]
|
||||
pub struct Config {
|
||||
pub key_bindings: HashMap<KeyPattern, Action>,
|
||||
pub workspace_mode: crate::shell::Mode,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
|
@ -39,6 +40,7 @@ impl Config {
|
|||
|
||||
Config {
|
||||
key_bindings: HashMap::new(),
|
||||
workspace_mode: crate::shell::Mode::global(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -180,6 +182,7 @@ pub enum Action {
|
|||
Workspace(u8),
|
||||
MoveToWorkspace(u8),
|
||||
Focus(FocusAction),
|
||||
Orientation(crate::shell::layout::Orientation),
|
||||
Spawn(String),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -283,6 +283,15 @@ impl Common {
|
|||
Action::Focus(focus) => match focus {
|
||||
_ => { /* TODO */ }
|
||||
},
|
||||
Action::Orientation(orientation) => {
|
||||
let output = active_output(seat, &self);
|
||||
self.shell.set_orientation(
|
||||
&seat,
|
||||
&output,
|
||||
*orientation,
|
||||
);
|
||||
return FilterResult::Intercept(());
|
||||
}
|
||||
Action::Spawn(command) => {
|
||||
if let Err(err) =
|
||||
std::process::Command::new("/bin/sh")
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -135,9 +135,10 @@ impl State {
|
|||
handle: LoopHandle<'static, State>,
|
||||
log: LogState,
|
||||
) -> State {
|
||||
let config = Config::load();
|
||||
init_shm_global(&mut display, vec![], None);
|
||||
init_xdg_output_manager(&mut display, None);
|
||||
let shell = init_shell(&mut display);
|
||||
let shell = init_shell(&config, &mut display);
|
||||
let initial_seat = crate::input::add_seat(&mut display, "seat-0".into());
|
||||
init_data_device(
|
||||
&mut display,
|
||||
|
|
@ -170,8 +171,7 @@ impl State {
|
|||
|
||||
State {
|
||||
common: Common {
|
||||
config: Config::load(),
|
||||
|
||||
config,
|
||||
display: Rc::new(RefCell::new(display)),
|
||||
socket,
|
||||
event_loop_handle: handle,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue