guest@dotshare [~/groups/wms/awesome] $ ls Mr-Snail-Goes-to-Town/ | cat

Mr. Snail Goes to Town (scrot) (+2 likes)

guff Jun 28, 2011 (wms/awesome)

rc.lua(raw, dl)

SCROT

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- Standard awesome library
require("awful")
require("awful.autofocus")
require("awful.rules")
require("awful.remote")
-- Theme handling library
require("beautiful")
beautiful.init(awful.util.getdir("config") .. "/theme/theme.lua")
-- Notification library
require("naughty")

-- Misc. settings and tools
require("cfg.misc")
-- Load layouts and tags
require("cfg.tags")
require("misc.notifications")
-- Load wibox
require("cfg.wibox")

-- Key bindings
require("cfg.global-bindings")
require("cfg.client-bindings")

-- Set keys and buttons
root.keys(globalkeys)
root.buttons(globalbuttons)

require("cfg.rules")

shifty.init()

CLICK TO VIEW

x

misc_notifications.lua(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
-- Show fancy notifications for backlight and volume hotkeys

function fancy_notify(percent, icon_function, notification)
    local img = image.argb32(200, 50, nil)
    img:draw_rectangle(0, 0, img.width, img.height, true, beautiful.bg_normal)
    img:insert(image(icon_function(percent)), 0, 1)
    img:draw_rectangle(60, 20, 130, 10, true, beautiful.bg_focus)
    img:draw_rectangle(62, 22, 126 * percent / 100, 6, true, beautiful.fg_focus)
    
    local id = nil
    if notification then id = notification.id end
    return naughty.notify({ icon = img, replaces_id = id,
                            text = "\n" .. math.ceil(percent) .. "%",
                            font = "Sans Bold 10" })
end

-- Brightness notifications
function brightness_down()
    brightness_adjust(-10)
end

function brightness_up()
    brightness_adjust(10)
end

local bright_notification = nil
function brightness_adjust(inc)
    -- Uncomment if your backlight keys don't work automatically
    --os.execute("xbacklight -inc " .. inc .. " > /dev/null 2>&1")
    local brightness = tonumber(awful.util.pread("xbacklight -get"))
    bright_notification =
        fancy_notify(brightness, brightness_get_icon, bright_notification)
end

function brightness_get_icon(brightness)
    return awful.util.getdir("config") .. "/icons/brightness.png"
end

-- Volume notifications

-- Each of these functions returns the current volume, so that it can be used
-- by my volume icon widget to update its icon. It's not necessary for the
-- notifications alone, however
function volume_down()
    return volume_adjust(-5)
end

function volume_up()
    return volume_adjust(5)
end

function volume_mute()
    return volume_adjust(0)
end

function get_volume()
    return tonumber(
        string.match(awful.util.pread("amixer -c0 get Master"), "(%d+)%%")
    )
end

function get_muted()
    return string.find(awful.util.pread("amixer -c0 get Master"),
                       '%[on%]') == nil
end

local vol_notification = nil
function volume_adjust(inc)
    if inc < 0 then inc = math.abs(inc) .. "%-"
    elseif inc > 0 then inc = inc .. "%+"
    else inc = "toggle" end
    local volume, is_muted =
		string.match(awful.util.pread("amixer -c0 set Master " .. inc),
					 "(%d+)%%.*%[(%a+)%]")
	is_muted = is_muted == "off"
	volume = tonumber(volume)
    --local volume = get_volume()
    --local is_muted = get_muted()
    if is_muted then volume = 0 end
    vol_notification = fancy_notify(volume, volume_get_icon, vol_notification)
    return volume
end

function volume_get_icon(volume)
    local is_muted = get_muted()
    local icon_str = nil
    if volume > 70 then icon_str = "high.png"
    elseif volume > 30 then icon_str = "medium.png"
    elseif volume > 0 then icon_str = "low.png"
    elseif volume == 0 then icon_str = "off.png" end
    if is_muted then icon_str = "muted.png" end
    return awful.util.getdir("config") .. "/icons/volume-" .. icon_str
end
 

x

misc_dict.lua(raw, dl)

1
2
3
4
5
6
7
8
9
words = {}

for word in io.lines(awful.util.getdir("cache") .. "/dictcache") do
	table.insert(words, word)
end

function dict_cb(text, cur_pos, ncomp)
	return awful.completion.generic(text, cur_pos, ncomp, words)
end
 

x

theme_theme.lua(raw, dl)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
---------------------------
-- Smoked awesome theme  --
---------------------------

theme_base = awful.util.getdir("config") .. "/theme/"

theme = {}

theme.font = "Droid Sans 8"
theme.tasklist_font = "Droid Sans 8"
theme.taglist_font = "Droid Sans 9"

theme.bg_normal     = "#61645B"
theme.bg_focus      = "#8D8873"
theme.bg_urgent     = "#DC8536"
theme.bg_minimize   = "#352E2A"

theme.fg_normal     = "#E7E5DE"
theme.fg_focus      = "#F5F5F5"
theme.fg_urgent     = "#f7f7f7"
theme.fg_minimize  = "#b9bbbb"

theme.border_width  = "1"
theme.border_normal = "#cbc8c1"
theme.border_focus  = "#282421"
theme.border_marked = "#f7f7f7"

-- There are another variables sets
-- overriding the default one when
-- defined, the sets are:
-- [taglist|tasklist]_[bg|fg]_[focus|urgent]
-- titlebar_[bg|fg]_[normal|focus]
-- Example:
--taglist_bg_focus = #ff0000

-- Display the taglist squares
theme.taglist_squares_sel = theme_base .. "taglist/squarefw.png"
theme.taglist_squares_unsel = theme_base .. "taglist/square.png"

-- get rid of that stupid moth
theme.tasklist_floating_icon = theme_base .. "tasklist/floatingw.png"

-- Widget stuff
theme.batt_ok = "#79B94A"
theme.batt_danger = "#CBF045"
theme.batt_dying = "#FC5D44"

-- Variables set for theming menu
-- menu_[bg|fg]_[normal|focus]
-- menu_[border_color|border_width]
theme.menu_submenu_icon = theme_base .. "submenu.png"
theme.menu_height   = "10"
theme.menu_width    = "120"

-- You can add as many variables as
-- you wish and access them by using
-- beautiful.variable in your rc.lua
--bg_widget    = #cc0000

-- Define the image to load
theme.titlebar_close_button_normal = theme_base .. "titlebar/close_normal.png"
theme.titlebar_close_button_focus = theme_base .. "titlebar/close_focus.png"

theme.titlebar_ontop_button_normal_inactive = theme_base .. "titlebar/ontop_normal_inactive.png"
theme.titlebar_ontop_button_focus_inactive = theme_base .. "titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_active = theme_base .. "titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_active = theme_base .. "titlebar/ontop_focus_active.png"

theme.titlebar_sticky_button_normal_inactive = theme_base .. "titlebar/sticky_normal_inactive.png"
theme.titlebar_sticky_button_focus_inactive = theme_base .. "titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_active = theme_base .. "titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_active = theme_base .. "titlebar/sticky_focus_active.png"

theme.titlebar_floating_button_normal_inactive = theme_base .. "titlebar/floating_normal_inactive.png"
theme.titlebar_floating_button_focus_inactive = theme_base .. "titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_active = theme_base .. "titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_active = theme_base .. "titlebar/floating_focus_active.png"

theme.titlebar_maximized_button_normal_inactive =
	theme_base .. "titlebar/maximized_normal_inactive.png"
theme.titlebar_maximized_button_focus_inactive =
	theme_base .. "titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_active =
	theme_base .. "titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_active =
	theme_base .. "titlebar/maximized_focus_active.png"

-- You can use your own command to set your wallpaper
theme.wallpaper_cmd = { "awsetbg " .. awful.util.getdir("config") .. "/theme/snail.png" }

-- You can use your own layout icons like this:
theme.layout_fairh = theme_base .. "layouts/fairh.png"
theme.layout_fairv = theme_base .. "layouts/fairv.png"
theme.layout_floating = theme_base .. "layouts/floating.png"
theme.layout_magnifier = theme_base .. "layouts/magnifier.png"
theme.layout_max = theme_base .. "layouts/max.png"
theme.layout_fullscreen = theme_base .. "layouts/fullscreen.png"
theme.layout_tilebottom = theme_base .. "layouts/tilebottom.png"
theme.layout_tileleft = theme_base .. "layouts/tileleft.png"
theme.layout_tile = theme_base .. "layouts/tile.png"
theme.layout_tiletop = theme_base .. "layouts/tiletop.png"


theme.awesome_icon = theme_base .. "awesome-icon-3.png"

return theme
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
 

x

cfg_global-bindings.lua(raw, dl)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
require("misc.dict")

globalkeys = awful.util.table.join(
    -- Special function keys
    awful.key({ }, "XF86MonBrightnessUp", brightness_up),
    awful.key({ }, "XF86MonBrightnessDown", brightness_down),
    awful.key({ }, "XF86ScreenSaver", function () awful.util.spawn("slimlock") end),
    awful.key({ }, "XF86AudioLowerVolume", volume_down_and_update),
    awful.key({ }, "XF86AudioRaiseVolume", volume_up_and_update),
    awful.key({ }, "XF86AudioMute", volume_mute_and_update),
	awful.key({ }, "Print", function () awful.util.spawn("scrot -e 'mv $f ~/Pictures/ && xdg-open ~/Pictures/$f'") end),
    
    -- MPD keys
    awful.key({ modkey, "Shift"   }, "Up", function () awful.util.spawn("ncmpcpp toggle") end),
    awful.key({ modkey, "Shift"   }, "Down", function () awful.util.spawn("ncmpcpp stop") end),
    awful.key({ modkey, "Shift"   }, "Left", function () awful.util.spawn("ncmpcpp prev") end),
    awful.key({ modkey, "Shift"   }, "Right", function () awful.util.spawn("ncmpcpp next") end),

    -- Shifty keys
    awful.key({ modkey, "Control" }, "t", function() shifty.add({ rel_index = 1 }) end),
    awful.key({ modkey, "Shift"   }, "t", function() shifty.add({ rel_index = 1, nopopup = true }) end),
    awful.key({ modkey, "Control" }, "g",           shifty.rename),
    awful.key({ modkey, "Control" }, "w",           shifty.del),
    
    -- Launch my terminal setup
    awful.key({ modkey,           }, "g",
        function()
            awful.util.spawn("sakura")
            awful.util.spawn("sakura -f \"Terminus (TTF) 9\"")
            awful.util.spawn("sakura -f \"Terminus (TTF) 9\"")
        end
    ),
    awful.key({ modkey,           }, "Left",   awful.tag.viewprev       ),
    awful.key({ modkey,           }, "Right",  awful.tag.viewnext       ),
    awful.key({ modkey,           }, "Escape", awful.tag.history.restore),
    awful.key({ modkey,           }, "e", function () awful.util.spawn("thunar") end),
    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,           }, "w", function () mymainmenu:show({keygrabber=true}) end),

    -- Layout manipulation
    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,           }, "u", awful.client.urgent.jumpto),
    awful.key({ modkey,           }, "Tab",
        function ()
            awful.client.focus.history.previous()
            if client.focus then
                client.focus:raise()
            end
        end),

    -- Standard program
    awful.key({ modkey,           }, "Return", function () awful.util.spawn(terminal) end),
    awful.key({ modkey, "Control" }, "r", awesome.restart),
    awful.key({ modkey, "Shift"   }, "q", awesome.quit),

    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(layouts,  1) end),
    awful.key({ modkey, "Shift"   }, "space", function () awful.layout.inc(layouts, -1) end),

    -- Prompt
    awful.key({ modkey,           }, ";",
        function ()
            awful.prompt.run({ prompt = "Dict: " }, mypromptbox[mouse.screen].widget,
            function(word)
                local definition = awful.util.pread("dict " .. word .. " 2>&1")
                naughty.notify({ text = definition, timeout = 13, title = word,
                    width = 400, font = "Sans 7" })
            end, dict_cb, awful.util.getdir("cache") .. "/dict")
        end
    ),
    awful.key({ modkey, "Control" }, ";",
        function ()
            if selection() then
                definition = awful.util.pread("dict " .. selection() .. " 2>&1")
                naughty.notify({ text = definition, timeout = 13,
                    title = selection(), width = 400, font = "Sans 7" })
            end
        end
    ),
    awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),

    awful.key({ modkey }, "x",
              function ()
                  awful.prompt.run({ prompt = "Run Lua code: " },
                  mypromptbox[mouse.screen].widget,
                  awful.util.eval, nil,
                  awful.util.getdir("cache") .. "/history_eval")
              end),
    -- all minimized clients are restored 
    awful.key({ modkey, "Shift"   }, "n", 
        function()
            local tags = awful.tag.selectedlist()
            for j=1, #tags do
                for i=1, #tags[j]:clients() do
                    tags[j]:clients()[i].minimized=false
                    tags[j]:clients()[i]:redraw()
                end
            end
        end),
    -- show desktop/unminimize
    awful.key({ modkey            }, "d", 
        function()
            local tag = awful.tag.selected()
            for i=1, #tag:clients() do
                tag:clients()[i].minimized = not tag:clients()[i].minimized
                if not tag:clients()[i].minimized then
                    tag:clients()[i]:redraw()
                end
            end
        end)
)

for i=1, ( shifty.config.maxtags or 9 ) do
  
    globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey }, i,
        function ()
            local t = awful.tag.viewonly(shifty.getpos(i))
        end))
    globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Control" }, i,
        function ()
            local t = shifty.getpos(i)
            t.selected = not t.selected
        end))
    globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Control", "Shift" }, i,
        function ()
            if client.focus then
            awful.client.toggletag(shifty.getpos(i))
        end
    end))
    -- move clients to other tags
    globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Shift" }, i,
    function ()
        if client.focus then
            local t = shifty.getpos(i)
            awful.client.movetotag(t)
            --awful.tag.viewonly(t)
        end
    end))
end

globalbuttons = awful.util.table.join(
    awful.button({ }, 3, function () mymainmenu:toggle() end),
    awful.button({ }, 4, awful.tag.viewnext),
    awful.button({ }, 5, awful.tag.viewprev)
)

shifty.config.globalkeys = globalkeys
 

x

cfg_tags.lua(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
require("shifty")

layouts =
{
    awful.layout.suit.floating,
    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.magnifier
}

mytags = { "☉", "⌨", "☐", "☷", "♪", "⚈", "⌘", "⌥" }

-- All have init = true, because trying to move a client to a not-yet-created
-- tag seems to be problematic, i.e. takes two attempts
shifty.config.tags = {
    [mytags[1]] = { position = 1, init = true, layout = "floating", },
    [mytags[2]] = { position = 2, init = true, layout = "floating", },
    [mytags[3]] = { position = 3, init = true, layout = "tilebottom",
                    mwfact = 0.7, },
    [mytags[4]] = { position = 4, init = true, layout = "tiletop", },
    [mytags[5]] = { position = 5, },
    [mytags[6]] = { position = 6, },
    [mytags[7]] = { position = 7, mwfact = 0.1943359375,
                    layout = "tileleft", },
    [mytags[8]] = { position = 8, },
    
}

local tags = shifty.config.tags

shifty.config.apps = {
    { match = { "Firefox.*", "xchat", "liferea", }, tag = mytags[1], },
    { match = { "geany" }, tag = mytags[2], },
    { match = { "gimp%-toolbox" }, float = false, tag = mytags[7], slave = false, },
    { match = { "gimp%-image%-window" }, tag = mytags[7], slave = true, },
    { match = { "color%-dialog" }, float = true, },
    -- Heck, if it has dialog in the name, safe to assume it should float
    { match = { ".*dialog.*" }, float = true, },
    { match = { "inkscape", "Blender" }, tag = mytags[7], maximized_horizontal = true,
      maximized_vertical = true, },
    { match = { "devhelp", "evince" }, tag = mytags[4], maximized_horizontal = true,
      maximized_vertical = true, },  
    { match = { "banshee", "totem", "gmpc", "vlc", }, tag = mytags[5], },
    { match = { "sakura", }, tag = mytags[3], },
    { match = { "Pidgin", "File Operation Progress", "pinentry", "Thunderbird", },
        float = true, },
    { match = { "" }, buttons = 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)),
      border_width = beautiful.border_width, border_color = beautiful.border_color,
      focus = true, 
    },
}

shifty.config.defaults = {
  layout = "floating", 
  run = function(tag) naughty.notify({ text = "Created " .. tag.name }) end,
}

shifty.config.layouts = layouts
shifty.config.guess_name = false
shifty.config.guess_position = false
 

x

cfg_rules.lua(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
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
            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 end)
client.add_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
 

x

cfg_client-bindings.lua(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
clientkeys = awful.util.table.join(
    awful.key({ modkey,           }, "f",      function (c) c.fullscreen = not c.fullscreen  end),
    awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end),
    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,           }, "o",      awful.client.movetoscreen                        ),
    awful.key({ modkey, "Shift"   }, "r",      function (c) c:redraw()                       end),
    awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end),
    awful.key({ modkey,           }, "n",      function (c) c.minimized = not c.minimized    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,           }, "/",      awful.mouse.client.resize)
)

clientbuttons = 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))

shifty.config.clientkeys = clientkeys
 

x

cfg_wibox.lua(raw, dl)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
-- widgets
require("vicious")
require("misc.notifications")
-- freedesktop menu
require("cfg.menu")

mytextclock = widget({ type = "textbox" })
vicious.register(mytextclock, vicious.widgets.date, "%a %b %d, %l:%M %p")

wifi_info = { ssid = "N/A" }
wifi_text = widget({ type = "textbox" })

wifi_icon = widget({ type = "imagebox" })

function update_wifi_icon()
    local icon_dir = awful.util.getdir("config") .. "/icons/wireless-"
    local icon_str = "disconnected"
    if wifi_info.ssid ~= "N/A" then
        if wifi_info.qual >= 75 then icon_str = "full"
        elseif wifi_info.qual >= 50 then icon_str = "high"
        elseif wifi_info.qual >= 25 then icon_str = "medium"
        elseif wifi_info.qual > 0 then icon_str = "low"
        else icon_str = "none" end
    end
    wifi_icon.image = image(icon_dir .. icon_str .. ".png")
end

vicious.register(wifi_text, vicious.widgets.wifi, 
    function(widget, args)
        wifi_info.ssid = args["{ssid}"]
        wifi_info.qual = args["{linp}"]
        update_wifi_icon()
        return wifi_info.qual .. "%"
    end, 1, "wlan0")
update_wifi_icon()

myweather = widget({ type = "textbox" })
wdata = { tempf = "N/A", }
-- Need to siphon off the data for use in the tooltips later
vicious.register(myweather, vicious.widgets.weather,
    function(widget, args)
        if args["{tempf}"] ~= "N/A" then
            wdata.tempf = args["{tempf}"]
        end
        wdata.weather = args["{weather}"]
        wdata.sky = args["{sky}"]
        wdata.city = args["{city}"]
        wdata.wind = args["{windmph}"]
        wdata.wind_dir = args["{wind}"]
        wdata.humidity = args["{humid}"]
        return wdata.tempf .. "° "
    end, 600, "KGIF")

fs_info = {}
fsdummy = widget({ type = "textbox" })
vicious.register(fsdummy, vicious.widgets.fs,
    function(widget, args)
        fs_info.rootsize = args["{/ size_gb}"]
        fs_info.homesize = args["{/home size_gb}"]
        fs_info.rootfree = args["{/ avail_gb}"]
        fs_info.homefree = args["{/home avail_gb}"]
    end, 60
)

mem_bar = awful.widget.progressbar()
-- Progressbar properties
mem_bar:set_width(8)
mem_bar:set_height(18)
mem_bar:set_vertical(true)
mem_bar:set_background_color("#494B4F")
mem_bar:set_border_color("#000000")
mem_bar:set_color("#AECF96")
mem_bar:set_gradient_colors({ "#AECF96", "#88A175", "#FF5656" })

mem_info = {}
vicious.register(mem_bar, vicious.widgets.mem, 
    function(widget, args)
        mem_info.percent = args[1]
        mem_info.usage = args[2]
        mem_info.total = args[3]
        mem_info.swapused = args[6]
        mem_info.swaptotal = args[7]
        return mem_info.percent
    end, 10
)

--cputext = widget( { type = "textbox" })
--vicious.register(cputext, vicious.widgets.cpu, "$1%", 2) 
cpu_bar = awful.widget.progressbar()
cpu_bar:set_width(8):set_height(18):set_vertical(true)
cpu_bar:set_background_color("#494b4f"):set_border_color("#000000")
cpu_bar:set_color("#AD8488"):set_gradient_colors({ "#AD8488", "#964C53", "#FF3548" })

cpu_info = {}
vicious.register(cpu_bar, vicious.widgets.cpu,
    function(widget, args)
        cpu_info.load1 = args[1]
        cpu_info.load2 = args[2]
        return (cpu_info.load1 + cpu_info.load2) / 2
    end, 2
)

volume_icon = widget({ type = "imagebox" })
volume_icon.image = image(volume_get_icon(get_volume()))

function update_volume_icon(volume)
    volume_icon.image = image(volume_get_icon(volume))
end

function volume_up_and_update()
    local volume = volume_up()
    update_volume_icon(volume)
end

function volume_down_and_update()
    local volume = volume_down()
    update_volume_icon(volume)
end

function volume_mute_and_update()
    local volume = volume_mute()
    update_volume_icon(volume)
end

volume_icon:buttons(awful.util.table.join(
    awful.button({}, 1, function () awful.util.spawn("pavucontrol") end),
    awful.button({}, 2, volume_mute_and_update),
    awful.button({}, 4, volume_up_and_update),
    awful.button({}, 5, volume_down_and_update))
)

batt_info = {}
batt_text = widget({ type = "textbox" })
vicious.register(batt_text, vicious.widgets.bat,
    function(widget, args)
        batt_info.state = args[1]
        batt_info.level = args[2]
        batt_info.remaining = args[3]
        if batt_info.state == "-" or batt_info.state == "+" then
            return " " .. args[3]
        else
            return nil
        end
    end, 5, "BAT0"
)

batt_icon = widget({ type = "imagebox" })
batt_icon_image = image(awful.util.getdir("config") .. "/icons/batticon.png")
-- surprised this isn't in lua's math library
local function round(x)
    if x - math.floor(x) >= 0.5 then return math.ceil(x) else return math.floor(x) end
end

function update_batt_icon()
    batt_icon.image = batt_icon_image
    local off_x, off_y = 1, { top = 3, bot = 1 }
    local w, h = batt_icon.image.width, batt_icon.image.height
    local color = beautiful.batt_ok
    if batt_info.level > 30 then color = beautiful.batt_ok
    elseif batt_info.level > 10 then color = beautiful.batt_danger
    else color = beautiful.batt_dying end
    
    local percent = batt_info.level / 100
    local rect_h = round((h - off_y.top - off_y.bot) * percent)
    batt_icon.image:draw_rectangle(off_x, h - rect_h, w - 2 * off_x, rect_h - off_y.bot, true, color)
    
    if batt_info.state ~= "-" then 
        batt_icon.image:insert(
            image(awful.util.getdir("config") .. "/icons/charging.png"))
    end
end

batt_timer = timer({ timeout = 5 })
batt_timer:add_signal("timeout", update_batt_icon)
batt_timer:start()

local batt_buttons = awful.util.table.join(
    awful.button({ }, 1,
        function()
            run_or_raise("xfce4-power-information", { class = "xfce4-power-information" } )
        end
    ),
    awful.button({ }, 3,
        function()
            run_or_raise("xfce4-power-manager-settings", { class = "xfce4-power-manager-settings" } )
        end
    ),
    awful.button({ }, 4, 
        function()
            os.execute("xbacklight -inc 10 > /dev/null 2>&1")
            brightness_adjust(10)
        end
    ),
    awful.button({ }, 5,
        function()
            os.execute("xbacklight -dec 10 > /dev/null 2>&1")
            brightness_adjust(-10)
        end
    )
)

batt_text:buttons(batt_buttons)
batt_icon:buttons(batt_buttons)

local sysmon_buttons = awful.button({}, 1,
    function()
        run_or_raise("lxtask", { class = "lxtask" } )
    end
)

mem_bar.widget:buttons(sysmon_buttons)
cpu_bar.widget:buttons(sysmon_buttons)

awful.tooltip({ objects = { batt_icon, batt_text }, timer_function = function()
    return string.format("<big>Battery:</big>\n<b>Level:</b> %s%%\n<b>State:</b> %s\n<b>"
        .. "Time remaining:</b> %s", batt_info.level, batt_info.state, batt_info.remaining)
    end, timeout = 10
})

awful.tooltip({ objects = { mem_bar.widget, cpu_bar.widget }, timer_function = function()
    return string.format("<b>CPU0:</b> %s%%; <b>CPU1:</b> %s%%\n\n<b>Memory used:</b> "
        .. "%sMB, %s%% \n<b>Memory total:</b> %sMB\n<b>Swap used:</b> %sMB\n<b>Swap total:</b> "
        .. "%sMB\n\n<b>Filesystems</b>:\n<b>/:</b> size %sGB, free %sGB\n<b>/home:</b> size"
        .. " %sGB, free %sGB\n%s %s", cpu_info.load1, cpu_info.load2, mem_info.usage,
        mem_info.percent, mem_info.total, mem_info.swapused, mem_info.swaptotal,
        fs_info.rootsize, fs_info.rootfree, fs_info.homesize, fs_info.homefree,
        awful.util.pread('uptime | sed "s/\\(.*users\\).*/\\1/"'),
        awful.util.pread("cut -d\" \" -f1,2,3 /proc/loadavg"))
    end,
    timeout = 1
})

awful.tooltip({ objects = { wifi_icon, }, timer_function = function()
    return string.format("%s: %d%%", wifi_info.ssid, wifi_info.qual)
end, timeout = 1 })

awful.tooltip({ objects = { mytextclock, myweather, }, timer_function = function()
    return string.format("<big><b>Winter Haven, FL</b></big>\n<b>%s</b>\n<b>Sky:</b> %s\n%s, "
        .. "%s°\n<b>Humidity:</b> %s%%", os.date("%a %b %d, %l:%M:%S %p"), wdata.sky,
        wdata.weather, wdata.tempf, wdata.humidity)
    end, timeout = 1 })
    
awful.tooltip({ objects = { volume_icon, }, timer_function = function()
    if get_muted() then return "Volume: " .. get_volume() .. "%," .. " muted"
    else return "Volume: " .. get_volume() .. "%" end
end, timeout = 1 })

local calendar = nil
local offset = 0

function remove_calendar()
    if calendar ~= nil then
        naughty.destroy(calendar)
        calendar = nil
        offset = 0
    end
end

function add_calendar(inc_offset)
    local save_offset = offset
    remove_calendar()
    offset = save_offset + inc_offset
    local datespec = os.date("*t")
    local today = datespec.day
    datespec = datespec.year * 12 + datespec.month - 1 + offset
    datespec = (datespec % 12 + 1) .. " " .. math.floor(datespec / 12)
    local cal = awful.util.pread("cal -m " .. datespec)
    cal = string.gsub(cal, "^%s*(.-)%s*$", "%1")
    cal = string.gsub(cal, today .. "[ \n]",
        '<span bgcolor="white" fgcolor="#61645B">%1</span>', 1)
    calendar = naughty.notify({
        text = string.format('<span font_desc="%s">%s</span>', "monospace",
            os.date("%a, %d %B %Y") .. "\n" .. cal),
        timeout = 0, hover_timeout = 0.5,
        width = 160,
    })
end

mytextclock:add_signal("mouse::leave", remove_calendar)

mytextclock:buttons(awful.util.table.join(
    awful.button({ }, 1, function()
        if calendar ~= nil then
            remove_calendar()
        else
            add_calendar(0)
        end
    end),
    awful.button({ }, 4, function()
        add_calendar(1)
    end),
    awful.button({ }, 5, function()
        add_calendar(-1)
    end)
))


-- Create a systray
mysystray = widget({ type = "systray" })

-- 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, awful.tag.viewtoggle),
    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
            if client.focus == c then
                c.minimized = not c.minimized
            else
                client.focus = c
                c:raise()
            end
        end
    ),
    awful.button({ }, 2, function (c) c:kill() end),
    awful.button({ }, 3,
        function ()
            if instance then
                instance:hide()
                instance = nil
            else
                instance = awful.menu.clients({ width=250 })
            end
        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
    )
)

for s = 1, screen.count() do
    -- Create a promptbox for each screen
    mypromptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.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(s, awful.widget.taglist.label.noempty, mytaglist.buttons)

    -- Create a tasklist widget
    mytasklist[s] = awful.widget.tasklist(
        function(c)
            return awful.widget.tasklist.label.currenttags(c, s)
        end, mytasklist.buttons
    )
    -- Create the wibox
    mywibox[s] = awful.wibox({ position = "top", height="18", screen = s })
    -- Space out a few widgets
    
    -- Add widgets to the wibox - order matters
    mywibox[s].widgets = {
        {
			mylauncher,
            mytaglist[s],
            mypromptbox[s],
            layout = awful.widget.layout.horizontal.leftright
        },
        
        mylayoutbox[s],
        batt_text,
        batt_icon,
        wifi_icon,
        volume_icon,
        s == 1 and mysystray or nil,
        mem_bar.widget,
        cpu_bar.widget,
        mytextclock,
        myweather,
        mytasklist[s],
        layout = awful.widget.layout.horizontal.rightleft
        
    }
end

shifty.taglist = mytaglist
shifty.promptbox = mypromptbox

awful.widget.layout.margins[cpu_bar.widget] = { left = 5 }
awful.widget.layout.margins[myweather] = { left = 5 }
awful.widget.layout.margins[batt_icon] = { left = 2, right = 2 }
 

x

cfg_misc.lua(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
-- This is used later as the default terminal and editor to run.
terminal = "lxterminal"
editor = "vim"
editor_cmd = terminal .. " -e " .. editor
browser = "firefox"

modkey = "Mod4"

local oldspawn = awful.util.spawn
awful.util.spawn = function (s)
  oldspawn(s, false)
end

--- Spawns cmd if no client can be found matching properties
-- If such a client can be found, pop to first tag where it is visible, and give it focus
-- @param cmd the command to execute
-- @param properties a table of properties to match against clients.  Possible entries: any properties of the client object
function run_or_raise(cmd, properties)
   local clients = client.get()
   local focused = awful.client.next(0)
   local findex = 0
   local matched_clients = {}
   local n = 0
   for i, c in pairs(clients) do
      --make an array of matched clients
      if match(properties, c) then
         n = n + 1
         matched_clients[n] = c
         if c == focused then
            findex = n
         end
      end
   end
   if n > 0 then
      local c = matched_clients[1]
      -- if the focused window matched switch focus to next in list
      if 0 < findex and findex < n then
         c = matched_clients[findex+1]
      end
      local ctags = c:tags()
      if table.getn(ctags) == 0 then
         -- ctags is empty, show client on current tag
         local curtag = awful.tag.selected()
         awful.client.movetotag(curtag, c)
      else
         -- Otherwise, pop to first tag client is visible on
         awful.tag.viewonly(ctags[1])
      end
      -- And then focus the client
      client.focus = c
      c:raise()
      return
   end
   awful.util.spawn(cmd)
end

-- Returns true if all pairs in table1 are present in table2
function match (table1, table2)
   for k, v in pairs(table1) do
      if table2[k] ~= v and not table2[k]:find(v) then
         return false
      end
   end
   return true
end
 

x

cfg_menu.lua(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
-- applications menu
require('freedesktop.utils')
freedesktop.utils.terminal = terminal
freedesktop.utils.icon_theme = 'gnome'
require('freedesktop.menu')
local lock = "slimlock"
local ck = "dbus-send --system --print-reply --dest=\"org.freedesktop.ConsoleKit\" "
			.. "/org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager."
local suspend = "dbus-send --system --print-reply --dest=\"org.freedesktop.UPower\" "
				.. "/org/freedesktop/UPower org.freedesktop.UPower.Suspend"

local logoutmenu = {
	{ "Shutdown", ck .. "Stop", freedesktop.utils.lookup_icon({ icon = 'system-shutdown' }) },
	{ "Reboot", ck .. "Restart",  freedesktop.utils.lookup_icon({ icon = 'gtk-refresh' }) },
	{ "Suspend", suspend, freedesktop.utils.lookup_icon({ icon = 'media-playback-pause' }) },
	{ "Lock screen", lock, freedesktop.utils.lookup_icon({ icon = 'system-lock-screen' }) },
	{ "Log out", awesome.quit, freedesktop.utils.lookup_icon({ icon = 'system-log-out' }) },
}

awful.menu.menu_keys = { up = { "j", "Up" },
						 down = { "k", "Down" },
						 exec = { "Return", "l", "Right" },
						 back = { "Left", "h", "Escape" } }

menu_items = freedesktop.menu.new()
myawesomemenu = {
   { "manual", terminal .. " -e man awesome", freedesktop.utils.lookup_icon({ icon = 'help' }) },
   { "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua", freedesktop.utils.lookup_icon({ icon = 'package_settings' }) },
   { "restart", awesome.restart, freedesktop.utils.lookup_icon({ icon = 'gtk-refresh' }) },
   { "quit", awesome.quit, freedesktop.utils.lookup_icon({ icon = 'gtk-quit' }) }
}


table.insert(menu_items, { "awesome", myawesomemenu, beautiful.awesome_icon })
table.insert(menu_items, { "open terminal", terminal, freedesktop.utils.lookup_icon({icon = 'terminal'}) })
table.insert(menu_items, { "session", logoutmenu, freedesktop.utils.lookup_icon({ icon = 'system-log-out' }) })

mymainmenu = awful.menu.new({ items = menu_items, width = 150 })

mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
                                   menu = mymainmenu })

-- desktop icons
require('freedesktop.desktop')
for s = 1, screen.count() do
    freedesktop.desktop.add_applications_icons({screen = s, showlabels = true})
    freedesktop.desktop.add_dirs_and_files_icons({screen = s, showlabels = true})
end
 

x

Notes

Includes freedesktop menu, several custom imagebox widgets, and fancy lookin' notifications for brightness and volume hotkeys. Uses shifty for tag management.

Comments

Hund said about 12 years ago

How did you get notify-osd to look like that? With borders and all? :)