i3 configs often include bindings to launch applications. For example, to run Konsole terminal when Super+Enter
is pressed, one would add this line to their config:
bindsym --release Mod4+Return exec "konsole"
The standard approach to make windows flaot is to find out the window's class and (optionally) instance name. Running xprop
and clicking on the window would output:
$ euql1n@dominator ~> xprop | grep CLASS
WM_CLASS(STRING) = "konsole", "konsole"
Then, one could force the window to float using for_window
in their config:
for_window [class="konsole"] floating enable
Problem statement
Consider the situation where you don't want all instances of the application to float. For example, you want a floating terminal window to appear on Super+Shift+Enter
key press, and a non-floating on Super+Enter
.
Some programs, like urxvt
and termite
, make this task easy by letting you explicitly specify the instance name. For example, the following lines can be added to the config to get the desired behaviour with termite
:
# Setup key bindings
set $mod=Mod4
bindsym --release $mod+Return exec "termite"
bindsym --release $mod+Shift+Return exec "termite --name=floating"
# Make only the `floating` version of termite float
for_window [class="Termite" instance="floating"] floating enable
Unfortunately, this isn't always possible - konsole
, for example, doesn't take any command line arguments that define the instance name. What do we do in this case?
Solution
The solution is based on this answer. We create a special wrapper script that will force our apps to float. The script will take our desired command as an argument, and will execute it making sure the resultant window is set to float.
You can download the float-runner.sh
from this gist, or simply create file called float-runner.sh
and put this inside:
#!/usr/bin/env bash
# Get the command from arguments
arg_str="$*"
$arg_str &
pid="$!"
# Wait for the window to open and grab its window ID
winid=''
while : ; do
winid="`wmctrl -lp | awk -vpid=$pid '$3==pid {print $1; exit}'`"
[[ -z "${winid}" ]] || break
done
# Focus the window we found
wmctrl -ia "${winid}"
# Make it float
i3-msg floating enable > /dev/null;
# Move it to the center for good measure
i3-msg move position center > /dev/null;
# Wait for the application to quit
wait "${pid}";
I put this script into ~/.config/i3/
directory, but you can put it wherever you want. You might also want to make sure wmctrl
is installed before running it.
Finally, wrap relevant command in your i3 config with this script. For example, to get the behaviour described above with konsole, one would write:
set $mod=Mod4
bindsym --release $mod+Return exec "konsole"
bindsym --release $mod+Shift+Return exec "bash ~/.config/i3/float-runner.sh konsole"
And voila, konsole will float whenever you start it using Super+Shift+Enter
.