Assume square corners for windowed fullscreen windows

This commit is contained in:
Ivan Molodetskikh
2026-04-16 16:52:10 +03:00
parent 892470afd3
commit a1b0bd6d1c
5 changed files with 64 additions and 31 deletions
+24 -6
View File
@@ -290,6 +290,9 @@ pub trait LayoutElement {
Some(requested)
}
fn is_windowed_fullscreen(&self) -> bool {
false
}
fn is_pending_windowed_fullscreen(&self) -> bool {
false
}
@@ -297,6 +300,22 @@ pub trait LayoutElement {
let _ = value;
}
/// The effective geometry corner radius for this element.
///
/// Returns zero when the element is in windowed fullscreen, since fullscreen windows have
/// square corners.
///
/// This method only handles windowed fullscreen and not maximized/real fullscreen. This is
/// because windowed fullscreen is handled by the element itself, whereas other sizing modes
/// are handled externally by the Tile, so the corner radius changes for those modes is also
/// handled externally.
fn geometry_corner_radius(&self) -> CornerRadius {
if self.is_windowed_fullscreen() {
return CornerRadius::default();
}
self.rules().geometry_corner_radius.unwrap_or_default()
}
fn is_child_of(&self, parent: &Self) -> bool;
fn rules(&self) -> &ResolvedWindowRules;
@@ -2854,13 +2873,12 @@ impl<W: LayoutElement> Layout<W> {
ws.scrolling_insert_position(pos_within_workspace)
};
let rules = move_.tile.window().rules();
let border_width = move_.tile.effective_border_width().unwrap_or(0.);
let corner_radius = rules
.geometry_corner_radius
.map_or(CornerRadius::default(), |radius| {
radius.expanded_by(border_width as f32)
});
let corner_radius = move_
.tile
.window()
.geometry_corner_radius()
.expanded_by(border_width as f32);
mon.insert_hint = Some(InsertHint {
workspace: insert_ws,
position,
+4
View File
@@ -243,6 +243,10 @@ impl LayoutElement for TestWindow {
self.0.requested_size.get()
}
fn is_windowed_fullscreen(&self) -> bool {
self.0.is_windowed_fullscreen.get()
}
fn is_pending_windowed_fullscreen(&self) -> bool {
self.0.is_pending_windowed_fullscreen.get()
}
+28 -19
View File
@@ -403,9 +403,9 @@ impl<W: LayoutElement> Tile<W> {
self.shadow.update_config(shadow_config);
let window_size = self.window_size();
let radius = rules
.geometry_corner_radius
.unwrap_or_default()
let radius = self
.window
.geometry_corner_radius()
.fit_to(window_size.w as f32, window_size.h as f32);
self.rounded_corner_damage.set_corner_radius(radius);
}
@@ -473,11 +473,22 @@ impl<W: LayoutElement> Tile<W> {
border_window_size.w -= border_width * 2.;
border_window_size.h -= border_width * 2.;
let radius = rules
.geometry_corner_radius
.map_or(CornerRadius::default(), |radius| {
radius.expanded_by(border_width as f32)
})
// FIXME: this takes into account the animation from normal sizing mode to
// maximized/fullscreen, but it doesn't take into account the corner radius animation from
// the window itself.
//
// Currently, an easy way to see the problem is to start from a window with a nonzero
// radius, then go from windowed fullscreen (that forces 0 radius) to regular fullscreen.
// At the start of the animation, windowed fullscreen becomes false, but the window hasn't
// animated to the normal fullscreen yet, so the radius here jumps to its nonzero value,
// even though it should remain zero throughout.
//
// Later, when windows get the surface shape protocol with radii, this issue will happen
// when that changes between animated commits.
let radius = self
.window
.geometry_corner_radius()
.expanded_by(border_width as f32)
.scaled_by(1. - expanded_progress as f32);
self.border.update_render_elements(
border_window_size,
@@ -496,9 +507,8 @@ impl<W: LayoutElement> Tile<W> {
let radius = if self.visual_border_width().is_some() {
radius
} else {
rules
.geometry_corner_radius
.unwrap_or_default()
self.window
.geometry_corner_radius()
.scaled_by(1. - expanded_progress as f32)
};
self.shadow.update_render_elements(
@@ -1059,9 +1069,9 @@ impl<W: LayoutElement> Tile<W> {
// Clip to geometry including during the fullscreen animation to help with buggy clients
// that submit a full-sized buffer before acking the fullscreen state (Firefox).
let clip_to_geometry = fullscreen_progress < 1. && rules.clip_to_geometry == Some(true);
let radius = rules
.geometry_corner_radius
.unwrap_or_default()
let radius = self
.window
.geometry_corner_radius()
.scaled_by(1. - expanded_progress as f32);
// Popups go on top, whether it's resize or not.
@@ -1235,11 +1245,10 @@ impl<W: LayoutElement> Tile<W> {
// animated corner radius.
if fullscreen_progress < 1. && has_border_shader {
let border_width = self.visual_border_width().unwrap_or(0.);
let radius = rules
.geometry_corner_radius
.map_or(CornerRadius::default(), |radius| {
radius.expanded_by(border_width as f32)
})
let radius = self
.window
.geometry_corner_radius()
.expanded_by(border_width as f32)
.scaled_by(1. - expanded_progress as f32);
let size = self.fullscreen_backdrop.size();
+3 -4
View File
@@ -370,11 +370,10 @@ impl Thumbnail {
// Clip thumbnails to their geometry.
let radius = if mapped.sizing_mode().is_normal() {
mapped.rules().geometry_corner_radius
mapped.geometry_corner_radius()
} else {
None
}
.unwrap_or_default();
CornerRadius::default()
};
let has_border_shader = BorderRenderElement::has_shader(ctx.renderer);
let clip_shader = ClippedSurfaceRenderElement::shader(ctx.renderer).cloned();
+5 -2
View File
@@ -486,8 +486,7 @@ impl Mapped {
let bbox = self.window.bbox_with_popups().to_physical_precise_up(scale);
let has_border_shader = BorderRenderElement::has_shader(renderer);
let rules = self.rules();
let radius = rules.geometry_corner_radius.unwrap_or_default();
let radius = self.geometry_corner_radius();
let window_size = self
.size()
.to_f64()
@@ -1293,6 +1292,10 @@ impl LayoutElement for Mapped {
}
}
fn is_windowed_fullscreen(&self) -> bool {
self.is_windowed_fullscreen
}
fn is_pending_windowed_fullscreen(&self) -> bool {
self.is_pending_windowed_fullscreen
}