*Before proceeding, be aware that I deprecated this i3 config on August 22nd, 2020, meaning I won’t update it anymore unless I use it again some day in the future. I will keep it on my website though.*
=i3= is a window manager for GNU/Linux which automatically tiles windows in workspaces. This configuration was ade to automatically handle some tasks such as which software allowed where, autostart, and launching software with shortcuts.
The first I do is declaring the modifier key and the alt key —I don’t find the names =Mod1= and =Mod4= to be explicit enough. This will map =$mod= to the Super key (or as some people unfortunately call it, the /Windows/ key) and =$alt= to the Alt key.
Let’s also bind the =$up=, =$down=, =$left= and =$right= variables to respectively the up, down, left, and right arrows on the keyboard. Why bind them to variables? If I ever want to modify the arrow keys to some other keys, like =é=, =a=, =u=, and =i= (the equivalent of =wqsd= on the bépo layout) or =c=, =t=, =s=, and =r= (the equivalent of =hjkl= on the bépo layout), I will just have to modify these four lines.
I’ll also set the =$term= variable. A lot of shortcuts in my i3 config rely on the terminal emulator itself to launch commands in the terminal, and thus call the terminal itself. If I ever need to move from my current terminal, I will just have to change the name of the executable here.
Floating windows are windows that are not tiled with other windows, but rather are free to go anywhere on your screen, with any size. A bit like what you would get with any other non-tiling window manager or desktop environment (though most of them support minimal tiling features).
Let’s declare our floading modyfier. With floating windows, you can move them around by clicking on the window’s borders; but since we don’t have any with this config, we will have instead to press the floating modifier while clicking on the window (anywhere on the window is fine) to move them around.
First of all, I do not want i3 to warp my mouse each time I change windows; my mouse stays where it is.
#+BEGIN_SRC conf
mouse_warping none
#+END_SRC
I also to not want the window focus to follow my mouse, because sometimes I will just knock my physical mouse out of the way of my hand, and when I do that the software mouse will most likely end up in another window I do not want to focus.
While in fullscreen, some software might generate a popup. In that case, I want to be aware of that, and any popup will make me leave fullscreen in order to be presented with said popup.
When changing workspace as described below, we often want to go back to the previous workspace we were working on, but we might not remember immediately which one it was, or we might still have our fingers ready to fire the shortcut which made us make the first workspace change. Hence, if we type the same workspace change shortcut, instead of doing nothing it will bring us back to the previous workspace we were on.
As mentioned in at the beginning of this document, I am using i3-gaps, which brings spacing (gaps) between windows to i3.
First, I want space around my windows only when there are several containers on the same screen, otherwise they will be maximized.
#+BEGIN_SRC conf
smart_gaps on
#+END_SRC
I also do not want to see any window border, so I will be turning this setting off.
#+BEGIN_SRC conf
smart_borders on
#+END_SRC
By the way, the default border is invisible, since it is zero pixels wide.
#+BEGIN_SRC conf
default_border pixel 0
#+END_SRC
Then comes the size of these gaps. I made the outer gap negative so the space between my windows and the border of my screens is smaller than the gap between my containers.
#+BEGIN_SRC conf
gaps inner 20
gaps outer -10
#+END_SRC
Some parameters are also available when it comes to the colors i3 uses. Honestly, we won’t see these colors much, so let’s simply keep the default values.
And although this is not specifically assigning a window to a workspace, I also want to have the tenth workspace assigned to a specific output in case I have two screens — and since this is the case when I am using only one computer, Marpa, I will be using some EmacsLisp in order to generate a different configuration file from this org file depending on the name of the machine.
#+NAME: ws10-output-edp1
#+BEGIN_SRC emacs-lisp
(if (string= system-name "Marpa")
"workspace 10 output eDP-1"
"")
#+END_SRC
Now I’ll call the above code as a noweb reference that should be executed.
I use *A LOT* of shortcuts when it comes to my workflow. Like, all the time. So, expect this chapter to be a bit long, and I’ll try to make it readable still.
Shortcuts are set like so:
#+BEGIN_SRC conf :tangle no
bindsym shortcut command
#+END_SRC
#+NAME: generate-shortcuts
#+BEGIN_SRC emacs-lisp :exports none :var table=[] :tangle no
I have a couple of shortcuts which are related to my terminal. For instance, ~$mod+Return~ opens a regular terminal instance while ~$mod+$alt+M~ opens an SSH instance on my Mila host.
And although this is not really an i3 shortcut per se, I add here the shortcut for launching pywal, which will set one of my wallpapers as the wallpaper and will generate my system’s color configuration from it.
It is possible to indicate to i3 how windows interact with one another, and especially how they are organized by spawning new windows either to the right or below the current window.
Just like windows, it is also possible to change focus between workspaces, because let’s be honest, most people won’t have ten screens to display all ten workspaces at the same time, and frankly that would be impractical.
To close windows, we have two main shortcuts: Alt+F4 and mod+q. The first one is here due to habits, but I don’t really use it anymore due to my main keyboard which doesn’t have any easy access to the functions keys, hence mod+q.
It is possible to change the size of the current window, even if it is a floating one. The first shortcut that might interest you is $mod+f which switches your current window to fullscreen. But to resize a window, you will need to enter the ~resize~ mode.
| $mod+f | fullscreen toggle | Puts the current window in fullscreen or exits it |
| $mod+r | mode "resize" | Enter resize mode |
When it comes to modes, they are defined as follows:
#+BEGIN_SRC conf :tangle no
mode "nameofyourmode" {
here go your shortcuts
}
#+END_SRC
So, all the following shortcuts will be inserted in a mode called ~resize~. Note that not only are the resizing shortcuts bound to the arrow keys, they are also bound to ~ctsr~, which is the bépo equivalent of ~hjkl~.
| $right | resize grow width 20 px or 10 ppt | Increase the width of the current window |
| r | resize grow width 20 px or 10 ppt | Increase the width of the current window |
| $left | resize shrink width 10 px or 5 ppt | Decrease the width of the current window |
| c | resize shrink width 10 px or 5 ppt | Decrease the width of the current window |
| $down | resize grow height 10 px or 5 ppt | Increase the height of the current window |
| t | resize grow height 10 px or 5 ppt | Increase the height of the current window |
| $up | resize shrink height 10 px or 5 ppt | Decrease the height of the current window |
| s | resize shrink height 10 px or 5 ppt | Decrease the height of the current window |
| Return | mode "default" | Return to the default mode |
| Escape | mode "default" | Return to the default mode |
If you prefer, you can think of these shortcuts not as increasing or decreasing the width or height of the current window, but rather as how the bottom or right limit of the windows will be moved relative to the top left corner.
| $mod+Shift+space | floating toggle | Toggles the window between tiled and floating mode |
| $mod+space | focus mode_toggle | Toggles the focus between tiled and floating windows |
| $mod+Ctrl+c | move position center | Centers the focused floating window |
If you want to move around your floating window, you can do it with your mouse while holding down the floating modifier declared [[#Variables_declaration-Floating_windows-897d0c3b][here]].
You can think of i3’s scratchpad as some sort of extra workspace in which you can hide your windows you are not using, or as if you want to reduce a window to the taskbar of other window managers or desktop environments. You have basically two shortcuts for the scratchpad: one that sends the current window to the scratchpad, and one that cicles through the windows sent to the scratchpad and shows them to you sequencially. If you go through all of them, they will be hidden again. You can get a window out of the scratchpad by tiling it to the current workspace with the shortcut described above.
You also have the possibility of making a floating window a sticky window. This means not only will it show on all workspaces, it will also be on top of every other window. It can be useful if you have some notes you want to keep an eye on for instance.
It is possible to dynamically change the gaps between containers if we want to change a bit the appearance of i3. For that, we obviously have some shortcuts.
A big part of my i3 shortcuts though are related to launching various software. I’ll try to sort them by category here, but do take a look even at categories which you might not be interested in, they might actually have something useful for you.
These commands will allow the user to launch applications which provide ~.desktop~ files or user-defined ~.desktop~ files, as well as commands with the help of rofi.
Here we have four commands for managing our screen’s brightness (this is useful for laptops, not so much with desktops), and two of them are actually duplicates of the other two in case a laptop doesn’t have dedicated keys or we are using a keyboard which doesn’t provide them.
Some shortcuts are dedicated to media control, especially when it comes to controlling music. All of these media control shortcuts will be calls to ~mpc~ which will in turn send commands to ~mpd~, which is the music server I use on my computers.
Additionally, we have a shortcut for entering presentation mode on the additional screen of the computer; on my main computer, Mila, the additional screen is HDMI-1, while it is VGA1 on my travel laptop. We’ll use some Emacs Lisp to determine on the configuration file export which screens names to use.
My travel laptop has a fingerprint reader which can be used as an authentification method when the root password is asked. Let’s launch our policy kit manager if that is the case: