diff options
| author | user <user@clank> | 2026-09-10 15:40:09 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-10 15:40:09 +0200 |
| commit | 9c5b3319ac4d9a63404fe0cf0d55320754c982ba (patch) | |
| tree | 28e0020a92a55512120467d698bcc09a95e8e17a /include | |
| parent | build: a vendor bump rebuilds libghostty-vt, everywhere it is consumed (diff) | |
| download | slosh-9c5b3319ac4d9a63404fe0cf0d55320754c982ba.tar.gz slosh-9c5b3319ac4d9a63404fe0cf0d55320754c982ba.tar.xz slosh-9c5b3319ac4d9a63404fe0cf0d55320754c982ba.zip | |
tabs: the strip can stand on its side (tab_bar_side left/right)
A sidebar lists one tab per row down the chosen edge, tab_bar_width
columns wide; the panes trade the strip's row for the sidebar's columns
in tab_area(), the one place that arithmetic lives. The per-tab cell
drawing is extracted from draw_tab_strip (label, rename editor, bell,
hover, drop states, hit) and shared, so every mouse verb -- click,
double-click rename, drag to a tab, drop on + -- works in both shapes
because the hits move with the cells.
The strip's indicators (pane count, prefix badge) take the sidebar's
bottom rows, reserved first under the same budgeting rule the strip
applies from the right. The status line below keeps the full width. A
terminal too narrow to give up the columns falls back to top, re-derived
per frame, so a resize moves the bar without anyone storing state.
Diffstat (limited to 'include')
| -rw-r--r-- | include/app_internal.h | 6 | ||||
| -rw-r--r-- | include/config.h | 16 |
2 files changed, 21 insertions, 1 deletions
diff --git a/include/app_internal.h b/include/app_internal.h index be3f979..11f96b4 100644 --- a/include/app_internal.h +++ b/include/app_internal.h @@ -449,6 +449,11 @@ void walk_all(app_t *a, leaf_fn fn, void *ud); /* src/app_layout.c */ uint16_t eff_gap(split_dir_t dir); rect_t app_tab_area(app_t *a); +/* Where the tab bar lands this frame (TAB_BAR_*), and how many columns a + * sidebar takes. The side is re-derived per frame: a screen too narrow for + * the sidebar falls back to the top row. */ +int app_tab_bar_side(const app_t *a); +uint16_t app_tab_bar_cols(void); void close_leaf(app_t *a, node_t *leaf); node_t *first_leaf_of(node_t *n); void focus_dir(app_t *a, int dx, int dy); @@ -509,6 +514,7 @@ void find_corners(app_t *a); void ensure_config(void); void draw_toasts(app_t *a, screen_t *s); void draw_tab_strip(app_t *a, screen_t *s); +void draw_tab_sidebar(app_t *a, screen_t *s); void draw_status_line(app_t *a, screen_t *s); void draw_node(app_t *a, screen_t *s, node_t *n); void draw_min_bar(app_t *a, screen_t *s); diff --git a/include/config.h b/include/config.h index 0d8a396..1392288 100644 --- a/include/config.h +++ b/include/config.h @@ -113,6 +113,14 @@ typedef struct { typedef enum { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT } align_t; +/* tab_bar_side: where the strip of tabs lives. Top is the classic row; left + * and right turn it into a sidebar, one tab per row. */ +enum { + TAB_BAR_TOP = 0, + TAB_BAR_LEFT, + TAB_BAR_RIGHT, +}; + /* size_follows: which attached client sizes the shared screen. */ enum { SIZE_FOLLOWS_ACTIVE = 0, /* newest attach, then last input */ @@ -306,7 +314,13 @@ typedef struct { * sense that an animated shader then only advances when something else * causes a frame. */ uint16_t anim_ms; - bool status_bar; /* the strip along the top: tabs, prefix, pane count */ + bool status_bar; /* the strip along the top: tabs, prefix, pane count */ + /* Where the strip goes when it is on: the top row, or a sidebar on either + * edge. A sidebar lists one tab per row and moves the strip's indicators + * (pane count, prefix badge) to its bottom rows; the status line below is + * untouched and keeps the full width either way. */ + int tab_bar_side; /* TAB_BAR_* */ + uint16_t tab_bar_width; /* columns a sidebar takes; ignored for top */ bool status_line; /* the line along the bottom: what you are looking at */ /* How far the strip and the line are held off the left and right edges. * Separate from `gap`, which is the space around the *panes*: the two happen |
