Rofi Window Switcher and Application Launcher
repository·next·Indexed 12 days ago
https://github.com/davatorium/rofiA highly extensible window switcher, application launcher, and dmenu replacement for Linux and BSD. Rofi features advanced filtering (fuzzy, regex, glob), robust Wayland and X11 support, and a powerful theming engine using the .rasi format. It includes built-in modes such as run, drun, window, ssh, and combi, and supports custom script modes and plugins.
What's inside Rofi
- Rofi is a versatile window switcher, application launcher, and dmenu replacement. It provides a textual list of options that a user can select from, such as running an application, selecting a window, or choosing options provided by an external script. It is highly configurable, supports UTF-8, and features advanced theming and extensible modes via scripts and plugins.
Access Rofi documentation and manpages
nextRofi documentation is organized into two main tracks: Development (current/bleeding edge) and Stable (version-specific).
- Use the Development links to access the latest manpages, theme specifications, and feature guides (such as Dmenu, Script mode, and Debugging).
- Use the Stable links to access documentation specifically for the current stable release (e.g., version 2.0.0).
Key documentation areas include:
- Manpages: Detailed command-line interface and mode references.
- Themes: Specifications for
rofi-theme.5androfi-dmenu.5. - Guides: Specialized topics like Transparency, Positioning, Plugins, and Dynamic Themes.
How Rofi script mode works (API and Lifecycle)
nextRofi script mode operates via a simple request-response loop using an executable.
Execution Flow
- Initial Call: Rofi executes the script with no arguments. The script's standard output becomes the list of selectable entries.
- User Action: When an entry is selected, Rofi re-runs the script, providing the selected text as the first command-line argument.
Environment Variables
Rofi provides context to your script via these variables:
ROFI_RETV: An integer representing the current state:0: Initial call.1: An entry was selected.2: A custom entry was selected.10-28: Custom keybindings 1-19 (must be explicitly enabled via script options).
ROFI_INFO: Contains the value of theinforow option if a user selects an entry with that property set.ROFI_DATA: Contains data passed from the script to its next execution via thedatamode option.
Example Script
This script provides two options: 'reload' and 'quit'. Selecting 'quit' exits the script.
#!/usr/bin/env bash if [ x"$@" = x"quit" ] then exit 0 fi echo "reload" echo "quit"Handle icons in themes
nextRofi supports three methods for specifying icons:
- Filename: A direct path to an image file.
- icon-name: A name looked up via the system's icon-theme (uses GdkPixbuf).
- Markup String: A string rendered as an icon using Pango. This requires a
<spantag to define color and font.
Markup String Example:
To use a markup string, the string must start with a
<spantag. For example, to render a red power icon via dmenu:echo -en "testing\0icon\x1f<span color='red'>⏻</span>" | ./rofi -dmenuHandle icons via filenames, names, or markup
nextRofi supports three methods for specifying icons:
- Filename: A direct path to an image file.
- icon-name: A name looked up via the system icon theme.
- Markup String: A string rendered as an icon using Pango. This requires a
<spantag to define color and font.
For filenames and icon-names, GdkPixbuf is used for rendering.
# Example of using a markup string as an icon in dmenu mode echo -en "testing\0icon\x1f<span color='red'>⏻</span>" | ./rofi -dmenuUnderstand the rofi layout model and hierarchy
nextThe rofi window is structured as a hierarchy of boxes that pack other boxes or widgets. Boxes can be oriented either
verticalorhorizontal.Default Hierarchy
The default layout follows this structure:
window{BOX:vertical}mainbox{BOX:vertical}inputbar{BOX:horizontal}promptentrycase-indicator(ci)num-filtered-rows(fr)num-rows(ns)
messagetextbox
listviewelementelement-iconelement-text
mode-switcher{BOX:horizontal}Button(multiple)
Fixed Widgets
The following widgets are considered 'fixed' and provide core functionality:
promptentryoverlaycase-indicatormessagelistviewmode-switchernum-rowsnum-filtered-rows
Configure mouse button identifiers in rofi
nextWhen binding mouse actions, you can use specific button identifiers. The identifier format is
Mouse<D><Button>, whereDis an optional indicator for a double press.Available Buttons
Primary: Primary (Left) mouse buttonSecondary: Secondary (Right) mouse buttonMiddle: Middle mouse buttonForward: Forward mouse buttonBack: Back mouse buttonExtraN: The N-th mouse button (hardware dependent)
Double Click Example
To represent a double click on the primary button, use
MouseDPrimary.Example usage in configuration:
configuration { me-accept-entry: "MouseDPrimary"; }How Rofi theme loading and overriding works
nextRofi always loads a
defaulttheme. To use a different theme, add an@themestatement to yourconfig.rasifile.Overriding Mechanism: If you use
@theme "name", you can override any property of that theme by defining the same widget section later in yourconfig.rasifile. Multiple properties for the same widget can be grouped using commas (e.g.,entry, element-text { ... }).To inspect the default theme without your local config, run:
rofi -no-config -dump-themerofi -no-config -dump-themeUnderstand the rofi layout model and box structure
nextThe rofi window layout is built using a hierarchical structure of boxes that pack other boxes or widgets. Boxes can be oriented either
verticalorhorizontal(similar to GTK).Core Hierarchy
By default, the layout follows this structure:
window(vertical box)mainbox(vertical box)inputbar(horizontal box)prompt,entry,case-indicator,overlay,num-filtered-rows,num-rows
message(contains atextbox)listview(containselementwidgets)mode-switcher(horizontal box containingbuttonwidgets)
Fixed Widgets
The following widgets are considered 'fixed' and provide core functionality:
promptentryoverlaycase-indicatormessagelistviewmode-switchernum-rowsnum-filtered-rows
/* Default packing keywords */ mainbox Packs: `inputbar, message, listview, mode-switcher` inputbar Packs: `prompt,entry,case-indicator`"Available rofi modes and their behaviors
nextRofi operates in several distinct modes, each serving a different purpose:
window: Lists all windows for switching.shift-deletecloses a window;control-enterorshift-enterruns a command on the window (configured viawindow-command).windowcd: Similar towindowbut only shows windows on the current desktop.shift-deletekills the window.run: Lists executables in$PATH.shift-deleteremoves an entry from history;control-enterruns the command;shift-enterruns it in a terminal.Control-lopens File Browser mode.drun: Launches applications based on installed.desktopfiles (XDG specification).shift-deleteremoves history;control-enterruns the command;shift-enterruns in a terminal.Control-lopens File Browser mode.ssh: Lists SSH targets from yoursshconfig.keys: Shows a searchable list of keybindings.script: Allows for custom scripted modes.combi: Combines multiple modes into one list. Use-combi-modesto specify which modes to include. You can filter results using a!bang prefix (e.g.,!wto filter for modes starting with 'w').
Use @media queries for conditional theme loading
nextRofi themes support
@mediablocks to conditionally load CSS rules based on constraints like window dimensions, aspect ratio, or environment. Constraints can use integers or fractions (e.g.,120px).Supported keys:
min-width/max-width: Width constraints.min-height/max-height: Height constraints.min-aspect-ratio/max-aspect-ratio: Aspect ratio constraints.monitor-id: The monitor ID (checkrofi -helpfor IDs).enabled: Boolean option. Supports environment variables or theDMENUkeyword to detect if running in dmenu mode.
/* Load when width is at least 120px */ @media ( min-width: 120 px ) { } /* Load based on environment variable */ @media ( enabled: env(DO_LIGHT, false )) { } /* Load only when in dmenu mode */ @media ( enabled: DMENU) { }Understand how transparency layers work in rofi
nextRofi builds its window by drawing the background first, then layering each widget on top with its own transparency factor. Because transparency is applied cumulatively (one layer on top of another), setting a transparency value on every widget will result in a much less transparent final appearance than expected.
To achieve a clean transparent look, use this pattern:
- Set all elements (
*) to be fully transparent. - Set the background color specifically on the
windowelement. - Only set background colors on specific widgets where you want distinct coloring.
/* 1. Make everything transparent by default */ * { background: transparent; } /* 2. Set the base background on the window */ window { background: #cc1c1c1c; } /* 3. Only color specific widgets as needed */- Set all elements (