Run or raise

From awesome

Jump to: navigation, search

Some clients you don't want more than one of (Firefox springs to mind). The function run_or_raise starts the client if it is not running, otherwise it makes that client visible, or if there a multiple matching clients running it will cycle through them.

Caveat: I haven't tested this on multiple screens yet, it may fail miserably...

--- Spawns cmd if no client can be found matching properties
-- If such a client can be found, pop to first tag where it is visible, and give it focus
-- @param cmd the command to execute
-- @param properties a table of properties to match against clients.  Possible entries: any properties of the client object
function run_or_raise(cmd, properties)
   local clients = client.get()
   local focused = awful.client.next(0)
   local findex = 0
   local matched_clients = {}
   local n = 0
   for i, c in pairs(clients) do
      --make an array of matched clients
      if match(properties, c) then
         n = n + 1
         matched_clients[n] = c
         if c == focused then
            findex = n
         end
      end
   end
   if n > 0 then
      local c = matched_clients[1]
      -- if the focused window matched switch focus to next in list
      if 0 < findex and findex < n then
         c = matched_clients[findex+1]
      end
      local ctags = c:tags()
      if table.getn(ctags) == 0 then
         -- ctags is empty, show client on current tag
         local curtag = awful.tag.selected()
         awful.client.movetotag(curtag, c)
      else
         -- Otherwise, pop to first tag client is visible on
         awful.tag.viewonly(ctags[1])
      end
      -- And then focus the client
      client.focus = c
      c:raise()
      return
   end
   awful.util.spawn(cmd)
end

-- Returns true if all pairs in table1 are present in table2
function match (table1, table2)
   for k, v in pairs(table1) do
      if table2[k] ~= v and not table2[k]:find(v) then
         return false
      end
   end
   return true
end

Usage example:

keybinding({"Mod4"}, "f", function () run_or_raise("firefox", { class = "Firefox" }) end):add()

note: the above keybinding didn't work for me, I had to add the following to line to the globalkeys table in my ~/.config/awesome/rc.lua:

awful.key({ modkey,}, "f", function () run_or_raise("firefox", { class = "Firefox" }) end),

The following are the keybindings I have for google-chrome that use the substring matching with the NAME attribute. They allow me to cycle through my web browser windows seperately from my gmail, and evernote windows. Hotkey launching, or raising, of evernote and gmail is very sweet:

awful.key({ modkey, }, "w", function () run_or_raise("google-chrome", { name = "Google Chrome" }) end),
awful.key({ modkey, }, "v", function () run_or_raise("google-chrome --app='http://www.evernote.com/Home.action?login=true'", { name = "Evernote" }) end),
awful.key({ modkey, }, "g", function () run_or_raise("google-chrome --app='http://mail.google.com/mail/'", { name = "Gmail" }) end),
Personal tools