fix: center tab labels for symmetric highlight padding (#2570)
* fix: center tab labels for symmetric highlight padding * docs: note centered tab labels in the changelog * fix: center tab labels by display width, not char count
This commit is contained in:
parent
f5067ed829
commit
6c6ddcd493
|
|
@ -13,6 +13,7 @@
|
|||
- The plugin marketplace now discovers valid manifests at repository roots and subdirectories, groups multiple plugins under each repository, and publishes their versions and exact default-branch commits.
|
||||
|
||||
### Changed
|
||||
- Desktop tab labels are now centered in their tabs, so the active-tab highlight has symmetric padding.
|
||||
- Bumped the client/server protocol version to 20 for pane terminal bell forwarding.
|
||||
- Experimental pane graphics now support bounded named layers, acknowledged full-RGBA primary-layer direct file frames on audited local terminals, owned BGRA fallback, exact pixel mouse input, and placement-only resize replay.
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ mod tests {
|
|||
assert_eq!(frame.hyperlinks, vec![uri.to_owned()]);
|
||||
assert_eq!(
|
||||
frame_digest(&frame),
|
||||
"ce383feeaac30922502b7c4f8af53b5ca30e816ec4503ca6d015738b584da487"
|
||||
"a7c21fa42305a41231c7ae254f264f6ef923f46301d8fc4cd35ab6dfdd651b6b"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -407,7 +407,14 @@ pub(super) fn render_tab_bar(app: &AppState, frame: &mut Frame, area: Rect) {
|
|||
};
|
||||
let width = rect.width as usize;
|
||||
let name = tab_chrome_label(ws, idx);
|
||||
let text = format!(" {:width$}", name, width = width.saturating_sub(1));
|
||||
// Pad by terminal columns, not chars, so wide glyphs stay centered.
|
||||
let padding = width.saturating_sub(display_width_u16(&name) as usize);
|
||||
let left = padding / 2;
|
||||
let text = format!(
|
||||
"{empty:left$}{name}{empty:right$}",
|
||||
empty = "",
|
||||
right = padding - left
|
||||
);
|
||||
frame.render_widget(Paragraph::new(text).style(style), rect);
|
||||
}
|
||||
|
||||
|
|
@ -656,6 +663,62 @@ mod tests {
|
|||
assert!(view.new_tab_hit_area.width > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cjk_tab_labels_are_centered_by_display_width() {
|
||||
let mut app = AppState::test_new();
|
||||
let mut ws = Workspace::test_new("test");
|
||||
ws.tabs[0].set_custom_name("提交 herdr 的反馈".into());
|
||||
|
||||
app.workspaces = vec![ws];
|
||||
app.active = Some(0);
|
||||
app.view.tab_bar_rect = Rect::new(0, 0, 30, 1);
|
||||
let view = compute_tab_bar_view(&app.workspaces[0], app.view.tab_bar_rect, 0, true, false);
|
||||
app.view.tab_hit_areas = view.tab_hit_areas;
|
||||
|
||||
let backend = TestBackend::new(30, 1);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
terminal
|
||||
.draw(|frame| render_tab_bar(&app, frame, app.view.tab_bar_rect))
|
||||
.unwrap();
|
||||
|
||||
// 17 display columns + 4 padding: two columns each side, wide glyphs
|
||||
// starting right after the left padding.
|
||||
let rect = app.view.tab_hit_areas[0];
|
||||
assert_eq!(rect.width, 21);
|
||||
let buffer = terminal.backend().buffer();
|
||||
assert_eq!(buffer[(rect.x, rect.y)].symbol(), " ");
|
||||
assert_eq!(buffer[(rect.x + 1, rect.y)].symbol(), " ");
|
||||
assert_eq!(buffer[(rect.x + 2, rect.y)].symbol(), "提");
|
||||
assert_eq!(buffer[(rect.x + rect.width - 2, rect.y)].symbol(), " ");
|
||||
assert_eq!(buffer[(rect.x + rect.width - 1, rect.y)].symbol(), " ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_labels_are_centered_in_their_cells() {
|
||||
let mut app = AppState::test_new();
|
||||
let mut ws = Workspace::test_new("test");
|
||||
ws.tabs[0].set_custom_name("omarchy".into());
|
||||
|
||||
app.workspaces = vec![ws];
|
||||
app.active = Some(0);
|
||||
app.view.tab_bar_rect = Rect::new(0, 0, 30, 1);
|
||||
let view = compute_tab_bar_view(&app.workspaces[0], app.view.tab_bar_rect, 0, true, false);
|
||||
app.view.tab_hit_areas = view.tab_hit_areas;
|
||||
|
||||
let backend = TestBackend::new(30, 1);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
terminal
|
||||
.draw(|frame| render_tab_bar(&app, frame, app.view.tab_bar_rect))
|
||||
.unwrap();
|
||||
|
||||
let rect = app.view.tab_hit_areas[0];
|
||||
let buffer = terminal.backend().buffer();
|
||||
let cell: String = (rect.x..rect.x + rect.width)
|
||||
.map(|x| buffer[(x, rect.y)].symbol())
|
||||
.collect();
|
||||
assert_eq!(cell, " omarchy ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_auto_named_tab_keeps_readable_weight() {
|
||||
let mut app = AppState::test_new();
|
||||
|
|
|
|||
Loading…
Reference in New Issue