Initial commit.

This commit is contained in:
Vincent Bernat 2012-07-06 14:19:54 +02:00
commit c130561cb7
17 changed files with 1029 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*~
/wallpapers

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "themes/nice-and-clean-theme"]
path = themes/nice-and-clean-theme
url = https://github.com/waf/nice-and-clean-theme/

89
bin/build-wallpaper Executable file
View file

@ -0,0 +1,89 @@
#!/usr/bin/env python
# Build a multi screen wallpaper
# First argument is the directory where the wallpapers can be
# found. We use xinerama to know the dimension of each screen.
import sys
import os
import re
import random
import string
import subprocess
import optparse
import xcb
import xcb.xproto
import xcb.xinerama
import Image
parser = optparse.OptionParser()
parser.add_option("-d", "--directory", dest="directory", default=".",
help="search for images in DIRECTORY", metavar="DIRECTORY")
parser.add_option("-t", "--target", dest="target", default="background.jpg",
help="write background to FILE", metavar="FILE")
parser.add_option("-c", "--crop", dest="crop", action="store_true",
help="crop image instead of centering them")
options, args = parser.parse_args()
assert not args, "No additional arguments are accepted"
background = None
# Get display size
display = xcb.connect()
root = display.get_setup().roots[0]
background = Image.new('RGB', (root.width_in_pixels, root.height_in_pixels))
# Query xinerama (not randr since the query is longer)
try:
xinerama = display(xcb.xinerama.key)
except xcb.ExtensionException:
xinerama = None
if not xinerama or not xinerama.IsActive().reply().state:
screens = [(background.size[0], background.size[1], 0, 0)]
else:
screens = [(screen.width, screen.height, screen.x_org, screen.y_org)
for screen in xinerama.QueryScreens().reply().screen_info]
screens.sort(key=lambda screen: -screen[0]*screen[1])
# Get as many random image as we have screens
images = []
for root, _, files in os.walk(os.path.join(options.directory)):
for i in files:
if string.lower(os.path.splitext(i)[1]) in ('.jpg',
'.jpeg',
'.png'):
images.append(os.path.join(root, i))
images = random.sample(images,
len(screens) + \
random.randint(0, 3)) # Randomly favor larger images
images = [Image.open(os.path.join(options.directory,
image)) for image in images]
images.sort(key=lambda image: -image.size[0]*image.size[1])
for index in range(len(screens)):
x, y, offsetx, offsety = screens[index]
image = images[index]
# Find the right size for the screen
imx, imy = x, image.size[1]*x/image.size[0]
if (options.crop and imy < y) or (not options.crop and imy > y):
imx, imy = image.size[0]*y/image.size[1], y
image = image.resize((imx, imy), Image.CUBIC)
if options.crop:
image = image.crop(((imx-x)/2, (imy-y)/2,
imx-(imx-x)/2, imy-(imy-y)/2))
# Include it
if options.crop:
background.paste(image, (offsetx, offsety))
else:
background.paste(image, ((x-imx)/2 + offsetx,
(y-imy)/2 + offsety))
# Save
assert background, "Don't know the size of the display area"
background.save(options.target)

50
rc.lua Normal file
View file

@ -0,0 +1,50 @@
require("awful")
require("awful.autofocus")
require("awful.rules")
require("beautiful")
require("naughty")
-- Simple function to load additional LUA files from rc/.
function loadrc(name)
local success
local result
local path = awful.util.getdir("config") .. "/rc/" .. name .. ".lua"
success, result = pcall(function() return dofile(path) end)
if not success then
return print("E: error loading RC file '" .. name .. "': " .. result)
end
return result
end
-- Error handling
loadrc("errors")
-- Global configuration
modkey = "Mod4"
config = {}
config.terminal = table.concat({"urxvtcd",
"++iso14755 +sb -si -sw -j -fn fixed -sl 2000",
"-fade 40 -sh 30 -bc -tint white -fg white -depth 32",
"--color4 RoyalBlue --color12 RoyalBlue",
"-bg rgba:0000/0000/0000/bbbb -fadecolor rgba:0000/0000/0000/6666"},
" ")
config.layouts = {
awful.layout.suit.tile,
awful.layout.suit.magnifier,
awful.layout.suit.floating,
}
config.hostname = awful.util.pread('uname -n'):gsub('\n', '')
-- Remaining modules
loadrc("theme")
loadrc("start")
loadrc("bindings")
loadrc("wallpaper")
loadrc("tags")
loadrc("widgets")
loadrc("xlock")
loadrc("signals")
loadrc("rules")
root.keys(config.keys.global)
startapps()

74
rc/bindings.lua Normal file
View file

@ -0,0 +1,74 @@
config.keys = {}
config.mouse = {}
config.keys.global = awful.util.table.join(
-- Tag navigation
awful.key({ modkey, }, "Left", awful.tag.viewprev ),
awful.key({ modkey, }, "Right", awful.tag.viewnext ),
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
-- Focus
awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
-- Layout manipulation
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
awful.key({ modkey, }, "space", function () awful.layout.inc(config.layouts, 1) end),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(config.layouts, -1) end),
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
end),
-- Spawn a terminal
awful.key({ modkey, }, "Return", function () awful.util.spawn(config.terminal) end),
-- Restart awesome
awful.key({ modkey, "Control" }, "r", awesome.restart)
)
config.keys.client = awful.util.table.join(
awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
awful.key({ modkey, }, "x", function (c) c:kill() end),
awful.key({ modkey, }, "o", awful.client.movetoscreen ),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end),
awful.key({ modkey, }, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
end),
awful.key({ modkey, }, "i",
function (c)
-- The client currently has the input focus, so it cannot be
-- minimized, since minimized clients can't have the focus.
c.minimized = true
end)
)
config.mouse.client = awful.util.table.join(
awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
awful.button({ modkey }, 1, awful.mouse.client.move),
awful.button({ modkey }, 3, awful.mouse.client.resize))

31
rc/errors.lua Normal file
View file

@ -0,0 +1,31 @@
require("awesome")
require("naughty")
-- 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
local in_error = false
awesome.add_signal("debug::error", function (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)
end
function dbg(vars)
local text = ""
for i=1, #vars do text = text .. vars[i] .. " | " end
naughty.notify({ text = text, timeout = 0 })
end

21
rc/rules.lua Normal file
View file

@ -0,0 +1,21 @@
awful.rules.rules = {
-- All clients will match this rule.
{ rule = { },
properties = { border_width = beautiful.border_width,
border_color = beautiful.border_normal,
focus = true,
keys = config.keys.client,
buttons = config.mouse.client }},
{ rule = { class = "Emacs" },
properties = { tag = config.tags.emacs }},
{ rule = { name = "Iceweasel" },
properties = { tag = config.tags.www }},
{ rule = { name = "Firefox" },
properties = { tag = config.tags.www }},
{ rule = { name = "Chromium" },
properties = { tag = config.tags.www }},
{ rule = { class = "Pidgin" },
properties = { tag = config.tags.im }},
{ rule = { class = "URxvt" },
properties = { }, callback = awful.client.setslave },
}

356
rc/sharetags.lua Normal file
View file

@ -0,0 +1,356 @@
-- functions to share tags on multiple screens
--{{{ Grab environment we need
local capi = { widget = widget,
screen = screen,
image = image,
client = client,
button = button }
local setmetatable = setmetatable
local math = math
local type = type
local pcall = pcall
local util = require("awful.util")
local tag = require("awful.tag")
local beautiful = require("beautiful")
local layout = require("awful.widget.layout")
local awful = require("awful")
local mouse = mouse
local pairs = pairs
local ipairs = ipairs
--}}}
module("sharetags")
--{{{ Private structures
tagwidgets = setmetatable({}, { __mode = 'k' })
local cachedtags = {}
label = {}
--}}}
--{{{ Functions
--{{{ create_tags: create a table of tags and bind them to screens
-- @param names : list to label the tags
-- @param layouts : list of layouts for the tags
-- @return table of tag objects
function create_tags(names, layouts)
local tags = {}
local count = #names
if capi.screen.count() >= #names then
count = capi.screen.count() + 1
end
for tagnumber = 1, count do
tags[tagnumber] = awful.tag.add(names[tagnumber], {})
tag.setproperty(tags[tagnumber], "number", tagnumber)
-- Add tags to screen one by one
tags[tagnumber].screen = 1
awful.layout.set(layouts[tagnumber], tags[tagnumber])
end
for s = 1, capi.screen.count() do
-- I'm sure you want to see at least one tag.
tags[s].screen = s
tags[s].selected = true
end
cachedtags = tags
return tags
end
--}}}
--{{{ tag_move: move a tag to a screen
-- @param t : the tag object to move
-- @param scr : the screen object to move to
function tag_move(t, scr)
local ts = t or awful.tag.selected()
local screen_target = scr or awful.util.cycle(capi.screen.count(), ts.screen + 1)
if ts.screen and screen_target ~= ts.screen then
-- switch for tag
ts.screen = screen_target
-- switch for all clients on tag
if #ts:clients() > 0 then
for _ , c in ipairs(ts:clients()) do
if not c.sticky then
c.screen = screen_target
c:tags( {ts} )
else
awful.client.toggletag(ts,c)
end
end
end
end
end
--}}}
--{{{ tag_to_screen: move a tag to a screen if its not already there
-- @param t : the tag object to move
-- @param scr : the screen object to move to
function tag_to_screen(t, scr)
local ts = t or awful.tag.selected()
local screen_origin = ts.screen
local screen_target = scr or awful.util.cycle(capi.screen.count(), ts.screen + 1)
awful.tag.history.restore(ts.screen,1)
-- move the tag only if we are on a different screen
if screen_origin ~= screen_target then
tag_move(ts, screen_target)
end
awful.tag.viewonly(ts)
mouse.screen = ts.screen
if #ts:clients() > 0 then
local c = ts:clients()[1]
capi.client.focus = c
end
end
--}}}
--{{{ Return labels for a taglist widget with all tag from screen.
-- It returns the tag name and set a special
-- foreground and background color for selected tags.
-- @param t The tag.
-- @param args The arguments table.
-- bg_focus The background color for selected tag.
-- fg_focus The foreground color for selected tag.
-- bg_urgent The background color for urgent tags.
-- fg_urgent The foreground color for urgent tags.
-- squares_sel Optional: a user provided image for selected squares.
-- squares_unsel Optional: a user provided image for unselected squares.
-- squares_resize Optional: true or false to resize squares.
-- @return A string to print, a background color, a background image and a
-- background resize value.
function label.all(t, args)
if not args then args = {} end
local theme = beautiful.get()
local fg_focus = args.fg_focus or theme.taglist_fg_focus or theme.fg_focus
local bg_focus = args.bg_focus or theme.taglist_bg_focus or theme.bg_focus
local fg_urgent = args.fg_urgent or theme.taglist_fg_urgent or theme.fg_urgent
local bg_urgent = args.bg_urgent or theme.taglist_bg_urgent or theme.bg_urgent
local bg_occupied = args.bg_occupied or theme.taglist_bg_occupied
local fg_occupied = args.fg_occupied or theme.taglist_fg_occupied
local taglist_squares_sel = args.squares_sel or theme.taglist_squares_sel
local taglist_squares_unsel = args.squares_unsel or theme.taglist_squares_unsel
local taglist_squares_resize = theme.taglist_squares_resize or args.squares_resize or "true"
local font = args.font or theme.taglist_font or theme.font or ""
local text = "<span font_desc='"..font.."'>"
local sel = capi.client.focus
local bg_color = nil
local fg_color = nil
local bg_image
local icon
local bg_resize = false
local is_selected = false
if not args.screen then
args.screen = t.screen
end
if t.selected and t.screen == args.screen then
bg_color = bg_focus
fg_color = fg_focus
end
if sel and sel.type ~= "desktop" then
if taglist_squares_sel then
-- Check that the selected clients is tagged with 't'.
local seltags = sel:tags()
for _, v in ipairs(seltags) do
if v == t then
bg_image = capi.image(taglist_squares_sel)
bg_resize = taglist_squares_resize == "true"
is_selected = true
break
end
end
end
end
if not is_selected then
local cls = t:clients()
if #cls > 0 then
if taglist_squares_unsel then
bg_image = capi.image(taglist_squares_unsel)
bg_resize = taglist_squares_resize == "true"
end
if bg_occupied then bg_color = bg_occupied end
if fg_occupied then fg_color = fg_occupied end
end
for k, c in pairs(cls) do
if c.urgent then
if bg_urgent then bg_color = bg_urgent end
if fg_urgent then fg_color = fg_urgent end
break
end
end
end
if not tag.getproperty(t, "icon_only") then
if fg_color then
text = text .. "<span color='"..util.color_strip_alpha(fg_color).."'>"
text = " " .. text.. (util.escape(t.name) or "") .." </span>"
else
text = text .. " " .. (util.escape(t.name) or "") .. " "
end
end
text = text .. "</span>"
if tag.geticon(t) and type(tag.geticon(t)) == "image" then
icon = tag.geticon(t)
elseif tag.geticon(t) then
icon = capi.image(tag.geticon(t))
end
return text, bg_color, bg_image, icon
end
--}}}
--{{{ list_update: update a list of widgets
-- @param screen : the screen to draw the taglist for
-- @param w : the widget container
-- @param label : label function to use
-- @param buttons : a table with button bindings to set
-- @param widgets : a table with widget style parameters
-- @param objects : the list of tags to be displayed
-- @param scr : the current screen
local function list_update(w, buttons, label, data, widgets, objects, scr)
-- Hack: if it has been registered as a widget in a wibox,
-- it's w.len since __len meta does not work on table until Lua 5.2.
-- Otherwise it's standard #w.
local len = (w.len or #w) / 2
-- Add more widgets
if len < #objects then
for i = len * 2 + 1, #objects * 2, 2 do
local ib = capi.widget({ type = "imagebox", align = widgets.imagebox.align })
local tb = capi.widget({ type = "textbox", align = widgets.textbox.align })
w[i] = ib
w[i + 1] = tb
w[i + 1]:margin({ left = widgets.textbox.margin.left, right = widgets.textbox.margin.right })
w[i + 1].bg_resize = widgets.textbox.bg_resize or false
w[i + 1].bg_align = widgets.textbox.bg_align or ""
if type(objects[math.floor(i / 2) + 1]) == "tag" then
tagwidgets[ib] = objects[math.floor(i / 2) + 1]
tagwidgets[tb] = objects[math.floor(i / 2) + 1]
end
end
-- Remove widgets
elseif len > #objects then
for i = #objects * 2 + 1, len * 2, 2 do
w[i] = nil
w[i + 1] = nil
end
end
-- update widgets text
for k = 1, #objects * 2, 2 do
local o = objects[(k + 1) / 2]
if not o then
o = objects[(k-1) / 2]
end
if buttons then
-- Use a local variable so that the garbage collector doesn't strike
-- between now and the :buttons() call.
local btns = data[o]
if not btns then
btns = {}
data[o] = btns
for kb, b in ipairs(buttons) do
-- Create a proxy button object: it will receive the real
-- press and release events, and will propagate them the the
-- button object the user provided, but with the object as
-- argument.
local btn = capi.button { modifiers = b.modifiers, button = b.button }
btn:add_signal("press", function () b:emit_signal("press", o) end)
btn:add_signal("release", function () b:emit_signal("release", o) end)
btns[#btns + 1] = btn
end
end
w[k]:buttons(btns)
w[k + 1]:buttons(btns)
end
args = { screen = scr }
local text, bg, bg_image, icon = label(o, args)
-- Check if we got a valid text here, it might contain e.g. broken utf8.
if not pcall(function() w[k + 1].text = text end) then
w[k + 1].text = "<i>Invalid</i>"
end
w[k + 1].bg, w[k + 1].bg_image = bg, bg_image
w[k].bg, w[k].image = bg, icon
if not w[k + 1].text then
w[k+1].visible = false
else
w[k+1].visible = true
end
if not w[k].image then
w[k].visible = false
else
w[k].visible = true
end
end
end
--}}}
--{{{ taglist_update: update the taglist widget
-- @param screen : the screen to draw the taglist for
-- @param w : the taglist widget
-- @param label : label function to use
-- @param buttons : a table with button bindings to set
-- @param widgets : a table with widget style parameters
-- @param objects : the list of tags to be displayed
local function taglist_update (screen, w, label, buttons, data, widgets)
list_update(w, buttons, label, data, widgets, cachedtags, screen)
end
--}}}
--{{{ taglist: create a taglist widget for the shared tags
-- @param screen : the screen to draw the taglist for
-- @param label : label function to use
-- @param buttons : a table with button bindings to set
function taglist(screen, label, buttons)
local w = {
layout = layout.horizontal.leftright
}
local widgets = { }
widgets.imagebox = { }
widgets.textbox = { ["margin"] = { ["left"] = 0,
["right"] = 0},
["bg_resize"] = true
}
local data = setmetatable({}, { __mode = 'kv' })
local u = function (s)
if s == screen then
taglist_update(s, w, label, buttons, data, widgets)
end
end
local uc = function (c) return u(c.screen) end
capi.client.add_signal("focus", uc)
capi.client.add_signal("unfocus", uc)
tag.attached_add_signal(screen, "property::selected", uc)
tag.attached_add_signal(screen, "property::icon", uc)
tag.attached_add_signal(screen, "property::hide", uc)
tag.attached_add_signal(screen, "property::name", uc)
capi.screen[screen]:add_signal("tag::attach", function(screen, tag)
u(screen.index)
end)
capi.screen[screen]:add_signal("tag::detach", function(screen, tag)
u(screen.index)
end)
capi.client.add_signal("new", function(c)
c:add_signal("property::urgent", uc)
c:add_signal("property::screen", function(c)
-- If client change screen, refresh it anyway since we don't from
-- which screen it was coming :-)
u(screen)
end)
c:add_signal("tagged", uc)
c:add_signal("untagged", uc)
end)
capi.client.add_signal("unmanage", uc)
u(screen)
return w
end
--}}}
--}}}
-- vim: fdm=marker:

29
rc/signals.lua Normal file
View file

@ -0,0 +1,29 @@
-- Signal function to execute when a new client appears.
client.add_signal("manage",
function (c, startup)
-- Enable sloppy focus
c:add_signal("mouse::enter",
function(c)
if ((awful.layout.get(c.screen) ~= awful.layout.suit.magnifier or awful.client.getmaster(c.screen) == c)
and awful.client.focus.filter(c)) then
client.focus = c
end
end)
if not startup then
-- Put windows in a smart way, only if they does not set an initial position.
if not c.size_hints.user_position and not c.size_hints.program_position then
awful.placement.no_overlap(c)
awful.placement.no_offscreen(c)
end
end
end)
client.add_signal("focus", function(c)
c.border_color = beautiful.border_focus
c.opacity = 1
end)
client.add_signal("unfocus", function(c)
c.border_color = beautiful.border_normal
c.opacity = 0.8
end)

79
rc/start.lua Normal file
View file

@ -0,0 +1,79 @@
-- Startup
-- run a command only if the client does not already exist
xrun = function(name, cmd)
if os.execute("xwininfo -name '" .. name .. "' > /dev/null 2> /dev/null") == 0 then
return
end
awful.util.spawn_with_shell(cmd or name)
end
-- Setup display
local xrandr = {
naruto = "--output VGA1 --auto --output DVI1 --auto --left-of VGA1",
neo = "--output HDMI-0 --auto --output DVI-0 --auto --right-of HDMI-0"
}
if xrandr[config.hostname] then
os.execute("xrandr " .. xrandr[config.hostname])
end
-- Spawn a composoting manager
awful.util.spawn("unagi", false)
-- Start idempotent commands
local execute = {
-- Start PulseAudio
"pulseaudio --check || pulseaudio -D",
"xset -b", -- Disable bell
-- Enable numlock
"numlockx on",
}
if config.hostname == "naruto" then
execute = awful.util.table.join(
execute, {
-- Keyboard configuration
"xset m 4 3", -- Mouse acceleration
"setxkbmap us '' compose:rwin ctrl:nocaps",
"xmodmap -e 'keysym Pause = XF86ScreenSaver'" })
elseif config.hostname == "neo" then
execute = awful.util.table.join(
execute, {
-- Keyboard configuration
"xset m 3 3", -- Mouse acceleration
"setxkbmap us '' compose:rwin ctrl:nocaps",
"xmodmap -e 'keysym Pause = XF86ScreenSaver'"})
elseif config.hostname == "guybrush" then
execute = awful.util.table.join(
execute, {
-- Keyboard configuration
"setxkbmap us '' compose:rctrl ctrl:nocaps",
"xmodmap -e 'keysym XF86AudioPlay = XF86ScreenSaver'",
-- Wheel emulation
"xinput set-int-prop 'TPPS/2 IBM TrackPoint' 'Evdev Wheel Emulation' 8 1",
"xinput set-int-prop 'TPPS/2 IBM TrackPoint' 'Evdev Wheel Emulation Button' 8 2",
"xinput set-int-prop 'TPPS/2 IBM TrackPoint' 'Evdev Wheel Emulation Axes' 8 6 7 4 5",
-- Disable touchpad
"xinput set-int-prop 'SynPS/2 Synaptics TouchPad' 'Synaptics Off' 8 1"})
end
os.execute(table.concat(execute, ";"))
-- Spawn various X programs
startapps = function()
xrun("polkit-gnome-authentication-agent-1",
"/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1")
xrun("Bluetooth Applet",
"bluetooth-applet")
if config.hostname == "naruto" then
xrun("Pidgin", "pidgin")
elseif config.hostname == "neo" then
xrun("Pidgin", "pidgin")
xrun("keepassx", "keepassx -min -lock")
xrun("Transmission", "transmission-gtk -m")
elseif config.hostname == "guybrush" then
xrun("keepassx", "keepassx -min -lock")
-- xrun("nm-applet")
end
end

55
rc/tags.lua Normal file
View file

@ -0,0 +1,55 @@
-- Tags
loadrc("sharetags")
local tags = { names = { "main", "emacs", "www", "im", 5 },
layout = { awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.tile,
awful.layout.suit.tile }}
tags = sharetags.create_tags(tags.names, tags.layout)
config.tags = {}
-- Compute the maximum number of digit we need, limited to 9
keynumber = math.min(9, #tags)
-- 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, #tags do
config.tags[tags[i].name] = tags[i]
if i <= keynumber then
config.keys.global = awful.util.table.join(
config.keys.global,
awful.key({ modkey }, "#" .. i + 9,
function ()
local t = tags[i]
if t.screen ~= mouse.screen then
sharetags.tag_move(t, mouse.screen)
end
awful.tag.viewonly(tags[i])
end),
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
if tags[i] then
awful.tag.viewtoggle(tags[i])
end
end),
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[i] then
awful.client.movetotag(tags[i])
end
end),
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[i] then
awful.client.toggletag(tags[i])
end
end))
end
end
awful.tag.setproperty(config.tags.emacs, "mwfact", 0.6) -- emacs
awful.tag.setproperty(config.tags.www, "mwfact", 0.7) -- www

33
rc/theme.lua Normal file
View file

@ -0,0 +1,33 @@
-- Theme
beautiful.init(awful.util.getdir("config") .. "/themes/custom.lua")
-- GTK stuff: we choose Adwaita theme which seems to be the only one
-- kept up-to-date with GTK2 and GTK3...
-- Also see: http://developer.gnome.org/gtk3/3.2/GtkSettings.html
local gtk = 'gtk-font-name="' .. beautiful.font .. '"' .. [[
gtk-theme-name="Adwaita"
gtk-icon-theme-name="gnome-wine"
gtk-cursor-theme-name="oxy-cherry"
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_BOTH
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=1
gtk-menu-images=1
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle="hintfull"
gtk-xft-rgba="rgb"
gtk-key-theme-name="Emacs"
]]
local gtk2 = io.open(os.getenv("HOME") .. "/.gtkrc-2.0", "w")
gtk2:write(gtk)
gtk2:close()
-- GTK3 is the same, but no double quotes for strings
local gtk3 = io.open(os.getenv("HOME") .. "/.config/gtk-3.0/settings.ini")
gtk3:write("[Settings]\n")
gtk3:write(gtk:gsub('"', ''))
gtk3:close()

25
rc/wallpaper.lua Normal file
View file

@ -0,0 +1,25 @@
-- Change wallpaper
local wtimer = timer { timeout = 0 }
config.wallpaper = {}
config.wallpaper.directory = awful.util.getdir("config") .. "/wallpapers"
config.wallpaper.current = awful.util.getdir("cache") .. "/current-wallpaper.png"
-- We use fvwm-root because default backend for awsetbg does not seem
-- to accept to set multiscreen wallpapers.
local change = function()
awful.util.spawn_with_shell(
awful.util.getdir("config") .. "/bin/build-wallpaper " ..
"--crop --directory " .. config.wallpaper.directory ..
" --target " .. config.wallpaper.current ..
"&& fvwm-root -r " .. config.wallpaper.current)
end
wtimer:add_signal("timeout", function()
change()
wtimer:stop()
wtimer.timeout = math.random(3000, 3600)
wtimer:start()
end)
wtimer:start()

150
rc/widgets.lua Normal file
View file

@ -0,0 +1,150 @@
-- Widgets
require("vicious")
-- Separator
local separator = widget({ type = "textbox" })
separator.text = ' <span color="' .. beautiful.fg_widget_sep .. '">|</span> '
-- Date
local datewidget = widget({ type = "textbox" })
vicious.register(datewidget, vicious.widgets.date,
'<span font="Terminus 8" color="' .. beautiful.fg_widget_clock .. '">%a %d/%m, %H:%M</span>', 61)
-- CPU usage
local cpuwidget = widget({ type = "textbox" })
cpuwidget.text = '<span font="Terminus 8" color="' .. beautiful.fg_widget_label .. '">CPU: </span>'
local cpugraph = awful.widget.graph()
cpugraph:set_width(45):set_height(12):set_max_value(100)
cpugraph:set_border_color(beautiful.fg_widget_border)
cpugraph:set_gradient_angle(0):set_gradient_colors({
beautiful.fg_widget_start, beautiful.fg_widget_center, beautiful.fg_widget_end
})
vicious.register(cpugraph, vicious.widgets.cpu, "$1")
local cpuvalue = widget({ type = "textbox" })
vicious.register(cpuvalue, vicious.widgets.cpu,
function (widget, args)
return string.format('<span font="Terminus 8" color="' ..
beautiful.fg_widget_value ..
'"> %2d%%</span>', args[1])
end)
-- Battery
local batwidget = nil
if config.hostname == "guybrush" then
batwidget = widget({ type = "textbox" })
vicious.register(batwidget, vicious.widgets.bat,
'<span font="Terminus 8" color="' .. beautiful.fg_widget_label .. '">BAT: </span>' ..
'<span font="Terminus 8" color="' .. beautiful.fg_widget_value .. '">$1 $2%</span>',
61, "BAT0")
end
-- Memory usage
local memwidget = widget({ type = "textbox" })
vicious.register(memwidget, vicious.widgets.mem,
'<span font="Terminus 8" color="' .. beautiful.fg_widget_label .. '">Mem: </span>' ..
'<span font="Terminus 8" color="' .. beautiful.fg_widget_value .. '">$1%</span>',
13)
-- Volume level
local volwidget = widget({ type = "textbox" })
vicious.register(volwidget, vicious.widgets.volume,
'<span font="Terminus 8" color="' .. beautiful.fg_widget_label .. '">Vol: </span>' ..
'<span font="Terminus 8" color="' .. beautiful.fg_widget_value .. '">$2 $1%</span>',
2, "Master")
volwidget:buttons(awful.util.table.join(
awful.button({ }, 1, function () awful.util.spawn("pavucontrol", false) end),
awful.button({ }, 4, function () awful.util.spawn("amixer -q -c 0 set Master 2dB+", false) end),
awful.button({ }, 5, function () awful.util.spawn("amixer -q -c 0 set Master 2dB-", false) end)
))
local systray = widget({ type = "systray" })
-- {{{ Wibox initialisation
local wibox = {}
local promptbox = {}
local layoutbox = {}
local taglist = {}
taglist.buttons = awful.util.table.join(
awful.button({ }, 1,
function(t)
if t.screen ~= mouse.screen then
sharetags.tag_move(t, mouse.screen)
end
awful.tag.viewonly(t)
end),
awful.button({ modkey }, 1, awful.client.movetotag),
awful.button({ }, 3,
function(t)
if t.screen ~= mouse.screen then
sharetags.tag_move(t, mouse.screen)
end
awful.tag.viewtoggle(t)
end),
awful.button({ modkey }, 3, awful.client.toggletag),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev))
local tasklist = {}
tasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if c == client.focus then
c.minimized = true
else
if not c:isvisible() then
awful.tag.viewonly(c:tags()[1])
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end))
for s = 1, screen.count() do
promptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright })
layoutbox[s] = awful.widget.layoutbox(s)
tasklist[s] = awful.widget.tasklist(
function(c)
return awful.widget.tasklist.label.currenttags(c, s)
end, tasklist.buttons)
-- Create the taglist
taglist[s] = sharetags.taglist(s, sharetags.label.all, taglist.buttons)
-- Create the wibox
wibox[s] = awful.wibox({ screen = s,
fg = beautiful.fg_normal,
bg = beautiful.bg_widget,
position = "top",
height = 14,
})
-- Add widgets to the wibox
local onfirst = function(what)
if s == 1 then return what end
return nil
end
local onsecond = function(what)
if s == 2 or screen.count() == 1 then return what end
return nil
end
wibox[s].widgets = {
{
taglist[s], layoutbox[s],
separator, promptbox[s],
layout = awful.widget.layout.horizontal.leftright
},
onfirst(systray), onfirst(seperator),
datewidget, separator,
onsecond(volwidget), onsecond(separator),
onsecond(batwidget), onsecond(batwidget and separator or nil),
onfirst(memwidget), onfirst(separator),
onfirst(cpuvalue), onfirst(cpugraph.widget), onfirst(cpuwidget), onfirst(separator),
tasklist[s], separator,
layout = awful.widget.layout.horizontal.rightleft }
end
config.keys.global = awful.util.table.join(
config.keys.global,
awful.key({ modkey }, "r", function () promptbox[mouse.screen]:run() end))

9
rc/xlock.lua Normal file
View file

@ -0,0 +1,9 @@
-- Lockscreen
xrun("xautolock",
"xautolock -time 5 -locker 'i3lock -n -i " ..
awful.util.getdir("cache") .. "/current-wallpaper.png'")
config.keys.global = awful.util.table.join(
config.keys.global,
awful.key({}, "XF86ScreenSaver", function() awful.util.spawn("xautolock -locknow", false) end))

22
themes/custom.lua Normal file
View file

@ -0,0 +1,22 @@
-- Small modifications to anrxc's zenburn theme
local theme = loadrc("../themes/nice-and-clean-theme/theme")
if theme then
theme.wallpaper_cmd = { "/bin/true" }
theme.font = "Cantarell 9"
theme.bg_normal = theme.bg_normal .. "99"
theme.bg_focus = theme.bg_focus .. "99"
theme.bg_urgent = theme.bg_urgent .. "99"
theme.bg_minimize = theme.bg_minimize .. "99"
theme.bg_widget = "#00000099"
theme.fg_widget_label = "#708090"
theme.fg_widget_value = "#FFFFFF"
theme.fg_widget_sep = "#FFFFFF"
theme.fg_widget_border = "#FFFFFF"
theme.fg_widget_clock = "#FF7F00"
theme.fg_widget_end = "#FFFFFF"
theme.fg_widget_center = "#FFCCCC"
theme.fg_widget_start = "#FF0000"
return theme
end

@ -0,0 +1 @@
Subproject commit 687d77ae6c2c2cfc38ca85f226006244384560d6