i3-wm Advanced Lessons
By WretchedGhost
- 4 minutes read - 839 wordsAfter using i3-wm (which I will call i3 from here on out) for over 5 years now, I have pretty much got it almost exactly how I like it. For reference here is my latest i3 config which can be found at https://git.wretchednet.com/wretchedghost/i3-wretchedbox This config might change here and there so check often as some things might have been updated since this post.
Today’s lesson will revolve around some advanced tweaks to add to your config for a more finely tuned system on i3.
Options for for_window and classes
I have recently learned how to implement for_window options in i3. These allow for very fine-tuned window management such as controlling the size of a window, controlling floating windows, setting up how popup windows work, and more.
Let’s start with a few examples.
This example here will force Thunderbird to never float and also always be contained to workspace 3.
for_window [class="^Thunderbird$" title=" ? Mozilla Thunderbird$"] floating disabled, move container to workspace 3
for_window [class="^Thunderbird$" title="Sending Message - Re:.$"] floating disabled, move container to workspace 3
The first for_window locks the Thunderbird program to workspace 3 and doesn’t allow floating. The second one does the same but targets only the reply which can often cause the window to float, which I prefer to have the a new window created right next to the main Thunderbird program splitting it into half of the screen to share with the reply window.
This next example helps i3 work like most non-tiling window managers by allowing floating windows to be created instead of a whole new window that takes up the entire workspace for links. This works well with logging into Google’s pop-up webpages that often use a floating window.
for_window [class="^Links$" title="^Links - "] floating enable
Assigning classes to programs
Just like above with the for_window classes, i3 allows for assigning classes to programs to force them to a specific workspace.
If I wanted to assign all browsers to use workspace 1 only, I would add the below to my ~/.config/i3/config:
asign [class="^Brave*"] $ws1
assign [class="^Firefox*"] $ws1
assign [class="^Pale Moon"] $ws1
assign [class="^Midori"] $ws1
Mostly, you only have to add a carat (^) with the program name to force it to go to one workspace only. Adding a (*) at the end allows wildcard any and all Brave or Firefox windows to ws1.
Sticky Windows
A sticky window does pretty much what it says. It sticks to the screen no matter which workspace you are on but only when the listed program is in floating mode. Here is the example from my i3 config:
for_window [instance="^URxvt"] sticky enable
for_window [class="^Brave*"] sticky enable
for_window [class="^Firefox*"] sticky enable
for_window [class="^org.remmina.Remmina"] sticky enable
for_window [class="^Thunar"] sticky enable
for_window [class="^Pcmanfm"] sticky enable
for_window [class="^Arandr"] sticky enable
for_window [title="^WinBox"] sticky enable
Some programs take a little more than just ^program-name like remmina for example.
You can use the xprop program to discover the name of the window that i3 can use.
$ xprop
This will give you a plus sign mouse icon that allows you to click on the window you want to know the information on. Here is my output for my urxvt terminal:
_NET_WM_DESKTOP(CARDINAL) = 0
_NET_WM_STATE(ATOM) =
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_NET_WM_PID(CARDINAL) = 333233
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, _NET_WM_PING
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLASS(STRING) = "urxvt", "URxvt"
WM_HINTS(WM_HINTS):
Client accepts input or input focus: True
Initial state is Normal State.
window id # of group leader: 0x2a0000a
WM_NORMAL_HINTS(WM_SIZE_HINTS):
program specified minimum size: 15 by 26
program specified resize increment: 11 by 22
program specified base size: 4 by 4
window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "wretchedbox"
WM_COMMAND(STRING) = { "urxvt" }
_NET_WM_ICON_NAME(UTF8_STRING) = "waynes@wretchedbox:~"
WM_ICON_NAME(STRING) = "waynes@wretchedbox:~"
_NET_WM_NAME(UTF8_STRING) = "config (~/.config/i3) - VIM"
WM_NAME(STRING) = "config (~/.config/i3) - VIM"
The most important take-away from this is the WM_CLASS(STRING) = “urxvt”, “URxvt” which shows that urxvt needs to written as URxvt in your i3 config file. Other programs can show up with different capitalization structure like midori will only have the first letter capitalized, Midori.
Floating Window Fine Tuning
Using the for_window again we can fine tune how windows are presented when we open the program. Lets use the pcmanfm program.
for_window [class="Pcmanfm"] floating enable
for_window [class="Pcmanfm"] resize set 820 640
This will open pcmanfm in a floating window in the center of the screen at the size of 820x640 pixels which is LengthxHeight.
For gsimplecal, which I have set up by allowing my i3status bar to be clickable to reveal the calendar under the time/date, has been set to floating enabled and to popup under the mouse. The windows has to be taken down by 28px since some of it would get cut off due to it displaying past or above my window screen. Also that size is to compensate for my i3status bar size.
for_window [class="(?i)gsimplecal"] floating enable, move position mouse, move down 28 px
Conclusion
Here we have demonstrated a few advanced examples with using i3. I feel since I have learned and implemented these tweaks my workflow has improved quite a bit.