4

I am using archlinux in combination with awesome-wm for quite a while now. I still haven't figured out how to automatically grab the focus on an application when changing workspace through Mod+number.

For example, I have firefox running on workspace 2 and some terminals on workspace 1. If I am in workspace 2 and press Mod+1 to go to workspace 1, no terminal is focussed. I can ofcourse click on a terminal to grab focus, or press Mod+j or Mod+k, but I would like this to happen automatically.

How can I make this possible? Thanks in advance!

4

I figured it out so I will answer my own question. This might not be the best or most efficient way, but it gets the job done. This question might fit more on stackoverflow since it is more focussed on programming.

I wrote this function, which grabs focus on the first client on screen (except for Conky, the system monitor I use).

-- Grab focus on first client on screen
function grab_focus()
    local all_clients = client.get()
    for i, c in pairs(all_clients) do
        if c:isvisible() and c.class ~= "Conky" then
            client.focus = c
        end
    end
end

I now call this function in rc.lua where the numbered keys are mapped:

-- Bind all key numbers to tags.
...
if tags[screen][i] then
    awful.tag.viewonly(tags[screen][i])
    grab_focus()
end
1

Thank you very much Carlito, I've been struggling around the whole afternoon to solve this problem, and your function works perfectly.

I just call it by itself "grab_focus()" into the keybinding "for" cycle I want to.

I use Awesome 3.5 with Shifty, this is how I fixed it (please notice "grab_focus()"):

-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.

   for i = 1, (shifty.config.maxtags or 9) do
    globalkeys = awful.util.table.join(globalkeys,
        awful.key({ modkey }, "#" .. i + 9,
                  function ()
                      awful.tag.viewonly(shifty.getpos(i))
                      grab_focus()
                end),
        awful.key({ modkey, "Control" }, "#" .. i + 9,
                  function ()
                      awful.tag.viewtoggle(shifty.getpos(i))
                  end),
        awful.key({ modkey, "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus then
                          local t = shifty.getpos(i)
                          awful.client.movetotag(t)
                          awful.tag.viewonly(t)
                       end
                  end),
        awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus then
                          awful.client.toggletag(shifty.getpos(i))
                      end
                  end))
end
1

I found the previously mentioned method to work poorly on multiscreen setups as the isvisible check also checks other screens.

After looking around the API documentation I arrived at this solution

Disclaimer: I don't have much experience with awesome and this is my first attempt at doing anything that isn't a copy-paste. So far for me it is working nicely though.

for k,t in pairs(awful.tag.gettags(s)) do t:connect_signal("property::selected", function(t) local c = t.clients(t)[1] if c then client.focus = c end end) end

where 's' is the screen. Do this for each screen. I have it in the same loop as tag setup in the standard rc.lua.

Basically loop through the tags of a screen and add an event listener for when the tag gets selected, which then fires the function which gets the first client connected to the tag and sets it as the focused client.

I am using awesome 3.5 and there are some differences to be aware of if you are using previous versions. In 3.4 for example the connect_signal function is named add_signal.

This solution automatically works when switching tags through other means to as it connects a listener to the operation of switching tags itself.

  • Remember to properly format your answer. Use a right angle bracket > before each line of a block quote, and indent code blocks with four spaces – bwDraco Dec 7 '14 at 19:55
  • Thanks. I'm not that known with the rules and best practices here. – Reaver Dec 7 '14 at 20:01
0

What I don't like with these solutions is that they don't always focus the client under the mouse.

The best solution I found is that script that you just have to put in your rc.lua :

tag.connect_signal(
"property::selected",
  function (t)
    local selected = tostring(t.selected) == "false"
    if selected then
     local focus_timer = timer({ timeout = 0.2 })
     focus_timer:connect_signal("timeout", function()
    local c = awful.mouse.client_under_pointer()
    if not (c == nil) then
      client.focus = c
      c:raise()
    end
    focus_timer:stop()
  end)
  focus_timer:start()
 end
end)
0

I use something like this to grab automatically focus on tag change

tag.connect_signal("property::selected", function() focus_on_last_in_history(mouse.screen) end)

and this one to refocus when closing a window on a tag

client.connect_signal("unmanage", function() focus_on_last_in_history(mouse.screen) end)

function focus_on_last_in_history( screen )
  local c = awful.client.focus.history.get(screen, 0)
  if not (c == nil) then
    client.focus = c
    c:raise()
  end
end
0

With the latest 4.0 version of awesome, none of these solutions were working.

Here is one that will automatically focus whichever client is under your mouse whenever you switch tags/workspaces.

tag.connect_signal("property::selected", function (t)
    local selected = tostring(t.selected) == "true"
    if selected then
        local mouseX = mouse.coords().x
        local mouseY = mouse.coords().y
        for k,v in pairs(t.screen.all_clients) do
            if v.first_tag.index==t.index and mouseX>=v.x and mouseX<=(v.x+v.width) and mouseY>=v.y and mouseY<=(v.y+v.height) then
                client.focus = v
                v:raise()
            end
        end
    end
end)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.