1
0
Fork 0
forked from wry/wry

theme: add separate bar_height setting

This commit is contained in:
Julian Orth 2025-09-17 17:19:19 +02:00
parent 3933eba30c
commit 01f9c094ee
12 changed files with 97 additions and 36 deletions

View file

@ -315,5 +315,11 @@ pub mod sized {
/// ///
/// Default: 4 /// Default: 4
const 02 => BORDER_WIDTH, const 02 => BORDER_WIDTH,
/// The height of the bar.
///
/// Defaults to the TITLE_HEIGHT if not set explicitly.
///
/// Default: 17
const 03 => BAR_HEIGHT,
} }
} }

View file

@ -2302,6 +2302,7 @@ impl ConfigProxyHandler {
let sized = match sized { let sized = match sized {
TITLE_HEIGHT => ThemeSized::title_height, TITLE_HEIGHT => ThemeSized::title_height,
BORDER_WIDTH => ThemeSized::border_width, BORDER_WIDTH => ThemeSized::border_width,
BAR_HEIGHT => ThemeSized::bar_height,
_ => return Err(CphError::UnknownSized(sized.0)), _ => return Err(CphError::UnknownSized(sized.0)),
}; };
Ok(sized) Ok(sized)
@ -2309,7 +2310,7 @@ impl ConfigProxyHandler {
fn handle_get_size(&self, sized: Resizable) -> Result<(), CphError> { fn handle_get_size(&self, sized: Resizable) -> Result<(), CphError> {
let sized = self.get_sized(sized)?; let sized = self.get_sized(sized)?;
let size = sized.field(&self.state.theme).get(); let size = sized.field(&self.state.theme).val.get();
self.respond(Response::GetSize { size }); self.respond(Response::GetSize { size });
Ok(()) Ok(())
} }
@ -2322,7 +2323,9 @@ impl ConfigProxyHandler {
if size > sized.max() { if size > sized.max() {
return Err(CphError::InvalidSize(size, sized)); return Err(CphError::InvalidSize(size, sized));
} }
sized.field(&self.state.theme).set(size); let field = sized.field(&self.state.theme);
field.val.set(size);
field.set.set(true);
self.spaces_change(); self.spaces_change();
Ok(()) Ok(())
} }

View file

@ -78,7 +78,7 @@ impl Renderer<'_> {
fullscreen = ws.fullscreen.get(); fullscreen = ws.fullscreen.get();
} }
let theme = &self.state.theme; let theme = &self.state.theme;
let th = theme.sizes.title_height.get(); let bh = theme.sizes.bar_height();
let srgb_srgb = self.state.color_manager.srgb_gamma22(); let srgb_srgb = self.state.color_manager.srgb_gamma22();
let srgb = &srgb_srgb.linear; let srgb = &srgb_srgb.linear;
if let Some(fs) = &fullscreen { if let Some(fs) = &fullscreen {
@ -89,7 +89,7 @@ impl Renderer<'_> {
let non_exclusive_rect = output.non_exclusive_rect_rel.get(); let non_exclusive_rect = output.non_exclusive_rect_rel.get();
let (x, mut y) = non_exclusive_rect.translate_inv(x, y); let (x, mut y) = non_exclusive_rect.translate_inv(x, y);
if self.state.show_bar.get() { if self.state.show_bar.get() {
let bar_bg = Rect::new_sized(0, 0, non_exclusive_rect.width(), th).unwrap(); let bar_bg = Rect::new_sized(0, 0, non_exclusive_rect.width(), bh).unwrap();
let bar_bg = self.base.scale_rect(bar_bg); let bar_bg = self.base.scale_rect(bar_bg);
let bar_bg_abs = { let bar_bg_abs = {
let (x, y) = self.base.scale_point(x, y); let (x, y) = self.base.scale_point(x, y);
@ -166,7 +166,7 @@ impl Renderer<'_> {
self.render_surface(&data.surface, rect.x1(), rect.y1(), Some(&bounds)); self.render_surface(&data.surface, rect.x1(), rect.y1(), Some(&bounds));
} }
} }
y += th + 1; y += bh + 1;
} }
if let Some(ws) = output.workspace.get() { if let Some(ws) = output.workspace.get() {
self.render_workspace(&ws, x, y); self.render_workspace(&ws, x, y);
@ -196,7 +196,7 @@ impl Renderer<'_> {
&& ws.render_highlight.get() > 0 && ws.render_highlight.get() > 0
{ {
let color = self.state.theme.colors.highlight.get(); let color = self.state.theme.colors.highlight.get();
let bounds = ws.position.get().at_point(x, y + th + 1); let bounds = ws.position.get().at_point(x, y + bh + 1);
self.base.ops.push(GfxApiOpt::Sync); self.base.ops.push(GfxApiOpt::Sync);
self.base.fill_boxes(&[bounds], &color, srgb); self.base.fill_boxes(&[bounds], &color, srgb);
} }

View file

@ -1524,7 +1524,7 @@ impl State {
if !self.show_bar.get() { if !self.show_bar.get() {
return 0; return 0;
} }
(self.theme.sizes.title_height.get() - 2).max(0) (self.theme.sizes.bar_height() - 2).max(0)
} }
pub fn color_management_available(&self) -> bool { pub fn color_management_available(&self) -> bool {

View file

@ -354,11 +354,22 @@ colors! {
highlight = (0x9d, 0x28, 0xc6, 0x7f), highlight = (0x9d, 0x28, 0xc6, 0x7f),
} }
pub struct ThemeSize {
pub val: Cell<i32>,
pub set: Cell<bool>,
}
impl ThemeSize {
pub fn get(&self) -> i32 {
self.val.get()
}
}
macro_rules! sizes { macro_rules! sizes {
($($name:ident = ($min:expr, $max:expr, $def:expr),)*) => { ($($name:ident = ($min:expr, $max:expr, $def:expr),)*) => {
pub struct ThemeSizes { pub struct ThemeSizes {
$( $(
pub $name: Cell<i32>, pub $name: ThemeSize,
)* )*
} }
@ -387,7 +398,7 @@ macro_rules! sizes {
} }
} }
pub fn field(self, theme: &Theme) -> &Cell<i32> { pub fn field(self, theme: &Theme) -> &ThemeSize {
let sizes = &theme.sizes; let sizes = &theme.sizes;
match self { match self {
$( $(
@ -409,7 +420,8 @@ macro_rules! sizes {
pub fn reset(&self) { pub fn reset(&self) {
let default = Self::default(); let default = Self::default();
$( $(
self.$name.set(default.$name.get()); self.$name.val.set(default.$name.val.get());
self.$name.set.set(false);
)* )*
} }
} }
@ -418,7 +430,10 @@ macro_rules! sizes {
fn default() -> Self { fn default() -> Self {
Self { Self {
$( $(
$name: Cell::new($def), $name: ThemeSize {
val: Cell::new($def),
set: Cell::new(false),
},
)* )*
} }
} }
@ -426,8 +441,19 @@ macro_rules! sizes {
} }
} }
impl ThemeSizes {
pub fn bar_height(&self) -> i32 {
if self.bar_height.set.get() {
self.bar_height.val.get()
} else {
self.title_height.val.get()
}
}
}
sizes! { sizes! {
title_height = (0, 1000, 17), title_height = (0, 1000, 17),
bar_height = (0, 1000, 17),
border_width = (0, 1000, 4), border_width = (0, 1000, 4),
} }

View file

@ -516,16 +516,16 @@ impl OutputNode {
}; };
let font = self.state.theme.font.get(); let font = self.state.theme.font.get();
let theme = &self.state.theme; let theme = &self.state.theme;
let th = theme.sizes.title_height.get(); let bh = theme.sizes.bar_height();
let scale = self.global.persistent.scale.get(); let scale = self.global.persistent.scale.get();
let scale = if scale != 1 { let scale = if scale != 1 {
Some(scale.to_f64()) Some(scale.to_f64())
} else { } else {
None None
}; };
let mut texture_height = th; let mut texture_height = bh;
if let Some(scale) = scale { if let Some(scale) = scale {
texture_height = (th as f64 * scale).round() as _; texture_height = (bh as f64 * scale).round() as _;
} }
let active_id = self.workspace.get().map(|w| w.id); let active_id = self.workspace.get().map(|w| w.id);
for ws in self.workspaces.iter() { for ws in self.workspaces.iter() {
@ -577,7 +577,7 @@ impl OutputNode {
} }
let mut pos = 0; let mut pos = 0;
let theme = &self.state.theme; let theme = &self.state.theme;
let th = theme.sizes.title_height.get(); let bh = theme.sizes.bar_height();
let scale = self.global.persistent.scale.get(); let scale = self.global.persistent.scale.get();
let scale = if scale != 1 { let scale = if scale != 1 {
Some(scale.to_f64()) Some(scale.to_f64())
@ -587,9 +587,9 @@ impl OutputNode {
let active_id = self.workspace.get().map(|w| w.id); let active_id = self.workspace.get().map(|w| w.id);
let non_exclusive_rect = self.non_exclusive_rect.get(); let non_exclusive_rect = self.non_exclusive_rect.get();
let output_width = non_exclusive_rect.width(); let output_width = non_exclusive_rect.width();
rd.underline = Rect::new_sized(0, th, output_width, 1).unwrap(); rd.underline = Rect::new_sized(0, bh, output_width, 1).unwrap();
for ws in self.workspaces.iter() { for ws in self.workspaces.iter() {
let mut title_width = th; let mut title_width = bh;
let title = &*ws.title_texture.borrow(); let title = &*ws.title_texture.borrow();
if let Some(title) = title { if let Some(title) = title {
if let Err(e) = title.flip() { if let Err(e) = title.flip() {
@ -616,7 +616,7 @@ impl OutputNode {
}); });
} }
} }
let rect = Rect::new_sized(pos, 0, title_width, th).unwrap(); let rect = Rect::new_sized(pos, 0, title_width, bh).unwrap();
if Some(ws.id) == active_id { if Some(ws.id) == active_id {
rd.active_workspace = Some(OutputWorkspaceRenderData { rd.active_workspace = Some(OutputWorkspaceRenderData {
rect, rect,
@ -652,7 +652,7 @@ impl OutputNode {
non_exclusive_rect.x1(), non_exclusive_rect.x1(),
non_exclusive_rect.y1(), non_exclusive_rect.y1(),
non_exclusive_rect.width(), non_exclusive_rect.width(),
th + 1, bh + 1,
) )
.unwrap(); .unwrap();
if self.title_visible.get() { if self.title_visible.get() {
@ -786,7 +786,7 @@ impl OutputNode {
pub fn update_rects(self: &Rc<Self>) { pub fn update_rects(self: &Rc<Self>) {
let rect = self.global.pos.get(); let rect = self.global.pos.get();
let th = self.state.theme.sizes.title_height.get(); let bh = self.state.theme.sizes.bar_height();
let exclusive = self.exclusive_zones.get(); let exclusive = self.exclusive_zones.get();
let y1 = rect.y1() + exclusive.top; let y1 = rect.y1() + exclusive.top;
let x2 = rect.x2() - exclusive.right; let x2 = rect.x2() - exclusive.right;
@ -804,7 +804,7 @@ impl OutputNode {
)); ));
let mut y1 = y1; let mut y1 = y1;
if self.state.show_bar.get() { if self.state.show_bar.get() {
y1 += th + 1; y1 += bh + 1;
} }
let height = (y2 - y1).max(0); let height = (y2 - y1).max(0);
self.workspace_rect self.workspace_rect
@ -1136,7 +1136,7 @@ impl OutputNode {
self.pointer_down.set(s, (x, y)); self.pointer_down.set(s, (x, y));
} }
let (x, y) = self.non_exclusive_rect_rel.get().translate(x, y); let (x, y) = self.non_exclusive_rect_rel.get().translate(x, y);
if y >= self.state.theme.sizes.title_height.get() { if y >= self.state.theme.sizes.bar_height() {
return; return;
} }
let ws = 'ws: { let ws = 'ws: {
@ -1266,15 +1266,15 @@ impl OutputNode {
return None; return None;
} }
let show_bar = self.state.show_bar.get(); let show_bar = self.state.show_bar.get();
let th = self.state.theme.sizes.title_height.get(); let bh = self.state.theme.sizes.bar_height();
if show_bar && y_abs < rect.y1() + th + 1 { if show_bar && y_abs < rect.y1() + bh + 1 {
let rd = &*self.render_data.borrow(); let rd = &*self.render_data.borrow();
let (x, _) = rect.translate(x_abs, y_abs); let (x, _) = rect.translate(x_abs, y_abs);
let mut last_x2 = 0; let mut last_x2 = 0;
for t in &rd.titles { for t in &rd.titles {
if x < t.x2 { if x < t.x2 {
return Some(TileDragDestination { return Some(TileDragDestination {
highlight: Rect::new_sized(rect.x1() + t.x1, rect.y1(), t.x2 - t.x1, th)?, highlight: Rect::new_sized(rect.x1() + t.x1, rect.y1(), t.x2 - t.x1, bh)?,
ty: TddType::MoveToWorkspace { ty: TddType::MoveToWorkspace {
workspace: t.ws.clone(), workspace: t.ws.clone(),
}, },
@ -1287,7 +1287,7 @@ impl OutputNode {
rect.x1() + last_x2, rect.x1() + last_x2,
rect.y1(), rect.y1(),
rect.x2() - last_x2, rect.x2() - last_x2,
th, bh,
)?, )?,
ty: TddType::MoveToNewWorkspace { ty: TddType::MoveToNewWorkspace {
output: self.clone(), output: self.clone(),
@ -1295,7 +1295,7 @@ impl OutputNode {
}); });
} }
let bar_height = match show_bar { let bar_height = match show_bar {
true => th + 1, true => bh + 1,
false => 0, false => 0,
}; };
let rect = Rect::new(rect.x1(), rect.y1() + bar_height, rect.x2(), rect.y2())?; let rect = Rect::new(rect.x1(), rect.y1() + bar_height, rect.x2(), rect.y2())?;
@ -1324,8 +1324,8 @@ impl OutputNode {
if !rect.contains(x_abs, y_abs) { if !rect.contains(x_abs, y_abs) {
return None; return None;
} }
let th = self.state.theme.sizes.title_height.get(); let bh = self.state.theme.sizes.bar_height();
if y_abs - rect.y1() > th + 1 { if y_abs - rect.y1() > bh + 1 {
return None; return None;
} }
if self.state.workspace_display_order.get() == WorkspaceDisplayOrder::Sorted { if self.state.workspace_display_order.get() == WorkspaceDisplayOrder::Sorted {
@ -1333,7 +1333,7 @@ impl OutputNode {
return None; return None;
} }
return Some(WorkspaceDragDestination { return Some(WorkspaceDragDestination {
highlight: Rect::new_sized(rect.x1(), rect.y1(), rect.width(), th)?, highlight: Rect::new_sized(rect.x1(), rect.y1(), rect.width(), bh)?,
output: self.clone(), output: self.clone(),
before: None, before: None,
}); });
@ -1357,7 +1357,7 @@ impl OutputNode {
rect.x1() + prev_center, rect.x1() + prev_center,
rect.y1(), rect.y1(),
center - prev_center, center - prev_center,
th, bh,
)?, )?,
output: self.clone(), output: self.clone(),
before: Some(t.ws.clone()), before: Some(t.ws.clone()),
@ -1375,7 +1375,7 @@ impl OutputNode {
rect.x1() + prev_center, rect.x1() + prev_center,
rect.y1(), rect.y1(),
rect.x2() - prev_center, rect.x2() - prev_center,
th, bh,
)?, )?,
output: self.clone(), output: self.clone(),
before: None, before: None,
@ -1383,7 +1383,7 @@ impl OutputNode {
} }
pub fn update_tray_positions(self: &Rc<Self>) { pub fn update_tray_positions(self: &Rc<Self>) {
let th = self.state.theme.sizes.title_height.get(); let bh = self.state.theme.sizes.bar_height();
let rect = self.non_exclusive_rect.get(); let rect = self.non_exclusive_rect.get();
let output_width = rect.width(); let output_width = rect.width();
let mut right = output_width; let mut right = output_width;
@ -1394,7 +1394,7 @@ impl OutputNode {
continue; continue;
} }
have_any = true; have_any = true;
right -= th; right -= bh;
let rel_pos = Rect::new_sized(right, 1, icon_size, icon_size).unwrap(); let rel_pos = Rect::new_sized(right, 1, icon_size, icon_size).unwrap();
let abs_pos = rel_pos.move_(rect.x1(), rect.y1()); let abs_pos = rel_pos.move_(rect.x1(), rect.y1());
item.set_position(abs_pos, rel_pos); item.set_position(abs_pos, rel_pos);
@ -1406,7 +1406,7 @@ impl OutputNode {
if prev_right != right { if prev_right != right {
{ {
let min = prev_right.min(right); let min = prev_right.min(right);
let rect = Rect::new_sized(rect.x1() + min, 0, output_width, th).unwrap(); let rect = Rect::new_sized(rect.x1() + min, 0, output_width, bh).unwrap();
self.state.damage(rect); self.state.damage(rect);
} }
self.schedule_update_render_data(); self.schedule_update_render_data();
@ -1581,7 +1581,7 @@ impl Node for OutputNode {
return FindTreeResult::AcceptsInput; return FindTreeResult::AcceptsInput;
} }
let bar_height = match self.state.show_bar.get() { let bar_height = match self.state.show_bar.get() {
true => self.state.theme.sizes.title_height.get() + 1, true => self.state.theme.sizes.bar_height() + 1,
false => 0, false => 0,
}; };
if usecase == FindTreeUsecase::SelectWorkspace { if usecase == FindTreeUsecase::SelectWorkspace {

View file

@ -195,6 +195,7 @@ pub struct Theme {
pub highlight_color: Option<Color>, pub highlight_color: Option<Color>,
pub border_width: Option<i32>, pub border_width: Option<i32>,
pub title_height: Option<i32>, pub title_height: Option<i32>,
pub bar_height: Option<i32>,
pub font: Option<String>, pub font: Option<String>,
} }

View file

@ -58,6 +58,7 @@ impl Parser for ThemeParser<'_> {
highlight_color, highlight_color,
border_width, border_width,
title_height, title_height,
bar_height,
font, font,
), ),
) = ext.extract(( ) = ext.extract((
@ -81,6 +82,7 @@ impl Parser for ThemeParser<'_> {
opt(val("highlight-color")), opt(val("highlight-color")),
recover(opt(s32("border-width"))), recover(opt(s32("border-width"))),
recover(opt(s32("title-height"))), recover(opt(s32("title-height"))),
recover(opt(s32("bar-height"))),
recover(opt(str("font"))), recover(opt(str("font"))),
), ),
))?; ))?;
@ -116,6 +118,7 @@ impl Parser for ThemeParser<'_> {
highlight_color: color!(highlight_color), highlight_color: color!(highlight_color),
border_width: border_width.despan(), border_width: border_width.despan(),
title_height: title_height.despan(), title_height: title_height.despan(),
bar_height: bar_height.despan(),
font: font.map(|f| f.value.to_string()), font: font.map(|f| f.value.to_string()),
}) })
} }

View file

@ -893,6 +893,7 @@ impl State {
} }
size!(BORDER_WIDTH, border_width); size!(BORDER_WIDTH, border_width);
size!(TITLE_HEIGHT, title_height); size!(TITLE_HEIGHT, title_height);
size!(BAR_HEIGHT, bar_height);
if let Some(font) = &theme.font { if let Some(font) = &theme.font {
set_font(font); set_font(font);
} }

View file

@ -1907,6 +1907,11 @@
"description": "The height of tabs.", "description": "The height of tabs.",
"minimum": 0.0 "minimum": 0.0
}, },
"bar-height": {
"type": "integer",
"description": "The height of the bar. Defaults to the title-height if not set.",
"minimum": 0.0
},
"font": { "font": {
"type": "string", "type": "string",
"description": "The name of the font to use." "description": "The name of the font to use."

View file

@ -4235,6 +4235,16 @@ The table has the following fields:
The numbers should be greater than or equal to 0. The numbers should be greater than or equal to 0.
- `bar-height` (optional):
The height of the bar. Defaults to the title-height if not set.
The value of this field should be a number.
The numbers should be integers.
The numbers should be greater than or equal to 0.
- `font` (optional): - `font` (optional):
The name of the font to use. The name of the font to use.

View file

@ -2123,6 +2123,12 @@ Theme:
minimum: 0 minimum: 0
required: false required: false
description: The height of tabs. description: The height of tabs.
bar-height:
kind: number
integer_only: true
minimum: 0
required: false
description: The height of the bar. Defaults to the title-height if not set.
font: font:
kind: string kind: string
required: false required: false