What do you think? Discuss, post comments, or ask questions at the end of this article [More about me]

Skip to end of metadata
Go to start of metadata

I'm a big fan of i3 (tiling window manager for Linux).  I'm also a big fan of Arch and the user-friendly Manjaro Linux (which is based on Arch).  Put these together (i3 + Manjaro) and you get Manjaro i3 (Community Edition): a very nice distro with a well implemented i3wm environment (by default).

Tiling window managers do have a fairly steep learning curve, but dang, in terms of efficiency and managing many windows and tasks at once, you just can't beat a tiling window manager (for me anyway).

The below is a guide mostly just for me and covers some setup notes for my Manjaro i3 systems. 

The below guide was written largely for me and covers some setup notes for my Manjaro i3 systems. It might not work directly on your system as it depends (somewhat) on other applications I install/use (these are also outlined in the the guide below). In other words YMMV - and expect to have to modify the below to suit your needs.

Note: for brevity I'm going to refer to my Manjaro i3 system as Mi3 below.

Guide

Turn on firewall

Let's first enable the firewall (here we're using ufw):

sudo systemctl enable ufw
sudo ufw enable

We can set firewall config via the gufw:

sudo gufw

Enable TRIM for SSD

If you have an SSD, I'd suggest enabling the fstrim.timer service for TRIM.

See Enable periodic TRIM - including on a LUKS partition.

Trackpad setup

With i3 my hands hardly leave the keyboard and almost never reach for the mouse.  As such, I generally use my touchpad.  My preference is to disable mouse tapping, use 'natural scrolling' and disable 'horizontal scrolling'.  Although you can set all these settings using Manjaro i3's bmenu (mod+ctrl+b, and choose 'Hardware and drivers' → 'Configure touchpad'), these settings will not survive a reboot.

If you use libinput

To make these settings permanent, you can either add them to your .i3/config file, or set the options in /etc/X11/xorg.conf.d/30-touchpad.conf.  We're going to do the latter.  Edit the file using your preferred editor.  Below is an example of the settings I prefer.

/etc/X11/xorg.conf.d/30-touchpad.conf
Section "InputClass"
    Identifier "touchpad"
    Driver "libinput"
    MatchIsTouchpad "on"
    Option "Tapping" "off"
    Option "NaturalScrolling" "true"
    Option "HorizontalScrolling" "false"
EndSection

If you use (or prefer) xf86-input-synaptics

So, you can use the older arch synaptics driver instead of the newer libinput drivers.  Note that the synaptics driver is deprecated and hasn't been updated since 2012.  Having said that, on my Metabox P650RS-G the synaptics driver just feels better (the libinput drivers feel a bit "floaty", and not as responsive - I've yet to play around with it's config to improve the feel).

Let's first install the driver with pacman

sudo pacman -S xf86-input-synaptics

Once pacman installs, you'll need to copy /usr/share/X11/xorg.conf.d/70-synaptics.conf to the /etc/X11/xorg.conf.d

sudo cp /usr/share/X11/xorg.conf.d/70-synaptics.conf /etc/X11/xorg.conf.d

Now let's backup and then remove the current libinput touchpad conf file (which in my case was 30-touchpad.conf).

sudo mv 30-touchpad.conf 30-touchpad.conf.backup

I prefer natural scrolling with the touchpad, so let's modify 70-synaptics.conf to add this (note this is taken direclty from the official arch synaptics page):

Section "InputClass"
    Identifier "touchpad catchall"
    Driver "synaptics"
    MatchIsTouchpad "on"
	...
    Option "VertScrollDelta" "-111"
	Option "HorizScrollDelta" "-111"
...
EndSection

Note you'll need to reboot or restart X for the changes to take place.

Volume control

On all my laptops, I've been able to control volume with the standard volume up/down/mute keys (e.g. fn+f1 etc.) by installing volumeicon with

sudo pacman -S volumeicon

Once installed you'll need to add the following to your i3 config:

exec --no-startup-id volumeicon

Disable "beep" sound in terminal application

On one of my machines there was a very annoying "beep" sound that played whenever I did stuff (like hitting backspace too much in the terminal).  This got annoying pretty quickly.

I couldn't find a setting to disable this.  After some research it appears to be an X11 session property which can be disabled by running the following from terminal:

xset -b

You can make this stick after reboot by editing /etc/xprofile or ~/.xprofile (user specific setting) and adding the above command to either file.  If either file does not exist just create one.

Fixing Screen tearing (with Picom)

On Arch the Compton composite manager was recently renamed to Picom.  This article has been updated to reflect this. 

This requires the picom package to be installed (and active).  If you don't have this installed, do:

sudo pacman -S picom

To activate it from i3wm, add this line to your i3 config:

exec --no-startup-id picom -b

On one my laptops (Thinkpad e480) there was noticable screen tearing with picom enabled.  To eliminate the screen tearing found there were several tweaks needed to the ~/.config/picom.conf configuration file.  Below are the changes needed (note you'll need to replace the original settings below with these ones):

backend = "glx";
...
vsync = "opengl-swc";

Fixing QT5 applications (like VLC) UI scaling (if icons, fonts are too big)

On my Mi3 setup, I noticed that QT5 applications like VLC had huge icons and fonts were all messed up.  Now, I don't have a HiDPI screen (screen resolution is 1920x1080) but still had this issue.  Here's what ended up fixing this for me:

Add the following lines to your .profile:

export QT_QPA_PLATFORMTHEME="qt5ct"
export QT_AUTO_SCREEN_SCALE_FACTOR=0 
export QT_SCALE_FACTOR=1 

Restart then open up (install if not already installed) qt5ct (run from terminal).  Change settings and font to size 10 of some look that you like.  Here's settings that I quite like:

Hibernate (suspend to disk)

I sometimes prefer to hibernate my system, but unfortunately on one of my machines hibernation wasn't working.

See Use a swap file and enable hibernation on Arch Linux - including on a LUKS root partition.

Stop 2018 Razer Blade 15 waking right after sleep

One of my (nicer) machines (Razer Blade 15) wouldn't sleep, or at least stay asleep (kind of like my kids...).  It would immediately wake after trying to sleep.  Apparently, it's caused by the USB 3.0 chip used on the machine.

You can fix this by running (see Arch wiki here):

echo XHC | sudo tee /proc/acpi/wakeup

However, this needs to be run after every startup.  Let's use systemd to run this as a service.

First, create a service file by:

sudo nano /etc/systemd/system/xhc-sleep.service

and paste the following:

[Unit]
Description=Workaround for razer blade 15 waking after sleeping (USB 3.0 causing).

[Service]
ExecStart=echo XHC | tee /proc/acpi/wakeup

[Install]
WantedBy=multi-user.target

Now, let's enable and start the service:

sudo systemctl enable xhc-sleep.service
sudo systemctl start xhc-sleep.service

Note, even with this, after first starting up and then (the first) sleep - my machine wakes up immediately (unless I close my lid, which makes it stay asleep).  After that first "wake-up" it will now sleep properly (i.e. not wakeup automatically).

Stop 2019 Razer Blade 15 infinite suspend loop

On my 2019 Razer Blade 15, it would wake from suspend correctly on the first suspend after a boot.  Thereafter when it woke it would, after about 10 seconds, sleep again ad infinitum.

The ArchWiki gives the workaround for this issue in the form of a kernel parameter:

append the following kernel parameter to the GRUB_CMDLINE_LINUX_DEFAULT line in /etc/default/grub:

button.lid_init_state=open

After appending if should look something like line 4 in:

GRUB_DEFAULT=saved
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR='Manjaro'
GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=UUID=f68ed3c5-da10-4288-890f-b83d8763e85e nvidia-drm.modeset=1 button.lid_init_state=open"
GRUB_CMDLINE_LINUX=""

# If you want to enable the save default function, uncomment the following
# line, and set GRUB_DEFAULT to saved.
GRUB_SAVEDEFAULT=true
...

Save the changes and then run:

sudo update-grub

Set default applications

We can generally set default (or preferred applications) in Mi3 by using the morec_menu (mod+z).  Navigate with mod+z → settings → preferred applications.  However, in my case, even setting my preferred browser to chrome (or chromium) didn't stick.

What did work though was modifying the ~/.config/mimeapps.list and replacing the default userapp-Pale Moon.desktop reference with google-chrome.desktop.

Alternatively, you can set the default http and https xdg-mime applications with:

xdg-mime default <browser>.desktop x-scheme-handler/http
xdg-mime default <browser>.desktop x-scheme-handler/https

where you can replace <browser> with you installed browser (e.g. pale-moon, firefox, chromium etc.).

Unlocking gnome-keyring on login

On many DEs that use gnome-keyring to securely store credentials (like usernames and passwords) they will automatically unlock the the keyring when logging in.  On i3... not so much.

To get i3 to successfully unlock your keyring on login, you'll need to use the method outlined here.

Edit /etc/pam.d/login and add the following two lines:

auth       optional     pam_gnome_keyring.so
session    optional     pam_gnome_keyring.so auto_start

After a restart (or logout/login) your gnome keyring should be unlocked.

Ricing (theming) and modifying i3

One of the beauties with i3 (and Linux in general) is that you can you modify your environment to suit how you like to work.  This is particularly true with i3 where you can modify not only how it looks but also how it behaves.

i3 makes this quite easy by providing a single config file where most changes can be made (~/.i3/config). 

Below is a copy of my config file that I usually implement to make the interface more appealing (to me).  Note the visual changes in my config are chosen to go along with the numix gtk theme (install with sudo pacman -S numix-gtk-theme).  It looks like this (screenshot running chrome, watching some netflix, and working in urxvt):


Note you don't have to be using manjaro-i3 to use this config.  If you're using stock Manjaro (or Arch) please ensure you have at least the following packages installed: i3-wm (or i3-gaps if you want dem' gaps), i3exit, i3status, py3status, and picom.  You can install all these packages with:

sudo pacman -S i3-wm i3exit i3status py3status picom

My config file:

Note that this config file contains other modifications that I prefer in my i3 setup, such as:

  • define mod_next at top of file: used throughout config, e.g.  mod=Mod1 (i.e. super), mod_next=Mod4 (i.e. alt)
  • conky config files (see following section)
  • also using rofi (sudo pacman -S rofi) for both window listing (mod+Tab) and as a launcher (mod+d);
  • using py3status instead of i3status (sudo pacman -S py3status);
  • change split h/v keys to mod+z|x (alternatively mod+mod_next+q|e)
  • using mod_next+u|i|o|p|[ keys for various apps (like launching pamac, chromium, bitwarden, putty, nautilus);
  • added resizing windows without needing resize mode and disabled resizing mode.  Can also use vim style keys here;
  • changes to container and splitting shortcuts; 
  • mod+mod_next+z, mod+mod+next+x increases/decreases current window transparency needs transset-df (sudo pacman -S transset-df);
  • sticky window toggle set to (mod+ctrl+s);
  • added "netflix" and "spotify" window settings (mod+mod_next+n, mod+mod_next+m);
  • added "redshift" mode (mod_next+r) to help my old ninja eyes...

I have several bindsyms that use integrated bash scripts (i.e. not external but explicitly defined in my i3 config) which depend on xdotool. Please ensure you have xdotool installed, e.g. do "pacman -S xdotool"

You'll note that I (perhaps peculiarly) use mod=Mod1 (super key) and mod_next=Mod4 (alt) instead of just using a single key mod key.  I thought I would briefly explain the reason why:

At work I'm in a rather peculiar environment where I usually have to work on a base windows environment (which I really only use for email) and then remote desktop into a variety of Linux desktops and dev environments (either running i3 or no gui at all).  As such, Super+L locks the host windows machine (which behaviour I am not permitted to change).

Hence, by necessity, I've moved to alt as the default mod key (since I'm a die-hard vim key fan), and now use the super key for mostly launching applications etc.  On my home machines I'm under no such restrictions (and just run straight Linux environments).  I did try to get used to two different configs (one at work and one at home) but my muscle memory didn't like that so I settled on the current config which I'm now used to.

Contents of my ~/.i3/config
# i3 config file (v4)
# Please see http://i3wm.org/docs/userguide.html for a complete reference!

# MISC. SETTERS
# Set mod key ($mod_next=<Alt>, Mod4=<Super>)
set $mod Mod1
set $mod_next Mod4
set $border_no_name border pixel 5
set $border_normal border normal 5

# Theme colors
# set variable for main accent color
#set $acolor #eb564d
set $acolor #d64161

# set other colors
set $bgicolor #00979E
set $bgucolor #6a6868
set $txtacolor #F9FAF9
set $txtucolor #bdbbbb
set $indcolor #4deb56

# class                   border  backgr. text    indic.   child_border
client.focused          $acolor $acolor $txtacolor $indcolor $acolor
client.focused_inactive $bgicolor $bgicolor $txtacolor $indcolor $bgicolor
client.unfocused        $bgucolor $bgucolor $txtucolor $indcolor $bgucolor
#client.urgent           #CB4B16 #FDF6E3 #CB4B16 $indcolor
#client.placeholder      #000000 #0c0c0c $txtacolor #000000
#client.background       #2B2C2B

# set default desktop layout (default is tiling) <default|stacking|tabbed>
workspace_layout stacking

# set preferred focus_wrapping <yes|no|force>
#focus_wrapping no

# Configure border style <normal|1pixel|pixel xx|none|pixel>
for_window [class=".*"] $border_no_name

# Hide borders <none|vertical|horizontal|both|smart>
hide_edge_borders none

# set popup behaviour during full screen <smart|ignore|leave_fullscreen>
popup_during_fullscreen leave_fullscreen

# change borders
bindsym $mod+period $border_no_name
bindsym $mod+$mod_next+period $border_normal
bindsym $mod+$mod_nextShift+period border none

# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
#font pango:monospace 8
font xft:BitstreamVeraSans-Roman 11

# Use Mouse+$mod to drag floating windows
floating_modifier $mod

# Autostart applications
exec --no-startup-id "xkbset exp =m; xkbset m"
exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
#exec --no-startup-id alttab -pk h -nk l -fg "#d58681" -bg "#4a4a4a" -frame "#eb564d" -t 128x150 -i 127x64
exec --no-startup-id conky -c ~/.config/conky
exec --no-startup-id conky -c ~/.config/conky_shortcuts
exec --no-startup-id copyq
exec --no-startup-id fcitx -d
exec --no-startup-id nitrogen --restore
exec --no-startup-id nm-applet
exec --no-startup-id xautolock -time 10 -locker blurlock
exec --no-startup-id xfce4-power-manager
exec --no-startup-id "pkill -9 redshift; redshift -P -t 5000:4000"
exec --no-startup-id polychromatic-tray-applet
set $picom_start "pkill picom; sleep 1; picom -b"
exec_always --no-startup-id $picom_start
exec_always --no-startup-id ff-theme-util
exec_always --no-startup-id fix_xcursor
exec_always --no-startup-id optimus-manager-qt

# kill focused window
bindsym $mod+Shift+q kill

# start program launcher
#bindsym $mod+d exec --no-startup-id dmenu_recency
bindsym $mod_next+d exec --no-startup-id "rofi -show-icons -modi windowcd,window,drun -show drun"
bindsym $mod_next+Return exec --no-startup-id "rofi -show-icons -modi windowcd,window,drun -show drun"
bindsym $mod_next+Tab exec --no-startup-id "rofi -show-icons -modi windowcd,window,drun -show window"

# launch categorized menu
#bindsym $mod+c exec --no-startup-id morc_menu

################################################################################################
## sound-section - DO NOT EDIT if you wish to automatically upgrade Alsa -> Pulseaudio later! ##
################################################################################################

exec --no-startup-id volumeicon
#bindsym $mod+Ctrl+m exec terminal -e 'alsamixer'
#exec --no-startup-id pulseaudio
#exec --no-startup-id pa-applet
#bindsym $mod+Ctrl+m exec pavucontrol

################################################################################################

# Increase/decrease sink volume 1
bindsym $mod+F1 exec amixer -qD pulse set Master toggle; exec notify-send 'sound toggled'
bindsym $mod+F2 exec amixer -qc 0 set Master 2db-; exec notify-send 'volume decreased'
bindsym $mod+F3 exec amixer -qc 0 set Master 2db+; exec notify-send 'volume increased'

# Screen brightness controls
#bindsym $mod+F8 exec sudo xbacklight -10
bindsym $mod+F8 exec "sleep 1; xset dpms force off"
bindsym $mod+F9 exec sudo xbacklight +10

# focus_follows_mouse no

# hjkl focus
bindsym $mod+h focus left
bindsym $mod+j focus down
bindsym $mod+k focus up
bindsym $mod+l focus right

# master-stack keybinding (moves stack window to master and current master back to stack window)
bindsym $mod+m exec "i3-msg \\"focus left, move right, focus up, move left\\""
bindsym $mod+Shift+m exec "i3-msg \\"move right, focus up, move left\\""
bindsym $mod+comma exec "i3-msg \\"focus up, move right, focus up, focus left\\""
bindsym $mod+Shift+comma exec "i3-msg \\"focus up, move right, focus left\\""

# container focusing (with fallback for case where window is direct child of workspace container)
# NOTE: requires xdotool
#bindsym $mod+Ctrl+h exec "WINDOW=$(xdotool getactivewindow); i3-msg \\"focus parent; focus left; focus child\\"; NEW_WINDOW=$(xdotool getactivewindow); if [ \\"$NEW_WINDOW\\" -eq \\"$WINDOW\\" ]; then i3-msg \\"focus left\\"; fi"
#bindsym $mod+Ctrl+j exec "WINDOW=$(xdotool getactivewindow); i3-msg \\"focus parent; focus down; focus child\\"; NEW_WINDOW=$(xdotool getactivewindow); if [ \\"$NEW_WINDOW\\" -eq \\"$WINDOW\\" ]; then i3-msg \\"focus down\\"; fi"
#bindsym $mod+Ctrl+k exec "WINDOW=$(xdotool getactivewindow); i3-msg \\"focus parent; focus up; focus child\\"; NEW_WINDOW=$(xdotool getactivewindow); if [ \\"$NEW_WINDOW\\" -eq \\"$WINDOW\\" ]; then i3-msg \\"focus up\\"; fi"
#bindsym $mod+Ctrl+l exec "WINDOW=$(xdotool getactivewindow); i3-msg \\"focus parent; focus right; focus child\\"; NEW_WINDOW=$(xdotool getactivewindow); if [ \\"$NEW_WINDOW\\" -eq \\"$WINDOW\\" ]; then i3-msg \\"focus right\\"; fi"

# move focused window
bindsym $mod+Shift+Left move left 100px
bindsym $mod+Shift+Down move down 100px
bindsym $mod+Shift+Up move up 100px
bindsym $mod+Shift+Right move right 100px

# hjkl move
bindsym $mod+Shift+h move left 100px
bindsym $mod+Shift+j move down 100px
bindsym $mod+Shift+k move up 100px
bindsym $mod+Shift+l move right 100px

# workspace back and forth (with/without active container)
workspace_auto_back_and_forth yes
bindsym $mod+Shift+b move container to workspace back_and_forth; workspace back_and_forth

# Set $con_title (embedded script) - used in split orientations below.
# Three options for container title_format below (comment out one).  
# - the first option give a simple oblique title format (which I prefer).
# - the second option uses application window title (but colored and bolded) that was selected when the container was created.
# - the third option simply uses "CONTAINER" window title - you can then use $mod+slash to set a custom name 
# NOTE1: Comment out all options to use default container title_format.
# NOTE2: requires xdotool.
#
#set $con_title i3-msg focus parent, title_format \\"<span font_style='oblique'><tt> <u>%title</u></tt></span>\\", focus child
#set $con_title i3-msg focus parent, title_format \\"<span foreground='#FEC196'><b>📦 %title</b></span>\\", focus child
#set $con_title ANSWER=$(xdotool getwindowfocus getwindowname); i3-msg focus parent, title_format \\"<span foreground='#FEC196'><b> ⮡\\"$ANSWER\\"</b></span>\\", focus child
#set $con_title i3-msg focus parent, title_format \\"<span foreground='#FEC196'><b>📦 <tt><u>\\$mod+/</u></tt> to change container title</b></span>\\", focus child


# dynamic renaming of parent container
bindsym $mod+slash exec "ANSWER=$(zenity --title=\\"i3-msg title_format\\" --text \\"Change %title for parent container\\" --entry); if [ -n \\"$ANSWER\\" ]; then i3-msg focus parent, title_format \\"<span font_style='oblique'> <u><tt>$ANSWER</tt></u></span>\\", focus child; fi"
bindsym $mod+$mod_next+slash focus parent, title_format "<span font_style='oblique'> <u><tt>%title</tt></u></span>", focus child
bindsym $mod+Ctrl+w exec "WINDOWS=$(xdotool search --all --onlyvisible --desktop $(xprop -notype -root _NET_CURRENT_DESKTOP | cut -c 24-) \\"\\" 2>/dev/null); for window in $WINDOWS; do xdotool windowactivate $window; i3-msg \\"split h; layout tabbed\\"; $con_title; done"
bindsym $mod+$mod_next+Ctrl+w exec "WINDOWS=$(xdotool search --all --onlyvisible --desktop $(xprop -notype -root _NET_CURRENT_DESKTOP | cut -c 24-) \\"\\" 2>/dev/null); for window in $WINDOWS; do xdotool windowactivate $window; i3-msg \\"move left\\"; $con_title; done"

# container layouts
bindsym $mod+w layout tabbed
bindsym $mod+q layout splith
bindsym $mod+e layout splitv
bindsym $mod+s layout stacking

# child container layouts (creates a child container from current selected application)
bindsym $mod+z split h; exec "$con_title"
bindsym $mod+x split v; exec "$con_title"
bindsym $mod+c layout toggle

# alternate container layout bindsyms
bindsym $mod+$mod_next+q split h; exec "$con_title"
bindsym $mod+$mod_next+e split v; exec "$con_title"
bindsym $mod+$mod_next+w split h; layout tabbed; exec "$con_title"
bindsym $mod+$mod_next+s split h; layout stacked; exec "$con_title"

# toggle fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle
bindsym $mod+shift+f exec "i3-msg focus parent, fullscreen toggle, focus child"
bindsym --whole-window $mod+button8 fullscreen toggle

# several 16:9 resolutions binded for quick switching
bindsym $mod+bracketright exec xrandr -s 1280x720
bindsym $mod+backslash exec xrandr -s 1920x1080

# toggle tiling / floating focus
bindsym $mod+Shift+space floating toggle

# change focus between tiling / floating windows
bindsym $mod+Tab focus mode_toggle

# toggle sticky
bindsym $mod+Ctrl+s sticky toggle;exec notify-send 'sticky windows toggled'

# window transparency adjustment (and alias to restart picom)
bindsym $mod+$mod_next+z exec transset-df -a --min 0.20 --dec 0.20
bindsym $mod+$mod_next+Shift+z exec transset-df -a --min 0.1 --dec 0.1
bindsym $mod+$mod_next+Ctrl+z exec "WINDOWS=$(xdotool search --all --onlyvisible --desktop $(xprop -notype -root _NET_CURRENT_DESKTOP | cut -c 24-) \\"\\" 2>/dev/null); for window in $WINDOWS; do xdotool windowactivate $window; transset-df -a --min 0.20 --dec 0.20; done"
bindsym $mod+$mod_next+x exec transset-df -a --inc 0.20 --max 0.99
bindsym $mod+$mod_next+Shift+x exec transset-df -a --inc 0.1 --max 0.99
bindsym $mod+$mod_next+Ctrl+x exec "WINDOWS=$(xdotool search --all --onlyvisible --desktop $(xprop -notype -root _NET_CURRENT_DESKTOP | cut -c 24-) \\"\\" 2>/dev/null); for window in $WINDOWS; do xdotool windowactivate $window; transset-df -a --inc 0.20 --max 0.99; done"
bindsym $mod+$mod_next+c exec --no-startup-id $picom_start

# window dimming enable or disable (uses xdotool and xprop to set a anti-dim flag, which picom recognises in focus-exclude array) 
bindsym $mod+$mod_next+a exec xprop -id $(xdotool getactivewindow) -f ANTIDIM_FLAG 8c -set ANTIDIM_FLAG 1; exec notify-send 'anti-dim set on window'
bindsym $mod+$mod_next+d exec xprop -id $(xdotool getactivewindow) -remove ANTIDIM_FLAG; exec notify-send 'dim set on window'

# focus the parent container
bindsym $mod+a focus parent
bindsym $mod+Shift+a focus child

# move the currently focused window to the scratchpad
bindsym $mod+Shift+Tab move scratchpad

# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym $mod+minus scratchpad show

#navigate workspaces next / previous
bindsym $mod+Ctrl+Right workspace next
bindsym $mod+Ctrl+Left workspace prev

# Workspace names
# to display names or symbols instead of plain workspace numbers you can use
# something like: set $ws1 1:mail
#                 set $ws2 2:
set $ws1 1
set $ws2 2
set $ws3 3
set $ws4 4
set $ws5 5
set $ws6 6
set $ws7 7
set $ws8 8

# switch to workspace
bindsym $mod+1 workspace $ws1
bindsym $mod+2 workspace $ws2
bindsym $mod+3 workspace $ws3
bindsym $mod+4 workspace $ws4
bindsym $mod+5 workspace $ws5
bindsym $mod+6 workspace $ws6
bindsym $mod+7 workspace $ws7
bindsym $mod+8 workspace $ws8

# Move focused container to workspace
bindsym $mod+Shift+1 move container to workspace $ws1
bindsym $mod+Shift+2 move container to workspace $ws2
bindsym $mod+Shift+3 move container to workspace $ws3
bindsym $mod+Shift+4 move container to workspace $ws4
bindsym $mod+Shift+5 move container to workspace $ws5
bindsym $mod+Shift+6 move container to workspace $ws6
bindsym $mod+Shift+7 move container to workspace $ws7
bindsym $mod+Shift+8 move container to workspace $ws8

# Move focused container to workspace, and switch to that workspace
bindsym $mod+$mod_next+1 move container to workspace $ws1; workspace $ws1
bindsym $mod+$mod_next+2 move container to workspace $ws2; workspace $ws2
bindsym $mod+$mod_next+3 move container to workspace $ws3; workspace $ws3
bindsym $mod+$mod_next+4 move container to workspace $ws4; workspace $ws4
bindsym $mod+$mod_next+5 move container to workspace $ws5; workspace $ws5
bindsym $mod+$mod_next+6 move container to workspace $ws6; workspace $ws6
bindsym $mod+$mod_next+7 move container to workspace $ws7; workspace $ws7
bindsym $mod+$mod_next+8 move container to workspace $ws8; workspace $ws8

# Open applications on specific workspaces
# assign [class="Thunderbird"] $ws1
# assign [class="Pale moon"] $ws2
# assign [class="Pcmanfm"] $ws3
# assign [class="Skype"] $ws5

# Open specific applications in floating mode
for_window [class=".*"] title_format " %title"
for_window [class="(?i)Gcolor3"] floating enable border pixel 1
for_window [class="(?i)Gnome-calculator"] floating enable
for_window [class="(?i)Kupfer"] border none
for_window [class="(?i)System-config-printer.py"] floating enable border normal
for_window [class="(?i)arandr"] floating enable
for_window [class="Calamares"] floating enable border normal
for_window [class="Clipgrab"] floating enable
for_window [class="Galculator"] floating enable border pixel 1
for_window [class="Lightdm-gtk-greeter-settings"] floating enable
for_window [class="Lxappearance"] floating enable sticky enable border normal
for_window [class="Manjaro Settings Manager"] floating enable border normal
for_window [class="Manjaro-hello"] floating enable
for_window [class="Qtconfig-qt4"] floating enable sticky enable border normal
for_window [class="Shutter"] floating disable
for_window [class="Simple-scan"] floating enable border normal
for_window [class="Thus"] floating enable border normal
for_window [class="Timeset-gui"] floating enable border normal
for_window [class="Xfburn"] floating enable
for_window [class="copyq"] floating enable border pixel 1
for_window [class="octopi"] floating enable
for_window [class="qt5ct"] floating enable sticky enable border normal
for_window [class="spectacle"] floating disable
for_window [title="About Pale Moon"] floating enable
for_window [title="File Transfer*"] floating enable
for_window [title="MuseScore: Play Panel"] floating enable
for_window [title="alsamixer"] floating enable border pixel 1
for_window [class="(?i)^timeshift-gtk$"] floating disable
for_window [class="(?i)^gnome-calculator$"] floating disable

# Application shortcuts
bindsym $mod+Return exec i3-sensible-terminal
bindsym Print exec --no-startup-id i3-scrot
bindsym $mod+Ctrl+x --release exec --no-startup-id xkill

# shortcuts to often used applications
bindsym $mod_next+u exec --no-startup-id pamac-manager
bindsym $mod_next+i exec --no-startup-id brave
bindsym $mod_next+o exec --no-startup-id xfce4-appfinder
bindsym $mod_next+p exec --no-startup-id putty
bindsym $mod_next+bracketleft exec --no-startup-id nautilus

#sm-player shortcuts (e.g. for use if send smplayer to scratchpad)
bindsym $mod_next+Shift+space exec --no-startup-id smplayer -send-action pause
bindsym $mod_next+Shift+h exec --no-startup-id smplayer -send-action rewind1
bindsym $mod_next+Shift+l exec --no-startup-id smplayer -send-action forward1

# switch to workspace with urgent window automatically
for_window [urgent=latest] focus

# reload the configuration file
bindsym $mod+Ctrl+c reload

# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym $mod+Ctrl+r restart

bindsym $mod_next+l exec i3exit lock

# exit i3 (logs you out of your X session)
#bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"

# Set shut down, restart and locking features
bindsym $mod+0 mode "$mode_system"
set $mode_system (l)ock, (e)xit, switch_(u)ser, (Shift+s)uspend, (s)uspend+lock, (h)ibernate, (Shift+h)ibernate+lock, (r)eboot, shut(d)own
mode "$mode_system" {
    bindsym l exec --no-startup-id i3exit lock, mode "default"
    bindsym Shift+s exec --no-startup-id i3exit suspend, mode "default"
    bindsym s exec --no-startup-id "i3exit lock; i3exit suspend", mode "default"
    bindsym u exec --no-startup-id i3exit switch_user, mode "default"
    bindsym e exec --no-startup-id i3exit logout, mode "default"
    bindsym h exec --no-startup-id i3exit hibernate, mode "default"
    bindsym Shift+h exec --no-startup-id "i3exit lock; i3exit hibernate", mode "default"
    bindsym r exec --no-startup-id i3exit reboot, mode "default"
    bindsym d exec --no-startup-id i3exit shutdown, mode "default"

    # exit system mode: "Enter" or "Escape"
    bindsym Return mode "default"
    bindsym Escape mode "default"
}

# Lock screen
bindsym $mod+Home exec --no-startup-id i3exit lock, mode "default"
bindsym $mod+F12 exec --no-startup-id i3exit suspend, mode "default"

## Resize window (you can also use the mouse for that)
#bindsym $mod+r mode "resize"
#mode "resize" {
        ## These bindings trigger as soon as you enter the resize mode
        ## Pressing left will shrink the window’s width.
        ## Pressing right will grow the window’s width.
        ## Pressing up will shrink the window’s height.
        ## Pressing down will grow the window’s height.
        #bindsym l resize shrink width 5 px or 5 ppt
        #bindsym j resize grow height 5 px or 5 ppt
        #bindsym k resize shrink height 5 px or 5 ppt
        #bindsym semicolon resize grow width 5 px or 5 ppt

        ## same bindings, but for the arrow keys
        #bindsym Left resize shrink width 10 px or 10 ppt
        #bindsym Down resize grow height 10 px or 10 ppt
        #bindsym Up resize shrink height 10 px or 10 ppt
        #bindsym Right resize grow width 10 px or 10 ppt

        ## exit resize mode: Enter or Escape
        #bindsym Return mode "default"
        #bindsym Escape mode "default"
#}

# arrow key resizing without resize mode
bindsym $mod+$mod_next+Left resize shrink width 50 px or 5 ppt
bindsym $mod+$mod_next+Down resize grow height 50 px or 5 ppt
bindsym $mod+$mod_next+Up resize shrink height 50 px or 5 ppt
bindsym $mod+$mod_next+Right resize grow width 50 px or 5 ppt
bindsym $mod+$mod_next+Shift+Left resize shrink width 100 px or 10 ppt
bindsym $mod+$mod_next+Shift+Down resize grow height 100 px or 10 ppt
bindsym $mod+$mod_next+Shift+Up resize shrink height 100 px or 10 ppt
bindsym $mod+$mod_next+Shift+Right resize grow width 100 px or 10 ppt

# hkjl resize
bindsym $mod+$mod_next+h resize shrink width 50 px or 5 ppt
bindsym $mod+$mod_next+j resize grow height 50 px or 5 ppt
bindsym $mod+$mod_next+k resize shrink height 50 px or 5 ppt
bindsym $mod+$mod_next+l resize grow width 50 px or 5 ppt
bindsym $mod+$mod_next+Shift+h resize shrink width 100 px or 10 ppt
bindsym $mod+$mod_next+Shift+j resize grow height 100 px or 10 ppt
bindsym $mod+$mod_next+Shift+k resize shrink height 100 px or 10 ppt
bindsym $mod+$mod_next+Shift+l resize grow width 100 px or 10 ppt

# predefined sizes (70/30)
bindsym $mod+$mod_next+u resize set width 40 ppt
bindsym $mod+$mod_next+i resize set width 50 ppt
bindsym $mod+$mod_next+o resize set width 60 ppt

# "netflix" and "spotify" modes
bindsym $mod+$mod_next+n floating enable;sticky enable; move position 1300px 708px resize set 612 343;border none
bindsym $mod+$mod_next+m floating enable;sticky enable; resize set 791 70;border none
bindsym $mod+$mod_next+Shift+m resize set height 64; border none

# redshift modes
bindsym $mod_next+r mode "$mode_redshift"
set $mode_redshift Set colour temperature: (a)uto, (r)eset, (2)500K, (3)000K, (4)000K, (5)000K
set $kill_redshift pkill -9 redshift;
mode "$mode_redshift" {
    bindsym a exec --no-startup-id "$kill_redshift redshift -P -t 5000:4000", mode "default"
    bindsym r exec --no-startup-id "$kill_redshift redshift -x", mode "default"
    bindsym 2 exec --no-startup-id "$kill_redshift redshift -P -O 2500", mode "default"
    bindsym 3 exec --no-startup-id "$kill_redshift redshift -P -O 3000", mode "default"
    bindsym 4 exec --no-startup-id "$kill_redshift redshift -P -O 4000", mode "default"
    bindsym 5 exec --no-startup-id "$kill_redshift redshift -P -O 5000", mode "default"

    # exit mode: "Enter" or "Escape"
    bindsym Return mode "default"
    bindsym Escape mode "default"
}


# Start i3bar to display a workspace bar (plus the system information i3status if available)
bar {
    i3bar_command i3bar
    status_command py3status -c ~/.i3status.conf
    position bottom

## please set your primary output first. Example: 'xrandr --output eDP1 --primary'
#   tray_output primary
#   tray_output eDP1

    bindsym button4 nop bindsym button5 nop
#   font xft:URWGothic-Book 11
    strip_workspace_numbers yes

    colors {
        background #4a4a4a
        statusline #F9FAF9
        separator  #454947

#                      border  backgr. text
        focused_workspace  #F9FAF9 $acolor #F9FAF9
        active_workspace   #595B5B #353836 #FDF6E3
        inactive_workspace #595B5B #283339 #EEE8D5
        binding_mode       $acolor #2C2C2C #F9FAF9
        urgent_workspace   $acolor #FDF6E3 #E5201D
    }
}

# hide/unhide i3status bar
bindsym $mod+Control+m bar mode toggle

#############################
### settings for i3-gaps: ###
#############################

## Set inner/outer gaps
#gaps inner 6
#gaps outer -6
#
## Additionally, you can issue commands with the following syntax. This is useful to bind keys to changing the gap size.
## gaps inner|outer current|all set|plus|minus <px>
## gaps inner all set 10
## gaps outer all plus 5
#
## Smart gaps (gaps used if only more than one container on the workspace)
##smart_gaps on
#
## Smart borders (draw borders around container only if it is not the only container on this workspace)
## on|no_gaps (on=always activate and no_gaps=only activate if the gap size to the edge of the screen is 0)
#smart_borders on
#
## Press $mod+Shift+g to enter the gap mode. Choose o or i for modifying outer/inner gaps. Press one of + / - (in-/decrement for current workspace) or 0 (remove gaps for current workspace). If you also press Shift with these keys, the change will be global for all workspaces.
#set $mode_gaps Gaps: (o) outer, (i) inner
#set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global)
#set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global)
#bindsym $mod+Shift+g mode "$mode_gaps"
#
#mode "$mode_gaps" {
#        bindsym o      mode "$mode_gaps_outer"
#        bindsym i      mode "$mode_gaps_inner"
#        bindsym Return mode "default"
#        bindsym Escape mode "default"
#}
#mode "$mode_gaps_inner" {
#        bindsym plus  gaps inner current plus 5
#        bindsym minus gaps inner current minus 5
#        bindsym 0     gaps inner current set 0
#
#        bindsym Shift+plus  gaps inner all plus 5
#        bindsym Shift+minus gaps inner all minus 5
#        bindsym Shift+0     gaps inner all set 0
#
#        bindsym Return mode "default"
#        bindsym Escape mode "default"
#}
#mode "$mode_gaps_outer" {
#        bindsym plus  gaps outer current plus 5
#        bindsym minus gaps outer current minus 5
#        bindsym 0     gaps outer current set 0
#
#        bindsym Shift+plus  gaps outer all plus 5
#        bindsym Shift+minus gaps outer all minus 5
#        bindsym Shift+0     gaps outer all set 0
#
#        bindsym Return mode "default"
#        bindsym Escape mode "default"
#}

DPI Scaling with .Xresource and Xft.dpi

You may want/need to change your DPI with i3.  With my setup(s), I've never had success setting DPI with xrandr --dpi (which is often suggested).  Instead, we can set the DPI directly by editing (or creating) ~/.Xresources.

You might need to experiment  to find a DPI value that works for you.  Create or edit .Xresources your preferred DPI by adding the following (in this example I've set my DPI to 88 dots per inch):

~/.Xresources
Xft.dpi: 88
Override Chromium / Chrome (DPI) scaling

Recently Chromium appears to be respecting the Xft.dpi setting (which previously it didn't).  My preferred DPI was a bit hard to see now in Chromium.  You can override this behaviour  by set setting the --force-device-scale-factor flag.

Create (or edit) the file ~/.config/chromium-flags.conf and add the following (with your preferred scaling factor):

If you use Chrome credit (or edit) ~/config.chrome-flags.conf instead. 

~/.config/chromium-flags.conf
--force-device-scale-factor=0.96

Restart your browser windows and it should now no longer be using the Xft.dpi setting.

Ricing Conky (numix theme)

I've also riced my Conky setup somewhat.  Most of these changes to are to match my theme and current shortcuts setup.  I have two conky configs: one for showing various system stats (like cpu, RAM, swap etc.) and one showing several keyboard shortcuts.  See below for screenshot of my current conky setup:

Let's start with the conky config files:

Conky (numix) theme for system stats (top right in image above)
conky.config = {
	alignment = 'top_right',
	background = true,
	cpu_avg_samples = 2,
	default_color = 'F9FAF9',
	color2 = 'D64161',
	double_buffer = true,
	font = 'Bitstream Vera Sans:size=8',
	draw_shades = false,
	gap_x = 25,
	gap_y = 13,
	minimum_width = 200,
	no_buffers = true,
	own_window = true,
	own_window_type = 'override',
	own_window_transparent = true,
	update_interval = 1.0,
	use_xft = true,
}
conky.text = [[
${voffset 8}$color2${font Bitstream Vera Sans:size=16}${time %A}$font\
${voffset -8}$alignr$color${font Bitstream Vera Sans:size=38}${time %e}$font
$color${voffset -30}$color${font Bitstream Vera Sans:size=18}${time %b}$font\
${voffset -3} $color${font Bitstream Vera Sans:size=20}${time %Y}$font$color2$hr
#
${voffset 20}${goto 40}${color}CPU${font Bitstream Vera Sans:bold:size=8}$alignr$cpu%
${voffset 5}${goto 40}$font$color2${top name 1}$alignr$color${top cpu 1}%
${goto 40}$color2${top name 2}$alignr$color${top cpu 2}%
${goto 40}$color2${top name 3}$alignr$color${top cpu 3}%
${goto 40}$color2${top name 4}$alignr$color${top cpu 4}%
${goto 40}$color2${top name 5}$alignr$color${top cpu 5}%
#
${voffset 10}${goto 40}${color}RAM${font Bitstream Vera Sans:bold:size=8}$alignr$mem$font
${goto 40}${voffset 5}$color2${top_mem name 1}$alignr$color${top_mem mem_res 1}
${goto 40}$color2${top_mem name 2}$alignr$color${top_mem mem_res 2}
${goto 40}$color2${top_mem name 3}$alignr$color${top_mem mem_res 3}
${goto 40}$color2${top_mem name 4}$alignr$color${top_mem mem_res 4}
${goto 40}$color2${top_mem name 5}$alignr$color${top_mem mem_res 5}
#
${voffset 10}${goto 40}${color}Swap${font Bitstream Vera Sans:bold:size=8}$alignr${swap}/ ${swapfree}
${voffset 15}$font$alignr${execi 10000 awk -F= '/TION/ {print $2}' /etc/lsb-release |sed 's/"//g'} \
${execi 10000 awk -F= '/EASE=/ {printf $2" "} /NAME/ {print $2}' /etc/lsb-release}
${voffset 10}${color2}${alignr}${execi 1200 whoami}@${nodename}
${alignr}${color2}${font Bitstream Vera Sans:size=8}uptime: ${color}${uptime_short}
${voffset 5}${color2}${font Bitstream Vera Sans:size=8}${alignr}kernel: ${color}${kernel}
]]

Conky shortcuts conf (see lower left in image above)
conky.config = {
	alignment = 'bottom_left',
	background = true,
	cpu_avg_samples = 2,
	default_color = 'D64161',
	color2 = 'F9FAF9',
	double_buffer = true,
	font = 'Bitstream Vera Sans:size=8',
	draw_shades = false,
	gap_x = 25,
	gap_y = 45,
	minimum_width = 200,
	no_buffers = true,
	own_window = true,
	own_window_type = 'override',
	own_window_transparent = true,
	update_interval = 1.0,
	use_xft = true,
}
conky.text = [[
${color2}mod = ${color}<alt>
${color2}mod_next = ${color}<super>

${color2}open new terminal - ${color}mod+Enter
${color2}open browser - ${color}mod_next+i
${color2}open pamac-manager - ${color}mod_next+u
${color2}open bitwarden-desktop - ${color}mod_next+o
${color2}open putty - ${color}mod_next+p

${color2}rofi (launcher) - ${color}mod_next+d
${color2}rofi (windows) - ${color}mod_next+Tab
${color2}kill focused - ${color}mod+Shift+q

${color2}container layout (tabbed) - ${color}mod+w
${color2}container layout (horiz) - ${color}mod+q
${color2}container layout (vert) - ${color}mod+e
${color2}container layout (stck) - ${color}mod+s
${color2}split container (horiz) - ${color}mod+z
${color2}split container (vert) - ${color}mod+x
${color2}toggle container type - ${color}mod+c

${color2}focus windows - ${color}mod+[hjkl]

${color2}switch to workspace 1-8 - ${color}mod+1-8
${color2}send to workspace 1-8 - ${color}mod+Alt+1-8
${color2}navigate workspaces - ${color}mod+Ctrl+arrows

${color2}toggle floating - ${color}mod+Shift+Space
${color2}toggle sticky - ${color}mod+Cntrl+s
${color2}window opacity up[dn] - ${color}mod+Alt+[x|z]
${color2}window dim disable[enable] - ${color}mod+Alt+[a|d]

${color2}exit - ${color}mod+0
]]

My main i3 config file (see preceding section) expects these conky config files to be in ~/.config (you can place them anywhere really, you'll just need to update your i3 config file to point to them).

Ricing the (standard) i3 status bar

I usually also make modifications to the i3 status bar colours for the system stats.  User specific i3 status bar config is configured int he ~/.i3status.conf file.  Here's is mine, with several changes including:

  • default font colour change;
  • disk format change (showing decimal %used / %total);
  • added wlan ip address and ethernet ip address (these are hidden if not connected);
  • added battery %remaining time (next to %percentage)

Contents of my ~/.i3status.conf (for use with standard i3status)
# i3status configuration file.
# see "man i3status" for documentation.

# It is important that this file is edited as UTF-8.
# The following line should contain a sharp s:
# ß
# If the above line is not correctly displayed, fix your editor first!

general {
        colors = true
        interval = 5
        color_good = "#F9FAF9"
        color_bad = "#F9FAF9"
        color_degraded = "#DC322F"
}

order += "cpu_usage"
order += "disk /"
order += "wireless _first_"
order += "ethernet _first_"
order += "battery all"
order += "tztime local"

cpu_usage {
        format = " cpu  %usage "
}

disk "/" {
	prefix_type = decimal
	format = " ⛁ %percentage_used (U:%used, F:%free) "
}

wireless _first_ {
	# if you use %speed, i3status requires root privileges
        format_up = " wlan: %ip "
        format_down = ""
}

ethernet _first_ {
	# if you use %speed, i3status requires root privileges
        format_up = " eth: %ip "
        format_down = ""
}

battery all {
        # format = "%status %percentage %remaining %emptytime"
        format = " %status %percentage %remaining "
        format_down = "No battery"
        last_full_capacity = true
        integer_battery_capacity = true
        status_chr = "⚡"
        status_bat = "🔋"
        status_unk = ""
        status_full = "☻"
        low_threshold = 15
        threshold_type = time
}

tztime local {
        format = "%Y-%m-%d %H:%M:%S"
        #format = " %d.%m. %H:%M "
}

Using (and ricing) py3status instead of i3status

py3status is a python wrapper for i3status that provides a lot more features and extendability.  py3status gives more much control and provides some very cool modules.  First, you'll need to install py3status with:

sudo pacman -S py3status

Once, installed you'll need to modify your ~/.i3/config file and replace the status_command i3status directive with

status_command py3status -c ~/.i3status.conf

You'll notice that we use the same .i3status.conf file (which with py3status we can define some extra modules etc.). 

Before you can use my py3status config file, you'll need to install font-awesome fonts (4.7) - I had issues with version 5, but works well with v4:

yay -S ttf-font-awesome-4

Below is my config file, which looks like this:

and includes p3status modules for:

  • spotify;
  • current network rate (download / upload);
  • public ip address information (isp, city, country);
  • currently connected network (wifi ssid and local ip address);
  • battery (with font awesome icons);
  • countdown timer;

Contents of my ~/.i3status.conf (for use with py3status)
# i3status configuration file.
# see "man i3status" for documentation.

# It is important that this file is edited as UTF-8.
# The following line should contain a sharp s:
# ß
# If the above line is not correctly displayed, fix your editor first!

general {
        colors = true
        interval = 5
        color_good = "#F9FAF9"
        color_bad = "#F9FAF9"
        color_degraded = "#DC322F"
}

order += "spotify"
order += "net_rate"
order += "whatismyip"
order += "wireless _first_"
order += "ethernet _first_"
order += "cpu_usage"
order += "disk /"
#order += "diskdata"
order += "timer"
order += "battery all"
#order += "battery_level"
order += "path_exists VPN"
order += "external_script"
order += "tztime local"

spotify {
	format = "( {artist} : {title})"
	format_down = ""
	format_stopped = ""
}

timer {
	format = ":{timer}"
	time = 3600
}

cpu_usage {
        format = " cpu  %usage "
}

disk "/" {
	prefix_type = decimal
	format = " ⛁ %percentage_used (U:%used, F:%free) "	
}

diskdata {
	disk = sda2
	prefix_type = decimal
	#format_space = "[\?min_length=5 {value:.2f}]"
	format = " ⛁ {used_percent}% (U:{used} GB, F:{free} GB) "
}

external_script {
    format = "{output}"
    script_path = "cat /sys/class/tty/tty0/active"
}

whatismyip {
	format = " 🖧 {isp}\|{city}\|{countryCode} ({ip}) "
	icon_on = "🖧"
	hide_when_offline = True
	url_geo = "http://ip-api.com/json"
}

wireless _first_ {
	# if you use %speed, i3status requires root privileges
        format_up = "  %essid (%ip) "
        format_down = ""
}

ethernet _first_ {
	# if you use %speed, i3status requires root privileges
        format_up = "  eth (%ip) "
        format_down = ""
}

net_rate {
	format_value = "[\?min_length=10 {value:.1f} {unit}]"
	si_units = "True"
	format = "{down}⇣ {up}⇡"
        interfaces_blacklist = "lo"
}

battery all {
        format = " %status %percentage (%remaining) %consumption "
        format_down = "No battery"
        last_full_capacity = true
        integer_battery_capacity = true
        status_chr = "⚡"
        status_bat = ""
        status_unk = "?"
        status_full = ""
        low_threshold = 15
        threshold_type = time
}

battery_level {
	cache_timeout = 5
	measurement_mode = "acpi"
	hide_when_full = "True"
	hide_seconds = "True"
	blocks = ""
	color_charging = "#00ff00"
	format = " {icon} {percent}% ({time_remaining}) "
}

tztime local {
        format = "%Y-%m-%d %H:%M:%S"
        #format = " %d/%m %H:%M:%S"
}

path_exists VPN {
        format = "%title:tun0"
        format_down = ""
        color_good = "#00ff00"
        path = "/sys/class/net/tun0/dev_id"
}

Ricing dmenu

Along with the main i3 config file, there is also a config file dmenu (main application launcher in Mi3).  The appearance (colours etc.) are configured in the ~/.dmenurc file.  Here is my .dmenurc config file with colours that match my main i3 config:

Contents of my ~/.dmenurc
#
# ~/.dmenurc
#
 
## define the font for dmenu to be used
DMENU_FN="Noto-10.5"
 
## background colour for unselected menu-items
DMENU_NB="#4a4a4a"
 
## textcolour for unselected menu-items
DMENU_NF="#F9FAF9"
 
## background colour for selected menu-items
DMENU_SB="#eb564d"
 
## textcolour for selected menu-items
DMENU_SF="#F9FAF9"
 
## command for the terminal application to be used:
TERMINAL_CMD="terminal -e"
 
## export our variables
DMENU_OPTIONS="-fn $DMENU_FN -nb $DMENU_NB -nf $DMENU_NF -sf $DMENU_SF -sb $DMENU_SB"

Ricing rofi (to match my theming)

If you use rofi, as I do (see my .i3/config above), you can also change it's theme.  There are a very nice selection of themes included with rofi.  You can change theme by running the following from your terminal

rofi-theme-selector

Theme files can be found in usr/share/rofi/themes.

I really liked the lb.rasi theme (which is included with rofi).  However, it didn't quite match the colours of my current theme.  I made a few subtle changes to this theme (only changed colours to match what I like).  Below is the resulting file, which should be placed in the rofi theme folder (see above).

Contents of my /usr/share/rofi/themes/lb-numix.rasi
/**
 * ROFI Color theme
 * User: JT (adpated from lb by Qball)
 * Copyright: Dave Davenport
 */
 
* {
    selected-normal-foreground:  @foreground;
    foreground:                  #FFFFFF;
    normal-foreground:           @foreground;
    alternate-normal-background: rgba ( 255, 255, 255, 7 % );
    red:                         rgba ( 220, 50, 47, 100 % );
    selected-urgent-foreground:  rgba ( 51, 51, 51, 100 % );
    blue:                        rgba ( 38, 139, 210, 100 % );
    urgent-foreground:           rgba ( 255, 153, 153, 100 % );
    alternate-urgent-background: rgba ( 255, 255, 255, 7 % );
    active-foreground:           @bordercolor;
    lightbg:                     rgba ( 238, 232, 213, 100 % );
    selected-active-foreground:  @foreground;
    alternate-active-background: rgba ( 255, 255, 255, 7 % );
    background:                  rgba ( 51, 51, 51, 93 % );
    bordercolor:                 rgba ( 214, 65, 97, 100 % );
    alternate-normal-foreground: @foreground;
    normal-background:           rgba ( 0, 0, 0, 0 % );
    lightfg:                     rgba ( 88, 104, 117, 100 % );
    selected-normal-background:  @bordercolor;
    border-color:                @bordercolor;
    spacing:                     2;
    separatorcolor:              @bordercolor;
    urgent-background:           rgba ( 0, 0, 0, 0 % );
    selected-urgent-background:  rgba ( 255, 153, 153, 100 % );
    alternate-urgent-foreground: @urgent-foreground;
    background-color:            rgba ( 0, 0, 0, 0 % );
    alternate-active-foreground: @active-foreground;
    active-background:           rgba ( 0, 0, 0, 0 % );
    selected-active-background:  @bordercolor;
}
#window {
    background-color: @background;
    border:           1;
    padding:          5;
}
#mainbox {
    border:  0;
    padding: 0;
}
#message {
    border:       1px dash 0px 0px ;
    border-color: @separatorcolor;
    padding:      1px ;
}
#textbox {
    text-color: @foreground;
}
#listview {
    fixed-height: 0;
    border:       2px solid 0px 0px ;
    border-color: @separatorcolor;
    spacing:      2px ;
    scrollbar:    true;
    padding:      2px 0px 0px ;
}
#element {
    border:  0;
    padding: 1px;
}
#element.normal.normal {
    background-color: @normal-background;
    text-color:       @normal-foreground;
}
#element.normal.urgent {
    background-color: @urgent-background;
    text-color:       @urgent-foreground;
}
#element.normal.active {
    background-color: @active-background;
    text-color:       @active-foreground;
}
#element.selected.normal {
    background-color: @selected-normal-background;
    text-color:       @selected-normal-foreground;
}
#element.selected.urgent {
    background-color: @selected-urgent-background;
    text-color:       @selected-urgent-foreground;
}
#element.selected.active {
    background-color: @selected-active-background;
    text-color:       @selected-active-foreground;
}
#element.alternate.normal {
    background-color: @alternate-normal-background;
    text-color:       @alternate-normal-foreground;
}
#element.alternate.urgent {
    background-color: @alternate-urgent-background;
    text-color:       @alternate-urgent-foreground;
}
#element.alternate.active {
    background-color: @alternate-active-background;
    text-color:       @alternate-active-foreground;
}
#scrollbar {
    width:        4px ;
    border:       0;
    handle-width: 8px ;
    padding:      0;
    handle-color: @bordercolor;
}
#sidebar {
    border:       2px dash 0px 0px ;
    border-color: @separatorcolor;
}
#button.selected {
    background-color: @selected-normal-background;
    text-color:       @selected-normal-foreground;
}
#inputbar {
    spacing:    0;
    text-color: @normal-foreground;
    padding:    1px ;
}
#case-indicator {
    spacing:    0;
    text-color: @normal-foreground;
}
#entry {
    spacing:    0;
    text-color: @normal-foreground;
}
#prompt {
    spacing:    0;
    text-color: @normal-foreground;
}
#inputbar {
    children:   [ prompt,textbox-prompt-colon,entry,case-indicator ];
}
#textbox-prompt-colon {
    expand:     false;
    str:        ":";
    margin:     0px 0.3em 0em 0em ;
    text-color: @normal-foreground;
}

Ricing notifications (dunst)

You can also modify the look of the system notifications.  Configure colours etc. in ~/.config/dunst/dunstrc.  Here's a few small modifications to my dunstrc file (to match my theme):

Modifications to ~/.config/dunst/dunstrc
[global]
    frame_width = 3
    frame_color = "#eb564d"
    
    font = Noto Sans 10
    
    # Allow a small subset of html markup:
    #   <b>bold</b>
    #   <i>italic</i>
    #   <s>strikethrough</s>
    #   <u>underline</u>
    # 
    # For a complete reference see
    # <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
    # If markup is not allowed, those tags will be stripped out of the
    # message.
    markup = yes
    
    # The format of the message.  Possible variables are:
    #   %a  appname
    #   %s  summary
    #   %b  body
    #   %i  iconname (including its path)
    #   %I  iconname (without its path)
    #   %p  progress value if set ([  0%] to [100%]) or nothing
    # Markup is allowed
    format = "%s %p\n%b"
    
    # Sort messages by urgency.
    sort = yes
    
    # Show how many messages are currently hidden (because of geometry).
    indicate_hidden = yes
    
    # Alignment of message text.
    # Possible values are "left", "center" and "right".
    alignment = left
    
    # The frequency with wich text that is longer than the notification
    # window allows bounces back and forth.
    # This option conflicts with "word_wrap".
    # Set to 0 to disable.
    bounce_freq = 5

    
    # Show age of message if message is older than show_age_threshold
    # seconds.
    # Set to -1 to disable.
    show_age_threshold = 60
    
    # Split notifications into multiple lines if they don't fit into
    # geometry.
    word_wrap = no
    
    # Ignore newlines '\n' in notifications.
    ignore_newline = no
    
    
    # The geometry of the window:
    #   [{width}]x{height}[+/-{x}+/-{y}]
    # The geometry of the message window.
    # The height is measured in number of notifications everything else
    # in pixels.  If the width is omitted but the height is given
    # ("-geometry x2"), the message window expands over the whole screen
    # (dmenu-like).  If width is 0, the window expands to the longest
    # message displayed.  A positive x is measured from the left, a
    # negative from the right side of the screen.  Y is measured from
    # the top and down respectevly.
    # The width can be negative.  In this case the actual width is the
    # screen width minus the width defined in within the geometry option.
    geometry = "0x4-25+25"
    
    # Shrink window if it's smaller than the width.  Will be ignored if
    # width is 0.
    shrink = yes
    
    # The transparency of the window.  Range: [0; 100].
    # This option will only work if a compositing windowmanager is
    # present (e.g. xcompmgr, compiz, etc.).
    transparency = 15
    
    # Don't remove messages, if the user is idle (no mouse or keyboard input)
    # for longer than idle_threshold seconds.
    # Set to 0 to disable.
    # default 120
    idle_threshold = 120 
    
    # Which monitor should the notifications be displayed on.
    monitor = 0
    
    # Display notification on focused monitor.  Possible modes are:
    #   mouse: follow mouse pointer
    #   keyboard: follow window with keyboard focus
    #   none: don't follow anything
    # 
    # "keyboard" needs a windowmanager that exports the
    # _NET_ACTIVE_WINDOW property.
    # This should be the case for almost all modern windowmanagers.
    # 
    # If this option is set to mouse or keyboard, the monitor option
    # will be ignored.
    follow = mouse
    
    # Should a notification popped up from history be sticky or timeout
    # as if it would normally do.
    sticky_history = yes
    
    # Maximum amount of notifications kept in history
    history_length = 20
    
    # Display indicators for URLs (U) and actions (A).
    show_indicators = yes
    
    # The height of a single line.  If the height is smaller than the
    # font height, it will get raised to the font height.
    # This adds empty space above and under the text.
    line_height = 0
    
    # Draw a line of "separator_height" pixel height between two
    # notifications.
    # Set to 0 to disable.
    separator_height = 1
    
    # Padding between text and separator.
    # padding = 8
    padding = 8
    
    # Horizontal padding.
    horizontal_padding = 10
    
    # Define a color for the separator.
    # possible values are:
    #  * auto: dunst tries to find a color fitting to the background;
    #  * foreground: use the same color as the foreground;
    #  * frame: use the same color as the frame;
    #  * anything else will be interpreted as a X color.
    separator_color = #263238
    
    # Print a notification on startup.
    # This is mainly for error detection, since dbus (re-)starts dunst
    # automatically after a crash.
    startup_notification = false
    
    # dmenu path.
    dmenu = /usr/bin/dmenu -p dunst:
    
    # Browser for opening urls in context menu.
    browser = palemoon

    # Align icons left/right/off
    icon_position = left

    # Paths to default icons.
    icon_path = /usr/share/icons/Adwaita/16x16/status/:/usr/share/icons/Adwaita/16x16/devices/

    # Limit icons size.
    max_icon_size=128

[shortcuts]

    # Shortcuts are specified as [modifier+][modifier+]...key
    # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
    # "mod3" and "mod4" (windows-key).
    # Xev might be helpful to find names for keys.
    
    # Close notification.
    #close = mod1+space
    
    # Close all notifications.
    # close_all = ctrl+shift+space
    #close_all = ctrl+mod1+space

    # Redisplay last message(s).
    # On the US keyboard layout "grave" is normally above TAB and left
    # of "1".
    #history = ctrl+mod4+h 
    
    # Context menu.
    #context = ctrl+mod1+c

[urgency_low]
    # IMPORTANT: colors have to be defined in quotation marks.
    # Otherwise the "#" and following would be interpreted as a comment.
    background = "#4a4a4a"
    foreground = "#F9FAF9"
    timeout = 3

[urgency_normal]
    background = "#4a4a4a"
    foreground = "#F9FAF9"
    timeout = 3

[urgency_critical]
    background = "#D62929"
    foreground = "#F9FAF9"
    timeout = 0


# Every section that isn't one of the above is interpreted as a rules to
# override settings for certain messages.
# Messages can be matched by "appname", "summary", "body", "icon", "category",
# "msg_urgency" and you can override the "timeout", "urgency", "foreground",
# "background", "new_icon" and "format".
# Shell-like globbing will get expanded.
#
# SCRIPTING
# You can specify a script that gets run when the rule matches by
# setting the "script" option.
# The script will be called as follows:
#   script appname summary body icon urgency
# where urgency can be "LOW", "NORMAL" or "CRITICAL".
# 
# NOTE: if you don't want a notification to be displayed, set the format
# to "".
# NOTE: It might be helpful to run dunst -print in a terminal in order
# to find fitting options for rules.

#[espeak]
#    summary = "*"
#    script = dunst_espeak.sh

#[script-test]
#    summary = "*script*"
#    script = dunst_test.sh

#[ignore]
#    # This notification will not be displayed
#    summary = "foobar"
#    format = ""

#[signed_on]
#    appname = Pidgin
#    summary = "*signed on*"
#    urgency = low
#
#[signed_off]
#    appname = Pidgin
#    summary = *signed off*
#    urgency = low
#
#[says]
#    appname = Pidgin
#    summary = *says*
#    urgency = critical
#
#[twitter]
#    appname = Pidgin
#    summary = *twitter.com*
#    urgency = normal
#
#[Claws Mail]
#    appname = claws-mail
#    category = email.arrived
#    urgency = normal
#    background = "#2F899E"
#    foreground = "#FFA247"
#
#[mute.sh]
#     appname = mute
#     category = mute.sound
#     script = mute.sh
#
#[JDownloader]
#    appname = JDownloader
#    category = JD
#    background = "#FFA247"
#    foreground = "#FFFFFF"
#
#[newsbeuter]
#    summary = *Feeds*
#    background = "#A8EB41"
#    foreground = "#FFFFFF"
#
[irc]
        appname = weechat
        timeout = 0
        background = "#0033bb"
        foreground = "#dddddd"
#
[weechat hl]
     appname = weechat
     category = weechat.HL
     background = "#FF5C47"
     foreground = "#FFFFFF"
#
[weechat pn]
     appname = weechat
     category = weechat.PM
     background = "#D53B84"
     foreground = "#FFFFFF"
#
#[CMUS]
#    appname = CMUS
#    category = cmus
#    background = "#6C4AB7"
#    foreground = "#FFE756"
#
#
#     background = "#30AB70"
#     foreground = "#F67245"
#
# vim: ft=cfg

I've disabled the default dunst shortcuts as they interfered with some of my i3 config bindsyms.

Ricing alttab

Although I do like the way i3 approaches window switching - I do miss the speed of alt-tabbing for switching between the last focused application and the current application (and doing so often).  For this I use the very nice alttab.  It's in the AUR so once you've enabled AUR (and installed something like yay) you can do:

sudo yay -S alttab-git

You can customise the look of alttab by changing the background, foreground and frame colour.  Below is the settings that match my numix theme.  Add the following to your ~/.i3/config:

exec --no-startup-id alttab -fg "#d58681" -bg "#4a4a4a" -frame "#eb564d" -t 128x150 -i 127x64

I also like to add a bit of transparency to my alttab.  You can do this by adding a rule for alttab to the opacity-rule array definition as seen in my picom.conf:

# Thank you code_nomad: http://9m.no/ꪯ鵞
# and Arch Wiki contributors: https://wiki.archlinux.org/index.php/Compton

#################################
#
# Backend
#
#################################

# Backend to use: "xrender" or "glx".
# GLX backend is typically much faster but depends on a sane driver.
backend = "glx";

#################################
#
# GLX backend
#
#################################

glx-no-stencil = true;

# GLX backend: Copy unmodified regions from front buffer instead of redrawing them all.
# My tests with nvidia-drivers show a 10% decrease in performance when the whole screen is modified,
# but a 20% increase when only 1/4 is.
# My tests on nouveau show terrible slowdown.
glx-copy-from-front = false;

# GLX backend: Use MESA_copy_sub_buffer to do partial screen update.
# My tests on nouveau shows a 200% performance boost when only 1/4 of the screen is updated.
# May break VSync and is not available on some drivers.
# Overrides --glx-copy-from-front.
glx-use-copysubbuffermesa = true;

# GLX backend: Avoid rebinding pixmap on window damage.
# Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe).
# Recommended if it works.
glx-no-rebind-pixmap = true;

# GLX backend: GLX buffer swap method we assume.
# Could be undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).
# undefined is the slowest and the safest, and the default value.
# copy is fastest, but may fail on some drivers,
# 2-6 are gradually slower but safer (6 is still faster than 0).
# Usually, double buffer means 2, triple buffer means 3.
# buffer-age means auto-detect using GLX_EXT_buffer_age, supported by some drivers.
# Useless with --glx-use-copysubbuffermesa.
# Partially breaks --resize-damage.
# Defaults to undefined.
#glx-swap-method = "undefined";

#################################
#
# Shadows
#
#################################

# Enabled client-side shadows on windows.
shadow = false
# The blur radius for shadows. (default 12)
shadow-radius = 5;
# The left offset for shadows. (default -15)
shadow-offset-x = -5;
# The top offset for shadows. (default -15)
shadow-offset-y = -5;
# The translucency for shadows. (default .75)
shadow-opacity = 0.5;

# Set if you want different colour shadows
# shadow-red = 0.0;
# shadow-green = 0.0;
# shadow-blue = 0.0;

# The shadow exclude options are helpful if you have shadows enabled. Due to the way picom draws its shadows, certain applications will have visual glitches
# (most applications are fine, only apps that do weird things with xshapes or argb are affected).
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher.
shadow-exclude = [
    "! name~=''",
    "name = 'Notification'",
    "name = 'Plank'",
    "name = 'Docky'",
    "name = 'Kupfer'",
    "name = 'xfce4-notifyd'",
    "name = 'cpt_frame_window'",
    "name *= 'VLC'",
    "name *= 'compton'",
    "name *= 'picom'",
    "name *= 'Chromium'",
    "name *= 'Chrome'",
    "class_g = 'Firefox' && argb",
    "class_g = 'Conky'",
    "class_g = 'Kupfer'",
    "class_g = 'Synapse'",
    "class_g ?= 'Notify-osd'",
    "class_g ?= 'Cairo-dock'",
    "class_g ?= 'Xfce4-notifyd'",
    "class_g ?= 'Xfce4-power-manager'",
    # disables shadows for hidden windows
    "_GTK_FRAME_EXTENTS@:c",
    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
    # disables shadows on sticky windows:
    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
    # disables shadows on i3 frames
    "class_g ?= 'i3-frame'",
    # workaround for conky until it provides window properties:
    "override_redirect = 1 && !WM_CLASS@:s"
];
# Avoid drawing shadow on all shaped windows (see also: --detect-rounded-corners)
shadow-ignore-shaped = false;

#################################
#
# Opacity
#
#################################

inactive-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
inactive-opacity-override = false;
opacity-rule = [
    "80:class_g = 'copyq'",
    "90:name = 'alttab'",
    # no opacity on sticky windows
    "99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# Dim inactive windows. (0.0 - 1.0)
inactive-dim = 0.2;

# Do not let dimness adjust based on window opacity.
# inactive-dim-fixed = true;
# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred.
# blur-background = true;
# Blur background of opaque windows with transparent frames as well.
# blur-background-frame = true;
# Do not let blur radius adjust based on window opacity.
blur-background-fixed = false;
blur-background-exclude = [
    "window_type = 'dock'",
    "window_type = 'desktop'"
];

#################################
#
# Fading
#
#################################

# Fade windows during opacity changes.
fading = true;
# The time between steps in a fade in milliseconds. (default 10).
fade-delta = 4;
# Opacity change between steps while fading in. (default 0.028).
fade-in-step = 0.03;
# Opacity change between steps while fading out. (default 0.03).
fade-out-step = 0.03;
# Fade windows in/out when opening/closing
# no-fading-openclose = true;

# Specify a list of conditions of windows that should not be faded.
fade-exclude = [ ];

#################################
#
# Other
#
#################################

# Try to detect WM windows and mark them as active.
mark-wmwin-focused = true;
# Mark all non-WM but override-redirect windows active (e.g. menus).
mark-ovredir-focused = true;
# Use EWMH _NET_WM_ACTIVE_WINDOW to determine which window is focused instead of using FocusIn/Out events.
# Usually more reliable but depends on a EWMH-compliant WM.
use-ewmh-active-win = true;
# Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on.
detect-rounded-corners = true;

# Detect _NET_WM_OPACITY on client windows, useful for window managers not passing _NET_WM_OPACITY of client windows to frame windows.
# This prevents opacity being ignored for some apps.
# For example without this enabled my xfce4-notifyd is 100% opacity no matter what.
detect-client-opacity = true;

# Specify refresh rate of the screen.
# If not specified or 0, picom will try detecting this with X RandR extension.
refresh-rate = 0;

# Vertical synchronization: match the refresh rate of the monitor
vsync = true;

# Enable DBE painting mode, intended to use with VSync to (hopefully) eliminate tearing.
# Reported to have no effect, though.
dbe = false;

# Limit picom to repaint at most once every 1 / refresh_rate second to boost performance.
# This should not be used with --vsync drm/opengl/opengl-oml as they essentially does --sw-opti's job already,
# unless you wish to specify a lower refresh rate than the actual value.
sw-opti = true;

# Unredirect all windows if a full-screen opaque window is detected, to maximize performance for full-screen windows, like games.
# Known to cause flickering when redirecting/unredirecting windows.
unredir-if-possible = false;

# Specify a list of conditions of windows that should always be considered focused.
# Exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# Use WM_TRANSIENT_FOR to group windows, and consider windows in the same group focused at the same time.
detect-transient = true;
# Use WM_CLIENT_LEADER to group windows, and consider windows in the same group focused at the same time.
# WM_TRANSIENT_FOR has higher priority if --detect-transient is enabled, too.
detect-client-leader = true;

#################################
#
# Window type settings
#
#################################

wintypes:
{
    tooltip =
    {
        # fade: Fade the particular type of windows.
        fade = true;
        # shadow: Give those windows shadow
        shadow = false;
        # opacity: Default opacity for the type of windows.
        opacity = 0.85;
        # focus: Whether to always consider windows of this type focused.
        focus = true;
    };
};

######################
#
# XSync
# See: https://github.com/yshui/picom/commit/b18d46bcbdc35a3b5620d817dd46fbc76485c20d
#
######################

# Use X Sync fence to sync clients' draw calls. Needed on nvidia-drivers with GLX backend for some users.
xrender-sync-fence = true;

Resulting alttab settings that match my theme:

Dim non-active windows instead of applying transparency (and implement per window dim enable/disable shortcuts)

I prefer visual identification of non-active windows by dimming rather than transparency.  By default, Manjaro i3 uses a non-active window transparency as a way to help visually identify active/non-active windows.  This works quite well, but I find this adds to the "visual noise" in a busy i3 session.

The following approach replaces the default inactive window transparency with picom dim rules.  We'll also cover how modify dimming on a per window basis via a keyboard shortcuts (occasionally want to disable the default dimming on a window by window basis).

First, let's disable picom's inactive-opacity setting.  Your opacity settings in picom.conf might look something like this:

inactive-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
inactive-opacity-override = false;
opacity-rule = [
    "80:class_g = 'copyq'",
    "90:name = 'alttab'",
    # no opacity on sticky windows
    "99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

We want to make sure that inactive-opacity is set to 1 (or disabled) and active-opacity is also set to 1.  I've also kept a few opacity=rule rules that I want to still apply to several window types.  Note the last rule above - it simply disables transparency for sticky windows (another i3 concept which allows to keep a window showing/pinned on all workspaces).

Now, let's setup default dim settings.  We'll do so by adding the following settings:

# Dim inactive windows. (0.0 - 1.0)
inactive-dim = 0.2;
...
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

Note the focus-exclude rule array.  This defines rules for NOT applying dim on window types. 

Notice the rule ANTIDIM_FLAG@:8c, we'll use this to NOT applying dimming by window property (which we'll apply to selected windows via an i3 keyboard shortcut).

We can apply arbitrary window properties on selected windows.  Picom will respect these rules (by property).  The ANTIDIM_FLAG@:8c rules above (in the focus-exclude array is an example of this).  To apply/remove this window property on a selected window add the following bindsyms to your i3.conf:

# window dimming enable or disable (uses xdotool and xprop to set a anti-dim flag, which picom recognises in focus-exclude array) 
bindsym $mod+Mod1+a exec xprop -id $(xdotool getactivewindow) -f ANTIDIM_FLAG 8c -set ANTIDIM_FLAG 1; exec notify-send 'anti-dim set on window'
bindsym $mod+Mod1+d exec xprop -id $(xdotool getactivewindow) -remove ANTIDIM_FLAG; exec notify-send 'dim set on window'

For the above shortcuts to work, you'll need to install xdotool and xprop.

The above shortcuts will enable the ANTIDIM property for the currently selected window (which will disable dimming on said window) or disable the ANTIDIM property (which will then respect the default dim settings defined above).

For reference here is my ~/.config/picom.conf

~/.config/picom.conf
# Thank you code_nomad: http://9m.no/ꪯ鵞
# and Arch Wiki contributors: https://wiki.archlinux.org/index.php/Compton

#################################
#
# Backend
#
#################################

# Backend to use: "xrender" or "glx".
# GLX backend is typically much faster but depends on a sane driver.
backend = "glx";

#################################
#
# GLX backend
#
#################################

glx-no-stencil = true;

# GLX backend: Copy unmodified regions from front buffer instead of redrawing them all.
# My tests with nvidia-drivers show a 10% decrease in performance when the whole screen is modified,
# but a 20% increase when only 1/4 is.
# My tests on nouveau show terrible slowdown.
glx-copy-from-front = false;

# GLX backend: Use MESA_copy_sub_buffer to do partial screen update.
# My tests on nouveau shows a 200% performance boost when only 1/4 of the screen is updated.
# May break VSync and is not available on some drivers.
# Overrides --glx-copy-from-front.
glx-use-copysubbuffermesa = true;

# GLX backend: Avoid rebinding pixmap on window damage.
# Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe).
# Recommended if it works.
glx-no-rebind-pixmap = true;

# GLX backend: GLX buffer swap method we assume.
# Could be undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).
# undefined is the slowest and the safest, and the default value.
# copy is fastest, but may fail on some drivers,
# 2-6 are gradually slower but safer (6 is still faster than 0).
# Usually, double buffer means 2, triple buffer means 3.
# buffer-age means auto-detect using GLX_EXT_buffer_age, supported by some drivers.
# Useless with --glx-use-copysubbuffermesa.
# Partially breaks --resize-damage.
# Defaults to undefined.
#glx-swap-method = "undefined";

#################################
#
# Shadows
#
#################################

# Enabled client-side shadows on windows.
shadow = false
# The blur radius for shadows. (default 12)
shadow-radius = 5;
# The left offset for shadows. (default -15)
shadow-offset-x = -5;
# The top offset for shadows. (default -15)
shadow-offset-y = -5;
# The translucency for shadows. (default .75)
shadow-opacity = 0.5;

# Set if you want different colour shadows
# shadow-red = 0.0;
# shadow-green = 0.0;
# shadow-blue = 0.0;

# The shadow exclude options are helpful if you have shadows enabled. Due to the way picom draws its shadows, certain applications will have visual glitches
# (most applications are fine, only apps that do weird things with xshapes or argb are affected).
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher.
shadow-exclude = [
    "! name~=''",
    "name = 'Notification'",
    "name = 'Plank'",
    "name = 'Docky'",
    "name = 'Kupfer'",
    "name = 'xfce4-notifyd'",
    "name = 'cpt_frame_window'",
    "name *= 'VLC'",
    "name *= 'compton'",
    "name *= 'picom'",
    "name *= 'Chromium'",
    "name *= 'Chrome'",
    "class_g = 'Firefox' && argb",
    "class_g = 'Conky'",
    "class_g = 'Kupfer'",
    "class_g = 'Synapse'",
    "class_g ?= 'Notify-osd'",
    "class_g ?= 'Cairo-dock'",
    "class_g ?= 'Xfce4-notifyd'",
    "class_g ?= 'Xfce4-power-manager'",
    # disables shadows for hidden windows
    "_GTK_FRAME_EXTENTS@:c",
    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
    # disables shadows on sticky windows:
    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
    # disables shadows on i3 frames
    "class_g ?= 'i3-frame'",
    # workaround for conky until it provides window properties:
    "override_redirect = 1 && !WM_CLASS@:s"
];
# Avoid drawing shadow on all shaped windows (see also: --detect-rounded-corners)
shadow-ignore-shaped = false;

#################################
#
# Opacity
#
#################################

inactive-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
inactive-opacity-override = false;
opacity-rule = [
    "80:class_g = 'copyq'",
    "90:name = 'alttab'",
    # no opacity on sticky windows
    "99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# Dim inactive windows. (0.0 - 1.0)
inactive-dim = 0.2;

# Do not let dimness adjust based on window opacity.
# inactive-dim-fixed = true;
# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred.
# blur-background = true;
# Blur background of opaque windows with transparent frames as well.
# blur-background-frame = true;
# Do not let blur radius adjust based on window opacity.
blur-background-fixed = false;
blur-background-exclude = [
    "window_type = 'dock'",
    "window_type = 'desktop'"
];

#################################
#
# Fading
#
#################################

# Fade windows during opacity changes.
fading = true;
# The time between steps in a fade in milliseconds. (default 10).
fade-delta = 4;
# Opacity change between steps while fading in. (default 0.028).
fade-in-step = 0.03;
# Opacity change between steps while fading out. (default 0.03).
fade-out-step = 0.03;
# Fade windows in/out when opening/closing
# no-fading-openclose = true;

# Specify a list of conditions of windows that should not be faded.
fade-exclude = [ ];

#################################
#
# Other
#
#################################

# Try to detect WM windows and mark them as active.
mark-wmwin-focused = true;
# Mark all non-WM but override-redirect windows active (e.g. menus).
mark-ovredir-focused = true;
# Use EWMH _NET_WM_ACTIVE_WINDOW to determine which window is focused instead of using FocusIn/Out events.
# Usually more reliable but depends on a EWMH-compliant WM.
use-ewmh-active-win = true;
# Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on.
detect-rounded-corners = true;

# Detect _NET_WM_OPACITY on client windows, useful for window managers not passing _NET_WM_OPACITY of client windows to frame windows.
# This prevents opacity being ignored for some apps.
# For example without this enabled my xfce4-notifyd is 100% opacity no matter what.
detect-client-opacity = true;

# Specify refresh rate of the screen.
# If not specified or 0, picom will try detecting this with X RandR extension.
refresh-rate = 0;

# Vertical synchronization: match the refresh rate of the monitor
vsync = true;

# Enable DBE painting mode, intended to use with VSync to (hopefully) eliminate tearing.
# Reported to have no effect, though.
dbe = false;

# Limit picom to repaint at most once every 1 / refresh_rate second to boost performance.
# This should not be used with --vsync drm/opengl/opengl-oml as they essentially does --sw-opti's job already,
# unless you wish to specify a lower refresh rate than the actual value.
sw-opti = true;

# Unredirect all windows if a full-screen opaque window is detected, to maximize performance for full-screen windows, like games.
# Known to cause flickering when redirecting/unredirecting windows.
unredir-if-possible = false;

# Specify a list of conditions of windows that should always be considered focused.
# Exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# Use WM_TRANSIENT_FOR to group windows, and consider windows in the same group focused at the same time.
detect-transient = true;
# Use WM_CLIENT_LEADER to group windows, and consider windows in the same group focused at the same time.
# WM_TRANSIENT_FOR has higher priority if --detect-transient is enabled, too.
detect-client-leader = true;

#################################
#
# Window type settings
#
#################################

wintypes:
{
    tooltip =
    {
        # fade: Fade the particular type of windows.
        fade = true;
        # shadow: Give those windows shadow
        shadow = false;
        # opacity: Default opacity for the type of windows.
        opacity = 0.85;
        # focus: Whether to always consider windows of this type focused.
        focus = true;
    };
};

######################
#
# XSync
# See: https://github.com/yshui/picom/commit/b18d46bcbdc35a3b5620d817dd46fbc76485c20d
#
######################

# Use X Sync fence to sync clients' draw calls. Needed on nvidia-drivers with GLX backend for some users.
xrender-sync-fence = true;

Enabling per window transparency with transset-df (and keybind changing it)

Using window transparencies effectively can make a big difference to the overall use and focus in managing lots of windows, especially when you might have a few sticky windows as well.

Although you can modify transparencies etc. by editing ~/.config/picom.conf, there's no functionality to increase or decrease transparencies 'on the fly' and for specific windows only.

You can achieve this with transset-df.  First you'll need to install it with

sudo pacman -S transset-df

Once installed, using transset-df is very straightforward, for example, to set transparency to 80%, simply call

transset-df 0.8

and then click on a window to set the transparency for that window.

We can do even better though with i3.  In my ~/.i3/config I've added

# window transparency adjustment (and alias to restart picom)
bindsym $mod+Mod1+z exec transset-df -a --min 0.25 --dec 0.25
bindsym $mod+Mod1+x exec transset-df -a --inc 0.25
bindsym $mod+Mod1+c exec --no-startup-id picom -b

These shortcuts will increase or decrease transparency of the currently selected window by +/-25%.  You might notice I also have a shortcut (mod+alt+c) for picom, which will reset start/reset picom.  You'll see why next.

I prefer my sticky windows to be opaque by default, and using the above I can then change them to suit. To change the default window transparency used for sticky windows you'll need to modify your picom config (~/.config/picom.conf) and make sure it contains 

"99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"

in the opacity-rule array.

This works to my liking.  However, I've found that when I want to change my sticky window back to opaque, my default inactive-opacity setting for picom kicks in (in other words, when I select something else my sticky window is not quite opaque).  Resetting picom with mod+alt+c fixes this and reapplies my default transparency setting for sticky windows.

For reference here is my ~/.config/picom.conf

~/.config/picom.conf
# Thank you code_nomad: http://9m.no/ꪯ鵞
# and Arch Wiki contributors: https://wiki.archlinux.org/index.php/Compton

#################################
#
# Backend
#
#################################

# Backend to use: "xrender" or "glx".
# GLX backend is typically much faster but depends on a sane driver.
backend = "glx";

#################################
#
# GLX backend
#
#################################

glx-no-stencil = true;

# GLX backend: Copy unmodified regions from front buffer instead of redrawing them all.
# My tests with nvidia-drivers show a 10% decrease in performance when the whole screen is modified,
# but a 20% increase when only 1/4 is.
# My tests on nouveau show terrible slowdown.
glx-copy-from-front = false;

# GLX backend: Use MESA_copy_sub_buffer to do partial screen update.
# My tests on nouveau shows a 200% performance boost when only 1/4 of the screen is updated.
# May break VSync and is not available on some drivers.
# Overrides --glx-copy-from-front.
glx-use-copysubbuffermesa = true;

# GLX backend: Avoid rebinding pixmap on window damage.
# Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe).
# Recommended if it works.
glx-no-rebind-pixmap = true;

# GLX backend: GLX buffer swap method we assume.
# Could be undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).
# undefined is the slowest and the safest, and the default value.
# copy is fastest, but may fail on some drivers,
# 2-6 are gradually slower but safer (6 is still faster than 0).
# Usually, double buffer means 2, triple buffer means 3.
# buffer-age means auto-detect using GLX_EXT_buffer_age, supported by some drivers.
# Useless with --glx-use-copysubbuffermesa.
# Partially breaks --resize-damage.
# Defaults to undefined.
#glx-swap-method = "undefined";

#################################
#
# Shadows
#
#################################

# Enabled client-side shadows on windows.
shadow = false
# The blur radius for shadows. (default 12)
shadow-radius = 5;
# The left offset for shadows. (default -15)
shadow-offset-x = -5;
# The top offset for shadows. (default -15)
shadow-offset-y = -5;
# The translucency for shadows. (default .75)
shadow-opacity = 0.5;

# Set if you want different colour shadows
# shadow-red = 0.0;
# shadow-green = 0.0;
# shadow-blue = 0.0;

# The shadow exclude options are helpful if you have shadows enabled. Due to the way picom draws its shadows, certain applications will have visual glitches
# (most applications are fine, only apps that do weird things with xshapes or argb are affected).
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher.
shadow-exclude = [
    "! name~=''",
    "name = 'Notification'",
    "name = 'Plank'",
    "name = 'Docky'",
    "name = 'Kupfer'",
    "name = 'xfce4-notifyd'",
    "name = 'cpt_frame_window'",
    "name *= 'VLC'",
    "name *= 'compton'",
    "name *= 'picom'",
    "name *= 'Chromium'",
    "name *= 'Chrome'",
    "class_g = 'Firefox' && argb",
    "class_g = 'Conky'",
    "class_g = 'Kupfer'",
    "class_g = 'Synapse'",
    "class_g ?= 'Notify-osd'",
    "class_g ?= 'Cairo-dock'",
    "class_g ?= 'Xfce4-notifyd'",
    "class_g ?= 'Xfce4-power-manager'",
    # disables shadows for hidden windows
    "_GTK_FRAME_EXTENTS@:c",
    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
    # disables shadows on sticky windows:
    "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
    # disables shadows on i3 frames
    "class_g ?= 'i3-frame'",
    # workaround for conky until it provides window properties:
    "override_redirect = 1 && !WM_CLASS@:s"
];
# Avoid drawing shadow on all shaped windows (see also: --detect-rounded-corners)
shadow-ignore-shaped = false;

#################################
#
# Opacity
#
#################################

inactive-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
inactive-opacity-override = false;
opacity-rule = [
    "80:class_g = 'copyq'",
    "90:name = 'alttab'",
    # no opacity on sticky windows
    "99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# Dim inactive windows. (0.0 - 1.0)
inactive-dim = 0.2;

# Do not let dimness adjust based on window opacity.
# inactive-dim-fixed = true;
# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred.
# blur-background = true;
# Blur background of opaque windows with transparent frames as well.
# blur-background-frame = true;
# Do not let blur radius adjust based on window opacity.
blur-background-fixed = false;
blur-background-exclude = [
    "window_type = 'dock'",
    "window_type = 'desktop'"
];

#################################
#
# Fading
#
#################################

# Fade windows during opacity changes.
fading = true;
# The time between steps in a fade in milliseconds. (default 10).
fade-delta = 4;
# Opacity change between steps while fading in. (default 0.028).
fade-in-step = 0.03;
# Opacity change between steps while fading out. (default 0.03).
fade-out-step = 0.03;
# Fade windows in/out when opening/closing
# no-fading-openclose = true;

# Specify a list of conditions of windows that should not be faded.
fade-exclude = [ ];

#################################
#
# Other
#
#################################

# Try to detect WM windows and mark them as active.
mark-wmwin-focused = true;
# Mark all non-WM but override-redirect windows active (e.g. menus).
mark-ovredir-focused = true;
# Use EWMH _NET_WM_ACTIVE_WINDOW to determine which window is focused instead of using FocusIn/Out events.
# Usually more reliable but depends on a EWMH-compliant WM.
use-ewmh-active-win = true;
# Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on.
detect-rounded-corners = true;

# Detect _NET_WM_OPACITY on client windows, useful for window managers not passing _NET_WM_OPACITY of client windows to frame windows.
# This prevents opacity being ignored for some apps.
# For example without this enabled my xfce4-notifyd is 100% opacity no matter what.
detect-client-opacity = true;

# Specify refresh rate of the screen.
# If not specified or 0, picom will try detecting this with X RandR extension.
refresh-rate = 0;

# Vertical synchronization: match the refresh rate of the monitor
vsync = true;

# Enable DBE painting mode, intended to use with VSync to (hopefully) eliminate tearing.
# Reported to have no effect, though.
dbe = false;

# Limit picom to repaint at most once every 1 / refresh_rate second to boost performance.
# This should not be used with --vsync drm/opengl/opengl-oml as they essentially does --sw-opti's job already,
# unless you wish to specify a lower refresh rate than the actual value.
sw-opti = true;

# Unredirect all windows if a full-screen opaque window is detected, to maximize performance for full-screen windows, like games.
# Known to cause flickering when redirecting/unredirecting windows.
unredir-if-possible = false;

# Specify a list of conditions of windows that should always be considered focused.
# Exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# Use WM_TRANSIENT_FOR to group windows, and consider windows in the same group focused at the same time.
detect-transient = true;
# Use WM_CLIENT_LEADER to group windows, and consider windows in the same group focused at the same time.
# WM_TRANSIENT_FOR has higher priority if --detect-transient is enabled, too.
detect-client-leader = true;

#################################
#
# Window type settings
#
#################################

wintypes:
{
    tooltip =
    {
        # fade: Fade the particular type of windows.
        fade = true;
        # shadow: Give those windows shadow
        shadow = false;
        # opacity: Default opacity for the type of windows.
        opacity = 0.85;
        # focus: Whether to always consider windows of this type focused.
        focus = true;
    };
};

######################
#
# XSync
# See: https://github.com/yshui/picom/commit/b18d46bcbdc35a3b5620d817dd46fbc76485c20d
#
######################

# Use X Sync fence to sync clients' draw calls. Needed on nvidia-drivers with GLX backend for some users.
xrender-sync-fence = true;


Window Management and various other implementations in i3

My usage and window management approaches in i3 have evolved over time - and continue to evolve.  If you look through my dev branch you'll see many changes and things tried (and reverted) as I've slowly tried out things until I've found what works best for me.  That's one the many things I love about i3 (and linux in general).

Below are just a few of the window management approaches that have stuck with me.  Please note that these approaches might not work for you - and that's fine.  Feel free to adapt (or disregard) them.

Master-stack (stack-stack) swap stack window with master keybind

I find myself now generally using a "master-stack" approach to window management with i3.  More specifically, I have two "stacking" layouts (horizontally) side-by-side, like so:

That is, I have a "master" stacking layout on the left and use a "stack" stacking (or splitv) layout on the right.

Now, i3 is a manual tiling manager which means that to move windows you can move window manually from the "stack" layout to the master - however it won't automatically move the current "master" to the "stack" layout when doing so (other dynamic tiling managers usually do this in a master-stack layout).

We can however, simulate this basic concept with a bindsym which will move the focused "stack" window to the right (the "master" layout), focus up (to select the currently selected "master" window), move it right, and then focus on the (now new) master window.  Add the following to your i3.conf file (I've found $mod+m works well for me):

# master-stack keybinding (moves stack window to master and current master back to stack window)
bindsym $mod+m exec "i3-msg \\"move left; focus up; move right; focus left\\""

Quick demo of using the above bindsym to switch windows in master-stack layout:

My "special" window combiner bindsyms

Note I no longer use these.  I use of i3 is constantly evolving and I find myself using more of a "master-stack" or a "stack-stack" approach to window management.  As such, I haven't used the below approach much lately so have deprecated them (removed them) in my config.  These might work well for you though so give them a try!

I found that much of my time was spend combining two adjacent windows into a single container.  That is, say I have four application windows all in a tabbed container, like so:

Now, most of the time I just want to combine two windows (in this example, my browser window and the Atom window to the right) into a split h container.  To do this, you would usually do something like

  1. create split h container;
  2. focus on the right app window;
  3. move right app window left (which combines into container);
  4. focus back on left app.

The above steps result in:

Now, that gets rather tedious after doing it a thousand times. 

Thankfully, you can basically do all these steps and bind it to a single shortcut defined in you i3 config file.  Behold:

# special combo for horizontal split of two windows next to each other
bindsym $mod+x split h, layout splith, focus right, move left, focus left, $con_title
bindsym $mod+Shift+x split h, layout splith, focus left, move right, focus right, $con_title

The two bindsyms will combine in a split container with the right adjacent window ($mod+x) or with the adjacent window on the left ($mod+Shift+x).

I also have similar bindsyms for combining adjacent windows into a tabbed container:

# special combo for container tabbed split of two windows next to each other
bindsym $mod+z split h, layout tabbed, focus right, move left, focus left, $con_title
bindsym $mod+Shift+z split h, layout tabbed, focus left, move right, focus right, $con_title

Container renaming

Dynamic container renaming

I've noticed that when you have a heavy window workload (lots of windows) and you've containerised lots of them - container names kind of... suck.  That is, they almost become so convoluted that it's easy to get lost.  For example look at the screenshot below of a normal workload for me (during development):

Notice the container names at the top (stuff like T[filezilla putty H[chromium chromium]]...) I struggle to segregate and identify (remember) where I put that chromium or terminal window that I was working on.

Now notice the difference with the same workload but container names changed:

Can you see the difference?  I've simply renamed the containers into something I understand; I have a container to my git related stuff (git clients and stuff), a container for several IDEs I use, another for apps I'm using to deploy applications to several web servers, and a container with stuff related to the latest javascript question/problem I'm figuring out.  These are all much more recognisable to me and helps me avoid "too many obscure window titles" hell.

I recently found this post on reddit that outlined a few ways to rename containers on the fly.  This can be achieved with a single bindsym that uses zenity (so make sure you have the zenity package installed) to pop up an input window for you to enter a container name and then focuses on the window parent, renames the container and then focuses back on the child window.  Below I've embedded a modified version of the script into a single bindsym command:

# dynamic renaming of parent container
bindsym $mod+slash exec "answer=$(zenity --title=\\"i3-msg title_format\\" --text \\"Change %TITLE for parent container\\" --entry); if [ -n \\"$answer\\" ]; then i3-msg focus parent, title_format \\"<span foreground='pink'><b> $answer</b></span>\\", focus child; else i3-msg focus parent, title_format \\"<span foreground='pink'><b> %title</b></span>\\", focus child; fi"

I've bound it to $mod+slash ("/" key).

Automatic container renaming from selected window

The above method can be used to default any container name to that of (for example) the currently selected window at the time of creating the container.  By defining the following config variable:

set $con_title exec "answer=$(xdotool getwindowfocus getwindowname); i3-msg focus parent, title_format \\"<span foreground='#ff8c85'><b> ⮡$answer</b></span>\\", focus child"

 and appending to our special window combiner bindsyms (see sections above), like this:

# special combo for horizontal split of two windows next to each other
bindsym $mod+x split h, layout splith, focus right, move left, focus left, $con_title
bindsym $mod+Shift+x split h, layout splith, focus left, move right, focus right, $con_title

Will cause the container title (created by $mod+x etc.) to be based on the window title of the application selected at the time of container generation.

Changing title behaviour to default for a single container

I've created a simple bindsym shortcut ($mod+Mod1+slash) to change the container title of a single (selected) container back to i3 default (e.g. T[chromium]).

Reverting to previous window title behaviour altogether

If you don't like this container title behaviour simply change the $con_title definition to:

set $con_title focus parent; title_format "<span foreground='#ff8c85'><b> %title</b></span>"; focus child; title_format " %title"

Scratchpad specific applications and bind their showing/hiding to a key shortcut

The below is a deprecated approach to showing/hiding applications on the scratchpad.  I've moved to using more i3 native approaches

The i3 scratchpad is great holding area for application windows that you might want to keep hide from all workspaces until you need them.  I often use the scratchpad for applications like my email client (which I don't want to see until an email arrives etc.) or for an on-demand terminal (not really a drop-down terminal but similar use case), or for an application that I regularly want to (quickly) popup, retrieve information and then have it get out of the way just as quickly (like a password manager for example).

In order for the use case(s) above, you really want to bind the scratchpad application to a keyboard shortcut that can be pressed to show the scratchpad application, and then pressed again to hide said application.

I wrote several scripts and integrated these directly in my i3.conf.  They basically check if an application is running, if it's not then start it (where you can then scratchpad it with the normal shortcut: mod+Shift+minus).  If it is running (and already on the scratchpad) pressing the shortcut will show/hide said application.  Of course, you can write a script to do all this and call it from your i3.conf, but I prefer to explicitly define the bash script in my conf (partly to cut down on others needing to take copy of my scripts separately from my i3.conf file).

Enough waffling, some i3.conf examples:

Terminator (terminal application)

I use the very cool (I think) terminator.  See my i3.conf bindsym below:

bindsym $mod+Shift+Return exec "APP=\\"terminator\\"; CLASS=\\"Terminator\\"; if pgrep -x \\"$APP\\" > /dev/null 2>&1; then i3-msg \\"[class=\\"$CLASS\\"] scratchpad show\\"; else \\"$APP\\"; fi"

You'll note that I define separate bash variables ($APP, $CLASS) here as the command to start Terminator is "terminator" but the WM_CLASS (window class) returned is "Terminator".

KeeWeb

My bindsym for KeeWeb (keepass cross-platform client):

bindsym $mod+o exec "APP=\\"KeeWeb\\"; if pgrep -x \\"$APP\\" > /dev/null 2>&1; then i3-msg \\"[class=\\"$APP\\"] scratchpad show\\"; else \\"$APP\\"; fi"

Save i3 layouts with i3-layout-manager

This is now removed from my current config.  Was great but I no longer use it (plus was a bit experimental and had a few issues I ran into).  Would still recommend though if you like the idea of predefining i3 layouts.

i3 natively supports saving and loading specific window layouts with the i3-save-tree, however the implementation is not really "user ready" in the sense that you can't use it as is to easily save and load different layouts.

Tomáš Báča wrote a neat script that makes this functionality much simpler to use.

I find having set/defined layouts really eases managing complex window setups.  Often I am working with many windows in some complicated setup (with child window containers of window containers etc.) and want to just get back to something simple(r) - which can be surprisingly tedious 

I've also added three layouts (which can be loaded) I use most and have provided bindsyms for each in my i3 config file.  These are:

Layout fileLayout NameKeyboard shortcutDescription
layout-ALL-TABBED.jsonALL-TABBEDmod+Shift+wBasic layout with single (root) tab container.  Useful for when you have a complex window layout and want to remove all windows and place in simple tabbed layout.
layout-SPLIT-TWO-TABBED.jsonSPLIT-TWO-TABBEDmod+Shift+aLayout with two root child containers (horizontally split) with each root child container set to be a tabbed container.
layout-SPLIT-FOUR-TABBED.jsonSPLIT-FOUR-TABBEDmod+Shift+sLayout with four root child containers (screen partitioned into four quarters) with each root child container set to be a tabbed container.

You'll need to have the i3-layout-manager script in your system path for the i3.conf  shortcuts to work and load on startup.

You can clone the git repo (or even just download the script) and copy (or create a symbolic link) in your system path (I'd suggest /usr/local/bin), like below

git clone https://github.com/klaxalk/i3-layout-manager.git
cd i3-layout-manager
sudo cp layout_manager.sh /usr/local/bin/i3-layout-manager
sudo chmod +x /usr/local/bin/i3-layout-manager

Download (somewhere) and copy my layouts above into the ~/.layouts folder, e.g.:

cp layout-ALL-TABBED.json layout-SPLIT-TWO-TABBED.json layout-SPLIT-FOUR-TABBED.json ~/.layouts

References

  1. https://forum.manjaro.org/t/reversed-scrolling-in-i3-edition/25811
  2. https://wiki.archlinux.org/index.php/Libinput
  3. https://wiki.archlinux.org/index.php/Touchpad_Synaptics
  4. https://wiki.archlinux.org/index.php/Razer_Blade#2018_version
  5. https://forum.manjaro.org/t/how-disable-bios-beep-like-sound-in-some-applications/17094/5
  6. https://wiki.archlinux.org/index.php/GNOME/Keyring#PAM_method
  7. https://i3wm.org/i3status/manpage.html#_disk
  8. http://duncanlock.net/blog/2013/06/07/how-to-switch-to-compton-for-beautiful-tear-free-compositing-in-xfce/
  9. http://vadim-kirilchuk-linux.blogspot.com.au/2013/05/swap-file-for-hibernation.html
  10. https://github.com/DaveDavenport/rofi
  11. https://wiki.archlinux.org/index.php/Per-application_transparency
  12. https://forum.manjaro.org/t/manjaro-i3-how-to-use-lightdm-as-lockscreen/42131
  13. https://www.reddit.com/r/i3wm/comments/7f84ae/is_there_a_way_to_rename_parent_containers/
  14. https://github.com/klaxalk/i3-layout-manager