---
name: "notcurses_tabbed"
section: "3"
platform: "linux"
package: "notcurses"
version: "3.0.17-3"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/notcurses_tabbed"
---

# notcurses\_tabbed(3)

tabbed interface widget

## NAME

notcurses\_tabbed – tabbed interface widget

## SYNOPSIS

**#include \<notcurses/notcurses.h\>**

-

  ```
  #define NCTABBED_OPTION_BOTTOM 0x0001
  struct nctabbed;
  struct ncplane;
  struct nctab;
  typedef struct nctabbed_options {
    uint64_t selchan; // channel for the selected tab header
    uint64_t hdrchan; // channel for unselected tab headers
    uint64_t sepchan; // channel for the tab separator
    const char* separator; // separator string (copied by nctabbed_create())
    uint64_t flags;   // bitmask of NCTABBED_OPTION_*
  } nctabbed_options;
  typedef void (*tabcb)(struct nctab* t, struct ncplane* ncp, void* userptr);
  ```

**struct nctabbed\* nctabbed\_create(struct ncplane\*** *ncp***, const nctabbed\_options\*** *opts***);**

**void nctabbed\_destroy(struct nctabbed\*** *nt***);**

**void nctabbed\_redraw(struct nctabbed\*** *nt***);**

**void nctabbed\_ensure\_selected\_header\_visible(struct nctabbed\*** *nt***);**

**struct nctab\* nctabbed\_selected(struct nctabbed\*** *nt***);**

**struct nctab\* nctabbed\_leftmost(struct nctabbed\*** *nt***);**

**int nctabbed\_tabcount(struct nctabbed\*** *nt***);**

**struct ncplane\* nctabbed\_plane(struct nctabbed\*** *nt***);**

**struct ncplane\* nctabbed\_content\_plane(struct nctabbed\*** *nt***);**

**tabcb nctab\_cb(struct nctab\*** *t***);**

**const char\* nctab\_name(struct nctab\*** *t***);**

**int nctab\_name\_width(struct nctab\*** *t***);**

**void\* nctab\_userptr(struct nctab\*** *t***);**

**struct nctab\* nctab\_next(struct nctab\*** *t***);**

**struct nctab\* nctab\_prev(struct nctab\*** *t***);**

**struct nctab\* nctabbed\_add(struct nctabbed\*** *nt***,** **struct nctab\*** *after***, struct nctab\*** *before***, tabcb** *tcb***, const char\*** *name***, void\*** *opaque*\*\*);

**int nctabbed\_del(struct nctabbed\*** *nt***, struct** **nctab\*** *t***);**

**int nctab\_move(struct nctabbed\*** *nt***, struct** **nctab\*** *t***, struct nctab\*** *after***,** **struct nctab\*** *before***);**

**void nctab\_move\_right(struct nctabbed\*** *nt***,** **struct nctab\*** *t***);**

**void nctab\_move\_left(struct nctabbed\*** *nt***,** **struct nctab\*** *t***);**

**void nctabbed\_rotate(struct nctabbed\*** *nt***, int** *amt***);**

**struct nctab\* nctabbed\_next(struct nctabbed\*** *nt***);**

**struct nctab\* nctabbed\_prev(struct nctabbed\*** *nt***);**

**struct nctab\* nctabbed\_select(struct nctabbed\*** *nt***, struct nctab\*** *t***);**

**void nctabbed\_channels(struct nctabbed\*** *nt***,** **uint64\_t\* RESTRICT** *hdrchan***, uint64\_t\* RESTRICT** *selchan***, uint64\_t\* RESTRICT** *sepchan***);**

**uint64\_t nctabbed\_hdrchan(struct nctabbed\*** *nt***);**

**uint64\_t nctabbed\_selchan(struct nctabbed\*** *nt***);**

**uint64\_t nctabbed\_sepchan(struct nctabbed\*** *nt***);**

**const char\* nctabbed\_separator(struct nctabbed\*** *nt***);**

**int nctabbed\_separator\_width(struct nctabbed\*** *nt***);**

**void nctabbed\_set\_hdrchan(struct nctabbed\*** *nt***,** **uint64\_t** *chan***);**

**void nctabbed\_set\_selchan(struct nctabbed\*** *nt***,** **uint64\_t** *chan***);**

**void nctabbed\_set\_sepchan(struct nctabbed\*** *nt***,** **uint64\_t** *chan***);**

**tabcb nctab\_set\_cb(struct nctab\*** *t***, tabcb** *newcb***);**

**int nctab\_set\_name(struct nctab\*** *t***, const char\*** *newname***);**

**void\* nctab\_set\_userptr(struct nctab\*** *t***, void\*** *newopaque***);**

**int nctabbed\_set\_separator(struct nctabbed\*** *nt***,** **const char\*** *separator***);**

## DESCRIPTION

An **nctabbed** is a widget with one area for data display and a bar with names of tabs. Unless there are no tabs, exactly one tab is "selected", and exactly one tab is "leftmost". The selected tab is the one that controls the tab content plane. The leftmost tab is the one of which the header is visible furthest to the left. Any tab can be moved to and from anywhere in the list. The tabs can be "rotated", which really means the leftmost tab gets shifted. The widget is drawn only when **nctabbed\_redraw** or **ntabbed\_create** are called.

### LAYOUT

The widget has a tab list either on the top or the bottom, 1 row thick. The tab list contains tab headers (i.e. their names), separated with the separator specified in **nctabbed\_create** or **nctabbed\_set\_separator**. The channels for the selected tab's header, other tab headers and the separator can be set independently of each other. The tab separator can be 0-length, or NULL, in which case there is no visible separator between tab headers. The selected tab can be made sure to be visible when drawn (by changing the leftmost tab) by calling the very long-named **nctabbed\_ensure\_selected\_header\_visible**. The rest of the widget is an **ncplane** housing the selected tab content. (if any)

### THE TAB CALLBACK

The tab callback (of type **tabcb**) takes a tab, the tab content plane, and the opaque pointer given to **nctabbed\_add** or **nctabbed\_set\_userptr**. It is called when the tab content is supposed to be drawn, that is when the whole widget is redrawn. It should draw the tab content and possibly make other actions, but it should not assume anything about the current state of the tab content plane, nor should it modify the widget's or the tab's state.

## RETURN VALUES

**nctabbed\_create** returns the newly created widget, or **NULL** when the widget failed to be created. This destroys the **ncplane** given to it even if it fails.

**nctabbed\_selected** and **nctabbed\_leftmost** return the selected and leftmost tabs, respectively. If there are no tabs, these return **NULL**.

**nctab\_name** returns the tab's name. This is not a copy, and it should not be stored, since it is freed when the tab's name is changed or the tab is deleted.

**nctabbed\_next**, **nctabbed\_prev** and **nctabbed\_select** return the newly selected tab.

**nctabbed\_separator** returns the tab separator. This is not a copy, and it should not be stored, since it is freed when the separator is changed or the widget is deleted.

Functions returning **int** return **-1** on failure.

## SEE ALSO

**[notcurses(3)](/notcurses/3.md)**, **[notcurses\_channels(3)](/notcurses_channels/3.md)**, **[notcurses\_plane(3)](/notcurses_plane/3.md)**

## AUTHORS

v3.0.17.
