i3

Related articles
Comparison of tiling window managers
Window manager
Sway
i3
is a
tiling window manager
inspired by
wmii
that is primarily targeted at developers and advanced users.
The stated goals for
i3
include clear documentation, proper multi-monitor support, a tree structure for windows, and different modes like in
vim
.
Installation
i3
can be
installed
with the
i3-wm
package.
An
i3
package group is also available. It includes the window manager, a screen locker and two programs which write a status line to
i3bar
through
stdout
.
Note
i3-gaps
— a fork of
i3
with gaps and other features — was merged into
i3-wm
, and as such is no longer available. Install the
i3-wm
package instead.
Starting
From tty
Run
i3
with
xinit
.
Display manager
i3-wm
includes
i3.desktop
as
Xsession
which starts the window manager.
i3-with-shmlog.desktop
enables logs (useful for debugging).
Usage
See the
official documentation
for more information, namely the
i3 User's Guide
.
Keyboard shortcuts
In
i3
, commands are invoked with a modifier key, referred to as
$mod
. This is
Alt
(Mod1) by default, with
Super
(Mod4) being a popular alternative. Super is the key usually represented on a keyboard as a Windows icon, or on an Apple keyboard as a Command key.
See the
i3 reference card
and
Using i3
for the defaults. See
Keyboard bindings
to add new shortcuts.
Users of non-Qwerty keyboard layouts may wish to circumvent the "configuration wizard" as
described below
.
If switching between multiple window managers or desktop environments, consider using
sxhkd
or another environment agnostic program to manage bindings. More information can be found in
Keyboard shortcuts#Xorg
.
Containers and layouts
i3
manages windows in a tree structure, with containers as building blocks. This structure branches with horizontal or vertical splits. Containers are tiled by default, but can be set to
tabbed or stacking
layouts, as well as made floating (such as for dialog windows). Floating windows are always on top.
See
i3 Tree
and
Containers and the tree data structure
for details.
Application launcher
i3
uses
dmenu
as an application launcher, which is bound by default to
$mod+d
. As it is an optional dependency
dmenu
must first be installed before this functionality can be used.
i3-wm
contains
i3-dmenu-desktop
, a
Perl
wrapper for
dmenu
which uses
desktop entries
to create a list of all installed applications. Alternatively,
j4-dmenu-desktop
can be used.
rofi
is a popular
dmenu
replacement and more that can list desktop entries.
KRunner as application launcher in KDE Plasma/i3
It is possible to have i3 running alongside KDE Plasma as seen here:
KDE#Use a different window manager
When running Plasma with
KDEWM=/usr/bin/i3
, one can set
KRunner
as an alternative application launcher with
$mod+d
by adding the following to the
i3
config:
~/.config/i3/config
set $menu --no-startup-id qdbus6 org.kde.krunner /App display
bindsym $mod+d exec $menu
Configuration
See
Configuring i3
for details. The rest of this article assumes the
i3
configuration file to be in the folder
~/.config/
.
Configuration wizard and alternative keyboard layouts
When
i3
is first started, it offers to run the configuration wizard
i3-config-wizard
. This tool creates
~/.config/i3/config
by rewriting a template configuration file in
/etc/i3/config.keycodes
. It makes two modifications to the default template:
It asks the user to choose a default modifier key, which it adds to the template as a single line, like
set $mod Mod1
; and
it replaces all
bindcode
lines with
bindsym
lines corresponding to the user's current keyboard layout.
Step 2 is designed to ensure that the four navigation shortcuts,
j
,
k
,
l
and
;
on a Qwerty keyboard, will be mapped to keysyms which have the same location, e.g.
h
,
t
,
n
,
s
on a
Dvorak
keyboard. The side-effect of this magic is that up to fifteen other keysyms may be remapped in ways which break the mnemonics - so that, for a Dvorak user, "restart" is bound to
$mod1+p
instead of
$mod1+r
, "split horizontally" is bound to
$mod1+d
instead of
$mod1+h
, and so on.
Therefore, users of alternate keyboard layouts who want straightforward key bindings, which match the bindings given in tutorials, may prefer to circumvent the "config wizard". This can be done by just copying
/etc/i3/config
into
~/.config/i3/config
(or
~/.i3/config
), and editing that file.
Note that a keycode-based configuration is also possible, e.g. for users who often switch between keyboard layouts, but want the
i3
bindings to stay the same.
Autostart
Add an
exec
command in
~/.config/i3/config
file to execute a command at startup. For example:
exec terminator
Using an
exec_always
command instead will ensure that the command is also run whenever i3 is restarted.
Alternatively, you can use a dedicated implementation of
XDG Autostart
.
i3bar
In addition to showing workspace information, i3bar can act as an input for i3status or an alternative, such as those mentioned in the next section. For example:
~/.config/i3/config
bar {
    output            LVDS1
    status_command    i3status
    position          top
    mode              hide
    workspace_buttons yes
    tray_output       none

    font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1

    colors {
        background #000000
        statusline #ffffff

        focused_workspace  #ffffff #285577
        active_workspace   #ffffff #333333
        inactive_workspace #888888 #222222
        urgent_workspace   #ffffff #900000
    }
}
See the
Configuring i3bar
for details.
i3bar alternatives
Some users may prefer panels such as those provided by conventional
Desktop Environments
. This can be achieved within
i3
by launching the panel application of choice during startup.
For example, to use the
Xfce
panel (
xfce4-panel
), add the following line anywhere in
~/.config/i3/config
:
exec --no-startup-id xfce4-panel --disable-wm-check
i3bar can be disabled by commenting the
bar{ }
section of
~/.config/i3/config
, or defining a keybind to toggle the bar:
~/.config/i3/config
# bar toggle, hide or show
bindsym $mod+m bar mode toggle
Replacements independent of the desktop environment are listed below:
polybar
— A fast and easy-to-use tool for creating status bars.
https://github.com/jaagr/polybar
||
polybar
excalibar
— Lightweight yet customizable status bar written in C.
https://github.com/cylgom/excalibar
||
excalibar-git
AUR
i3status
Copy over the default configuration files to the home directory:
$ cp /etc/i3status.conf ~/.config/i3status/config
Not all plugins are defined in the default configuration and some configuration values may be invalid for your system, so they need to be updated accordingly. See
i3status(1)
for details.
i3status replacements
bumblebee-status
— Theme-able Python status bar generator.
https://github.com/tobi-wan-kenobi/bumblebee-status
||
bumblebee-status
AUR
conky
— Highly extensible system monitor. For usage with i3bar see
this tutorial
.
https://github.com/brndnmtthws/conky
||
conky
goblocks
— Fast, lightweight i3status replacement written in Go.
https://github.com/davidscholberg/goblocks
||
goblocks
AUR
goi3bar
— i3status replacement written in Go. Configuration-file driven with several plugins, concurrency options, and rich plugin support.
https://github.com/denbeigh2000/goi3bar/
||
goi3bar-git
AUR
i3blocks
— Extensible via shell scripts. It can handle click events, interrupts, and defining of refresh intervals on a per-block basis.
https://github.com/vivien/i3blocks
||
i3blocks
i3pystatus
— Extensible Python 3 status bar with many plugins and configuration options by default.
https://github.com/enkore/i3pystatus
||
i3pystatus-git
AUR
i3status-rust
— Highly efficient and feature-rich replacement written in Rust. Can handle push updates, individual update intervals, theming and click events.
https://github.com/greshake/i3status-rust
||
i3status-rust
j4status
— Provides a statusline, configurable via plugins, and written in C.
https://sardemff7.github.io/j4status/
||
j4status-git
AUR
ty3status
— i3status replacement written in Typescript. Built with first class support for javascript blocks.
https://github.com/mrkmg/ty3status
||
ty3status-git
AUR
i3status wrappers
i3cat
— A
go
based wrapper which can concatenate inputs from multiple external sources. It can handle click events and forwarding user specified signals to its subprocesses.
https://vincent-petithory.github.io/i3cat/
||
i3cat-git
AUR
py3status
— An extensible i3status wrapper written in Python.
https://github.com/ultrabug/py3status
||
py3status
YaGoStatus
— Yet Another i3status replacement written in Go.
https://github.com/burik666/yagostatus
||
yagostatus-git
AUR
Iconic fonts in the status bar
This article or section is a candidate for merging with
Fonts#Emoji and symbols
.
Notes:
ttf-font-awesome, ttf-font-icons
and
ttf-ionicons
are just samples of symbolic (iconic) fonts, there are nothing related to
i3
with them. (Discuss in
Talk:I3
)
otf-font-awesome
— Scalable vector icons that can be customized with CSS.
https://fontawesome.com/
||
otf-font-awesome
ttf-font-icons
— Non-overlapping and consistently sized mix of Awesome and Ionicons. This also avoids minor overlapping between DejaVu Sans and Awesome.
https://kageurufu.net/icons.pdf
||
ttf-font-icons
AUR
ttf-ionicons
— The premium icon font for Ionic Framework.
https://ionicframework.com/docs/ionicons/
||
ttf-ionicons
AUR
See also
Fonts#Emoji and symbols
.
To combine fonts, define a font fallback sequence in your configuration file, separating fonts with
,
like so:
~/.config/i3/config
bar {
  ...
  font pango:DejaVu Sans Mono, Icons 8
  ...
}
In accordance with
pango syntax
, font size is specified only once, at the end of the comma-separated list of font families. Setting a size for each font would cause all but the last font to be ignored.
Add icons to the format strings in
~/.config/i3status/config
using the unicode numbers given in the cheatsheets linked above. The input method will vary between text editors. For instance, to insert the "heart" icon (unicode number f004):
This article or section is a candidate for merging with
Input method
.
Notes:
Should be described in one place. (Discuss in
Talk:I3
)
in various gui text editors (e.g.
gedit
, Leafpad) and terminals (e.g. GNOME Terminal, xfce4-terminal):
Ctrl+Shift+u
,
f004
,
Enter
in
Emacs
:
C-x
,
8
,
RET
,
f004
,
RET
in
Vim
(while in insert mode):
Ctrl+v
,
uf004
in
urxvt
: while holding
Ctrl+Shift
, type
f004
Terminal emulator
By default when pressing
$mod+Enter
it launches the
i3-sensible-terminal
which is a script that invokes a terminal. See
i3-sensible-terminal(1)
for the order terminals are invoked in.
To instead launch a terminal of choice, modify this line in
~/.config/i3/config
:
bindsym $mod+Return exec i3-sensible-terminal
Alternatively, set the
$TERMINAL
environment variable
.
Disable title click
Add
bindsym button1 nop
to not select a window when you click on its title frame. Useful if your default layout is tabbed and you often miss click i3's tabs instead of something in an application.
Tips and tricks
Jump to opened window
i3ipc-python
— Provides the
/usr/share/doc/python-i3ipc/examples/i3-cycle-focus.py
script which implements
Alt-Tab
functionality for
i3
(see the comments in this script for details).
https://github.com/altdesktop/i3ipc-python
||
python-i3ipc
quickswitch-i3
— Python utility to quickly change to and locate windows in
i3
https://github.com/OliverUv/quickswitch-for-i3/
||
quickswitch-i3
AUR
Rofi
— Switch between windows
https://github.com/davatorium/rofi?tab=readme-ov-file#modes
||
rofi
wmfocus
— Focus and select windows
https://github.com/svenstaro/wmfocus
||
wmfocus
Jump to urgent window
Add to
~/.config/i3/config
:
[1]
bindsym $mod+x [urgent=latest] focus
Save and restore the window layout
i3-wm
provides the
i3-save-tree
script to save and restore workspace layouts. To use it, install its dependency
perl-anyevent-i3
.
Note
This section only provides a quick tutorial on how to save the current window layout of a single workspace and how to restore it for later use. Refer to the
official documentation
for more details.
Save the current window layout of a single workspace
To save the current window layout, follow these steps:
First, execute various commands to open windows in a preferred workspace and resize them if needed. Make sure to write down each executed command for each window.
Now, in a new workspace, open a terminal and run the following:
$ i3-save-tree --workspace N > ~/.config/i3/workspace_N.json
where N is the number of the preferred workspace. This will save the current layout of workspace N to the file
~/.config/i3/workspace_N.json
.
The newly created file needs to be edited by uncommenting the commented lines. This may be done automatically with the following command:
$ sed -i 's|^\(\s*\)// "|\1"|g; /^\s*\/\//d' ~/.config/i3/workspace_N.json
Restore the window layout of the workspace
There are two ways to restore the layout of the workspace: by writing a script, or by editing
~/.config/i3/config
to automatically load the layout. In this section only the first case will be considered, refer to the
official documentation
for the second case.
To restore the saved layout in the previous section, write a file named
load_layout.sh
with the following contents:
The starting lines:
~/load_layout.sh
#!/bin/sh
i3-msg "workspace --no-auto-back-and-forth M; append_layout ~/.config/i3/workspace_N.json"
where M is the number of the workspace in which you would like to load the previously saved layout and N is the number of workspaces saved in the previous section.
And the commands used in the previous section to get the preferred windows, but enclosed in parentheses and with an ampersand appended before the last parentheses.
For example, if the saved layout contained three
uxterm
windows:
~/load_layout.sh
#!/bin/sh

# First we append the saved layout of workspace N to workspace M
i3-msg "workspace --no-auto-back-and-forth M; append_layout ~/.config/i3/workspace_N.json"

# And finally we fill the containers with the programs they had
(uxterm &)
(uxterm &)
(uxterm &)
Then set the file as
executable
. Finally, the layout of workspace N can be loaded onto to workspace M by running:
$ ~/load_layout.sh
Tip
Adding
bindsym $mod+g exec ~/load_layout.sh
to
~/.config/i3/config
and restarting
i3
will bind Mod+g to run the above script.
Note
If the above script does not work properly, refer to the
official documentation
. The
swallows
sections of
~/.config/i3/workspace_N.json
needs to be manually edited.
Scratchpad containers
By default,
scratchpads
only contain a single window. However, containers can also be made a scratchpad.
Create a new container (for example,
Mod+Enter
), split it (
Mod+v
) and create another container. Focus the parent (
Mod+a
), split in the opposite direction (
Mod+h
), and create a container again.
Focus the first container (with focus parent as needed), make the window floating (
Mod+Shift+Space
), and move it to the scratchpad (
Mod+Shift+-
). You can now split containers to preference.
Note
Containers cannot be resized individually in floating windows.  Resize the containers before making windows floating.
Tip
When only using terminal applications, consider a multiplexer such as
tmux
instead.
See also
[2]
for multiple scratchpads.
Screensaver and power management
With
Power management#xss-lock
you can register a screenlocker for your
i3
session. The
-time
option with
xautolock
locks the screen after a given time period:
xautolock -time 10 -locker "i3lock -i
background_image.png
" &
A
systemd
service file can be used to lock the screen before the system is being sent to sleep or hibernation state. See
Power management/Suspend and hibernate#Custom systemd units
. Note that i3lock requires the type of service to be
forking
.
See also
DPMS
.
Another option is to use
xidlehook
AUR
with
betterlockscreen
AUR
or any other screensaver.
xidlehook
is a
xautolock
replacement written in
Rust
, but with a few extra features. This includes the option to disable locking when audio is playing or when the screen is in full screen. The
--timer
option is given in seconds:
xidlehook --not-when-audio --not-when-fullscreen --timer 360 "betterlockscreen -l dim" "" &
Shutdown, reboot, lock screen
Key combinations for shutdown, reboot and screenlock can be added to
~/.config/i3/config
. The below example assumes you have
polkit
installed to allow unprivileged users to run
power management
commands.
set $Locker i3lock && sleep 1

set $mode_system System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown
mode "$mode_system" {
    bindsym l exec --no-startup-id $Locker, mode "default"
    bindsym e exec --no-startup-id i3-msg exit, mode "default"
    bindsym s exec --no-startup-id $Locker && systemctl suspend, mode "default"
    bindsym h exec --no-startup-id $Locker && systemctl hibernate, mode "default"
    bindsym r exec --no-startup-id systemctl reboot, mode "default"
    bindsym Shift+s exec --no-startup-id systemctl poweroff -i, mode "default"

    # back to normal: Enter or Escape
    bindsym Return mode "default"
    bindsym Escape mode "default"
}

bindsym $mod+Pause mode "$mode_system"
Once completed, you will be presented with a prompt whenever you press
$mod+pause
. For more complex behavior, use a separate script, and refer to it in the mode.
[3]
Note
sleep 1
adds a small delay to prevent possible race conditions with suspend
[4]
The
-i
argument for
systemctl poweroff
causes a shutdown even if other users are logged-in (this requires
polkit
), or when
logind
(wrongly) assumes so.
[5]
For a list of alternative screen lockers, see
List of applications/Security#Screen lockers
.
Swallow terminal window
Similarly to
dwm
, i3 can "swallow" the current terminal window with the new GUI window launched from it. This can be done through the use of the
i3-swallow-git
AUR
package.
For example, to let
mpv
's window swallow the originating terminal:
$ swallow mpv
video.mp4
Alternatively, terminal swallowing can be simulated by using a
tabbed or stacked container
in order to hide the terminal window when you are not using it. However, this comes with the drawback of always having a window list at the top of the container.
External displays manual management
Thanks to
xrandr
there are many ways to easily manage systems displays. The below example integrates it in the
i3
configuration file, and behave as the Power Management section above.
Here a laptop with both VGA and HDMI outputs will use a menu selection to switch them On/Off:
## Manual management of external displays
# Set the shortcuts and what they do
set $mode_display Ext Screen (v) VGA ON, (h) HDMI ON, (x) VGA OFF, (y) HDMI OFF
mode "$mode_display" {
    bindsym v exec --no-startup-id xrandr --output VGA1 --auto --right-of LVDS1, mode "default"
    bindsym h exec --no-startup-id xrandr --output HDMI1 --auto --right-of LVDS1, mode "default"
    bindsym x exec --no-startup-id xrandr --output VGA1 --auto --off, mode "default"
    bindsym y exec --no-startup-id xrandr --output HDMI1 --auto --off, mode "default"

    # back to normal: Enter or Escape
    bindsym Return mode "default"
    bindsym Escape mode "default"
}
# Declare here the shortcut to bring the display selection menu
bindsym $mod+x mode "$mode_display"
Any window that is still open in a switched Off display will automatically come back to the remaining active display.
The simplest way to determine names of your devices is to plug the device you wish to use and run:
$ xrandr --query
which will output the available, recognized devices and their in-system names to set your configuration file appropriately.
Refer to the
xrandr
page or
xrandr(1)
for the complete list of available options, the
i3 userguide
and/or the
i3 FAQ on reddit
for more info.
Tabbed or stacked web-browsing
Some web-browsers intentionally do not implement tabs, since managing tabs is considered to be the task of the window manager, not the task of the browser.
To let
i3
manage your tab-less web-browser, in this example for
uzbl
, add the following line to your
~/.config/i3/config
for_window [class="Uzbl-core"] focus child, layout stacking, focus
This is for stacked web browsing, meaning that the windows will be shown vertically. The advantage over tabbed browsing is that the window-titles are fully visible, even if a lot of browser windows are open.
If you prefer tabbed browsing, with windows in horizontal direction ('tabs'), use
for_window [class="Uzbl-core"] focus child, layout tabbed, focus
Workspace variables
As workspaces are defined multiple times in
i3
, assigning workspace variables can be helpful. For example:
set $WS1 term
set $WS2 web
set $WS3 misc
set $WS4 media
set $WS5 code
Then replace workspace names with their matching variables:
bindsym $mod+1          workspace $WS1
...
bindsym $mod+Shift+1    move container to workspace $WS1
See
Changing named workspaces
for more information.
Correct handling of floating dialogs
While dialogs should open in floating mode by default
[6]
, many still open in tiling mode. To change this behaviour, check the dialog's
WM_WINDOW_ROLE
with
xorg-xprop
and add the correct rules to
~/.i3/config
(using
pcre
syntax):
for_window [window_role="About"] floating enable
for_window [window_role="Organizer"] floating enable
for_window [window_role="Preferences"] floating enable
for_window [window_role="bubble"] floating enable
for_window [window_role="page-info"] floating enable
for_window [window_role="pop-up"] floating enable
for_window [window_role="task_dialog"] floating enable
for_window [window_role="toolbox"] floating enable
for_window [window_role="webconsole"] floating enable
for_window [window_type="dialog"] floating enable
for_window [window_type="menu"] floating enable
You can also use title rules and regular expressions:
for_window [title="Preferences$"] floating enable
or
WM_CLASS
:
for_window [class="(?i)mplayer"] floating enable
Network download/upload speed in statusbar
You can use this upstream
script
. Change the
ifaces
variable if necessary, save the script in a suitable place (for example
~/.config/i3/
), make it
executable
and point your
status_command
to it.
Automatically switch horizontal / vertical window split orientation
The
autotiling
package can be used for automatic switching horizontal / vertical window split orientation resulting in a similar behavior to the spiral tiling of bspwm. After installation add the following to your
~/.config/i3/config
and reload i3.
exec_always --no-startup-id
autotiling
Troubleshooting
General
In many cases, bugs are fixed in the development versions
i3-git
AUR
and
i3status-git
AUR
, and upstream will ask to reproduce any errors with this version.
[7]
See also
Debugging/Getting traces#Compilation options
.
Buttons in the i3 message bar do not work
Buttons such as "Edit config" in
i3-nagbar
call
i3-sensible-terminal
, so make sure your
Terminal emulator
is recognized by
i3
.
Faulty line wraps in tiled terminals
i3
v4.3 and higher ignore size increment hints for tiled windows
[8]
. This may cause terminals to wrap lines prematurely, amongst other issues. As a workaround, make the offending window floating, before tiling it again.
Mouse cursor remains in waiting mode
When starting a script or application which does not support startup notifications, the mouse cursor will remain in busy/watch/clock mode for 60 seconds.
To solve this for a particular application, use the
--no-startup-id
parameter, for example:
exec --no-startup-id ~/script
bindsym $mod+d exec --no-startup-id dmenu_run
To disable this animation globally, see
Cursor themes#Create links to missing cursors
.
Unresponsive key bindings
Some tools such as
scrot
may not work when used with a regular key binding (executed after key press). In those cases, execute commands after key release with the
--release
argument
[9]
:
bindsym --release Print exec --no-startup-id scrot
bindsym --release Shift+Print exec --no-startup-id scrot -s
Tearing
i3
does not properly implement double buffering
[10]
hence tearing or flickering may occur. See
picom
, or
TearFree option
of modesetting driver.
Tray icons not visible
The
tray_output primary
directive may require setting a primary output with
xrandr
, specifying the output explicitly or simply removing this directive.
[11]
See
Xrandr
for details. The default configuration created by i3-config-wizard no longer adds this directive to the configuration from
i3
4.12.
Default workspace for Spotify
To assign a default workspace for spotify windows one cannot use the standard route with
assign
and should rather use a
for_window
command, such as
~/.config/i3/config
...
for_window [class="Spotify"] move container to workspace $ws10
To ensure
for_window
does not move the window if already in
$ws10
, one can instead use
move --no-auto-back-and-forth
.
See also
Official website
Funtoo:I3 Tiling Window Manager
i3 Source code
i3-extras
- Collection of scripts and patches
i3ipc-glib
- A library for
i3
extensions
i3ipc-ruby
- An improved library for
i3
extensions in Ruby
j4tools
- non-official tools designed to work with
i3
Online Colorscheme Configurator for i3, i3status
(non-official)
Arch Linux Forums
The i3 thread
- A general discussion about
i3
i3 desktop screenshots and config sharing
Screencasts
i3 window manager v4.1 screencast
i3 window manager v4.1X screencasts