Clean the config code.

This commit is contained in:
Kolan Sh 2014-08-15 22:15:51 +04:00
parent 1bdc6f55fc
commit 3b1ebf63c1
15 changed files with 0 additions and 2315 deletions

View File

@ -1,19 +0,0 @@
## 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

View File

@ -1,67 +0,0 @@
-- 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

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

View File

@ -1,524 +0,0 @@
---------------------------------------------------------------------------
-- @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&param2=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

View File

@ -1,407 +0,0 @@
-- 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)
-- }}}

View File

@ -1,158 +0,0 @@
-- 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