From a3974c2ddaaf60b7edd5e718b3d225b3a01697a6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 12 Oct 2026 23:32:13 +0100 Subject: [PATCH] fix(layout): make tab bars more compact --- compositor/src/overview.rs | 26 ++++++++++++++++++------ compositor/src/render/tabs.rs | 4 ++-- crates/ferese-layout/src/lib.rs | 2 +- scripts/tests/test_tree_tabs_isolated.py | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/compositor/src/overview.rs b/compositor/src/overview.rs index b08ff97..2617fd0 100644 --- a/compositor/src/overview.rs +++ b/compositor/src/overview.rs @@ -99,7 +99,7 @@ fn label_font(database: &fontdb::Database, family: &str) -> Option { } type LabelBuffer = (MemoryRenderBuffer, smithay::utils::Size); -type LabelStyle = (u64, [u32; 4]); +type LabelStyle = (u64, u64, [u32; 4]); type OverviewStateLabel = HashMap>; #[derive(Debug)] @@ -247,12 +247,16 @@ impl OverviewState { scale: f64, color: [f32; 4], ) -> Option<(MemoryRenderBuffer, smithay::utils::Size)> { - let key = (scale.to_bits(), color.map(f32::to_bits)); + self.label_with_size(text, scale, color, 13.0) + } + + fn label_with_size(&mut self, text: &str, scale: f64, color: [f32; 4], font_size: f64) -> Option { + let key = (scale.to_bits(), font_size.to_bits(), color.map(f32::to_bits)); if let Some(buffer) = self.labels.get(text).and_then(|styles| styles.get(&key)) { return Some(buffer.clone()); } let font = self.font.as_ref()?; - let scaled = font.as_scaled((13.0 * scale) as f32); + let scaled = font.as_scaled((font_size * scale) as f32); let width = (text .chars() .map(|ch| scaled.h_advance(font.glyph_id(ch))) @@ -260,7 +264,7 @@ impl OverviewState { .ceil() as i32 + 4) .max(1); - let height = (18.0 * scale).ceil() as i32; + let height = ((font_size + 5.0) * scale).ceil() as i32; let mut pixels = vec![0_u8; (width * height * 4) as usize]; let mut pen = 2.0; for ch in text.chars() { @@ -520,10 +524,20 @@ impl Ferese { } pub(crate) fn overview_window_label(&mut self, id: WindowId, scale: f64, width: f64) -> Option { + self.window_title_label(id, scale, width, 13.0) + } + + pub(crate) fn window_title_label( + &mut self, + id: WindowId, + scale: f64, + width: f64, + font_size: f64, + ) -> Option { let record = self.windows.record(id)?; let limit = ((width - 16.0) / 8.0).clamp(1.0, 48.0) as usize; let color = self.theme_settings.text_primary_color.0; - let style = (scale.to_bits(), color.map(f32::to_bits)); + let style = (scale.to_bits(), font_size.to_bits(), color.map(f32::to_bits)); if let Some(label) = self.overview.window_labels.get(&id) && label.revision == record.metadata_revision @@ -549,7 +563,7 @@ impl Ferese { } let revision = record.metadata_revision; - let buffer = self.overview.label(&text, scale, color)?; + let buffer = self.overview.label_with_size(&text, scale, color, font_size)?; self.overview.window_labels.insert( id, WindowLabel { diff --git a/compositor/src/render/tabs.rs b/compositor/src/render/tabs.rs index 60516c1..4cf07c7 100644 --- a/compositor/src/render/tabs.rs +++ b/compositor/src/render/tabs.rs @@ -40,7 +40,7 @@ pub(super) fn tab_elements( .material_radius .min(shell.height * 0.5) .min(shell.width * 0.5); - let inset = 3.0_f64.min(shell.height * 0.25).min(width * 0.25); + let inset = 2.0_f64.min(shell.height * 0.25).min(width * 0.25); let material = crate::effects::resolve_material( crate::effects::SemanticRole::Panel, state.theme_settings.material_style, @@ -68,7 +68,7 @@ pub(super) fn tab_elements( if !protected && width > 20.0 && rect.height >= 16.0 - && let Some((buffer, size)) = state.overview_window_label(id, scale, width) + && let Some((buffer, size)) = state.window_title_label(id, scale, width, 12.0) { let location = Point::::from(( ((rect.x - f64::from(output_geometry.loc.x) diff --git a/crates/ferese-layout/src/lib.rs b/crates/ferese-layout/src/lib.rs index c8a8061..d001d31 100644 --- a/crates/ferese-layout/src/lib.rs +++ b/crates/ferese-layout/src/lib.rs @@ -6,7 +6,7 @@ mod scrolling; pub use scrolling::{Column, ColumnDisplay, ColumnWidth, ScrollingLayout, ViewportFocusStrategy, ViewportTarget}; -pub const TAB_BAR_HEIGHT: f64 = 30.0; +pub const TAB_BAR_HEIGHT: f64 = 24.0; const MIN_SPLIT_RATIO: f64 = 0.05; const MAX_SPLIT_RATIO: f64 = 0.95; diff --git a/scripts/tests/test_tree_tabs_isolated.py b/scripts/tests/test_tree_tabs_isolated.py index 695defb..8d29e0a 100644 --- a/scripts/tests/test_tree_tabs_isolated.py +++ b/scripts/tests/test_tree_tabs_isolated.py @@ -120,7 +120,7 @@ class TabGroupsTest(unittest.TestCase): for index in range(3): left = active["x"] + active["width"] * index / 3 + 4 right = active["x"] + active["width"] * (index + 1) / 3 - 4 - box = (round(left * scale), round((active["y"] - 25) * scale), + box = (round(left * scale), round((active["y"] - 20) * scale), round(right * scale), round((active["y"] - 5) * scale)) pixels = image.crop(box).tobytes() if not any(min(pixels[i:i + 3]) > 130 for i in range(0, len(pixels), 3)):