awesome/rc.lua
changeset 7 03125e413ae3
child 8 0eae48be1d62
--- /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)
+