shell: Properly center and resize new floating windows
This commit is contained in:
parent
f65a59aae2
commit
397ddaab1e
2 changed files with 65 additions and 12 deletions
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue