From 01f9c094eee086f692b531fde1fa5eb7c3fd998d Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 17 Sep 2025 17:19:19 +0200 Subject: [PATCH 1/2] theme: add separate bar_height setting --- jay-config/src/theme.rs | 6 +++ src/config/handler.rs | 7 +++- src/renderer.rs | 8 ++-- src/state.rs | 2 +- src/theme.rs | 34 +++++++++++++++-- src/tree/output.rs | 50 ++++++++++++------------- toml-config/src/config.rs | 1 + toml-config/src/config/parsers/theme.rs | 3 ++ toml-config/src/lib.rs | 1 + toml-spec/spec/spec.generated.json | 5 +++ toml-spec/spec/spec.generated.md | 10 +++++ toml-spec/spec/spec.yaml | 6 +++ 12 files changed, 97 insertions(+), 36 deletions(-) diff --git a/jay-config/src/theme.rs b/jay-config/src/theme.rs index 35f1757e..8e15201b 100644 --- a/jay-config/src/theme.rs +++ b/jay-config/src/theme.rs @@ -315,5 +315,11 @@ pub mod sized { /// /// Default: 4 const 02 => BORDER_WIDTH, + /// The height of the bar. + /// + /// Defaults to the TITLE_HEIGHT if not set explicitly. + /// + /// Default: 17 + const 03 => BAR_HEIGHT, } } diff --git a/src/config/handler.rs b/src/config/handler.rs index 8b464863..49223df9 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -2302,6 +2302,7 @@ impl ConfigProxyHandler { let sized = match sized { TITLE_HEIGHT => ThemeSized::title_height, BORDER_WIDTH => ThemeSized::border_width, + BAR_HEIGHT => ThemeSized::bar_height, _ => return Err(CphError::UnknownSized(sized.0)), }; Ok(sized) @@ -2309,7 +2310,7 @@ impl ConfigProxyHandler { fn handle_get_size(&self, sized: Resizable) -> Result<(), CphError> { 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 }); Ok(()) } @@ -2322,7 +2323,9 @@ impl ConfigProxyHandler { if size > sized.max() { 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(); Ok(()) } diff --git a/src/renderer.rs b/src/renderer.rs index fc6cb4c5..4e9ab16a 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -78,7 +78,7 @@ impl Renderer<'_> { fullscreen = ws.fullscreen.get(); } 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_srgb.linear; if let Some(fs) = &fullscreen { @@ -89,7 +89,7 @@ impl Renderer<'_> { let non_exclusive_rect = output.non_exclusive_rect_rel.get(); let (x, mut y) = non_exclusive_rect.translate_inv(x, y); 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_abs = { 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)); } } - y += th + 1; + y += bh + 1; } if let Some(ws) = output.workspace.get() { self.render_workspace(&ws, x, y); @@ -196,7 +196,7 @@ impl Renderer<'_> { && ws.render_highlight.get() > 0 { 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.fill_boxes(&[bounds], &color, srgb); } diff --git a/src/state.rs b/src/state.rs index 21e61e93..1c1d30ee 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1524,7 +1524,7 @@ impl State { if !self.show_bar.get() { 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 { diff --git a/src/theme.rs b/src/theme.rs index 787bc73f..78be8640 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -354,11 +354,22 @@ colors! { highlight = (0x9d, 0x28, 0xc6, 0x7f), } +pub struct ThemeSize { + pub val: Cell, + pub set: Cell, +} + +impl ThemeSize { + pub fn get(&self) -> i32 { + self.val.get() + } +} + macro_rules! sizes { ($($name:ident = ($min:expr, $max:expr, $def:expr),)*) => { pub struct ThemeSizes { $( - pub $name: Cell, + pub $name: ThemeSize, )* } @@ -387,7 +398,7 @@ macro_rules! sizes { } } - pub fn field(self, theme: &Theme) -> &Cell { + pub fn field(self, theme: &Theme) -> &ThemeSize { let sizes = &theme.sizes; match self { $( @@ -409,7 +420,8 @@ macro_rules! sizes { pub fn reset(&self) { 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 { 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! { title_height = (0, 1000, 17), + bar_height = (0, 1000, 17), border_width = (0, 1000, 4), } diff --git a/src/tree/output.rs b/src/tree/output.rs index 1df18b71..51f284ef 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -516,16 +516,16 @@ impl OutputNode { }; let font = self.state.theme.font.get(); 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 = if scale != 1 { Some(scale.to_f64()) } else { None }; - let mut texture_height = th; + let mut texture_height = bh; 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); for ws in self.workspaces.iter() { @@ -577,7 +577,7 @@ impl OutputNode { } let mut pos = 0; 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 = if scale != 1 { Some(scale.to_f64()) @@ -587,9 +587,9 @@ impl OutputNode { let active_id = self.workspace.get().map(|w| w.id); let non_exclusive_rect = self.non_exclusive_rect.get(); 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() { - let mut title_width = th; + let mut title_width = bh; let title = &*ws.title_texture.borrow(); if let Some(title) = title { 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 { rd.active_workspace = Some(OutputWorkspaceRenderData { rect, @@ -652,7 +652,7 @@ impl OutputNode { non_exclusive_rect.x1(), non_exclusive_rect.y1(), non_exclusive_rect.width(), - th + 1, + bh + 1, ) .unwrap(); if self.title_visible.get() { @@ -786,7 +786,7 @@ impl OutputNode { pub fn update_rects(self: &Rc) { 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 y1 = rect.y1() + exclusive.top; let x2 = rect.x2() - exclusive.right; @@ -804,7 +804,7 @@ impl OutputNode { )); let mut y1 = y1; if self.state.show_bar.get() { - y1 += th + 1; + y1 += bh + 1; } let height = (y2 - y1).max(0); self.workspace_rect @@ -1136,7 +1136,7 @@ impl OutputNode { self.pointer_down.set(s, (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; } let ws = 'ws: { @@ -1266,15 +1266,15 @@ impl OutputNode { return None; } let show_bar = self.state.show_bar.get(); - let th = self.state.theme.sizes.title_height.get(); - if show_bar && y_abs < rect.y1() + th + 1 { + let bh = self.state.theme.sizes.bar_height(); + if show_bar && y_abs < rect.y1() + bh + 1 { let rd = &*self.render_data.borrow(); let (x, _) = rect.translate(x_abs, y_abs); let mut last_x2 = 0; for t in &rd.titles { if x < t.x2 { 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 { workspace: t.ws.clone(), }, @@ -1287,7 +1287,7 @@ impl OutputNode { rect.x1() + last_x2, rect.y1(), rect.x2() - last_x2, - th, + bh, )?, ty: TddType::MoveToNewWorkspace { output: self.clone(), @@ -1295,7 +1295,7 @@ impl OutputNode { }); } let bar_height = match show_bar { - true => th + 1, + true => bh + 1, false => 0, }; 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) { return None; } - let th = self.state.theme.sizes.title_height.get(); - if y_abs - rect.y1() > th + 1 { + let bh = self.state.theme.sizes.bar_height(); + if y_abs - rect.y1() > bh + 1 { return None; } if self.state.workspace_display_order.get() == WorkspaceDisplayOrder::Sorted { @@ -1333,7 +1333,7 @@ impl OutputNode { return None; } 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(), before: None, }); @@ -1357,7 +1357,7 @@ impl OutputNode { rect.x1() + prev_center, rect.y1(), center - prev_center, - th, + bh, )?, output: self.clone(), before: Some(t.ws.clone()), @@ -1375,7 +1375,7 @@ impl OutputNode { rect.x1() + prev_center, rect.y1(), rect.x2() - prev_center, - th, + bh, )?, output: self.clone(), before: None, @@ -1383,7 +1383,7 @@ impl OutputNode { } pub fn update_tray_positions(self: &Rc) { - 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 output_width = rect.width(); let mut right = output_width; @@ -1394,7 +1394,7 @@ impl OutputNode { continue; } have_any = true; - right -= th; + right -= bh; let rel_pos = Rect::new_sized(right, 1, icon_size, icon_size).unwrap(); let abs_pos = rel_pos.move_(rect.x1(), rect.y1()); item.set_position(abs_pos, rel_pos); @@ -1406,7 +1406,7 @@ impl OutputNode { if prev_right != 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.schedule_update_render_data(); @@ -1581,7 +1581,7 @@ impl Node for OutputNode { return FindTreeResult::AcceptsInput; } 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, }; if usecase == FindTreeUsecase::SelectWorkspace { diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index 9aaca933..f0e88a2e 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -195,6 +195,7 @@ pub struct Theme { pub highlight_color: Option, pub border_width: Option, pub title_height: Option, + pub bar_height: Option, pub font: Option, } diff --git a/toml-config/src/config/parsers/theme.rs b/toml-config/src/config/parsers/theme.rs index bc971520..76efa092 100644 --- a/toml-config/src/config/parsers/theme.rs +++ b/toml-config/src/config/parsers/theme.rs @@ -58,6 +58,7 @@ impl Parser for ThemeParser<'_> { highlight_color, border_width, title_height, + bar_height, font, ), ) = ext.extract(( @@ -81,6 +82,7 @@ impl Parser for ThemeParser<'_> { opt(val("highlight-color")), recover(opt(s32("border-width"))), recover(opt(s32("title-height"))), + recover(opt(s32("bar-height"))), recover(opt(str("font"))), ), ))?; @@ -116,6 +118,7 @@ impl Parser for ThemeParser<'_> { highlight_color: color!(highlight_color), border_width: border_width.despan(), title_height: title_height.despan(), + bar_height: bar_height.despan(), font: font.map(|f| f.value.to_string()), }) } diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index cec684db..06be7941 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -893,6 +893,7 @@ impl State { } size!(BORDER_WIDTH, border_width); size!(TITLE_HEIGHT, title_height); + size!(BAR_HEIGHT, bar_height); if let Some(font) = &theme.font { set_font(font); } diff --git a/toml-spec/spec/spec.generated.json b/toml-spec/spec/spec.generated.json index 174b9f84..d73d8555 100644 --- a/toml-spec/spec/spec.generated.json +++ b/toml-spec/spec/spec.generated.json @@ -1907,6 +1907,11 @@ "description": "The height of tabs.", "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": { "type": "string", "description": "The name of the font to use." diff --git a/toml-spec/spec/spec.generated.md b/toml-spec/spec/spec.generated.md index 4f6893ea..1e8e646a 100644 --- a/toml-spec/spec/spec.generated.md +++ b/toml-spec/spec/spec.generated.md @@ -4235,6 +4235,16 @@ The table has the following fields: 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): The name of the font to use. diff --git a/toml-spec/spec/spec.yaml b/toml-spec/spec/spec.yaml index b9239cca..46d2f3f0 100644 --- a/toml-spec/spec/spec.yaml +++ b/toml-spec/spec/spec.yaml @@ -2123,6 +2123,12 @@ Theme: minimum: 0 required: false 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: kind: string required: false From 035e2972de324b010ac345f0ae3b25fa7dafe337 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 17 Sep 2025 18:37:13 +0200 Subject: [PATCH 2/2] theme: add title-font and bar-font settings --- jay-config/src/_private/client.rs | 8 ++++++++ jay-config/src/_private/ipc.rs | 6 ++++++ jay-config/src/theme.rs | 20 +++++++++++++++++++- src/config/handler.rs | 24 ++++++++++++++++++++---- src/theme.rs | 14 ++++++++++++++ src/tree/container.rs | 2 +- src/tree/float.rs | 2 +- src/tree/output.rs | 2 +- toml-config/src/config.rs | 2 ++ toml-config/src/config/parsers/theme.rs | 6 ++++++ toml-config/src/lib.rs | 13 ++++++++++--- toml-spec/spec/spec.generated.json | 8 ++++++++ toml-spec/spec/spec.generated.md | 12 ++++++++++++ toml-spec/spec/spec.yaml | 8 ++++++++ 14 files changed, 116 insertions(+), 11 deletions(-) diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index f7eed6c0..99e28791 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -650,6 +650,14 @@ impl ConfigClient { self.send(&ClientMessage::SetFont { font }); } + pub fn set_bar_font(&self, font: &str) { + self.send(&ClientMessage::SetBarFont { font }); + } + + pub fn set_title_font(&self, font: &str) { + self.send(&ClientMessage::SetTitleFont { font }); + } + pub fn get_font(&self) -> String { let res = self.send_with_response(&ClientMessage::GetFont); get_response!(res, String::new(), GetFont { font }); diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index aabd1343..2a66bd84 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -768,6 +768,12 @@ pub enum ClientMessage<'a> { connector: Connector, blend_space: BlendSpace, }, + SetBarFont { + font: &'a str, + }, + SetTitleFont { + font: &'a str, + }, } #[derive(Serialize, Deserialize, Debug)] diff --git a/jay-config/src/theme.rs b/jay-config/src/theme.rs index 8e15201b..5618b519 100644 --- a/jay-config/src/theme.rs +++ b/jay-config/src/theme.rs @@ -145,6 +145,8 @@ pub fn get_font() -> String { /// /// Default: `monospace 8`. /// +/// See also [`set_bar_font`] and [`set_title_font`]. +/// /// The font name should be specified in [pango][pango] syntax. /// /// [pango]: https://docs.gtk.org/Pango/type_func.FontDescription.from_string.html @@ -152,7 +154,23 @@ pub fn set_font(font: &str) { get!().set_font(font) } -/// Resets the font to the default. +/// Sets the font used by the bar. +/// +/// If this function is not called, the font set by [`set_font`] is used. See that +/// function for more details. +pub fn set_bar_font(font: &str) { + get!().set_bar_font(font) +} + +/// Sets the font used by window titles. +/// +/// If this function is not called, the font set by [`set_font`] is used. See that +/// function for more details. +pub fn set_title_font(font: &str) { + get!().set_title_font(font) +} + +/// Resets the fonts to the defaults. /// /// Currently the default is `monospace 8`. pub fn reset_font() { diff --git a/src/config/handler.rs b/src/config/handler.rs index 49223df9..e839723a 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -2341,16 +2341,30 @@ impl ConfigProxyHandler { } fn handle_reset_font(&self) { - self.state - .theme - .font - .set(self.state.theme.default_font.clone()); + let theme = &self.state.theme; + theme.font.set(self.state.theme.default_font.clone()); + theme.bar_font.set(None); + theme.title_font.set(None); } fn handle_set_font(&self, font: &str) { self.state.theme.font.set(Arc::new(font.to_string())); } + fn handle_set_bar_font(&self, font: &str) { + self.state + .theme + .bar_font + .set(Some(Arc::new(font.to_string()))); + } + + fn handle_set_title_font(&self, font: &str) { + self.state + .theme + .title_font + .set(Some(Arc::new(font.to_string()))); + } + fn handle_get_font(&self) { let font = self.state.theme.font.get().to_string(); self.respond(Response::GetFont { font }); @@ -3143,6 +3157,8 @@ impl ConfigProxyHandler { } => self .handle_connector_set_blend_space(connector, blend_space) .wrn("connector_set_blend_space")?, + ClientMessage::SetBarFont { font } => self.handle_set_bar_font(font), + ClientMessage::SetTitleFont { font } => self.handle_set_title_font(font), } Ok(()) } diff --git a/src/theme.rs b/src/theme.rs index 78be8640..9b4c5e80 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -463,6 +463,8 @@ pub struct Theme { pub colors: ThemeColors, pub sizes: ThemeSizes, pub font: CloneCell>, + pub bar_font: CloneCell>>, + pub title_font: CloneCell>>, pub default_font: Arc, } @@ -473,7 +475,19 @@ impl Default for Theme { colors: Default::default(), sizes: Default::default(), font: CloneCell::new(default_font.clone()), + bar_font: Default::default(), + title_font: Default::default(), default_font, } } } + +impl Theme { + pub fn title_font(&self) -> Arc { + self.title_font.get().unwrap_or_else(|| self.font.get()) + } + + pub fn bar_font(&self) -> Arc { + self.bar_font.get().unwrap_or_else(|| self.font.get()) + } +} diff --git a/src/tree/container.rs b/src/tree/container.rs index 73576cd1..f3c34548 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -707,7 +707,7 @@ impl ContainerNode { }; let theme = &self.state.theme; let th = theme.sizes.title_height.get(); - let font = theme.font.get(); + let font = theme.title_font(); let last_active = self.focus_history.last().map(|v| v.node.node_id()); let have_active = self.children.iter().any(|c| c.active.get()); let scales = self.state.scales.lock(); diff --git a/src/tree/float.rs b/src/tree/float.rs index 649f7934..66d5956c 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -205,7 +205,7 @@ impl FloatNode { true => theme.colors.focused_title_text.get(), false => theme.colors.unfocused_title_text.get(), }; - let font = theme.font.get(); + let font = theme.title_font(); let title = self.title.borrow_mut(); let ctx = match self.state.render_ctx.get() { Some(c) => c, diff --git a/src/tree/output.rs b/src/tree/output.rs index 51f284ef..d5d298e8 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -514,7 +514,7 @@ impl OutputNode { let Some(ctx) = self.state.render_ctx.get() else { return on_completed.event(); }; - let font = self.state.theme.font.get(); + let font = self.state.theme.bar_font(); let theme = &self.state.theme; let bh = theme.sizes.bar_height(); let scale = self.global.persistent.scale.get(); diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index f0e88a2e..d8692dbf 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -197,6 +197,8 @@ pub struct Theme { pub title_height: Option, pub bar_height: Option, pub font: Option, + pub title_font: Option, + pub bar_font: Option, } #[derive(Debug, Clone)] diff --git a/toml-config/src/config/parsers/theme.rs b/toml-config/src/config/parsers/theme.rs index 76efa092..b0016b99 100644 --- a/toml-config/src/config/parsers/theme.rs +++ b/toml-config/src/config/parsers/theme.rs @@ -60,7 +60,9 @@ impl Parser for ThemeParser<'_> { title_height, bar_height, font, + title_font, ), + (bar_font,), ) = ext.extract(( ( opt(val("attention-requested-bg-color")), @@ -84,7 +86,9 @@ impl Parser for ThemeParser<'_> { recover(opt(s32("title-height"))), recover(opt(s32("bar-height"))), recover(opt(str("font"))), + recover(opt(str("title-font"))), ), + (recover(opt(str("bar-font"))),), ))?; macro_rules! color { ($e:expr) => { @@ -120,6 +124,8 @@ impl Parser for ThemeParser<'_> { title_height: title_height.despan(), bar_height: bar_height.despan(), font: font.map(|f| f.value.to_string()), + title_font: title_font.map(|f| f.value.to_string()), + bar_font: bar_font.map(|f| f.value.to_string()), }) } } diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index 06be7941..52f9b70a 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -41,7 +41,7 @@ use { set_show_float_pin_icon, set_ui_drag_enabled, set_ui_drag_threshold, status::{set_i3bar_separator, set_status, set_status_command, unset_status_command}, switch_to_vt, - theme::{reset_colors, reset_font, reset_sizes, set_font}, + theme::{reset_colors, reset_font, reset_sizes, set_bar_font, set_font, set_title_font}, toggle_float_above_fullscreen, toggle_show_bar, video::{ ColorSpace, Connector, DrmDevice, Eotf, connectors, drm_devices, @@ -894,9 +894,16 @@ impl State { size!(BORDER_WIDTH, border_width); size!(TITLE_HEIGHT, title_height); size!(BAR_HEIGHT, bar_height); - if let Some(font) = &theme.font { - set_font(font); + macro_rules! font { + ($fun:ident, $field:ident) => { + if let Some(font) = &theme.$field { + $fun(font); + } + }; } + font!(set_font, font); + font!(set_title_font, title_font); + font!(set_bar_font, bar_font); } fn handle_switch_device(self: &Rc, dev: InputDevice, actions: &Rc) { diff --git a/toml-spec/spec/spec.generated.json b/toml-spec/spec/spec.generated.json index d73d8555..7c5a04e2 100644 --- a/toml-spec/spec/spec.generated.json +++ b/toml-spec/spec/spec.generated.json @@ -1915,6 +1915,14 @@ "font": { "type": "string", "description": "The name of the font to use." + }, + "title-font": { + "type": "string", + "description": "The name of the font to use in window titles. Defaults to `font` if not set." + }, + "bar-font": { + "type": "string", + "description": "The name of the font to use in the bar. Defaults to `font` if not set." } }, "required": [] diff --git a/toml-spec/spec/spec.generated.md b/toml-spec/spec/spec.generated.md index 1e8e646a..3b265480 100644 --- a/toml-spec/spec/spec.generated.md +++ b/toml-spec/spec/spec.generated.md @@ -4251,6 +4251,18 @@ The table has the following fields: The value of this field should be a string. +- `title-font` (optional): + + The name of the font to use in window titles. Defaults to `font` if not set. + + The value of this field should be a string. + +- `bar-font` (optional): + + The name of the font to use in the bar. Defaults to `font` if not set. + + The value of this field should be a string. + ### `TileState` diff --git a/toml-spec/spec/spec.yaml b/toml-spec/spec/spec.yaml index 46d2f3f0..7f56000a 100644 --- a/toml-spec/spec/spec.yaml +++ b/toml-spec/spec/spec.yaml @@ -2133,6 +2133,14 @@ Theme: kind: string required: false description: The name of the font to use. + title-font: + kind: string + required: false + description: The name of the font to use in window titles. Defaults to `font` if not set. + bar-font: + kind: string + required: false + description: The name of the font to use in the bar. Defaults to `font` if not set. Config: