Tada.

On Thu, Aug 27, 2009 at 16:46, Julien Danjou<jul...@danjou.info> wrote:
> Seems ok to merge, except that there's still 3 things that I'd like:

> - Configurable history limit (20 is arbitrary)
>  a variable in the module that the user can modify is enough and
>  trivial to add;

Done, setting awful.tag.history.limit does the job.

> - The old behaviour was fine for restore(), this one is totally
>  different since it always goes -1. This can be another
>  feature/keybinding but I think the old one should be restored;

This was a bit tricky but with a bit of argument overloading proved to
be quite nice. I'm not sure if the implementation is clear enough, i
tried to be verbose in comments.

> - Handling of "out of history" not yelling errors. :)

Of course.

As usual please test before merging.

Cheers,
koniu
From 296d98700a6abdd94c180936137738e677df8fd5 Mon Sep 17 00:00:00 2001
From: koniu <gkusni...@gmail.com>
Date: Thu, 27 Aug 2009 15:03:45 +0100
Subject: [PATCH 1/3] awful.tag: fix and improve tag history

This fixes a long standing tag history breakage. To store history
of tag switching we rely on a special signal "tag::history::update"
which needs to be emitted by any function which deals with tag
selection.

History is multi-level with a configurable limit:
awful.tag.history.limit = 20 (by default).

awful.tag.history.restore function gets a new argument 'idx' which can
be either 'previous' (default) which will revert to the previously
selected set of tags, or a numerical index in the tag history table.

Signed-off-by: koniu <gkusni...@gmail.com>
---
 lib/awful/tag.lua.in |   53 +++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/lib/awful/tag.lua.in b/lib/awful/tag.lua.in
index 8ec1bbd..ee27e1d 100644
--- a/lib/awful/tag.lua.in
+++ b/lib/awful/tag.lua.in
@@ -24,12 +24,12 @@ module("awful.tag")
 -- Private data
 local data = {}
 data.history = {}
-data.history.past = {}
 data.history.current = {}
 data.tags = setmetatable({}, { __mode = 'k' })
 
 -- History functions
 history = {}
+history.limit = 20
 
 -- Compare 2 tables of tags.
 -- @param a The first table.
@@ -77,26 +77,50 @@ function new(names, screen, layout)
 end
 
 --- Update the tag history.
--- @param screen The screen number.
-function history.update(screen)
+-- @param obj Screen object.
+function history.update(obj)
+    local screen = obj.index
     local curtags = capi.screen[screen]:tags()
-    if not compare_select(curtags, data.history.current[screen]) then
-        data.history.past[screen] = data.history.current[screen]
-        data.history.current[screen] = {}
-        for k, v in ipairs(curtags) do
-            data.history.current[screen][k] = v.selected
+    if not compare_select(curtags, data.history.current[screen]) and #selectedlist(screen) > 0 then
+        -- create history table
+        if not data.history[screen] then
+          data.history[screen] = {} 
+        -- limit history to 20 steps
+        elseif #data.history[screen] == history.limit then
+            table.remove(data.history[screen])
         end
+        -- store previously selected tags in the history table
+        table.insert(data.history[screen], 1, data.history.current[screen])
+        data.history[screen].previous = data.history[screen][1]
+        -- store currently selected tags
+        data.history.current[screen] = selectedlist(screen)
     end
 end
 
 --- Revert tag history.
 -- @param screen The screen number.
-function history.restore(screen)
+-- @param idx Index in history. Defaults to "previous" which is a special index
+-- toggling between last two selected sets of tags. Number (eg 1) will go back
+-- to the given index in history.
+function history.restore(screen, idx)
     local s = screen or capi.mouse.screen
     local tags = capi.screen[s]:tags()
-    for k, t in pairs(tags) do
-        t.selected = data.history.past[s][k]
+    local i = idx or "previous"
+    local previous = selectedlist(s)
+    -- do nothing if history empty
+    if not data.history[s] or not data.history[s][i] then return end
+    -- deselect all tags
+    viewnone(s)
+    -- select tags from the history entry
+    for _, t in ipairs(data.history[s][i]) do
+        t.selected = true
     end
+    -- update currently selected tags table
+    data.history.current[s] = data.history[s][i]
+    -- store previously selected tags
+    data.history[s]["previous"] = previous
+    -- remove the reverted history entry
+    if i ~= "previous" then table.remove(data.history[s], i) end
 end
 
 --- Return a table with all visible tags
@@ -231,6 +255,7 @@ function viewidx(i, screen)
             showntags[util.cycle(#showntags, k + i)].selected = true
         end
     end
+    capi.screen[screen]:emit_signal("tag::history::update")
 end
 
 --- View next tag. This is the same as tag.viewidx(1).
@@ -250,6 +275,7 @@ end
 function viewonly(t)
     viewnone(t.screen)
     t.selected = true
+    capi.screen[t.screen]:emit_signal("tag::history::update")
 end
 
 --- View only a set of tags.
@@ -260,6 +286,7 @@ function viewmore(tags, screen)
     for i, t in pairs(tags) do
         t.selected = true
     end
+    capi.screen[screen]:emit_signal("tag::history::update")
 end
 
 --- Get tag data table.
@@ -339,6 +366,10 @@ capi.client.add_signal("manage", function(c)
     c:add_signal("property::screen", withcurrent)
 end)
 
+for s = 1, capi.screen.count() do
+    capi.screen[s]:add_signal("tag::history::update", history.update)
+end
+
 setmetatable(_M, { __call = function (_, ...) return new(...) end })
 
 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
-- 
1.6.3.3

From 32371b4ec9303529b8ff47fe716c7eb7173b978a Mon Sep 17 00:00:00 2001
From: koniu <gkusni...@gmail.com>
Date: Thu, 27 Aug 2009 16:16:56 +0100
Subject: [PATCH 2/3] awful.tag: add viewtoggle function

Helper function to toggle tag selection whilst updating history.

Signed-off-by: koniu <gkusni...@gmail.com>
---
 lib/awful/tag.lua.in |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/lib/awful/tag.lua.in b/lib/awful/tag.lua.in
index ee27e1d..d3ae36b 100644
--- a/lib/awful/tag.lua.in
+++ b/lib/awful/tag.lua.in
@@ -289,6 +289,13 @@ function viewmore(tags, screen)
     capi.screen[screen]:emit_signal("tag::history::update")
 end
 
+--- Toggle selection of a tag
+-- @param tag Tag to be toggled
+function viewtoggle(t)
+    t.selected = not t.selected
+    capi.screen[t.screen]:emit_signal("tag::history::update")
+end
+
 --- Get tag data table.
 -- @param tag The Tag.
 -- @return The data table.
-- 
1.6.3.3

From bf5a09e57ee681a061e49e0def95c33258264f7f Mon Sep 17 00:00:00 2001
From: koniu <gkusni...@gmail.com>
Date: Thu, 27 Aug 2009 16:20:14 +0100
Subject: [PATCH 3/3] awesomerc: use awful.tag.viewtoggle

Signed-off-by: koniu <gkusni...@gmail.com>
---
 awesomerc.lua.in |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/awesomerc.lua.in b/awesomerc.lua.in
index 2c32772..724c539 100644
--- a/awesomerc.lua.in
+++ b/awesomerc.lua.in
@@ -78,7 +78,7 @@ mytaglist = {}
 mytaglist.buttons = awful.util.table.join(
                     awful.button({ }, 1, awful.tag.viewonly),
                     awful.button({ modkey }, 1, awful.client.movetotag),
-                    awful.button({ }, 3, function (tag) tag.selected = not tag.selected end),
+                    awful.button({ }, 3, awful.tag.viewtoggle),
                     awful.button({ modkey }, 3, awful.client.toggletag),
                     awful.button({ }, 4, awful.tag.viewnext),
                     awful.button({ }, 5, awful.tag.viewprev)
@@ -247,7 +247,7 @@ for i = 1, keynumber do
                   function ()
                       local screen = mouse.screen
                       if tags[screen][i] then
-                          tags[screen][i].selected = not tags[screen][i].selected
+                          awful.tag.viewtoggle(tags[screen][i])
                       end
                   end),
         awful.key({ modkey, "Shift" }, i,
-- 
1.6.3.3

Reply via email to