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 the pure awesomeness that is Manjaro i3 (Community Edition).

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:

sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer

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.

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.

Screen tearing (with Compton)

On one my laptops (Thinkpad e480) there was noticable screen tearing with compton enabled.  To eliminate the screen tearing found there were several tweaks needed to the ~/.config/compton.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 my default Mi3 install hibernation wasn't working.  This may be because in this instance I didn't use a separate swap partition and instead opted to simply use a swap file for swap needs.

First just check that you can hibernate (mod+0, followed by h).  If you can, then there's no need to do the below.  If you can't, continue (below).

Let's first enable hibernation.  To setup hibernate we're going to install the hibernator package and run it as root:

sudo pacman -S hibernator
sudo hibernator

Once the hibernator script has run you should have the requirements for hibernate to work.

If you're using a swap file (as opposed to a swap partition) then we'll need to do a bit more work.  I assume there that you're using grub as you're boot loader.

We're going to be editing /etc/default/grub.  Note that there is scope here to mess things up royally.  So, let's backup our current grub file to be safe(r)

sudo cp /etc/default/grub /etc/default/grub.backup

So, before we can edit our grub, we need a few pieces of information:

  1. device name of parition where have swap file;
  2. physical offset of /swapfile (which is my swap file).

For (1), we can simply run df and find the partition where our swap file is (which will usually be the same partition as Mi3 is installed to).  In my case, running dfoutputs:

The partition where I have Mi3 installed is /dev/sda3.

For (2), we can run sudo sudo filefrag -v /swapfile.  For my system doing so outputs:

The value we are after is the ext 0 physical offset as shown in the image (red rectangle). 

With these pieces of information let's now edit our grub

sudo nano /etc/default/grub

We want to find the lines starting with GRUB_CMDLINE_LINUX (which was line 5 in my case) and add the following with the bits of information previously outlined:

GRUB_CMDLINE_LINUX="resume=/dev/sda3 resume_offset=249856"

Now, we can save our changes and then run

sudo update-grub

Reboot and hibernation should hopefully now be working.  GIve it a go.

Stop 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

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):


My config file:

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

  • conky config files (see following section)
  • pamac-manager now starts as normal (not float);
  • 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);
  • using 'uiop[' keys for various apps (like launching pamac, chromium, bitwarden, putty, nautilus);
  • added resizing windows without needing resize mode (mod+alt+Left shrinks width by 20ppt, mod+alt+shift+Left shrinks width by 10ppt, etc.) - and disabled resizing mode.  Can also use vim style keys here;
  • changes to container and splitting shortcuts; 
  • mod+alt+z, mod+alt+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" modes (mod+alt+n, mod+alt+m);
  • added some "special" window management shortcuts (mod+z, mod+shift+z, mod+x, mod+shift+x): these are some of my favourites and essentially combines two windows (that are next to each other) into a separate container.

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"

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 (Mod1=<Alt>, Mod4=<Super>)
set $mod 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 other colors
set $bdrcolor #4d4949
set $bgicolor #eb564d
set $bgucolor #6a6868
set $txtacolor #F9FAF9
set $txtucolor #bdbbbb
set $indcolor #00ff00

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

# 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

# change borders
bindsym $mod+v border none
bindsym $mod+b $border_normal
bindsym $mod+n $border_no_name

# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
font xft:URWGothic-Book 11
#font pango:monospace 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 nitrogen --restore; sleep 1; compton -b
#exec --no-startup-id manjaro-hello
exec --no-startup-id nm-applet
exec --no-startup-id xfce4-power-manager
#exec --no-startup-id pamac-tray
exec --no-startup-id copyq
# exec --no-startup-id blueman-applet
# exec_always --no-startup-id sbxkb
# exec --no-startup-id start_conky_maia
# exec --no-startup-id start_conky_green
exec --no-startup-id conky -c ~/.config/conky
exec --no-startup-id conky -c ~/.config/conky_shortcuts
exec --no-startup-id xautolock -time 10 -locker blurlock
exec_always --no-startup-id ff-theme-util
exec_always --no-startup-id fix_xcursor
exec --no-startup-id fcitx -d
exec --no-startup-id alttab -pk h -nk l -fg "#d58681" -bg "#4a4a4a" -frame "#eb564d" -t 128x150 -i 127x64
exec_always --no-startup-id "pkill skippy-xd; skippy-xd --start-daemon"

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

# start program launcher
#bindsym $mod+d exec --no-startup-id dmenu_recency
#exec --no-startup-id kupfer
bindsym $mod+d exec --no-startup-id "rofi -show-icons -modi windowcd,window,drun -show drun"
bindsym $mod+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

# launch i3-layout-Manager (and binding several layouts) - EXPERIMENTAL
#bindsym $mod+c exec --no-startup-id i3-layout-manager
#bindsym $mod+Shift+w exec --no-startup-id "i3-layout-manager ALL-TABBED"
#bindsym $mod+Shift+a exec --no-startup-id "i3-layout-manager SPLIT-TWO-TABBED"
#bindsym $mod+Shift+s exec --no-startup-id "i3-layout-manager SPLIT-FOUR-TABBED"

################################################################################################
## 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+F9 exec sudo xbacklight +10

# focus_follows_mouse no

# change focus
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right

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

# 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 no
#bindsym $mod+b workspace back_and_forth
#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 leaves the shown title as i3 deault (e.g. %title).
# - 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 
# NOTE: requires xdotool
#
#set $con_title i3-msg focus parent, title_format \\"<span foreground='#FEC196'><b> 📦 %title</b></span>\\", focus child, title_format \\" %title\\"
#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 foreground='#FEC196'><b> 📦 $ANSWER</b></span>\\", focus child; fi"
bindsym $mod+Mod1+slash focus parent, title_format "<span foreground='#FEC196'><b> 📦 %title</b></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+Mod1+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;exec notify-send 'tabbed layout'
bindsym $mod+q layout splith;exec notify-send 'horizontal layout'
bindsym $mod+e layout splitv;exec notify-send 'vertical layout'
bindsym $mod+s layout stacking;exec notify-send 'stacking layout'

# child container layouts (creates a child container from current selected application)
bindsym $mod+Mod1+w split h; layout tabbed; exec "$con_title"
bindsym $mod+Mod1+q split h; exec "$con_title"
bindsym $mod+Mod1+e split h; layout splitv; exec "$con_title"
bindsym $mod+Mod1+s split h; layout stacking; exec "$con_title"

# 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, exec "$con_title"
bindsym $mod+Shift+x split h, layout splith, focus left, move right, focus right, exec "$con_title"

# 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, exec "$con_title"
bindsym $mod+Shift+z split h, layout tabbed, focus left, move right, focus right, exec "$con_title"

# toggle fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle
bindsym $mod+Mod1+f floating enable;move position 0px 0px;resize set 1920 1080;border none

bindsym $mod+space 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+Mod1+space focus mode_toggle

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

# window transparency adjustment (and alias to restart compton)
bindsym $mod+Mod1+z exec transset-df -a --min 0.20 --dec 0.20
bindsym $mod+Mod1+Shift+z exec transset-df -a --min 0.1 --dec 0.1
bindsym $mod+Mod1+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+Mod1+x exec transset-df -a --inc 0.20 --max 0.99
bindsym $mod+Mod1+Shift+x exec transset-df -a --inc 0.1 --max 0.99
bindsym $mod+Mod1+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+Mod1+c exec --no-startup-id "pkill compton; compton -b"

# window dimming enable or disable (uses xdotool and xprop to set a anti-dim flag, which compton 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'

# 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+Mod1+1 move container to workspace $ws1
bindsym $mod+Mod1+2 move container to workspace $ws2
bindsym $mod+Mod1+3 move container to workspace $ws3
bindsym $mod+Mod1+4 move container to workspace $ws4
bindsym $mod+Mod1+5 move container to workspace $ws5
bindsym $mod+Mod1+6 move container to workspace $ws6
bindsym $mod+Mod1+7 move container to workspace $ws7
bindsym $mod+Mod1+8 move container to workspace $ws8

# Move to workspace with focused container
bindsym $mod+Shift+1 move container to workspace $ws1; workspace $ws1
bindsym $mod+Shift+2 move container to workspace $ws2; workspace $ws2
bindsym $mod+Shift+3 move container to workspace $ws3; workspace $ws3
bindsym $mod+Shift+4 move container to workspace $ws4; workspace $ws4
bindsym $mod+Shift+5 move container to workspace $ws5; workspace $ws5
bindsym $mod+Shift+6 move container to workspace $ws6; workspace $ws6
bindsym $mod+Shift+7 move container to workspace $ws7; workspace $ws7
bindsym $mod+Shift+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 [title="alsamixer"] floating enable border pixel 1
for_window [class="Calamares"] floating enable border normal
for_window [class="Clipgrab"] floating enable
for_window [title="File Transfer*"] floating enable
for_window [class="Galculator"] floating enable border pixel 1
#for_window [class="GParted"] floating enable border normal
for_window [class="Lightdm-gtk-greeter-settings"] floating enable
for_window [class="Lxappearance"] floating enable sticky enable border normal
for_window [class="Manjaro-hello"] floating enable
for_window [class="Manjaro Settings Manager"] floating enable border normal
for_window [title="MuseScore: Play Panel"] floating enable
#for_window [class="Nitrogen"] floating enable sticky enable border normal
#for_window [class="Oblogout"] fullscreen enable
for_window [class="octopi"] floating enable
for_window [title="About Pale Moon"] floating enable
#for_window [class="Pamac-manager"] floating enable border normal
#for_window [class="Pavucontrol"] floating enable
for_window [class="qt5ct"] floating enable sticky enable border normal
for_window [class="Qtconfig-qt4"] floating enable sticky enable border normal
for_window [class="Simple-scan"] floating enable border normal
for_window [class="(?i)System-config-printer.py"] floating enable border normal
#for_window [class="Skype"] floating enable border normal
for_window [class="Thus"] floating enable border normal
for_window [class="Timeset-gui"] floating enable border normal
#for_window [class="(?i)virtualbox"] floating enable border normal
for_window [class="Xfburn"] floating enable
for_window [class="copyq"] floating enable border pixel 1
for_window [class="Shutter"] floating enable
for_window [title="Color Picker"] floating enable border none
for_window [class="(?i)Kupfer"] border none
for_window [class="(?i)Gnome-calculator"] floating enable
for_window [class="(?i)Gcolor3"] floating enable border none

# setting up dropdown terminal (using tilix)
# NOTE: you'll need to disable CSD and set 'Application title' to '${activeTerminalTitle}' (appearance options)
for_window [title="dropdown-terminal"] sticky enable border none
for_window [title="dropdown-terminal"] move scratchpad
exec --no-startup-id tilix -t dropdown-terminal
bindsym $mod+Shift+Return [title="dropdown-terminal"] scratchpad show
bindsym $mod+Mod1+Return [title="dropdown-terminal"] move position 0px 0px; resize set 1920 600

# setting up dropdown Bitwarden
for_window [title="Bitwarden"] sticky enable border none
exec --no-startup-id bitwarden
bindsym $mod+o [class="Bitwarden"] scratchpad show

# Application shortcuts
bindsym $mod+Return exec tilix
bindsym $mod+Ctrl+b exec terminal -e 'bmenu'
#bindsym $mod+F2 exec --no-startup-id pavucontrol
#bindsym $mod+F5 exec terminal -e 'mocp'
bindsym $mod+F10 exec blueman-manager
bindsym $mod+t exec --no-startup-id pkill compton
bindsym $mod+Ctrl+t exec --no-startup-id compton -b
bindsym $mod+Ctrl+d --release exec "killall dunst; exec notify-send 'restart dunst'"
bindsym Print exec --no-startup-id i3-scrot
bindsym $mod+Print --release exec --no-startup-id i3-scrot -w
bindsym $mod+Shift+Print --release exec --no-startup-id i3-scrot -s
bindsym $mod+Ctrl+x --release exec --no-startup-id xkill
bindsym Mod1+grave exec --no-startup-id skippy-xd --activate-window-picker

# shortcuts to often used applications
bindsym $mod+u exec pamac-manager
bindsym $mod+i exec chromium
bindsym $mod+p exec putty
bindsym $mod+bracketleft exec nautilus
bindsym $mod+Shift+bracketleft exec gksu nautilus

#sm-player shortcuts (e.g. for use if send smplayer to scratchpad)
bindsym Mod1+Shift+space exec --no-startup-id smplayer -send-action pause
bindsym Mod1+Shift+h exec --no-startup-id smplayer -send-action rewind1
bindsym Mod1+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+Shift+c reload

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

# 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, (s)uspend, (h)ibernate, (r)eboot, (Shift+s)hutdown
mode "$mode_system" {
    bindsym l exec --no-startup-id i3exit lock, mode "default"
    bindsym s exec --no-startup-id 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 r exec --no-startup-id i3exit reboot, mode "default"
    bindsym Shift+s 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+Mod1+Left resize shrink width 100 px or 10 ppt
bindsym $mod+Mod1+Down resize grow height 100 px or 10 ppt
bindsym $mod+Mod1+Up resize shrink height 100 px or 10 ppt
bindsym $mod+Mod1+Right resize grow width 100 px or 10 ppt

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

# predefined sizes (90/10)
bindsym $mod+Mod1+u resize set width 10 ppt
bindsym $mod+Mod1+i resize set width 50 ppt
bindsym $mod+Mod1+o resize set width 90 ppt

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

# Color palette used for the terminal ( ~/.Xresources file )
# Colors are gathered based on the documentation:
# https://i3wm.org/docs/userguide.html#xresources
# Change the variable name at the place you want to match the color
# of your terminal like this:
# [example]
# If you want your bar to have the same background color as your
# terminal background change the line 362 from:
# background #14191D
# to:
# background $term_background
# Same logic applied to everything else.
set_from_resource $term_background background
set_from_resource $term_foreground foreground
set_from_resource $term_color0     color0
set_from_resource $term_color1     color1
set_from_resource $term_color2     color2
set_from_resource $term_color3     color3
set_from_resource $term_color4     color4
set_from_resource $term_color5     color5
set_from_resource $term_color6     color6
set_from_resource $term_color7     color7
set_from_resource $term_color8     color8
set_from_resource $term_color9     color9
set_from_resource $term_color10    color10
set_from_resource $term_color11    color11
set_from_resource $term_color12    color12
set_from_resource $term_color13    color13
set_from_resource $term_color14    color14
set_from_resource $term_color15    color15

# 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+m bar mode toggle

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

#############################
### 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"
}

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,
	color2 = 'EB564D',
	cpu_avg_samples = 2,
	default_color = 'F9FAF9',
	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,
	color2 = 'F9FAF9',
	cpu_avg_samples = 2,
	default_color = 'EB564D',
	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}open new terminal - ${color}mod+Enter
${color2}open browser - ${color}mod+i
${color2}open pamac-manager - ${color}mod+u
${color2}open bitwarden-desktop - ${color}mod+o
${color2}open putty - ${color}mod+p

${color2}rofi (launcher) - ${color}mod+d
${color2}rofi (windows) - ${color}mod+Tab
${color2}bmenu - ${color}mod+Ctrl+b
${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}child container (tabbed) - ${color}mod+Alt+w
${color2}child container (horiz) - ${color}mod+Alt+q
${color2}child container (vert) - ${color}mod+Alt+e
${color2}child container (stck) - ${color}mod+Alt+s

${color2}tab with next window - ${color}mod+z
${color2}tab with previous window - ${color}mod+Shift+z
${color2}splith with next window - ${color}mod+x
${color2}splith with previous window - ${color}mod+Shift+x

${color2}focus windows - ${color}mod+[hjkl | arrow_keys]
${color2}focus containers - ${color}mod+Ctrl+[hjkl | arrows]

${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+Shift+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
${color2}help - ${color}mod+Shift+h
${color2}mod = ${color}<Super>
]]

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 += "load"
order += "disk /"
# order += "disk /home"
order += "wireless _first_"
order += "ethernet _first_"
order += "battery all"
# order += "load"
order += "tztime local"
# order += "ipv6"

cpu_usage {
        format = " cpu  %usage "
}

load {
        format = " load %1min "
        # max_threshold = 0.3
}

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_chr = "⚡"
        # status_bat = "bat"
        # status_bat = "☉"
        status_bat = ""
        # status_unk = "?"
        status_unk = ""
        # status_full = ""
        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 += "load"
order += "cpu_usage"
#order += "disk /"
order += "diskdata"
order += "timer"
#order += "battery all"
order += "battery_level"
# order += "load"
order += "path_exists VPN"
order += "external_script"
order += "tztime local"
# order += "ipv6"

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

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

cpu_usage {
        format = " cpu  %usage "
}

load {
        format = " load %1min "
        # max_threshold = 0.3
}

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 %emptytime"
        format = " %status %percentage %remaining "
        format_down = "No battery"
        last_full_capacity = true
        integer_battery_capacity = true
        # status_chr = ""
        status_chr = "⚡"
        # status_bat = "bat"
        # status_bat = "☉"
        status_bat = ""
        # status_unk = "?"
        status_unk = ""
        # status_full = ""
        status_full = "☻"
        low_threshold = 15
        threshold_type = time
}

battery_level {
	cache_timeout = 30
	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 ( 235, 86, 77, 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 compton.conf:

# Shadow
shadow = false;
# no-dnd-shadow = true;
# no-dock-shadow = true;
clear-shadow = true;
detect-rounded-corners = true;
shadow-radius = 5;
shadow-offset-x = 1;
shadow-offset-y = 1;
shadow-opacity = .3;
shadow-ignore-shaped = false;
shadow-exclude = [
	"name = 'Notification'",
# workaround for conky until it provides window properties:
	"override_redirect = 1 && !WM_CLASS@:s",
    "class_g ?= 'Dmenu'",
#	"class_g ?= 'Dunst'",
# disable shadows for hidden windows:
	"_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
	"_GTK_FRAME_EXTENTS@:c",
# disables shadows on sticky windows:
#	"_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
# disables shadows on i3 frames
	"class_g ?= 'i3-frame'"
];

# shadow-exclude-reg = "x10+0+0";
# xinerama-shadow-crop = true;

# opacity settings
menu-opacity = 0.95;
#inactive-opacity = 0.93;
active-opacity = 1;
alpha-step = 0.01;
opacity-rule = [
#"99:name *?= 'Call'",
##"99:class_g = 'Chromium'",
#"99:name *?= 'Conky'",
#"99:class_g = 'Darktable'",
#"50:class_g = 'Dmenu'",
#"99:name *?= 'Event'",
#"99:class_g = 'Firefox'",
#"99:class_g = 'GIMP'",
#"99:name *?= 'Image'",
#"99:class_g = 'Lazpaint'",
#"99:class_g = 'Midori'",
#"99:name *?= 'Minitube'",
#"99:class_g = 'Mousepad'",
#"99:name *?= 'MuseScore'",
#"90:name *?= 'Page Info'",
#"99:name *?= 'Pale Moon'",
##"90:name *?= 'Panel'",
#"99:class_g = 'Pinta'",
#"90:name *?= 'Restart'",
#"99:name *?= 'sudo'",
#"99:name *?= 'Screenshot'",
#"99:class_g = 'Viewnior'",
#"99:class_g = 'VirtualBox'",
#"99:name *?= 'VLC'",
##"99:name *?= 'Write'",
#"99:name *?= 'dropdown-terminal'",
#"93:class_g = 'URxvt' && !_NET_WM_STATE@:32a",
##"0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
"90:name = 'alttab'",
"80:class_g = 'copyq'",
"99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# dim settings
inactive-dim = 0.2;
# exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
  "class_g = 'Cairo-clock'"
];

blur-background = false;
blur-kern = "3x3box";

fading = false;
fade-delta = 1;
fade-in-step = 0.03;
fade-out-step = 0.03;
fade-exclude = [ ];

#backend = "xrender";
backend = "glx";
mark-wmwin-focused = true;
mark-ovredir-focused = true;
detect-client-opacity = true;
unredir-if-possible = true;
refresh-rate = 0;
#vsync = "none";
#vsync = "drm";
vsync = "opengl-swc";
dbe = false;
paint-on-overlay = true;
detect-transient = true;
detect-client-leader = true;
invert-color-include = [ ];
glx-copy-from-front = false;
glx-swap-method = "undefined";

wintypes :
{
  tooltip :
  {
    fade = true;
    shadow = false;
    opacity = 0.85;
    focus = true;
  };
  fullscreen :
  {
    fade = true;
    shadow = false;
    opacity = 1;
    focus = 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 compton 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 compton's inactive-opacity setting.  Your opacity settings in compton.conf should look something like this:

# opacity settings
menu-opacity = 0.95;
#inactive-opacity = 0.93;
active-opacity = 1;
alpha-step = 0.01;
opacity-rule = [
"90:name = 'alttab'",
"80:class_g = 'copyq'",
"99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

You'll note that we've disabled inactive-opacity  and set active-opacity  to 1.  We'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 settings
inactive-dim = 0.2;
# exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
  "class_g = 'Cairo-clock'"
];

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.  Compton 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 compton 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/compton.conf

~/.config/compton.conf
# Shadow
shadow = false;
# no-dnd-shadow = true;
# no-dock-shadow = true;
clear-shadow = true;
detect-rounded-corners = true;
shadow-radius = 5;
shadow-offset-x = 1;
shadow-offset-y = 1;
shadow-opacity = .3;
shadow-ignore-shaped = false;
shadow-exclude = [
	"name = 'Notification'",
# workaround for conky until it provides window properties:
	"override_redirect = 1 && !WM_CLASS@:s",
    "class_g ?= 'Dmenu'",
#	"class_g ?= 'Dunst'",
# disable shadows for hidden windows:
	"_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
	"_GTK_FRAME_EXTENTS@:c",
# disables shadows on sticky windows:
#	"_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
# disables shadows on i3 frames
	"class_g ?= 'i3-frame'"
];

# shadow-exclude-reg = "x10+0+0";
# xinerama-shadow-crop = true;

# opacity settings
menu-opacity = 0.95;
#inactive-opacity = 0.93;
active-opacity = 1;
alpha-step = 0.01;
opacity-rule = [
#"99:name *?= 'Call'",
##"99:class_g = 'Chromium'",
#"99:name *?= 'Conky'",
#"99:class_g = 'Darktable'",
#"50:class_g = 'Dmenu'",
#"99:name *?= 'Event'",
#"99:class_g = 'Firefox'",
#"99:class_g = 'GIMP'",
#"99:name *?= 'Image'",
#"99:class_g = 'Lazpaint'",
#"99:class_g = 'Midori'",
#"99:name *?= 'Minitube'",
#"99:class_g = 'Mousepad'",
#"99:name *?= 'MuseScore'",
#"90:name *?= 'Page Info'",
#"99:name *?= 'Pale Moon'",
##"90:name *?= 'Panel'",
#"99:class_g = 'Pinta'",
#"90:name *?= 'Restart'",
#"99:name *?= 'sudo'",
#"99:name *?= 'Screenshot'",
#"99:class_g = 'Viewnior'",
#"99:class_g = 'VirtualBox'",
#"99:name *?= 'VLC'",
##"99:name *?= 'Write'",
#"99:name *?= 'dropdown-terminal'",
#"93:class_g = 'URxvt' && !_NET_WM_STATE@:32a",
##"0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
"90:name = 'alttab'",
"80:class_g = 'copyq'",
"99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# dim settings
inactive-dim = 0.2;
# exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
  "class_g = 'Cairo-clock'"
];

blur-background = false;
blur-kern = "3x3box";

fading = false;
fade-delta = 1;
fade-in-step = 0.03;
fade-out-step = 0.03;
fade-exclude = [ ];

#backend = "xrender";
backend = "glx";
mark-wmwin-focused = true;
mark-ovredir-focused = true;
detect-client-opacity = true;
unredir-if-possible = true;
refresh-rate = 0;
#vsync = "none";
#vsync = "drm";
vsync = "opengl-swc";
dbe = false;
paint-on-overlay = true;
detect-transient = true;
detect-client-leader = true;
invert-color-include = [ ];
glx-copy-from-front = false;
glx-swap-method = "undefined";

wintypes :
{
  tooltip :
  {
    fade = true;
    shadow = false;
    opacity = 0.85;
    focus = true;
  };
  fullscreen :
  {
    fade = true;
    shadow = false;
    opacity = 1;
    focus = 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/compton.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 compton)
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 compton -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 compton, which will reset start/reset compton.  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 compton config (~/.config/compton.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 compton kicks in (in other words, when I select something else my sticky window is not quite opaque).  Resetting compton with mod+alt+c fixes this and reapplies my default transparency setting for sticky windows.

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

~/.config/compton.conf
# Shadow
shadow = false;
# no-dnd-shadow = true;
# no-dock-shadow = true;
clear-shadow = true;
detect-rounded-corners = true;
shadow-radius = 5;
shadow-offset-x = 1;
shadow-offset-y = 1;
shadow-opacity = .3;
shadow-ignore-shaped = false;
shadow-exclude = [
	"name = 'Notification'",
# workaround for conky until it provides window properties:
	"override_redirect = 1 && !WM_CLASS@:s",
    "class_g ?= 'Dmenu'",
#	"class_g ?= 'Dunst'",
# disable shadows for hidden windows:
	"_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
	"_GTK_FRAME_EXTENTS@:c",
# disables shadows on sticky windows:
#	"_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
# disables shadows on i3 frames
	"class_g ?= 'i3-frame'"
];

# shadow-exclude-reg = "x10+0+0";
# xinerama-shadow-crop = true;

# opacity settings
menu-opacity = 0.95;
#inactive-opacity = 0.93;
active-opacity = 1;
alpha-step = 0.01;
opacity-rule = [
#"99:name *?= 'Call'",
##"99:class_g = 'Chromium'",
#"99:name *?= 'Conky'",
#"99:class_g = 'Darktable'",
#"50:class_g = 'Dmenu'",
#"99:name *?= 'Event'",
#"99:class_g = 'Firefox'",
#"99:class_g = 'GIMP'",
#"99:name *?= 'Image'",
#"99:class_g = 'Lazpaint'",
#"99:class_g = 'Midori'",
#"99:name *?= 'Minitube'",
#"99:class_g = 'Mousepad'",
#"99:name *?= 'MuseScore'",
#"90:name *?= 'Page Info'",
#"99:name *?= 'Pale Moon'",
##"90:name *?= 'Panel'",
#"99:class_g = 'Pinta'",
#"90:name *?= 'Restart'",
#"99:name *?= 'sudo'",
#"99:name *?= 'Screenshot'",
#"99:class_g = 'Viewnior'",
#"99:class_g = 'VirtualBox'",
#"99:name *?= 'VLC'",
##"99:name *?= 'Write'",
#"99:name *?= 'dropdown-terminal'",
#"93:class_g = 'URxvt' && !_NET_WM_STATE@:32a",
##"0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'",
"90:name = 'alttab'",
"80:class_g = 'copyq'",
"99:_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'"
];

# dim settings
inactive-dim = 0.2;
# exclude treats as always focused (doesn't dim)
focus-exclude = [
  "ANTIDIM_FLAG@:8c",
  "_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
  "class_g = 'Cairo-clock'"
];

blur-background = false;
blur-kern = "3x3box";

fading = false;
fade-delta = 1;
fade-in-step = 0.03;
fade-out-step = 0.03;
fade-exclude = [ ];

#backend = "xrender";
backend = "glx";
mark-wmwin-focused = true;
mark-ovredir-focused = true;
detect-client-opacity = true;
unredir-if-possible = true;
refresh-rate = 0;
#vsync = "none";
#vsync = "drm";
vsync = "opengl-swc";
dbe = false;
paint-on-overlay = true;
detect-transient = true;
detect-client-leader = true;
invert-color-include = [ ];
glx-copy-from-front = false;
glx-swap-method = "undefined";

wintypes :
{
  tooltip :
  {
    fade = true;
    shadow = false;
    opacity = 0.85;
    focus = true;
  };
  fullscreen :
  {
    fade = true;
    shadow = false;
    opacity = 1;
    focus = 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.

My "special" window combiner bindsyms

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

Although still in my i3 config file, this is now disabled (commented out) as it is still experimental with several issues

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