Swapping all clients between Awesome tags

Default Awesome config has a shortcut to move a single client to another tag by pressing modkey+Shift+# where # is the tag number (1-9): for example, pressing modkey+Shift+3 will move current client to 3rd tag.

While that is undoubtedly useful, you may want to move all clients at once, or actually just swap clients between tags.

Not a big deal, let's code it.

local function swap_clients(target_tag_index)
    local screen = mouse.screen
    local from_tag = awful.screen.focused().selected_tag
    local to_tag = screen.tags[target_tag_index]

    if to_tag then
        t = to_tag:clients()

        for i, c in ipairs(from_tag:clients()) do
            awful.client.movetotag(to_tag, c)
        end
        for i, c in ipairs(t) do
            awful.client.movetotag(from_tag, c)
        end

        local from_ncol = awful.tag.getncol(from_tag)
        awful.tag.setncol(awful.tag.getncol(to_tag), from_tag)
        awful.tag.setncol(from_ncol, to_tag)

        local from_mwfact = awful.tag.getmwfact(from_tag)
        awful.tag.setmwfact(awful.tag.getmwfact(to_tag), from_tag)
        awful.tag.setmwfact(from_mwfact, to_tag)

        local from_nmaster = awful.tag.getnmaster(from_tag)
        awful.tag.setnmaster(awful.tag.getnmaster(to_tag), from_tag)
        awful.tag.setnmaster(from_nmaster, to_tag)

        local from_layout = from_tag.layout
        from_tag.layout = to_tag.layout
        to_tag.layout = from_layout

        awful.tag.viewonly(to_tag)
    end
end

This function not only exchanges clients between tags but also preserves layout.

Find where the modkey+Shift+# shortcut is registered (look for the globalkeys table inside a for loop) and bind our new feature to modkey+Ctrl+#:

    -- Swap clients.
    awful.key({ modkey, "Control" }, "#" .. i + 9,
              function ()
                  swap_clients(i)
              end, {}),

You can also bind modkey+Ctrl+Left and modkey+Ctrl+Right to move the current tag left or right (or, in other words, to swap clients with previous or next tag). Add this to the globalkeys table somewhere outside the loop:

    awful.key({ modkey, "Control" }, "Right",
              function ()
                  local sel = awful.screen.focused().selected_tag
                  local idx = awful.tag.getidx(sel)
                  swap_clients(idx + 1)
              end, {}),

    awful.key({ modkey, "Control" }, "Left",
              function ()
                  local sel = awful.screen.focused().selected_tag
                  local idx = awful.tag.getidx(sel)
                  swap_clients(idx - 1)
              end, {}),

Bingo. Restart Awesome and control your tags like a pro, lol.

If you have any comments, contact me by email.