1
0
Fork 0
forked from wry/wry

add window gaps

This commit is contained in:
atagen 2026-04-05 20:04:13 +10:00
parent 769d12a525
commit 750bf06ce9
9 changed files with 144 additions and 13 deletions

View file

@ -2440,6 +2440,7 @@ impl ConfigProxyHandler {
BORDER_WIDTH => ThemeSized::border_width,
BAR_HEIGHT => ThemeSized::bar_height,
BAR_SEPARATOR_WIDTH => ThemeSized::bar_separator_width,
GAP => ThemeSized::gap,
_ => return Err(CphError::UnknownSized(sized.0)),
};
Ok(sized)

View file

@ -334,18 +334,102 @@ impl Renderer<'_> {
}
}
if let Some(child) = container.mono_child.get() {
let body = container.mono_body.get().move_(x, y);
let mb = container.mono_body.get();
if self.state.theme.sizes.gap.get() > 0 && !child.node.node_is_container() {
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let bw = self.state.theme.sizes.border_width.get();
let border_color = self.state.theme.colors.border.get();
let focused_border_color =
self.state.theme.colors.focused_title_background.get();
let c = if child.active.get() {
&focused_border_color
} else {
&border_color
};
let full_h = mb.y2();
let full_w = mb.width();
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),
];
self.base.fill_boxes2(
&frame_rects,
c,
&srgb_srgb.linear,
RenderIntent::Perceptual,
x,
y,
);
}
let body = mb.move_(x, y);
let body = self.base.scale_rect(body);
let content = container.mono_content.get();
child
.node
.node_render(self, x + content.x1(), y + content.y1(), Some(&body));
} else {
let gap = self.state.theme.sizes.gap.get();
let (srgb_srgb, bw, border_color, focused_border_color, tpuh) = if gap > 0 {
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let bw = self.state.theme.sizes.border_width.get();
let border_color = self.state.theme.colors.border.get();
let focused_border_color = self.state.theme.colors.focused_title_background.get();
let tpuh = self.state.theme.title_plus_underline_height();
(
Some(srgb_srgb),
bw,
border_color,
focused_border_color,
tpuh,
)
} else {
(None, 0, Color::SOLID_BLACK, Color::SOLID_BLACK, 0)
};
for child in container.children.iter() {
let body = child.body.get();
if body.x1() >= container.width.get() || body.y1() >= container.height.get() {
break;
}
if let Some(srgb_srgb) = srgb_srgb {
if !child.node.node_is_container() {
let srgb = &srgb_srgb.linear;
let c = if child.border_color_is_focused.get() {
&focused_border_color
} else {
&border_color
};
let title_rect = child.title_rect.get();
let top_y = if tpuh > 0 { title_rect.y1() } else { body.y1() };
let full_h = body.y2() - top_y;
let full_w = body.width();
let frame_rects = [
Rect::new_sized_saturating(body.x1() - bw, top_y, bw, full_h),
Rect::new_sized_saturating(body.x2(), top_y, bw, full_h),
Rect::new_sized_saturating(
body.x1() - bw,
top_y - bw,
full_w + 2 * bw,
bw,
),
Rect::new_sized_saturating(
body.x1() - bw,
body.y2(),
full_w + 2 * bw,
bw,
),
];
self.base.fill_boxes2(
&frame_rects,
c,
srgb,
RenderIntent::Perceptual,
x,
y,
);
}
}
let body = body.move_(x, y);
let body = self.base.scale_rect(body);
let content = child.content.get();

View file

@ -586,6 +586,7 @@ sizes! {
bar_height = (0, 1000, 17),
border_width = (0, 1000, 4),
bar_separator_width = (0, 1000, 1),
gap = (0, 1000, 0),
}
impl StaticText for ThemeSized {
@ -595,6 +596,7 @@ impl StaticText for ThemeSized {
ThemeSized::bar_height => "Bar Height",
ThemeSized::border_width => "Border Width",
ThemeSized::bar_separator_width => "Bar Separator Width",
ThemeSized::gap => "Gap",
}
}
}

View file

@ -158,6 +158,7 @@ pub struct ContainerChild {
pub body: Cell<Rect>,
pub content: Cell<Rect>,
factor: Cell<f64>,
pub border_color_is_focused: Cell<bool>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
@ -211,6 +212,7 @@ impl ContainerNode {
title_rect: Default::default(),
focus_history: Default::default(),
attention_requested: Cell::new(false),
border_color_is_focused: Default::default(),
});
let child_node_ref = child_node.clone();
let mut child_nodes = AHashMap::new();
@ -332,6 +334,7 @@ impl ContainerNode {
title_rect: Default::default(),
focus_history: Default::default(),
attention_requested: Default::default(),
border_color_is_focused: Default::default(),
});
let r = link.to_ref();
links.insert(new.node_id(), link);
@ -382,11 +385,16 @@ impl ContainerNode {
}
fn damage(&self) {
let bw = if self.state.theme.sizes.gap.get() > 0 {
self.state.theme.sizes.border_width.get()
} else {
0
};
self.state.damage(Rect::new_sized_saturating(
self.abs_x1.get(),
self.abs_y1.get(),
self.width.get(),
self.height.get(),
self.abs_x1.get() - bw,
self.abs_y1.get() - bw,
self.width.get() + 2 * bw,
self.height.get() + 2 * bw,
));
}
@ -447,6 +455,7 @@ impl ContainerNode {
fn perform_split_layout(self: &Rc<Self>) {
let sum_factors = self.sum_factors.get();
let border_width = self.state.theme.sizes.border_width.get();
let spacing = self.state.theme.sizes.gap.get().max(border_width);
let title_height_tmp = self.state.theme.title_height();
let title_plus_underline_height = self.state.theme.title_plus_underline_height();
let split = self.split.get();
@ -482,7 +491,7 @@ impl ContainerNode {
};
let body = Rect::new_sized_saturating(x1, y1, width, height);
child.body.set(body);
pos += body_size + border_width;
pos += body_size + spacing;
if split == ContainerSplit::Vertical {
pos += title_plus_underline_height;
}
@ -522,7 +531,7 @@ impl ContainerNode {
};
body = Rect::new_sized_saturating(x1, y1, width, height);
child.body.set(body);
pos += size + border_width;
pos += size + spacing;
if split == ContainerSplit::Vertical {
pos += title_plus_underline_height;
}
@ -545,11 +554,12 @@ impl ContainerNode {
fn update_content_size(&self) {
let border_width = self.state.theme.sizes.border_width.get();
let spacing = self.state.theme.sizes.gap.get().max(border_width);
let title_plus_underline_height = self.state.theme.title_plus_underline_height();
let nc = self.num_children.get();
match self.split.get() {
ContainerSplit::Horizontal => {
let new_content_size = self.width.get().sub((nc - 1) as i32 * border_width).max(0);
let new_content_size = self.width.get().sub((nc - 1) as i32 * spacing).max(0);
self.content_width.set(new_content_size);
self.content_height
.set(self.height.get().sub(title_plus_underline_height).max(0));
@ -560,7 +570,7 @@ impl ContainerNode {
.get()
.sub(
title_plus_underline_height
+ (nc - 1) as i32 * (border_width + title_plus_underline_height),
+ (nc - 1) as i32 * (spacing + title_plus_underline_height),
)
.max(0);
self.content_height.set(new_content_size);
@ -832,6 +842,7 @@ impl ContainerNode {
let have_active = self.children.iter().any(|c| c.active.get());
let abs_x = self.abs_x1.get();
let abs_y = self.abs_y1.get();
let gap = self.state.theme.sizes.gap.get();
for (i, child) in self.children.iter().enumerate() {
let rect = child.title_rect.get();
if self.toplevel_data.visible.get() && !mono && split != ContainerSplit::Horizontal {
@ -842,15 +853,17 @@ impl ContainerNode {
rect.height() + tuh,
));
}
if i > 0 {
let rect = if mono {
if gap > 0 && !mono && !child.node.node_is_container() {
child.border_color_is_focused.set(child.active.get());
} else if gap == 0 && i > 0 {
let sep = if mono {
Rect::new_sized_saturating(rect.x1() - bw, 0, bw, th)
} else if split == ContainerSplit::Horizontal {
Rect::new_sized_saturating(rect.x1() - bw, 0, bw, cheight)
} else {
Rect::new_sized_saturating(0, rect.y1() - bw, cwidth, bw)
};
rd.border_rects.push(rect);
rd.border_rects.push(sep);
}
if child.active.get() {
rd.active_title_rects.push(rect);
@ -1184,6 +1197,9 @@ impl ContainerNode {
// log::info!("node_child_active_changed");
self.schedule_render_titles();
self.schedule_compute_render_positions();
if self.state.theme.sizes.gap.get() > 0 && self.toplevel_data.visible.get() {
self.damage();
}
if let Some(parent) = self.toplevel_data.parent.get() {
parent.node_child_active_changed(self.deref(), active, depth + 1);
}
@ -1920,6 +1936,7 @@ impl ContainingNode for ContainerNode {
title_rect: Cell::new(node.title_rect.get()),
focus_history: Cell::new(None),
attention_requested: Cell::new(false),
border_color_is_focused: Default::default(),
});
if let Some(fh) = node.focus_history.take() {
link.focus_history.set(Some(fh.append(link.to_ref())));
@ -1974,6 +1991,7 @@ impl ContainingNode for ContainerNode {
};
let num_children = self.num_children.fetch_sub(1) - 1;
if num_children == 0 {
self.damage();
self.tl_destroy();
return;
}

View file

@ -819,6 +819,21 @@ impl OutputNode {
.set(bar_rect_with_separator_rel);
self.bar_separator_rect.set(bar_separator_rect);
self.bar_separator_rect_rel.set(bar_separator_rect_rel);
let gap = self.state.theme.sizes.gap.get();
if gap > 0 {
workspace_rect = Rect::new_sized_saturating(
workspace_rect.x1() + gap,
workspace_rect.y1() + gap,
(workspace_rect.width() - 2 * gap).max(0),
(workspace_rect.height() - 2 * gap).max(0),
);
workspace_rect_rel = Rect::new_sized_saturating(
workspace_rect_rel.x1() + gap,
workspace_rect_rel.y1() + gap,
(workspace_rect_rel.width() - 2 * gap).max(0),
(workspace_rect_rel.height() - 2 * gap).max(0),
);
}
self.workspace_rect.set(workspace_rect);
self.workspace_rect_rel.set(workspace_rect_rel);
self.update_tray_positions();