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,
wayland::{
compositor::with_states,
output::Output,
seat::{PointerGrabStartData, Seat},
shell::xdg::XdgToplevelSurfaceRoleAttributes,
Serial,
},
};
use std::collections::HashSet;
use std::{collections::HashSet, sync::Mutex};
use crate::state::State;
@ -49,14 +51,58 @@ impl FloatingLayout {
}
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 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 = (
-geometry.loc.x + (geometry.size.w / 2) - (win_geo.size.w / 2),
-geometry.loc.y + (geometry.size.h / 2) - (win_geo.size.h / 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) + win_geo.loc.y,
);
#[allow(irrefutable_let_patterns)]
if let Kind::Xdg(xdg) = &window.toplevel() {
xdg.with_pending_state(|state| {
@ -64,6 +110,9 @@ impl FloatingLayout {
state.states.unset(XdgState::TiledRight);
state.states.unset(XdgState::TiledTop);
state.states.unset(XdgState::TiledBottom);
if geo_updated {
state.size = Some(win_geo.size);
}
});
xdg.send_configure();
}

View file

@ -107,6 +107,13 @@ impl CompositorHandler for State {
}
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
if let Some((window, seat)) = self
.common
@ -118,7 +125,11 @@ impl CompositorHandler for State {
{
match window.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);
self.common.shell.map_window(&window, &output, dh);
} else {
@ -181,13 +192,6 @@ impl CompositorHandler for State {
}) {
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);
}
}
}