Add awesome configuration
authorFabien Ninoles <fabien@tzone.org>
Mon, 27 Oct 2014 12:54:34 -0400
changeset 7 03125e413ae3
parent 6 8daa0d8b9a0e
child 8 0eae48be1d62
Add awesome configuration
.hgignore
awesome/my.lua
awesome/rc.lua
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Mon Oct 27 12:54:34 2014 -0400
@@ -0,0 +1,5 @@
+syntax: glob
+
+*.ps
+*.xkb
+*.xkm
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/awesome/my.lua	Mon Oct 27 12:54:34 2014 -0400
@@ -0,0 +1,266 @@
+require("naughty")
+require("awful")
+require("debug")
+require("vicious")
+require("wicked")
+require("beautiful")
+
+local ipairs = ipairs
+local pairs = pairs
+local naughty = naughty
+local awful = awful
+local debug = debug
+local vicious = vicious
+local wicked = wicked
+local beautiful = beautiful
+
+local capi = {
+   keygrabber = keygrabber,
+   client = client,
+   string = string,
+   widget = widget,
+}
+
+module("my")
+
+local in_error = false
+function notify_error(err)
+   -- Make sure we don't go into an endless error loop
+   if in_error then return end
+   in_error = true
+
+   naughty.notify({ preset = naughty.config.presets.critical,
+                    title = "Oops, an error happened!",
+                    text = err })
+   in_error = false
+end
+
+function mkspawn(p)
+   return function () awful.util.spawn(p) end
+end
+
+function setxkbmap(kb)
+   XKBDIR="$HOME/.xkb"
+   -- Strange bug on xkbcomp: pushing directly the output to the display
+   -- lead to an error; We need to convert it first to .xkb and then feed
+   -- xkbcomp again for setting the x display
+   p = 'setxkbmap "' .. kb .. " -print | xkbcomp -xkb -a -I" .. XKBDIR .. " - - | kxbcomp - $DISPLAY"
+   awful.util.spawn_with_shell(p)
+end
+
+function kill_all(rule)
+   for c in awful.client.iterate(rule) do
+      c:kill()
+   end
+end
+
+function quit()
+   kill_all(awful.rules.any)
+   awesome.quit()
+end
+
+function show_clients()
+   if instance then
+      instance:hide()
+      instance = nil
+   else
+      instance = awful.menu.clients({width=250})
+   end
+end
+
+local function widgets_cpu()
+   local w = awful.widget.graph()
+   -- Graph properties
+   w:set_width(30)
+   w:set_background_color("#729fcf")
+   w:set_gradient_colors({ "#729fcf", "LightBlue", "white" })
+-- Register widget
+   vicious.register(w, vicious.widgets.cpu, "$1", 1)
+   return w
+end
+
+local function widgets_mdp()
+   -- Initialize widget
+   local w = capi.widget({ type = "textbox" })
+   -- Register widget
+   vicious.register(w, vicious.widgets.mpd,
+                    function (widget, args)
+                       if args["{state}"] == "Stop" then 
+                          return " - "
+                       else 
+                          return args["{Artist}"]..' - '.. args["{Title}"]
+                       end
+                    end, 10)
+   return w
+end
+
+local function widgets_mem(monitor)
+-- Initialize widget
+   local w = awful.widget.progressbar()
+-- Progressbar properties
+   w:set_width(10)
+   w:set_vertical(true)
+   w:set_background_color("#729fcf")
+   w:set_gradient_colors({ "#729fcf", "LightBlue", "white" })
+-- Register widget
+   vicious.register(w, vicious.widgets.mem, "$1", 5)
+   return w
+end
+
+local function widgets_net(device)
+   local w = capi.widget({ type = "textbox"})
+   -- w:set_vertical(true)
+   w.width = 150
+   w.align = 'center'
+   vicious.register(w, wicked.widgets.net,
+                    '${' .. device .. ' up} / ${' .. device .. ' down}',
+                   1)
+   return w
+end
+
+local function widgets_mode()
+   local w = capi.widget({ type = "textbox"})
+   widgets.mode_widget = w
+   return w
+end
+
+local function widgets_keyboard()
+   local w = capi.widget({ type = "textbox"})
+   widgets.keyboard_widget = w
+   return w
+end
+
+local function widgets_decorated(w, onclick)
+   local wg = w
+   if w.widget then
+      wg = w.widget
+   end
+   wg:buttons(awful.util.table.join(
+                awful.button({}, 1, onclick)))
+   return w
+end
+
+widgets = {
+   cpu = widgets_cpu,
+   mem = widgets_mem,
+   net = widgets_net,
+   mdp = widgets_mdp,
+   mode = widgets_mode,
+   keyboard = widgets_keyboard,
+   decorated = widgets_decorated,
+}
+
+function make_key(k, n, f)
+   return { key = k, name = n, func = f}
+end
+
+function show_kt(keytable, title)
+   -- todo: replace with a menu ?
+   text = ""
+   for _, k in ipairs(keytable) do
+      text = text .. "\'" .. k.key .. "\'\t" .. k.name .. "\n"
+   end
+   naughty.notify({text = text, 
+                   title = title, 
+                   position = "top_left",
+   })
+end
+
+local keynames = {
+   [" "] = "space",
+   ["\t"] = "tab",
+}
+
+local function translate_key(mod, key)
+   local skey = ""
+   for m,v in pairs(mod) do
+      if v then 
+         skey = skey .. v .. "+"
+      end
+   end
+   skey = skey .. (keynames[key] or key)
+   return skey
+end
+
+local function kt_handler(keytable, mod, key, event)
+   if event == "release" then 
+      return true 
+   end
+   local theme = beautiful.get()
+   widgets.mode_widget.bg = theme.bg_focus
+   if key == "Escape" then   
+      return false
+   end
+   local skey = capi.string.lower(translate_key(mod, key))
+   if skey == "control+h" or skey == "shift+?" then
+      show_kt(keytable, "Current binding")
+      return true
+   end
+   for _,k in ipairs(keytable) do
+      if skey == capi.string.lower(k.key) then
+         return k.func(c)
+      end
+   end
+   -- notify_error("Nothing for " .. skey)
+   widgets.mode_widget.bg = theme.bg_urgent
+   return true
+end
+
+local function stop_kt()
+   capi.keygrabber.stop()
+   widgets.mode_widget.visible = false
+end
+
+function mkinteractive(f)
+  return function (c)
+     stop_kt()
+     return f(c)
+  end
+end
+
+
+-- local is_in_run_kt = false
+function run_kt(c, keytable, title)
+   widgets.mode_widget.text = "Mode: " .. title
+   widgets.mode_widget.visible = true
+   widgets.mode_widget.bg = "LightBlue"
+   widgets.mode_widget:buttons(
+      awful.util.table.join(
+         awful.button({}, 1, function () show_kt(keytable, "Binding") end),
+         awful.button({}, 3, stop_kt)))
+   capi.keygrabber.run(function (mod, key, event)
+         if not kt_handler(keytable, mod, key, event) then
+            stop_kt()
+            return false
+         end
+         return true
+   end)
+end
+
+function make_kt(keytable, title)
+   return function (c) 
+      -- if is_in_run_kt then
+      --    -- notify_error("Already in run_kt:\n" .. debug.traceback())
+      --    is_in_run_kt = false -- reset
+      --    return false
+      -- end
+      return run_kt(c, keytable, title)
+   end
+end
+
+function make_focus_bydirection(direction)
+   return function ()
+      awful.client.focus.bydirection(direction)
+      if capi.client.focus then capi.client.focus:raise() end
+      return true
+   end
+end
+
+function make_globalkeys(modifiers, keytable)
+   local t = {}
+   for _,k in ipairs(keytable) do
+      t = awful.util.table.join(t, awful.key(modifiers, k.key, k.func))
+   end
+   return t
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/awesome/rc.lua	Mon Oct 27 12:54:34 2014 -0400
@@ -0,0 +1,645 @@
+require("debug")
+--
+-- Standard awesome library
+require("awful")
+require("awful.autofocus")
+-- Theme handling library
+require("beautiful")
+-- Notification library
+require("naughty")
+-- shifty - dynamic tagging library
+require("shifty")
+-- Revelation
+require("revelation")
+-- vicious widgets
+local vicious = require("vicious")
+local wicked = require("wicked")
+-- Load Debian menu entries
+require("debian.menu")
+
+-- require("keychains")
+
+require("my")
+
+-- {{{ Error handling
+-- Check if awesome encountered an error during startup and fell back to
+-- another config (This code will only ever execute for the fallback config)
+if awesome.startup_errors then
+   naughty.notify({ preset = naughty.config.presets.critical,
+                    title = "Oops, there were errors during startup!",
+                    text = awesome.startup_errors })
+end
+
+-- Handle runtime errors after startup
+do
+   awesome.add_signal("debug::error", my.notify_error)
+end
+-- }}}
+
+-- Variable definitions
+-- Themes define colours, icons, and wallpapers
+-- The default is a dark theme
+-- theme_path = "/usr/share/awesome/themes/default/theme.lua"
+-- Uncommment this for a lighter theme
+theme_path = "/usr/share/awesome/themes/sky/theme.lua"
+
+-- This is used later as the default terminal and editor to run.
+terminal = "x-terminal-emulator"
+editor = os.getenv("EDITOR") or "editor"
+editor_cmd = terminal .. " -e " .. editor
+browser = "iceweasel"
+mail = "icedove"
+musicplayer = "ario"
+monitor = "gnome-system-monitor"
+filemanager = "pcmanfm"
+lookup = "pcmanfm -f"
+calculator = "galculator"
+
+-- Default modkey.
+-- Usually, Mod4 is the key with a logo between Control and Alt.
+-- If you do not like this or do not have such a key, I suggest you to remap
+-- Mod4 to another key using xmodmap or other tools.  However, you can use
+-- another modifier like Mod1, but it may interact with others.
+modkey = "Mod4"
+
+wallpaper_dir = "/home/fabien/themes/backgrounds/"
+wallpaper = wallpaper_dir .. "universalis_1024_jsh.jpg"
+
+-- Actually load theme
+beautiful.init(theme_path)
+beautiful.get().wallpaper_cmd = { "awsetbg -a " .. wallpaper }
+awful.util.spawn_with_shell("pgrep unagi || unagi &")
+
+
+-- Table of layouts to cover with awful.layout.inc, order matters.
+layouts =
+   {
+      awful.layout.suit.tile,
+      awful.layout.suit.tile.left,
+      awful.layout.suit.tile.bottom,
+      awful.layout.suit.tile.top,
+      awful.layout.suit.fair,
+      awful.layout.suit.fair.horizontal,
+      awful.layout.suit.max,
+      awful.layout.suit.max.fullscreen,
+      awful.layout.suit.magnifier,
+      awful.layout.suit.floating
+   }
+
+-- Define if we want to use titlebar on all applications.
+use_titlebar = true
+
+-- Shifty configured tags.
+shifty.config.tags = {
+   w1 = {
+      layout    = awful.layout.suit.tile,
+      mwfact    = 0.60,
+      exclusive = false,
+      position  = 1,
+      init      = true,
+      screen    = 1,
+      slave     = true,
+   },
+   web = {
+      layout      = awful.layout.suit.tile.bottom,
+      mwfact      = 0.65,
+      exclusive   = true,
+      max_clients = 1,
+      position    = 4,
+      spawn       = browser,
+   },
+   mail = {
+      layout    = awful.layout.suit.tile,
+      mwfact    = 0.55,
+      exclusive = false,
+      position  = 5,
+      spawn     = mail,
+      slave     = true
+   },
+   media = {
+      layout    = awful.layout.suit.float,
+      exclusive = false,
+      position  = 8,
+      spawn     = musicplayer
+   },
+   office = {
+      layout   = awful.layout.suit.tile,
+      position = 9,
+   },
+   steam = {
+      layout      = awful.layout.suit.max,
+      mwfact      = 0.65,
+      exclusive   = true,
+      spawn       = "steam",
+      position    = 6,
+   },
+}
+
+-- SHIFTY: application matching rules
+-- order here matters, early rules will be applied first
+shifty.config.apps = {
+   {
+      match = {
+         "Navigator",
+         "Vimperator",
+         "Gran Paradiso",
+      },
+      float = false,
+      tag = "web",
+   },
+   {
+      match = {
+         "Shredder.*",
+         "Thunderbird",
+         "Icedove",
+         "mutt",
+      },
+      tag = "mail",
+   },
+   {
+      match = {
+         "pcmanfm",
+      },
+      slave = true
+   },
+   {
+      match = {
+         "OpenOffice.*",
+         "Abiword",
+         "Gnumeric",
+      },
+      tag = "office",
+   },
+   {
+      match = {
+         "Mplayer.*",
+         "Mirage",
+         "gimp",
+         "gtkpod",
+         "Ufraw",
+         "easytag",
+         "Ario",
+      },
+      tag = "media",
+      nopopup = true,
+   },
+   {
+      match = {
+         "MPlayer",
+         "Gnuplot",
+         "galculator",
+         "speedcrunch"
+      },
+      float = true,
+   },
+   {
+      match = { "emacs" },
+      tag = "emacs"
+   },
+   {
+      match = {
+         terminal,
+      },
+      honorsizehints = false,
+      slave = true,
+   },
+   {
+      match = { "Steam" },
+      tag = "steam",
+   },
+   {
+      match = {""},
+      buttons = awful.util.table.join(
+         awful.button({}, 1, function (c) client.focus = c; c:raise() end),
+         awful.button({modkey}, 1, function(c)
+               client.focus = c
+               c:raise()
+               awful.mouse.client.move(c)
+         end),
+         awful.button({modkey}, 3, awful.mouse.client.resize)
+      )
+   },
+}
+
+-- SHIFTY: default tag creation rules
+-- parameter description
+--  * floatBars : if floating clients should always have a titlebar
+--  * guess_name : should shifty try and guess tag names when creating
+--                 new (unconfigured) tags?
+--  * guess_position: as above, but for position parameter
+--  * run : function to exec when shifty creates a new tag
+--  * all other parameters (e.g. layout, mwfact) follow awesome's tag API
+shifty.config.defaults = {
+   layout = awful.layout.suit.tile.bottom,
+   ncol = 1,
+   mwfact = 0.60,
+   floatBars = true,
+   guess_name = true,
+   guess_position = true,
+}
+
+--  Wibox
+-- Create a textbox widget
+mytextclock = awful.widget.textclock({align = "right"})
+
+-- Create a laucher widget and a main menu
+myawesomemenu = {
+   {"manual", terminal .. " -e man awesome"},
+   {"edit config",
+    editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua"},
+   {"restart", awesome.restart},
+   {"quit", my.quit}
+}
+
+mymainmenu = awful.menu(
+   {
+      items = {
+         {"awesome", myawesomemenu, beautiful.awesome_icon},
+         { "Debian", debian.menu.Debian_menu.Debian },
+         {"open terminal", terminal}}
+})
+
+mylauncher = awful.widget.launcher({image = image(beautiful.awesome_icon),
+                                    menu = mymainmenu})
+
+-- Create a systray
+mysystray = widget({type = "systray", align = "right"})
+
+-- Create a wibox for each screen and add it
+mywibox = {}
+mypromptbox = {}
+mylayoutbox = {}
+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({modkey}, 3, awful.client.toggletag),
+   awful.button({}, 4, awful.tag.viewnext),
+   awful.button({}, 5, awful.tag.viewprev)
+)
+
+mytasklist = {}
+mytasklist.buttons = awful.util.table.join(
+   awful.button({}, 1, function(c)
+         if not c:isvisible() then
+            awful.tag.viewonly(c:tags()[1])
+         end
+         client.focus = c
+         c:raise()
+   end),
+   awful.button({modkey}, 3, my.show_clients),
+   awful.button({}, 3, function(c)
+         c.minimized = not c.minimized
+   end),
+   awful.button({}, 4, function()
+         awful.client.focus.byidx(1)
+         if client.focus then client.focus:raise() end
+   end),
+   awful.button({}, 5, function()
+         awful.client.focus.byidx(-1)
+         if client.focus then client.focus:raise() end
+end))
+
+local mycpuwidget = my.widgets.decorated(my.widgets.cpu(), my.mkspawn(monitor))
+local mymemwidget = my.widgets.decorated(my.widgets.mem(), my.mkspawn(monitor))
+local mynetwidget = my.widgets.decorated(my.widgets.net("eth1"), my.mkspawn(monitor))
+-- local mynetupwidget = my.decorated_monitor_widget(make_netwidget("eth1", "up"))
+-- local mynetdownwidget = my.decorated_monitor_widget(make_netwidget("eth1", "down"))
+local myktwidget = my.widgets.mode()
+
+for s = 1, screen.count() do
+   awful.util.spawn("awsetbg -a " .. wallpaper, false, s)
+
+   -- status box
+
+   -- Create a promptbox for each screen
+   mypromptbox[s] =
+      awful.widget.prompt({layout = awful.widget.layout.leftright})
+   -- Create an imagebox widget which will contains an icon indicating which
+   -- layout we're using.  We need one layoutbox per screen.
+   mylayoutbox[s] = awful.widget.layoutbox(s)
+   mylayoutbox[s]:buttons(awful.util.table.join(
+                             awful.button({}, 1, function() awful.layout.inc(layouts, 1) end),
+                             awful.button({}, 3, function() awful.layout.inc(layouts, -1) end),
+                             awful.button({}, 4, function() awful.layout.inc(layouts, 1) end),
+                             awful.button({}, 5, function() awful.layout.inc(layouts, -1) end)))
+   -- Create a taglist widget
+   mytaglist[s] = awful.widget.taglist.new(s,
+                                           awful.widget.taglist.label.all,
+                                           mytaglist.buttons)
+
+   -- Create a tasklist widget
+   mytasklist[s] = awful.widget.tasklist.new(
+      function(c)
+        return awful.widget.tasklist.label.currenttags(c, s)
+      end,
+      mytasklist.buttons)
+
+
+   -- Create the wibox
+   mywibox[s] = awful.wibox({position = "top", screen = s})
+   -- Add widgets to the wibox - order matters
+   mywibox[s].widgets = {
+      {
+         myktwidget,
+         mylauncher,
+         s == 1 and mycpuwidget or nil,
+         s == 1 and mymemwidget or nil,
+         mytaglist[s],
+         mypromptbox[s],
+         layout = awful.widget.layout.horizontal.leftright
+      },
+      mylayoutbox[s],
+      s == 1 and mynetwidget or nil,
+      mytextclock,
+      s == 1 and mysystray or nil,
+      mytasklist[s],
+      layout = awful.widget.layout.horizontal.rightleft
+   }
+
+   mywibox[s].screen = s
+end
+
+-- SHIFTY: initialize shifty
+-- the assignment of shifty.taglist must always be after its actually
+-- initialized with awful.widget.taglist.new()
+shifty.taglist = mytaglist
+shifty.init()
+
+-- Mouse bindings
+root.buttons(awful.util.table.join(
+                awful.button({}, 3, function() mymainmenu:toggle() end),
+                awful.button({}, 4, awful.tag.viewnext),
+                awful.button({}, 5, awful.tag.viewprev)
+))
+
+-- key tables
+
+local tagkeys = {
+   -- Shifty: keybindings specific to shifty
+   my.make_key("n", "Send to Next Tag", shifty.send_next), -- client to next tag
+   my.make_key("a", "Add tag", my.mkinteractive(shifty.add)), -- create a new tag
+   my.make_key("r", "Rename tag", my.mkinteractive(shifty.rename)), -- rename a tag
+   my.make_key("d", "Delete tag", shifty.del),
+   my.make_key("Shift+A", "Add tag (no popup)", -- nopopup new tag
+            my.mkinteractive(function() shifty.add({nopopup = true}) end)),
+   my.make_key("Up", "View prev",
+            function () awful.tag.viewprev(); return true; end),
+   my.make_key("Down", "View next", 
+            function () awful.tag.viewnext(); return true; end),
+   my.make_key("Shift+Up", "Move tag left", 
+            function()
+               local t = awful.tag.selected()
+               local s = awful.util.cycle(screen.count(), t.screen + 1)
+               awful.tag.history.restore()
+               t = shifty.tagtoscr(s, t)
+               awful.tag.viewonly(t)
+               return true
+   end),
+   my.make_key("Shift+Right", "Move tag left", 
+            function()
+               local t = awful.tag.selected()
+               local s = awful.util.cycle(screen.count(), t.screen + 1)
+               awful.tag.history.restore()
+               t = shifty.tagtoscr(s, t)
+               awful.tag.viewonly(t)
+               return true
+   end),
+}
+
+local awesome_keys = {
+   my.make_key("m", "Menu", my.mkinteractive(function () 
+               mymainmenu:show({keygrabber=true}) 
+               return true
+   end)),
+   -- my.make_key("k", "Kill all clients", 
+   --             function () 
+   --                for client.
+   --                my.kill_all(function (c)
+   my.make_key("r", "Restart", awesome.restart),
+   my.make_key("q", "Quit", awesome.quit),
+   my.make_key("t", "Terminal", my.mkspawn(terminal)),
+}
+
+local layout_keys = {
+   my.make_key("Right", "Focus right",
+            function () awful.client.focus.bydirection("right"); return true end),
+   my.make_key("Left", "Focus left",
+            function () awful.client.focus.bydirection("left"); return true end),
+   my.make_key("Up", "Focus up",
+            function () awful.client.focus.bydirection("up"); return true end),
+   my.make_key("Down", "Focus down",
+            function () awful.client.focus.bydirection("down"); return true end),
+   my.make_key("Shift+Right", "Move right",
+            function () awful.client.swap.bydirection("right"); return true end),
+   my.make_key("Shift+Left", "Move left",
+            function () awful.client.swap.bydirection("left"); return true end),
+   my.make_key("Shift+Up", "Move up",
+            function () awful.client.swap.bydirection("up"); return true end),
+   my.make_key("Shift+Down", "Move down",
+            function () awful.client.swap.bydirection("down"); return true end),
+   -- my.make_key("Right", "Focus next",
+   --          function () awful.client.focus.byidx(1); return true end),
+   -- my.make_key("Left", "Focus prev",
+   --          function () awful.client.focus.byidx(-1); return true end),
+   -- my.make_key("Shift+Right", "Move next", 
+   --          function() awful.client.swap.byidx(1); return true end),
+   -- my.make_key("Shift+Left", "Move previous", 
+   --          function() awful.client.swap.byidx(-1); return true end),
+   -- my.make_key("Shift+Right", "Move next", 
+   --          function() awful.screen.focus(1); return true end),
+   -- my.make_key("Shift+Left", "Move previous", 
+   --          function() awful.screen.focus(-1); return true end),
+   my.make_key("c", "Master grow",
+            function() awful.tag.incmwfact(0.05); return true end),
+   my.make_key("z", "Master shrink",
+            function() awful.tag.incmwfact(-0.05); return true end),
+   my.make_key("Shift+c", "Add master windows", 
+            function() awful.tag.incnmaster(1); return true end),
+   my.make_key("Shift+z", "Remove master windows",
+            function() awful.tag.incnmaster(-1); return true end),
+   my.make_key("Control+c", "Add column",
+            function() awful.tag.incncol(1); return true end),
+   my.make_key("Control+z", "Remove column", 
+            function() awful.tag.incncol(-1); return true end),
+   my.make_key("Space", "Next layout", 
+            function() awful.layout.inc(layouts, 1); return true end),
+   my.make_key("Shift+_", "Previous layout", 
+            function() awful.layout.inc(layouts, -1) ; return true end),
+}
+
+media_keys = {
+   -- media keys
+   my.make_key("XF86HomePage", "Browser", my.mkspawn(browser)),
+   my.make_key("XF86Mail", "Mail", my.mkspawn(mail)),
+   my.make_key("XF86Search", "Search file...", my.mkspawn(lookup)),
+   my.make_key("XF86Explorer", "File Manager", my.mkspawn(filemanager)),
+   my.make_key("XF86Calculator", "Calculator", my.mkspawn(calculator)),
+   my.make_key("XF86Tools", "Music", my.mkspawn(musicplayer)),
+   my.make_key("XF86AudioPrev", "Previous song", my.mkspawn("mpc prev")),
+   my.make_key("XF86AudioNext", "Next song", my.mkspawn("mpc next")),
+   my.make_key("XF86AudioPlay", "Play song", my.mkspawn("mpc toggle")),
+   my.make_key("XF86AudioMute", "Mute", my.mkspawn("pulseaudio-ctl mute")),
+   my.make_key("XF86AudioLowerVolume", "Volume down", my.mkspawn("pulseaudio-ctl down")),
+   my.make_key("XF86AudioRaiseVolume", "Volume up", my.mkspawn("pulseaudio-ctl up")),
+   my.make_key("XF86Eject", "Eject", my.mkspawn("eject")),
+}
+
+global_table = {
+   my.make_key("Escape", "Restore History", awful.tag.history.restore),
+   my.make_key("e", "Revel windows", revelation),
+   my.make_key("c", "Previous tag", awful.tag.viewprev),
+   my.make_key("z", "Next tag", awful.tag.viewnext),
+   my.make_key("Right", "Right client", my.make_focus_bydirection("right")),
+   my.make_key("Left", "Left client", my.make_focus_bydirection("left")),
+   my.make_key("Up", "Up client", my.make_focus_bydirection("up")),
+   my.make_key("Down", "Down client", my.make_focus_bydirection("down")),
+   my.make_key("u", "Jump to urgent", awful.client.urgent.jumpto),
+   my.make_key("Tab", "Previous client", 
+            function()
+               awful.client.focus.history.previous()
+               if client.focus then
+                  client.focus:raise()
+               end
+   end),
+
+   -- Prompt
+   my.make_key("F2", "Run...", function()
+               awful.prompt.run({prompt = "Run: "},
+                  mypromptbox[mouse.screen].widget,
+                  awful.util.spawn, awful.completion.shell,
+                  awful.util.getdir("cache") .. "/history")
+   end),
+
+   my.make_key("F3", "Eval...", function()
+               awful.prompt.run({prompt = "Run Lua code: "},
+                  mypromptbox[mouse.screen].widget,
+                  awful.util.eval, nil,
+                  awful.util.getdir("cache") .. "/history_eval")
+   end),
+
+   -- modal key binding
+   my.make_key("a", "Main mode", my.make_kt(awesome_keys, "awesome") ),
+   my.make_key("t", "Tag mode...", my.make_kt(tagkeys, "tag") ),
+   my.make_key("l", "layout mode...", my.make_kt(layout_keys, "layout") ),
+}
+
+client_keytable = {
+   my.make_key("F4", "Kill client", 
+            function(c) c:kill() end),
+   my.make_key("k", "Kill client", 
+            function(c) c:kill() end),
+   my.make_key("f", "Toggle fullscreen", 
+            function(c) c.fullscreen = not c.fullscreen  end),
+   my.make_key("space", "Toggle floating", 
+            awful.client.floating.toggle),
+   my.make_key("m", "Toggle maximize", 
+      function(c)
+         c.maximized_horizontal = not c.maximized_horizontal
+         c.maximized_vertical   = not c.maximized_vertical
+   end),
+   my.make_key("h", "Toggle minimized",
+               function (c)
+                  c.minimized = not c.minimized
+   end),
+   my.make_key("Return", "Swap master", 
+            function(c)
+               c:swap(awful.client.getmaster())
+   end),
+   my.make_key("o", "Move to screen", awful.client.movetoscreen),
+}
+
+-- Key bindings
+globalkeys = awful.util.table.join(
+   awful.key({modkey}, "F1", function () my.show_kt(global_table, "Global binding") end),
+   my.make_globalkeys({modkey}, global_table),
+   my.make_globalkeys({}, media_keys), 
+   -- forcing restart of mpd.
+   -- it sometime have difficulty to connect to pulse
+   awful.key({modkey}, "F6", function ()
+   	awful.util.spawn("pkill -9 mpd")
+	awful.util.spawn("mpd")
+	end)
+   )
+
+
+-- Client awful tagging: this is useful to tag some clients and then do stuff
+-- like move to tag on them
+clientkeys = awful.util.table.join(
+   awful.key({modkey, "Shift"}, "F1", 
+      function () my.show_kt(client_keytable, "Client binding") end),
+   my.make_globalkeys({modkey}, client_keytable),
+   awful.key({modkey, "Shift"}, "r", function(c) c:redraw() end),
+   awful.key({modkey, "Shift"}, "t", awful.client.togglemarked))
+
+
+-- SHIFTY: assign client keys to shifty for use in
+-- match() function(manage hook)
+shifty.config.clientkeys = clientkeys
+shifty.config.modkey = modkey
+
+-- Compute the maximum number of digit we need, limited to 10
+local number_row = { 
+   '"', '<', '>', '(', ')',
+   '@', '+', '-', '/', '*'
+}
+
+for i = 1, (shifty.config.maxtags or #number_row) do
+   local k = number_row[i-1]
+   globalkeys = awful.util.table.join(
+      globalkeys,
+      awful.key({modkey}, k, function()
+            local t =  awful.tag.viewonly(shifty.getpos(i))
+      end),
+      awful.key({modkey, "Control"}, k, function()
+            local t = shifty.getpos(i)
+            t.selected = not t.selected
+      end),
+      awful.key({modkey, "Control", "Shift"}, k, function()
+            if client.focus then
+               awful.client.toggletag(shifty.getpos(i))
+            end
+      end),
+      -- move clients to other tags
+      awful.key({modkey, "Shift"}, k, function()
+            if client.focus then
+               t = shifty.getpos(i)
+               awful.client.movetotag(t)
+               awful.tag.viewonly(t)
+            end
+   end))
+end
+
+-- Set keys
+-- mympdwidget:append_global_keys()
+-- keychains.init(globalkeys,{})
+root.keys(globalkeys)
+
+-- local function kt2kc(kt)
+--    t = {}
+--    for _,k in ipairs(kt) do
+--       t[k.key] = { func = k.func, info = key.desc }
+--    end
+--    return t
+-- end
+-- keychains.add({modkey}, "w", "Awesome", nil, kt2kc(awesome_keys))
+-- keychains.start(5)
+
+-- Hook function to execute when focusing a client.
+client.add_signal("focus", 
+                  function(c)
+                     if not awful.client.ismarked(c) then
+                        c.border_color = beautiful.border_focus
+                        c.opacity = 1.0
+                     end
+end)
+
+-- Hook function to execute when unfocusing a client.
+client.add_signal("unfocus", function(c)
+                     if not awful.client.ismarked(c) then
+                        c.border_color = beautiful.border_normal
+                        c.opacity = 0.8
+                     end
+end)
+