shell: Properly center and resize new floating windows

This commit is contained in:
Victoria Brekenfeld 2022-07-06 23:41:11 +02:00
parent f65a59aae2
commit 397ddaab1e
2 changed files with 65 additions and 12 deletions

View file

@ -7,12 +7,14 @@ use smithay::{
}, },
utils::IsAlive, utils::IsAlive,
wayland::{ wayland::{
compositor::with_states,
output::Output, output::Output,
seat::{PointerGrabStartData, Seat}, seat::{PointerGrabStartData, Seat},
shell::xdg::XdgToplevelSurfaceRoleAttributes,
Serial, Serial,
}, },
}; };
use std::collections::HashSet; use std::{collections::HashSet, sync::Mutex};
use crate::state::State; use crate::state::State;
@ -49,14 +51,58 @@ impl FloatingLayout {
} }
fn map_window_internal(&mut self, space: &mut Space, window: Window, output: &Output) { fn map_window_internal(&mut self, space: &mut Space, window: Window, output: &Output) {
let win_geo = window.bbox(); let mut win_geo = window.geometry();
let layers = layer_map_for_output(&output); let layers = layer_map_for_output(&output);
let geometry = layers.non_exclusive_zone(); let geometry = layers.non_exclusive_zone();
let mut geo_updated = false;
{
let (min_size, max_size) = with_states(window.toplevel().wl_surface(), |states| {
let attrs = states
.data_map
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
.unwrap()
.lock()
.unwrap();
(attrs.min_size, attrs.max_size)
});
if win_geo.size.w > geometry.size.w / 3 * 2 {
// try a more reasonable size
let mut width = geometry.size.w / 3 * 2;
if max_size.w != 0 {
// don't go larger then the max_size ...
width = std::cmp::min(max_size.w, width);
}
if min_size.w != 0 {
// ... but also don't go smaller than the min_size
width = std::cmp::max(min_size.w, width);
}
// but no matter the supported sizes, don't be larger than our non-exclusive-zone
win_geo.size.w = std::cmp::min(width, geometry.size.w);
geo_updated = true;
}
if win_geo.size.h > geometry.size.h / 3 * 2 {
// try a more reasonable size
let mut height = geometry.size.h / 3 * 2;
if max_size.h != 0 {
// don't go larger then the max_size ...
height = std::cmp::min(max_size.h, height);
}
if min_size.h != 0 {
// ... but also don't go smaller than the min_size
height = std::cmp::max(min_size.h, height);
}
// but no matter the supported sizes, don't be larger than our non-exclusive-zone
win_geo.size.h = std::cmp::min(height, geometry.size.h);
geo_updated = true;
}
}
let position = ( let position = (
-geometry.loc.x + (geometry.size.w / 2) - (win_geo.size.w / 2), geometry.loc.x + (geometry.size.w / 2) - (win_geo.size.w / 2) + win_geo.loc.x,
-geometry.loc.y + (geometry.size.h / 2) - (win_geo.size.h / 2), geometry.loc.y + (geometry.size.h / 2) - (win_geo.size.h / 2) + win_geo.loc.y,
); );
#[allow(irrefutable_let_patterns)] #[allow(irrefutable_let_patterns)]
if let Kind::Xdg(xdg) = &window.toplevel() { if let Kind::Xdg(xdg) = &window.toplevel() {
xdg.with_pending_state(|state| { xdg.with_pending_state(|state| {
@ -64,6 +110,9 @@ impl FloatingLayout {
state.states.unset(XdgState::TiledRight); state.states.unset(XdgState::TiledRight);
state.states.unset(XdgState::TiledTop); state.states.unset(XdgState::TiledTop);
state.states.unset(XdgState::TiledBottom); state.states.unset(XdgState::TiledBottom);
if geo_updated {
state.size = Some(win_geo.size);
}
}); });
xdg.send_configure(); xdg.send_configure();
} }

View file

@ -107,6 +107,13 @@ impl CompositorHandler for State {
} }
fn commit(&mut self, dh: &DisplayHandle, surface: &WlSurface) { fn commit(&mut self, dh: &DisplayHandle, surface: &WlSurface) {
on_commit_buffer_handler(surface);
self.early_import_surface(dh, surface);
self.common.shell.popups.commit(surface);
for workspace in &self.common.shell.spaces {
workspace.space.commit(surface);
}
// initial configure // initial configure
if let Some((window, seat)) = self if let Some((window, seat)) = self
.common .common
@ -118,7 +125,11 @@ impl CompositorHandler for State {
{ {
match window.toplevel() { match window.toplevel() {
Kind::Xdg(toplevel) => { Kind::Xdg(toplevel) => {
if self.toplevel_ensure_initial_configure(&toplevel) { if self.toplevel_ensure_initial_configure(&toplevel)
&& with_renderer_surface_state(&surface, |state| {
state.wl_buffer().is_some()
})
{
let output = active_output(&seat, &self.common); let output = active_output(&seat, &self.common);
self.common.shell.map_window(&window, &output, dh); self.common.shell.map_window(&window, &output, dh);
} else { } else {
@ -181,13 +192,6 @@ impl CompositorHandler for State {
}) { }) {
layer_map_for_output(output).arrange(dh); layer_map_for_output(output).arrange(dh);
} }
on_commit_buffer_handler(surface);
self.early_import_surface(dh, surface);
self.common.shell.popups.commit(surface);
for workspace in &self.common.shell.spaces {
workspace.space.commit(surface);
}
} }
} }