Skip to content

Commit

Permalink
Add support for stretching tab bar to fill width of tab bar
Browse files Browse the repository at this point in the history
Resolves #1914
  • Loading branch information
dberlin committed Oct 6, 2023
1 parent 11dec45 commit 3e3f2dc
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 17 deletions.
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ members = [
"wezterm-gui",
"wezterm-mux-server",
"wezterm-open-url",
"wezterm-ssh"
"wezterm-ssh",
]
resolver = "2"
exclude = [
"termwiz/codegen"
]
exclude = ["termwiz/codegen"]

[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 1
# debug = 2

[profile.dev]
Expand All @@ -28,8 +28,8 @@ opt-level = 3
#split-debuginfo = "unpacked"

[patch.crates-io]
xcb = {git="https://github.com/rust-x-bindings/rust-xcb", rev="dbdaa01c178c6fbe68bd51b7ad44c08172181083"} # waiting on a release with https://github.com/rust-x-bindings/rust-xcb/pull/230
xcb = { git = "https://github.com/rust-x-bindings/rust-xcb", rev = "dbdaa01c178c6fbe68bd51b7ad44c08172181083" } # waiting on a release with https://github.com/rust-x-bindings/rust-xcb/pull/230

# We use our own vendored cairo, which has minimal deps and should just
# build via cargo.
cairo-sys-rs = {path="deps/cairo", version="0.18.0"}
cairo-sys-rs = { path = "deps/cairo", version = "0.18.0" }
4 changes: 4 additions & 0 deletions config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,10 @@ pub struct Config {
#[dynamic(default)]
pub tab_and_split_indices_are_zero_based: bool,

/// Specifies to fill the width of the window with the tab bar
#[dynamic(default)]
pub tab_bar_fill: bool,

/// Specifies the maximum width that a tab can have in the
/// tab bar. Defaults to 16 glyphs in width.
#[dynamic(default = "default_tab_max_width")]
Expand Down
2 changes: 2 additions & 0 deletions docs/config/appearance.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ details.
bar at the bottom of the window instead of the top
* [tab_max_width](lua/config/tab_max_width.md) sets the maximum width, measured in cells,
of a given tab when using retro tab mode.
* [tab_bar_fill](lua/config/tab_bar_fill.md) sets the fancy tab bar to fill
the width of the title bar.

#### Native (Fancy) Tab Bar appearance

Expand Down
15 changes: 15 additions & 0 deletions docs/config/lua/config/tab_bar_title_fill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
tags:
- tab_bar
---
# `tab_bar_fill`

Specifies that the fancy tab bar should allow tab titles
to take up the entire width of the tab bar.
In this mode, maximum tab width is ignored.

Defaults to false.

```lua
config.tab_bar_fill = true
```
23 changes: 15 additions & 8 deletions wezterm-gui/src/tabbar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ impl TabBarState {

let mut active_tab_no = 0;

let config_tab_max_width = if config.tab_bar_fill {
// We have no layout, so this is a rough estimate
// The tab bar consits of the tab titles, the new tab button, and some padding
title_width.saturating_sub(new_tab.len() + 3) / (tab_info.len())
} else {
config.tab_max_width
};

let tab_titles: Vec<TitleText> = if config.show_tabs_in_tab_bar {
tab_info
.iter()
Expand All @@ -337,7 +345,7 @@ impl TabBarState {
pane_info,
config,
false,
config.tab_max_width,
config_tab_max_width,
)
})
.collect()
Expand All @@ -346,18 +354,16 @@ impl TabBarState {
};
let titles_len: usize = tab_titles.iter().map(|s| s.len).sum();
let number_of_tabs = tab_titles.len();

let available_cells =
title_width.saturating_sub(number_of_tabs.saturating_sub(1) + new_tab.len());
let tab_width_max = if config.use_fancy_tab_bar || available_cells >= titles_len {
// We can render each title with its full width
usize::max_value()
usize::MAX
} else {
// We need to clamp the length to balance them out
available_cells / number_of_tabs
}
.min(config.tab_max_width);

.min(config_tab_max_width);
let mut line = Line::with_width(0, SEQ_ZERO);

let mut x = 0;
Expand Down Expand Up @@ -399,9 +405,10 @@ impl TabBarState {
}

for (tab_idx, tab_title) in tab_titles.iter().enumerate() {
let tab_title_len = tab_title.len.min(tab_width_max);
// The title is allowed to grow to the max size of the computed tab width
let tab_title_max_len = tab_title.len.max(tab_width_max).min(tab_width_max);
let active = tab_idx == active_tab_no;
let hover = !active && is_tab_hover(mouse_x, x, tab_title_len);
let hover = !active && is_tab_hover(mouse_x, x, tab_title_max_len);

// Recompute the title so that it factors in both the hover state
// and the adjusted maximum tab width based on available space.
Expand All @@ -411,7 +418,7 @@ impl TabBarState {
pane_info,
config,
hover,
tab_title_len,
tab_title_max_len,
);

let cell_attrs = if active {
Expand Down
31 changes: 28 additions & 3 deletions wezterm-gui/src/termwindow/render/fancy_tab_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,33 @@ impl crate::TermWindow {
_ => 0.,
})
.sum();
let max_tab_width = ((self.dimensions.pixel_width as f32 / num_tabs)
- (1.5 * metrics.cell_size.width as f32))
.max(0.);

// Unlike num tabs this only includes items on the tab bar, since the new tab button is fixed width.
let num_tabs_or_status: f32 = items
.iter()
.map(|item| match item.item {
TabBarItem::RightStatus { .. }
| TabBarItem::LeftStatus { .. }
| TabBarItem::Tab { .. } => 1.,
_ => 0.,
})
.sum();
// When filling, we allow the entire title bar to be taken up, leaving
// a little space for the new tab button (which is 2x cell width)
// and padding.
let max_tab_width = if self.config.tab_bar_fill {
(self.dimensions.pixel_width as f32 - (5.0 * metrics.cell_size.width as f32)).max(0.)
/ num_tabs_or_status
} else {
((self.dimensions.pixel_width as f32 / num_tabs)
- (1.5 * metrics.cell_size.width as f32))
.max(0.)
};
let min_tab_width = if self.config.tab_bar_fill {
(max_tab_width - 5.0).max(0.)
} else {
0.
};

// Reserve space for the native titlebar buttons
if self
Expand Down Expand Up @@ -335,6 +359,7 @@ impl crate::TermWindow {
}
TabBarItem::Tab { tab_idx, active } => {
let mut elem = item_to_elem(item);
elem.min_width = Some(Dimension::Pixels(min_tab_width));
elem.max_width = Some(Dimension::Pixels(max_tab_width));
elem.content = match elem.content {
ElementContent::Text(_) => unreachable!(),
Expand Down

0 comments on commit 3e3f2dc

Please sign in to comment.