💾 Archived View for gmi.bacardi55.io › blog › 2023 › 01 › 19 › new-laptop-part3-i3wm-configuration captured on 2023-11-14 at 07:57:42. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

New laptop part 3: i3wm configuration

Posted on 2023-01-19

Edit: considering the complexity of this article, I strongly suggest you read it via a web browser:

https://bacardi55.io/2023/01/19/new-laptop-part-3-i3wm-configuration/

Introduction

Continuing the [framework laptop blog post series], where I first wrote about [my impression of the framework laptop], then about what [I had to do to fix EndeavourOS / Archlinux on it] and lastely about the [installation and configuration of some "core" softwares]. This post is about my i3wm configuration that I have redone from scratch, heavily inspired by [EndeavourOS one].

The TLDR; as usual, is look at [my dotfiles] :)

Mandatory screenshot:

Be careful, this post is *very* long due to covering many topics. For this reason, I'm adding for the first time a table of content for this post:

framework laptop blog post series

my impression of the framework laptop

I had to do to fix EndeavourOS / Archlinux on it

installation and configuration of some "core" softwares

EndeavourOS one

my dotfiles

Configuring i3wm

The basics

The basic settings, with comments that shouldn't need more explaination:

---
title: "set the mod key to the winkey:"
date:
---
set $mod Mod4
---
title: "default i3 tiling mode:"
date:
---
workspace_layout default
---
title: "Back and forth between workspaces"
date:
---
workspace_auto_back_and_forth yes

#border indicator on windows:
new_window pixel 1

---
title: "Set inner/outer gaps"
date:
---
gaps inner 3
gaps outer 2

---
title: "Use Mouse+$mod to drag floating windows to their wanted position"
date:
---
floating_modifier $mod

Workspaces

Workspaces naming convention

First, let's define the different workspaces. I have both "personal" and "work" related workspace. To visualy separate them, I add "🌢" in front of the "name" of each work related workspace (yes there is a connection^^).

I use 10 workspaces each, they are the same: browsers (web and gemini, in tabbed mode), "terminal", emails, chats, files, 7, 8, 9, 10.

## Personal workspaces
set $ws1 "1:"
set $ws2 "2:"
set $ws3 "3:✉️"
set $ws4 "4:"
set $ws5 "5:"
set $ws6 "6:"
set $ws7 "7:7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"
## Work workspaces
set $wsw1 "11:🌢"
set $wsw2 "12:🌢"
set $wsw3 "13:🌢✉️"
set $wsw4 "14:🌢"
set $wsw5 "15:🌢"
set $wsw6 "16:🌢"
set $wsw7 "17:🌢7"
set $wsw8 "18:🌢8"
set $wsw9 "19:🌢9"
set $wsw10 "20:🌢10"

Assigning workspaces to screens

To assign workspace to specific screens, it is easy:

workspace $ws1 output DP1
workspace $ws2 output DP2-2
workspace $ws3 output DP2-2
workspace $ws4 output eDP1
workspace $wsw1 output DP1
workspace $wsw2 output DP2-2
workspace $wsw3 output DP1
workspace $wsw4 output DP2-1

Switching between workspaces

Of course, naming is fine, but more important is to switch between them. To switch between personal workspaces, I'm using the `window' (`$mod') key and a number key. To switch between work workspaces, I'm using the `window' (`$mod') key + `Alt' (`Mod1') key + a number key.

---
title: "switch to workspace"
date:
---
## Personal workspaces
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
bindsym $mod+9    workspace  $ws9
bindsym $mod+0    workspace  $ws10
## Work workspaces
bindsym $mod+Mod1+1    workspace  $wsw1
bindsym $mod+Mod1+2    workspace  $wsw2
bindsym $mod+Mod1+3    workspace  $wsw3
bindsym $mod+Mod1+4    workspace  $wsw4
bindsym $mod+Mod1+5    workspace  $wsw5
bindsym $mod+Mod1+6    workspace  $wsw6
bindsym $mod+Mod1+7    workspace  $wsw7
bindsym $mod+Mod1+8    workspace  $wsw8
bindsym $mod+Mod1+9    workspace  $wsw9
bindsym $mod+Mod1+0    workspace  $wsw10

Moving workspaces around

To move workspaces between screens (outputs), `window' (`$mod') + `shift' + Left/Right/Up/Down:

---
title: "Move workspaces to output"
date:
---
bindsym $mod+Shift+Mod1+Left move workspace to output left
bindsym $mod+Shift+Mod1+Right move workspace to output right
bindsym $mod+Shift+Mod1+Up move workspace to output up
bindsym $mod+Shift+Mod1+Down move workspace to output down

Switch between workspace

To replicate the usual "alt+tab" but for workspaces, I use `window' + `tab' (with `shift' to go backward).

---
title: "switch/iterate between workspaces"
date:
---
bindsym $mod+Tab workspace next
bindsym $mod+Shift+Tab workspace prev

Renaming workspace

I very often rename workspace, specially for work related workspace, I usually rename them with a customer or specific project name. For this I'm using `window' + `x' to rename personal workspace (ask for name and use it as is) and `window' + `alt' + `x' to rename a work related workspace (use the name with "🌢" before).

---
title: "rename workspace"
date:
---
bindsym $mod+x exec "i3-input -F 'move container to workspace %s; workspace %s' -P 'Rename workspace to: '"
bindsym $mod+Mod1+x exec "i3-input -F 'move container workspace 🌢%s; workspace 🌢%s' -P 'Rename workspace to: 🌢'"

Open new empty workspace

In case all workspace are taken (never really happens…), I use `window' + `shift' + `n' to open a new empty one using a script called `empty_workspace'. The script came with the i3wm configuration of EndeavourOS, thanks to them!

---
title: "open new empty workspace"
date:
---
bindsym $mod+Shift+n exec ~/.config/i3/scripts/empty_workspace

The `empty_workspace' script:

#!/usr/bin/env bash
MAX_DESKTOPS=20
WORKSPACES=$(seq -s '\n' 1 1 ${MAX_DESKTOPS})
EMPTY_WORKSPACE=$( (i3-msg -t get_workspaces | tr ',' '\n' | grep num | awk -F:  '{print int($2)}' ; \
            echo -e ${WORKSPACES} ) | sort -n | uniq -u | head -n 1)

i3-msg workspace ${EMPTY_WORKSPACE}

Containers / Window

Changing focus between windows

Using `window' + Left/Up/Right/Down keys:

---
title: "change focus"
date:
---
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right

Also, for the usual "alt+tab" behaviour:

---
title: "alt tab old school style"
date:
---
bindsym Mod1+Tab focus right
bindsym Mod1+Shift+Tab focus left

For focusing the parent container:

---
title: "focus the parent container"
date:
---
bindsym $mod+a focus parent

Moving to the latest "urgent" window

---
title: "urgent"
date:
---
bindsym $mod+Escape [urgent=latest] focus

Move focused window around

`window' (`$mod') + `shift' + a Left/Up/Down/Right to windows around.

---
title: "move focused window"
date:
---
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right

Moving focused containers (windows) between workspaces

Easy, `window' (`$mod') + `shift' + a key number to move to a personal workspace. `window' (`$mod') + `alt' (`Mod1') + `shift' + a key number to move to a work workspace.

---
title: "move focused container to workspace"
date:
---
## Personal workspaces
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
bindsym $mod+Shift+9    move container to workspace  $ws9
bindsym $mod+Shift+0    move container to workspace  $ws10
## Work workspaces
bindsym $mod+Mod1+Shift+1    move container to workspace  $wsw1
bindsym $mod+Mod1+Shift+2    move container to workspace  $wsw2
bindsym $mod+Mod1+Shift+3    move container to workspace  $wsw3
bindsym $mod+Mod1+Shift+4    move container to workspace  $wsw4
bindsym $mod+Mod1+Shift+5    move container to workspace  $wsw5
bindsym $mod+Mod1+Shift+6    move container to workspace  $wsw6
bindsym $mod+Mod1+Shift+7    move container to workspace  $wsw7
bindsym $mod+Mod1+Shift+8    move container to workspace  $wsw8
bindsym $mod+Mod1+Shift+9    move container to workspace  $wsw9
bindsym $mod+Mod1+Shift+0    move container to workspace  $wsw10

Floating and resizing

Toggle tiling / floating of a window:

---
title: "toggle tiling / floating"
date:
---
bindsym $mod+Shift+f floating toggle

Switch focus between tiling and floating windows:

---
title: "change focus between tiling / floating windows"
date:
---
bindsym $mod+space focus mode_toggle

Resizing is done via `window' + `shift' + `s' and then arrow keys or h/j/k/l:

---
title: "resize window (you can also use the mouse for that):"
date:
---
mode "resize" {
---
title: "These bindings trigger as soon as you enter the resize mode"
date:
---
---
title: "Pressing left will shrink the window's width."
date:
---
---
title: "Pressing right will grow the window's width."
date:
---
---
title: "Pressing up will shrink the window's height."
date:
---
---
title: "Pressing down will grow the window's height."
date:
---
  bindsym j resize shrink width 10 px or 10 ppt
  bindsym k resize grow height 10 px or 10 ppt
  bindsym l resize shrink height 10 px or 10 ppt
  bindsym h resize grow width 10 px or 10 ppt

---
title: "same bindings, but for the arrow keys"
date:
---
  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

---
title: "back to normal: Enter or Escape"
date:
---
  bindsym Return mode "default"
  bindsym Escape mode "default"
}
bindsym $mod+Shift+s mode "resize"

Scratchpad

From time to time, I like putting windows as scratchpad windows, for this I use `window' (+ `shift') + `²':

---
title: "scratchpad"
date:
---
bindsym $mod+Shift+twosuperior move scratchpad
bindsym $mod+twosuperior scratchpad show

Layouts

Spliting layout

I like creating a horizontal split with `window' + `v' and a vertical split with `window' + `h'. It's the opposite of the default, but it makes more sense for me^^.

---
title: "split in horizontal orientation"
date:
---
bindsym $mod+h split v
---
title: "split in vertical orientation"
date:
---
bindsym $mod+v split h

Workspace layout

Layout selection is done via `window' + `s' (stacking), `window' + `z' (tabbed) or `window' + `e' (split toggle):

---
title: "change container layout (stacked, tabbed, toggle split)"
date:
---
bindsym $mod+s layout stacking
bindsym $mod+z layout tabbed
bindsym $mod+e layout toggle split

i3bar

config

Basically, having the i3bar at the top of each screen. System tray displayed on the primary screen (in my case the central one). For the status part, I use [i3blocks] (see next paragraph).

bar {
    font pango: Noto Sans Regular 10
    status_command i3blocks -c ~/.config/i3/i3blocks.conf
    position top
    tray_output primary
    tray_padding 0
    strip_workspace_numbers yes
}

i3blocks

i3blocks

My status looks like this:

This example includes the system tray, which represent the last 4 icons, from right to left: syncthing, redshift, nm-applet and blueman-applet.

I'm using mostly default stuff from i3blocks, except 2 custom scripts:

[dunst]
command=~/workspace/contrib/i3blocks-contrib/dunst/dunst
format=json
interval=-1

The `~/workspace/contrib/i3blocks-contrib/dunst/dunst' comes from [i3blocks-contrib] and can be found [here].

i3blocks-contrib

here

QoL improvements with rofi

[All my rofi configuration can be found on sourcehut]

All my rofi configuration can be found on sourcehut

Application launcher

To launch application, I start the launcher with `window' + `d':

bindsym $mod+d exec rofi -modi drun -show drun -config ~/.config/rofi/rofidmenu.rasi

Window selector

Open a window listing all windows (in any workspace) with filter to quickly jump to it. Example:

bindsym $mod+t exec rofi -show window -config ~/.config/rofi/rofidmenu.rasi

Workspace selector

Open a window listing all workspaces with filter to quickly jump to it. Example:

---
title: "keybinding in fancy rofi (automated):"
date:
---
bindsym $mod+mod1+Tab exec ~/.config/i3/scripts/keyhint-2

Clipboard

bindsym $mod+c exec --no-startup-id rofi -modi "clipboard:greenclip print" -show clipboard -config ~/.config/rofi/rofidmenu.rasi

Password store integration

Configuration or rofi-pass:

mkdir ~/.config/rofi-pass && cp /etc/rofi-pass.conf ~/.config/rofi-pass/config

And i3wm configuration:

bindsym $mod+p exec /usr/bin/rofi-pass

Power menu

The power menu allow easy select to hibernate, suspend, lock, logout, reboot or shutdown:

bindsym $mod+Shift+e exec ~/.config/i3/scripts/powermenu

Power profiles switcher

The power profiles menu allow easy select different power profiles: performance, balanced or power saver:

bindsym $mod+Shift+p exec ~/.config/i3/scripts/power-profiles

Some keybinds

Audio related

Audio specific keybind:

---
title: "volume"
date:
---
bindsym XF86AudioRaiseVolume exec amixer -D pulse sset Master 5%+ && pkill -RTMIN+1 i3blocks
bindsym XF86AudioLowerVolume exec amixer -D pulse sset Master 5%- && pkill -RTMIN+1 i3blocks

---
title: "gradular volume control"
date:
---
bindsym $mod+XF86AudioRaiseVolume exec amixer -D pulse sset Master 1%+ && pkill -RTMIN+1 i3blocks
bindsym $mod+XF86AudioLowerVolume exec amixer -D pulse sset Master 1%- && pkill -RTMIN+1 i3blocks

---
title: "mute"
date:
---
bindsym XF86AudioMute exec amixer sset Master toggle && killall -USR1 i3blocks

---
title: "audio control"
date:
---
bindsym XF86AudioPlay exec playerctl play
bindsym XF86AudioPause exec playerctl pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous

Backlight control

/Remember to fix the backlight control as described in the previous post./

---
title: "Backlight control"
date:
---
bindsym XF86MonBrightnessUp exec xbacklight +5 && notify-send "Brightness - $(xbacklight -get | cut -d '.' -f 1)%"
bindsym XF86MonBrightnessDown exec xbacklight -5 && notify-send "Brightness - $(xbacklight -get | cut -d '.' -f 1)%"

Screenshots

3 possibility to take screenshots with `scrot': Full screenshots (all screens) with `Print Screen', screenshot of the focused window with `window' + `Print Screen' or a screenshot of a manually selected area with `shift' + `Print Screen' (and then just click and select the area to screenshot):

bindsym Print exec scrot ~/Téléchargements/screenshots/%Y-%m-%d-%T-screenshot.png && notify-send "Screenshot saved"
bindsym $mod+Print exec scrot --focus ~/Téléchargements/screenshots/%Y-%m-%d-%T-screenshot.png && notify-send "Screenshot saved"
bindsym --release Shift+Print exec scrot --select ~/Téléchargements/screenshots/%Y-%m-%d-%T-screenshot.png && notify-send "Screenshot saved"

Applications

Open app via Keybinds

Just giving an example, it's that easy:

bindsym $mod+w exec /usr/bin/firefox-nightly -P bacardi55

Bind app to workspaces

I have some app being binded to specific workspace:

---
title: "bind program to workspace and focus to them on startup:"
date:
---
assign [class="(?i)firefox-nightly"] $ws1
assign [class="(?i)firefox"] $wsw1
assign [class="Thunar"] $ws5
assign [class="Emacs"] $ws2

---
title: "automatic set focus new window if it opens on another workspace than the current:"
date:
---
for_window [class=Xfce4-terminal] focus
for_window [class=(?i)firefox] focus
for_window [class=Thunar] focus

Floating rules

For some specific windows, I want them to be automatically floating:

for_window [class="Galculator" instance="galculator"] floating enable
for_window [class="Pavucontrol" instance="pavucontrol"] floating enable
for_window [window_role="About"] floating enable

Others

There are other things in my config, such as autostarted programs, theming (will be part of another post regarding the global "theming" of my laptop) or keybind to open window (self explanatory based on the documention). To have a full view, feel free to read the [full configuration file on source hut].

full configuration file on source hut

Conclusion

/gemlog/

Send me a gemini mention

send me an email!