tmenu reads a newline-delimited list of items from stdin, lets you filter by typing, and executes the selected entry via /bin/sh -c. The entire implementation fits in a single C source file under 300 lines. The only runtime dependency is Xlib.
- Why tmenu?
- Quick Start
- Installation
- Usage
- Key Bindings
- Configuration
- Contributing
- Related Projects
- Star History
- License
| Feature | tmenu | dmenu | rofi |
|---|---|---|---|
| Source size | under 300 lines | ~2500 lines | ~15000 lines |
| Dependencies | Xlib only | Xlib, Xft | Xlib, cairo, pango, ... |
| Config file | none (compile-time) | none (compile-time) | yes |
| Executes typed text | yes | yes | no |
| Launch overhead | minimal | minimal | moderate |
| Auditable in an hour | yes | hard | no |
tmenu follows the suckless philosophy: small, auditable, compile-time configured. No config file parser, no IPC, no scripting layer. Read the source - understand the program.
git clone https://github.com/tinyopsec/tmenu && cd tmenu && make && sudo make install
tmenu_rungit clone https://github.com/tinyopsec/tmenu
cd tmenu
make
sudo make installInstalls to /usr/local/bin/. To change the prefix:
sudo make install PREFIX=/usrUninstall:
sudo make uninstall| Dependency | ||
|---|---|---|
| Xlib | libx11 |
libx11-dev |
| C compiler | gcc |
build-essential |
yay -S tmenuInstall XQuartz, then build from source as above.
Install libX11 via ports or pkgsrc, then build from source.
# Use the bundled launcher (scans $PATH):
tmenu_run
# Pipe items manually:
printf "st\nfirefox\nhtop\n" | tmenuType to filter, navigate with arrow keys, press Enter to execute. If the typed text matches no item, it is executed directly as a shell command.
| Flag | Description |
|---|---|
-b |
Show menu at the bottom of the screen |
-l N |
Vertical list with N visible lines |
-p text |
Prompt displayed left of the input field |
# Vertical launcher with prompt:
printf "st\nfirefox\nthunderbird\n" | tmenu -l 5 -p "run: "
# Power menu at bottom:
printf "suspend\nreboot\npoweroff\n" | tmenu -b -p "power: "
# Session menu:
printf "lock\nlogout\n" | tmenu -b -p "session: "dwm / swm:
static const char *dmenucmd[] = { "tmenu_run", NULL };Recompile your WM after editing the config.
i3:
bindsym $mod+d exec tmenu_run
.xinitrc example:
export PATH="$HOME/.local/bin:$PATH"
picom &
feh --bg-scale ~/wallpaper.png &
exec swmDebugging
Check binary is available:
which tmenu
which tmenu_runRun the launcher directly to test:
tmenu_runIf the keybinding does nothing, check:
$PATHis set before your WM starts (set it in.xinitrc)- WM config references
tmenu_runcorrectly - Binary is executable:
chmod +x /usr/local/bin/tmenu_run
Test with explicit input:
$ printf "echo hello\n" | tmenu| Key | Action |
|---|---|
Enter / KP_Enter |
Execute selected item or typed text |
Escape |
Exit without executing |
BackSpace |
Delete character left of cursor |
Up / Left |
Move selection up or left |
Down / Right |
Move selection down or right |
Ctrl+U |
Clear entire input field |
Ctrl+W |
Delete one word left of cursor |
Ctrl+K |
Move selection up (vertical list) |
Ctrl+J |
Move selection down (vertical list) |
To remap keys, edit the kp() function in tmenu.c and recompile.
tmenu has no runtime config file. All settings are macros at the top of tmenu.c. Edit and recompile to apply changes:
$EDITOR tmenu.c
make && sudo make install| Macro | Default | Description |
|---|---|---|
FONT |
"-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*" |
X11 core font string |
FGNORM |
"#bbbbbb" |
Normal item foreground color |
BGNORM |
"#222222" |
Normal item background color |
FGSEL |
"#eeeeee" |
Selected item foreground color |
BGSEL |
"#005577" |
Selected item background color |
TOP |
1 |
1 = top of screen, 0 = bottom |
LINES |
0 |
Default line count (0 = horizontal) |
PROMPT |
NULL |
Default prompt string |
To increase limits, adjust MAXITEMS (default: 65536) and MAXTEXT (default: 256) in tmenu.c.
-#define BGSEL "#005577"
+#define BGSEL "#8b0000"
-#define FONT "-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*"
+#define FONT "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*"Bug reports and patches are welcome via GitHub Issues and pull requests.
- No comments in production code
- No external dependencies beyond Xlib
- No unnecessary abstraction
- Compiles clean:
gcc -std=c99 -pedantic -Wall -Wextra - Total source must remain under 300 lines
Features are added by patching the source, not by adding runtime options. Changes that require a config file or a new library dependency will not be accepted.
| Project | Description | Link |
|---|---|---|
| dmenu | The original dynamic menu for X | suckless.org |
| suckless.org | Philosophy behind tmenu | suckless.org |
| Xlib manual | Reference for X11 programming | x.org |
MIT. See LICENSE for details.
