Awesome-3.5 config added.
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 298 B |
After Width: | Height: | Size: 218 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 216 B |
After Width: | Height: | Size: 217 B |
After Width: | Height: | Size: 299 B |
After Width: | Height: | Size: 247 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 1000 B |
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,33 @@
|
|||
-- {{{ init environment
|
||||
local wakka = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display()
|
||||
local lines = "<u>AUR Updates:</u>\n"
|
||||
local f = io.popen("cower -u", "r")
|
||||
local s = f:read('*all')
|
||||
line = lines .. "\n" .. s .. "\n"
|
||||
f:close()
|
||||
return line
|
||||
end
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
function wakka.addToWidget(mywidget)
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
|
||||
return wakka
|
|
@ -0,0 +1,9 @@
|
|||
os.execute ("numlockx on &")
|
||||
os.execute ("xsetroot -cursor_name left_ptr &")
|
||||
os.execute ("xscreensaver -no-splash &")
|
||||
os.execute ("pidgin &")
|
||||
os.execute ("pgrep stardict || stardict &")
|
||||
os.execute ("pgrep urxvt || urxvt &")
|
||||
os.execute ("pgrep firefox || firefox &")
|
||||
os.execute ("nvidia-settings -a GPUOverclockingState=1 -a GPU2DClockFreqs=135,135 -a GPU3DClockFreqs=629,480")
|
||||
os.execute (os.getenv("HOME").."/.config/awesome/set_wall.sh "..os.getenv("HOME").."/wallpapers/")
|
|
@ -0,0 +1,19 @@
|
|||
## Description ##
|
||||
|
||||
This is an advanced MPD widget\client for AwesomeWM.
|
||||
|
||||
For the detailed installation guide please see http://awesome.naquadah.org/wiki/Awesompd_widget .
|
||||
|
||||
Also you can find an example of the widget configuration in the file rcsample.lua.
|
||||
|
||||
## Version explanation ##
|
||||
|
||||
Use this version with Awesome v3.4.x. If you are using the git pre-4.0 version of Awesome, please consider using [this](https://github.com/alexander-yakushev/awesompd/tree/for-awesome-git) version instead.
|
||||
|
||||
### Changes in 1.1.0 ###
|
||||
|
||||
* Album covers are now also shown for the local tracks (images are taken from the current track's folder)
|
||||
* When the Jamendo track is playing you can visit artist's or album's page from the Jamendo menu
|
||||
* Notification now shows the album name for the current track (for both local and Jamendo tracks)
|
||||
* A few minor modifications and bugfixes
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
-- Asynchronous io.popen for Awesome WM.
|
||||
-- How to use...
|
||||
-- ...asynchronously:
|
||||
-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
|
||||
-- ...synchronously
|
||||
-- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error"
|
||||
|
||||
asyncshell = {}
|
||||
asyncshell.request_table = {}
|
||||
asyncshell.id_counter = 0
|
||||
asyncshell.folder = "/tmp/asyncshell"
|
||||
asyncshell.file_template = asyncshell.folder .. '/req'
|
||||
|
||||
-- Create a directory for asynchell response files
|
||||
os.execute("mkdir -p " .. asyncshell.folder)
|
||||
|
||||
-- Returns next tag - unique identifier of the request
|
||||
local function next_id()
|
||||
asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000
|
||||
return asyncshell.id_counter
|
||||
end
|
||||
|
||||
-- Sends an asynchronous request for an output of the shell command.
|
||||
-- @param command Command to be executed and taken output from
|
||||
-- @param callback Function to be called when the command finishes
|
||||
-- @return Request ID
|
||||
function asyncshell.request(command, callback)
|
||||
local id = next_id()
|
||||
local tmpfname = asyncshell.file_template .. id
|
||||
asyncshell.request_table[id] = {callback = callback}
|
||||
local req =
|
||||
string.format("bash -c '%s > %s; " ..
|
||||
'echo "asyncshell.deliver(%s)" | ' ..
|
||||
"awesome-client' 2> /dev/null",
|
||||
string.gsub(command, "'", "'\\''"), tmpfname, id, tmpfname)
|
||||
awful.util.spawn(req)
|
||||
return id
|
||||
end
|
||||
|
||||
-- Calls the remembered callback function on the output of the shell
|
||||
-- command.
|
||||
-- @param id Request ID
|
||||
-- @param output The output file of the shell command to be delievered
|
||||
function asyncshell.deliver(id)
|
||||
if asyncshell.request_table[id] and
|
||||
asyncshell.request_table[id].callback then
|
||||
local output = io.open(asyncshell.file_template .. id, 'r')
|
||||
asyncshell.request_table[id].callback(output)
|
||||
end
|
||||
end
|
||||
|
||||
-- Sends a synchronous request for an output of the command. Waits for
|
||||
-- the output, but if the given timeout expires returns nil.
|
||||
-- @param command Command to be executed and taken output from
|
||||
-- @param timeout Maximum amount of time to wait for the result
|
||||
-- @return File handler on success, nil otherwise
|
||||
function asyncshell.demand(command, timeout)
|
||||
local id = next_id()
|
||||
local tmpfname = asyncshell.file_template .. id
|
||||
local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & " ..
|
||||
"(sleep %s; echo asynchell_timeout)",
|
||||
command, tmpfname, timeout))
|
||||
local result = f:read("*line")
|
||||
if result == "asyncshell_done" then
|
||||
return io.open(tmpfname)
|
||||
end
|
||||
end
|
After Width: | Height: | Size: 241 B |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 248 B |
After Width: | Height: | Size: 240 B |
After Width: | Height: | Size: 342 B |
After Width: | Height: | Size: 210 B |
|
@ -0,0 +1,524 @@
|
|||
---------------------------------------------------------------------------
|
||||
-- @author Alexander Yakushev <yakushev.alex@gmail.com>
|
||||
-- @copyright 2011 Alexander Yakushev
|
||||
-- @release v1.1.5
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
-- Grab environment
|
||||
local os = os
|
||||
local awful = awful
|
||||
local string = string
|
||||
local table = table
|
||||
local io = io
|
||||
local pairs = pairs
|
||||
local type = type
|
||||
local assert = assert
|
||||
local print = print
|
||||
local tonumber = tonumber
|
||||
local math = math
|
||||
local tostring = tostring
|
||||
local asyncshell = asyncshell
|
||||
|
||||
module('jamendo')
|
||||
|
||||
-- UTILITY STUFF
|
||||
-- Checks whether file specified by filename exists.
|
||||
local function file_exists(filename, mode)
|
||||
mode = mode or 'r'
|
||||
f = io.open(filename, mode)
|
||||
if f then
|
||||
f:close()
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Global variables
|
||||
FORMAT_MP3 = { display = "MP3 (128k)",
|
||||
short_display = "MP3",
|
||||
value = "mp31" }
|
||||
FORMAT_OGG = { display = "Ogg Vorbis (q4)",
|
||||
short_display = "Ogg",
|
||||
value = "ogg2" }
|
||||
ORDER_RATINGDAILY = { display = "Daily rating",
|
||||
short_display = "daily rating",
|
||||
value = "ratingday_desc" }
|
||||
ORDER_RATINGWEEKLY = { display = "Weekly rating",
|
||||
short_display = "weekly rating",
|
||||
value = "ratingweek_desc" }
|
||||
ORDER_RATINGTOTAL = { display = "All time rating",
|
||||
short_display = "all time rating",
|
||||
value = "ratingtotal_desc" }
|
||||
ORDER_RANDOM = { display = "Random",
|
||||
short_display = "random",
|
||||
value = "random_desc" }
|
||||
ORDER_RELEVANCE = { display = "None (consecutive)",
|
||||
short_display = "none",
|
||||
value = "searchweight_desc" }
|
||||
SEARCH_ARTIST = { display = "Artist",
|
||||
unit = "artist",
|
||||
value = "artist_id" }
|
||||
SEARCH_ALBUM = { display = "Album",
|
||||
unit = "album",
|
||||
value = "album_id" }
|
||||
SEARCH_TAG = { display = "Tag",
|
||||
unit = "tag",
|
||||
value = "tag_id" }
|
||||
ALL_FORMATS = { FORMAT_MP3, FORMAT_OGG }
|
||||
ALL_ORDERS = { ORDER_RELEVANCE, ORDER_RANDOM, ORDER_RATINGDAILY,
|
||||
ORDER_RATINGWEEKLY, ORDER_RATINGTOTAL }
|
||||
|
||||
current_request_table = { unit = "track",
|
||||
fields = {"id", "artist_url", "artist_name", "name",
|
||||
"stream", "album_image", "album_name" },
|
||||
joins = { "track_album", "album_artist" },
|
||||
params = { streamencoding = FORMAT_MP3,
|
||||
order = ORDER_RATINGWEEKLY,
|
||||
n = 100 }}
|
||||
|
||||
-- Local variables
|
||||
local jamendo_list = {}
|
||||
local cache_file = awful.util.getdir ("cache").."/jamendo_cache"
|
||||
local cache_header = "[version=1.1.0]"
|
||||
local album_covers_folder = awful.util.getdir("cache") .. "/jamendo_covers/"
|
||||
local default_mp3_stream = nil
|
||||
local search_template = { fields = { "id", "name" },
|
||||
joins = {},
|
||||
params = { order = ORDER_RELEVANCE,
|
||||
n = 1}}
|
||||
|
||||
-- DEPRECATED. Will be removed in the next major release.
|
||||
-- Returns default stream number for MP3 format. Requests API for it
|
||||
-- not more often than every hour.
|
||||
local function get_default_mp3_stream()
|
||||
if not default_mp3_stream or
|
||||
(os.time() - default_mp3_stream.last_checked) > 3600 then
|
||||
local trygetlink =
|
||||
perform_request("echo $(curl -w %{redirect_url} " ..
|
||||
"'http://api.jamendo.com/get2/stream/track/redirect/" ..
|
||||
"?streamencoding="..FORMAT_MP3.value.."&id=729304')")
|
||||
local _, _, prefix = string.find(trygetlink,"stream(%d+)\.jamendo\.com")
|
||||
default_mp3_stream = { id = prefix, last_checked = os.time() }
|
||||
end
|
||||
return default_mp3_stream.id
|
||||
end
|
||||
|
||||
-- Returns the track ID from the given link to Jamendo stream. If the
|
||||
-- given text is not the Jamendo stream returns nil.
|
||||
function get_id_from_link(link)
|
||||
local _, _, id = string.find(link,"storage%-new.newjamendo.com%?trackid=(%d+)")
|
||||
return id
|
||||
end
|
||||
|
||||
-- Returns link to music stream for the given track ID. Uses MP3
|
||||
-- format and the default stream for it.
|
||||
local function get_link_by_id(id)
|
||||
-- This function is subject to change in the future.
|
||||
return string.format("http://storage-new.newjamendo.com?trackid=%s&format=mp31&u=0", id)
|
||||
end
|
||||
|
||||
-- -- Returns the album id for given music stream.
|
||||
-- function get_album_id_by_link(link)
|
||||
-- local id = get_id_from_link(link, true)
|
||||
-- if id and jamendo_list[id] then
|
||||
-- return jamendo_list[id].album_id
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- Returns the track table for the given music stream.
|
||||
function get_track_by_link(link)
|
||||
local id = get_id_from_link(link, true)
|
||||
if id and jamendo_list[id] then
|
||||
return jamendo_list[id]
|
||||
end
|
||||
end
|
||||
|
||||
-- If a track is actually a Jamendo stream, replace it with normal
|
||||
-- track name.
|
||||
function replace_link(track_name)
|
||||
local track = get_track_by_link(track_name)
|
||||
if track then
|
||||
return track.display_name
|
||||
else
|
||||
return track_name
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns table of track IDs, names and other things based on the
|
||||
-- request table.
|
||||
function return_track_table(request_table)
|
||||
local req_string = form_request(request_table)
|
||||
local response = perform_request(req_string)
|
||||
if not response then
|
||||
return nil -- Bad internet connection
|
||||
end
|
||||
parse_table = parse_json(response)
|
||||
for i = 1, table.getn(parse_table) do
|
||||
if parse_table[i].stream == "" then
|
||||
-- Some songs don't have Ogg stream, use MP3 instead
|
||||
parse_table[i].stream = get_link_by_id(parse_table[i].id)
|
||||
end
|
||||
_, _, parse_table[i].artist_link_name =
|
||||
string.find(parse_table[i].artist_url, "\\/artist\\/(.+)")
|
||||
-- Remove Jamendo escape slashes
|
||||
parse_table[i].artist_name =
|
||||
string.gsub(parse_table[i].artist_name, "\\/", "/")
|
||||
parse_table[i].name = string.gsub(parse_table[i].name, "\\/", "/")
|
||||
|
||||
parse_table[i].display_name =
|
||||
parse_table[i].artist_name .. " - " .. parse_table[i].name
|
||||
-- Do Jamendo a favor, extract album_id for the track yourself
|
||||
-- from album_image link :)
|
||||
local _, _, album_id =
|
||||
string.find(parse_table[i].album_image, "\\/(%d+)\\/covers")
|
||||
parse_table[i].album_id = album_id or 0
|
||||
-- Save fetched tracks for further caching
|
||||
jamendo_list[parse_table[i].id] = parse_table[i]
|
||||
end
|
||||
save_cache()
|
||||
return parse_table
|
||||
end
|
||||
|
||||
-- Generates the request to Jamendo API based on provided request
|
||||
-- table. If request_table is nil, uses current_request_table instead.
|
||||
-- For all values that do not exist in request_table use ones from
|
||||
-- current_request_table.
|
||||
-- return - HTTP-request
|
||||
function form_request(request_table)
|
||||
local curl_str = "curl -A 'Mozilla/4.0' -fsm 5 \"%s\""
|
||||
local url = "http://api.jamendo.com/en/?m=get2%s%s"
|
||||
request_table = request_table or current_request_table
|
||||
|
||||
local fields = request_table.fields or current_request_table.fields
|
||||
local joins = request_table.joins or current_request_table.joins
|
||||
local unit = request_table.unit or current_request_table.unit
|
||||
|
||||
-- Form field&joins string (like field1+field2+fieldN%2Fjoin+)
|
||||
local fnj_string = "&m_params="
|
||||
for i = 1, table.getn(fields) do
|
||||
fnj_string = fnj_string .. fields[i] .. "+"
|
||||
end
|
||||
fnj_string = string.sub(fnj_string,1,string.len(fnj_string)-1)
|
||||
|
||||
fnj_string = fnj_string .. "%2F" .. unit .. "%2Fjson%2F"
|
||||
for i = 1, table.getn(joins) do
|
||||
fnj_string = fnj_string .. joins[i] .. "+"
|
||||
end
|
||||
fnj_string = fnj_string .. "%2F"
|
||||
|
||||
local params = {}
|
||||
-- If parameters where supplied in request_table, add them to the
|
||||
-- parameters in current_request_table.
|
||||
if request_table.params and
|
||||
request_table.params ~= current_request_table.params then
|
||||
-- First fill params with current_request_table parameters
|
||||
for k, v in pairs(current_request_table.params) do
|
||||
params[k] = v
|
||||
end
|
||||
-- Then add and overwrite them with request_table parameters
|
||||
for k, v in pairs(request_table.params) do
|
||||
params[k] = v
|
||||
end
|
||||
else -- Or just use current_request_table.params
|
||||
params = current_request_table.params
|
||||
end
|
||||
-- Form parameter string (like param1=value1¶m2=value2)
|
||||
local param_string = ""
|
||||
for k, v in pairs(params) do
|
||||
if type(v) == "table" then
|
||||
v = v.value
|
||||
end
|
||||
v = string.gsub(v, " ", "+")
|
||||
param_string = param_string .. "&" .. k .. "=" .. v
|
||||
end
|
||||
|
||||
return string.format(curl_str, string.format(url, fnj_string, param_string))
|
||||
end
|
||||
|
||||
-- Primitive function for parsing Jamendo API JSON response. Does not
|
||||
-- support arrays. Supports only strings and numbers as values.
|
||||
-- Provides basic safety (correctly handles special symbols like comma
|
||||
-- and curly brackets inside strings)
|
||||
-- text - JSON text
|
||||
function parse_json(text)
|
||||
local parse_table = {}
|
||||
local block = {}
|
||||
local i = 0
|
||||
local inblock = false
|
||||
local instring = false
|
||||
local curr_key = nil
|
||||
local curr_val = nil
|
||||
while i and i < string.len(text) do
|
||||
if not inblock then -- We are not inside the block, find next {
|
||||
i = string.find(text, "{", i+1)
|
||||
inblock = true
|
||||
block = {}
|
||||
else
|
||||
if not curr_key then -- We haven't found key yet
|
||||
if not instring then -- We are not in string, check for more tags
|
||||
local j = string.find(text, '"', i+1)
|
||||
local k = string.find(text, '}', i+1)
|
||||
if j and j < k then -- There are more tags in this block
|
||||
i = j
|
||||
instring = true
|
||||
else -- Block is over, we found its ending
|
||||
i = k
|
||||
inblock = false
|
||||
table.insert(parse_table, block)
|
||||
end
|
||||
else -- We are in string, find its ending
|
||||
_, i, curr_key = string.find(text,'(.-[^%\\])"', i+1)
|
||||
instring = false
|
||||
end
|
||||
else -- We have the key, let's find the value
|
||||
if not curr_val then -- Value is not found yet
|
||||
if not instring then -- Not in string, check if value is string
|
||||
local j = string.find(text, '"', i+1)
|
||||
local k = string.find(text, '[,}]', i+1)
|
||||
if j and j < k then -- Value is string
|
||||
i = j
|
||||
instring = true
|
||||
else -- Value is int
|
||||
_, i, curr_val = string.find(text,'(%d+)', i+1)
|
||||
end
|
||||
else -- We are in string, find its ending
|
||||
local j = string.find(text, '"', i+1)
|
||||
if j == i+1 then -- String is empty
|
||||
i = j
|
||||
curr_val = ""
|
||||
else
|
||||
_, i, curr_val = string.find(text,'(.-[^%\\])"', i+1)
|
||||
curr_val = utf8_codes_to_symbols(curr_val)
|
||||
end
|
||||
instring = false
|
||||
end
|
||||
else -- We have both key and value, add it to table
|
||||
block[curr_key] = curr_val
|
||||
curr_key = nil
|
||||
curr_val = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return parse_table
|
||||
end
|
||||
|
||||
-- Jamendo returns Unicode symbols as \uXXXX. Lua does not transform
|
||||
-- them into symbols so we need to do it ourselves.
|
||||
function utf8_codes_to_symbols (s)
|
||||
local hexnums = "[%dabcdefABCDEF]"
|
||||
local pattern = string.format("\\u(%s%s%s%s?)",
|
||||
hexnums, hexnums, hexnums, hexnums)
|
||||
local decode = function(code)
|
||||
code = tonumber(code, 16)
|
||||
if code < 128 then -- one-byte symbol
|
||||
return string.char(code)
|
||||
elseif code < 2048 then -- two-byte symbol
|
||||
-- Grab high and low bytes
|
||||
local hi = math.floor(code / 64)
|
||||
local lo = math.mod(code, 64)
|
||||
-- Return symbol as \hi\lo
|
||||
return string.char(hi + 192, lo + 128)
|
||||
elseif code < 65536 then
|
||||
-- Grab high, middle and low bytes
|
||||
local hi = math.floor(code / 4096)
|
||||
local leftover = code - hi * 4096
|
||||
local mi = math.floor(leftover / 64)
|
||||
leftover = leftover - mi * 64
|
||||
local lo = math.mod(leftover, 64)
|
||||
-- Return symbol as \hi\mi\lo
|
||||
return string.char(hi + 224, mi + 160, lo + 128)
|
||||
elseif code < 1114112 then
|
||||
-- Grab high, highmiddle, lowmiddle and low bytes
|
||||
local hi = math.floor(code / 262144)
|
||||
local leftover = code - hi * 262144
|
||||
local hm = math.floor(leftover / 4096)
|
||||
leftover = leftover - hm * 4096
|
||||
local lm = math.floor(leftover / 64)
|
||||
local lo = math.mod(leftover, 64)
|
||||
-- Return symbol as \hi\hm\lm\lo
|
||||
return string.char(hi + 240, hm + 128, lm + 128, lo + 128)
|
||||
else -- It is not Unicode symbol at all
|
||||
return tostring(code)
|
||||
end
|
||||
end
|
||||
return string.gsub(s, pattern, decode)
|
||||
end
|
||||
|
||||
-- Retrieves mapping of track IDs to track names and album IDs to
|
||||
-- avoid redundant queries when Awesome gets restarted.
|
||||
local function retrieve_cache()
|
||||
local bus = io.open(cache_file)
|
||||
local track = {}
|
||||
if bus then
|
||||
local header = bus:read("*line")
|
||||
if header == cache_header then
|
||||
for l in bus:lines() do
|
||||
local _, _, id, artist_link_name, album_name, album_id, track_name =
|
||||
string.find(l,"(%d+)-([^-]+)-([^-]+)-(%d+)-(.+)")
|
||||
track = {}
|
||||
track.id = id
|
||||
track.artist_link_name = string.gsub(artist_link_name, '\\_', '-')
|
||||
track.album_name = string.gsub(album_name, '\\_', '-')
|
||||
track.album_id = album_id
|
||||
track.display_name = track_name
|
||||
jamendo_list[id] = track
|
||||
end
|
||||
else
|
||||
-- We encountered an outdated version of the cache
|
||||
-- file. Let's just remove it.
|
||||
awful.util.spawn("rm -f " .. cache_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Saves track IDs to track names and album IDs mapping into the cache
|
||||
-- file.
|
||||
function save_cache()
|
||||
local bus = io.open(cache_file, "w")
|
||||
bus:write(cache_header .. "\n")
|
||||
for id,track in pairs(jamendo_list) do
|
||||
bus:write(string.format("%s-%s-%s-%s-%s\n", id,
|
||||
string.gsub(track.artist_link_name, '-', '\\_'),
|
||||
string.gsub(track.album_name, '-', '\\_'),
|
||||
track.album_id, track.display_name))
|
||||
end
|
||||
bus:flush()
|
||||
bus:close()
|
||||
end
|
||||
|
||||
-- Retrieve cache on initialization
|
||||
retrieve_cache()
|
||||
|
||||
-- Returns a filename of the album cover and formed wget request that
|
||||
-- downloads the album cover for the given track name. If the album
|
||||
-- cover already exists returns nil as the second argument.
|
||||
function fetch_album_cover_request(track_id)
|
||||
local track = jamendo_list[track_id]
|
||||
local album_id = track.album_id
|
||||
|
||||
if album_id == 0 then -- No cover for tracks without album!
|
||||
return nil
|
||||
end
|
||||
local file_path = album_covers_folder .. album_id .. ".jpg"
|
||||
|
||||
if not file_exists(file_path) then -- We need to download it
|
||||
-- First check if cache directory exists
|
||||
f = io.popen('test -d ' .. album_covers_folder .. ' && echo t')
|
||||
if f:read("*line") ~= 't' then
|
||||
awful.util.spawn("mkdir " .. album_covers_folder)
|
||||
end
|
||||
f:close()
|
||||
|
||||
if not track.album_image then -- Wow! We have album_id, but
|
||||
local a_id = tostring(album_id) --don't have album_image. Well,
|
||||
local prefix = --it happens.
|
||||
string.sub(a_id, 1, string.len(a_id) - 3)
|
||||
track.album_image =
|
||||
string.format("http://imgjam.com/albums/s%s/%s/covers/1.100.jpg",
|
||||
prefix == "" and 0 or prefix, a_id)
|
||||
end
|
||||
|
||||
return file_path, string.format("wget %s -O %s 2> /dev/null",
|
||||
track.album_image, file_path)
|
||||
else -- Cover already downloaded, return its filename and nil
|
||||
return file_path, nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns a file containing an album cover for given track id. First
|
||||
-- searches in the cache folder. If file is not there, fetches it from
|
||||
-- the Internet and saves into the cache folder.
|
||||
function get_album_cover(track_id)
|
||||
local file_path, fetch_req = fetch_album_cover_request(track_id)
|
||||
if fetch_req then
|
||||
local f = io.popen(fetch_req)
|
||||
f:close()
|
||||
|
||||
-- Let's check if file is finally there, just in case
|
||||
if not file_exists(file_path) then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return file_path
|
||||
end
|
||||
|
||||
-- Same as get_album_cover, but downloads (if necessary) the cover
|
||||
-- asynchronously.
|
||||
function get_album_cover_async(track_id)
|
||||
local file_path, fetch_req = fetch_album_cover_request(track_id)
|
||||
if fetch_req then
|
||||
asyncshell.request(fetch_req)
|
||||
end
|
||||
end
|
||||
|
||||
-- Checks if track_name is actually a link to Jamendo stream. If true
|
||||
-- returns the file with album cover for the track.
|
||||
function try_get_cover(track_name)
|
||||
local id = get_id_from_link(track_name)
|
||||
if id then
|
||||
return get_album_cover(id)
|
||||
end
|
||||
end
|
||||
|
||||
-- Same as try_get_cover, but calls get_album_cover_async inside.
|
||||
function try_get_cover_async(track_name)
|
||||
local id = get_id_from_link(track_name)
|
||||
if id then
|
||||
return get_album_cover_async(id)
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns the track table for given query and search method.
|
||||
-- what - search method - SEARCH_ARTIST, ALBUM or TAG
|
||||
-- s - string to search
|
||||
function search_by(what, s)
|
||||
-- Get a default request and set unit and query
|
||||
local req = search_template
|
||||
req.unit = what.unit
|
||||
req.params.searchquery = s
|
||||
local resp = perform_request(form_request(req))
|
||||
if resp then
|
||||
local search_res = parse_json(resp)[1]
|
||||
|
||||
if search_res then
|
||||
-- Now when we got the search result, find tracks filtered by
|
||||
-- this result.
|
||||
local params = {}
|
||||
params[what.value] = search_res.id
|
||||
req = { params = params }
|
||||
local track_table = return_track_table(req)
|
||||
return { search_res = search_res, tracks = track_table }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Executes request_string with io.popen and returns the response.
|
||||
function perform_request(reqest_string)
|
||||
local bus = assert(io.popen(reqest_string,'r'))
|
||||
local response = bus:read("*all")
|
||||
bus:close()
|
||||
-- Curl with popen can sometimes fail to fetch data when the
|
||||
-- connection is slow. Let's try again if it fails.
|
||||
if string.len(response) == 0 then
|
||||
bus = assert(io.popen(reqest_string,'r'))
|
||||
response = bus:read("*all")
|
||||
bus:close()
|
||||
-- If it still can't read anything, return nil
|
||||
if string.len(response) ~= 0 then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return response
|
||||
end
|
||||
|
||||
-- Sets default streamencoding in current_request_table.
|
||||
function set_current_format(format)
|
||||
current_request_table.params.streamencoding = format
|
||||
end
|
||||
|
||||
-- Sets default order in current_request_table.
|
||||
function set_current_order(order)
|
||||
current_request_table.params.order = order
|
||||
end
|
|
@ -0,0 +1,407 @@
|
|||
-- Standard awesome library
|
||||
require("awful")
|
||||
require("awful.autofocus")
|
||||
require("awful.rules")
|
||||
-- Theme handling library
|
||||
require("beautiful")
|
||||
-- Notification library
|
||||
require("naughty")
|
||||
|
||||
-- Load Debian menu entries
|
||||
require("debian.menu")
|
||||
|
||||
-- {{{ Variable definitions
|
||||
-- Themes define colours, icons, and wallpapers
|
||||
beautiful.init("/usr/share/awesome/themes/default/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
|
||||
|
||||
-- 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"
|
||||
|
||||
-- Table of layouts to cover with awful.layout.inc, order matters.
|
||||
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.spiral,
|
||||
awful.layout.suit.spiral.dwindle,
|
||||
awful.layout.suit.max,
|
||||
awful.layout.suit.max.fullscreen,
|
||||
awful.layout.suit.magnifier
|
||||
}
|
||||
-- }}}
|
||||
|
||||
-- {{{ Tags
|
||||
-- Define a tag table which hold all screen tags.
|
||||
tags = {}
|
||||
for s = 1, screen.count() do
|
||||
-- Each screen has its own tag table.
|
||||
tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1])
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ Menu
|
||||
-- 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", awesome.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 })
|
||||
-- }}}
|
||||
|
||||
-- {{{ Wibox
|
||||
-- Create a textclock widget
|
||||
mytextclock = awful.widget.textclock({ align = "right" })
|
||||
|
||||
-- Create a systray
|
||||
mysystray = widget({ type = "systray" })
|
||||
|
||||
-- BEGIN OF AWESOMPD WIDGET DECLARATION
|
||||
|
||||
require('awesompd/awesompd')
|
||||
|
||||
musicwidget = awesompd:create() -- Create awesompd widget
|
||||
musicwidget.font = "Liberation Mono" -- Set widget font
|
||||
musicwidget.scrolling = true -- If true, the text in the widget will be scrolled
|
||||
musicwidget.output_size = 30 -- Set the size of widget in symbols
|
||||
musicwidget.update_interval = 10 -- Set the update interval in seconds
|
||||
|
||||
-- Set the folder where icons are located (change username to your login name)
|
||||
musicwidget.path_to_icons = "/home/username/.config/awesome/icons"
|
||||
|
||||
-- Set the default music format for Jamendo streams. You can change
|
||||
-- this option on the fly in awesompd itself.
|
||||
-- possible formats: awesompd.FORMAT_MP3, awesompd.FORMAT_OGG
|
||||
musicwidget.jamendo_format = awesompd.FORMAT_MP3
|
||||
|
||||
-- Specify the browser you use so awesompd can open links from
|
||||
-- Jamendo in it.
|
||||
musicwidget.browser = "firefox"
|
||||
|
||||
-- If true, song notifications for Jamendo tracks and local tracks
|
||||
-- will also contain album cover image.
|
||||
musicwidget.show_album_cover = true
|
||||
|
||||
-- Specify how big in pixels should an album cover be. Maximum value
|
||||
-- is 100.
|
||||
musicwidget.album_cover_size = 50
|
||||
|
||||
-- This option is necessary if you want the album covers to be shown
|
||||
-- for your local tracks.
|
||||
musicwidget.mpd_config = "/home/username/.mpdconf"
|
||||
|
||||
-- Specify decorators on the left and the right side of the
|
||||
-- widget. Or just leave empty strings if you decorate the widget
|
||||
-- from outside.
|
||||
musicwidget.ldecorator = " "
|
||||
musicwidget.rdecorator = " "
|
||||
|
||||
-- Set all the servers to work with (here can be any servers you use)
|
||||
musicwidget.servers = {
|
||||
{ server = "localhost",
|
||||
port = 6600 },
|
||||
{ server = "192.168.0.72",
|
||||
port = 6600 }
|
||||
}
|
||||
|
||||
-- Set the buttons of the widget. Keyboard keys are working in the
|
||||
-- entire Awesome environment. Also look at the line 352.
|
||||
musicwidget:register_buttons({ { "", awesompd.MOUSE_LEFT, musicwidget:command_playpause() },
|
||||
{ "Control", awesompd.MOUSE_SCROLL_UP, musicwidget:command_prev_track() },
|
||||
{ "Control", awesompd.MOUSE_SCROLL_DOWN, musicwidget:command_next_track() },
|
||||
{ "", awesompd.MOUSE_SCROLL_UP, musicwidget:command_volume_up() },
|
||||
{ "", awesompd.MOUSE_SCROLL_DOWN, musicwidget:command_volume_down() },
|
||||
{ "", awesompd.MOUSE_RIGHT, musicwidget:command_show_menu() },
|
||||
{ "", "XF86AudioLowerVolume", musicwidget:command_volume_down() },
|
||||
{ "", "XF86AudioRaiseVolume", musicwidget:command_volume_up() },
|
||||
{ modkey, "Pause", musicwidget:command_playpause() } })
|
||||
|
||||
musicwidget:run() -- After all configuration is done, run the widget
|
||||
|
||||
-- END OF AWESOMPD WIDGET DECLARATION
|
||||
-- Don't forget to add the widget to the wibox. It is done on the line 216.
|
||||
|
||||
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
|
||||
client.focus = c
|
||||
c:raise()
|
||||
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.all, 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", screen = s })
|
||||
-- Add widgets to the wibox - order matters
|
||||
mywibox[s].widgets = {
|
||||
{
|
||||
mylauncher,
|
||||
mytaglist[s],
|
||||
mypromptbox[s],
|
||||
layout = awful.widget.layout.horizontal.leftright
|
||||
},
|
||||
mylayoutbox[s],
|
||||
mytextclock,
|
||||
musicwidget.widget, -- Awesompd widget is added like this
|
||||
s == 1 and mysystray or nil,
|
||||
mytasklist[s],
|
||||
layout = awful.widget.layout.horizontal.rightleft
|
||||
}
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ 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 bindings
|
||||
globalkeys = awful.util.table.join(
|
||||
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, }, "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 }, "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)
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
-- Compute the maximum number of digit we need, limited to 9
|
||||
keynumber = 0
|
||||
for s = 1, screen.count() do
|
||||
keynumber = math.min(9, math.max(#tags[s], keynumber));
|
||||
end
|
||||
|
||||
-- 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, keynumber do
|
||||
globalkeys = awful.util.table.join(globalkeys,
|
||||
awful.key({ modkey }, "#" .. i + 9,
|
||||
function ()
|
||||
local screen = mouse.screen
|
||||
if tags[screen][i] then
|
||||
awful.tag.viewonly(tags[screen][i])
|
||||
end
|
||||
end),
|
||||
awful.key({ modkey, "Control" }, "#" .. i + 9,
|
||||
function ()
|
||||
local screen = mouse.screen
|
||||
if tags[screen][i] then
|
||||
awful.tag.viewtoggle(tags[screen][i])
|
||||
end
|
||||
end),
|
||||
awful.key({ modkey, "Shift" }, "#" .. i + 9,
|
||||
function ()
|
||||
if client.focus and tags[client.focus.screen][i] then
|
||||
awful.client.movetotag(tags[client.focus.screen][i])
|
||||
end
|
||||
end),
|
||||
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
|
||||
function ()
|
||||
if client.focus and tags[client.focus.screen][i] then
|
||||
awful.client.toggletag(tags[client.focus.screen][i])
|
||||
end
|
||||
end))
|
||||
end
|
||||
|
||||
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))
|
||||
|
||||
-- Set keys
|
||||
-- Add this line before root.keys(globalkeys).
|
||||
musicwidget:append_global_keys()
|
||||
|
||||
root.keys(globalkeys)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Rules
|
||||
awful.rules.rules = {
|
||||
-- All clients will match this rule.
|
||||
{ rule = { },
|
||||
properties = { border_width = beautiful.border_width,
|
||||
border_color = beautiful.border_normal,
|
||||
focus = true,
|
||||
keys = clientkeys,
|
||||
buttons = clientbuttons } },
|
||||
{ rule = { class = "MPlayer" },
|
||||
properties = { floating = true } },
|
||||
{ rule = { class = "pinentry" },
|
||||
properties = { floating = true } },
|
||||
{ rule = { class = "gimp" },
|
||||
properties = { floating = true } },
|
||||
-- Set Firefox to always map on tags number 2 of screen 1.
|
||||
-- { rule = { class = "Firefox" },
|
||||
-- properties = { tag = tags[1][2] } },
|
||||
}
|
||||
-- }}}
|
||||
|
||||
-- {{{ Signals
|
||||
-- Signal function to execute when a new client appears.
|
||||
client.add_signal("manage", function (c, startup)
|
||||
-- Add a titlebar
|
||||
-- awful.titlebar.add(c, { modkey = modkey })
|
||||
|
||||
-- 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
|
||||
-- Set the windows at the slave,
|
||||
-- i.e. put it at the end of others instead of setting it master.
|
||||
-- awful.client.setslave(c)
|
||||
|
||||
-- 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)
|
||||
-- }}}
|
|
@ -0,0 +1,158 @@
|
|||
-- Provides UTF-8 aware string functions implemented in pure lua:
|
||||
-- * string.utf8len(s)
|
||||
-- * string.utf8sub(s, i, j)
|
||||
--
|
||||
-- All functions behave as their non UTF-8 aware counterparts with the exception
|
||||
-- that UTF-8 characters are used instead of bytes for all units.
|
||||
--
|
||||
-- Note: all validations had been removed due to awesome usage specifics.
|
||||
--[[
|
||||
Copyright (c) 2006-2007, Kyle Smith
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
--]]
|
||||
|
||||
-- ABNF from RFC 3629
|
||||
--
|
||||
-- UTF8-octets = *( UTF8-char )
|
||||
-- UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
|
||||
-- UTF8-1 = %x00-7F
|
||||
-- UTF8-2 = %xC2-DF UTF8-tail
|
||||
-- UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
|
||||
-- %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
|
||||
-- UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
|
||||
-- %xF4 %x80-8F 2( UTF8-tail )
|
||||
-- UTF8-tail = %x80-BF
|
||||
--
|
||||
|
||||
-- returns the number of bytes used by the UTF-8 character at byte i in s
|
||||
-- also doubles as a UTF-8 character validator
|
||||
function utf8charbytes (s, i)
|
||||
-- argument defaults
|
||||
i = i or 1
|
||||
local c = string.byte(s, i)
|
||||
|
||||
-- determine bytes needed for character, based on RFC 3629
|
||||
if c > 0 and c <= 127 then
|
||||
-- UTF8-1
|
||||
return 1
|
||||
elseif c >= 194 and c <= 223 then
|
||||
-- UTF8-2
|
||||
local c2 = string.byte(s, i + 1)
|
||||
return 2
|
||||
elseif c >= 224 and c <= 239 then
|
||||
-- UTF8-3
|
||||
local c2 = s:byte(i + 1)
|
||||
local c3 = s:byte(i + 2)
|
||||
return 3
|
||||
elseif c >= 240 and c <= 244 then
|
||||
-- UTF8-4
|
||||
local c2 = s:byte(i + 1)
|
||||
local c3 = s:byte(i + 2)
|
||||
local c4 = s:byte(i + 3)
|
||||
return 4
|
||||
end
|
||||
end
|
||||
|
||||
-- returns the number of characters in a UTF-8 string
|
||||
function utf8len (s)
|
||||
local pos = 1
|
||||
local bytes = string.len(s)
|
||||
local len = 0
|
||||
|
||||
while pos <= bytes and len ~= chars do
|
||||
local c = string.byte(s,pos)
|
||||
len = len + 1
|
||||
|
||||
pos = pos + utf8charbytes(s, pos)
|
||||
end
|
||||
|
||||
if chars ~= nil then
|
||||
return pos - 1
|
||||
end
|
||||
|
||||
return len
|
||||
end
|
||||
|
||||
-- functions identically to string.sub except that i and j are UTF-8 characters
|
||||
-- instead of bytes
|
||||
function utf8sub (s, i, j)
|
||||
j = j or -1
|
||||
|
||||
if i == nil then
|
||||
return ""
|
||||
end
|
||||
|
||||
local pos = 1
|
||||
local bytes = string.len(s)
|
||||
local len = 0
|
||||
|
||||
-- only set l if i or j is negative
|
||||
local l = (i >= 0 and j >= 0) or utf8len(s)
|
||||
local startChar = (i >= 0) and i or l + i + 1
|
||||
local endChar = (j >= 0) and j or l + j + 1
|
||||
|
||||
-- can't have start before end!
|
||||
if startChar > endChar then
|
||||
return ""
|
||||
end
|
||||
|
||||
-- byte offsets to pass to string.sub
|
||||
local startByte, endByte = 1, bytes
|
||||
|
||||
while pos <= bytes do
|
||||
len = len + 1
|
||||
|
||||
if len == startChar then
|
||||
startByte = pos
|
||||
end
|
||||
|
||||
pos = pos + utf8charbytes(s, pos)
|
||||
|
||||
if len == endChar then
|
||||
endByte = pos - 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return string.sub(s, startByte, endByte)
|
||||
end
|
||||
|
||||
-- replace UTF-8 characters based on a mapping table
|
||||
function utf8replace (s, mapping)
|
||||
local pos = 1
|
||||
local bytes = string.len(s)
|
||||
local charbytes
|
||||
local newstr = ""
|
||||
|
||||
while pos <= bytes do
|
||||
charbytes = utf8charbytes(s, pos)
|
||||
local c = string.sub(s, pos, pos + charbytes - 1)
|
||||
newstr = newstr .. (mapping[c] or c)
|
||||
pos = pos + charbytes
|
||||
end
|
||||
|
||||
return newstr
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
-- {{{ init environment
|
||||
local wakka = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display()
|
||||
local lines = "<u>Bitcoin:</u>\n"
|
||||
local tick = "<u>MtGox:</u>\n"
|
||||
local f = io.popen("bitcoind getbalance", "r")
|
||||
local t = io.popen("curl -q -s https://mtgox.com/code/data/ticker.php", "r")
|
||||
local s = f:read('*all')
|
||||
local g = t:read('*all')
|
||||
line = lines .. "\n" .. s .. "\n"
|
||||
ticker = tick .. "\n" .. g .. "\n"
|
||||
f:close()
|
||||
t:close()
|
||||
-- return line, ticker
|
||||
return string.format('%s%s',line, ticker)
|
||||
end
|
||||
|
||||
--local function ticker()
|
||||
-- local ticker = "<u>Ticker:</u>\n"
|
||||
-- local t = io.popen("curl -q -s https://mtgox.com/code/data/ticker.php", "r")
|
||||
-- local q = t:read('*all')
|
||||
-- line1 = ticker .. "\n" .. q .. "\n"
|
||||
-- t:close()
|
||||
-- return line1
|
||||
--end
|
||||
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
function wakka.addToWidget(mywidget)
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
run_display = display()
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", run_display),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
|
||||
return wakka
|
|
@ -0,0 +1,133 @@
|
|||
-- @author Peter J. Kranz (Absurd-Mind, peter@myref.net)
|
||||
-- Any questions, criticism or praise just drop me an email
|
||||
|
||||
-- {{{ init environment
|
||||
local M = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
units = {"KB", "MB", "GB", "TB", "PB", "EB"}
|
||||
local usage = {}
|
||||
-- }}}
|
||||
|
||||
-- {{{ local functions
|
||||
-- {{{ Unit formatter
|
||||
-- formats a value to the corresponding unit
|
||||
local function uformat(value)
|
||||
local ret = tonumber(value)
|
||||
for i, u in pairs(units) do
|
||||
if ret < 1024 then
|
||||
return string.format("%.1f" .. u, ret)
|
||||
end
|
||||
ret = ret / 1024;
|
||||
end
|
||||
return "N/A"
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ getData
|
||||
-- gets the required data from df
|
||||
local function getData(onlyLocal)
|
||||
-- Fallback to listing local filesystems
|
||||
local warg = ""
|
||||
if onlyLocal == true then
|
||||
warg = "-l"
|
||||
end
|
||||
|
||||
local fs_info = {} -- Get data from df
|
||||
local f = io.popen("LC_ALL=C df -kP " .. warg)
|
||||
|
||||
for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount)
|
||||
local s = string.match(line, "^.-[%s]([%d]+)")
|
||||
local u,a,p = string.match(line, "([%d]+)[%D]+([%d]+)[%D]+([%d]+)%%")
|
||||
local m = string.match(line, "%%[%s]([%p%w]+)")
|
||||
|
||||
if u and m then -- Handle 1st line and broken regexp
|
||||
fs_info[m] = {}
|
||||
fs_info[m]["size"] = s
|
||||
fs_info[m]["used"] = u
|
||||
fs_info[m]["avail"] = a
|
||||
fs_info[m]["used_p"] = tonumber(p)
|
||||
fs_info[m]["avail_p"] = 100 - tonumber(p)
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
return fs_info
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display(orange, red, onlyLocal)
|
||||
data = getData(onlyLocal)
|
||||
local lines = "<u>diskusage:</u>\n"
|
||||
|
||||
local longest = 0
|
||||
local longestSize = 0;
|
||||
local longestUsed = 0;
|
||||
for i, m in pairs(data) do
|
||||
if i:len() > longest then
|
||||
longest = i:len()
|
||||
end
|
||||
|
||||
local s = uformat(m["size"])
|
||||
if s:len() > longestSize then
|
||||
longestSize = s:len()
|
||||
end
|
||||
|
||||
local u = uformat(m["used"])
|
||||
if u:len() > longestUsed then
|
||||
longestUsed = u:len()
|
||||
end
|
||||
end
|
||||
longest = longest + 8
|
||||
|
||||
for i, m in pairs(data) do
|
||||
local u = uformat(m["used"])
|
||||
local s = uformat(m["size"])
|
||||
|
||||
if m["used_p"] >= red then
|
||||
lines = lines .. "<span color='darkred'>"
|
||||
elseif m["used_p"] >= orange then
|
||||
lines = lines .. "<span color='orange'>"
|
||||
else
|
||||
lines = lines .. "<span color='darkgreen'>"
|
||||
end
|
||||
|
||||
lines = lines
|
||||
.. "\n"
|
||||
.. i
|
||||
.. string.rep(" ", longest + longestSize - i:len() - u:len())
|
||||
.. u
|
||||
.. " / "
|
||||
.. s
|
||||
.. string.rep(" ", longestUsed - s:len())
|
||||
.. " ("
|
||||
.. m["used_p"]
|
||||
.. "%)</span>"
|
||||
end
|
||||
|
||||
return lines
|
||||
end
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
-- {{{ global functions
|
||||
function M.addToWidget(mywidget, orange, red, onlyLocal)
|
||||
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", display(orange, red, onlyLocal)),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
-- }}}
|
||||
|
||||
return M
|
|
@ -0,0 +1,126 @@
|
|||
local wibox = wibox
|
||||
local widget = widget
|
||||
local screen = screen
|
||||
local image = image
|
||||
local button = button
|
||||
local table = table
|
||||
local ipairs = ipairs
|
||||
local awful = require("awful")
|
||||
local utils = require("freedesktop.utils")
|
||||
|
||||
module("freedesktop.desktop")
|
||||
|
||||
local current_pos = {}
|
||||
local iconsize = { width = 48, height = 48 }
|
||||
local labelsize = { width = 130, height = 20 }
|
||||
local margin = { x = 20, y = 20 }
|
||||
|
||||
function add_icon(settings)
|
||||
|
||||
local s = settings.screen
|
||||
|
||||
if not current_pos[s] then
|
||||
current_pos[s] = { x = (screen[s].geometry.width - iconsize.width - margin.x), y = 40 }
|
||||
end
|
||||
|
||||
local totheight = (settings.icon and iconsize.height or 0) + (settings.label and labelsize.height or 0)
|
||||
if totheight == 0 then return end
|
||||
|
||||
if current_pos[s].y + totheight > screen[s].geometry.height - 40 then
|
||||
current_pos[s].x = current_pos[s].x - labelsize.width - iconsize.width - margin.x
|
||||
current_pos[s].y = 40
|
||||
end
|
||||
|
||||
if (settings.icon) then
|
||||
icon = awful.widget.button({ image = settings.icon })
|
||||
local newbuttons = icon:buttons()
|
||||
table.insert(newbuttons, button({}, 1, nil, settings.click));
|
||||
icon:buttons(newbuttons)
|
||||
|
||||
icon_container = wibox({ position = "floating", screen = s, bg = "#00000000" })
|
||||
icon_container.widgets = { icon }
|
||||
icon_container:geometry({
|
||||
width = iconsize.width,
|
||||
height = iconsize.height,
|
||||
y = current_pos[s].y,
|
||||
x = current_pos[s].x
|
||||
})
|
||||
icon_container.screen = s
|
||||
|
||||
current_pos[s].y = current_pos[s].y + iconsize.height + 5
|
||||
end
|
||||
|
||||
if (settings.label) then
|
||||
caption = widget({ type="textbox", align="right", width=labelsize.width })
|
||||
caption.ellipsize = "middle"
|
||||
caption.text = settings.label
|
||||
caption:buttons({
|
||||
button({ }, 1, settings.click)
|
||||
})
|
||||
|
||||
caption_container = wibox({ position = "floating", screen = s, bg = "#00000000" })
|
||||
caption_container.widgets = { caption }
|
||||
caption_container:geometry({
|
||||
width = labelsize.width,
|
||||
height = labelsize.height,
|
||||
y = current_pos[s].y,
|
||||
x = current_pos[s].x - labelsize.width + iconsize.width
|
||||
})
|
||||
caption_container.screen = s
|
||||
end
|
||||
|
||||
current_pos[s].y = current_pos[s].y + labelsize.height + margin.y
|
||||
end
|
||||
|
||||
--- Adds subdirs and files icons to the desktop
|
||||
-- @param dir The directory to parse, (default is ~/Desktop)
|
||||
-- @param showlabels Shows icon captions (default is false)
|
||||
function add_applications_icons(arg)
|
||||
for i, program in ipairs(utils.parse_desktop_files({
|
||||
dir = arg.dir or '~/Desktop/',
|
||||
icon_sizes = {
|
||||
iconsize.width .. "x" .. iconsize.height,
|
||||
"128x128", "96x96", "72x72", "64x64", "48x48",
|
||||
"36x36", "32x32", "24x24", "22x22", "16x6"
|
||||
}
|
||||
})) do
|
||||
if program.show then
|
||||
add_icon({
|
||||
label = arg.showlabels and program.Name or nil,
|
||||
icon = program.icon_path,
|
||||
screen = arg.screen,
|
||||
click = function () awful.util.spawn(program.cmdline) end
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Adds subdirs and files icons to the desktop
|
||||
-- @param dir The directory to parse
|
||||
-- @param showlabels Shows icon captions
|
||||
-- @param open_with The program to use to open clicked files and dirs (i.e. xdg_open, thunar, etc.)
|
||||
function add_dirs_and_files_icons(arg)
|
||||
arg.open_with = arg.open_width or 'thunar'
|
||||
for i, file in ipairs(utils.parse_dirs_and_files({
|
||||
dir = arg.dir or '~/Desktop/',
|
||||
icon_sizes = {
|
||||
iconsize.width .. "x" .. iconsize.height,
|
||||
"128x128", "96x96", "72x72", "64x64", "48x48",
|
||||
"36x36", "32x32", "24x24", "22x22", "16x6"
|
||||
}
|
||||
})) do
|
||||
if file.show then
|
||||
add_icon({
|
||||
label = arg.showlabels and file.filename or nil,
|
||||
icon = file.icon,
|
||||
screen = arg.screen,
|
||||
click = function () awful.util.spawn(arg.open_with .. ' ' .. file.path) end
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function add_desktop_icons(args)
|
||||
add_applications_icons(args)
|
||||
add_dirs_and_files_icons(args)
|
||||
end
|
|
@ -0,0 +1,97 @@
|
|||
-- Grab environment
|
||||
local utils = require("freedesktop.utils")
|
||||
local io = io
|
||||
local string = string
|
||||
local table = table
|
||||
local os = os
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
|
||||
module("freedesktop.menu")
|
||||
|
||||
all_menu_dirs = {
|
||||
'/usr/share/applications/',
|
||||
'/usr/local/share/applications/',
|
||||
'~/.local/share/applications/'
|
||||
}
|
||||
|
||||
show_generic_name = false
|
||||
|
||||
--- Create menus for applications
|
||||
-- @param menu_dirs A list of application directories (optional).
|
||||
-- @return A prepared menu w/ categories
|
||||
function new(arg)
|
||||
-- the categories and their synonyms where shamelessly copied from lxpanel
|
||||
-- source code.
|
||||
local programs = {}
|
||||
local config = arg or {}
|
||||
|
||||
programs['AudioVideo'] = {}
|
||||
programs['Development'] = {}
|
||||
programs['Education'] = {}
|
||||
programs['Game'] = {}
|
||||
programs['Graphics'] = {}
|
||||
programs['Network'] = {}
|
||||
programs['Office'] = {}
|
||||
programs['Settings'] = {}
|
||||
programs['System'] = {}
|
||||
programs['Utility'] = {}
|
||||
programs['Other'] = {}
|
||||
|
||||
for i, dir in ipairs(config.menu_dirs or all_menu_dirs) do
|
||||
local entries = utils.parse_desktop_files({dir = dir})
|
||||
for j, program in ipairs(entries) do
|
||||
-- check whether to include in the menu
|
||||
if program.show and program.Name and program.cmdline then
|
||||
if show_generic_name and program.GenericName then
|
||||
program.Name = program.Name .. ' (' .. program.GenericName .. ')'
|
||||
end
|
||||
local target_category = nil
|
||||
if program.categories then
|
||||
for _, category in ipairs(program.categories) do
|
||||
if programs[category] then
|
||||
target_category = category
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not target_category then
|
||||
target_category = 'Other'
|
||||
end
|
||||
if target_category then
|
||||
table.insert(programs[target_category], { program.Name, program.cmdline, program.icon_path })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- sort each submenu alphabetically case insensitive
|
||||
for k, v in pairs(programs) do
|
||||
table.sort(v, function(a, b) return a[1]:lower() < b[1]:lower() end)
|
||||
end
|
||||
|
||||
local menu = {
|
||||
{ "Accessories", programs["Utility"], utils.lookup_icon({ icon = 'applications-accessories.png' }) },
|
||||
{ "Development", programs["Development"], utils.lookup_icon({ icon = 'applications-development.png' }) },
|
||||
{ "Education", programs["Education"], utils.lookup_icon({ icon = 'applications-science.png' }) },
|
||||
{ "Games", programs["Game"], utils.lookup_icon({ icon = 'applications-games.png' }) },
|
||||
{ "Graphics", programs["Graphics"], utils.lookup_icon({ icon = 'applications-graphics.png' }) },
|
||||
{ "Internet", programs["Network"], utils.lookup_icon({ icon = 'applications-internet.png' }) },
|
||||
{ "Multimedia", programs["AudioVideo"], utils.lookup_icon({ icon = 'applications-multimedia.png' }) },
|
||||
{ "Office", programs["Office"], utils.lookup_icon({ icon = 'applications-office.png' }) },
|
||||
{ "Other", programs["Other"], utils.lookup_icon({ icon = 'applications-other.png' }) },
|
||||
{ "Settings", programs["Settings"], utils.lookup_icon({ icon = 'preferences-desktop.png' }) },
|
||||
{ "System Tools", programs["System"], utils.lookup_icon({ icon = 'applications-system.png' }) },
|
||||
}
|
||||
|
||||
-- Removing empty entries from menu
|
||||
local cleanedMenu = {}
|
||||
for index, item in ipairs(menu) do
|
||||
itemTester = item[2]
|
||||
if itemTester[1] then
|
||||
table.insert(cleanedMenu, item)
|
||||
end
|
||||
end
|
||||
|
||||
return cleanedMenu
|
||||
end
|
|
@ -0,0 +1,255 @@
|
|||
-- Grab environment
|
||||
|
||||
local io = io
|
||||
local os = os
|
||||
local table = table
|
||||
local type = type
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
|
||||
module("freedesktop.utils")
|
||||
|
||||
terminal = 'xterm'
|
||||
|
||||
icon_theme = nil
|
||||
|
||||
all_icon_sizes = {
|
||||
'128x128',
|
||||
'96x96',
|
||||
'72x72',
|
||||
'64x64',
|
||||
'48x48',
|
||||
'36x36',
|
||||
'32x32',
|
||||
'24x24',
|
||||
'22x22',
|
||||
'16x16'
|
||||
}
|
||||
all_icon_types = {
|
||||
'apps',
|
||||
'actions',
|
||||
'devices',
|
||||
'places',
|
||||
'categories',
|
||||
'status',
|
||||
'mimetypes'
|
||||
}
|
||||
all_icon_paths = { os.getenv("HOME") .. '/.icons/', '/usr/share/icons/' }
|
||||
|
||||
icon_sizes = {}
|
||||
|
||||
local mime_types = {}
|
||||
|
||||
function get_lines(...)
|
||||
local f = io.popen(...)
|
||||
return function () -- iterator
|
||||
local data = f:read()
|
||||
if data == nil then f:close() end
|
||||
return data
|
||||
end
|
||||
end
|
||||
|
||||
function file_exists(filename)
|
||||
local file = io.open(filename, 'r')
|
||||
local result = (file ~= nil)
|
||||
if result then
|
||||
file:close()
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function lookup_icon(arg)
|
||||
if arg.icon:sub(1, 1) == '/' and (arg.icon:find('.+%.png') or arg.icon:find('.+%.xpm')) then
|
||||
-- icons with absolute path and supported (AFAICT) formats
|
||||
return arg.icon
|
||||
else
|
||||
local icon_path = {}
|
||||
local icon_themes = {}
|
||||
local icon_theme_paths = {}
|
||||
if icon_theme and type(icon_theme) == 'table' then
|
||||
icon_themes = icon_theme
|
||||
elseif icon_theme then
|
||||
icon_themes = { icon_theme }
|
||||
end
|
||||
for i, theme in ipairs(icon_themes) do
|
||||
for j, path in ipairs(all_icon_paths) do
|
||||
table.insert(icon_theme_paths, path .. theme .. '/')
|
||||
end
|
||||
-- TODO also look in parent icon themes, as in freedesktop.org specification
|
||||
end
|
||||
table.insert(icon_theme_paths, '/usr/share/icons/hicolor/') -- fallback theme cf spec
|
||||
|
||||
local isizes = icon_sizes
|
||||
for i, sz in ipairs(all_icon_sizes) do
|
||||
table.insert(isizes, sz)
|
||||
end
|
||||
|
||||
for i, icon_theme_directory in ipairs(icon_theme_paths) do
|
||||
for j, size in ipairs(arg.icon_sizes or isizes) do
|
||||
for k, icon_type in ipairs(all_icon_types) do
|
||||
table.insert(icon_path, icon_theme_directory .. size .. '/' .. icon_type .. '/')
|
||||
end
|
||||
end
|
||||
end
|
||||
-- lowest priority fallbacks
|
||||
table.insert(icon_path, '/usr/share/pixmaps/')
|
||||
table.insert(icon_path, '/usr/share/icons/')
|
||||
table.insert(icon_path, '/usr/share/app-install/icons/')
|
||||
|
||||
for i, directory in ipairs(icon_path) do
|
||||
if (arg.icon:find('.+%.png') or arg.icon:find('.+%.xpm')) and file_exists(directory .. arg.icon) then
|
||||
return directory .. arg.icon
|
||||
elseif file_exists(directory .. arg.icon .. '.png') then
|
||||
return directory .. arg.icon .. '.png'
|
||||
elseif file_exists(directory .. arg.icon .. '.xpm') then
|
||||
return directory .. arg.icon .. '.xpm'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function lookup_file_icon(arg)
|
||||
load_mime_types()
|
||||
|
||||
local extension = arg.filename:match('%a+$')
|
||||
local mime = mime_types[extension] or ''
|
||||
local mime_family = mime:match('^%a+') or ''
|
||||
|
||||
-- possible icons in a typical gnome theme (i.e. Tango icons)
|
||||
local possible_filenames = {
|
||||
mime,
|
||||
'gnome-mime-' .. mime,
|
||||
mime_family,
|
||||
'gnome-mime-' .. mime_family,
|
||||
extension
|
||||
}
|
||||
|
||||
for i, filename in ipairs(possible_filenames) do
|
||||
local icon = lookup_icon({icon = filename, icon_sizes = (arg.icon_sizes or all_icon_sizes)})
|
||||
if icon then
|
||||
return icon
|
||||
end
|
||||
end
|
||||
|
||||
-- If we don't find ad icon, then pretend is a plain text file
|
||||
return lookup_icon({ icon = 'txt', icon_sizes = arg.icon_sizes or all_icon_sizes })
|
||||
end
|
||||
|
||||
--- Load system MIME types
|
||||
-- @return A table with file extension <--> MIME type mapping
|
||||
function load_mime_types()
|
||||
if #mime_types == 0 then
|
||||
for line in io.lines('/etc/mime.types') do
|
||||
if not line:find('^#') then
|
||||
local parsed = {}
|
||||
for w in line:gmatch('[^%s]+') do
|
||||
table.insert(parsed, w)
|
||||
end
|
||||
if #parsed > 1 then
|
||||
for i = 2, #parsed do
|
||||
mime_types[parsed[i]] = parsed[1]:gsub('/', '-')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Parse a .desktop file
|
||||
-- @param file The .desktop file
|
||||
-- @param requested_icon_sizes A list of icon sizes (optional). If this list is given, it will be used as a priority list for icon sizes when looking up for icons. If you want large icons, for example, you can put '128x128' as the first item in the list.
|
||||
-- @return A table with file entries.
|
||||
function parse_desktop_file(arg)
|
||||
local program = { show = true, file = arg.file }
|
||||
for line in io.lines(arg.file) do
|
||||
for key, value in line:gmatch("(%w+)=(.+)") do
|
||||
program[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
-- Don't show the program if NoDisplay is true
|
||||
-- Only show the program if there is not OnlyShowIn attribute
|
||||
-- or if it's equal to 'awesome'
|
||||
if program.NoDisplay == "true" or program.OnlyShowIn ~= nil and program.OnlyShowIn ~= "awesome" then
|
||||
program.show = false
|
||||
end
|
||||
|
||||
-- Look up for a icon.
|
||||
if program.Icon then
|
||||
program.icon_path = lookup_icon({ icon = program.Icon, icon_sizes = (arg.icon_sizes or all_icon_sizes) })
|
||||
if program.icon_path ~= nil and not file_exists(program.icon_path) then
|
||||
program.icon_path = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Split categories into a table.
|
||||
if program.Categories then
|
||||
program.categories = {}
|
||||
for category in program.Categories:gmatch('[^;]+') do
|
||||
table.insert(program.categories, category)
|
||||
end
|
||||
end
|
||||
|
||||
if program.Exec then
|
||||
local cmdline = program.Exec:gsub('%%c', program.Name)
|
||||
cmdline = cmdline:gsub('%%[fmuFMU]', '')
|
||||
cmdline = cmdline:gsub('%%k', program.file)
|
||||
if program.icon_path then
|
||||
cmdline = cmdline:gsub('%%i', '--icon ' .. program.icon_path)
|
||||
else
|
||||
cmdline = cmdline:gsub('%%i', '')
|
||||
end
|
||||
if program.Terminal == "true" then
|
||||
cmdline = terminal .. ' -e ' .. cmdline
|
||||
end
|
||||
program.cmdline = cmdline
|
||||
end
|
||||
|
||||
return program
|
||||
end
|
||||
|
||||
--- Parse a directory with .desktop files
|
||||
-- @param dir The directory.
|
||||
-- @param icons_size, The icons sizes, optional.
|
||||
-- @return A table with all .desktop entries.
|
||||
function parse_desktop_files(arg)
|
||||
local programs = {}
|
||||
local files = get_lines('find '.. arg.dir ..' -name "*.desktop" 2>/dev/null')
|
||||
for file in files do
|
||||
arg.file = file
|
||||
table.insert(programs, parse_desktop_file(arg))
|
||||
end
|
||||
return programs
|
||||
end
|
||||
|
||||
--- Parse a directory files and subdirs
|
||||
-- @param dir The directory.
|
||||
-- @param icons_size, The icons sizes, optional.
|
||||
-- @return A table with all .desktop entries.
|
||||
function parse_dirs_and_files(arg)
|
||||
local files = {}
|
||||
local paths = get_lines('find '..arg.dir..' -maxdepth 1 -type d')
|
||||
for path in paths do
|
||||
if path:match("[^/]+$") then
|
||||
local file = {}
|
||||
file.filename = path:match("[^/]+$")
|
||||
file.path = path
|
||||
file.show = true
|
||||
file.icon = lookup_icon({ icon = "folder", icon_sizes = (arg.icon_sizes or all_icon_sizes) })
|
||||
table.insert(files, file)
|
||||
end
|
||||
end
|
||||
local paths = get_lines('find '..arg.dir..' -maxdepth 1 -type f')
|
||||
for path in paths do
|
||||
if not path:find("%.desktop$") then
|
||||
local file = {}
|
||||
file.filename = path:match("[^/]+$")
|
||||
file.path = path
|
||||
file.show = true
|
||||
file.icon = lookup_file_icon({ filename = file.filename, icon_sizes = (arg.icon_sizes or all_icon_sizes) })
|
||||
table.insert(files, file)
|
||||
end
|
||||
end
|
||||
return files
|
||||
end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
-- {{{ init environment
|
||||
local wakka = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display()
|
||||
local lines = "<u>GFX Temp:</u>\n"
|
||||
local f = io.popen("ssh setkeh@192.168.1.8 /opt/bin/aticonfig --odgt | grep Temperature | cut -c 43-52", "r")
|
||||
local s = f:read('*all')
|
||||
line = lines .. "\n" .. s .. "\n"
|
||||
f:close()
|
||||
return line
|
||||
end
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
function wakka.addToWidget(mywidget)
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
|
||||
return wakka
|
|
@ -0,0 +1,47 @@
|
|||
## check-gmail.py -- A command line util to check GMail -*- Python -*-
|
||||
## modified to display mailbox summary for conky
|
||||
|
||||
# ======================================================================
|
||||
# Copyright (C) 2006 Baishampayan Ghose <b.ghose@ubuntu.com>
|
||||
# Modified 2008 Hunter Loftis <hbloftis@uncc.edu>
|
||||
# Time-stamp: Mon Jul 31, 2006 20:45+0530
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation.
|
||||
# ======================================================================
|
||||
|
||||
import sys
|
||||
import urllib # For BasicHTTPAuthentication
|
||||
import feedparser # For parsing the feed
|
||||
from textwrap import wrap
|
||||
|
||||
_URL = "https://mail.google.com/gmail/feed/atom"
|
||||
|
||||
uname = sys.argv[1]
|
||||
password = sys.argv[2]
|
||||
maxlen = sys.argv[3]
|
||||
|
||||
urllib.FancyURLopener.prompt_user_passwd = lambda self, host, realm: (uname, password)
|
||||
|
||||
def auth():
|
||||
'''The method to do HTTPBasicAuthentication'''
|
||||
opener = urllib.FancyURLopener()
|
||||
f = opener.open(_URL)
|
||||
feed = f.read()
|
||||
return feed
|
||||
|
||||
|
||||
def readmail(feed, maxlen):
|
||||
'''Parse the Atom feed and print a summary'''
|
||||
atom = feedparser.parse(feed)
|
||||
print '${color1} %s new email(s)\n' % (len(atom.entries))
|
||||
for i in range(min(len(atom.entries), maxlen)):
|
||||
print ' ${color2}%s' % atom.entries[i].title
|
||||
#uncomment the following line if you want to show the name of the sender
|
||||
# print ' ${color2}%s' % atom.entries[i].author
|
||||
if len(atom.entries) > maxlen:
|
||||
print ' ${color}more...'
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = auth() # Do auth and then get the feed
|
||||
readmail(f, int(maxlen)) # Let the feed be chewed by feedparser
|
|
@ -0,0 +1,95 @@
|
|||
function HTML_ToText (text)
|
||||
-- Declare variables, load the file. Make tags lowercase.
|
||||
text = string.gsub (text,"(%b<>)",
|
||||
function (tag)
|
||||
return tag:lower()
|
||||
end)
|
||||
--[[
|
||||
First we kill the developer formatting (tabs, CR, LF)
|
||||
and produce a long string with no newlines and tabs.
|
||||
We also kill repeated spaces as browsers ignore them anyway.
|
||||
]]
|
||||
local devkill=
|
||||
{
|
||||
["("..string.char(10)..")"] = " ",
|
||||
["("..string.char(13)..")"] = " ",
|
||||
["("..string.char(15)..")"] = "",
|
||||
["(%s%s+)"]=" ",
|
||||
}
|
||||
for pat, res in pairs (devkill) do
|
||||
text = string.gsub (text, pat, res)
|
||||
end
|
||||
-- Then we remove the header. We do this by stripping it first.
|
||||
text = string.gsub (text, "(<%s*head[^>]*>)", "<head>")
|
||||
text = string.gsub (text, "(<%s*%/%s*head%s*>)", "</head>")
|
||||
text = string.gsub (text, "(<head>,*<%/head>)", "")
|
||||
-- Kill all scripts. First we nuke their attribs.
|
||||
text = string.gsub (text, "(<%s*script[^>]*>)", "<script>")
|
||||
text = string.gsub (text, "(<%s*%/%s*script%s*>)", "</script>")
|
||||
text = string.gsub (text, "(<script>,*<%/script>)", "")
|
||||
-- Ok, same for styles.
|
||||
text = string.gsub (text, "(<%s*style[^>]*>)", "<style>")
|
||||
text = string.gsub (text, "(<%s*%/%s*style%s*>)", "</style>")
|
||||
text = string.gsub (text, "(<style>.*<%/style>)", "")
|
||||
|
||||
-- Replace <td> with tabulators.
|
||||
text = string.gsub (text, "(<%s*td[^>]*>)","\t")
|
||||
|
||||
-- Replace <br> with linebreaks.
|
||||
text = string.gsub (text, "(<%s*br%s*%/%s*>)","\n")
|
||||
|
||||
-- Replace <li> with an asterisk surrounded by 2 spaces.
|
||||
-- Replace </li> with a newline.
|
||||
text = string.gsub (text, "(<%s*li%s*%s*>)"," * ")
|
||||
text = string.gsub (text, "(<%s*/%s*li%s*%s*>)","\n")
|
||||
|
||||
-- <p>, <div>, <tr>, <ul> will be replaced to a double newline.
|
||||
text = string.gsub (text, "(<%s*div[^>]*>)", "\n\n")
|
||||
text = string.gsub (text, "(<%s*p[^>]*>)", "\n\n")
|
||||
text = string.gsub (text, "(<%s*tr[^>]*>)", "\n\n")
|
||||
text = string.gsub (text, "(<%s*%/*%s*ul[^>]*>)", "\n\n")
|
||||
--
|
||||
|
||||
-- Nuke all other tags now.
|
||||
text = string.gsub (text, "(%b<>)","")
|
||||
|
||||
-- Replace entities to their correspondant stuff where applicable.
|
||||
-- C# is owned badly here by using a table. :-P
|
||||
-- A metatable secures entities, so you can add them natively as keys.
|
||||
-- Enclosing brackets also get added automatically (capture!)
|
||||
local entities = {}
|
||||
setmetatable (entities,
|
||||
{
|
||||
__newindex = function (tbl, key, value)
|
||||
key = string.gsub (key, "(%#)" , "%%#")
|
||||
key = string.gsub (key, "(%&)" , "%%&")
|
||||
key = string.gsub (key, "(%;)" , "%%;")
|
||||
key = string.gsub (key, "(.+)" , "("..key..")")
|
||||
rawset (tbl, key, value)
|
||||
end
|
||||
})
|
||||
entities =
|
||||
{
|
||||
[" "] = " ",
|
||||
["•"] = " * ",
|
||||
["‹"] = "<",
|
||||
["›"] = ">",
|
||||
["™"] = "(tm)",
|
||||
["⁄"] = "/",
|
||||
["<"] = "<",
|
||||
[">"] = ">",
|
||||
["©"] = "(c)",
|
||||
["®"] = "(r)",
|
||||
-- Then kill all others.
|
||||
-- You can customize this table if you would like to,
|
||||
-- I just got bored of copypasting. :-)
|
||||
-- http://hotwired.lycos.com/webmonkey/reference/special_characters/
|
||||
["%&.+%;"] = "",
|
||||
}
|
||||
for entity, repl in pairs (entities) do
|
||||
text = string.gsub (text, entity, repl)
|
||||
end
|
||||
|
||||
return text
|
||||
|
||||
end
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
|
||||
-- Standard awesome library
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
awful.rules = require("awful.rules")
|
||||
require("awful.autofocus")
|
||||
-- Widget and layout library
|
||||
local wibox = require("wibox")
|
||||
-- Theme handling library
|
||||
local beautiful = require("beautiful")
|
||||
beautiful.init("/home/rat/.config/awesome/themes/default/theme.lua")
|
||||
-- Notification library
|
||||
local naughty = require("naughty")
|
||||
local menubar = require("menubar")
|
||||
--FreeDesktop
|
||||
require('freedesktop.utils')
|
||||
require('freedesktop.menu')
|
||||
freedesktop.utils.icon_theme = 'gnome'
|
||||
--Vicious + Widgets
|
||||
vicious = require("vicious")
|
||||
|
||||
globalkeys = {}
|
||||
|
||||
|
||||
|
||||
-- {{{ Key bindings
|
||||
globalkeys = awful.util.table.join(
|
||||
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, }, "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({ }, "Print", function () awful.util.spawn("upload_screens scr") end),
|
||||
|
||||
awful.key({ }, "XF86AudioRaiseVolume", function () volumecfg.up(0) end),
|
||||
awful.key({ }, "XF86AudioLowerVolume", function () volumecfg.down(0) end),
|
||||
awful.key({ }, "XF86AudioMute", function () volumecfg.toggle() 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),
|
||||
awful.key({ modkey, }, "w", function () awful.util.spawn("luakit") end, "Start Luakit Web Browser"),
|
||||
|
||||
awful.key({ modkey, "Control" }, "n", awful.client.restore),
|
||||
|
||||
-- Prompt
|
||||
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),
|
||||
-- Menubar
|
||||
awful.key({ modkey }, "p", function() menubar.show() end)
|
||||
)
|
||||
|
||||
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, }, "t", function (c) c.ontop = not c.ontop end),
|
||||
awful.key({ modkey, }, "n",
|
||||
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),
|
||||
awful.key({ modkey, }, "m",
|
||||
function (c)
|
||||
c.maximized_horizontal = not c.maximized_horizontal
|
||||
c.maximized_vertical = not c.maximized_vertical
|
||||
end)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
-- Set keys
|
||||
root.keys(globalkeys)
|
||||
-- }}}
|
|
@ -0,0 +1,123 @@
|
|||
-- Document key bindings
|
||||
|
||||
local awful = require("awful")
|
||||
local table = table
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local math = math
|
||||
local string = string
|
||||
local type = type
|
||||
local modkey = "Mod4"
|
||||
local beautiful = require("beautiful")
|
||||
local naughty = require("naughty")
|
||||
local capi = {
|
||||
root = root,
|
||||
client = client
|
||||
}
|
||||
|
||||
module("keydoc")
|
||||
|
||||
local doc = { }
|
||||
local currentgroup = "Misc"
|
||||
local orig = awful.key.new
|
||||
|
||||
-- Replacement for awful.key.new
|
||||
local function new(mod, key, press, release, docstring)
|
||||
-- Usually, there is no use of release, let's just use it for doc
|
||||
-- if it's a string.
|
||||
if press and release and not docstring and type(release) == "string" then
|
||||
docstring = release
|
||||
release = nil
|
||||
end
|
||||
local k = orig(mod, key, press, release)
|
||||
-- Remember documentation for this key (we take the first one)
|
||||
if k and #k > 0 and docstring then
|
||||
doc[k[1]] = { help = docstring,
|
||||
group = currentgroup }
|
||||
end
|
||||
|
||||
return k
|
||||
end
|
||||
awful.key.new = new -- monkey patch
|
||||
|
||||
-- Turn a key to a string
|
||||
local function key2str(key)
|
||||
local sym = key.key or key.keysym
|
||||
local translate = {
|
||||
["#14"] = "#",
|
||||
[" "] = "Space",
|
||||
}
|
||||
sym = translate[sym] or sym
|
||||
if not key.modifiers or #key.modifiers == 0 then return sym end
|
||||
local result = ""
|
||||
local translate = {
|
||||
[modkey] = "⊞",
|
||||
Shift = "⇧",
|
||||
Control = "Ctrl",
|
||||
}
|
||||
for _, mod in pairs(key.modifiers) do
|
||||
mod = translate[mod] or mod
|
||||
result = result .. mod .. " + "
|
||||
end
|
||||
return result .. sym
|
||||
end
|
||||
|
||||
-- Unicode "aware" length function (well, UTF8 aware)
|
||||
-- See: http://lua-users.org/wiki/LuaUnicode
|
||||
local function unilen(str)
|
||||
local _, count = string.gsub(str, "[^\128-\193]", "")
|
||||
return count
|
||||
end
|
||||
|
||||
-- Start a new group
|
||||
function group(name)
|
||||
currentgroup = name
|
||||
return {}
|
||||
end
|
||||
|
||||
local function markup(keys)
|
||||
local result = {}
|
||||
|
||||
-- Compute longest key combination
|
||||
local longest = 0
|
||||
for _, key in ipairs(keys) do
|
||||
if doc[key] then
|
||||
longest = math.max(longest, unilen(key2str(key)))
|
||||
end
|
||||
end
|
||||
|
||||
local curgroup = nil
|
||||
for _, key in ipairs(keys) do
|
||||
if doc[key] then
|
||||
local help, group = doc[key].help, doc[key].group
|
||||
local skey = key2str(key)
|
||||
result[group] = (result[group] or "") ..
|
||||
'<span font="DejaVu Sans Mono 10" color="' .. beautiful.fg_widget_clock .. '"> ' ..
|
||||
string.format("%" .. (longest - unilen(skey)) .. "s ", "") .. skey ..
|
||||
'</span> <span color="' .. beautiful.fg_widget_value .. '">' ..
|
||||
help .. '</span>\n'
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
-- Display help in a naughty notification
|
||||
local nid = nil
|
||||
function display()
|
||||
local strings = awful.util.table.join(
|
||||
markup(capi.root.keys()),
|
||||
capi.client.focus and markup(capi.client.focus:keys()) or {})
|
||||
|
||||
local result = ""
|
||||
for group, res in pairs(strings) do
|
||||
if #result > 0 then result = result .. "\n" end
|
||||
result = result ..
|
||||
'<span weight="bold" color="' .. beautiful.fg_widget_value_important .. '">' ..
|
||||
group .. "</span>\n" .. res
|
||||
end
|
||||
nid = naughty.notify({ text = result,
|
||||
replaces_id = nid,
|
||||
hover_timeout = 0.1,
|
||||
timeout = 30 }).id
|
||||
end
|
|
@ -0,0 +1,36 @@
|
|||
function table.val_to_str ( v )
|
||||
if "string" == type( v ) then
|
||||
v = string.gsub( v, "\n", "\\n" )
|
||||
if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
|
||||
return "'" .. v .. "'"
|
||||
end
|
||||
return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
|
||||
else
|
||||
return "table" == type( v ) and table.tostring( v ) or
|
||||
tostring( v )
|
||||
end
|
||||
end
|
||||
|
||||
function table.key_to_str ( k )
|
||||
if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
|
||||
return k
|
||||
else
|
||||
return "[" .. table.val_to_str( k ) .. "]"
|
||||
end
|
||||
end
|
||||
|
||||
function table.tostring( tbl )
|
||||
local result, done = {}, {}
|
||||
for k, v in ipairs( tbl ) do
|
||||
table.insert( result, table.val_to_str( v ) )
|
||||
done[ k ] = true
|
||||
end
|
||||
for k, v in pairs( tbl ) do
|
||||
if not done[ k ] then
|
||||
table.insert( result,
|
||||
table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
|
||||
end
|
||||
end
|
||||
return "{" .. table.concat( result, "," ) .. "}"
|
||||
end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
-- {{{ init environment
|
||||
local wakka = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display()
|
||||
local lines = "<u>Namecoin:</u>\n"
|
||||
local f = io.popen("namecoind getbalance", "r")
|
||||
local s = f:read('*all')
|
||||
line = lines .. "\n" .. s .. "\n"
|
||||
f:close()
|
||||
return line
|
||||
end
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
function wakka.addToWidget(mywidget)
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
|
||||
return wakka
|
|
@ -0,0 +1,34 @@
|
|||
-- {{{ init environment
|
||||
local wakka = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display()
|
||||
local lines = "<u>Pacman Updates:</u>\n"
|
||||
local f = io.popen("sudo emerge -uavDN world", "r")
|
||||
local s = f:read('*all')
|
||||
line = "Total:" s
|
||||
print(line)
|
||||
f:close()
|
||||
return line
|
||||
end
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
function wakka.addToWidget(mywidget)
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
|
||||
return wakka
|
|
@ -0,0 +1 @@
|
|||
*.swp
|
|
@ -0,0 +1,43 @@
|
|||
Perceptive, a weather notification module for awesome
|
||||
================================
|
||||
|
||||
Perceptive is a module for awesome wm for brief and compact
|
||||
weather notification via naughty lib and Yahoo! Weather API.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
- awesome 3.4 (awesome 3.5 is not supported yet)
|
||||
- /tmp directory (I'll store a temporary file over there.)
|
||||
- python 2.7
|
||||
|
||||
Usage
|
||||
-----
|
||||
Clone perceptive repository into your $XDG_CONFIG_HOME/awesome (awesome config dir).
|
||||
Then, add on top of rc.lua :
|
||||
|
||||
require("perceptive")
|
||||
|
||||
Bind perceptive notification to some widget:
|
||||
|
||||
perceptive.register(mytextclock, 2123260)
|
||||
|
||||
Where the second argument is so-called WOEID code of your city.
|
||||
To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link.
|
||||
It will look like http://weather.yahoo.com/united-states/california/san-diego-2487889/
|
||||
and the last number in that link will be the ID you need.
|
||||
|
||||
Screenshot
|
||||
-----
|
||||
![Screenshot][1]
|
||||
|
||||
[1]: http://github.com/ioga/perceptive/raw/master/screenshot.png
|
||||
|
||||
License
|
||||
-----
|
||||
Copyright (C) 2011-2013 Ilia Glazkov.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,83 @@
|
|||
-- Perceptive, a weather notification module for Awesome WM.
|
||||
--
|
||||
-- Author: Ilia Glazkov
|
||||
|
||||
local naughty = naughty
|
||||
local timer = timer
|
||||
local io = require("io")
|
||||
local debug = require("debug")
|
||||
local string = string
|
||||
local print = print
|
||||
|
||||
module('perceptive')
|
||||
|
||||
local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
|
||||
local script_path = project_path .. 'weather-fetcher.py'
|
||||
local script_cmd = script_path .. ' --id='
|
||||
local tmpfile = '/tmp/.awesome.weather'
|
||||
local weather_data = ""
|
||||
local notification = nil
|
||||
local pattern = '%a.+'
|
||||
local city_id = nil
|
||||
|
||||
|
||||
function execute(cmd, output, callback)
|
||||
-- Executes command line, writes its output to temporary file, and
|
||||
-- runs the callback with output as an argument.
|
||||
local cmdline = cmd .. " &> " .. output .. " & "
|
||||
io.popen(cmdline):close()
|
||||
|
||||
local execute_timer = timer({ timeout = 7 })
|
||||
execute_timer:add_signal("timeout", function()
|
||||
execute_timer:stop()
|
||||
local f = io.open(output)
|
||||
callback(f:read("*all"))
|
||||
f:close()
|
||||
end)
|
||||
execute_timer:start()
|
||||
end
|
||||
|
||||
|
||||
function fetch_weather()
|
||||
execute(script_cmd .. city_id, tmpfile, function(text)
|
||||
old_weather_data = weather_data
|
||||
weather_data = string.gsub(text, "[\n]$", "")
|
||||
if notification ~= nil and old_weather_data ~= weather_data then
|
||||
show_notification()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function remove_notification()
|
||||
if notification ~= nil then
|
||||
naughty.destroy(notification)
|
||||
notification = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function show_notification()
|
||||
remove_notification()
|
||||
notification = naughty.notify({
|
||||
text = weather_data,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
function register(widget, id)
|
||||
city_id = id
|
||||
update_timer = timer({ timeout = 600 })
|
||||
update_timer:add_signal("timeout", function()
|
||||
fetch_weather()
|
||||
end)
|
||||
update_timer:start()
|
||||
fetch_weather()
|
||||
|
||||
widget:add_signal("mouse::enter", function()
|
||||
show_notification()
|
||||
end)
|
||||
widget:add_signal("mouse::leave", function()
|
||||
remove_notification()
|
||||
end)
|
||||
end
|
After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,87 @@
|
|||
#!/usr/bin/env python2.7
|
||||
# coding=utf-8
|
||||
"""Fetch weather using Yandex XML API."""
|
||||
|
||||
__author__ = "Ilia Glazkov"
|
||||
|
||||
import argparse
|
||||
from urllib2 import urlopen
|
||||
from xml.etree.ElementTree import ElementTree
|
||||
|
||||
|
||||
WEATHER_API_PREFIX = "http://weather.yahooapis.com/forecastrss?u=f&w="
|
||||
URLOPEN_TIMEOUT = 5
|
||||
|
||||
CELSIUS = '°F'
|
||||
DASH = "—"
|
||||
|
||||
CURRENT_DAY = 'Now'
|
||||
|
||||
|
||||
def weather_url_by_id(id):
|
||||
return WEATHER_API_PREFIX + str(id)
|
||||
|
||||
|
||||
def fetch_weather_tree(id):
|
||||
return ElementTree().parse(
|
||||
urlopen(weather_url_by_id(id), timeout=URLOPEN_TIMEOUT))
|
||||
|
||||
|
||||
def format_date_string(day, text, temp, max_temp=None):
|
||||
day = day or 'Now'
|
||||
|
||||
if max_temp:
|
||||
temp_string = DASH.join((str(temp), str(max_temp)))
|
||||
else:
|
||||
temp_string = str(temp)
|
||||
|
||||
return '%s: %s, %s%s.' % (day, text, temp_string, CELSIUS)
|
||||
|
||||
|
||||
class WeatherElement(object):
|
||||
def __init__(self, element):
|
||||
self.element = element
|
||||
|
||||
@property
|
||||
def day(self):
|
||||
return self.element.get('day') or CURRENT_DAY
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return self.element.get('text')
|
||||
|
||||
@property
|
||||
def temp(self):
|
||||
temp = self.element.get('temp')
|
||||
if temp is not None:
|
||||
return str(temp)
|
||||
|
||||
low, high = self.element.get('low'), self.element.get('high')
|
||||
if low is not None and high is not None:
|
||||
return DASH.join((str(low), str(high)))
|
||||
|
||||
def get_format_string(self):
|
||||
return '%s: %s, %s%s.' % (self.day, self.text, self.temp, CELSIUS)
|
||||
|
||||
|
||||
def get_weather_string(tree):
|
||||
condition = next(el for el in tree.iter()
|
||||
if el.tag.endswith('condition'))
|
||||
forecast = [el for el in tree.iter()
|
||||
if el.tag.endswith('forecast')]
|
||||
forecast.insert(0, condition)
|
||||
|
||||
return '\n'.join((
|
||||
WeatherElement(element).get_format_string()
|
||||
for element in forecast))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--id', type=int, required=True,
|
||||
help='Yahoo WEOID of the city')
|
||||
args = parser.parse_args()
|
||||
print get_weather_string(fetch_weather_tree(args.id))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,601 @@
|
|||
----< Includes >------------------------------------------------------
|
||||
--
|
||||
-- Standard awesome library
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
awful.rules = require("awful.rules")
|
||||
require("awful.autofocus")
|
||||
-- Widget and layout library
|
||||
local wibox = require("wibox")
|
||||
-- Autostart
|
||||
require("autostart")
|
||||
|
||||
----< Theme >---------------------------------------------------------
|
||||
--
|
||||
-- Theme handling library
|
||||
local beautiful = require("beautiful")
|
||||
beautiful.init(os.getenv("HOME").."/.config/awesome/themes/default/theme.lua")
|
||||
-- Notification library
|
||||
local naughty = require("naughty")
|
||||
local menubar = require("menubar")
|
||||
--FreeDesktop
|
||||
require('freedesktop.utils')
|
||||
require('freedesktop.menu')
|
||||
freedesktop.utils.icon_theme = 'gnome'
|
||||
--Vicious + Widgets
|
||||
vicious = require("vicious")
|
||||
local wi = require("wi")
|
||||
local html = require("html")
|
||||
|
||||
----< 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
|
||||
local in_error = false
|
||||
awesome.connect_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
|
||||
|
||||
----< Variables >-----------------------------------------------------
|
||||
--
|
||||
-- This is used later as the default terminal and editor to run.
|
||||
terminal = "urxvt -tr +sb"
|
||||
editor = os.getenv("EDITOR") or "vim"
|
||||
editor_cmd = terminal .. " -e " .. editor
|
||||
modkey = "Mod1"
|
||||
|
||||
----< Table of layouts >----------------------------------------------
|
||||
--
|
||||
-- Table of layouts to cover with awful.layout.inc, order matters.
|
||||
layouts =
|
||||
{
|
||||
awful.layout.suit.max,
|
||||
awful.layout.suit.fair,
|
||||
awful.layout.suit.fair.horizontal,
|
||||
awful.layout.suit.tile,
|
||||
awful.layout.suit.tile.left,
|
||||
awful.layout.suit.tile.bottom,
|
||||
awful.layout.suit.tile.top,
|
||||
awful.layout.suit.floating,
|
||||
awful.layout.suit.max.fullscreen,
|
||||
-- awful.layout.suit.spiral,
|
||||
-- awful.layout.suit.spiral.dwindle,
|
||||
-- awful.layout.suit.magnifier
|
||||
}
|
||||
|
||||
----< Naughty presets >-----------------------------------------------
|
||||
--
|
||||
naughty.config.defaults.timeout = 5
|
||||
naughty.config.defaults.screen = 1
|
||||
naughty.config.defaults.position = "top_right"
|
||||
naughty.config.defaults.margin = 8
|
||||
naughty.config.defaults.gap = 1
|
||||
naughty.config.defaults.ontop = true
|
||||
naughty.config.defaults.font = "terminus 9"
|
||||
naughty.config.defaults.icon = nil
|
||||
naughty.config.defaults.icon_size = 256
|
||||
naughty.config.defaults.fg = beautiful.fg_tooltip
|
||||
naughty.config.defaults.bg = beautiful.bg_tooltip
|
||||
naughty.config.defaults.border_color = beautiful.border_tooltip
|
||||
naughty.config.defaults.border_width = 2
|
||||
naughty.config.defaults.hover_timeout = nil
|
||||
|
||||
----< Tags >----------------------------------------------------------
|
||||
--
|
||||
tags = {
|
||||
names = { "term", "web", "vm", "office", "note",
|
||||
"game", "gimp", "dict", "im" },
|
||||
layout = { layouts[3], layouts[1], layouts[1], layouts[1], layouts[1],
|
||||
layouts[1], layouts[1], layouts[1], layouts[2]}
|
||||
}
|
||||
for s = 1, screen.count() do
|
||||
-- Each screen has its own tag table.
|
||||
tags[s] = awful.tag(tags.names, s, tags.layout)
|
||||
end
|
||||
|
||||
----< Wallpaper >-----------------------------------------------------
|
||||
--
|
||||
local wallpaper = require("wallpaper")
|
||||
|
||||
--
|
||||
--if beautiful.wallpaper then
|
||||
-- for s = 1, screen.count() do
|
||||
-- gears.wallpaper.maximized(beautiful.wallpaper, s, true)
|
||||
-- end
|
||||
--end
|
||||
|
||||
---- Wallpaper Changer Based On
|
||||
---- menu icon menu pdq 07-02-2012
|
||||
-- local wallmenu = {}
|
||||
-- local function wall_load(wall)
|
||||
-- local f = io.popen('ln -sfn ' .. home_path .. '.config/awesome/wallpaper/' .. wall .. ' ' .. home_path .. '.config/awesome/themes/default/bg.png')
|
||||
-- awesome.restart()
|
||||
-- end
|
||||
-- local function wall_menu()
|
||||
-- local f = io.popen('ls -1 ' .. home_path .. '.config/awesome/wallpaper/')
|
||||
-- for l in f:lines() do
|
||||
--local item = { l, function () wall_load(l) end }
|
||||
-- table.insert(wallmenu, item)
|
||||
-- end
|
||||
-- f:close()
|
||||
-- end
|
||||
-- wall_menu()
|
||||
|
||||
----< Menu >----------------------------------------------------------
|
||||
--
|
||||
menu_items = freedesktop.menu.new()
|
||||
myawesomemenu = {
|
||||
{ "next wall", os.getenv("HOME").."/.config/awesome/set_wall.sh "..os.getenv("HOME").."/wallpapers/" },
|
||||
{ "hibernate", "gksudo hibernate" },
|
||||
{ "lock", "xscreensaver-command --lock" },
|
||||
{ "reboot", "gksudo reboot" },
|
||||
{ "manual", terminal .. " -e man awesome", freedesktop.utils.lookup_icon({ icon = 'help' }) },
|
||||
{ "edit config", editor_cmd .. " " .. awesome.conffile, freedesktop.utils.lookup_icon({ icon = 'package_settings' }) },
|
||||
{ "restart", awesome.restart, freedesktop.utils.lookup_icon({ icon = 'system-shutdown' }) },
|
||||
{ "quit", awesome.quit, freedesktop.utils.lookup_icon({ icon = 'system-shutdown' }) }
|
||||
}
|
||||
table.insert(menu_items, { "Awesome", myawesomemenu, beautiful.awesome_icon })
|
||||
mymainmenu = awful.menu({ items = menu_items, width = 150 })
|
||||
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
|
||||
menu = mymainmenu })
|
||||
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
|
||||
|
||||
----< Widgets >-------------------------------------------------------
|
||||
--
|
||||
spacer = wibox.widget.textbox()
|
||||
spacer:set_text(' ')
|
||||
|
||||
--spacer2 = wibox.widget.textbox()
|
||||
--spacer2:set_text(' ')
|
||||
|
||||
--Battery Widget
|
||||
--batt = wibox.widget.textbox()
|
||||
--vicious.register(batt, vicious.widgets.bat, "$2% $3 ", 61, "BAT0")
|
||||
|
||||
|
||||
-- {{{ Wibox
|
||||
-- Create a textclock widget
|
||||
mytextclock = awful.widget.textclock()
|
||||
|
||||
-- Create a wibox for each screen and add it
|
||||
mywibox = {}
|
||||
myinfowibox = {}
|
||||
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, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end),
|
||||
awful.button({ }, 5, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end)
|
||||
)
|
||||
mytasklist = {}
|
||||
mytasklist.buttons = awful.util.table.join(
|
||||
awful.button({ }, 1, function (c)
|
||||
if c == client.focus then
|
||||
c.minimized = true
|
||||
else
|
||||
-- Without this, the following
|
||||
-- :isvisible() makes no sense
|
||||
c.minimized = false
|
||||
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),
|
||||
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))
|
||||
|
||||
-- Wi-Fi / Ethernet widgets
|
||||
wifi_widget_down = wibox.widget.textbox()
|
||||
wifi_widget_up = wibox.widget.textbox()
|
||||
icon_wifi = wibox.widget.imagebox()
|
||||
icon_wifi_down_up = wibox.widget.imagebox()
|
||||
icon_wifi:set_image (beautiful.widget_wifi)
|
||||
icon_wifi_down_up:set_image (beautiful.widget_wifi_down_up)
|
||||
wired_widget_down = wibox.widget.textbox()
|
||||
wired_widget_up = wibox.widget.textbox()
|
||||
icon_wired = wibox.widget.imagebox()
|
||||
icon_wired_down_up = wibox.widget.imagebox()
|
||||
icon_wired:set_image (beautiful.widget_wired)
|
||||
icon_wired_down_up:set_image (beautiful.widget_wired_down_up)
|
||||
|
||||
vicious.cache(vicious.widgets.net)
|
||||
vicious.register(wifi_widget_down, vicious.widgets.net, '<span color="#7F9F7F">${wlan0 down_mb}</span>', 2)
|
||||
vicious.register(wifi_widget_up, vicious.widgets.net, '<span color="#CC9393">${wlan0 up_mb}</span>', 2)
|
||||
vicious.register(wired_widget_down, vicious.widgets.net, '<span color="#7F9F7F">${eth0 down_mb}</span>', 2)
|
||||
vicious.register(wired_widget_up, vicious.widgets.net, '<span color="#CC9393">${eth0 up_mb}</span>', 2)
|
||||
|
||||
for s = 1, screen.count() do
|
||||
-- Create a promptbox for each screen
|
||||
mypromptbox[s] = awful.widget.prompt()
|
||||
-- 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.filter.all, mytaglist.buttons)
|
||||
|
||||
-- Create a tasklist widget
|
||||
mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons)
|
||||
|
||||
-- Create the wibox
|
||||
mywibox[s] = awful.wibox({ position = "top", screen = s , height = 15.5})
|
||||
|
||||
-- Widgets that are aligned to the left
|
||||
local left_layout = wibox.layout.fixed.horizontal()
|
||||
left_layout:add(mylauncher)
|
||||
left_layout:add(mytaglist[s])
|
||||
left_layout:add(mypromptbox[s])
|
||||
|
||||
-- Widgets that are aligned to the right
|
||||
local right_layout = wibox.layout.fixed.horizontal()
|
||||
if s == 1 then right_layout:add(wibox.widget.systray()) end
|
||||
right_layout:add(spacer)
|
||||
right_layout:add(cpuicon)
|
||||
right_layout:add(cpu)
|
||||
--right_layout:add(spacer)
|
||||
right_layout:add(memicon)
|
||||
right_layout:add(mem)
|
||||
--right_layout:add(spacer)
|
||||
--right_layout:add(weatheric)
|
||||
--right_layout:add(weather)
|
||||
--right_layout:add(spacer)
|
||||
--right_layout:add(mailicon)
|
||||
--right_layout:add(mailwidget)
|
||||
--right_layout:add(spacer)
|
||||
right_layout:add(baticon)
|
||||
right_layout:add(batpct)
|
||||
--right_layout:add(netwidgeticon)
|
||||
--right_layout:add(netwidget)
|
||||
--right_layout:add(wifiicon)
|
||||
--right_layout:add(wifi)
|
||||
--right_layout:add(spacer2)
|
||||
--right_layout:add(spacer)
|
||||
--right_layout:add(pacicon)
|
||||
--right_layout:add(pacwidget)
|
||||
--right_layout:add(spacer)
|
||||
--right_layout:add(spacer)
|
||||
--right_layout:add(spacer)
|
||||
right_layout:add(icon_wifi)
|
||||
right_layout:add(wifi_widget_down)
|
||||
right_layout:add(icon_wifi_down_up)
|
||||
right_layout:add(wifi_widget_up)
|
||||
right_layout:add(spacer)
|
||||
right_layout:add(icon_wired)
|
||||
right_layout:add(wired_widget_down)
|
||||
right_layout:add(icon_wired_down_up)
|
||||
right_layout:add(wired_widget_up)
|
||||
right_layout:add(spacer)
|
||||
right_layout:add(volicon)
|
||||
--right_layout:add(volumecfg.widget)
|
||||
right_layout:add(volpct)
|
||||
--right_layout:add(volspace)
|
||||
--right_layout:add(spacer)
|
||||
--right_layout:add(spacer)
|
||||
right_layout:add(mytextclock)
|
||||
right_layout:add(mylayoutbox[s])
|
||||
|
||||
-- Now bring it all together (with the tasklist in the middle)
|
||||
local layout = wibox.layout.align.horizontal()
|
||||
layout:set_left(left_layout)
|
||||
layout:set_middle(mytasklist[s])
|
||||
layout:set_right(right_layout)
|
||||
|
||||
mywibox[s]:set_widget(layout)
|
||||
|
||||
-- Create the bottom wibox
|
||||
--myinfowibox[s] = awful.wibox({ position = "bottom", screen = s })
|
||||
-- Widgets that are aligned to the bottom
|
||||
--local bottom_layout = wibox.layout.fixed.horizontal()
|
||||
-- bottom_layout:add(diskwidget)
|
||||
--bottom_layout:add(spacer)
|
||||
--bottom_layout:add(netwidgeticon)
|
||||
--bottom_layout:add(netwidget)
|
||||
--bottom_layout:add(spacer)
|
||||
--bottom_layout:add(wifiicon)
|
||||
--bottom_layout:add(wifi)
|
||||
|
||||
-- Now bring it all together
|
||||
--local layout = wibox.layout.align.horizontal()
|
||||
--layout:set_bottom(bottom_layout)
|
||||
|
||||
--myinfowibox[s]:set_widget(bottom_layout)
|
||||
|
||||
end
|
||||
-- }}}
|
||||
|
||||
----< 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 bindings >--------------------------------------------------
|
||||
--
|
||||
globalkeys = awful.util.table.join(
|
||||
-- Volume control --
|
||||
awful.key({ modkey }, ".", function ()
|
||||
awful.util.spawn("amixer set Master 9%+") end),
|
||||
awful.key({ modkey }, ",", function ()
|
||||
awful.util.spawn("amixer set Master 9%-") end),
|
||||
awful.key({ modkey }, "/", function ()
|
||||
awful.util.spawn("amixer sset Master toggle") end),
|
||||
|
||||
-- Volume control --
|
||||
awful.key({ }, "XF86AudioRaiseVolume", function ()
|
||||
awful.util.spawn("amixer set Master 9%+") end),
|
||||
awful.key({ }, "XF86AudioLowerVolume", function ()
|
||||
awful.util.spawn("amixer set Master 9%-") end),
|
||||
awful.key({ }, "XF86AudioMute", function ()
|
||||
awful.util.spawn("amixer sset Master toggle") end),
|
||||
|
||||
awful.key({ modkey, }, "[", awful.tag.viewprev ),
|
||||
awful.key({ modkey, }, "]", awful.tag.viewnext ),
|
||||
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
|
||||
|
||||
awful.key({ modkey, }, "k",
|
||||
function ()
|
||||
awful.client.focus.byidx( 1)
|
||||
if client.focus then client.focus:raise() end
|
||||
end),
|
||||
awful.key({ modkey, }, "j",
|
||||
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" }, "k", function () awful.client.swap.byidx( 1) end),
|
||||
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( -1) end),
|
||||
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative( 1) end),
|
||||
awful.key({ modkey, "Control" }, "j", 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, "Control" }, "l", function () os.execute ("xscreensaver-command --lock") end),
|
||||
|
||||
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),
|
||||
|
||||
awful.key({ modkey, "Control" }, "n", awful.client.restore),
|
||||
|
||||
-- Prompt
|
||||
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),
|
||||
awful.key({ modkey }, "l",function () awful.util.spawn( "mpc play" ) end),
|
||||
awful.key({ modkey }, ";",function () awful.util.spawn( "mpc pause" ) end),
|
||||
awful.key({ modkey }, "'",function () awful.util.spawn( "mpc prev" ) end),
|
||||
awful.key({ modkey }, "\\",function () awful.util.spawn( "mpc next" ) end)
|
||||
)
|
||||
|
||||
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)
|
||||
-- The client currently has the input focus, so it cannot be
|
||||
-- minimized, since minimized clients can't have the focus.
|
||||
c.minimized = true
|
||||
end),
|
||||
awful.key({ modkey, }, "m",
|
||||
function (c)
|
||||
c.maximized_horizontal = not c.maximized_horizontal
|
||||
c.maximized_vertical = not c.maximized_vertical
|
||||
end)
|
||||
)
|
||||
|
||||
-- Compute the maximum number of digit we need, limited to 9
|
||||
keynumber = 0
|
||||
for s = 1, screen.count() do
|
||||
keynumber = math.min(9, math.max(#tags[s], keynumber));
|
||||
end
|
||||
|
||||
-- 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, keynumber do
|
||||
globalkeys = awful.util.table.join(globalkeys,
|
||||
awful.key({ modkey }, "#" .. i + 9,
|
||||
function ()
|
||||
local screen = mouse.screen
|
||||
if tags[screen][i] then
|
||||
awful.tag.viewonly(tags[screen][i])
|
||||
end
|
||||
end),
|
||||
awful.key({ modkey, "Control" }, "#" .. i + 9,
|
||||
function ()
|
||||
local screen = mouse.screen
|
||||
if tags[screen][i] then
|
||||
awful.tag.viewtoggle(tags[screen][i])
|
||||
end
|
||||
end),
|
||||
awful.key({ modkey, "Shift" }, "#" .. i + 9,
|
||||
function ()
|
||||
if client.focus and tags[client.focus.screen][i] then
|
||||
awful.client.movetotag(tags[client.focus.screen][i])
|
||||
end
|
||||
end),
|
||||
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
|
||||
function ()
|
||||
if client.focus and tags[client.focus.screen][i] then
|
||||
awful.client.toggletag(tags[client.focus.screen][i])
|
||||
end
|
||||
end))
|
||||
end
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
-- Set keys
|
||||
root.keys(globalkeys)
|
||||
|
||||
----< Application rules >---------------------------------------------
|
||||
--
|
||||
awful.rules.rules = {
|
||||
-- All clients will match this rule.
|
||||
{ rule = { },
|
||||
properties = { border_width = beautiful.border_width,
|
||||
border_color = beautiful.border_normal,
|
||||
focus = true,
|
||||
keys = clientkeys,
|
||||
buttons = clientbuttons } },
|
||||
{ rule = { class = "URxvt" },
|
||||
properties = { tag = tags[1][1] } },
|
||||
{ rule = { class = "Firefox" },
|
||||
properties = { tag = tags[1][2] } },
|
||||
{ rule = { class = "VirtualBox" },
|
||||
properties = { tag = tags[1][3] } },
|
||||
{ rule = { class = "Remmina" },
|
||||
properties = { tag = tags[1][3] } },
|
||||
{ rule = { class = "Spicy" },
|
||||
properties = { tag = tags[1][3] } },
|
||||
{ rule = { class = "Aqemu" },
|
||||
properties = { tag = tags[1][3] } },
|
||||
{ rule = { class = "Soffice" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-writer" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-calc" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-draw" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-base" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-math" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-impress" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "libreoffice-startcenter" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "Okular" },
|
||||
properties = { floating = false, tag = tags[1][4] } },
|
||||
{ rule = { class = "Lyx" },
|
||||
properties = { tag = tags[1][4] } },
|
||||
{ rule = { class = "Evince" },
|
||||
properties = { tag = tags[1][4] } },
|
||||
{ rule = { class = "Qt Jambi application" },
|
||||
properties = { tag = tags[1][5] } },
|
||||
{ rule = { class = "Pidgin" },
|
||||
properties = { tag = tags[1][9] } },
|
||||
{ rule = { class = "Stardict" },
|
||||
properties = { tag = tags[1][8] } },
|
||||
{ rule = { class = "MPlayer" },
|
||||
properties = { floating = true } },
|
||||
{ rule = { class = "Texreport-gtk" },
|
||||
properties = { floating = true } },
|
||||
{ rule = { class = "etracer" },
|
||||
properties = { tag = tags[1][6] } },
|
||||
{ rule = { class = "Eboard" },
|
||||
properties = { tag = tags[1][6] } },
|
||||
{ rule = { class = "charleygame-bin" },
|
||||
properties = { tag = tags[1][6] } },
|
||||
{ rule = { class = "lincity-ng" },
|
||||
properties = { tag = tags[1][6] } },
|
||||
-- XTerm на пятом и шестом теге первого экрана
|
||||
-- { rule = { class = "XTerm" }, callback = function(c) c:tags({tags[1][4], tags[1][6]}) end},
|
||||
}
|
||||
|
||||
----< Signals >------------------------------------------------------
|
||||
-- Signal function to execute when a new client appears.
|
||||
client.add_signal("manage", function (c, startup)
|
||||
-- Add a titlebar
|
||||
-- awful.titlebar.add(c, { modkey = modkey })
|
||||
|
||||
-- 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
|
||||
-- Set the windows at the slave,
|
||||
-- i.e. put it at the end of others instead of setting it master.
|
||||
-- awful.client.setslave(c)
|
||||
|
||||
-- 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)
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
feh --bg-scale "$(find $1 | shuf -n1)"
|
|
@ -0,0 +1,33 @@
|
|||
-- {{{ init environment
|
||||
local wakka = {}
|
||||
local capi = {
|
||||
mouse = mouse,
|
||||
screen = screen
|
||||
}
|
||||
|
||||
-- {{{ display
|
||||
-- formats the lines for the notify
|
||||
local function display()
|
||||
local lines = "<u>AUR Updates:</u>\n"
|
||||
local f = io.popen("archey", "r")
|
||||
local s = f:read('*all')
|
||||
line = lines .. "\n" .. s .. "\n"
|
||||
f:close()
|
||||
return line
|
||||
end
|
||||
-- }}}
|
||||
-- }}}
|
||||
|
||||
function wakka.addToWidget(mywidget)
|
||||
mywidget:add_signal('mouse::enter', function ()
|
||||
usage = naughty.notify({
|
||||
text = string.format('<span font_desc="%s">%s</span>', "monospace", display()),
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
screen = capi.mouse.screen
|
||||
})
|
||||
end)
|
||||
mywidget:add_signal('mouse::leave', function () naughty.destroy(usage) end)
|
||||
end
|
||||
|
||||
return wakka
|
|
@ -0,0 +1,3 @@
|
|||
Background images:
|
||||
Mikael Eriksson <mikael_eriksson@miffe.org>
|
||||
Licensed under CC-BY-SA-3.0
|
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 997 B |
After Width: | Height: | Size: 194 B |
After Width: | Height: | Size: 194 B |
After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 395 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 195 B |
After Width: | Height: | Size: 216 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 170 B |
After Width: | Height: | Size: 195 B |
After Width: | Height: | Size: 215 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 198 B |
After Width: | Height: | Size: 187 B |
After Width: | Height: | Size: 278 B |
After Width: | Height: | Size: 193 B |
After Width: | Height: | Size: 345 B |
After Width: | Height: | Size: 334 B |
|
@ -0,0 +1,149 @@
|
|||
---------------------------
|
||||
-- Default SETKEH theme --
|
||||
---------------------------
|
||||
|
||||
local awful = require("awful")
|
||||
|
||||
--Configure home path so you dont have too
|
||||
home_path = os.getenv('HOME') .. '/'
|
||||
|
||||
theme = {}
|
||||
theme.wallpaper = awful.util.getdir("config") .. "/themes/default/bg.png"
|
||||
--theme.font = "sans 8"
|
||||
theme.font = "terminus 8"
|
||||
|
||||
theme.bg_normal = "#222222"
|
||||
theme.bg_focus = "#535d6c"
|
||||
theme.bg_urgent = "#ff0000"
|
||||
theme.bg_minimize = "#444444"
|
||||
theme.bg_tooltip = "#d6d6d6"
|
||||
theme.bg_em = "#5a5a5a"
|
||||
theme.bg_systray = theme.bg_normal
|
||||
|
||||
theme.fg_normal = "#aaaaaa"
|
||||
theme.fg_focus = "#ffffff"
|
||||
theme.fg_urgent = "#ffffff"
|
||||
theme.fg_minimize = "#ffffff"
|
||||
theme.fg_tooltip = "#1a1a1a"
|
||||
theme.fg_em = "#d6d6d6"
|
||||
|
||||
theme.border_width = "1"
|
||||
theme.border_normal = "#000000"
|
||||
theme.border_focus = "#535d6c"
|
||||
theme.border_marked = "#91231c"
|
||||
theme.fg_widget_value = "#aaaaaa"
|
||||
theme.fg_widget_clock = "#aaaaaa"
|
||||
theme.fg_widget_value_important = "#aaaaaa"
|
||||
theme.fg_widget = "#908884"
|
||||
theme.fg_center_widget = "#636363"
|
||||
theme.fg_end_widget = "#1a1a1a"
|
||||
theme.bg_widget = "#2a2a2a"
|
||||
theme.border_widget = "#3F3F3F"
|
||||
|
||||
-- There are other variable sets
|
||||
-- overriding the default one when
|
||||
-- defined, the sets are:
|
||||
-- [taglist|tasklist]_[bg|fg]_[focus|urgent]
|
||||
-- titlebar_[bg|fg]_[normal|focus]
|
||||
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
|
||||
-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
|
||||
-- Example:
|
||||
--theme.taglist_bg_focus = "#ff0000"
|
||||
|
||||
-- Display the taglist squares
|
||||
theme.taglist_squares_sel = home_path .. '.config/awesome/themes/default/taglist/squarefw.png'
|
||||
theme.taglist_squares_unsel = home_path .. '.config/awesome/themes/default/taglist/squarew.png'
|
||||
|
||||
theme.tasklist_floating_icon = home_path .. '.config/awesome/themes/default/tasklist/floatingw.png'
|
||||
|
||||
-- Variables set for theming the menu:
|
||||
-- menu_[bg|fg]_[normal|focus]
|
||||
-- menu_[border_color|border_width]
|
||||
theme.menu_submenu_icon = home_path .. '.config/awesome/themes/default/submenu.png'
|
||||
theme.menu_height = "15"
|
||||
theme.menu_width = "100"
|
||||
|
||||
-- You can add as many variables as
|
||||
-- you wish and access them by using
|
||||
-- beautiful.variable in your rc.lua
|
||||
--theme.bg_widget = "#cc0000"
|
||||
|
||||
-- Define the image to load
|
||||
theme.titlebar_close_button_normal = home_path .. '.config/awesome/themes/default/titlebar/close_normal.png'
|
||||
theme.titlebar_close_button_focus = home_path .. '.config/awesome/themes/default/titlebar/close_focus.png'
|
||||
|
||||
theme.titlebar_ontop_button_normal_inactive = home_path .. '.config/awesome/themes/default/titlebar/ontop_normal_inactive.png'
|
||||
theme.titlebar_ontop_button_focus_inactive = home_path .. '.config/awesome/themes/default/titlebar/ontop_focus_inactive.png'
|
||||
theme.titlebar_ontop_button_normal_active = home_path .. '/home/setkeh/.config/awesome/themes/default/titlebar/ontop_normal_active.png'
|
||||
theme.titlebar_ontop_button_focus_active = home_path .. '.config/awesome/themes/default/titlebar/ontop_focus_active.png'
|
||||
|
||||
theme.titlebar_sticky_button_normal_inactive = home_path .. '.config/awesome/themes/default/titlebar/sticky_normal_inactive.png'
|
||||
theme.titlebar_sticky_button_focus_inactive = home_path .. '.config/awesome/themes/default/titlebar/sticky_focus_inactive.png'
|
||||
theme.titlebar_sticky_button_normal_active = home_path .. '.config/awesome/themes/default/titlebar/sticky_normal_active.png'
|
||||
theme.titlebar_sticky_button_focus_active = home_path .. '.config/awesome/themes/default/titlebar/sticky_focus_active.png'
|
||||
|
||||
theme.titlebar_floating_button_normal_inactive = home_path .. '.config/awesome/themes/default/titlebar/floating_normal_inactive.png'
|
||||
theme.titlebar_floating_button_focus_inactive = home_path .. '.config/awesome/themes/default/titlebar/floating_focus_inactive.png'
|
||||
theme.titlebar_floating_button_normal_active = home_path .. '.config/awesome/themes/default/titlebar/floating_normal_active.png'
|
||||
theme.titlebar_floating_button_focus_active = home_path .. '.config/awesome/themes/default/titlebar/floating_focus_active.png'
|
||||
|
||||
theme.titlebar_maximized_button_normal_inactive = home_path .. '.config/awesome/themes/default/titlebar/maximized_normal_inactive.png'
|
||||
theme.titlebar_maximized_button_focus_inactive = home_path .. '.config/awesome/themes/default/titlebar/maximized_focus_inactive.png'
|
||||
theme.titlebar_maximized_button_normal_active = home_path .. '.config/awesome/themes/default/titlebar/maximized_normal_active.png'
|
||||
theme.titlebar_maximized_button_focus_active = home_path .. '.config/awesome/themes/default/titlebar/maximized_focus_active.png'
|
||||
|
||||
-- You can use your own layout icons like this:
|
||||
theme.layout_fairh = home_path .. '.config/awesome/themes/default/layouts/fairhw.png'
|
||||
theme.layout_fairv = home_path .. '.config/awesome/themes/default/layouts/fairvw.png'
|
||||
theme.layout_floating = home_path .. '.config/awesome/themes/default/layouts/floatingw.png'
|
||||
theme.layout_magnifier = home_path .. '.config/awesome/themes/default/layouts/magnifierw.png'
|
||||
theme.layout_max = home_path .. '.config/awesome/themes/default/layouts/maxw.png'
|
||||
theme.layout_fullscreen = home_path .. '.config/awesome/themes/default/layouts/fullscreenw.png'
|
||||
theme.layout_tilebottom = home_path .. '.config/awesome/themes/default/layouts/tilebottomw.png'
|
||||
theme.layout_tileleft = home_path .. '.config/awesome/themes/default/layouts/tileleftw.png'
|
||||
theme.layout_tile = home_path .. '.config/awesome/themes/default/layouts/tilew.png'
|
||||
theme.layout_tiletop = home_path .. '.config/awesome/themes/default/layouts/tiletopw.png'
|
||||
theme.layout_spiral = home_path .. '.config/awesome/themes/default/layouts/spiralw.png'
|
||||
theme.layout_dwindle = home_path .. '.config/awesome/themes/default/layouts/dwindlew.png'
|
||||
|
||||
theme.awesome_icon = home_path .. '.config/awesome/themes/default/icon/awesome16.png'
|
||||
theme.arch_icon = home_path .. '.config/awesome/themes/default/icon/Arch.png'
|
||||
|
||||
-- {{{ Widgets
|
||||
theme.widget_disk = awful.util.getdir("config") .. "/themes/default/widgets/disk.png"
|
||||
theme.widget_cpu = awful.util.getdir("config") .. "/themes/default/widgets/cpu.png"
|
||||
theme.widget_ac = awful.util.getdir("config") .. "/themes/default/widgets/ac.png"
|
||||
theme.widget_acblink = awful.util.getdir("config") .. "/themes/default/widgets/acblink.png"
|
||||
theme.widget_blank = awful.util.getdir("config") .. "/themes/default/widgets/blank.png"
|
||||
theme.widget_batfull = awful.util.getdir("config") .. "/themes/default/widgets/batfull.png"
|
||||
theme.widget_batmed = awful.util.getdir("config") .. "/themes/default/widgets/batmed.png"
|
||||
theme.widget_batlow = awful.util.getdir("config") .. "/themes/default/widgets/batlow.png"
|
||||
theme.widget_batempty = awful.util.getdir("config") .. "/themes/default/widgets/batempty.png"
|
||||
theme.widget_vol = awful.util.getdir("config") .. "/themes/default/widgets/vol.png"
|
||||
theme.widget_mute = awful.util.getdir("config") .. "/themes/default/widgets/mute.png"
|
||||
theme.widget_pac = awful.util.getdir("config") .. "/themes/default/widgets/pac.png"
|
||||
theme.widget_pacnew = awful.util.getdir("config") .. "/themes/default/widgets/pacnew.png"
|
||||
theme.widget_mail = awful.util.getdir("config") .. "/themes/default/widgets/mail.png"
|
||||
theme.widget_mailnew = awful.util.getdir("config") .. "/themes/default/widgets/mailnew.png"
|
||||
theme.widget_temp = awful.util.getdir("config") .. "/themes/default/widgets/temp.png"
|
||||
theme.widget_tempwarn = awful.util.getdir("config") .. "/themes/default/widgets/tempwarm.png"
|
||||
theme.widget_temphot = awful.util.getdir("config") .. "/themes/default/widgets/temphot.png"
|
||||
theme.widget_wifi = awful.util.getdir("config") .. "/themes/default/widgets/wifi.png"
|
||||
theme.widget_nowifi = awful.util.getdir("config") .. "/themes/default/widgets/nowifi.png"
|
||||
theme.widget_wired = "/home/kolan/.config/awesome/Icons/16x16/net-wired.png"
|
||||
theme.widget_wired_down_up = "/home/kolan/.config/awesome/Icons/16x16/down_up.png"
|
||||
theme.widget_wifi_down_up = "~/.config/awesome/Icons/16x16/down_up.png"
|
||||
theme.widget_mpd = awful.util.getdir("config") .. "/themes/default/widgets/mpd.png"
|
||||
theme.widget_play = awful.util.getdir("config") .. "/themes/default/widgets/play.png"
|
||||
theme.widget_pause = awful.util.getdir("config") .. "/themes/default/widgets/pause.png"
|
||||
theme.widget_ram = awful.util.getdir("config") .. "/themes/default/widgets/ram.png"
|
||||
theme.widget_mem = awful.util.getdir("config") .. "/themes/default/tp/ram.png"
|
||||
theme.widget_swap = awful.util.getdir("config") .. "/themes/default/tp/swap.png"
|
||||
theme.widget_fs = awful.util.getdir("config") .. "/themes/default/tp/fs_01.png"
|
||||
theme.widget_fs2 = awful.util.getdir("config") .. "/themes/default/tp/fs_02.png"
|
||||
theme.widget_up = awful.util.getdir("config") .. "/themes/default/tp/up.png"
|
||||
theme.widget_down = awful.util.getdir("config") .. "/themes/default/tp/down.png"
|
||||
-- }}}
|
||||
|
||||
return theme
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 598 B |
After Width: | Height: | Size: 623 B |
After Width: | Height: | Size: 876 B |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 1013 B |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 816 B |
After Width: | Height: | Size: 774 B |
After Width: | Height: | Size: 758 B |
After Width: | Height: | Size: 1.3 KiB |