refactor(shell/element): refactor how decorations height is accessed
This fixes several things: - The xwayland code previously incorrectly used the SSD_HEIGHT (for Windows) even when the X11 surface was in a stack - The SSD_HEIGHT was defined in surface.rs, even though rendering serverside decorations is done in the window/stack Rename (min|max)_size to (min|max)_size_without_ssd in CosmicSurface and make it act accordingly Add a new (min|max)_size() in CosmicWindow and CosmicStack, which takes the surface's (min|max)_size and adds the decorations. Change all callers to use (min|max)_size() from the window or stack respectively, except is_dialog() where it does not matter.
This commit is contained in:
parent
1118aa2877
commit
9b78a2d780
6 changed files with 103 additions and 80 deletions
|
|
@ -468,61 +468,16 @@ impl CosmicMapped {
|
||||||
|
|
||||||
pub fn min_size(&self) -> Option<Size<i32, Logical>> {
|
pub fn min_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
match &self.element {
|
match &self.element {
|
||||||
CosmicMappedInternal::Stack(stack) => {
|
CosmicMappedInternal::Stack(stack) => stack.min_size(),
|
||||||
stack.surfaces().fold(None, |min_size, window| {
|
CosmicMappedInternal::Window(window) => window.min_size(),
|
||||||
let win_min_size = window.min_size();
|
|
||||||
match (min_size, win_min_size) {
|
|
||||||
(None, None) => None,
|
|
||||||
(None, x) | (x, None) => x,
|
|
||||||
(Some(min1), Some(min2)) => {
|
|
||||||
Some((min1.w.max(min2.w), min1.h.max(min2.h)).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
CosmicMappedInternal::Window(window) => window.surface().min_size(),
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
match &self.element {
|
match &self.element {
|
||||||
CosmicMappedInternal::Stack(stack) => {
|
CosmicMappedInternal::Stack(stack) => stack.max_size(),
|
||||||
let theoretical_max = stack.surfaces().fold(None, |max_size, window| {
|
CosmicMappedInternal::Window(window) => window.max_size(),
|
||||||
let win_max_size = window.max_size();
|
|
||||||
match (max_size, win_max_size) {
|
|
||||||
(None, None) => None,
|
|
||||||
(None, x) | (x, None) => x,
|
|
||||||
(Some(max1), Some(max2)) => Some(
|
|
||||||
(
|
|
||||||
if max1.w == 0 {
|
|
||||||
max2.w
|
|
||||||
} else if max2.w == 0 {
|
|
||||||
max1.w
|
|
||||||
} else {
|
|
||||||
max1.w.min(max2.w)
|
|
||||||
},
|
|
||||||
if max1.h == 0 {
|
|
||||||
max2.h
|
|
||||||
} else if max2.h == 0 {
|
|
||||||
max1.h
|
|
||||||
} else {
|
|
||||||
max1.h.min(max2.h)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// The problem is, with accumulated sizes, the minimum size could be larger than our maximum...
|
|
||||||
let min_size = self.min_size();
|
|
||||||
match (theoretical_max, min_size) {
|
|
||||||
(None, _) => None,
|
|
||||||
(Some(max), None) => Some(max),
|
|
||||||
(Some(max), Some(min)) => Some((max.w.max(min.w), max.h.max(min.h)).into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CosmicMappedInternal::Window(window) => window.surface().max_size(),
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -911,6 +866,15 @@ impl CosmicMapped {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ssd_height(&self, pending: bool) -> Option<i32> {
|
||||||
|
match &self.element {
|
||||||
|
CosmicMappedInternal::Window(w) => (!w.surface().is_decorated(pending))
|
||||||
|
.then(|| crate::shell::element::window::SSD_HEIGHT),
|
||||||
|
CosmicMappedInternal::Stack(s) => Some(crate::shell::element::stack::TAB_HEIGHT),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsAlive for CosmicMapped {
|
impl IsAlive for CosmicMapped {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface};
|
use super::{
|
||||||
|
window::{Focus, RESIZE_BORDER},
|
||||||
|
CosmicSurface,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::cursor::CursorState,
|
backend::render::cursor::CursorState,
|
||||||
shell::{
|
shell::{
|
||||||
|
|
@ -658,6 +661,59 @@ impl CosmicStack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn min_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
|
self.surfaces()
|
||||||
|
.fold(None, |min_size, window| {
|
||||||
|
let win_min_size = window.min_size_without_ssd();
|
||||||
|
match (min_size, win_min_size) {
|
||||||
|
(None, None) => None,
|
||||||
|
(None, x) | (x, None) => x,
|
||||||
|
(Some(min1), Some(min2)) => {
|
||||||
|
Some((min1.w.max(min2.w), min1.h.max(min2.h)).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|size| size + (0, TAB_HEIGHT).into())
|
||||||
|
}
|
||||||
|
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
|
let theoretical_max = self
|
||||||
|
.surfaces()
|
||||||
|
.fold(None, |max_size, window| {
|
||||||
|
let win_max_size = window.max_size_without_ssd();
|
||||||
|
match (max_size, win_max_size) {
|
||||||
|
(None, None) => None,
|
||||||
|
(None, x) | (x, None) => x,
|
||||||
|
(Some(max1), Some(max2)) => Some(
|
||||||
|
(
|
||||||
|
if max1.w == 0 {
|
||||||
|
max2.w
|
||||||
|
} else if max2.w == 0 {
|
||||||
|
max1.w
|
||||||
|
} else {
|
||||||
|
max1.w.min(max2.w)
|
||||||
|
},
|
||||||
|
if max1.h == 0 {
|
||||||
|
max2.h
|
||||||
|
} else if max2.h == 0 {
|
||||||
|
max1.h
|
||||||
|
} else {
|
||||||
|
max1.h.min(max2.h)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|size| size + (0, TAB_HEIGHT).into());
|
||||||
|
// The problem is, with accumulated sizes, the minimum size could be larger than our maximum...
|
||||||
|
let min_size = self.min_size();
|
||||||
|
match (theoretical_max, min_size) {
|
||||||
|
(None, _) => None,
|
||||||
|
(Some(max), None) => Some(max),
|
||||||
|
(Some(max), Some(min)) => Some((max.w.max(min.w), max.h.max(min.h)).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,6 @@ struct Sticky(AtomicBool);
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct GlobalGeometry(Mutex<Option<Rectangle<i32, Global>>>);
|
struct GlobalGeometry(Mutex<Option<Rectangle<i32, Global>>>);
|
||||||
|
|
||||||
pub const SSD_HEIGHT: i32 = 36;
|
|
||||||
pub const RESIZE_BORDER: i32 = 10;
|
|
||||||
|
|
||||||
impl CosmicSurface {
|
impl CosmicSurface {
|
||||||
pub fn title(&self) -> String {
|
pub fn title(&self) -> String {
|
||||||
match self.0.underlying_surface() {
|
match self.0.underlying_surface() {
|
||||||
|
|
@ -451,7 +448,7 @@ impl CosmicSurface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn min_size(&self) -> Option<Size<i32, Logical>> {
|
pub fn min_size_without_ssd(&self) -> Option<Size<i32, Logical>> {
|
||||||
match self.0.underlying_surface() {
|
match self.0.underlying_surface() {
|
||||||
WindowSurface::Wayland(toplevel) => {
|
WindowSurface::Wayland(toplevel) => {
|
||||||
Some(with_states(toplevel.wl_surface(), |states| {
|
Some(with_states(toplevel.wl_surface(), |states| {
|
||||||
|
|
@ -465,16 +462,9 @@ impl CosmicSurface {
|
||||||
}
|
}
|
||||||
WindowSurface::X11(surface) => surface.min_size(),
|
WindowSurface::X11(surface) => surface.min_size(),
|
||||||
}
|
}
|
||||||
.map(|size| {
|
|
||||||
if self.is_decorated(false) {
|
|
||||||
size
|
|
||||||
} else {
|
|
||||||
size + (0, SSD_HEIGHT).into()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
pub fn max_size_without_ssd(&self) -> Option<Size<i32, Logical>> {
|
||||||
match self.0.underlying_surface() {
|
match self.0.underlying_surface() {
|
||||||
WindowSurface::Wayland(toplevel) => {
|
WindowSurface::Wayland(toplevel) => {
|
||||||
Some(with_states(toplevel.wl_surface(), |states| {
|
Some(with_states(toplevel.wl_surface(), |states| {
|
||||||
|
|
@ -488,13 +478,6 @@ impl CosmicSurface {
|
||||||
}
|
}
|
||||||
WindowSurface::X11(surface) => surface.max_size(),
|
WindowSurface::X11(surface) => surface.max_size(),
|
||||||
}
|
}
|
||||||
.map(|size| {
|
|
||||||
if self.is_decorated(false) {
|
|
||||||
size
|
|
||||||
} else {
|
|
||||||
size + (0, SSD_HEIGHT).into()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serial_acked(&self, serial: &Serial) -> bool {
|
pub fn serial_acked(&self, serial: &Serial) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,10 @@ use std::{
|
||||||
};
|
};
|
||||||
use wayland_backend::server::ObjectId;
|
use wayland_backend::server::ObjectId;
|
||||||
|
|
||||||
use super::{
|
use super::CosmicSurface;
|
||||||
surface::{RESIZE_BORDER, SSD_HEIGHT},
|
|
||||||
CosmicSurface,
|
pub const SSD_HEIGHT: i32 = 36;
|
||||||
};
|
pub const RESIZE_BORDER: i32 = 10;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct CosmicWindow(pub(super) IcedElement<CosmicWindowInternal>);
|
pub struct CosmicWindow(pub(super) IcedElement<CosmicWindowInternal>);
|
||||||
|
|
@ -386,6 +386,29 @@ impl CosmicWindow {
|
||||||
pub(crate) fn force_redraw(&self) {
|
pub(crate) fn force_redraw(&self) {
|
||||||
self.0.force_redraw();
|
self.0.force_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn min_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
|
self.0
|
||||||
|
.with_program(|p| p.window.min_size_without_ssd())
|
||||||
|
.map(|size| {
|
||||||
|
if self.0.with_program(|p| !p.window.is_decorated(false)) {
|
||||||
|
size + (0, SSD_HEIGHT).into()
|
||||||
|
} else {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn max_size(&self) -> Option<Size<i32, Logical>> {
|
||||||
|
self.0
|
||||||
|
.with_program(|p| p.window.max_size_without_ssd())
|
||||||
|
.map(|size| {
|
||||||
|
if self.0.with_program(|p| !p.window.is_decorated(false)) {
|
||||||
|
size + (0, SSD_HEIGHT).into()
|
||||||
|
} else {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ pub fn is_dialog(window: &CosmicSurface) -> bool {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if sizing suggest dialog
|
// Check if sizing suggest dialog
|
||||||
let max_size = window.max_size();
|
let max_size = window.max_size_without_ssd();
|
||||||
let min_size = window.min_size();
|
let min_size = window.min_size_without_ssd();
|
||||||
|
|
||||||
if min_size.is_some() && min_size == max_size {
|
if min_size.is_some() && min_size == max_size {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,7 @@ use std::{ffi::OsString, os::unix::io::OwnedFd, process::Stdio};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::cursor::{load_cursor_theme, Cursor},
|
backend::render::cursor::{load_cursor_theme, Cursor},
|
||||||
shell::{
|
shell::{focus::target::KeyboardFocusTarget, grabs::ReleaseMode, CosmicSurface, Shell},
|
||||||
element::surface::SSD_HEIGHT, focus::target::KeyboardFocusTarget, grabs::ReleaseMode,
|
|
||||||
CosmicSurface, Shell,
|
|
||||||
},
|
|
||||||
state::State,
|
state::State,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::handlers::{
|
wayland::handlers::{
|
||||||
|
|
@ -473,7 +470,7 @@ impl XwmHandler for State {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(current_geo) = current_geo {
|
if let Some(current_geo) = current_geo {
|
||||||
let ssd_height = if window.is_decorated() { 0 } else { SSD_HEIGHT };
|
let ssd_height = mapped.ssd_height(false).unwrap_or(0);
|
||||||
mapped.set_geometry(Rectangle::from_loc_and_size(
|
mapped.set_geometry(Rectangle::from_loc_and_size(
|
||||||
current_geo.loc,
|
current_geo.loc,
|
||||||
(
|
(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue