Respect exclusive zones

This commit is contained in:
Ottatop 2023-08-07 11:25:36 -05:00 committed by Ottatop
parent f3b0c081dc
commit 766567cf48
5 changed files with 140 additions and 133 deletions

View file

@ -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);
});
} }
} }
} }

View file

@ -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,
); );
} }

View file

@ -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(),
); );
} }
} }

View file

@ -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,
); );
} }

View file

@ -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