mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Respect exclusive zones
This commit is contained in:
parent
f3b0c081dc
commit
766567cf48
5 changed files with 140 additions and 133 deletions
|
@ -442,7 +442,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
||||||
first_tag.layout().layout(
|
first_tag.layout().layout(
|
||||||
self.windows.clone(),
|
self.windows.clone(),
|
||||||
state.focused_tags().cloned().collect(),
|
state.focused_tags().cloned().collect(),
|
||||||
self,
|
&mut self.space,
|
||||||
&focused_output,
|
&focused_output,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
||||||
first_tag.layout().layout(
|
first_tag.layout().layout(
|
||||||
self.windows.clone(),
|
self.windows.clone(),
|
||||||
state.focused_tags().cloned().collect(),
|
state.focused_tags().cloned().collect(),
|
||||||
self,
|
&mut self.space,
|
||||||
&focused_output,
|
&focused_output,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -724,6 +724,7 @@ impl<B: Backend> WlrLayerShellHandler for State<B> {
|
||||||
_layer: Layer,
|
_layer: Layer,
|
||||||
namespace: String,
|
namespace: String,
|
||||||
) {
|
) {
|
||||||
|
tracing::debug!("-------------NEW LAYER SURFACE");
|
||||||
let output = output
|
let output = output
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(Output::from_resource)
|
.and_then(Output::from_resource)
|
||||||
|
@ -737,18 +738,36 @@ impl<B: Backend> WlrLayerShellHandler for State<B> {
|
||||||
let mut map = layer_map_for_output(&output);
|
let mut map = layer_map_for_output(&output);
|
||||||
map.map_layer(&desktop::LayerSurface::new(surface, namespace))
|
map.map_layer(&desktop::LayerSurface::new(surface, namespace))
|
||||||
.expect("failed to map layer surface");
|
.expect("failed to map layer surface");
|
||||||
|
drop(map); // wow i really love refcells haha
|
||||||
|
|
||||||
|
// TODO: instead of deferring by 1 cycle, actually check if the surface has committed
|
||||||
|
// | before re-layouting
|
||||||
|
self.loop_handle.insert_idle(move |data| {
|
||||||
|
data.state.re_layout(&output);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layer_destroyed(&mut self, surface: wlr_layer::LayerSurface) {
|
fn layer_destroyed(&mut self, surface: wlr_layer::LayerSurface) {
|
||||||
if let Some((mut map, layer)) = self.space.outputs().find_map(|o| {
|
// WOO love having to deal with the borrow checker haha
|
||||||
|
let mut output: Option<Output> = None;
|
||||||
|
if let Some((mut map, layer, op)) = self.space.outputs().find_map(|o| {
|
||||||
let map = layer_map_for_output(o);
|
let map = layer_map_for_output(o);
|
||||||
let layer = map
|
let layer = map
|
||||||
.layers()
|
.layers()
|
||||||
.find(|&layer| layer.layer_surface() == &surface)
|
.find(|&layer| layer.layer_surface() == &surface)
|
||||||
.cloned();
|
.cloned();
|
||||||
layer.map(|layer| (map, layer))
|
layer.map(|layer| (map, layer, o))
|
||||||
}) {
|
}) {
|
||||||
map.unmap_layer(&layer);
|
map.unmap_layer(&layer);
|
||||||
|
output = Some(op.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: instead of deferring by 1 cycle, actually check if the surface has committed
|
||||||
|
// | before re-layouting
|
||||||
|
if let Some(output) = output {
|
||||||
|
self.loop_handle.insert_idle(move |data| {
|
||||||
|
data.state.re_layout(&output);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
first_tag.layout().layout(
|
first_tag.layout().layout(
|
||||||
self.state.windows.clone(),
|
self.state.windows.clone(),
|
||||||
state.focused_tags().cloned().collect(),
|
state.focused_tags().cloned().collect(),
|
||||||
&mut self.state,
|
&mut self.state.space,
|
||||||
&focused_output,
|
&focused_output,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
230
src/layout.rs
230
src/layout.rs
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
use itertools::{Either, Itertools};
|
use itertools::{Either, Itertools};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
desktop::{layer_map_for_output, Space},
|
||||||
output::Output,
|
output::Output,
|
||||||
utils::{Logical, Size},
|
utils::{Logical, Rectangle, Size},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -25,36 +26,55 @@ pub enum Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
pub fn layout<B: Backend>(
|
pub fn layout(
|
||||||
&self,
|
&self,
|
||||||
windows: Vec<WindowElement>,
|
windows: Vec<WindowElement>,
|
||||||
tags: Vec<Tag>,
|
tags: Vec<Tag>,
|
||||||
state: &mut State<B>,
|
space: &mut Space<WindowElement>,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
) {
|
) {
|
||||||
let windows = filter_windows(&windows, tags);
|
let windows = filter_windows(&windows, tags);
|
||||||
|
|
||||||
|
let Some(rect) = space.output_geometry(output).map(|op_geo| {
|
||||||
|
let map = layer_map_for_output(output);
|
||||||
|
if map.layers().peekable().peek().is_none() {
|
||||||
|
// INFO: Sometimes the exclusive zone is some weird number that doesn't match the
|
||||||
|
// | output res, even when there are no layer surfaces mapped. In this case, we
|
||||||
|
// | just return the output geometry.
|
||||||
|
op_geo
|
||||||
|
} else {
|
||||||
|
let zone = map.non_exclusive_zone();
|
||||||
|
tracing::debug!("non_exclusive_zone is {zone:?}");
|
||||||
|
Rectangle::from_loc_and_size(op_geo.loc + zone.loc, zone.size)
|
||||||
|
}
|
||||||
|
}) else {
|
||||||
|
// TODO: maybe default to something like 800x800 like in anvil so people still see
|
||||||
|
// | windows open
|
||||||
|
tracing::error!("Failed to get output geometry");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
tracing::debug!("Laying out with rect {rect:?}");
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Layout::MasterStack => master_stack(windows, state, output),
|
Layout::MasterStack => master_stack(windows, space, rect),
|
||||||
Layout::Dwindle => dwindle(windows, state, output),
|
Layout::Dwindle => dwindle(windows, space, rect),
|
||||||
Layout::Spiral => spiral(windows, state, output),
|
Layout::Spiral => spiral(windows, space, rect),
|
||||||
layout @ (Layout::CornerTopLeft
|
layout @ (Layout::CornerTopLeft
|
||||||
| Layout::CornerTopRight
|
| Layout::CornerTopRight
|
||||||
| Layout::CornerBottomLeft
|
| Layout::CornerBottomLeft
|
||||||
| Layout::CornerBottomRight) => corner(layout, windows, state, output),
|
| Layout::CornerBottomRight) => corner(layout, windows, space, rect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn master_stack<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output: &Output) {
|
fn master_stack(
|
||||||
let space = &mut state.space;
|
windows: Vec<WindowElement>,
|
||||||
|
space: &mut Space<WindowElement>,
|
||||||
let Some(output_geo) = space.output_geometry(output) else {
|
rect: Rectangle<i32, Logical>,
|
||||||
tracing::error!("could not get output geometry");
|
) {
|
||||||
return;
|
let size = rect.size;
|
||||||
};
|
let loc = rect.loc;
|
||||||
|
|
||||||
let output_loc = output.current_location();
|
|
||||||
|
|
||||||
let master = windows.first();
|
let master = windows.first();
|
||||||
let stack = windows.iter().skip(1);
|
let stack = windows.iter().skip(1);
|
||||||
|
@ -65,15 +85,15 @@ fn master_stack<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, o
|
||||||
|
|
||||||
if stack_count == 0 {
|
if stack_count == 0 {
|
||||||
// one window
|
// one window
|
||||||
master.request_size_change(state, output_loc, output_geo.size);
|
master.request_size_change(space, loc, size);
|
||||||
} else {
|
} else {
|
||||||
let loc = (output_loc.x, output_loc.y).into();
|
let loc = (loc.x, loc.y).into();
|
||||||
let new_master_size: Size<i32, Logical> = (output_geo.size.w / 2, output_geo.size.h).into();
|
let new_master_size: Size<i32, Logical> = (size.w / 2, size.h).into();
|
||||||
master.request_size_change(state, loc, new_master_size);
|
master.request_size_change(space, loc, new_master_size);
|
||||||
|
|
||||||
let stack_count = stack_count;
|
let stack_count = stack_count;
|
||||||
|
|
||||||
let height = output_geo.size.h as f32 / stack_count as f32;
|
let height = size.h as f32 / stack_count as f32;
|
||||||
let mut y_s = vec![];
|
let mut y_s = vec![];
|
||||||
for i in 0..stack_count {
|
for i in 0..stack_count {
|
||||||
y_s.push((i as f32 * height).round() as i32);
|
y_s.push((i as f32 * height).round() as i32);
|
||||||
|
@ -81,38 +101,36 @@ fn master_stack<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, o
|
||||||
let heights = y_s
|
let heights = y_s
|
||||||
.windows(2)
|
.windows(2)
|
||||||
.map(|pair| pair[1] - pair[0])
|
.map(|pair| pair[1] - pair[0])
|
||||||
.chain(vec![output_geo.size.h - y_s.last().expect("vec was empty")])
|
.chain(vec![size.h - y_s.last().expect("vec was empty")])
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for (i, win) in stack.enumerate() {
|
for (i, win) in stack.enumerate() {
|
||||||
win.request_size_change(
|
win.request_size_change(
|
||||||
state,
|
space,
|
||||||
(output_geo.size.w / 2 + output_loc.x, y_s[i] + output_loc.y).into(),
|
(size.w / 2 + loc.x, y_s[i] + loc.y).into(),
|
||||||
(output_geo.size.w / 2, i32::max(heights[i], 40)).into(),
|
(size.w / 2, i32::max(heights[i], 40)).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dwindle<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output: &Output) {
|
fn dwindle(
|
||||||
let space = &state.space;
|
windows: Vec<WindowElement>,
|
||||||
|
space: &mut Space<WindowElement>,
|
||||||
let Some(output_geo) = space.output_geometry(output) else {
|
rect: Rectangle<i32, Logical>,
|
||||||
tracing::error!("could not get output geometry");
|
) {
|
||||||
return;
|
let size = rect.size;
|
||||||
};
|
let loc = rect.loc;
|
||||||
|
|
||||||
let output_loc = output.current_location();
|
|
||||||
|
|
||||||
let mut iter = windows.windows(2).peekable();
|
let mut iter = windows.windows(2).peekable();
|
||||||
|
|
||||||
if iter.peek().is_none() {
|
if iter.peek().is_none() {
|
||||||
if let Some(window) = windows.first() {
|
if let Some(window) = windows.first() {
|
||||||
window.request_size_change(state, output_loc, output_geo.size);
|
window.request_size_change(space, loc, size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut win1_size = output_geo.size;
|
let mut win1_size = size;
|
||||||
let mut win1_loc = output_loc;
|
let mut win1_loc = loc;
|
||||||
for (i, wins) in iter.enumerate() {
|
for (i, wins) in iter.enumerate() {
|
||||||
let win1 = &wins[0];
|
let win1 = &wins[0];
|
||||||
let win2 = &wins[1];
|
let win2 = &wins[1];
|
||||||
|
@ -129,7 +147,7 @@ fn dwindle<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output
|
||||||
let width_partition = win1_size.w / 2;
|
let width_partition = win1_size.w / 2;
|
||||||
|
|
||||||
win1.request_size_change(
|
win1.request_size_change(
|
||||||
state,
|
space,
|
||||||
win1_loc,
|
win1_loc,
|
||||||
(win1_size.w - width_partition, i32::max(win1_size.h, 40)).into(),
|
(win1_size.w - width_partition, i32::max(win1_size.h, 40)).into(),
|
||||||
);
|
);
|
||||||
|
@ -137,13 +155,13 @@ fn dwindle<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output
|
||||||
win1_loc = (win1_loc.x + (win1_size.w - width_partition), win1_loc.y).into();
|
win1_loc = (win1_loc.x + (win1_size.w - width_partition), win1_loc.y).into();
|
||||||
win1_size = (width_partition, i32::max(win1_size.h, 40)).into();
|
win1_size = (width_partition, i32::max(win1_size.h, 40)).into();
|
||||||
|
|
||||||
win2.request_size_change(state, win1_loc, win1_size);
|
win2.request_size_change(space, win1_loc, win1_size);
|
||||||
}
|
}
|
||||||
Slice::Below => {
|
Slice::Below => {
|
||||||
let height_partition = win1_size.h / 2;
|
let height_partition = win1_size.h / 2;
|
||||||
|
|
||||||
win1.request_size_change(
|
win1.request_size_change(
|
||||||
state,
|
space,
|
||||||
win1_loc,
|
win1_loc,
|
||||||
(win1_size.w, i32::max(win1_size.h - height_partition, 40)).into(),
|
(win1_size.w, i32::max(win1_size.h - height_partition, 40)).into(),
|
||||||
);
|
);
|
||||||
|
@ -151,31 +169,30 @@ fn dwindle<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output
|
||||||
win1_loc = (win1_loc.x, win1_loc.y + (win1_size.h - height_partition)).into();
|
win1_loc = (win1_loc.x, win1_loc.y + (win1_size.h - height_partition)).into();
|
||||||
win1_size = (win1_size.w, i32::max(height_partition, 40)).into();
|
win1_size = (win1_size.w, i32::max(height_partition, 40)).into();
|
||||||
|
|
||||||
win2.request_size_change(state, win1_loc, win1_size);
|
win2.request_size_change(space, win1_loc, win1_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spiral<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output: &Output) {
|
fn spiral(
|
||||||
let space = &state.space;
|
windows: Vec<WindowElement>,
|
||||||
let Some(output_geo) = space.output_geometry(output) else {
|
space: &mut Space<WindowElement>,
|
||||||
tracing::error!("could not get output geometry");
|
rect: Rectangle<i32, Logical>,
|
||||||
return;
|
) {
|
||||||
};
|
let size = rect.size;
|
||||||
|
let loc = rect.loc;
|
||||||
let output_loc = output.current_location();
|
|
||||||
|
|
||||||
let mut iter = windows.windows(2).peekable();
|
let mut iter = windows.windows(2).peekable();
|
||||||
|
|
||||||
if iter.peek().is_none() {
|
if iter.peek().is_none() {
|
||||||
if let Some(window) = windows.first() {
|
if let Some(window) = windows.first() {
|
||||||
window.request_size_change(state, output_loc, output_geo.size);
|
window.request_size_change(space, loc, size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut win1_loc = output_loc;
|
let mut win1_loc = loc;
|
||||||
let mut win1_size = output_geo.size;
|
let mut win1_size = size;
|
||||||
|
|
||||||
for (i, wins) in iter.enumerate() {
|
for (i, wins) in iter.enumerate() {
|
||||||
let win1 = &wins[0];
|
let win1 = &wins[0];
|
||||||
|
@ -201,86 +218,78 @@ fn spiral<B: Backend>(windows: Vec<WindowElement>, state: &mut State<B>, output:
|
||||||
let height_partition = win1_size.h / 2;
|
let height_partition = win1_size.h / 2;
|
||||||
|
|
||||||
win1.request_size_change(
|
win1.request_size_change(
|
||||||
state,
|
space,
|
||||||
(win1_loc.x, win1_loc.y + height_partition).into(),
|
(win1_loc.x, win1_loc.y + height_partition).into(),
|
||||||
(win1_size.w, i32::max(win1_size.h - height_partition, 40)).into(),
|
(win1_size.w, i32::max(win1_size.h - height_partition, 40)).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
win1_size = (win1_size.w, i32::max(height_partition, 40)).into();
|
win1_size = (win1_size.w, i32::max(height_partition, 40)).into();
|
||||||
win2.request_size_change(state, win1_loc, win1_size);
|
win2.request_size_change(space, win1_loc, win1_size);
|
||||||
}
|
}
|
||||||
Slice::Below => {
|
Slice::Below => {
|
||||||
let height_partition = win1_size.h / 2;
|
let height_partition = win1_size.h / 2;
|
||||||
|
|
||||||
win1.request_size_change(
|
win1.request_size_change(
|
||||||
state,
|
space,
|
||||||
win1_loc,
|
win1_loc,
|
||||||
(win1_size.w, win1_size.h - i32::max(height_partition, 40)).into(),
|
(win1_size.w, win1_size.h - i32::max(height_partition, 40)).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
win1_loc = (win1_loc.x, win1_loc.y + (win1_size.h - height_partition)).into();
|
win1_loc = (win1_loc.x, win1_loc.y + (win1_size.h - height_partition)).into();
|
||||||
win1_size = (win1_size.w, i32::max(height_partition, 40)).into();
|
win1_size = (win1_size.w, i32::max(height_partition, 40)).into();
|
||||||
win2.request_size_change(state, win1_loc, win1_size);
|
win2.request_size_change(space, win1_loc, win1_size);
|
||||||
}
|
}
|
||||||
Slice::Left => {
|
Slice::Left => {
|
||||||
let width_partition = win1_size.w / 2;
|
let width_partition = win1_size.w / 2;
|
||||||
|
|
||||||
win1.request_size_change(
|
win1.request_size_change(
|
||||||
state,
|
space,
|
||||||
(win1_loc.x + width_partition, win1_loc.y).into(),
|
(win1_loc.x + width_partition, win1_loc.y).into(),
|
||||||
(win1_size.w - width_partition, i32::max(win1_size.h, 40)).into(),
|
(win1_size.w - width_partition, i32::max(win1_size.h, 40)).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
win1_size = (width_partition, i32::max(win1_size.h, 40)).into();
|
win1_size = (width_partition, i32::max(win1_size.h, 40)).into();
|
||||||
win2.request_size_change(state, win1_loc, win1_size);
|
win2.request_size_change(space, win1_loc, win1_size);
|
||||||
}
|
}
|
||||||
Slice::Right => {
|
Slice::Right => {
|
||||||
let width_partition = win1_size.w / 2;
|
let width_partition = win1_size.w / 2;
|
||||||
|
|
||||||
win1.request_size_change(
|
win1.request_size_change(
|
||||||
state,
|
space,
|
||||||
win1_loc,
|
win1_loc,
|
||||||
(win1_size.w - width_partition, i32::max(win1_size.h, 40)).into(),
|
(win1_size.w - width_partition, i32::max(win1_size.h, 40)).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
win1_loc = (win1_loc.x + (win1_size.w - width_partition), win1_loc.y).into();
|
win1_loc = (win1_loc.x + (win1_size.w - width_partition), win1_loc.y).into();
|
||||||
win1_size = (width_partition, i32::max(win1_size.h, 40)).into();
|
win1_size = (width_partition, i32::max(win1_size.h, 40)).into();
|
||||||
win2.request_size_change(state, win1_loc, win1_size);
|
win2.request_size_change(space, win1_loc, win1_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn corner<B: Backend>(
|
fn corner(
|
||||||
layout: &Layout,
|
layout: &Layout,
|
||||||
windows: Vec<WindowElement>,
|
windows: Vec<WindowElement>,
|
||||||
state: &mut State<B>,
|
space: &mut Space<WindowElement>,
|
||||||
output: &Output,
|
rect: Rectangle<i32, Logical>,
|
||||||
) {
|
) {
|
||||||
let space = &state.space;
|
let size = rect.size;
|
||||||
let Some(output_geo) = space.output_geometry(output) else {
|
let loc = rect.loc;
|
||||||
tracing::error!("could not get output geometry");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let output_loc = output.current_location();
|
|
||||||
match windows.len() {
|
match windows.len() {
|
||||||
0 => (),
|
0 => (),
|
||||||
1 => {
|
1 => {
|
||||||
windows[0].request_size_change(state, output_loc, output_geo.size);
|
windows[0].request_size_change(space, loc, size);
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
windows[0].request_size_change(
|
windows[0].request_size_change(space, loc, (size.w / 2, size.h).into());
|
||||||
state,
|
|
||||||
output_loc,
|
|
||||||
(output_geo.size.w / 2, output_geo.size.h).into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
windows[1].request_size_change(
|
windows[1].request_size_change(
|
||||||
state,
|
space,
|
||||||
(output_loc.x + output_geo.size.w / 2, output_loc.y).into(),
|
(loc.x + size.w / 2, loc.y).into(),
|
||||||
(output_geo.size.w / 2, output_geo.size.h).into(),
|
(size.w / 2, size.h).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -298,34 +307,24 @@ fn corner<B: Backend>(
|
||||||
let div_factor = 2;
|
let div_factor = 2;
|
||||||
|
|
||||||
corner.request_size_change(
|
corner.request_size_change(
|
||||||
state,
|
space,
|
||||||
match layout {
|
match layout {
|
||||||
Layout::CornerTopLeft => (output_loc.x, output_loc.y),
|
Layout::CornerTopLeft => (loc.x, loc.y),
|
||||||
Layout::CornerTopRight => (
|
Layout::CornerTopRight => (loc.x + size.w - size.w / div_factor, loc.y),
|
||||||
output_loc.x + output_geo.size.w - output_geo.size.w / div_factor,
|
Layout::CornerBottomLeft => (loc.x, loc.y + size.h - size.h / div_factor),
|
||||||
output_loc.y,
|
|
||||||
),
|
|
||||||
Layout::CornerBottomLeft => (
|
|
||||||
output_loc.x,
|
|
||||||
output_loc.y + output_geo.size.h - output_geo.size.h / div_factor,
|
|
||||||
),
|
|
||||||
Layout::CornerBottomRight => (
|
Layout::CornerBottomRight => (
|
||||||
output_loc.x + output_geo.size.w - output_geo.size.w / div_factor,
|
loc.x + size.w - size.w / div_factor,
|
||||||
output_loc.y + output_geo.size.h - output_geo.size.h / div_factor,
|
loc.y + size.h - size.h / div_factor,
|
||||||
),
|
),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
(
|
(size.w / div_factor, size.h / div_factor).into(),
|
||||||
output_geo.size.w / div_factor,
|
|
||||||
output_geo.size.h / div_factor,
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let vert_stack_count = vert_stack.len();
|
let vert_stack_count = vert_stack.len();
|
||||||
|
|
||||||
let height = output_geo.size.h as f32 / vert_stack_count as f32;
|
let height = size.h as f32 / vert_stack_count as f32;
|
||||||
let mut y_s = vec![];
|
let mut y_s = vec![];
|
||||||
for i in 0..vert_stack_count {
|
for i in 0..vert_stack_count {
|
||||||
y_s.push((i as f32 * height).round() as i32);
|
y_s.push((i as f32 * height).round() as i32);
|
||||||
|
@ -333,30 +332,28 @@ fn corner<B: Backend>(
|
||||||
let heights = y_s
|
let heights = y_s
|
||||||
.windows(2)
|
.windows(2)
|
||||||
.map(|pair| pair[1] - pair[0])
|
.map(|pair| pair[1] - pair[0])
|
||||||
.chain(vec![output_geo.size.h - y_s.last().expect("vec was empty")])
|
.chain(vec![size.h - y_s.last().expect("vec was empty")])
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for (i, win) in vert_stack.iter().enumerate() {
|
for (i, win) in vert_stack.iter().enumerate() {
|
||||||
win.request_size_change(
|
win.request_size_change(
|
||||||
state,
|
space,
|
||||||
(
|
(
|
||||||
match layout {
|
match layout {
|
||||||
Layout::CornerTopLeft | Layout::CornerBottomLeft => {
|
Layout::CornerTopLeft | Layout::CornerBottomLeft => size.w / 2 + loc.x,
|
||||||
output_geo.size.w / 2 + output_loc.x
|
Layout::CornerTopRight | Layout::CornerBottomRight => loc.x,
|
||||||
}
|
|
||||||
Layout::CornerTopRight | Layout::CornerBottomRight => output_loc.x,
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
y_s[i] + output_loc.y,
|
y_s[i] + loc.y,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
(output_geo.size.w / 2, i32::max(heights[i], 40)).into(),
|
(size.w / 2, i32::max(heights[i], 40)).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let horiz_stack_count = horiz_stack.len();
|
let horiz_stack_count = horiz_stack.len();
|
||||||
|
|
||||||
let width = output_geo.size.w as f32 / 2.0 / horiz_stack_count as f32;
|
let width = size.w as f32 / 2.0 / horiz_stack_count as f32;
|
||||||
let mut x_s = vec![];
|
let mut x_s = vec![];
|
||||||
for i in 0..horiz_stack_count {
|
for i in 0..horiz_stack_count {
|
||||||
x_s.push((i as f32 * width).round() as i32);
|
x_s.push((i as f32 * width).round() as i32);
|
||||||
|
@ -364,30 +361,21 @@ fn corner<B: Backend>(
|
||||||
let widths = x_s
|
let widths = x_s
|
||||||
.windows(2)
|
.windows(2)
|
||||||
.map(|pair| pair[1] - pair[0])
|
.map(|pair| pair[1] - pair[0])
|
||||||
.chain(vec![
|
.chain(vec![size.w / 2 - x_s.last().expect("vec was empty")])
|
||||||
output_geo.size.w / 2 - x_s.last().expect("vec was empty"),
|
|
||||||
])
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for (i, win) in horiz_stack.iter().enumerate() {
|
for (i, win) in horiz_stack.iter().enumerate() {
|
||||||
win.request_size_change(
|
win.request_size_change(
|
||||||
state,
|
space,
|
||||||
match layout {
|
match layout {
|
||||||
Layout::CornerTopLeft => {
|
Layout::CornerTopLeft => (x_s[i] + loc.x, loc.y + size.h / 2),
|
||||||
(x_s[i] + output_loc.x, output_loc.y + output_geo.size.h / 2)
|
Layout::CornerTopRight => (x_s[i] + loc.x + size.w / 2, loc.y + size.h / 2),
|
||||||
}
|
Layout::CornerBottomLeft => (x_s[i] + loc.x, loc.y),
|
||||||
Layout::CornerTopRight => (
|
Layout::CornerBottomRight => (x_s[i] + loc.x + size.w / 2, loc.y),
|
||||||
x_s[i] + output_loc.x + output_geo.size.w / 2,
|
|
||||||
output_loc.y + output_geo.size.h / 2,
|
|
||||||
),
|
|
||||||
Layout::CornerBottomLeft => (x_s[i] + output_loc.x, output_loc.y),
|
|
||||||
Layout::CornerBottomRight => {
|
|
||||||
(x_s[i] + output_loc.x + output_geo.size.w / 2, output_loc.y)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
(i32::max(widths[i], 1), output_geo.size.h / 2).into(),
|
(i32::max(widths[i], 1), size.h / 2).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ impl<B: Backend> State<B> {
|
||||||
if let Some(height) = height {
|
if let Some(height) = height {
|
||||||
window_size.h = height;
|
window_size.h = height;
|
||||||
}
|
}
|
||||||
window.request_size_change(self, window_loc, window_size);
|
window.request_size_change(&mut self.space, window_loc, window_size);
|
||||||
}
|
}
|
||||||
Msg::MoveWindowToTag { window_id, tag_id } => {
|
Msg::MoveWindowToTag { window_id, tag_id } => {
|
||||||
let Some(window) = window_id.window(self) else { return };
|
let Some(window) = window_id.window(self) else { return };
|
||||||
|
@ -672,7 +672,7 @@ impl<B: Backend> State<B> {
|
||||||
first_tag.layout().layout(
|
first_tag.layout().layout(
|
||||||
self.windows.clone(),
|
self.windows.clone(),
|
||||||
state.focused_tags().cloned().collect(),
|
state.focused_tags().cloned().collect(),
|
||||||
self,
|
&mut self.space,
|
||||||
output,
|
output,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use smithay::{
|
||||||
take_presentation_feedback_surface_tree, under_from_surface_tree,
|
take_presentation_feedback_surface_tree, under_from_surface_tree,
|
||||||
with_surfaces_surface_tree, OutputPresentationFeedback,
|
with_surfaces_surface_tree, OutputPresentationFeedback,
|
||||||
},
|
},
|
||||||
Window, WindowSurfaceType,
|
Space, Window, WindowSurfaceType,
|
||||||
},
|
},
|
||||||
input::{
|
input::{
|
||||||
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
|
||||||
|
@ -181,9 +181,9 @@ impl WindowElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request a size and loc change.
|
/// Request a size and loc change.
|
||||||
pub fn request_size_change<B: Backend>(
|
pub fn request_size_change(
|
||||||
&self,
|
&self,
|
||||||
state: &mut State<B>,
|
space: &mut Space<WindowElement>,
|
||||||
new_loc: Point<i32, Logical>,
|
new_loc: Point<i32, Logical>,
|
||||||
new_size: Size<i32, Logical>,
|
new_size: Size<i32, Logical>,
|
||||||
) {
|
) {
|
||||||
|
@ -210,7 +210,7 @@ impl WindowElement {
|
||||||
.set_mapped(true)
|
.set_mapped(true)
|
||||||
.expect("failed to set x11 win to mapped");
|
.expect("failed to set x11 win to mapped");
|
||||||
}
|
}
|
||||||
state.space.map_element(self.clone(), new_loc, false);
|
space.map_element(self.clone(), new_loc, false);
|
||||||
// if let Some(focused_output) = state.focus_state.focused_output.clone() {
|
// if let Some(focused_output) = state.focus_state.focused_output.clone() {
|
||||||
// self.send_frame(
|
// self.send_frame(
|
||||||
// &focused_output,
|
// &focused_output,
|
||||||
|
@ -527,7 +527,7 @@ pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &WindowElement)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((prev_loc, prev_size)) = resize {
|
if let Some((prev_loc, prev_size)) = resize {
|
||||||
window.request_size_change(state, prev_loc, prev_size);
|
window.request_size_change(&mut state.space, prev_loc, prev_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't use the focused output, use the one the window is on
|
// TODO: don't use the focused output, use the one the window is on
|
||||||
|
|
Loading…
Reference in a new issue