mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Really rudimentary master stack tiling
This commit is contained in:
parent
b5d24956db
commit
4b32c2f454
6 changed files with 129 additions and 8 deletions
|
@ -25,7 +25,13 @@ use smithay::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::{ClientState, State};
|
||||
use crate::{
|
||||
layout::{
|
||||
automatic::{MasterStack, MasterStackSide},
|
||||
Layout,
|
||||
},
|
||||
ClientState, State,
|
||||
};
|
||||
|
||||
impl BufferHandler for State {
|
||||
fn buffer_destroyed(&mut self, _buffer: &WlBuffer) {}
|
||||
|
@ -115,14 +121,28 @@ impl XdgShellHandler for State {
|
|||
&mut self.xdg_shell_state
|
||||
}
|
||||
|
||||
// TODO: this shouldn't call send_configure
|
||||
fn new_toplevel(&mut self, surface: ToplevelSurface) {
|
||||
let window = Window::new(surface);
|
||||
self.space.map_element(window, (50, 50), true);
|
||||
self.space.map_element(window, (0, 0), true);
|
||||
|
||||
let windows: Vec<Window> = self.space.elements().cloned().collect();
|
||||
let layout = MasterStack {
|
||||
side: MasterStackSide::Left,
|
||||
};
|
||||
|
||||
layout.layout_windows(self, windows);
|
||||
|
||||
// TODO: refresh all window geometries
|
||||
}
|
||||
|
||||
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
|
||||
let windows: Vec<Window> = self.space.elements().cloned().collect();
|
||||
let layout = MasterStack {
|
||||
side: MasterStackSide::Left,
|
||||
};
|
||||
|
||||
layout.layout_windows(self, windows);
|
||||
// TODO: refresh geometries
|
||||
}
|
||||
|
||||
|
|
10
src/layout.rs
Normal file
10
src/layout.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use smithay::desktop::Window;
|
||||
|
||||
use crate::State;
|
||||
|
||||
pub mod automatic;
|
||||
pub mod manual;
|
||||
|
||||
pub trait Layout {
|
||||
fn layout_windows(&self, state: &mut State, windows: Vec<Window>);
|
||||
}
|
90
src/layout/automatic.rs
Normal file
90
src/layout/automatic.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
use smithay::desktop::Window;
|
||||
|
||||
use crate::State;
|
||||
|
||||
use super::Layout;
|
||||
|
||||
/// A layout which puts one "master" window on one half of the screen and splits other windows
|
||||
/// among the other half.
|
||||
pub struct MasterStack {
|
||||
/// Which side of the screen the master window will be on
|
||||
pub side: MasterStackSide,
|
||||
}
|
||||
|
||||
pub enum MasterStackSide {
|
||||
Left,
|
||||
Right,
|
||||
Top,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
impl Layout for MasterStack {
|
||||
fn layout_windows(&self, state: &mut State, windows: Vec<Window>) {
|
||||
match self.side {
|
||||
MasterStackSide::Left => {
|
||||
let window_count = windows.len();
|
||||
if window_count == 0 {
|
||||
return;
|
||||
}
|
||||
let output = state
|
||||
.space
|
||||
.output_under(state.pointer_location)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let output_size = state.space.output_geometry(&output).unwrap().size;
|
||||
if window_count == 1 {
|
||||
let window = windows[0].clone();
|
||||
|
||||
window.toplevel().with_pending_state(|tl_state| {
|
||||
tl_state.size = Some(state.space.output_geometry(&output).unwrap().size);
|
||||
});
|
||||
|
||||
window.toplevel().send_pending_configure();
|
||||
|
||||
state
|
||||
.space
|
||||
.map_element(window, output.current_location(), false);
|
||||
return;
|
||||
}
|
||||
let mut windows = windows.iter();
|
||||
let first_window = windows.next().unwrap();
|
||||
|
||||
first_window.toplevel().with_pending_state(|tl_state| {
|
||||
let mut size = state.space.output_geometry(&output).unwrap().size;
|
||||
size.w /= 2;
|
||||
tl_state.size = Some(size);
|
||||
});
|
||||
|
||||
first_window.toplevel().send_pending_configure();
|
||||
state
|
||||
.space
|
||||
.map_element(first_window.clone(), output.current_location(), false);
|
||||
|
||||
let window_count = windows.len() as i32;
|
||||
let height = output_size.h / window_count;
|
||||
let x = output.current_location().x + output_size.w / 2;
|
||||
|
||||
for (i, win) in windows.enumerate() {
|
||||
win.toplevel().with_pending_state(|state| {
|
||||
let mut new_size = output_size;
|
||||
new_size.w /= 2;
|
||||
new_size.h /= window_count;
|
||||
state.size = Some(new_size);
|
||||
});
|
||||
|
||||
win.toplevel().send_pending_configure();
|
||||
|
||||
let mut new_loc = output.current_location();
|
||||
new_loc.x = x;
|
||||
new_loc.y = i as i32 * height;
|
||||
|
||||
state.space.map_element(win.clone(), new_loc, false);
|
||||
}
|
||||
}
|
||||
MasterStackSide::Right => todo!(),
|
||||
MasterStackSide::Top => todo!(),
|
||||
MasterStackSide::Bottom => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
0
src/layout/manual.rs
Normal file
0
src/layout/manual.rs
Normal file
|
@ -1,5 +1,6 @@
|
|||
mod grab;
|
||||
mod handlers;
|
||||
mod layout;
|
||||
mod pointer;
|
||||
mod window;
|
||||
mod xdg;
|
||||
|
|
|
@ -12,12 +12,6 @@ pub enum Float {
|
|||
Floating,
|
||||
}
|
||||
|
||||
impl Default for WindowState {
|
||||
fn default() -> Self {
|
||||
Self::new() // TODO: maybe actual defaults
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowState {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -27,4 +21,10 @@ impl WindowState {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for WindowState {
|
||||
fn default() -> Self {
|
||||
Self::new() // TODO: maybe actual defaults
|
||||
}
|
||||
}
|
||||
|
||||
impl SurfaceState for WindowState {}
|
||||
|
|
Loading…
Reference in a new issue