1
0
Fork 0
forked from wry/wry

all: add support for hy3 like tiling

This commit is contained in:
kossLAN 2026-04-10 13:16:35 -04:00
parent a41dbae899
commit cea4187fc0
No known key found for this signature in database
21 changed files with 1237 additions and 48 deletions

View file

@ -15,7 +15,7 @@ use {
theme::{Color, CornerRadius},
tree::{
ContainerNode, DisplayNode, FloatNode, OutputNode, PlaceholderNode, ToplevelData,
ToplevelNodeBase, WorkspaceNode,
ToplevelNodeBase, WorkspaceNode, tab_bar::TabBar,
},
},
std::{ops::Deref, rc::Rc, slice},
@ -277,6 +277,105 @@ impl Renderer<'_> {
self.render_tl_aux(placeholder.tl_data(), bounds, true);
}
fn render_tab_bar(&mut self, tab_bar: &TabBar, x: i32, y: i32, _container_width: i32) {
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let srgb = &srgb_srgb.linear;
let perceptual = RenderIntent::Perceptual;
let scalef = self.base.scalef as f32;
let radius = self.state.theme.sizes.tab_bar_radius.get();
let border_width = self.state.theme.sizes.tab_bar_border_width.get();
let text_padding = self.state.theme.sizes.tab_bar_text_padding.get();
let bar_height = tab_bar.height;
let render_scale = tab_bar.render_scale;
// Vulkan sorts ops: Fill < Tex < RoundedFill (by z_order, color) < RoundedTex.
// We use:
// FillRect tiny strip for Vulkan paint regions (hidden)
// RoundedFillRect z0 solid rounded bg
// RoundedFillRect z1 rounded border ring (on top of bg)
// RoundedCopyTexture title text (on top of everything)
for entry in &tab_bar.entries {
let (bg_color, border_color, _text_color) =
TabBar::entry_colors(self.state, entry);
let ex = entry.x.get();
let ew = entry.width.get();
let tab_rect = Rect::new_sized_saturating(ex, 0, ew, bar_height);
let tab_cr = CornerRadius::from(radius as f32);
// Tiny FillRect strip to establish Vulkan paint regions (visually hidden
// behind the RoundedFillRect bg that renders later).
let strip = Rect::new_sized_saturating(ex + radius, bar_height / 2, (ew - 2 * radius).max(1), 1);
self.base
.fill_boxes2(slice::from_ref(&strip), &bg_color, srgb, perceptual, x, y);
// Rounded solid bg fill (z_order=0, renders first among RoundedFill).
self.base.fill_rounded_rect_z(
tab_rect.move_(x, y),
&bg_color,
None,
srgb,
perceptual,
tab_cr.scaled_by(scalef),
0.0,
0,
);
// Rounded border ring on top (z_order=1, renders after bg).
if border_width > 0 {
self.base.fill_rounded_rect_z(
tab_rect.move_(x, y),
&border_color,
None,
srgb,
perceptual,
tab_cr.scaled_by(scalef),
border_width as f32 * scalef,
1,
);
}
// Title text as RoundedCopyTexture (sorts after all RoundedFill).
let tex_ref = entry.title_texture.borrow();
if let Some(tex) = tex_ref.as_ref()
&& let Some(texture) = tex.texture()
{
use crate::theme::TabTitleAlign;
let (tw, _th) = texture.size();
let tex_width = (tw as f64 / render_scale.to_f64()).round() as i32;
let tab_inner = ew - 2 * (text_padding + border_width);
let text_x = match self.state.theme.tab_title_align.get() {
TabTitleAlign::Start => x + ex + text_padding + border_width,
TabTitleAlign::Center => {
x + ex + border_width + (tab_inner.max(0) - tex_width).max(0) / 2 + text_padding.min(tab_inner.max(0) / 2)
}
TabTitleAlign::End => {
let end_x = x + ex + ew - tex_width - text_padding - border_width;
end_x.max(x + ex + border_width)
}
};
let (tx, ty) = self.base.scale_point(text_x, y);
self.base.render_rounded_texture(
&texture,
None,
tx,
ty,
None,
None,
render_scale,
None,
None,
AcquireSync::None,
ReleaseSync::None,
self.state.color_manager.srgb_gamma22(),
perceptual,
AlphaMode::PremultipliedElectrical,
CornerRadius::from(0.0_f32),
);
}
}
}
fn render_container_decorations(&mut self, container: &ContainerNode, x: i32, y: i32) {
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let srgb = &srgb_srgb.linear;
@ -291,6 +390,13 @@ impl Renderer<'_> {
self.render_container_decorations(container, x, y);
if let Some(child) = container.mono_child.get() {
// Render tab bar if present.
{
let tab_bar = container.tab_bar.borrow();
if let Some(tb) = tab_bar.as_ref() {
self.render_tab_bar(tb, x, y, container.width.get());
}
}
let mb = container.mono_body.get();
if self.state.theme.sizes.gap.get() != 0 {
let srgb_srgb = self.state.color_manager.srgb_gamma22();
@ -308,21 +414,22 @@ impl Renderer<'_> {
let perceptual = RenderIntent::Perceptual;
if !child.node.node_is_container() {
let cr = self.state.theme.corner_radius.get();
let full_h = mb.y2();
let frame_y = mb.y1();
let frame_h = mb.height();
if cr.is_zero() {
let frame_rects = [
Rect::new_sized_saturating(mb.x1() - bw, 0, bw, full_h),
Rect::new_sized_saturating(mb.x2(), 0, bw, full_h),
Rect::new_sized_saturating(mb.x1() - bw, -bw, full_w + 2 * bw, bw),
Rect::new_sized_saturating(mb.x1() - bw, full_h, full_w + 2 * bw, bw),
Rect::new_sized_saturating(mb.x1() - bw, frame_y, bw, frame_h),
Rect::new_sized_saturating(mb.x2(), frame_y, bw, frame_h),
Rect::new_sized_saturating(mb.x1() - bw, frame_y - bw, full_w + 2 * bw, bw),
Rect::new_sized_saturating(mb.x1() - bw, frame_y + frame_h, full_w + 2 * bw, bw),
];
self.base.fill_boxes2(&frame_rects, c, srgb, perceptual, x, y);
} else {
let outer = Rect::new_sized_saturating(
mb.x1() - bw,
-bw,
frame_y - bw,
full_w + 2 * bw,
full_h + 2 * bw,
frame_h + 2 * bw,
);
let scalef = self.base.scalef as f32;
let scaled_cr = cr.scaled_by(scalef);