💾 Archived View for gmi.bacardi55.io › blog › 2023 › 01 › 19 › new-laptop-part3-i3wm-configuration captured on 2023-07-22 at 16:36:45. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
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/
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
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
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"
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
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
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
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
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: 🌢'"
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}
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
`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
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
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"
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
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
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
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 }
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].
[All my rofi configuration can be found on sourcehut]
All my rofi configuration can be found on sourcehut
To launch application, I start the launcher with `window' + `d':
bindsym $mod+d exec rofi -modi drun -show drun -config ~/.config/rofi/rofidmenu.rasi
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
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
bindsym $mod+c exec --no-startup-id rofi -modi "clipboard:greenclip print" -show clipboard -config ~/.config/rofi/rofidmenu.rasi
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
The power menu allow easy select to hibernate, suspend, lock, logout, reboot or shutdown:
bindsym $mod+Shift+e exec ~/.config/i3/scripts/powermenu
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
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
/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)%"
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"
Just giving an example, it's that easy:
bindsym $mod+w exec /usr/bin/firefox-nightly -P bacardi55
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
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
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