Motivation
I use awesome, a tiling window manager to manage the GUI half of my linux environment.
There are some web applications that I use multiple times a day and some that I keep on my screen for monitoring purposes. For a while, it was a tedious task to reboot into my machine, relaunch around 5 separate chromium windows and assign them to a desktop for when I want to look at them. So, I found a way. I will show you how I did it using devdocs.io as an example.
The end result is having a dedicated chrome app window with no toolbar/border that runs if it's not already running:
Getting an instance ID
My first goal was to have some sort of unique identifier for each app. So I dug around the command line options for chromium
(chromium-browser
in Debian).
Turns out you can run any URL with the --app=
option and chromium will automatically assign your URL as the window's instance ID (first index) in its WM_CLASS
.
Or you could save the app as a desktop shortcut and get a more deterministic instance ID. This way, you get an ID similar to what you'd find for chrome apps in chrome://extensions
. That is what I did
and what follows is based on this.
Save the app as a shorcut
Go to your URL (e.g. devdocs.io) and from the chrome menu pick More Tools > Add to Desktop
and check Open as window
This will save a desktop entry on your desktop (if you don't have a desktop folder you have to create it) with content similar to the following:
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=DevDocs API Documentation
Exec=/usr/bin/chromium --profile-directory=Default --app-id=fckabphocaacjhpehedanblllacppdjb
Icon=chrome-fckabphocaacjhpehedanblllacppdjb-Default
StartupWMClass=crx_fckabphocaacjhpehedanblllacppdjb
Perfect! We have our instance ID in there so let's use it to script awesome.
Note: for convenience, I have a folder called webapps in the desktop folder where I move all these desktop entries. For example, $HOME/Desktop/webapps/devdocs.desktop
Awesome: run web apps if not running
Now that we know what the instance ID is for a web app, we can use wmctrl
to find it.
wmctrl -l -x
will list all your running windows along with their (instance, class) pairs.
Since we will be using outputs from standard commands let's define a function that gives us the output of a command:
function command_output(command)
local fh = io.popen(command)
local str = ""
for i in fh:lines() do
str = str .. i
end
io.close(fh)
return str
end
Define an idempotent function that we can safely call every time awesome is reloaded:
function run_webapp_once(webapp_file)
instance = webapp_instance(webapp_file)
if instance_running(instance) then
return
else
awful.util.spawn(webapp_exec_cmd(webapp_file))
end
end
Define the helper functions:
function webapp_exec_cmd(webapp_file)
instance = command_output('sed -n "s/Exec=\\(.*\\)$/\\1/p" ' .. webapp_file)
return instance
end
function webapp_instance(webapp_file)
instance = command_output('sed -n "s/StartupWMClass=\\(.*\\)$/\\1/p" ' .. webapp_file)
return instance
end
function instance_running(instance)
count = command_output("wmctrl -l -x | grep " .. instance .. " | wc -l")
return count ~= "0"
end
-- Example function that returns path to a *.desktop entry
function webapp_file(app_name)
return "~/Desktop/webapps/" .. app_name
end
Note that we use the desktop entry's content to get the instance ID and the command we execute.
After you have defined those functions then having your web applications launched on startup is as easy as creating a desktop shortcut and adding two lines to your rc.lua:
devdocs = webapp_file("devdocs") -- get the path to file
run_webapp_once(devdocs)
Awesome: assign them to a tag
If you are not familiar with awesome rules, then find the
table awful.rules.rules
in your rc.lua
. We will add the following rule to this table:
{ rule = { instance = webapp_instance(devdocs) },
properties = { tag = tags[3] and tags[3][2] } },
This basically tells awesome to assign the window with the
devdocs instance (instance = ...
) to desktop 2 on monitor 3 (tag[3][2]
).
Reload awesome (default: CtrlMetaR) and your windows should launch successfully.