commit 7956b900d981ecd14507e5ca0ba0f0215cc14428 parent 3aae75af93510d96ac16ef590694800f8538b982 Author: dudley <pyratebeard@gmail.com> Date: Sat, 13 Aug 2016 01:22:09 +0100 initial commit Diffstat:
571 files changed, 33092 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md @@ -1 +1,174 @@ -# dotfiles -\ No newline at end of file +``` + ██ ██ ████ ██ ██ + ░██ ░██ ░██░ â–‘â–‘ ░██ + ░██ ██████ ██████ ██████ ██ ░██ █████ ██████ + ██████ ██░░░░██░░░██░ ░░░██░ ░██ ░██ ██░░░██ ██░░░░ + ██░░░██░██ ░██ ░██ ░██ ░██ ░██░███████░░█████ +░██ ░██░██ ░██ ░██ ░██ ░██ ░██░██░░░░ ░░░░░██ +░░██████░░██████ ░░██ ░██ ░██ ███░░██████ ██████ + â–‘â–‘â–‘â–‘â–‘â–‘ â–‘â–‘â–‘â–‘â–‘â–‘ â–‘â–‘ â–‘â–‘ â–‘â–‘ â–‘â–‘â–‘ â–‘â–‘â–‘â–‘â–‘â–‘ â–‘â–‘â–‘â–‘â–‘â–‘ + + â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“ + â–‘â–“ about â–“ custom linux config files + â–‘â–“ author â–“ pyratebeard <root@pyratebeard.net> + â–‘â–“ code â–“ http://code.pyratebeard.net/dotfiles + â–‘â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“ + â–‘â–‘â–‘â–‘â–‘â–‘â–‘â–‘â–‘â–‘ + + awesome > awesome wm config and pyratebeard theme + bash > bash settings, aliases, and functions + dwb > dynamic web browser settings + gtk > mod of mist theme for gtk + irssi > nixers irc theme + moc > music on console custom theme and settings + mpd > music player daemon setup + mutt > minimal mutt setup + ncmpcpp > ncurses mpc++ ui/color settings + ranger > file manager with image previews and z3bra theme + sublime > sublime text 2 with greybeard, monokai, and gohu + tmux > terminal multiplexer with custom status bar + urxvt > sourcerer terminal colors and keyboard settings + vim > wizard status bar and sourcerer color scheme + zsh > zshell settings, aliases, and custom prompts + +``` + +##table of contents + - [introduction](#dotfiles) + - [managing](#managing) + - [installing](#installing) + - [how it works](#how-it-works) + - [tl;dr](#tldr) + - [my shell](#my-shell) + - [vim](#vim) + - [previews](#previews) + +#dotfiles +in the unix world programs are commonly configured in two different ways, via shell arguments or text based configuration files. programs with many options like window managers or text editors are configured on a per-user basis with files in your home directory `~`. in unix like operating systems any file or directory name that starts with a period or full stop character is considered hidden, and in a default view will not be displayed. thus the name dotfiles. + +it's been said of every console user: +> _"you are your dotfiles"_. + +since they dictate how your system will look and function. to many users (see [ricers](http://unixporn.net) and [beaners](http://nixers.net)) these files are very important, and need to be backed up and shared. people who create custom themes have the added challenge of managing multiple versions of them. i have tried many organization techniques. and just take my word for it when i say, keeping a git repo in the root of your home directory is a bad idea. i've written custom shell scripts for moving or symlinking files into place. there are even a few dotfile managers, but they all seem to have lots of dependencies. i knew there had to be a simple tool to help me. + +#managing +i manage mine with [gnu stow](http://www.gnu.org/software/stow/), a free, portable, lightweight symlink farm manager. this allows me to keep a versioned directory of all my config files that are virtually linked into place via a single command. this makes sharing these files among many users (root) and computers super simple. and does not clutter your home directory with version control files. + +#installing +stow is available for all linux and most other unix like distributions via your package manager. + +- `sudo pacman -S stow` +- `sudo apt-get install stow` +- `brew install stow` + +or clone it [from source](https://savannah.gnu.org/git/?group=stow) and [build it](http://git.savannah.gnu.org/cgit/stow.git/tree/INSTALL) yourself. + +#how it works +by default the stow command will create symlinks for files in the parent directory of where you execute the command. so my dotfiles setup assumes this repo is located in the root of your home directory `~/dotfiles`. and all stow commands should be executed in that directory. otherwise you'll need to use the `-d` flag with the repo directory location. + +to install most of my configs you execute the stow command with the folder name as the only argument. + +to install my **herbstluft** theme _greybeard_ use the command: + +`stow herbstluftwm` + +this will symlink files to `~/.config/herbstluftwm` and various other places. + +but you can override the default behavior and symlink files to another location with the `-t` (target) argument flag. + +to install the **ryu-login** you need to execute the command: + +`stow -t / ryu-login` + +this will symlink the file to `/etc/issue`. + +**note:** stow can only create a symlink if a config file does not already exist. if a default file was created upon program installation you must delete it first before you can install a new one with stow. this does not apply to directories, only files. + +#tl;dr +navigate to your home directory + +`cd ~` + +clone the repo: + +`git clone http://git.xero.nu/dotfiles.git` + +enter the dotfiles directory + +`cd dotfiles` + +install the zsh settings + +`stow zsh` + +install zsh settings for the root user + +`sudo stow zsh -t /root` + +install awesomewm theme + +`stow awesome` + +uninstall awesome theme + +`stow -D awesome` + +install herbstluftwm + +`stow herbstluftwm` + +etc, etc, etc... + +#my shell +i prefer a minimal setup, and choose to interact with my operating system via the so-called "terminal" or "command line", (read that quoting sarcastically) over a gui interface 2 times out of 3. with the web browser and video player among the noted outliers. in my opinion, using your computer should be a very personal experience. your colors, aliases, key-bindings, etc meticulously crafted to your exacting specifications. so for me, the unix shell is the most important part of my environment. + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/xero_shell.gif) + +my terminal emulator of choice is the lightweight, unicode, 256 color [urxvt](http://linux.die.net/man/1/urxvt). i use [zsh](http://linux.die.net/man/1/zsh) as my interactive shell. it's an extensible, bash like shell with awesome completion and correction engines. i manage multiple shell sessions with [tmux](http://linux.die.net/man/1/tmux). it's a feature packed terminal multiplexer with support for buffers, split windows, detached local and remote sessions, etc. i'm a member of the cult of [vim](http://linux.die.net/man/1/vim). sing phrases to the third reincarnation of the glorious ed! lel. [mpd](http://linux.die.net/man/1/mpd) is my music server and i use [ncmpcpp](http://ncmpcpp.rybczak.net/) as it's frontend. my configs for [urxvt](http://git.io/.urxvt), [zsh](http://git.io/.zsh), [tmux](http://git.io/.tmux), [vim](http://git.io/.vim), [mpd](http://git.io/.mpd) and [ncmpcpp](http://git.io/.ncmpcpp) shown above feature my [sourcerer](http://sourcerer.xero.nu) color scheme. + +#vim +with it's tight integration to the unix shell, [vim](http://www.vim.org) has quickly become my editor of choice. once you start to master the movements and operators you quickly begin manipulating, not just editing source code files. + +when you learn vim it's best to use a more vanilla config. if helps you focus on learning the editor and not the plugins. these are also great for [remote machines](http://git.io/.vimrc-min). but for your local dev environment, vim's vast and powerful plugin system can add many great features. i try to keep my editor slim and fast, but i find myself loving these plugins: + +- [vundle](https://github.com/gmarik/vundle.vim) - to manage other plugins +- [you complete me](https://github.com/Valloric/YouCompleteMe) - the best completion system +- [php complete](https://github.com/shawncplus/phpcomplete.vim) - extended php completions +- [syntastic](https://github.com/scrooloose/syntastic) - syntax linting +- [git gutter](https://github.com/airblade/vim-gitgutter) - git diff in the gutter +- [match it](https://github.com/isa/vim-matchit) - extended word and regex matching +- [lightline](https://github.com/itchyny/lightline.vim) - custom status line (for much rice) +- [fugitive](https://github.com/tpope/vim-fugitive) - fast git integration + +#previews +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/coils.png) +- [herbstluftwm](http://git.io/.herbstluftwm) +- [urxvt](http://git.io/.urxvt) +- [zsh](http://git.io/.zsh) +- [tmux](http://git.io/.tmux) +- [vim](http://git.io/.vim) +- [ncmpcpp](http://git.io/.ncmpcpp) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/blizzard-orb.png) +- [blizzard orb xcolors](https://github.com/xero/dotfiles/blob/master/urxvt/blizzard-orb.Xcolors) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/sysinfo.png) +- [sysinfo](http://git.io/v4aH5) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/neongold.png) +- [irssi](http://git.io/.irssi) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/scrot_converge.png) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/scrot_nightcity-1.png) +- [sysinfo](http://git.io/.sysinfo) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/scrot_nightcity-2.png) +- [sublime greybeard theme](http://git.io/sublimegreybeard) + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/scrot_nightcity-3.png) +- [chroimum with cathexis gtk](http://git.io/cathexis) & [greybeard devtools](http://git.io/greybeard-devtools) +- figlet [-f 3d](http://git.io/3d) webdev | lolcat + +![](https://raw.githubusercontent.com/xero/dotfiles/master/previews/scrot_nightcity-5.png) +- [color scripts](http://git.io/.fun) diff --git a/awesome/.config/awesome/lain/README.rst b/awesome/.config/awesome/lain/README.rst @@ -0,0 +1,47 @@ +Lain +==== + +-------------------------------------------------- +Layouts, widgets and utilities for Awesome WM 3.5+ +-------------------------------------------------- + +:Author: Luke Bonham <dada [at] archlinux [dot] info> +:Version: git +:License: GNU-GPL2_ +:Source: https://github.com/copycat-killer/lain + +Description +----------- + +Successor of awesome-vain_, this module provides new layouts, a set of widgets and utility functions, in order to improve Awesome_ usability and configurability. + +Read the wiki_ for all the info. + +Contributions +------------- + +Any contribution is welcome! Feel free to make a pull request. + +Just make sure that: + +- Your code fits with the general style of the module. In particular, you should use the same indentation pattern that the code uses, and also avoid adding space at the ends of lines. + +- Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using ``lain.helpers``. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment. + +- You test your changes before submitting to make sure that not only your code works, but did not break other parts of the module too! + +- You eventually update ``wiki`` submodule with a thorough section. + +Contributed widgets have to be put in ``lain/widgets/contrib``. + +Screenshots +----------- + +.. image:: http://i.imgur.com/8D9A7lW.png +.. image:: http://i.imgur.com/9Iv3OR3.png +.. image:: http://i.imgur.com/STCPcaJ.png + +.. _GNU-GPL2: http://www.gnu.org/licenses/gpl-2.0.html +.. _awesome-vain: https://github.com/vain/awesome-vain +.. _Awesome: http://awesome.naquadah.org/ +.. _wiki: https://github.com/copycat-killer/lain/wiki diff --git a/awesome/.config/awesome/lain/asyncshell.lua b/awesome/.config/awesome/lain/asyncshell.lua @@ -0,0 +1,79 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, worron + * (c) 2013, Alexander Yakushev + +--]] + +-- Asynchronous io.popen for Awesome WM. +-- How to use: +-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end) + +-- Grab environment +local awful = require('awful') + +-- Avoid discrepancies across multiple shells +awful.util.shell = '/bin/sh' + +-- Initialize tables for module +asyncshell = { request_table = {}, id_counter = 0 } + +-- Request counter +local function next_id() + asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000 + return asyncshell.id_counter +end + +-- Remove given request +function asyncshell.clear(id) + if asyncshell.request_table[id] then + if asyncshell.request_table[id].timer then + asyncshell.request_table[id].timer:stop() + asyncshell.request_table[id].timer = nil + end + asyncshell.request_table[id] = nil + end +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 +-- @param timeout Maximum amount of time to wait for the result (optional) +function asyncshell.request(command, callback, timeout) + local id = next_id() + asyncshell.request_table[id] = { callback = callback } + + local formatted_command = string.gsub(command, '"','\"') + + local req = string.format( + "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &", + id, formatted_command + ) + + if type(awful.spawn) == 'table' then + awful.spawn.with_shell(req) + else + awful.util.spawn_with_shell(req) + end + + if timeout then + asyncshell.request_table[id].timer = timer({ timeout = timeout }) + asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end) + asyncshell.request_table[id].timer:start() + end +end + +-- Calls the remembered callback function on the output of the shell command +-- @param id Request ID +-- @param output Shell command output to be delievered +function asyncshell.deliver(id, output) + local output = string.sub(output, 2, -2) + if asyncshell.request_table[id] then + asyncshell.request_table[id].callback(output) + asyncshell.clear(id) + end +end + +return asyncshell diff --git a/awesome/.config/awesome/lain/helpers.lua b/awesome/.config/awesome/lain/helpers.lua @@ -0,0 +1,151 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local debug = require("debug") + +local capi = { timer = (type(timer) == 'table' and timer or require ("gears.timer")) } +local io = { open = io.open, + lines = io.lines, + popen = io.popen } +local rawget = rawget +local table = { sort = table.sort } + +-- Lain helper functions for internal use +-- lain.helpers +local helpers = {} + +helpers.lain_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] +helpers.icons_dir = helpers.lain_dir .. 'icons/' +helpers.scripts_dir = helpers.lain_dir .. 'scripts/' + +-- {{{ Modules loader + +function helpers.wrequire(table, key) + local module = rawget(table, key) + return module or require(table._NAME .. '.' .. key) +end + +-- }}} + +-- {{{ File operations + +-- see if the file exists and is readable +function helpers.file_exists(file) + local f = io.open(file) + if f then + local s = f:read() + f:close() + f = s + end + return f ~= nil +end + +-- get all lines from a file, returns an empty +-- list/table if the file does not exist +function helpers.lines_from(file) + if not helpers.file_exists(file) then return {} end + local lines = {} + for line in io.lines(file) do + lines[#lines + 1] = line + end + return lines +end + +-- match all lines from a file, returns an empty +-- list/table if the file or match does not exist +function helpers.lines_match(regexp, file) + local lines = {} + for index,line in pairs(helpers.lines_from(file)) do + if string.match(line, regexp) then + lines[index] = line + end + end + return lines +end + +-- get first line of a file, return nil if +-- the file does not exist +function helpers.first_line(file) + return helpers.lines_from(file)[1] +end + +-- get first non empty line from a file, +-- returns nil otherwise +function helpers.first_nonempty_line(file) + for k,v in pairs(helpers.lines_from(file)) do + if #v then return v end + end + return nil +end + +-- }}} + +-- {{{ Timer maker + +helpers.timer_table = {} + +function helpers.newtimer(_name, timeout, fun, nostart) + local name = timeout + if not helpers.timer_table[name] then + helpers.timer_table[name] = capi.timer({ timeout = timeout }) + end + helpers.timer_table[name]:connect_signal("timeout", fun) + helpers.timer_table[name]:start() + if not nostart then + helpers.timer_table[name]:emit_signal("timeout") + end +end + +-- }}} + +-- {{{ Pipe operations + +-- read the full output of a pipe (command) +function helpers.read_pipe(cmd) + local f = assert(io.popen(cmd)) + local output = f:read("*all") + f:close() + return output +end + +-- }}} + +-- {{{ A map utility + +helpers.map_table = {} + +function helpers.set_map(element, value) + helpers.map_table[element] = value +end + +function helpers.get_map(element) + return helpers.map_table[element] +end + +-- }}} + +--{{{ Iterate over table of records sorted by keys +function helpers.spairs(t) + -- collect the keys + local keys = {} + for k in pairs(t) do keys[#keys+1] = k end + + table.sort(keys) + + -- return the iterator function + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end +end +--}}} + +return helpers diff --git a/awesome/.config/awesome/lain/icons/cal/white/1.png b/awesome/.config/awesome/lain/icons/cal/white/1.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/10.png b/awesome/.config/awesome/lain/icons/cal/white/10.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/11.png b/awesome/.config/awesome/lain/icons/cal/white/11.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/12.png b/awesome/.config/awesome/lain/icons/cal/white/12.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/13.png b/awesome/.config/awesome/lain/icons/cal/white/13.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/14.png b/awesome/.config/awesome/lain/icons/cal/white/14.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/15.png b/awesome/.config/awesome/lain/icons/cal/white/15.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/16.png b/awesome/.config/awesome/lain/icons/cal/white/16.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/17.png b/awesome/.config/awesome/lain/icons/cal/white/17.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/18.png b/awesome/.config/awesome/lain/icons/cal/white/18.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/19.png b/awesome/.config/awesome/lain/icons/cal/white/19.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/2.png b/awesome/.config/awesome/lain/icons/cal/white/2.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/20.png b/awesome/.config/awesome/lain/icons/cal/white/20.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/21.png b/awesome/.config/awesome/lain/icons/cal/white/21.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/22.png b/awesome/.config/awesome/lain/icons/cal/white/22.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/23.png b/awesome/.config/awesome/lain/icons/cal/white/23.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/24.png b/awesome/.config/awesome/lain/icons/cal/white/24.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/25.png b/awesome/.config/awesome/lain/icons/cal/white/25.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/26.png b/awesome/.config/awesome/lain/icons/cal/white/26.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/27.png b/awesome/.config/awesome/lain/icons/cal/white/27.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/28.png b/awesome/.config/awesome/lain/icons/cal/white/28.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/29.png b/awesome/.config/awesome/lain/icons/cal/white/29.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/3.png b/awesome/.config/awesome/lain/icons/cal/white/3.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/30.png b/awesome/.config/awesome/lain/icons/cal/white/30.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/31.png b/awesome/.config/awesome/lain/icons/cal/white/31.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/4.png b/awesome/.config/awesome/lain/icons/cal/white/4.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/5.png b/awesome/.config/awesome/lain/icons/cal/white/5.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/6.png b/awesome/.config/awesome/lain/icons/cal/white/6.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/7.png b/awesome/.config/awesome/lain/icons/cal/white/7.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/8.png b/awesome/.config/awesome/lain/icons/cal/white/8.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/cal/white/9.png b/awesome/.config/awesome/lain/icons/cal/white/9.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/cascade.png b/awesome/.config/awesome/lain/icons/layout/default/cascade.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/cascadebrowse.png b/awesome/.config/awesome/lain/icons/layout/default/cascadebrowse.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/cascadebrowsew.png b/awesome/.config/awesome/lain/icons/layout/default/cascadebrowsew.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/cascadew.png b/awesome/.config/awesome/lain/icons/layout/default/cascadew.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/centerfair.png b/awesome/.config/awesome/lain/icons/layout/default/centerfair.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/centerfairw.png b/awesome/.config/awesome/lain/icons/layout/default/centerfairw.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/centerhwork.png b/awesome/.config/awesome/lain/icons/layout/default/centerhwork.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/centerhworkw.png b/awesome/.config/awesome/lain/icons/layout/default/centerhworkw.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/centerwork.png b/awesome/.config/awesome/lain/icons/layout/default/centerwork.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/centerworkw.png b/awesome/.config/awesome/lain/icons/layout/default/centerworkw.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/termfair.png b/awesome/.config/awesome/lain/icons/layout/default/termfair.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/default/termfairw.png b/awesome/.config/awesome/lain/icons/layout/default/termfairw.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/zenburn/cascade.png b/awesome/.config/awesome/lain/icons/layout/zenburn/cascade.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/zenburn/cascadebrowse.png b/awesome/.config/awesome/lain/icons/layout/zenburn/cascadebrowse.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/zenburn/centerfair.png b/awesome/.config/awesome/lain/icons/layout/zenburn/centerfair.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/zenburn/centerwork.png b/awesome/.config/awesome/lain/icons/layout/zenburn/centerwork.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/layout/zenburn/termfair.png b/awesome/.config/awesome/lain/icons/layout/zenburn/termfair.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/mail.png b/awesome/.config/awesome/lain/icons/mail.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/no_net.png b/awesome/.config/awesome/lain/icons/no_net.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/01d.png b/awesome/.config/awesome/lain/icons/openweathermap/01d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/01n.png b/awesome/.config/awesome/lain/icons/openweathermap/01n.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/02d.png b/awesome/.config/awesome/lain/icons/openweathermap/02d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/02n.png b/awesome/.config/awesome/lain/icons/openweathermap/02n.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/03d.png b/awesome/.config/awesome/lain/icons/openweathermap/03d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/03n.png b/awesome/.config/awesome/lain/icons/openweathermap/03n.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/04d.png b/awesome/.config/awesome/lain/icons/openweathermap/04d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/04n.png b/awesome/.config/awesome/lain/icons/openweathermap/04n.png @@ -0,0 +1 @@ +04d.png +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/icons/openweathermap/09d.png b/awesome/.config/awesome/lain/icons/openweathermap/09d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/09n.png b/awesome/.config/awesome/lain/icons/openweathermap/09n.png @@ -0,0 +1 @@ +09d.png +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/icons/openweathermap/10d.png b/awesome/.config/awesome/lain/icons/openweathermap/10d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/10n.png b/awesome/.config/awesome/lain/icons/openweathermap/10n.png @@ -0,0 +1 @@ +10d.png +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/icons/openweathermap/11d.png b/awesome/.config/awesome/lain/icons/openweathermap/11d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/11n.png b/awesome/.config/awesome/lain/icons/openweathermap/11n.png @@ -0,0 +1 @@ +11d.png +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/icons/openweathermap/13d.png b/awesome/.config/awesome/lain/icons/openweathermap/13d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/13n.png b/awesome/.config/awesome/lain/icons/openweathermap/13n.png @@ -0,0 +1 @@ +13d.png +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/icons/openweathermap/50d.png b/awesome/.config/awesome/lain/icons/openweathermap/50d.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/openweathermap/50n.png b/awesome/.config/awesome/lain/icons/openweathermap/50n.png @@ -0,0 +1 @@ +50d.png +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/icons/openweathermap/README.md b/awesome/.config/awesome/lain/icons/openweathermap/README.md @@ -0,0 +1,3 @@ +[Plain Weather Icons](http://merlinthered.deviantart.com/art/plain-weather-icons-157162192), created by [MerlinTheRed](http://merlinthered.deviantart.com/). + +<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/"><img src="http://i.creativecommons.org/l/by-nc-sa/2.5/80x15.png" align="right"></a> diff --git a/awesome/.config/awesome/lain/icons/openweathermap/na.png b/awesome/.config/awesome/lain/icons/openweathermap/na.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/redshift/redshift_off.png b/awesome/.config/awesome/lain/icons/redshift/redshift_off.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/redshift/redshift_on.png b/awesome/.config/awesome/lain/icons/redshift/redshift_on.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/taskwarrior/task.png b/awesome/.config/awesome/lain/icons/taskwarrior/task.png Binary files differ. diff --git a/awesome/.config/awesome/lain/icons/taskwarrior/tasksmall.png b/awesome/.config/awesome/lain/icons/taskwarrior/tasksmall.png Binary files differ. diff --git a/awesome/.config/awesome/lain/init.lua b/awesome/.config/awesome/lain/init.lua @@ -0,0 +1,21 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +package.loaded.lain = nil + +local lain = +{ + layout = require("lain.layout"), + util = require("lain.util"), + widgets = require("lain.widgets") +} + +return lain diff --git a/awesome/.config/awesome/lain/layout/cascade.lua b/awesome/.config/awesome/lain/layout/cascade.lua @@ -0,0 +1,79 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") + +local cascade = +{ + name = "cascade", + nmaster = 0, + offset_x = 32, + offset_y = 8 +} + +function cascade.arrange(p) + + -- Cascade windows. + + -- A global border can be defined with + -- beautiful.global_border_width. + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- Opening a new window will usually force all existing windows to + -- get resized. This wastes a lot of CPU time. So let's set a lower + -- bound to "how_many": This wastes a little screen space but you'll + -- get a much better user experience. + local t = tag.selected(p.screen) + local num_c + if cascade.nmaster > 0 + then + num_c = cascade.nmaster + else + num_c = tag.getnmaster(t) + end + + local how_many = #cls + if how_many < num_c + then + how_many = num_c + end + + local current_offset_x = cascade.offset_x * (how_many - 1) + local current_offset_y = cascade.offset_y * (how_many - 1) + + -- Iterate. + for i = 1,#cls,1 + do + local c = cls[i] + local g = {} + + g.x = wa.x + (how_many - i) * cascade.offset_x + g.y = wa.y + (i - 1) * cascade.offset_y + g.width = wa.width - current_offset_x - 2*c.border_width + g.height = wa.height - current_offset_y - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + + c:geometry(g) + end +end + +return cascade diff --git a/awesome/.config/awesome/lain/layout/cascadetile.lua b/awesome/.config/awesome/lain/layout/cascadetile.lua @@ -0,0 +1,174 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local tonumber = tonumber + +local cascadetile = +{ + name = "cascadetile", + nmaster = 0, + ncol = 0, + mwfact = 0, + offset_x = 5, + offset_y = 32, + extra_padding = 0 +} + +function cascadetile.arrange(p) + + -- Layout with one fixed column meant for a master window. Its + -- width is calculated according to mwfact. Other clients are + -- cascaded or "tabbed" in a slave column on the right. + + -- It's a bit hard to demonstrate the behaviour with ASCII-images... + -- + -- (1) (2) (3) (4) + -- +----------+---+ +----------+---+ +----------+---+ +----------+---+ + -- | | | | | 3 | | | 4 | | +---+| + -- | | | -> | | | -> | +---++ -> | +---+|+ + -- | 1 | 2 | | 1 +---++ | 1 | 3 || | 1 +---+|+| + -- | | | | | 2 || | +---++| | +---+|+ | + -- | | | | | || | | 2 | | | | 2 |+ | + -- +----------+---+ +---------+---++ +--------+---+-+ +------+---+---+ + + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Borders are factored in. + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- Width of main column? + local t = tag.selected(p.screen) + local mwfact + if cascadetile.mwfact > 0 + then + mwfact = cascadetile.mwfact + else + mwfact = tag.getmwfact(t) + end + + -- Make slave windows overlap main window? Do this if ncol is 1. + local overlap_main + if cascadetile.ncol > 0 + then + overlap_main = cascadetile.ncol + else + overlap_main = tag.getncol(t) + end + + -- Minimum space for slave windows? See cascade.lua. + local num_c + if cascadetile.nmaster > 0 + then + num_c = cascadetile.nmaster + else + num_c = tag.getnmaster(t) + end + + local how_many = #cls - 1 + if how_many < num_c + then + how_many = num_c + end + local current_offset_x = cascadetile.offset_x * (how_many - 1) + local current_offset_y = cascadetile.offset_y * (how_many - 1) + + if #cls > 0 + then + -- Main column, fixed width and height. + local c = cls[1] + local g = {} + -- Subtracting the useless_gap width from the work area width here + -- makes this mwfact calculation work the same as in uselesstile. + -- Rounding is necessary to prevent the rendered size of slavewid + -- from being 1 pixel off when the result is not an integer. + local mainwid = math.floor((wa.width - useless_gap) * mwfact) + local slavewid = wa.width - mainwid + + if overlap_main == 1 + then + g.width = wa.width - 2*c.border_width + + -- The size of the main window may be reduced a little bit. + -- This allows you to see if there are any windows below the + -- main window. + -- This only makes sense, though, if the main window is + -- overlapping everything else. + g.width = g.width - cascadetile.extra_padding + else + g.width = mainwid - 2*c.border_width + end + + g.height = wa.height - 2*c.border_width + g.x = wa.x + g.y = wa.y + if useless_gap > 0 + then + -- Reduce width once and move window to the right. Reduce + -- height twice, however. + g.width = g.width - useless_gap + g.height = g.height - 2 * useless_gap + g.x = g.x + useless_gap + g.y = g.y + useless_gap + + -- When there's no window to the right, add an additional + -- gap. + if overlap_main == 1 + then + g.width = g.width - useless_gap + end + end + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + + -- Remaining clients stacked in slave column, new ones on top. + if #cls > 1 + then + for i = 2,#cls + do + c = cls[i] + g = {} + g.width = slavewid - current_offset_x - 2*c.border_width + g.height = wa.height - current_offset_y - 2*c.border_width + g.x = wa.x + mainwid + (how_many - (i - 1)) * cascadetile.offset_x + g.y = wa.y + (i - 2) * cascadetile.offset_y + if useless_gap > 0 + then + g.width = g.width - 2 * useless_gap + g.height = g.height - 2 * useless_gap + g.x = g.x + useless_gap + g.y = g.y + useless_gap + end + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + end + end + end +end + +return cascadetile diff --git a/awesome/.config/awesome/lain/layout/centerfair.lua b/awesome/.config/awesome/lain/layout/centerfair.lua @@ -0,0 +1,164 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010, Nicolas Estibals + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local math = { ceil = math.ceil, + floor = math.floor, + max = math.max } +local tonumber = tonumber + +local centerfair = { name = "centerfair" } + +function centerfair.arrange(p) + -- Layout with fixed number of vertical columns (read from nmaster). + -- Cols are centerded until there is nmaster columns, then windows + -- are stacked in the slave columns, with at most ncol clients per + -- column if possible. + + -- with nmaster=3 and ncol=1 you'll have + -- (1) (2) (3) + -- +---+---+---+ +-+---+---+-+ +---+---+---+ + -- | | | | | | | | | | | | | + -- | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> + -- | | | | | | | | | | | | | + -- +---+---+---+ +-+---+---+-+ +---+---+---+ + + -- (4) (5) + -- +---+---+---+ +---+---+---+ + -- | | | 3 | | | 2 | 4 | + -- + 1 + 2 +---+ -> + 1 +---+---+ + -- | | | 4 | | | 3 | 5 | + -- +---+---+---+ +---+---+---+ + + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Borders are factored in. + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- How many vertical columns? Read from nmaster on the tag. + local t = tag.selected(p.screen) + local num_x = centerfair.nmaster or tag.getnmaster(t) + local ncol = centerfair.ncol or tag.getncol(t) + if num_x <= 2 then num_x = 2 end + + local width = math.floor((wa.width - (num_x + 1)*useless_gap) / num_x) + + if #cls < num_x + then + -- Less clients than the number of columns, let's center it! + local offset_x = wa.x + (wa.width - #cls*width - (#cls - 1)*useless_gap) / 2 + local g = {} + g.y = wa.y + useless_gap + for i = 1, #cls do + local c = cls[i] + g.width = width - 2*c.border_width + g.height = wa.height - 2*useless_gap - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + g.x = offset_x + (i - 1) * (width + useless_gap) + c:geometry(g) + end + else + -- More clients than the number of columns, let's arrange it! + -- Master client deserves a special treatement + local c = cls[1] + local g = {} + g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width + g.height = wa.height - 2*useless_gap - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + + c:geometry(g) + + -- Treat the other clients + + -- Compute distribution of clients among columns + local num_y ={} + do + local remaining_clients = #cls-1 + local ncol_min = math.ceil(remaining_clients/(num_x-1)) + if ncol >= ncol_min + then + for i = (num_x-1), 1, -1 do + if (remaining_clients-i+1) < ncol + then + num_y[i] = remaining_clients-i + 1 + else + num_y[i] = ncol + end + remaining_clients = remaining_clients - num_y[i] + end + else + local rem = remaining_clients % (num_x-1) + if rem ==0 + then + for i = 1, num_x-1 do + num_y[i] = ncol_min + end + else + for i = 1, num_x-1 do + num_y[i] = ncol_min - 1 + end + for i = 0, rem-1 do + num_y[num_x-1-i] = num_y[num_x-1-i] + 1 + end + end + end + end + + -- Compute geometry of the other clients + local nclient = 2 -- we start with the 2nd client + g.x = g.x + g.width + useless_gap + 2*c.border_width + + for i = 1, (num_x-1) do + local height = math.floor((wa.height - (num_y[i] + 1)*useless_gap) / num_y[i]) + g.y = wa.y + useless_gap + for j = 0, (num_y[i]-2) do + local c = cls[nclient] + g.height = height - 2*c.border_width + g.width = width - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + nclient = nclient + 1 + g.y = g.y + height + useless_gap + end + local c = cls[nclient] + g.height = wa.height - (num_y[i] + 1)*useless_gap - (num_y[i] - 1)*height - 2*c.border_width + g.width = width - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + nclient = nclient + 1 + g.x = g.x + width + useless_gap + end + end +end + +return centerfair diff --git a/awesome/.config/awesome/lain/layout/centerhwork.lua b/awesome/.config/awesome/lain/layout/centerhwork.lua @@ -0,0 +1,136 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, Joerg Jaspert + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local tonumber = tonumber + +local centerhwork = +{ + name = "centerhwork", + top_left = 0, + top_right = 1, + bottom_left = 2, + bottom_right = 3 +} + +function centerhwork.arrange(p) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Borders are factored in. + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- Width of main column? + local t = awful.tag.selected(p.screen) + local mwfact = awful.tag.getmwfact(t) + + if #cls > 0 + then + -- Main column, fixed width and height. + local c = cls[1] + local g = {} + local mainhei = math.floor(wa.height * mwfact) + local slaveLwid = math.floor(wa.width / 2 ) + local slaveRwid = wa.width - slaveLwid + local slavehei = wa.height - mainhei + local slaveThei = math.floor(slavehei / 2) + local slaveBhei = slavehei - slaveThei + local Lhalfgap = math.floor(useless_gap / 2) + local Rhalfgap = useless_gap - Lhalfgap + + g.height = mainhei - 2*c.border_width + g.width = wa.width - 2*useless_gap - 2*c.border_width + g.x = wa.x + useless_gap + g.y = wa.y + slaveThei + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + + -- Auxiliary windows. + if #cls > 1 + then + local at = 0 + for i = 2,#cls + do + -- It's all fixed. If there are more than 5 clients, + -- those additional clients will float. This is + -- intentional. + if at == 4 + then + break + end + + c = cls[i] + g = {} + + if i - 2 == centerhwork.top_left + then + -- top left + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + g.width = slaveLwid - useless_gap - Lhalfgap - 2*c.border_width + g.height = slaveThei - 2*useless_gap - 2*c.border_width + elseif i - 2 == centerhwork.top_right + then + -- top right + g.x = wa.x + slaveLwid + Rhalfgap + g.y = wa.y + useless_gap + g.width = slaveRwid - useless_gap - Rhalfgap - 2*c.border_width + g.height = slaveThei - 2*useless_gap - 2*c.border_width + elseif i - 2 == centerhwork.bottom_left + then + -- bottom left + g.x = wa.x + useless_gap + g.y = wa.y + mainhei + slaveThei + useless_gap + g.width = slaveLwid - useless_gap - Lhalfgap - 2*c.border_width + g.height = slaveBhei - 2*useless_gap - 2*c.border_width + elseif i - 2 == centerhwork.bottom_right + then + -- bottom right + g.x = wa.x + slaveLwid + Rhalfgap + g.y = wa.y + mainhei + slaveThei + useless_gap + g.width = slaveRwid - useless_gap - Rhalfgap - 2*c.border_width + g.height = slaveBhei - 2*useless_gap - 2*c.border_width + end + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + + at = at + 1 + end + + -- Set remaining clients to floating. + for i = (#cls - 1 - 4),1,-1 + do + c = cls[i] + awful.client.floating.set(c, true) + end + end + end +end + +return centerhwork diff --git a/awesome/.config/awesome/lain/layout/centerwork.lua b/awesome/.config/awesome/lain/layout/centerwork.lua @@ -0,0 +1,136 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local tonumber = tonumber +local math = { floor = math.floor } + +local centerwork = +{ + name = "centerwork", + top_right = 0, + bottom_right = 1, + bottom_left = 2, + top_left = 3 +} + +function centerwork.arrange(p) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Borders are factored in. + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- Width of main column? + local t = awful.tag.selected(p.screen) + local mwfact = awful.tag.getmwfact(t) + + if #cls > 0 + then + -- Main column, fixed width and height. + local c = cls[1] + local g = {} + local mainwid = math.floor(wa.width * mwfact) + local slavewid = wa.width - mainwid + local slaveLwid = math.floor(slavewid / 2) + local slaveRwid = slavewid - slaveLwid + local slaveThei = math.floor(wa.height / 2) + local slaveBhei = wa.height - slaveThei + local Thalfgap = math.floor(useless_gap / 2) + local Bhalfgap = useless_gap - Thalfgap + + g.height = wa.height - 2*useless_gap - 2*c.border_width + g.width = mainwid - 2*c.border_width + g.x = wa.x + slaveLwid + g.y = wa.y + useless_gap + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + + -- Auxiliary windows. + if #cls > 1 + then + local at = 0 + for i = 2,#cls + do + -- It's all fixed. If there are more than 5 clients, + -- those additional clients will float. This is + -- intentional. + if at == 4 + then + break + end + + c = cls[i] + g = {} + + if i - 2 == centerwork.top_left + then + -- top left + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + g.width = slaveLwid - 2*useless_gap - 2*c.border_width + g.height = slaveThei - useless_gap - Thalfgap - 2*c.border_width + elseif i - 2 == centerwork.top_right + then + -- top right + g.x = wa.x + slaveLwid + mainwid + useless_gap + g.y = wa.y + useless_gap + g.width = slaveRwid - 2*useless_gap - 2*c.border_width + g.height = slaveThei - useless_gap - Thalfgap - 2*c.border_width + elseif i - 2 == centerwork.bottom_left + then + -- bottom left + g.x = wa.x + useless_gap + g.y = wa.y + slaveThei + Bhalfgap + g.width = slaveLwid - 2*useless_gap - 2*c.border_width + g.height = slaveBhei - useless_gap - Bhalfgap - 2*c.border_width + elseif i - 2 == centerwork.bottom_right + then + -- bottom right + g.x = wa.x + slaveLwid + mainwid + useless_gap + g.y = wa.y + slaveThei + Bhalfgap + g.width = slaveRwid - 2*useless_gap - 2*c.border_width + g.height = slaveBhei - useless_gap - Bhalfgap - 2*c.border_width + end + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + + at = at + 1 + end + + -- Set remaining clients to floating. + for i = (#cls - 1 - 4),1,-1 + do + c = cls[i] + awful.client.floating.set(c, true) + end + end + end +end + +return centerwork diff --git a/awesome/.config/awesome/lain/layout/centerworkd.lua b/awesome/.config/awesome/lain/layout/centerworkd.lua @@ -0,0 +1,123 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2016, Henrik Antonsson + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + + Based on centerwork.lua +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local tonumber = tonumber +local math = { floor = math.floor } + +local centerworkd = +{ + name = "centerworkd", +} + +function centerworkd.arrange(p) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Borders are factored in. + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- Width of main column? + local t = awful.tag.selected(p.screen) + local mwfact = awful.tag.getmwfact(t) + + if #cls > 0 + then + -- Main column, fixed width and height. + local c = cls[1] + local g = {} + local mainwid = math.floor(wa.width * mwfact) + local slavewid = wa.width - mainwid + local slaveLwid = math.floor(slavewid / 2) + local slaveRwid = slavewid - slaveLwid + local nbrLeftSlaves = math.floor(#cls / 2) + local nbrRightSlaves = math.floor((#cls - 1) / 2) + + local slaveLeftHeight = 0 + if nbrLeftSlaves > 0 then slaveLeftHeight = math.floor(wa.height / nbrLeftSlaves) end + if nbrRightSlaves > 0 then slaveRightHeight = math.floor(wa.height / nbrRightSlaves) end + + g.height = wa.height - 2*useless_gap - 2*c.border_width + g.width = mainwid - 2*c.border_width + g.x = wa.x + slaveLwid + g.y = wa.y + useless_gap + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + + -- Auxiliary windows. + if #cls > 1 + then + for i = 2,#cls + do + c = cls[i] + g = {} + + local rowIndex = math.floor(i/2) + + -- If i is even it should be placed on the left side + if i % 2 == 0 + then + -- left slave + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + (rowIndex-1)*slaveLeftHeight + + g.width = slaveLwid - 2*useless_gap - 2*c.border_width + + -- if last slave in left row use remaining space for that slave + if rowIndex == nbrLeftSlaves + then + g.height = wa.y + wa.height - g.y - useless_gap - 2*c.border_width + else + g.height = slaveLeftHeight - useless_gap - 2*c.border_width + end + else + -- right slave + g.x = wa.x + slaveLwid + mainwid + useless_gap + g.y = wa.y + useless_gap + (rowIndex-1)*slaveRightHeight + + g.width = slaveRwid - 2*useless_gap - 2*c.border_width + + -- if last slave in right row use remaining space for that slave + if rowIndex == nbrRightSlaves + then + g.height = wa.y + wa.height - g.y - useless_gap - 2*c.border_width + else + g.height = slaveRightHeight - useless_gap - 2*c.border_width + end + + end + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + end + end + end +end + +return centerworkd diff --git a/awesome/.config/awesome/lain/layout/init.lua b/awesome/.config/awesome/lain/layout/init.lua @@ -0,0 +1,20 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Layouts section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +local layout = { _NAME = "lain.layout" } + +return setmetatable(layout, { __index = wrequire }) diff --git a/awesome/.config/awesome/lain/layout/termfair.lua b/awesome/.config/awesome/lain/layout/termfair.lua @@ -0,0 +1,139 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local math = { ceil = math.ceil, + floor = math.floor, + max = math.max } +local tonumber = tonumber + +local termfair = { name = "termfair" } + +function termfair.arrange(p) + -- Layout with fixed number of vertical columns (read from nmaster). + -- New windows align from left to right. When a row is full, a now + -- one above it is created. Like this: + + -- (1) (2) (3) + -- +---+---+---+ +---+---+---+ +---+---+---+ + -- | | | | | | | | | | | | + -- | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> + -- | | | | | | | | | | | | + -- +---+---+---+ +---+---+---+ +---+---+---+ + + -- (4) (5) (6) + -- +---+---+---+ +---+---+---+ +---+---+---+ + -- | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | + -- +---+---+---+ -> +---+---+---+ -> +---+---+---+ + -- | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | + -- +---+---+---+ +---+---+---+ +---+---+---+ + + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Borders are factored in. + wa.height = wa.height - (global_border * 2) + wa.width = wa.width - (global_border * 2) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + + -- How many vertical columns? + local t = tag.selected(p.screen) + local num_x = termfair.nmaster or tag.getnmaster(t) + + -- Do at least "desired_y" rows. + local desired_y = termfair.ncol or tag.getncol(t) + + if #cls > 0 + then + local num_y = math.max(math.ceil(#cls / num_x), desired_y) + local cur_num_x = num_x + local at_x = 0 + local at_y = 0 + local remaining_clients = #cls + local width = math.floor((wa.width - (num_x + 1)*useless_gap) / num_x) + local height = math.floor((wa.height - (num_y + 1)*useless_gap) / num_y) + + -- We start the first row. Left-align by limiting the number of + -- available slots. + if remaining_clients < num_x + then + cur_num_x = remaining_clients + end + + -- Iterate in reversed order. + for i = #cls,1,-1 + do + -- Get x and y position. + local c = cls[i] + local this_x = cur_num_x - at_x - 1 + local this_y = num_y - at_y - 1 + + -- Calc geometry. + local g = {} + if this_x == (num_x - 1) + then + g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width + else + g.width = width - 2*c.border_width + end + if this_y == (num_y - 1) + then + g.height = wa.height - (num_y - 1)*height - (num_y + 1)*useless_gap - 2*c.border_width + else + g.height = height - 2*c.border_width + end + + g.x = wa.x + this_x*width + g.y = wa.y + this_y*height + + if useless_gap > 0 + then + -- All clients tile evenly. + g.x = g.x + (this_x + 1)*useless_gap + g.y = g.y + (this_y + 1)*useless_gap + + end + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + remaining_clients = remaining_clients - 1 + + -- Next grid position. + at_x = at_x + 1 + if at_x == num_x + then + -- Row full, create a new one above it. + at_x = 0 + at_y = at_y + 1 + + -- We start a new row. Left-align. + if remaining_clients < num_x + then + cur_num_x = remaining_clients + end + end + end + end +end + +return termfair diff --git a/awesome/.config/awesome/lain/layout/uselessfair.lua b/awesome/.config/awesome/lain/layout/uselessfair.lua @@ -0,0 +1,108 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile, worron + * (c) 2013, Luke Bonham + * (c) 2012, Josh Komoroske + * (c) 2010-2012, Peter Hofmann + +--]] + +local beautiful = require("beautiful") +local ipairs = ipairs +local math = { ceil = math.ceil, sqrt = math.sqrt, floor = math.floor, max = math.max } +local tonumber = tonumber + +local uselessfair = {} + +-- Transformation functions +local function swap(geometry) + return { x = geometry.y, y = geometry.x, width = geometry.height, height = geometry.width } +end + +-- Client geometry correction depending on useless gap and window border +local function size_correction(c, geometry, useless_gap) + geometry.width = math.max(geometry.width - 2 * c.border_width - useless_gap, 1) + geometry.height = math.max(geometry.height - 2 * c.border_width - useless_gap, 1) + geometry.x = geometry.x + useless_gap / 2 + geometry.y = geometry.y + useless_gap / 2 +end + +-- Main tiling function +local function fair(p, orientation) + + -- Theme vars + local useless_gap = beautiful.useless_gap_width or 0 + local global_border = beautiful.global_border_width or 0 + + -- Aliases + local wa = p.workarea + local cls = p.clients + + -- Nothing to tile here + if #cls == 0 then return end + + -- Workarea size correction depending on useless gap and global border + wa.height = wa.height - 2 * global_border - useless_gap + wa.width = wa.width - 2 * global_border - useless_gap + wa.x = wa.x + useless_gap / 2 + global_border + wa.y = wa.y + useless_gap / 2 + global_border + + -- Geometry calculation + local row, col = 0, 0 + + local rows = math.ceil(math.sqrt(#cls)) + local cols = math.ceil(#cls / rows) + + for i, c in ipairs(cls) do + local g = {} + + -- find tile orientation for current client and swap geometry if need + local need_swap = (orientation == "east" and #cls <= 2) or (orientation == "south" and #cls > 2) + local area = need_swap and swap(wa) or wa + + -- calculate geometry + if #cls < (cols * rows) and row == cols - 1 then + g.width = area.width / (rows - ((cols * rows) - #cls)) + else + g.width = area.width / rows + end + + g.height = area.height / cols + g.x = area.x + col * g.width + g.y = area.y + row * g.height + + -- turn back to real if geometry was swapped + if need_swap then g = swap(g) end + + -- window size correction depending on useless gap and window border + size_correction(c, g, useless_gap) + + -- set geometry + c:geometry(g) + + -- update tile grid coordinates + col = i % rows + row = math.floor(i / rows) + end +end + +-- Layout constructor +local function construct_layout(name, direction) + return { + name = name, + -- @p screen The screen number to tile + arrange = function(p) return fair(p, direction) end + } +end + +-- Build layouts with different tile direction +uselessfair.vertical = construct_layout("uselessfair", "south") +uselessfair.horizontal = construct_layout("uselessfairh", "east") + +-- Module aliase +uselessfair.arrange = uselessfair.vertical.arrange +uselessfair.name = uselessfair.vertical.name + +return uselessfair diff --git a/awesome/.config/awesome/lain/layout/uselesspiral.lua b/awesome/.config/awesome/lain/layout/uselesspiral.lua @@ -0,0 +1,123 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2009, Uli Schlachter + * (c) 2008, Julien Danjolu + +--]] + +local beautiful = require("beautiful") +local ipairs = ipairs +local tonumber = tonumber +local math = require("math") + +local uselesspiral = {} + +local function spiral(p, spiral) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 + + -- get our orientation right + local wa = p.workarea + local cls = p.clients + local n = #cls -- number of windows total; k = which window number + + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + + local static_wa = wa + + for k, c in ipairs(cls) do + if k < n then + if k % 2 == 0 then + wa.height = (wa.height / 2) + else + wa.width = (wa.width / 2) + end + end + + if k % 4 == 0 and spiral then + wa.x = wa.x - wa.width + elseif k % 2 == 0 or + (k % 4 == 3 and k < n and spiral) then + wa.x = wa.x + wa.width + end + + if k % 4 == 1 and k ~= 1 and spiral then + wa.y = wa.y - wa.height + elseif k % 2 == 1 and k ~= 1 or + (k % 4 == 0 and k < n and spiral) then + wa.y = wa.y + wa.height + end + + local wa2 = {} + wa2.x = wa.x + (useless_gap / 2) + global_border + wa2.y = wa.y + (useless_gap / 2) + global_border + wa2.height = wa.height - (useless_gap / 2) + wa2.width = wa.width - (useless_gap / 2) + + -- Useless gap. + if useless_gap > 0 + then + -- Top and left clients are shrinked by two steps and + -- get moved away from the border. Other clients just + -- get shrinked in one direction. + + top = false + left = false + + if wa2.y == static_wa.y then + top = true + end + + if wa2.x == static_wa.x then + left = true + end + + if top then + wa2.height = wa2.height - useless_gap + wa2.y = wa2.y - (useless_gap / 2) + else + wa2.height = wa2.height - (useless_gap / 2) + end + + if left then + wa2.width = wa2.width - useless_gap + wa2.x = wa2.x - (useless_gap / 2) + else + wa2.width = wa2.width - (useless_gap / 2) + end + end + -- End of useless gap. + + c:geometry(wa2) + end +end + +--- Dwindle layout +uselesspiral.dwindle = {} +uselesspiral.dwindle.name = "uselessdwindle" +function uselesspiral.dwindle.arrange(p) + return spiral(p, false) +end + +--- Spiral layout +uselesspiral.name = "uselesspiral" +function uselesspiral.arrange(p) + return spiral(p, true) +end + +return uselesspiral diff --git a/awesome/.config/awesome/lain/layout/uselesstile.lua b/awesome/.config/awesome/lain/layout/uselesstile.lua @@ -0,0 +1,231 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, projektile, worron + * (c) 2013, Luke Bonham + * (c) 2009, Donald Ephraim Curtis + * (c) 2008, Julien Danjolu + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local ipairs = ipairs +local math = { floor = math.floor, + ceil = math.ceil, + max = math.max, + min = math.min } +local tonumber = tonumber + +local uselesstile = {} + +-- Transformation functions +local function flip(canvas, geometry) + return { + -- vertical only + x = 2 * canvas.x + canvas.width - geometry.x - geometry.width, + y = geometry.y, + width = geometry.width, + height = geometry.height + } +end + +local function swap(geometry) + return { x = geometry.y, y = geometry.x, width = geometry.height, height = geometry.width } +end + +-- Find geometry for secondary windows column +local function cut_column(wa, n, index) + local width = math.floor(wa.width / n) + local area = { x = wa.x + (index - 1) * width, y = wa.y, width = width, height = wa.height } + + return area +end + +-- Find geometry for certain window in column +local function cut_row(wa, factor, index, used) + local height = math.floor(wa.height * factor.window[index] / factor.total) + local area = { x = wa.x, y = wa.y + used, width = wa.width, height = height } + + return area +end + +-- Client geometry correction depending on useless gap and window border +local function size_correction(c, geometry, useless_gap) + geometry.width = math.max(geometry.width - 2 * c.border_width - useless_gap, 1) + geometry.height = math.max(geometry.height - 2 * c.border_width - useless_gap, 1) + geometry.x = geometry.x + useless_gap / 2 + geometry.y = geometry.y + useless_gap / 2 +end + +-- Check size factor for group of clients and calculate total +local function calc_factor(n, winfactors) + local factor = { window = winfactors, total = 0, min = 1 } + + for i = 1, n do + if not factor.window[i] then + factor.window[i] = factor.min + else + factor.min = math.min(factor.window[i], factor.min) + if factor.window[i] < 0.05 then factor.window[i] = 0.05 end + end + factor.total = factor.total + factor.window[i] + end + + return factor +end + +-- Tile group of clients in given area +-- @canvas need for proper transformation only +-- @winfactors table with clients size factors +local function tile_column(canvas, area, list, useless_gap, transformation, winfactors) + local used = 0 + local factor = calc_factor(#list, winfactors) + + for i, c in ipairs(list) do + local g = cut_row(area, factor, i, used) + if i == #list then g.height = area.height - used end + used = used + g.height + + -- swap workarea dimensions + if transformation.flip then g = flip(canvas, g) end + if transformation.swap then g = swap(g) end + + -- useless gap and border correction + size_correction(c, g, useless_gap) + + + c:geometry(g) + end +end + +--Main tile function +local function tile(p, orientation) + + -- Theme vars + local useless_gap = beautiful.useless_gap_width or 0 + local global_border = beautiful.global_border_width or 0 + + -- Aliases + local wa = p.workarea + local cls = p.clients + local t = tag.selected(p.screen) + + -- Nothing to tile here + if #cls == 0 then return end + + -- Get tag prop + local nmaster = math.min(tag.getnmaster(t), #cls) + local mwfact = tag.getmwfact(t) + + if nmaster == 0 then + mwfact = 0 + elseif nmaster == #cls then + mwfact = 1 + end + + -- clients size factor + local data = tag.getdata(t).windowfact + + if not data then + data = {} + tag.getdata(t).windowfact = data + end + + -- Workarea size correction depending on useless gap and global border + wa.height = wa.height - 2 * global_border - useless_gap + wa.width = wa.width - 2 * global_border - useless_gap + wa.x = wa.x + useless_gap / 2 + global_border + wa.y = wa.y + useless_gap / 2 + global_border + + -- Find which transformation we need for given orientation + local transformation = { + swap = orientation == 'top' or orientation == 'bottom', + flip = orientation == 'left' or orientation == 'top' + } + + -- Swap workarea dimensions if orientation vertical + if transformation.swap then wa = swap(wa) end + + -- Split master and other windows + local cls_master, cls_other = {}, {} + + for i, c in ipairs(cls) do + if i <= nmaster then + table.insert(cls_master, c) + else + table.insert(cls_other, c) + end + end + + -- Tile master windows + local master_area = { + x = wa.x, + y = wa.y, + width = nmaster > 0 and math.floor(wa.width * mwfact) or 0, + height = wa.height + } + + if not data[0] then data[0] = {} end + tile_column(wa, master_area, cls_master, useless_gap, transformation, data[0]) + + -- Tile other windows + local other_area = { + x = wa.x + master_area.width, + y = wa.y, + width = wa.width - master_area.width, + height = wa.height + } + + -- get column number for other windows + local ncol = math.min(tag.getncol(t), #cls_other) + + if ncol == 0 then ncol = 1 end + + -- split other windows to column groups + local last_small_column = ncol - #cls_other % ncol + local rows_min = math.floor(#cls_other / ncol) + + local client_index = 1 + local used = 0 + for i = 1, ncol do + local position = transformation.flip and ncol - i + 1 or i + local rows = i <= last_small_column and rows_min or rows_min + 1 + local column = {} + + for j = 1, rows do + table.insert(column, cls_other[client_index]) + client_index = client_index + 1 + end + + -- and tile + local column_area = cut_column(other_area, ncol, position) + if i == ncol then column_area.width = other_area.width - used end + used = used + column_area.width + + if not data[i] then data[i] = {} end + tile_column(wa, column_area, column, useless_gap, transformation, data[i]) + end +end + +-- Layout constructor +local function construct_layout(name, orientation) + return { + name = name, + -- @p screen number to tile + arrange = function(p) return tile(p, orientation) end + } +end + +-- Build layouts with different tile direction +uselesstile.right = construct_layout("uselesstile", "right") +uselesstile.left = construct_layout("uselesstileleft", "left") +uselesstile.bottom = construct_layout("uselesstilebottom", "bottom") +uselesstile.top = construct_layout("uselesstiletop", "top") + +-- Module aliase +uselesstile.arrange = uselesstile.right.arrange +uselesstile.name = uselesstile.right.name + +return uselesstile diff --git a/awesome/.config/awesome/lain/scripts/dfs b/awesome/.config/awesome/lain/scripts/dfs @@ -0,0 +1,387 @@ +#!/bin/bash +# +# Adapted from Eridan's "fs" (cleanup, enhancements and switch to bash/Linux) +# JM, 10/12/2004 +# +# Integrated into Lain in september 2013 +# https://github.com/copycat-killer/lain + +# Requires gawk + +# ------------------------------------------------------------------------- +# Decoding options +# ------------------------------------------------------------------------- +USAGE="Usage: $0 [-h(elp)] | [-n(arrow mode)] | [-w(eb output)]" + +NARROW_MODE=0 +WEB_OUTPUT=0 + +while [ $# -gt 0 ]; do +case "$1" in +"-h" ) +echo $USAGE +exit +;; +"-d" ) +DEBUG=1 +;; +"-n" ) +NARROW_MODE=1 +;; +"-w" ) +WEB_OUTPUT=1 +;; +* ) +echo $USAGE +exit +;; +esac +shift +done + +# ------------------------------------------------------------------------- +# Preparations +# ------------------------------------------------------------------------- +SYSTEM=`uname -s` +PATTERN="/" + +case "$SYSTEM" in +"Linux" ) +DF_COMMAND="/usr/bin/env df -k" +SORT_COMMAND="/usr/bin/env sort -k6" +AWK_COMMAND="/usr/bin/env awk" +;; +* ) +DF_COMMAND="/bin/df -k" +SORT_COMMAND="/usr/bin/sort -k6" +AWK_COMMAND="/usr/bin/env gawk" +;; +esac + +# ------------------------------------------------------------------------- +# Grabbing "df" result +# ------------------------------------------------------------------------- +DF_RESULT=`$DF_COMMAND` +if [ ! -z $DEBUG ]; then +echo "--> DF_RESULT:" +echo "$DF_RESULT" +echo "" +fi + +# ------------------------------------------------------------------------- +# Preprocessing "df" result, to join split logical lines +# ------------------------------------------------------------------------- +PREPROCESSING_RESULT=` \ + echo "$DF_RESULT" | $AWK_COMMAND -v PATTERN=$PATTERN \ + ' + NF == 1 { + printf ("%s", $0) + } + +NF == 5 { + printf ("%s\n", $0) +} + +NF > 6 { +} + +NF == 6 { + printf ("%s\n", $0) +}' +` +if [ ! -z $DEBUG ]; then +echo "--> PREPROCESSING_RESULT:" +echo "$PREPROCESSING_RESULT" +echo "" +fi + +SORTED_FILE_SYSTEMS_INFO=`echo "$PREPROCESSING_RESULT" | $SORT_COMMAND` + +if [ ! -z $DEBUG ]; then +echo "--> SORTED_FILE_SYSTEMS_INFO:" +echo "$SORTED_FILE_SYSTEMS_INFO" +echo "" +fi + +# ------------------------------------------------------------------------- +# Computing mount point max length +# ------------------------------------------------------------------------- +MOUNT_POINT_MAX_LENGTH=` \ + echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v PATTERN=$PATTERN \ + ' + BEGIN { + mount_point_length_max = 15; + } + +END { + printf ("%d", mount_point_length_max); +} + +$0 ~ PATTERN { +# printf ("$6 = %s\n", $6); + + mount_point = $6; +# printf ("mount_point = %s\n", mount_point); + + mount_point_length = length (mount_point); +# printf ("mount_point_length = %d\n", mount_point_length); + + if (mount_point_length > mount_point_length_max) + mount_point_length_max = mount_point_length; +}' +` +if [ ! -z $DEBUG ]; then +echo "MOUNT_POINT_MAX_LENGTH: $MOUNT_POINT_MAX_LENGTH" +fi + +# ------------------------------------------------------------------------- +# Computing mount point data max size +# ------------------------------------------------------------------------- +MOUNT_POINT_MAX_SIZE=` \ + echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v PATTERN=$PATTERN \ + ' + BEGIN { + mount_point_size_max = 0; + } + +END { + printf ("%d", mount_point_size_max); +} + +$0 ~ PATTERN { +# df -k shows k_bytes! +# printf ("$2 = %s\n", $2); + + mount_point_size = $2 * 1024; +# printf ("mount_point_size = %d\n", mount_point_size); + + if (mount_point_size > mount_point_size_max) + mount_point_size_max = mount_point_size; +}' +` +if [ ! -z $DEBUG ]; then +echo "MOUNT_POINT_MAX_SIZE: $MOUNT_POINT_MAX_SIZE" +fi + +# ------------------------------------------------------------------------- +# Let's go! +# ------------------------------------------------------------------------- +echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v DEBUG=$DEBUG -v PATTERN=$PATTERN -v NARROW_MODE=$NARROW_MODE -v LEFT_COLUMN=$MOUNT_POINT_MAX_LENGTH -v MAX_SIZE=$MOUNT_POINT_MAX_SIZE -v SCALE=$SCALE -v WEB_OUTPUT=$WEB_OUTPUT \ + ' +# {printf ("$0 = %s\n", $0);} +# {printf ("$1 = %s\n", $1);} +# {printf ("PATTERN = %s\n", PATTERN);} +# {printf ("LEFT_COLUMN = %s\n", LEFT_COLUMN);} + + BEGIN { + k_bytes = 1024.0; + m_bytes = 1024.0 * k_bytes; + g_bytes = 1024.0 * m_bytes; + t_bytes = 1024.0 * g_bytes; + + if (WEB_OUTPUT) + { + all_stars = "**************************************************"; + current_date = strftime ("%d-%m-%Y @ %H:%M:%S", localtime (systime ())); + free_threshold = 10; # % + + printf ("<!-- DEBUT CONTENU -->\n"); + + printf ( \ + "<A NAME=\"top\"></A>\n" \ + "<P ALIGN=CENTER><SPAN CLASS=\"titleblue\">%s</SPAN><SPAN CLASS=\"textbold\"> -- STATUS OF <SPAN CLASS=\"titlered\">ALCOR</SPAN> FILE SYSTEMS</SPAN></P><BR>\n", + current_date ) + + printf ("<TABLE WIDTH=\"100%%\" BORDER=1>\n"); + + printf ( \ + "<TR>\n" \ + "<TD ALIGN=LEFT><STRONG>Mount point</STRONG></TD>\n" \ + "<TD ALIGN=CENTER><STRONG>%% Usato (<SPAN CLASS=\"titleblue\">*</SPAN>)" \ + " - %% Free (<SPAN CLASS=\"titlegreen\">*</SPAN>)</STRONG></TD>\n" \ + "<TD ALIGN=CENTER><STRONG>%% Used</STRONG></TD>\n" \ + "<TD ALIGN=CENTER><STRONG>Free</STRONG></TD>\n" \ + "<TD ALIGN=CENTER><STRONG>Total</STRONG></TD>\n" \ + "</TR>\n" ); + } + else + { + narrow_margin = " "; +# printf ("%-*s", LEFT_COLUMN + 2, "Mount point"); + if (NARROW_MODE) + printf ("\n%s", narrow_margin); + else + printf ("%-*s", LEFT_COLUMN + 2, ""); + print " Used Free Total "; + if (! NARROW_MODE) + print ""; + } + } + +END { + if (WEB_OUTPUT) + { + printf ("</TABLE>\n"); + + printf ("<!-- FIN CONTENU -->\n"); + } + else + { + if (NARROW_MODE) + printf ("%s", narrow_margin); + else + printf ("%-*s", LEFT_COLUMN + 2, ""); + print "|----|----|----|----|----|----|----|----|----|----|" + if (NARROW_MODE) + printf ("\n%s", narrow_margin); + else + printf ("%-*s", LEFT_COLUMN + 2, ""); + print "0 10 20 30 40 50 60 70 80 90 100"; + print ""; + } +} + +$0 ~ PATTERN { + + if (index ($0, "members") == 0 && index ($0, "Download") == 0 && index ($0, "admin") == 0) + { +# df -k shows k_bytes! + + total_size = $2 * k_bytes; + free_size = $4 * k_bytes; + percentage_occupied = substr($5, 0, 3); + mount_point = $6; + + percentage_free = int (100 - percentage_occupied); + +# reduction_factor: 2 + stars_number = int (percentage_occupied / 2); + + if (WEB_OUTPUT) + { + posGroup = index (mount_point, "scratch"); + if (posGroup == 0) + posGroup = index (mount_point, "u1"); + if (posGroup == 0) + posGroup = index (mount_point, "u2"); + if (posGroup == 0) + posGroup = index (mount_point, "u4"); + if (posGroup == 0) + posGroup = index (mount_point, "u5"); + + printf ("<TR>\n"); + + if (posGroup > 0 || percentage_free < free_threshold) + { + if (percentage_free < free_threshold) + { + class = "titlered"; + if (posGroup == 0) + posGroup = 1; # to display the whole mount_point in this color anyway + } + else if ((index (mount_point, "scratch") != 0) || (index (mount_point, "u1") != 0) || (index (mount_point, "u2") != 0)) + { + class = "titleorange"; + posGroup = 1; # to display the whole mount_point in this color + } + else if ((index (mount_point, "u4") != 0) || (index (mount_point, "u5") != 0)) + { + class = "titlebrown"; + posGroup = 1; # to display the whole mount_point in this color + } + + printf ( \ + "<TD ALIGN=LEFT>%s<SPAN CLASS=\"%s\">%s</SPAN></TD>\n", + substr (mount_point, 1, posGroup - 1), + class, + substr (mount_point, posGroup) ); + } + else + { + printf ("<TD ALIGN=LEFT>%s</TD>\n", mount_point); + } + + printf ( \ + "<TD ALIGN=CENTER><SPAN CLASS=\"titleblue\">%s</SPAN><SPAN CLASS=\"titlegreen\">%s</SPAN></TD>\n", + substr (all_stars, 1, stars_number), substr (all_stars, stars_number + 1, 49) ); + + if (percentage_free < free_threshold) + { + color_beginning = "<SPAN CLASS=\"titlered\">"; + color_end = "</SPAN>" + } + else + { + color_beginning = ""; + color_end = "" + } + + if (total_size > 1 * t_bytes) + printf ( \ + "<TD ALIGN=RIGHT>%s%3d%%%s</TD><TD ALIGN=RIGHT>%5.1f Tb</TD><TD ALIGN=RIGHT>%5.1f Tb</TD>\n", \ + color_beginning, percentage_occupied, color_end, free_size / t_bytes, total_size / t_bytes \ + ); + else if (total_size > 1 * g_bytes) + printf ( \ + "<TD ALIGN=RIGHT>%s%3d%%%s</TD><TD ALIGN=RIGHT>%5.1f Gb</TD><TD ALIGN=RIGHT>%5.1f Gb</TD>\n", \ + color_beginning, percentage_occupied, color_end, free_size / g_bytes, total_size / g_bytes \ + ); + else if (total_size > 1 * m_byptes) + printf ( \ + "<TD ALIGN=RIGHT>%s%3d%%%s</TD><TD ALIGN=RIGHT>%5.1f Mb</TD><TD ALIGN=RIGHT>%5.1f Mb</TD>\n", \ + color_beginning, percentage_occupied, color_end, free_size / m_bytes, total_size / m_bytes \ + ); + else + printf ( \ + "<TD ALIGN=RIGHT>%s%3d%%%s</TD><TD ALIGN=RIGHT>%5.1f Kb</TD><TD ALIGN=RIGHT>%5.1f Kb</TD>\n", \ + color_beginning, percentage_occupied, color_end, free_size / k_bytes, total_size / k_bytes \ + ); + + printf ("</TR>\n"); + } + + else + { +# printf ("percentage_occupied = %d\n", percentage_occupied); +# printf ("percentage_free = %d\n", percentage_free); + + printf ("%-*s", LEFT_COLUMN + 2, mount_point); + if (NARROW_MODE) + printf ("\n%s", narrow_margin); + +# printf ("stars_number = %d\n", stars_number); + + printf ("|"); + for (i = 1; i <= stars_number && i <= 49; i++) + { + printf ("%s", "*"); + } + for (i = stars_number + 1; i <= 49; i++) + { + printf ("%s", "-"); + } + + + if (total_size > 1 * t_bytes) + printf ( \ + "| %3d%% %6.1f %6.1f Tb\n", \ + percentage_occupied, free_size / t_bytes, total_size / t_bytes \ + ); + else if (total_size > 1 * g_bytes) + printf ( \ + "| %3d%% %6.1f %6.1f Gb\n", \ + percentage_occupied, free_size / g_bytes, total_size / g_bytes \ + ); + else if (total_size > 1 * m_byptes) + printf ( \ + "| %3d%% %6.1f %6.1f Mb\n", \ + percentage_occupied, free_size / m_bytes, total_size / m_bytes \ + ); + else + printf ( \ + "| %3d%% %6.1f %6.1f Kb\n", \ + percentage_occupied, free_size / k_bytes, total_size / k_bytes \ + ); + } + } # if +}' diff --git a/awesome/.config/awesome/lain/scripts/mpdcover b/awesome/.config/awesome/lain/scripts/mpdcover @@ -0,0 +1,68 @@ +#!/bin/bash +# +# A simple cover fetcher script for current playing song on mpd. +# +# Original author: Wolfgang Mueller +# +# Adapted for Lain internal use. +# https://github.com/copycat-killer/lain +# +# You can use, edit and redistribute this script in any way you like. +# +# Dependencies: imagemagick. +# +# Usage: mpdcover <music_directory> <song_file> <cover_resize> <default_art> + +# Configuration------------------------------------------------------- + +# Music directory +MUSIC_DIR=$1 + +# Song file +file=$2 + +# Regex expression used for image search +IMG_REG="(Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif)$" + +# Path of temporary resized cover +TEMP_PATH="/tmp/mpdcover.png" + +# Resize cover +COVER_RESIZE="$3x$3" + +if [ $COVER_RESIZE == "x" ]; then + COVER_RESIZE="100x100" +fi + +# The default cover to use (optional) +DEFAULT_ART=$4 + +# Thumbnail background (transparent) +COVER_BACKGROUND="none" + +#-------------------------------------------------------------------- + +# check if anything is playing at all +[[ -z $file ]] && exit 1 + +# Art directory +art="$MUSIC_DIR/${file%/*}" + +# find every file that matches IMG_REG set the first matching file to be the +# cover. +cover="$(find "$art/" -maxdepth 1 -type f | egrep -i -m1 "$IMG_REG")" + +# when no cover is found, use DEFAULT_ART as cover +cover="${cover:=$DEFAULT_ART}" + +# check if art is available +if [[ -n $cover ]]; then + if [[ -n $COVER_RESIZE ]]; then + convert "$cover" -scale $COVER_RESIZE -gravity "center" -background "$COVER_BACKGROUND" "$TEMP_PATH" + cover="$TEMP_PATH" + fi +else + rm $TEMP_PATH +fi + +exit 0 diff --git a/awesome/.config/awesome/lain/util/dkjson.lua b/awesome/.config/awesome/lain/util/dkjson.lua @@ -0,0 +1,713 @@ +-- Module options: +local always_try_using_lpeg = true +local register_global_module_table = false +local global_module_name = 'json' + +--[==[ + +David Kolf's JSON module for Lua 5.1/5.2 + +Version 2.5 + + +For the documentation see the corresponding readme.txt or visit +<http://dkolf.de/src/dkjson-lua.fsl/>. + +You can contact the author by sending an e-mail to 'david' at the +domain 'dkolf.de'. + + +Copyright (C) 2010-2013 David Heiko Kolf + +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. + +--]==] + +-- global dependencies: +local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset = + pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset +local error, require, pcall, select = error, require, pcall, select +local floor, huge = math.floor, math.huge +local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat = + string.rep, string.gsub, string.sub, string.byte, string.char, + string.find, string.len, string.format +local strmatch = string.match +local concat = table.concat + +local json = { version = "dkjson 2.5" } + +if register_global_module_table then + _G[global_module_name] = json +end + +local _ENV = nil -- blocking globals in Lua 5.2 + +pcall (function() + -- Enable access to blocked metatables. + -- Don't worry, this module doesn't change anything in them. + local debmeta = require "debug".getmetatable + if debmeta then getmetatable = debmeta end +end) + +json.null = setmetatable ({}, { + __tojson = function () return "null" end +}) + +local function isarray (tbl) + local max, n, arraylen = 0, 0, 0 + for k,v in pairs (tbl) do + if k == 'n' and type(v) == 'number' then + arraylen = v + if v > max then + max = v + end + else + if type(k) ~= 'number' or k < 1 or floor(k) ~= k then + return false + end + if k > max then + max = k + end + n = n + 1 + end + end + if max > 10 and max > arraylen and max > n * 2 then + return false -- don't create an array with too many holes + end + return true, max +end + +local escapecodes = { + ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f", + ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t" +} + +local function escapeutf8 (uchar) + local value = escapecodes[uchar] + if value then + return value + end + local a, b, c, d = strbyte (uchar, 1, 4) + a, b, c, d = a or 0, b or 0, c or 0, d or 0 + if a <= 0x7f then + value = a + elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then + value = (a - 0xc0) * 0x40 + b - 0x80 + elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then + value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80 + elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then + value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80 + else + return "" + end + if value <= 0xffff then + return strformat ("\\u%.4x", value) + elseif value <= 0x10ffff then + -- encode as UTF-16 surrogate pair + value = value - 0x10000 + local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400) + return strformat ("\\u%.4x\\u%.4x", highsur, lowsur) + else + return "" + end +end + +local function fsub (str, pattern, repl) + -- gsub always builds a new string in a buffer, even when no match + -- exists. First using find should be more efficient when most strings + -- don't contain the pattern. + if strfind (str, pattern) then + return gsub (str, pattern, repl) + else + return str + end +end + +local function quotestring (value) + -- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js + value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8) + if strfind (value, "[\194\216\220\225\226\239]") then + value = fsub (value, "\194[\128-\159\173]", escapeutf8) + value = fsub (value, "\216[\128-\132]", escapeutf8) + value = fsub (value, "\220\143", escapeutf8) + value = fsub (value, "\225\158[\180\181]", escapeutf8) + value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8) + value = fsub (value, "\226\129[\160-\175]", escapeutf8) + value = fsub (value, "\239\187\191", escapeutf8) + value = fsub (value, "\239\191[\176-\191]", escapeutf8) + end + return "\"" .. value .. "\"" +end +json.quotestring = quotestring + +local function replace(str, o, n) + local i, j = strfind (str, o, 1, true) + if i then + return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1) + else + return str + end +end + +-- locale independent num2str and str2num functions +local decpoint, numfilter + +local function updatedecpoint () + decpoint = strmatch(tostring(0.5), "([^05+])") + -- build a filter that can be used to remove group separators + numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+" +end + +updatedecpoint() + +local function num2str (num) + return replace(fsub(tostring(num), numfilter, ""), decpoint, ".") +end + +local function str2num (str) + local num = tonumber(replace(str, ".", decpoint)) + if not num then + updatedecpoint() + num = tonumber(replace(str, ".", decpoint)) + end + return num +end + +local function addnewline2 (level, buffer, buflen) + buffer[buflen+1] = "\n" + buffer[buflen+2] = strrep (" ", level) + buflen = buflen + 2 + return buflen +end + +function json.addnewline (state) + if state.indent then + state.bufferlen = addnewline2 (state.level or 0, + state.buffer, state.bufferlen or #(state.buffer)) + end +end + +local encode2 -- forward declaration + +local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder, state) + local kt = type (key) + if kt ~= 'string' and kt ~= 'number' then + return nil, "type '" .. kt .. "' is not supported as a key by JSON." + end + if prev then + buflen = buflen + 1 + buffer[buflen] = "," + end + if indent then + buflen = addnewline2 (level, buffer, buflen) + end + buffer[buflen+1] = quotestring (key) + buffer[buflen+2] = ":" + return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder, state) +end + +local function appendcustom(res, buffer, state) + local buflen = state.bufferlen + if type (res) == 'string' then + buflen = buflen + 1 + buffer[buflen] = res + end + return buflen +end + +local function exception(reason, value, state, buffer, buflen, defaultmessage) + defaultmessage = defaultmessage or reason + local handler = state.exception + if not handler then + return nil, defaultmessage + else + state.bufferlen = buflen + local ret, msg = handler (reason, value, state, defaultmessage) + if not ret then return nil, msg or defaultmessage end + return appendcustom(ret, buffer, state) + end +end + +function json.encodeexception(reason, value, state, defaultmessage) + return quotestring("<" .. defaultmessage .. ">") +end + +encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state) + local valtype = type (value) + local valmeta = getmetatable (value) + valmeta = type (valmeta) == 'table' and valmeta -- only tables + local valtojson = valmeta and valmeta.__tojson + if valtojson then + if tables[value] then + return exception('reference cycle', value, state, buffer, buflen) + end + tables[value] = true + state.bufferlen = buflen + local ret, msg = valtojson (value, state) + if not ret then return exception('custom encoder failed', value, state, buffer, buflen, msg) end + tables[value] = nil + buflen = appendcustom(ret, buffer, state) + elseif value == nil then + buflen = buflen + 1 + buffer[buflen] = "null" + elseif valtype == 'number' then + local s + if value ~= value or value >= huge or -value >= huge then + -- This is the behaviour of the original JSON implementation. + s = "null" + else + s = num2str (value) + end + buflen = buflen + 1 + buffer[buflen] = s + elseif valtype == 'boolean' then + buflen = buflen + 1 + buffer[buflen] = value and "true" or "false" + elseif valtype == 'string' then + buflen = buflen + 1 + buffer[buflen] = quotestring (value) + elseif valtype == 'table' then + if tables[value] then + return exception('reference cycle', value, state, buffer, buflen) + end + tables[value] = true + level = level + 1 + local isa, n = isarray (value) + if n == 0 and valmeta and valmeta.__jsontype == 'object' then + isa = false + end + local msg + if isa then -- JSON array + buflen = buflen + 1 + buffer[buflen] = "[" + for i = 1, n do + buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder, state) + if not buflen then return nil, msg end + if i < n then + buflen = buflen + 1 + buffer[buflen] = "," + end + end + buflen = buflen + 1 + buffer[buflen] = "]" + else -- JSON object + local prev = false + buflen = buflen + 1 + buffer[buflen] = "{" + local order = valmeta and valmeta.__jsonorder or globalorder + if order then + local used = {} + n = #order + for i = 1, n do + local k = order[i] + local v = value[k] + if v then + used[k] = true + buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) + prev = true -- add a seperator before the next element + end + end + for k,v in pairs (value) do + if not used[k] then + buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) + if not buflen then return nil, msg end + prev = true -- add a seperator before the next element + end + end + else -- unordered + for k,v in pairs (value) do + buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) + if not buflen then return nil, msg end + prev = true -- add a seperator before the next element + end + end + if indent then + buflen = addnewline2 (level - 1, buffer, buflen) + end + buflen = buflen + 1 + buffer[buflen] = "}" + end + tables[value] = nil + else + return exception ('unsupported type', value, state, buffer, buflen, + "type '" .. valtype .. "' is not supported by JSON.") + end + return buflen +end + +function json.encode (value, state) + state = state or {} + local oldbuffer = state.buffer + local buffer = oldbuffer or {} + state.buffer = buffer + updatedecpoint() + local ret, msg = encode2 (value, state.indent, state.level or 0, + buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state) + if not ret then + error (msg, 2) + elseif oldbuffer == buffer then + state.bufferlen = ret + return true + else + state.bufferlen = nil + state.buffer = nil + return concat (buffer) + end +end + +local function loc (str, where) + local line, pos, linepos = 1, 1, 0 + while true do + pos = strfind (str, "\n", pos, true) + if pos and pos < where then + line = line + 1 + linepos = pos + pos = pos + 1 + else + break + end + end + return "line " .. line .. ", column " .. (where - linepos) +end + +local function unterminated (str, what, where) + return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where) +end + +local function scanwhite (str, pos) + while true do + pos = strfind (str, "%S", pos) + if not pos then return nil end + local sub2 = strsub (str, pos, pos + 1) + if sub2 == "\239\187" and strsub (str, pos + 2, pos + 2) == "\191" then + -- UTF-8 Byte Order Mark + pos = pos + 3 + elseif sub2 == "//" then + pos = strfind (str, "[\n\r]", pos + 2) + if not pos then return nil end + elseif sub2 == "/*" then + pos = strfind (str, "*/", pos + 2) + if not pos then return nil end + pos = pos + 2 + else + return pos + end + end +end + +local escapechars = { + ["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f", + ["n"] = "\n", ["r"] = "\r", ["t"] = "\t" +} + +local function unichar (value) + if value < 0 then + return nil + elseif value <= 0x007f then + return strchar (value) + elseif value <= 0x07ff then + return strchar (0xc0 + floor(value/0x40), + 0x80 + (floor(value) % 0x40)) + elseif value <= 0xffff then + return strchar (0xe0 + floor(value/0x1000), + 0x80 + (floor(value/0x40) % 0x40), + 0x80 + (floor(value) % 0x40)) + elseif value <= 0x10ffff then + return strchar (0xf0 + floor(value/0x40000), + 0x80 + (floor(value/0x1000) % 0x40), + 0x80 + (floor(value/0x40) % 0x40), + 0x80 + (floor(value) % 0x40)) + else + return nil + end +end + +local function scanstring (str, pos) + local lastpos = pos + 1 + local buffer, n = {}, 0 + while true do + local nextpos = strfind (str, "[\"\\]", lastpos) + if not nextpos then + return unterminated (str, "string", pos) + end + if nextpos > lastpos then + n = n + 1 + buffer[n] = strsub (str, lastpos, nextpos - 1) + end + if strsub (str, nextpos, nextpos) == "\"" then + lastpos = nextpos + 1 + break + else + local escchar = strsub (str, nextpos + 1, nextpos + 1) + local value + if escchar == "u" then + value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16) + if value then + local value2 + if 0xD800 <= value and value <= 0xDBff then + -- we have the high surrogate of UTF-16. Check if there is a + -- low surrogate escaped nearby to combine them. + if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then + value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16) + if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then + value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000 + else + value2 = nil -- in case it was out of range for a low surrogate + end + end + end + value = value and unichar (value) + if value then + if value2 then + lastpos = nextpos + 12 + else + lastpos = nextpos + 6 + end + end + end + end + if not value then + value = escapechars[escchar] or escchar + lastpos = nextpos + 2 + end + n = n + 1 + buffer[n] = value + end + end + if n == 1 then + return buffer[1], lastpos + elseif n > 1 then + return concat (buffer), lastpos + else + return "", lastpos + end +end + +local scanvalue -- forward declaration + +local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta) + local len = strlen (str) + local tbl, n = {}, 0 + local pos = startpos + 1 + if what == 'object' then + setmetatable (tbl, objectmeta) + else + setmetatable (tbl, arraymeta) + end + while true do + pos = scanwhite (str, pos) + if not pos then return unterminated (str, what, startpos) end + local char = strsub (str, pos, pos) + if char == closechar then + return tbl, pos + 1 + end + local val1, err + val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta) + if err then return nil, pos, err end + pos = scanwhite (str, pos) + if not pos then return unterminated (str, what, startpos) end + char = strsub (str, pos, pos) + if char == ":" then + if val1 == nil then + return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")" + end + pos = scanwhite (str, pos + 1) + if not pos then return unterminated (str, what, startpos) end + local val2 + val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta) + if err then return nil, pos, err end + tbl[val1] = val2 + pos = scanwhite (str, pos) + if not pos then return unterminated (str, what, startpos) end + char = strsub (str, pos, pos) + else + n = n + 1 + tbl[n] = val1 + end + if char == "," then + pos = pos + 1 + end + end +end + +scanvalue = function (str, pos, nullval, objectmeta, arraymeta) + pos = pos or 1 + pos = scanwhite (str, pos) + if not pos then + return nil, strlen (str) + 1, "no valid JSON value (reached the end)" + end + local char = strsub (str, pos, pos) + if char == "{" then + return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta) + elseif char == "[" then + return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta) + elseif char == "\"" then + return scanstring (str, pos) + else + local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos) + if pstart then + local number = str2num (strsub (str, pstart, pend)) + if number then + return number, pend + 1 + end + end + pstart, pend = strfind (str, "^%a%w*", pos) + if pstart then + local name = strsub (str, pstart, pend) + if name == "true" then + return true, pend + 1 + elseif name == "false" then + return false, pend + 1 + elseif name == "null" then + return nullval, pend + 1 + end + end + return nil, pos, "no valid JSON value at " .. loc (str, pos) + end +end + +local function optionalmetatables(...) + if select("#", ...) > 0 then + return ... + else + return {__jsontype = 'object'}, {__jsontype = 'array'} + end +end + +function json.decode (str, pos, nullval, ...) + local objectmeta, arraymeta = optionalmetatables(...) + return scanvalue (str, pos, nullval, objectmeta, arraymeta) +end + +function json.use_lpeg () + local g = require ("lpeg") + + if g.version() == "0.11" then + error "due to a bug in LPeg 0.11, it cannot be used for JSON matching" + end + + local pegmatch = g.match + local P, S, R = g.P, g.S, g.R + + local function ErrorCall (str, pos, msg, state) + if not state.msg then + state.msg = msg .. " at " .. loc (str, pos) + state.pos = pos + end + return false + end + + local function Err (msg) + return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall) + end + + local SingleLineComment = P"//" * (1 - S"\n\r")^0 + local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/" + local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0 + + local PlainChar = 1 - S"\"\\\n\r" + local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars + local HexDigit = R("09", "af", "AF") + local function UTF16Surrogate (match, pos, high, low) + high, low = tonumber (high, 16), tonumber (low, 16) + if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then + return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000) + else + return false + end + end + local function UTF16BMP (hex) + return unichar (tonumber (hex, 16)) + end + local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit)) + local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP + local Char = UnicodeEscape + EscapeSequence + PlainChar + local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string") + local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0)) + local Fractal = P"." * R"09"^0 + local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1 + local Number = (Integer * Fractal^(-1) * Exponent^(-1))/str2num + local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1) + local SimpleValue = Number + String + Constant + local ArrayContent, ObjectContent + + -- The functions parsearray and parseobject parse only a single value/pair + -- at a time and store them directly to avoid hitting the LPeg limits. + local function parsearray (str, pos, nullval, state) + local obj, cont + local npos + local t, nt = {}, 0 + repeat + obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state) + if not npos then break end + pos = npos + nt = nt + 1 + t[nt] = obj + until cont == 'last' + return pos, setmetatable (t, state.arraymeta) + end + + local function parseobject (str, pos, nullval, state) + local obj, key, cont + local npos + local t = {} + repeat + key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state) + if not npos then break end + pos = npos + t[key] = obj + until cont == 'last' + return pos, setmetatable (t, state.objectmeta) + end + + local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected") + local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected") + local Value = Space * (Array + Object + SimpleValue) + local ExpectedValue = Value + Space * Err "value expected" + ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp() + local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue) + ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp() + local DecodeValue = ExpectedValue * g.Cp () + + function json.decode (str, pos, nullval, ...) + local state = {} + state.objectmeta, state.arraymeta = optionalmetatables(...) + local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state) + if state.msg then + return nil, state.pos, state.msg + else + return obj, retpos + end + end + + -- use this function only once: + json.use_lpeg = function () return json end + + json.using_lpeg = true + + return json -- so you can get the module using json = require "dkjson".use_lpeg() +end + +if always_try_using_lpeg then + pcall (json.use_lpeg) +end + +return json diff --git a/awesome/.config/awesome/lain/util/init.lua b/awesome/.config/awesome/lain/util/init.lua @@ -0,0 +1,229 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Utilities section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local math = { sqrt = math.sqrt } +local mouse = mouse +local pairs = pairs +local string = { gsub = string.gsub } +local client = client +local screen = screen +local tonumber = tonumber + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +-- Lain utilities submodule +-- lain.util +local util = { _NAME = "lain.util" } + +-- Like awful.menu.clients, but only show clients of currently selected +-- tags. +function util.menu_clients_current_tags(menu, args) + -- List of currently selected tags. + local cls_tags = awful.tag.selectedlist(mouse.screen) + + -- Final list of menu items. + local cls_t = {} + + if cls_tags == nil then return nil end + + -- For each selected tag get all clients of that tag and add them to + -- the menu. A click on a menu item will raise that client. + for i = 1,#cls_tags + do + local t = cls_tags[i] + local cls = t:clients() + + for k, c in pairs(cls) + do + cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "", + function () + c.minimized = false + client.focus = c + c:raise() + end, + c.icon } + end + end + + -- No clients? Then quit. + if #cls_t <= 0 then return nil end + + -- menu may contain some predefined values, otherwise start with a + -- fresh menu. + if not menu then menu = {} end + + -- Set the list of items and show the menu. + menu.items = cls_t + local m = awful.menu.new(menu) + m:show(args) + return m +end + +-- Magnify a client: Set it to "float" and resize it. +function util.magnify_client(c) + if not awful.client.floating.get(c) then + awful.client.floating.set(c, true) + + local mg = screen[mouse.screen].geometry + local tag = awful.tag.selected(mouse.screen) + local mwfact = awful.tag.getmwfact(tag) + local g = {} + g.width = math.sqrt(mwfact) * mg.width + g.height = math.sqrt(mwfact) * mg.height + g.x = mg.x + (mg.width - g.width) / 2 + g.y = mg.y + (mg.height - g.height) / 2 + c:geometry(g) + else + awful.client.floating.set(c, false) + end +end + +-- Read the nice value of pid from /proc. +local function get_nice_value(pid) + local n = first_line('/proc/' .. pid .. '/stat') + if n == nil + then + -- This should not happen. But I don't want to crash, either. + return 0 + end + + -- Remove pid and tcomm. This is necessary because tcomm may contain + -- nasty stuff such as whitespace or additional parentheses... + n = string.gsub(n, '.*%) ', '') + + -- Field number 17 now is the nice value. + fields = split(n, ' ') + return tonumber(fields[17]) +end + +-- To be used as a signal handler for "focus" +-- This requires beautiful.border_focus{,_highprio,_lowprio}. +function util.niceborder_focus(c) + local n = get_nice_value(c.pid) + if n == 0 + then + c.border_color = beautiful.border_focus + elseif n < 0 + then + c.border_color = beautiful.border_focus_highprio + else + c.border_color = beautiful.border_focus_lowprio + end +end + +-- To be used as a signal handler for "unfocus" +-- This requires beautiful.border_normal{,_highprio,_lowprio}. +function util.niceborder_unfocus(c) + local n = get_nice_value(c.pid) + if n == 0 + then + c.border_color = beautiful.border_normal + elseif n < 0 + then + c.border_color = beautiful.border_normal_highprio + else + c.border_color = beautiful.border_normal_lowprio + end +end + +-- Non-empty tag browsing +-- direction in {-1, 1} <-> {previous, next} non-empty tag +function util.tag_view_nonempty(direction, sc) + local s = sc or mouse.screen or 1 + local scr = screen[s] + + for i = 1, #awful.tag.gettags(s) do + awful.tag.viewidx(direction,s) + if #awful.client.visible(s) > 0 then + return + end + end +end + +-- {{{ Dynamic tagging +-- +-- Add a new tag +function util.add_tag(mypromptbox) + awful.prompt.run({prompt="New tag name: "}, mypromptbox[mouse.screen].widget, + function(text) + if text:len() > 0 then + props = { selected = true } + tag = awful.tag.add(new_name, props) + tag.name = text + tag:emit_signal("property::name") + end + end) +end + +-- Rename current tag +-- @author: minism +function util.rename_tag(mypromptbox) + local tag = awful.tag.selected(mouse.screen) + awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget, + function(text) + if text:len() > 0 then + tag.name = text + tag:emit_signal("property::name") + end + end) +end + +-- Move current tag +-- pos in {-1, 1} <-> {previous, next} tag position +function util.move_tag(pos) + local tag = awful.tag.selected(mouse.screen) + local idx = awful.tag.getidx(tag) + if tonumber(pos) <= -1 then + awful.tag.move(idx - 1, tag) + else + awful.tag.move(idx + 1, tag) + end +end + +-- Remove current tag (if empty) +-- Any rule set on the tag shall be broken +function util.remove_tag() + local tag = awful.tag.selected(mouse.screen) + local prevtag = awful.tag.gettags(mouse.screen)[awful.tag.getidx(tag) - 1] + awful.tag.delete(tag, prevtag) +end +-- +-- }}} + +-- On the fly useless gaps change +function util.useless_gaps_resize(thatmuch) + beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch + awful.layout.arrange(mouse.screen) +end + +-- On the fly global border change +function util.global_border_resize(thatmuch) + beautiful.global_border_width = tonumber(beautiful.global_border_width) + thatmuch + awful.layout.arrange(mouse.screen) +end + +-- Check if an element exist on a table +function util.element_in_table(element, tbl) + for _, i in pairs(tbl) do + if i == element then + return true + end + end + return false +end + +return setmetatable(util, { __index = wrequire }) diff --git a/awesome/.config/awesome/lain/util/markup.lua b/awesome/.config/awesome/lain/util/markup.lua @@ -0,0 +1,69 @@ + +--[[ + + Licensed under MIT License + * (c) 2013, Luke Bonham + * (c) 2009, Uli Schlachter + * (c) 2009, Majic + +--]] + +local beautiful = require("beautiful") +local tostring = tostring +local setmetatable = setmetatable + +-- Lain markup util submodule +-- lain.util.markup +local markup = {} + +local fg = {} +local bg = {} + +-- Convenience tags. +function markup.bold(text) return '<b>' .. tostring(text) .. '</b>' end +function markup.italic(text) return '<i>' .. tostring(text) .. '</i>' end +function markup.strike(text) return '<s>' .. tostring(text) .. '</s>' end +function markup.underline(text) return '<u>' .. tostring(text) .. '</u>' end +function markup.monospace(text) return '<tt>' .. tostring(text) .. '</tt>' end +function markup.big(text) return '<big>' .. tostring(text) .. '</big>' end +function markup.small(text) return '<small>' .. tostring(text) .. '</small>' end + +-- Set the font. +function markup.font(font, text) + return '<span font="' .. tostring(font) .. '">' .. tostring(text) ..'</span>' +end + +-- Set the foreground. +function fg.color(color, text) + return '<span foreground="' .. tostring(color) .. '">' .. tostring(text) .. '</span>' +end + +-- Set the background. +function bg.color(color, text) + return '<span background="' .. tostring(color) .. '">' .. tostring(text) .. '</span>' +end + +-- Context: focus +function fg.focus(text) return fg.color(beautiful.fg_focus, text) end +function bg.focus(text) return bg.color(beautiful.bg_focus, text) end +function markup.focus(text) return bg.focus(fg.focus(text)) end + +-- Context: normal +function fg.normal(text) return fg.color(beautiful.fg_normal, text) end +function bg.normal(text) return bg.color(beautiful.bg_normal, text) end +function markup.normal(text) return bg.normal(fg.normal(text)) end + +-- Context: urgent +function fg.urgent(text) return fg.color(beautiful.fg_urgent, text) end +function bg.urgent(text) return bg.color(beautiful.bg_urgent, text) end +function markup.urgent(text) return bg.urgent(fg.urgent(text)) end + +markup.fg = fg +markup.bg = bg + +-- link markup.{fg,bg}(...) calls to markup.{fg,bg}.color(...) +setmetatable(markup.fg, { __call = function(_, ...) return markup.fg.color(...) end }) +setmetatable(markup.bg, { __call = function(_, ...) return markup.bg.color(...) end }) + +-- link markup(...) calls to markup.fg.color(...) +return setmetatable(markup, { __call = function(_, ...) return markup.fg.color(...) end }) diff --git a/awesome/.config/awesome/lain/util/separators.lua b/awesome/.config/awesome/lain/util/separators.lua @@ -0,0 +1,102 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, Luke Bonham + * (c) 2015, plotnikovanton + +--]] + +local wibox = require("wibox") +local beautiful = require("beautiful") +local gears = require("gears") + +-- Lain Cairo separators util submodule +-- lain.util.separators +local separators = {} + +local height = beautiful.awful_widget_height or 0 +local width = beautiful.separators_width or 9 + +-- [[ Arrow + +-- Right +function separators.arrow_right(col1, col2) + local widget = wibox.widget.base.make_widget() + + widget.fit = function(m, w, h) return width, height end + + widget.draw = function(mycross, wibox, cr, width, height) + if col2 ~= "alpha" then + cr:set_source_rgb(gears.color.parse_color(col2)) + cr:new_path() + cr:move_to(0, 0) + cr:line_to(width, height/2) + cr:line_to(width, 0) + cr:close_path() + cr:fill() + + cr:new_path() + cr:move_to(0, height) + cr:line_to(width, height/2) + cr:line_to(width, height) + cr:close_path() + cr:fill() + end + + if col1 ~= "alpha" then + cr:set_source_rgb(gears.color.parse_color(col1)) + cr:new_path() + cr:move_to(0, 0) + cr:line_to(width, height/2) + cr:line_to(0, height) + cr:close_path() + cr:fill() + end + end + + return widget +end + +-- Left +function separators.arrow_left(col1, col2) + local widget = wibox.widget.base.make_widget() + + widget.fit = function(m, w, h) return width, height end + + widget.draw = function(mycross, wibox, cr, width, height) + if col1 ~= "alpha" then + cr:set_source_rgb(gears.color.parse_color(col1)) + cr:new_path() + cr:move_to(width, 0) + cr:line_to(0, height/2) + cr:line_to(0, 0) + cr:close_path() + cr:fill() + + cr:new_path() + cr:move_to(width, height) + cr:line_to(0, height/2) + cr:line_to(0, height) + cr:close_path() + cr:fill() + end + + if col2 ~= "alpha" then + cr:new_path() + cr:move_to(width, 0) + cr:line_to(0, height/2) + cr:line_to(width, height) + cr:close_path() + + cr:set_source_rgb(gears.color.parse_color(col2)) + cr:fill() + end + end + + return widget +end + +-- ]] + +return separators diff --git a/awesome/.config/awesome/lain/widgets/abase.lua b/awesome/.config/awesome/lain/widgets/abase.lua @@ -0,0 +1,44 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer +local async = require("lain.asyncshell") +local wibox = require("wibox") + +local setmetatable = setmetatable + +-- Basic template for custom widgets +-- Asynchronous version +-- lain.widgets.abase + +local function worker(args) + local abase = {} + local args = args or {} + local timeout = args.timeout or 5 + local cmd = args.cmd or "" + local settings = args.settings or function() end + + abase.widget = wibox.widget.textbox('') + + function abase.update() + async.request(cmd, function(f) + output = f + if output ~= abase.prev then + widget = abase.widget + settings() + abase.prev = output + end + end) + end + + newtimer(cmd, timeout, abase.update) + + return setmetatable(abase, { __index = abase.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/alsa.lua b/awesome/.config/awesome/lain/widgets/alsa.lua @@ -0,0 +1,53 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. <anrxc@sysphere.org> + +--]] + +local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + +local wibox = require("wibox") + +local string = { match = string.match, + format = string.format } + +local setmetatable = setmetatable + +-- ALSA volume +-- lain.widgets.alsa +local alsa = { last_level = "0", last_status = "" } + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 5 + local settings = args.settings or function() end + + alsa.cmd = args.cmd or "amixer" + alsa.channel = args.channel or "Master" + alsa.widget = wibox.widget.textbox('') + + function alsa.update() + mixer = read_pipe(string.format("%s get %s", alsa.cmd, alsa.channel)) + l,s = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + + if alsa.last_level ~= l or alsa.last_status ~= s then + volume_now = { level = l, status = s } + alsa.last_level = l + alsa.last_status = s + + widget = alsa.widget + settings() + end + end + + timer_id = string.format("alsa-%s-%s", alsa.cmd, alsa.channel) + newtimer(timer_id, timeout, alsa.update) + + return setmetatable(alsa, { __index = alsa.widget }) +end + +return setmetatable(alsa, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/alsabar.lua b/awesome/.config/awesome/lain/widgets/alsabar.lua @@ -0,0 +1,177 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2013, Rman + +--]] + +local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local math = { modf = math.modf } +local mouse = mouse +local string = { format = string.format, + match = string.match, + rep = string.rep } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- ALSA volume bar +-- lain.widgets.alsabar +local alsabar = { + channel = "Master", + step = "2%", + + colors = { + background = beautiful.bg_normal, + mute = "#EB8F8F", + unmute = "#A4CE8A" + }, + + terminal = terminal or "xterm", + mixer = terminal .. " -e alsamixer", + + notifications = { + font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), + font_size = "11", + color = beautiful.fg_normal, + bar_size = 18, + screen = 1 + }, + + _current_level = 0, + _muted = false +} + +function alsabar.notify() + alsabar.update() + + local preset = { + title = "", + text = "", + timeout = 5, + screen = alsabar.notifications.screen, + font = alsabar.notifications.font .. " " .. + alsabar.notifications.font_size, + fg = alsabar.notifications.color + } + + if alsabar._muted + then + preset.title = alsabar.channel .. " - Muted" + else + preset.title = alsabar.channel .. " - " .. alsabar._current_level .. "%" + end + + int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size) + preset.text = "[" + .. string.rep("|", int) + .. string.rep(" ", alsabar.notifications.bar_size - int) + .. "]" + + if alsabar.followmouse then + preset.screen = mouse.screen + end + + if alsabar._notify ~= nil then + alsabar._notify = naughty.notify ({ + replaces_id = alsabar._notify.id, + preset = preset, + }) + else + alsabar._notify = naughty.notify ({ + preset = preset, + }) + end +end + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 5 + local settings = args.settings or function() end + local width = args.width or 63 + local height = args.heigth or 1 + local ticks = args.ticks or false + local ticks_size = args.ticks_size or 7 + local vertical = args.vertical or false + + alsabar.cmd = args.cmd or "amixer" + alsabar.channel = args.channel or alsabar.channel + alsabar.step = args.step or alsabar.step + alsabar.colors = args.colors or alsabar.colors + alsabar.notifications = args.notifications or alsabar.notifications + alsabar.followmouse = args.followmouse or false + + alsabar.bar = awful.widget.progressbar() + + alsabar.bar:set_background_color(alsabar.colors.background) + alsabar.bar:set_color(alsabar.colors.unmute) + alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } }) + alsabar.bar:set_width(width) + alsabar.bar:set_height(height) + alsabar.bar:set_ticks(ticks) + alsabar.bar:set_ticks_size(ticks_size) + alsabar.bar:set_vertical(vertical) + + function alsabar.update() + -- Get mixer control contents + local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel)) + + -- Capture mixer control state: [5%] ... ... [on] + local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + + if (volu and tonumber(volu) ~= alsabar._current_level) or (mute and string.match(mute, "on") ~= alsabar._muted) + then + alsabar._current_level = tonumber(volu) + alsabar.bar:set_value(alsabar._current_level / 100) + if not mute and tonumber(volu) == 0 or mute == "off" + then + alsabar._muted = true + alsabar.tooltip:set_text (" [Muted] ") + alsabar.bar:set_color(alsabar.colors.mute) + else + alsabar._muted = false + alsabar.tooltip:set_text(string.format(" %s:%s ", alsabar.channel, volu)) + alsabar.bar:set_color(alsabar.colors.unmute) + end + + volume_now = {} + volume_now.level = tonumber(volu) + volume_now.status = mute + settings() + end + end + + alsabar.bar:buttons (awful.util.table.join ( + awful.button ({}, 1, function() + awful.util.spawn(alsabar.mixer) + end), + awful.button ({}, 3, function() + awful.util.spawn(string.format("%s set %s toggle", alsabar.cmd, alsabar.channel)) + alsabar.update() + end), + awful.button ({}, 4, function() + awful.util.spawn(string.format("%s set %s %s+", alsabar.cmd, alsabar.channel, alsabar.step)) + alsabar.update() + end), + awful.button ({}, 5, function() + awful.util.spawn(string.format("%s set %s %s-", alsabar.cmd, alsabar.channel, alsabar.step)) + alsabar.update() + end) + )) + + timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel) + + newtimer(timer_id, timeout, alsabar.update) + + return alsabar +end + +return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/base.lua b/awesome/.config/awesome/lain/widgets/base.lua @@ -0,0 +1,42 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + +local wibox = require("wibox") + +local setmetatable = setmetatable + +-- Basic template for custom widgets +-- lain.widgets.base + +local function worker(args) + local base = {} + local args = args or {} + local timeout = args.timeout or 5 + local cmd = args.cmd or "" + local settings = args.settings or function() end + + base.widget = wibox.widget.textbox('') + + function base.update() + if output ~= base.prev then + output = read_pipe(cmd) + widget = base.widget + settings() + base.prev = output + end + end + + newtimer(cmd, timeout, base.update) + + return setmetatable(base, { __index = base.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/bat.lua b/awesome/.config/awesome/lain/widgets/bat.lua @@ -0,0 +1,136 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local newtimer = require("lain.helpers").newtimer +local first_line = require("lain.helpers").first_line + +local naughty = require("naughty") +local wibox = require("wibox") + +local math = { floor = math.floor } +local string = { format = string.format } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- Battery infos +-- lain.widgets.bat + +local function worker(args) + local bat = {} + local args = args or {} + local timeout = args.timeout or 30 + local battery = args.battery or "BAT0" + local ac = args.ac or "AC0" + local notify = args.notify or "on" + local settings = args.settings or function() end + + bat.widget = wibox.widget.textbox('') + + bat_notification_low_preset = { + title = "Battery low", + text = "Plug the cable!", + timeout = 15, + fg = "#202020", + bg = "#CDCDCD" + } + + bat_notification_critical_preset = { + title = "Battery exhausted", + text = "Shutdown imminent", + timeout = 15, + fg = "#000000", + bg = "#FFFFFF" + } + + function update() + bat_now = { + status = "Not present", + ac_status = "N/A", + perc = "N/A", + time = "N/A", + watt = "N/A" + } + + local bstr = "/sys/class/power_supply/" .. battery + local astr = "/sys/class/power_supply/" .. ac + local present = first_line(bstr .. "/present") + + if present == "1" + then + -- current_now(I)[uA], voltage_now(U)[uV], power_now(P)[uW] + local rate_current = tonumber(first_line(bstr .. "/current_now")) + local rate_voltage = tonumber(first_line(bstr .. "/voltage_now")) + local rate_power = tonumber(first_line(bstr .. "/power_now")) + + -- energy_now(P)[uWh], charge_now(I)[uAh] + local energy_now = tonumber(first_line(bstr .. "/energy_now") or + first_line(bstr .. "/charge_now")) + + -- energy_full(P)[uWh], charge_full(I)[uAh], + local energy_full = tonumber(first_line(bstr .. "/energy_full") or + first_line(bstr .. "/charge_full")) + + + local energy_percentage = tonumber(first_line(bstr .. "/capacity")) or + math.floor((energy_now / energy_full) * 100) + + bat_now.status = first_line(bstr .. "/status") or "N/A" + bat_now.ac_status = first_line(astr .. "/online") or "N/A" + + -- if rate = 0 or rate not defined skip the round + if not (rate_power and rate_power > 0) and + not (rate_current and rate_current > 0) and + not (bat_now.status == "Full") + then + return + end + + local rate_time = 0 + if bat_now.status == "Charging" then + rate_time = (energy_full - energy_now) / (rate_power or rate_current) + elseif bat_now.status == "Discharging" then + rate_time = energy_now / (rate_power or rate_current) + end + + local hours = math.floor(rate_time) + local minutes = math.floor((rate_time - hours) * 60) + local watt = rate_power and (rate_power / 1e6) or (rate_voltage * rate_current) / 1e12 + + bat_now.perc = string.format("%d", energy_percentage) + bat_now.time = string.format("%02d:%02d", hours, minutes) + bat_now.watt = string.format("%.2fW", watt) + end + + widget = bat.widget + settings() + + -- notifications for low and critical states + if bat_now.status == "Discharging" and notify == "on" and bat_now.perc then + local nperc = tonumber(bat_now.perc) or 100 + if nperc <= 5 then + bat.id = naughty.notify({ + preset = bat_notification_critical_preset, + replaces_id = bat.id, + }).id + elseif nperc <= 15 then + bat.id = naughty.notify({ + preset = bat_notification_low_preset, + replaces_id = bat.id, + }).id + end + end + end + + newtimer(battery, timeout, update) + + return setmetatable(bat, { __index = bat.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/borderbox.lua b/awesome/.config/awesome/lain/widgets/borderbox.lua @@ -0,0 +1,61 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wibox = require("awful.wibox") +local setmetatable = setmetatable + +-- Creates a thin wibox at a position relative to another wibox +-- lain.widgets.borderbox +local borderbox = {} + +local function worker(relbox, s, args) + local where = args.position or 'top' + local color = args.color or '#FFFFFF' + local size = args.size or 1 + local box = nil + local wiboxarg = { + position = nil, + bg = color + } + + if where == 'top' + then + wiboxarg.width = relbox.width + wiboxarg.height = size + box = wibox(wiboxarg) + box.x = relbox.x + box.y = relbox.y - size + elseif where == 'bottom' + then + wiboxarg.width = relbox.width + wiboxarg.height = size + box = wibox(wiboxarg) + box.x = relbox.x + box.y = relbox.y + relbox.height + elseif where == 'left' + then + wiboxarg.width = size + wiboxarg.height = relbox.height + box = wibox(wiboxarg) + box.x = relbox.x - size + box.y = relbox.y + elseif where == 'right' + then + wiboxarg.width = size + wiboxarg.height = relbox.height + box = wibox(wiboxarg) + box.x = relbox.x + relbox.width + box.y = relbox.y + end + + box.screen = s + return box +end + +return setmetatable(borderbox, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/calendar.lua b/awesome/.config/awesome/lain/widgets/calendar.lua @@ -0,0 +1,132 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local icons_dir = require("lain.helpers").icons_dir + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local io = { popen = io.popen } +local os = { date = os.date } +local mouse = mouse +local string = { format = string.format, + sub = string.sub, + gsub = string.gsub } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- Calendar notification +-- lain.widgets.calendar +local calendar = {} +local cal_notification = nil + +function calendar:hide() + if cal_notification ~= nil then + naughty.destroy(cal_notification) + cal_notification = nil + end +end + +function calendar:show(t_out, inc_offset, scr) + calendar:hide() + + local f, c_text + local offs = inc_offset or 0 + local tims = t_out or 0 + local today = tonumber(os.date('%d')) + + calendar.offset = calendar.offset + offs + + if offs == 0 or calendar.offset == 0 + then -- current month showing, today highlighted + calendar.offset = 0 + calendar.notify_icon = calendar.icons .. today .. ".png" + + -- bg and fg inverted to highlight today + f = io.popen(string.format("%s | sed -r -e 's/_\\x08//g' -e '0,/(^| )%d($| )/ s/(^| )%d($| )/\\1<b><span foreground=\"%s\" background=\"%s\">%d<\\/span><\\/b>\\2/'", + calendar.cal, today, today, calendar.bg, calendar.fg, today)) + + else -- no current month showing, no day to highlight + local month = tonumber(os.date('%m')) + local year = tonumber(os.date('%Y')) + + month = month + calendar.offset + + while month > 12 do + month = month - 12 + year = year + 1 + end + + while month < 1 do + month = month + 12 + year = year - 1 + end + + calendar.notify_icon = nil + f = io.popen(string.format('%s %s %s', calendar.cal, month, year)) + end + + c_text = "<tt><span font='" .. calendar.font .. " " + .. calendar.font_size .. "'><b>" + .. f:read() .. "</b>\n\n" + .. f:read() .. "\n" + .. f:read("*all"):gsub("\n*$", "") + .. "</span></tt>" + f:close() + + if calendar.followmouse then + scrp = mouse.screen + else + scrp = scr or calendar.scr_pos + end + + cal_notification = naughty.notify({ + text = c_text, + icon = calendar.notify_icon, + position = calendar.position, + fg = calendar.fg, + bg = calendar.bg, + timeout = tims, + screen = scrp + }) +end + +function calendar:attach(widget, args) + local args = args or {} + + calendar.cal = args.cal or "/usr/bin/cal" + calendar.icons = args.icons or icons_dir .. "cal/white/" + calendar.font = args.font or beautiful.font:gsub(" %d.*", "") + calendar.font_size = tonumber(args.font_size) or 11 + calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + calendar.bg = args.bg or beautiful.bg_normal or "#000000" + calendar.position = args.position or "top_right" + calendar.scr_pos = args.scr_pos or 1 + calendar.followmouse = args.followmouse or false + + calendar.fg = string.sub(calendar.fg, 1, 7) + calendar.bg = string.sub(calendar.bg, 1, 7) + + calendar.offset = 0 + calendar.notify_icon = nil + + widget:connect_signal("mouse::enter", function () calendar:show(0, 0, calendar.scr_pos) end) + widget:connect_signal("mouse::leave", function () calendar:hide() end) + widget:buttons(awful.util.table.join(awful.button({ }, 1, function () + calendar:show(0, -1, calendar.scr_pos) end), + awful.button({ }, 3, function () + calendar:show(0, 1, calendar.scr_pos) end), + awful.button({ }, 4, function () + calendar:show(0, -1, calendar.scr_pos) end), + awful.button({ }, 5, function () + calendar:show(0, 1, calendar.scr_pos) end))) +end + +return setmetatable(calendar, { __call = function(_, ...) return create(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/ccurr.lua b/awesome/.config/awesome/lain/widgets/contrib/ccurr.lua @@ -0,0 +1,82 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Aaron Lebo + +--]] + +local newtimer = require("lain.helpers").newtimer +local json = require("lain.util").dkjson + +local wibox = require("wibox") + +local string = { format = string.format } +local tonumber = tonumber + +-- Crypto currencies widget +-- lain.widgets.contrib.ccurr +local ccurr = {} + +-- Currently gets +-- * BTC/USD +-- * DOGE/USD +-- using Coinbase and Cryptsy APIs. + +-- requires http://dkolf.de/src/dkjson-lua.fsl/home +-- based upon http://awesome.naquadah.org/wiki/Bitcoin_Price_Widget + +local function get(url) + local f = io.popen('curl -m 5 -s "' .. url .. '"') + if not f then + return 0 + else + local s = f:read("*all") + f:close() + return s + end +end + +local function parse(j) + local obj, pos, err = json.decode(j, 1, nil) + if err then + return nil + else + return obj + end +end + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 600 + local btc_url = args.btc_url or "https://coinbase.com/api/v1/prices/buy" + local doge_url = args.doge_url or "http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=132" + local settings = args.settings or function() end + + ccurr.widget = wibox.widget.textbox('') + + local function update() + price_now = { + btc = "N/A", + doge = "N/A" + } + + btc = parse(get(btc_url)) + doge = parse(get(doge_url)) + + if btc and doge then + price_now.btc = tonumber(btc["subtotal"]["amount"]) + price_now.doge = tonumber(doge["return"]["markets"]["DOGE"]["lasttradeprice"]) + price_now.doge = string.format("%.4f", price_now.btc * price_now.doge) + end + + widget = ccurr.widget + settings() + end + + newtimer("ccurr", timeout, update) + + return ccurr.widget +end + +return setmetatable(ccurr, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/init.lua b/awesome/.config/awesome/lain/widgets/contrib/init.lua @@ -0,0 +1,19 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Users contributed widgets section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +local widgets = { _NAME = "lain.widgets.contrib" } + +return setmetatable(widgets, { __index = wrequire }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/kbdlayout.lua b/awesome/.config/awesome/lain/widgets/contrib/kbdlayout.lua @@ -0,0 +1,82 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, Dario Gjorgjevski + +--]] + +local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + +local wibox = require("wibox") +local awful = require("awful") + +local string = { match = string.match } + +local setmetatable = setmetatable + +-- Keyboard layout switcher +-- lain.widgets.contrib.kblayout + +local function worker (args) + local kbdlayout = {} + kbdlayout.widget = wibox.widget.textbox('') + + local layouts = args.layouts + local settings = args.settings or function () end + local add_us_secondary = true + local timeout = args.timeout or 5 + local idx = 1 + + if args.add_us_secondary == false then add_us_secondary = false end + + -- Mouse bindings + kbdlayout.widget:buttons(awful.util.table.join( + awful.button({ }, 1, function () kbdlayout.next() end), + awful.button({ }, 3, function () kbdlayout.prev() end))) + + local function run_settings (layout, variant) + widget = kbdlayout.widget + kbdlayout_now = { layout=string.match(layout, "[^,]+"), -- Make sure to match the primary layout only. + variant=variant } + settings() + end + + function kbdlayout.update () + local status = read_pipe('setxkbmap -query') + + run_settings(string.match(status, "layout:%s*([^\n]*)"), + string.match(status, "variant:%s*([^\n]*)")) + end + + function kbdlayout.set (i) + idx = ((i - 1) % #layouts) + 1 -- Make sure to wrap around as needed. + local to_execute = 'setxkbmap ' .. layouts[idx].layout + + if add_us_secondary and not string.match(layouts[idx].layout, ",?us,?") then + to_execute = to_execute .. ",us" + end + + if layouts[idx].variant then + to_execute = to_execute .. ' ' .. layouts[idx].variant + end + + if os.execute(to_execute) then + run_settings(layouts[idx].layout, layouts[idx].variant) + end + end + + function kbdlayout.next () + kbdlayout.set(idx + 1) + end + + function kbdlayout.prev () + kbdlayout.set(idx - 1) + end + + newtimer("kbdlayout", timeout, kbdlayout.update) + return setmetatable(kbdlayout, { __index = kbdlayout.widget }) +end + +return setmetatable({}, { __call = function (_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/moc.lua b/awesome/.config/awesome/lain/widgets/contrib/moc.lua @@ -0,0 +1,109 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, anticlockwise <http://github.com/anticlockwise> + +--]] + +local helpers = require("lain.helpers") +local async = require("lain.asyncshell") + +local escape_f = require("awful.util").escape +local naughty = require("naughty") +local wibox = require("wibox") + +local io = { popen = io.popen } +local os = { execute = os.execute, + getenv = os.getenv } +local string = { format = string.format, + gmatch = string.gmatch } + +local setmetatable = setmetatable + +-- MOC audio player +-- lain.widgets.contrib.moc +local moc = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local cover_size = args.cover_size or 100 + local default_art = args.default_art or "" + local followmouse = args.followmouse or false + local settings = args.settings or function() end + + local mpdcover = helpers.scripts_dir .. "mpdcover" + + moc.widget = wibox.widget.textbox('') + + moc_notification_preset = { + title = "Now playing", + timeout = 6 + } + + helpers.set_map("current moc track", nil) + + function moc.update() + -- mocp -i will produce output like: + -- Artist: Travis + -- Album: The Man Who + -- etc. + async.request("mocp -i", function(f) + moc_now = { + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + elapsed = "N/A", + total = "N/A" + } + + for line in string.gmatch(f, "[^\n]+") do + for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do + if k == "State" then moc_now.state = v + elseif k == "File" then moc_now.file = v + elseif k == "Artist" then moc_now.artist = escape_f(v) + elseif k == "SongTitle" then moc_now.title = escape_f(v) + elseif k == "Album" then moc_now.album = escape_f(v) + elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v) + elseif k == "TotalTime" then moc_now.total = escape_f(v) + end + end + end + + moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist, + moc_now.album, moc_now.total, moc_now.title) + widget = moc.widget + settings() + + if moc_now.state == "PLAY" then + if moc_now.title ~= helpers.get_map("current moc track") then + helpers.set_map("current moc track", moc_now.title) + os.execute(string.format("%s %q %q %d %q", mpdcover, "", + moc_now.file, cover_size, default_art)) + + if followmouse then + moc_notification_preset.screen = mouse.screen + end + + moc.id = naughty.notify({ + preset = moc_notification_preset, + icon = "/tmp/mpdcover.png", + replaces_id = moc.id, + }).id + end + elseif moc_now.state ~= "PAUSE" then + helpers.set_map("current moc track", nil) + end + end) + end + + helpers.newtimer("moc", timeout, moc.update) + + return setmetatable(moc, { __index = moc.widget }) +end + +return setmetatable(moc, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/redshift.lua b/awesome/.config/awesome/lain/widgets/contrib/redshift.lua @@ -0,0 +1,79 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, blueluke <http://github.com/blueluke> + +--]] + +local awful = require("awful") +local os = os +local spawn = awful.util.spawn_with_shell + +local setmetatable = setmetatable + +-- Redshift +-- lain.widgets.contrib.redshift +local redshift = {} + +local attached = false -- true if attached to a widget +local active = false -- true if redshift is active +local running = false -- true if redshift was initialized +local update_fnct = function() end -- Function that is run each time redshift is toggled. See redshift:attach(). + + +local function init() + -- As there is no way to determine if redshift was previously + -- toggled off (i.e Awesome on-the-fly restart), kill redshift to make sure + os.execute("pkill redshift") + -- Remove existing color adjustment + spawn("redshift -x") + -- (Re)start redshift + spawn("redshift") + running = true + active = true +end + +function redshift:toggle() + if running then + -- Sending -USR1 toggles redshift (See project website) + os.execute("pkill -USR1 redshift") + active = not active + else + init() + end + update_fnct() +end + +function redshift:off() + if running and active then + redshift:toggle() + end +end + +function redshift:on() + if not active then + redshift:toggle() + end +end + +function redshift:is_active() + return active +end + +-- Attach to a widget +-- Provides a button which toggles redshift on/off on click +-- @param widget: Widget to attach to. +-- @param fnct: Function to be run each time redshift is toggled (optional). +-- Use it to update widget text or icons on status change. +function redshift:attach(widget, fnct) + update_fnct = fnct or function() end + if not attached then + init() + attached = true + update_fnct() + end + widget:buttons(awful.util.table.join( awful.button({}, 1, function () redshift:toggle() end) )) +end + +return setmetatable(redshift, { _call = function(_, ...) return create(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/task.lua b/awesome/.config/awesome/lain/widgets/contrib/task.lua @@ -0,0 +1,144 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Jan Xie + +--]] + +local icons_dir = require("lain.helpers").icons_dir + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local mouse = mouse +local io = io +local string = { len = string.len } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- Taskwarrior notification +-- lain.widgets.contrib.task +local task = {} + +local task_notification = nil + +function task:hide() + if task_notification ~= nil then + naughty.destroy(task_notification) + task_notification = nil + end +end + +function task:show(scr_pos) + task:hide() + + local f, c_text + + if task.followmouse then + local scrp = mouse.screen + else + local scrp = scr_pos or task.scr_pos + end + + f = io.popen('task') + c_text = "<span font='" + .. task.font .. " " + .. task.font_size .. "'>" + .. f:read("*all"):gsub("\n*$", "") + .. "</span>" + f:close() + + task_notification = naughty.notify({ title = "[task next]", + text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout, + screen = scrp + }) +end + +function task:prompt_add() + awful.prompt.run({ prompt = "Add task: " }, + mypromptbox[mouse.screen].widget, + function (...) + local f = io.popen("task add " .. ...) + c_text = "\n<span font='" + .. task.font .. " " + .. task.font_size .. "'>" + .. f:read("*all") + .. "</span>" + f:close() + + naughty.notify({ + text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout, + }) + end, + nil, + awful.util.getdir("cache") .. "/history_task_add") +end + +function task:prompt_search() + awful.prompt.run({ prompt = "Search task: " }, + mypromptbox[mouse.screen].widget, + function (...) + local f = io.popen("task " .. ...) + c_text = f:read("*all"):gsub(" \n*$", "") + f:close() + + if string.len(c_text) == 0 + then + c_text = "No results found." + else + c_text = "<span font='" + .. task.font .. " " + .. task.font_size .. "'>" + .. c_text + .. "</span>" + end + + naughty.notify({ + title = "[task next " .. ... .. "]", + text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout, + screen = mouse.screen + }) + end, + nil, + awful.util.getdir("cache") .. "/history_task") +end + +function task:attach(widget, args) + local args = args or {} + + task.font_size = tonumber(args.font_size) or 12 + task.font = beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) + task.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" + task.position = args.position or "top_right" + task.timeout = args.timeout or 7 + task.scr_pos = args.scr_pos or 1 + task.followmouse = args.followmouse or false + + task.notify_icon = icons_dir .. "/taskwarrior/task.png" + task.notify_icon_small = icons_dir .. "/taskwarrior/tasksmall.png" + + widget:connect_signal("mouse::enter", function () task:show(task.scr_pos) end) + widget:connect_signal("mouse::leave", function () task:hide() end) +end + +return setmetatable(task, { __call = function(_, ...) return create(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/tpbat/init.lua b/awesome/.config/awesome/lain/widgets/contrib/tpbat/init.lua @@ -0,0 +1,170 @@ + +--[[ + + tpbat.lua + Battery status widget for ThinkPad laptops that use SMAPI + lain.widgets.contrib.tpbat + + More on tp_smapi: http://www.thinkwiki.org/wiki/Tp_smapi + + Licensed under GNU General Public License v2 + * (c) 2013, Conor Heine + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local debug = { getinfo = debug.getinfo } +local newtimer = require("lain.helpers").newtimer +local first_line = require("lain.helpers").first_line +local beautiful = require("beautiful") +local naughty = require("naughty") +local wibox = require("wibox") + +local string = { format = string.format } +local math = { floor = math.floor } +local tostring = tostring +local setmetatable = setmetatable + +package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .. "?.lua;" .. package.path +local smapi = require("smapi") + +-- ThinkPad SMAPI-enabled battery info widget +-- lain.widgets.contrib.tpbat +local tpbat = { } +local tpbat_notification = nil + +function tpbat:hide() + if tpbat_notification ~= nil + then + naughty.destroy(tpbat_notification) + tpbat_notification = nil + end +end + +function tpbat:show(t_out) + tpbat:hide() + + local bat = self.bat + local t_out = t_out or 0 + + if bat == nil or not bat:installed() then return end + + local mfgr = bat:get('manufacturer') or "no_mfgr" + local model = bat:get('model') or "no_model" + local chem = bat:get('chemistry') or "no_chem" + local status = bat:get('state') or "nil" + local time = bat:remaining_time() + local msg = "\t" + + if status ~= "idle" and status ~= "nil" + then + if time == "N/A" + then + msg = "...Calculating time remaining..." + else + msg = time .. (status == "charging" and " until charged" or " remaining") + end + else + msg = "On AC Power" + end + + local str = string.format("%s : %s %s (%s)\n", bat.name, mfgr, model, chem) + .. string.format("\n%s \t\t\t %s", status:upper(), msg) + + tpbat_notification = naughty.notify({ + preset = { fg = beautiful.fg_normal }, + text = str, + timeout = t_out, + screen = client.focus and client.focus.screen or 1 + }) +end + +function tpbat.register(args) + local args = args or {} + local timeout = args.timeout or 30 + local battery = args.battery or "BAT0" + local settings = args.settings or function() end + + tpbat.bat = smapi:battery(battery) -- Create a new battery + local bat = tpbat.bat + + tpbat.widget = wibox.widget.textbox('') + + bat_notification_low_preset = { + title = "Battery low", + text = "Plug the cable!", + timeout = 15, + fg = "#202020", + bg = "#CDCDCD" + } + + bat_notification_critical_preset = { + title = "Battery exhausted", + text = "Shutdown imminent", + timeout = 15, + fg = "#000000", + bg = "#FFFFFF" + } + + if bat:get('state') == nil + then + local n = naughty.notify({ + preset = bat_notification_low_preset, + title = "SMAPI Battery Warning: Unable to read battery state!", + text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", + screen = client.focus and client.focus.screen or 1 + }) + end + + function update() + bat_now = { + status = "Not present", + perc = "N/A", + time = "N/A", + watt = "N/A" + } + + if bat:installed() + then + bat_now.status = bat:status() or "N/A" + bat_now.perc = bat:percent() + bat_now.time = bat:remaining_time() + -- bat_now.watt = string.format("%.2fW", (VOLTS * AMPS) / 1e12) + + -- notifications for low and critical states (when discharging) + if bat_now.status == "discharging" + then + if bat_now.perc <= 5 + then + tpbat.id = naughty.notify({ + preset = bat_notification_critical_preset, + replaces_id = tpbat.id, + screen = client.focus and client.focus.screen or 1 + }).id + elseif bat_now.perc <= 15 + then + tpbat.id = naughty.notify({ + preset = bat_notification_low_preset, + replaces_id = tpbat.id, + screen = client.focus and client.focus.screen or 1 + }).id + end + end + + bat_now.perc = tostring(bat_now.perc) + end + + widget = tpbat.widget + settings() + end + + newtimer("tpbat-" .. bat.name, timeout, update) + + widget:connect_signal('mouse::enter', function () tpbat:show() end) + widget:connect_signal('mouse::leave', function () tpbat:hide() end) + + return tpbat.widget +end + +return setmetatable(tpbat, { __call = function(_, ...) return tpbat.register(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/contrib/tpbat/smapi.lua b/awesome/.config/awesome/lain/widgets/contrib/tpbat/smapi.lua @@ -0,0 +1,102 @@ + +--[[ + + smapi.lua + Interface with thinkpad battery information + + Licensed under GNU General Public License v2 + * (c) 2013, Conor Heine + +--]] + +local first_line = require("lain.helpers").first_line + +local string = { format = string.format } +local tonumber = tonumber +local setmetatable = setmetatable + +local smapi = {} + +local apipath = "/sys/devices/platform/smapi" + +-- Most are readable values, but some can be written to (not implemented, yet?) +local readable = { + barcoding = true, + charging_max_current = true, + charging_max_voltage = true, + chemistry = true, + current_avg = true, + current_now = true, + cycle_count = true, + design_capacity = true, + design_voltage = true, + dump = true, + first_use_date = true, + force_discharge = false, + group0_voltage = true, + group1_voltage = true, + group2_voltage = true, + group3_voltage = true, + inhibit_charge_minutes = false, + installed = true, + last_full_capacity = true, + manufacture_date = true, + manufacturer = true, + model = true, + power_avg = true, + power_now = true, + remaining_capacity = true, + remaining_charging_time = true, + remaining_percent = true, + remaining_percent_error = true, + remaining_running_time = true, + remaining_running_time_now = true, + serial = true, + start_charge_thresh = false, + state = true, + stop_charge_thresh = false, + temperature = true, + voltage = true, +} + +function smapi:battery(name) + local bat = {} + + bat.name = name + bat.path = apipath .. "/" .. name + + function bat:get(item) + return self.path ~= nil and readable[item] and first_line(self.path .. "/" .. item) or nil + end + + function bat:installed() + return self:get("installed") == "1" + end + + function bat:status() + return self:get('state') + end + + -- Remaining time can either be time until battery dies or time until charging completes + function bat:remaining_time() + local time_val = bat_now.status == 'discharging' and 'remaining_running_time' or 'remaining_charging_time' + local mins_left = self:get(time_val) + + if mins_left:find("^%d+") == nil + then + return "N/A" + end + + local hrs = math.floor(mins_left / 60) + local min = mins_left % 60 + return string.format("%02d:%02d", hrs, min) + end + + function bat:percent() + return tonumber(self:get("remaining_percent")) + end + + return setmetatable(bat, {__metatable = false, __newindex = false}) +end + +return smapi diff --git a/awesome/.config/awesome/lain/widgets/cpu.lua b/awesome/.config/awesome/lain/widgets/cpu.lua @@ -0,0 +1,88 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local lines_match = require("lain.helpers").lines_match +local newtimer = require("lain.helpers").newtimer + +local wibox = require("wibox") + +local math = { ceil = math.ceil } +local string = { format = string.format, + gmatch = string.gmatch } +local tostring = tostring + +local setmetatable = setmetatable + +-- CPU usage +-- lain.widgets.cpu +local cpu = { core = {} } + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local settings = args.settings or function() end + + cpu.widget = wibox.widget.textbox('') + + function update() + -- Read the amount of time the CPUs have spent performing + -- different kinds of work. Read the first line of /proc/stat + -- which is the sum of all CPUs. + local times = lines_match("cpu","/proc/stat") + + for index,time in pairs(times) + do + local coreid = index - 1 + local core = cpu.core[coreid] or + { last_active = 0 , last_total = 0, usage = 0 } + local at = 1 + local idle = 0 + local total = 0 + + for field in string.gmatch(time, "[%s]+([^%s]+)") + do + -- 4 = idle, 5 = ioWait. Essentially, the CPUs have done + -- nothing during these times. + if at == 4 or at == 5 then + idle = idle + field + end + total = total + field + at = at + 1 + end + + local active = total - idle + + if core.last_active ~= active or core.last_total ~= total then + -- Read current data and calculate relative values. + local dactive = active - core.last_active + local dtotal = total - core.last_total + + local usage = math.ceil((dactive / dtotal) * 100) + + core.last_active = active + core.last_total = total + core.usage = usage + + -- Save current data for the next run. + cpu.core[coreid] = core; + end + end + + widget = cpu.widget + cpu_now = cpu.core + cpu_now.usage = cpu_now[0].usage + + settings() + end + + newtimer("cpu", timeout, update) + return cpu.widget +end + +return setmetatable(cpu, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/fs.lua b/awesome/.config/awesome/lain/widgets/fs.lua @@ -0,0 +1,121 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. <anrxc@sysphere.org> + * (c) 2009, Lucas de Vries <lucas@glacicle.com> + +--]] + +local helpers = require("lain.helpers") + +local beautiful = require("beautiful") +local wibox = require("wibox") +local naughty = require("naughty") + +local io = { popen = io.popen } +local pairs = pairs +local mouse = mouse +local string = { match = string.match, + format = string.format } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- File system disk space usage +-- lain.widgets.fs +local fs = {} +local fs_notification = nil + +function fs:hide() + if fs_notification ~= nil then + naughty.destroy(fs_notification) + fs_notification = nil + end +end + +function fs:show(t_out) + fs:hide() + + local ws = helpers.read_pipe(helpers.scripts_dir .. "dfs"):gsub("\n*$", "") + + if fs.followmouse then + fs.notification_preset.screen = mouse.screen + end + + fs_notification = naughty.notify({ + preset = fs.notification_preset, + text = ws, + timeout = t_out + }) +end + +-- Unit definitions +local unit = { ["mb"] = 1024, ["gb"] = 1024^2 } + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 600 + local partition = args.partition or "/" + local settings = args.settings or function() end + + fs.followmouse = args.followmouse or false + fs.notification_preset = args.notification_preset or { fg = beautiful.fg_normal } + + fs.widget = wibox.widget.textbox('') + + helpers.set_map(partition, false) + + function update() + fs_info = {} + fs_now = {} + local f = assert(io.popen("LC_ALL=C df -kP")) + + 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 .. " size_mb"] = string.format("%.1f", tonumber(s) / unit["mb"]) + fs_info[m .. " size_gb"] = string.format("%.1f", tonumber(s) / unit["gb"]) + fs_info[m .. " used_p"] = tonumber(p) + fs_info[m .. " avail_p"] = 100 - tonumber(p) + end + end + + f:close() + + fs_now.used = tonumber(fs_info[partition .. " used_p"]) or 0 + fs_now.available = tonumber(fs_info[partition .. " avail_p"]) or 0 + fs_now.size_mb = tonumber(fs_info[partition .. " size_mb"]) or 0 + fs_now.size_gb = tonumber(fs_info[partition .. " size_gb"]) or 0 + + widget = fs.widget + settings() + + if fs_now.used >= 99 and not helpers.get_map(partition) + then + naughty.notify({ + title = "warning", + text = partition .. " ran out!\nmake some room", + timeout = 8, + fg = "#000000", + bg = "#FFFFFF", + }) + helpers.set_map(partition, true) + else + helpers.set_map(partition, false) + end + end + + fs.widget:connect_signal('mouse::enter', function () fs:show(0) end) + fs.widget:connect_signal('mouse::leave', function () fs:hide() end) + + helpers.newtimer(partition, timeout, update) + + return setmetatable(fs, { __index = fs.widget }) +end + +return setmetatable(fs, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/imap.lua b/awesome/.config/awesome/lain/widgets/imap.lua @@ -0,0 +1,94 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local helpers = require("lain.helpers") +local async = require("lain.asyncshell") + +local naughty = require("naughty") +local wibox = require("wibox") + +local mouse = mouse +local string = { format = string.format, + gsub = string.gsub } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- Mail IMAP check +-- lain.widgets.imap + +local function worker(args) + local imap = {} + local args = args or {} + + local server = args.server + local mail = args.mail + local password = args.password + + local port = args.port or 993 + local timeout = args.timeout or 60 + local is_plain = args.is_plain or false + local followmouse = args.followmouse or false + local settings = args.settings or function() end + + local head_command = "curl --connect-timeout 3 -fsm 3" + local request = "-X 'SEARCH (UNSEEN)'" + + helpers.set_map(mail, 0) + + if not is_plain + then + password = helpers.read_pipe(password):gsub("\n", "") + end + + imap.widget = wibox.widget.textbox('') + + function update() + mail_notification_preset = { + icon = helpers.icons_dir .. "mail.png", + position = "top_left" + } + + if followmouse then + mail_notification_preset.screen = mouse.screen + end + + curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%q %s -k", + head_command, server, port, mail, password, request) + + async.request(curl, function(f) + _, mailcount = string.gsub(f, "%d+", "") + _ = nil + + widget = imap.widget + settings() + + if mailcount >= 1 and mailcount > helpers.get_map(mail) + then + if mailcount == 1 then + nt = mail .. " has one new message" + else + nt = mail .. " has <b>" .. mailcount .. "</b> new messages" + end + naughty.notify({ + preset = mail_notification_preset, + text = nt + }) + end + + helpers.set_map(mail, mailcount) + end) + + end + + helpers.newtimer(mail, timeout, update, true) + + return setmetatable(imap, { __index = imap.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/init.lua b/awesome/.config/awesome/lain/widgets/init.lua @@ -0,0 +1,20 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Widgets section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +local widgets = { _NAME = "lain.widgets" } + +return setmetatable(widgets, { __index = wrequire }) diff --git a/awesome/.config/awesome/lain/widgets/maildir.lua b/awesome/.config/awesome/lain/widgets/maildir.lua @@ -0,0 +1,105 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe +local spairs = require("lain.helpers").spairs + +local wibox = require("wibox") + +local awful = require("awful") +local util = require("lain.util") + +local io = { popen = io.popen } +local os = { getenv = os.getenv } +local pairs = pairs +local string = { len = string.len, + match = string.match } + +local setmetatable = setmetatable + +-- Maildir check +-- lain.widgets.maildir +local maildir = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 60 + local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail" + local ignore_boxes = args.ignore_boxes or {} + local settings = args.settings or function() end + local ext_mail_cmd = args.external_mail_cmd + + maildir.widget = wibox.widget.textbox('') + + function update() + if ext_mail_cmd ~= nil + then + awful.util.spawn(ext_mail_cmd) + end + + -- Find pathes to mailboxes. + local p = io.popen("find " .. mailpath .. + " -mindepth 1 -maxdepth 2 -type d" .. + " -not -name .git") + local boxes = {} + repeat + line = p:read("*l") + if line ~= nil + then + -- Find all files in the "new" subdirectory. For each + -- file, print a single character (no newline). Don't + -- match files that begin with a dot. + -- Afterwards the length of this string is the number of + -- new mails in that box. + local mailstring = read_pipe("find " .. line .. + "/new -mindepth 1 -type f " .. + "-not -name '.*' -printf a") + + -- Strip off leading mailpath. + local box = string.match(line, mailpath .. "/(.*)") + local nummails = string.len(mailstring) + if nummails > 0 + then + boxes[box] = nummails + end + end + until line == nil + + p:close() + + newmail = "no mail" + -- Count the total number of mails irrespective of where it was found + total = 0 + + for box, number in spairs(boxes) + do + -- Add this box only if it's not to be ignored. + if not util.element_in_table(box, ignore_boxes) + then + total = total + number + if newmail == "no mail" + then + newmail = box .. "(" .. number .. ")" + else + newmail = newmail .. ", " .. + box .. "(" .. number .. ")" + end + end + end + + widget = maildir.widget + settings() + end + + newtimer(mailpath, timeout, update, true) + return maildir.widget +end + +return setmetatable(maildir, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/mem.lua b/awesome/.config/awesome/lain/widgets/mem.lua @@ -0,0 +1,59 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local newtimer = require("lain.helpers").newtimer + +local wibox = require("wibox") + +local io = { lines = io.lines } +local math = { floor = math.floor } +local string = { gmatch = string.gmatch } + +local setmetatable = setmetatable + +-- Memory usage (ignoring caches) +-- lain.widgets.mem +local mem = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local settings = args.settings or function() end + + mem.widget = wibox.widget.textbox('') + + function update() + mem_now = {} + for line in io.lines("/proc/meminfo") + do + for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+") + do + if k == "MemTotal" then mem_now.total = math.floor(v / 1024) + elseif k == "MemFree" then mem_now.free = math.floor(v / 1024) + elseif k == "Buffers" then mem_now.buf = math.floor(v / 1024) + elseif k == "Cached" then mem_now.cache = math.floor(v / 1024) + elseif k == "SwapTotal" then mem_now.swap = math.floor(v / 1024) + elseif k == "SwapFree" then mem_now.swapf = math.floor(v / 1024) + end + end + end + + mem_now.used = mem_now.total - (mem_now.free + mem_now.buf + mem_now.cache) + mem_now.swapused = mem_now.swap - mem_now.swapf + + widget = mem.widget + settings() + end + + newtimer("mem", timeout, update) + + return mem.widget +end + +return setmetatable(mem, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/mpd.lua b/awesome/.config/awesome/lain/widgets/mpd.lua @@ -0,0 +1,128 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. <anrxc@sysphere.org> + +--]] + +local helpers = require("lain.helpers") +local async = require("lain.asyncshell") + +local escape_f = require("awful.util").escape +local naughty = require("naughty") +local wibox = require("wibox") + +local os = { execute = os.execute, + getenv = os.getenv } +local math = { floor = math.floor } +local mouse = mouse +local string = { format = string.format, + match = string.match, + gmatch = string.gmatch } + +local setmetatable = setmetatable + +-- MPD infos +-- lain.widgets.mpd +local mpd = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local password = args.password or "" + local host = args.host or "127.0.0.1" + local port = args.port or "6600" + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local cover_size = args.cover_size or 100 + local default_art = args.default_art or "" + local followmouse = args.followmouse or false + local echo_cmd = args.echo_cmd or "echo" + local settings = args.settings or function() end + + local mpdcover = helpers.scripts_dir .. "mpdcover" + local mpdh = "telnet://" .. host .. ":" .. port + local echo = echo_cmd .. " 'password " .. password .. "\nstatus\ncurrentsong\nclose'" + + mpd.widget = wibox.widget.textbox('') + + mpd_notification_preset = { + title = "Now playing", + timeout = 6 + } + + helpers.set_map("current mpd track", nil) + + function mpd.update() + async.request(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh, function (f) + mpd_now = { + state = "N/A", + file = "N/A", + name = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + date = "N/A", + time = "N/A", + elapsed = "N/A" + } + + for line in string.gmatch(f, "[^\n]+") do + for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do + if k == "state" then mpd_now.state = v + elseif k == "file" then mpd_now.file = v + elseif k == "Name" then mpd_now.name = escape_f(v) + elseif k == "Artist" then mpd_now.artist = escape_f(v) + elseif k == "Title" then mpd_now.title = escape_f(v) + elseif k == "Album" then mpd_now.album = escape_f(v) + elseif k == "Date" then mpd_now.date = escape_f(v) + elseif k == "Time" then mpd_now.time = v + elseif k == "elapsed" then mpd_now.elapsed = string.match(v, "%d+") + end + end + end + + mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist, + mpd_now.album, mpd_now.date, mpd_now.title) + widget = mpd.widget + settings() + + if mpd_now.state == "play" + then + if mpd_now.title ~= helpers.get_map("current mpd track") + then + helpers.set_map("current mpd track", mpd_now.title) + + if string.match(mpd_now.file, "http.*://") == nil + then -- local file + os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, + mpd_now.file, cover_size, default_art)) + current_icon = "/tmp/mpdcover.png" + else -- http stream + current_icon = default_art + end + + if followmouse then + mpd_notification_preset.screen = mouse.screen + end + + mpd.id = naughty.notify({ + preset = mpd_notification_preset, + icon = current_icon, + replaces_id = mpd.id, + }).id + end + elseif mpd_now.state ~= "pause" + then + helpers.set_map("current mpd track", nil) + end + end) + end + + helpers.newtimer("mpd", timeout, mpd.update) + + return setmetatable(mpd, { __index = mpd.widget }) +end + +return setmetatable(mpd, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/net.lua b/awesome/.config/awesome/lain/widgets/net.lua @@ -0,0 +1,94 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local helpers = require("lain.helpers") +local naughty = require("naughty") +local wibox = require("wibox") + +local string = { format = string.format, + gsub = string.gsub, + match = string.match } + +local setmetatable = setmetatable + +-- Network infos +-- lain.widgets.net + +local function worker(args) + local net = { last_t = 0, last_r = 0 } + + function net.get_device() + local ws = helpers.read_pipe("ip link show | cut -d' ' -f2,9") + ws = ws:match("%w+: UP") or ws:match("ppp%w+: UNKNOWN") + if ws then return ws:match("(%w+):") + else return "network off" end + end + + local args = args or {} + local timeout = args.timeout or 2 + local units = args.units or 1024 --kb + local notify = args.notify or "on" + local screen = args.screen or 1 + local settings = args.settings or function() end + local iface = args.iface or net.get_device() + + net.widget = wibox.widget.textbox('') + + helpers.set_map(iface, true) + + function update() + net_now = {} + + if iface == "" or string.match(iface, "network off") + then + iface = net.get_device() + end + + net_now.carrier = helpers.first_line(string.format('/sys/class/net/%s/carrier', iface)) or '0' + net_now.state = helpers.first_line(string.format('/sys/class/net/%s/operstate', iface)) or 'down' + + local now_t = helpers.first_line(string.format('/sys/class/net/%s/statistics/tx_bytes', iface)) or 0 + local now_r = helpers.first_line(string.format('/sys/class/net/%s/statistics/rx_bytes', iface)) or 0 + + if now_t ~= net.last_t or now_r ~= net.last_r then + net_now.sent = (now_t - net.last_t) / timeout / units + net_now.sent = string.gsub(string.format('%.1f', net_now.sent), ',', '.') + net_now.received = (now_r - net.last_r) / timeout / units + net_now.received = string.gsub(string.format('%.1f', net_now.received), ',', '.') + + widget = net.widget + settings() + + net.last_t = now_t + net.last_r = now_r + end + + if not string.match(net_now.carrier, "1") and notify == "on" + then + if helpers.get_map(iface) + then + naughty.notify({ + title = iface, + text = "no carrier", + icon = helpers.icons_dir .. "no_net.png", + screen = screen + }) + helpers.set_map(iface, false) + end + else + helpers.set_map(iface, true) + end + end + + helpers.newtimer(iface, timeout, update) + + return setmetatable(net, { __index = net.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/pulseaudio.lua b/awesome/.config/awesome/lain/widgets/pulseaudio.lua @@ -0,0 +1,49 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2016, Luke Bonham + +--]] + +local read_pipe = require("lain.helpers").read_pipe +local newtimer = require("lain.helpers").newtimer +local wibox = require("wibox") + +local string = { match = string.match, + format = string.format } + +local setmetatable = setmetatable + +-- PulseAudio volume +-- lain.widgets.pulseaudio +local pulseaudio = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 5 + local settings = args.settings or function() end + local scallback = args.scallback + + pulseaudio.cmd = args.cmd or string.format("pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p'") + pulseaudio.widget = wibox.widget.textbox('') + + function pulseaudio.update() + if scallback then pulseaudio.cmd = scallback() end + local s = read_pipe(pulseaudio.cmd) + + volume_now = {} + volume_now.left = tonumber(string.match(s, ":.-(%d+)%%")) + volume_now.right = tonumber(string.match(s, ":.-(%d+)%%")) + volume_now.muted = string.match(s, "muted: (%S+)") + + widget = pulseaudio.widget + settings() + end + + newtimer(string.format("pulseaudio-%s", timeout), timeout, pulseaudio.update) + + return setmetatable(pulseaudio, { __index = pulseaudio.widget }) +end + +return setmetatable(pulseaudio, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/sysload.lua b/awesome/.config/awesome/lain/widgets/sysload.lua @@ -0,0 +1,45 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local newtimer = require("lain.helpers").newtimer + +local wibox = require("wibox") + +local io = { open = io.open } +local string = { match = string.match } + +local setmetatable = setmetatable + +-- System load +-- lain.widgets.sysload +local sysload = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local settings = args.settings or function() end + + sysload.widget = wibox.widget.textbox('') + + function update() + local f = io.open("/proc/loadavg") + local ret = f:read("*all") + f:close() + + load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") + + widget = sysload.widget + settings() + end + + newtimer("sysload", timeout, update) + return sysload.widget +end + +return setmetatable(sysload, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/temp.lua b/awesome/.config/awesome/lain/widgets/temp.lua @@ -0,0 +1,49 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer + +local wibox = require("wibox") + +local io = { open = io.open } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- coretemp +-- lain.widgets.temp +local temp = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local tempfile = args.tempfile or "/sys/class/thermal/thermal_zone0/temp" + local settings = args.settings or function() end + + temp.widget = wibox.widget.textbox('') + + function update() + local f = io.open(tempfile) + if f ~= nil + then + coretemp_now = tonumber(f:read("*all")) / 1000 + f:close() + else + coretemp_now = "N/A" + end + + widget = temp.widget + settings() + end + + newtimer("coretemp", timeout, update) + + return temp.widget +end + +return setmetatable(temp, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/widgets/weather.lua b/awesome/.config/awesome/lain/widgets/weather.lua @@ -0,0 +1,144 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + +local async = require("lain.asyncshell") +local json = require("lain.util").dkjson +local lain_icons = require("lain.helpers").icons_dir + +local naughty = require("naughty") +local wibox = require("wibox") + +local math = { floor = math.floor } +local mouse = mouse +local string = { format = string.format, + gsub = string.gsub } + +local setmetatable = setmetatable + +-- OpenWeatherMap +-- current weather and X-days forecast +-- lain.widgets.weather + +local function worker(args) + local weather = {} + local args = args or {} + local APPID = args.APPID or "3e321f9414eaedbfab34983bda77a66e" -- lain default + local timeout = args.timeout or 900 -- 15 min + local timeout_forecast = args.timeout or 86400 -- 24 hrs + local current_call = args.current_call or "curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s&APPID=%s'" + local forecast_call = args.forecast_call or "curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s&APPID=%s'" + local city_id = args.city_id or 0 -- placeholder + local units = args.units or "metric" + local lang = args.lang or "en" + local cnt = args.cnt or 5 + local date_cmd = args.date_cmd or "date -u -d @%d +'%%a %%d'" + local icons_path = args.icons_path or lain_icons .. "openweathermap/" + local notification_preset = args.notification_preset or {} + local notification_text_fun = args.notification_text_fun or + function (wn) + local day = string.gsub(read_pipe(string.format(date_cmd, wn["dt"])), "\n", "") + local tmin = math.floor(wn["temp"]["min"]) + local tmax = math.floor(wn["temp"]["max"]) + local desc = wn["weather"][1]["description"] + + return string.format("<b>%s</b>: %s, %d - %d ", day, desc, tmin, tmax) + end + local weather_na_markup = args.weather_na_markup or " N/A " + local followmouse = args.followmouse or false + local settings = args.settings or function() end + + weather.widget = wibox.widget.textbox(weather_na_markup) + weather.icon_path = icons_path .. "na.png" + weather.icon = wibox.widget.imagebox(weather.icon_path) + + function weather.show(t_out) + weather.hide() + + if followmouse then + notification_preset.screen = mouse.screen + end + + if not weather.notification_text then + weather.forecast_update() + end + + weather.notification = naughty.notify({ + text = weather.notification_text, + icon = weather.icon_path, + timeout = t_out, + preset = notification_preset + }) + end + + function weather.hide() + if weather.notification then + naughty.destroy(weather.notification) + weather.notification = nil + end + end + + function weather.attach(obj) + obj:connect_signal("mouse::enter", function() + weather.show(0) + end) + obj:connect_signal("mouse::leave", function() + weather.hide() + end) + end + + function weather.forecast_update() + local cmd = string.format(forecast_call, city_id, units, lang, cnt, APPID) + async.request(cmd, function(f) + local pos, err + weather_now, pos, err = json.decode(f, 1, nil) + + if not err and weather_now and tonumber(weather_now["cod"]) == 200 then + weather.notification_text = '' + for i = 1, weather_now["cnt"] do + weather.notification_text = weather.notification_text .. + notification_text_fun(weather_now["list"][i]) + + if i < weather_now["cnt"] then + weather.notification_text = weather.notification_text .. "\n" + end + end + end + end) + end + + function weather.update() + local cmd = string.format(current_call, city_id, units, lang, APPID) + async.request(cmd, function(f) + local pos, err + weather_now, pos, err = json.decode(f, 1, nil) + + if not err and weather_now and tonumber(weather_now["cod"]) == 200 then + weather.icon_path = icons_path .. weather_now["weather"][1]["icon"] .. ".png" + widget = weather.widget + settings() + else + weather.icon_path = icons_path .. "na.png" + weather.widget:set_markup(weather_na_markup) + end + + weather.icon:set_image(weather.icon_path) + end) + end + + weather.attach(weather.widget) + + newtimer("weather-" .. city_id, timeout, weather.update) + newtimer("weather_forecast-" .. city_id, timeout, weather.forecast_update) + + return setmetatable(weather, { __index = weather.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/awesome/.config/awesome/lain/wiki/Home.md b/awesome/.config/awesome/lain/wiki/Home.md @@ -0,0 +1,34 @@ +Welcome to the Lain wiki! + +Dependencies +------------------ + +Package | Requested by | Reason of choice +--- | --- | --- +alsa-utils | ALSA widgets | / +curl | widgets accessing network resources | Simpler to install and use than LuaSocket. +imagemagick | album arts in [MPD](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. + +Installation +--------------- + +### Arch Linux + +[AUR package](https://aur.archlinux.org/packages/lain-git/) + +### Other distributions + + git clone https://github.com/copycat-killer/lain.git ~/.config/awesome/lain + +Usage +-------- + +First, include it into your `rc.lua`: + + local lain = require("lain") + +Then check out the submodules you want: + +- [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) +- [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) +- [Utilities](https://github.com/copycat-killer/lain/wiki/Utilities) +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/Layouts.md b/awesome/.config/awesome/lain/wiki/Layouts.md @@ -0,0 +1,327 @@ + + lain/layout + . + |-- termfair + |-- centerfair + |-- cascade + |-- cascadetile + |-- centerwork + |-- centerhwork + |-- centerworkd + |-- uselessfair + |-- uselesspiral + `-- uselesstile + +Just add your favourites to ``layouts`` table: + + layouts = + { + ... + lain.layout.termfair, + lain.layout.uselesstile, + ... + } + +Or set them on specific tags like this: + + awful.layout.set(lain.layout.uselessfair, tags[1][7]) + +How do layouts work? +========================= + +termfair +-------- + +I do a lot of work on terminals. The common tiling algorithms usually +maximize windows, so you'll end up with a terminal that has about 200 +columns or more. That's way too much. Have you ever read a manpage in a +terminal of this size? + +This layout restricts the size of each window. Each window will have the +same width but is variable in height. Furthermore, windows are +left-aligned. The basic workflow is as follows (the number above the +screen is the number of open windows, the number in a cell is the fixed +number of a client): + + (1) (2) (3) + +---+---+---+ +---+---+---+ +---+---+---+ + | | | | | | | | | | | | + | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> + | | | | | | | | | | | | + +---+---+---+ +---+---+---+ +---+---+---+ + + (4) (5) (6) + +---+---+---+ +---+---+---+ +---+---+---+ + | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | + +---+---+---+ -> +---+---+---+ -> +---+---+---+ + | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | + +---+---+---+ +---+---+---+ +---+---+---+ + +The first client will be located in the left column. When opening +another window, this new window will be placed in the left column while +moving the first window into the middle column. Once a row is full, +another row above it will be created. + +Default number of columns and rows are respectively taken from `nmaster` +and `ncol` values in `awful.tag`, but you can set your own. + +For example, this sets `termfair` to 3 columns and at least 1 row: + + lain.layout.termfair.nmaster = 3 + lain.layout.termfair.ncol = 1 + +centerfair +---------- + +Similar to `termfair`, but with fixed number of vertical columns. Cols are centerded until there are `nmaster` columns, then windows are stacked as slaves, with possibly `ncol` clients per column at most. + + (1) (2) (3) + +---+---+---+ +-+---+---+-+ +---+---+---+ + | | | | | | | | | | | | | + | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> + | | | | | | | | | | | | | + +---+---+---+ +-+---+---+-+ +---+---+---+ + + (4) (5) + +---+---+---+ +---+---+---+ + | | | 3 | | | 2 | 4 | + + 1 + 2 +---+ -> + 1 +---+---+ + | | | 4 | | | 3 | 5 | + +---+---+---+ +---+---+---+ + +Like `termfair`, default number of columns and rows are respectively taken from `nmaster` +and `ncol` values in `awful.tag`, but you can set your own. + +For example: + + lain.layout.centerfair.nmaster = 3 + lain.layout.centerfair.ncol = 1 + +cascade +------- + +Cascade all windows of a tag. + +You can control the offsets by setting these two variables: + + lain.layout.cascade.cascade_offset_x = 64 + lain.layout.cascade.cascade_offset_y = 16 + +The following reserves space for 5 windows: + + lain.layout.cascade.nmaster = 5 + +That is, no window will get resized upon the creation of a new window, +unless there's more than 5 windows. + +cascadetile +----------- + +Similar to `awful.layout.suit.tile` layout, however, clients in the slave +column are cascaded instead of tiled. + +Left column size can be set, otherwise is controlled by `mwfact` of the +tag. Additional windows will be opened in another column on the right. +New windows are placed above old windows. + +Whether the slave column is placed on top of the master window or not is +controlled by the value of `ncol`. A value of 1 means "overlapping slave column" +and anything else means "don't overlap windows". + +Usage example: + + lain.layout.cascadetile.cascade_offset_x = 2 + lain.layout.cascadetile.cascade_offset_y = 32 + lain.layout.cascadetile.extra_padding = 5 + lain.layout.cascadetile.nmaster = 5 + lain.layout.cascadetile.ncol = 1 + +`extra_padding` reduces the size of the master window if "overlapping +slave column" is activated. This allows you to see if there are any +windows in your slave column. + +Setting `cascade_offset_x` to a very small value or even 0 is reccommended to avoid wasting space. + +centerwork +---------- + +You start with one window, centered horizontally: + + +--------------------------+ + | +----------+ | + | | | | + | | | | + | | | | + | | MAIN | | + | | | | + | | | | + | | | | + | | | | + | +----------+ | + +--------------------------+ + +This is your main working window. You do most of the work right here. +Sometimes, you may want to open up additional windows. They're put in +the following four slots: + + +--------------------------+ + | +---+ +----------+ +---+ | + | | | | | | | | + | | 0 | | | | 1 | | + | | | | | | | | + | +---+ | MAIN | +---+ | + | +---+ | | +---+ | + | | | | | | | | + | | 2 | | | | 3 | | + | | | | | | | | + | +---+ +----------+ +---+ | + +--------------------------+ + +Yes, the number "four" is fixed. In total, you can only have five open +windows with this layout. Additional windows are not managed and set to +floating mode. **This is intentional**. + +You can set the order of the four auxiliary windows. This is the default +configuration: + + lain.layout.centerwork.top_left = 0 + lain.layout.centerwork.top_right = 1 + lain.layout.centerwork.bottom_left = 2 + lain.layout.centerwork.bottom_right = 3 + +This means: The bottom left slot will be occupied by the third window +(not counting the main window). Suppose you want your windows to appear +in this order: + + +--------------------------+ + | +---+ +----------+ +---+ | + | | | | | | | | + | | 3 | | | | 0 | | + | | | | | | | | + | +---+ | MAIN | +---+ | + | +---+ | | +---+ | + | | | | | | | | + | | 2 | | | | 1 | | + | | | | | | | | + | +---+ +----------+ +---+ | + +--------------------------+ + +This would require you to use these settings: + + lain.layout.centerwork.top_left = 3 + lain.layout.centerwork.top_right = 0 + lain.layout.centerwork.bottom_left = 2 + lain.layout.centerwork.bottom_right = 1 + +*Please note:* If you use Awesome's default configuration, navigation in +this layout may be very confusing. How do you get from the main window +to satellite ones depends on the order in which the windows are opened. +Thus, use of `awful.client.focus.bydirection()` is suggested. +Here's an example: + + globalkeys = awful.util.table.join( + ... + awful.key({ modkey }, "j", + function() + awful.client.focus.bydirection("down") + if client.focus then client.focus:raise() end + end), + awful.key({ modkey }, "k", + function() + awful.client.focus.bydirection("up") + if client.focus then client.focus:raise() end + end), + awful.key({ modkey }, "h", + function() + awful.client.focus.bydirection("left") + if client.focus then client.focus:raise() end + end), + awful.key({ modkey }, "l", + function() + awful.client.focus.bydirection("right") + if client.focus then client.focus:raise() end + end), + ... + ) + +centerhwork +----------- + +Same as `centerwork`, except that the main +window expands horizontally, and the 4 additional windows +are put ontop/below it, thus using the huge vertical space +much better. Useful if you have a screen turned 90°. + +centerworkd +----------- + +Same as `centerwork`, except that this version fills the slave-columns regardless of how many slave-clients are present. + +uselessfair, uselesspiral & uselesstile +--------------------------------------- +These are duplicates of the stock `fair`, `spiral` and `tile` layouts. + +However, "useless gaps" (see below) have been added. + +Useless gaps +============ + +Useless gaps are gaps between windows. They are "useless" because they +serve no special purpose despite increasing overview. I find it easier +to recognize window boundaries if windows are set apart a little bit. + +The `uselessfair` layout, for example, looks like this: + + +================+ + # # + # +---+ +---+ # + # | 1 | | | # + # +---+ | | # + # | 3 | # + # +---+ | | # + # | 2 | | | # + # +---+ +---+ # + # # + +================+ + +All of lain layouts provide useless gaps. To set the width of the gaps, +you have to add an item called `useless_gap_width` in your `theme.lua`. +If it doesn't exist, the width will default to 0. +Example: + + theme.useless_gap_width = 10 + +`uselesstile` patches +===================== + +xmonad-like +----------- + +If you want to have uselesstile behave like xmonad, with internal gaps two times wider than external ones, replace `lain/layout/uselesstile` with [this](https://gist.github.com/copycat-killer/9e56dcfbe66bfe14967c). + +inverted master +--------------- + +Want to invert master window position? Use [this](https://gist.github.com/copycat-killer/c59dc59c9f99d98218eb) version. You can set `single_gap` with `width` and `height` in your `theme.lua`, in order to define the window geometry when there's only one client, otherwise it goes maximized. An example: + + theme.single_gap = { width = 600, height = 100 } + +What about layout icons? +======================== + +They are located in ``lain/icons/layout``. + +To use them, add lines to your ``theme.lua`` like this: + + theme.lain_icons = os.getenv("HOME") .. "/.config/awesome/lain/icons/layout/default/" + theme.layout_termfair = theme.lain_icons .. "termfairw.png" + theme.layout_cascade = theme.lain_icons .. "cascadew.png" + theme.layout_cascadetile = theme.lain_icons .. "cascadetilew.png" + theme.layout_centerwork = theme.lain_icons .. "centerworkw.png" + +Credits goes to [Nicolas Estibals](https://github.com/nestibal) for creating +layout icons for default theme. + +You can use them as a template for your custom versions. + +[<- home](https://github.com/copycat-killer/lain/wiki) diff --git a/awesome/.config/awesome/lain/wiki/Utilities.md b/awesome/.config/awesome/lain/wiki/Utilities.md @@ -0,0 +1,182 @@ +separators +---------- + +Adds Cairo separators. + + local separators = lain.util.separators + +A separator function `separators.separator` takes two color arguments, defined as strings. `"alpha"` argument is allowed. [Example](https://github.com/copycat-killer/awesome-copycats/blob/master/rc.lua.powerarrow-darker#L255-256). + +You can customize height and width by setting `awful_widget_height` and `separators_width` in your `theme.lua`. Default values are 0 and 9, respectively. + +List of functions: + + +-- separators + | + |`-- arrow_right() Draw a right arrow. + |`-- arrow_left() Draw a left arrow. + +markup +------ + +Mades markup easier. + + local markup = lain.util.markup + +List of functions: + + +-- markup + | + |`-- bold() Set bold. + |`-- italic() Set italicized text. + |`-- strike() Set strikethrough text. + |`-- underline() Set underlined text. + |`-- monospace() Set monospaced text. + |`-- big() Set bigger text. + |`-- small() Set smaller text. + |`-- font() Set the font of the text. + | + |`--+ bg + | | + | |`-- color() Set background color. + | |`-- focus() Set focus background color. + | |`-- normal() Set normal background color. + | `-- urgent() Set urgent background color. + | + |`--+ fg + | | + | |`-- color() Set foreground color. + | |`-- focus() Set focus foreground color. + | |`-- normal() Set normal foreground color. + | `-- urgent() Set urgent foreground color. + | + |`-- focus() Set both foreground and background focus colors. + |`-- normal() Set both foreground and background normal colors. + `-- urgent() Set both foreground and background urgent colors. + +they all take one argument, which is the text to markup, except `font`, `fg.color` and `bg.color`: + + markup.font(font, text) + markup.fg.color(color, text) + markup.bg.color(color, text) + +`focus`, `normal` and `urgent` use `beautiful` variables. + +dynamic tagging +--------------- + +That is: + +- add a new tag; +- rename current tag; +- move current tag; +- remove current tag. + +If you delete a tag, any rule set on it shall be broken, so be careful. + +Use it with key bindings like these: + + awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag(mypromptbox) end), + awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), + awful.key({ modkey, "Shift" }, "Left", function () lain.util.move_tag(1) end), -- move to next tag + awful.key({ modkey, "Shift" }, "Right", function () lain.util.move_tag(-1) end), -- move to previous tag + awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end), + +**Note** that these function won't work properly with [Copland theme](https://github.com/copycat-killer/awesome-copycats) or any other configuration that already uses a dynamic tagging module like [Eminent](https://github.com/copycat-killer/awesome-copycats/tree/master/eminent). + +useless\_gaps\_resize +--------------------- + +Changes `beautiful.useless_gaps_width` on the fly. + +The function takes an integer argument, being the amount of pixel to add/remove to gaps. + +You could use it with these keybindings: + + -- On the fly useless gaps change + awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end), + awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end), + +where `altkey=Mod1`, or you could use it like this: + + mywidget:buttons(awful.util.table.join ( + awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end), + awful.button({}, 5, function() lain.util.useless_gaps_resize(1) end) + end) + )) + +so when hovering the mouse over `mywidget`, you can adjust useless gaps size by scrolling with the mouse wheel. + +tag\_view\_nonempty +------------------- + +This function lets you jump to the next/previous non-empty tag. +It takes two arguments: + +* `direction`: `1` for next non-empty tag, `-1` for previous. +* `sc`: Screen which the taglist is in. Default is `mouse.screen` or `1`. This + argument is optional. + +You can use it with key bindings like these: + + -- Non-empty tag browsing + awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end), + awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end), + +where `altkey = "Mod1"`. + +menu\_clients\_current\_tags +---------------------------- + +Similar to `awful.menu.clients`, but this menu only shows the clients +of currently visible tags. Use it with a key binding like this: + + awful.key({ "Mod1" }, "Tab", + function() + awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" } + awful.menu.menu_keys.up = { "Up", "k" } + lain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true }) + end), + +magnify\_client +--------------- + +Set a client to floating and resize it in the same way the "magnifier" +layout does it. Place it on the "current" screen (derived from the mouse +position). This allows you to magnify any client you wish, regardless of +the currently used layout. Use it with a client keybinding like this: + + clientkeys = awful.util.table.join( + ... + awful.key({ modkey, "Control" }, "m", lain.util.magnify_client), + ... + ) + +If you want to "de-magnify" it, just retype the keybinding. + +niceborder\_{focus, unfocus} +---------------------------- + +By default, your `rc.lua` contains something like this: + + client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) + client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) + +You can change it to this: + + client.connect_signal("focus", lain.util.niceborder_focus(c)) + client.connect_signal("unfocus", lain.util.niceborder_unfocus(c)) + +Now, when a client is focused or unfocused, Awesome will look up its +nice value in `/proc/<pid>/stat`. If it's less than 0, the client is +classified as "high priority"; if it's greater than 0, the client is +classified as "low priority". If it's equal to 0, nothing special +happens. + +This requires to define additional colors in your `theme.lua`. For example: + + theme.border_focus_highprio = "#FF0000" + theme.border_normal_highprio = "#A03333" + + theme.border_focus_lowprio = "#3333FF" + theme.border_normal_lowprio = "#333366" +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/Widgets.md b/awesome/.config/awesome/lain/wiki/Widgets.md @@ -0,0 +1,63 @@ +General usage +------------- + +Every widget is output by a `function`. + +For some widgets, `function` returns a `wibox.widget.textbox`, for others a table to be used for notification and update purposes. + +Every widget may take either a table or a list of variables as argument. + +If it takes a table, you have to define a function variable called `settings` in it, in order to make your customizations. + +To markup the textbox, call `widget:set_markup(...)` within `settings`. + +You can feed `set_markup` with predefined arguments, see the sections for all the details. + +`widget` is a textbox, so you can treat it like any other `wibox.widget.textbox`. + +Here follows an example: + + mycpu = lain.widgets.cpu({ + settings = function() + widget:set_markup("Cpu " .. cpu_now.usage) + end + }) + +If you want to see more complex applications, check [awesome-copycats](https://github.com/copycat-killer/awesome-copycats). + +Note +---- + +Some widgets use [asyncshell](https://github.com/copycat-killer/lain/blob/master/asyncshell.lua), which is based on `/bin/sh`. If you use multiple shells and [experience problems](https://github.com/copycat-killer/lain/issues/145), try re-setting your shell [here](https://github.com/copycat-killer/lain/blob/master/asyncshell.lua#L18). + +Index +----- + +- [abase](https://github.com/copycat-killer/lain/wiki/abase) +- [alsa](https://github.com/copycat-killer/lain/wiki/alsa) +- [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) +- [base](https://github.com/copycat-killer/lain/wiki/base) +- [bat](https://github.com/copycat-killer/lain/wiki/bat) +- [borderbox](https://github.com/copycat-killer/lain/wiki/borderbox) +- [calendar](https://github.com/copycat-killer/lain/wiki/calendar) +- [cpu](https://github.com/copycat-killer/lain/wiki/cpu) +- [fs](https://github.com/copycat-killer/lain/wiki/fs) +- [imap](https://github.com/copycat-killer/lain/wiki/imap) +- [maildir](https://github.com/copycat-killer/lain/wiki/maildir) +- [mem](https://github.com/copycat-killer/lain/wiki/mem) +- [mpd](https://github.com/copycat-killer/lain/wiki/mpd) +- [net](https://github.com/copycat-killer/lain/wiki/net) +- [pulseaudio](https://github.com/copycat-killer/lain/wiki/pulseaudio) +- [sysload](https://github.com/copycat-killer/lain/wiki/sysload) +- [temp](https://github.com/copycat-killer/lain/wiki/temp) +- [weather](https://github.com/copycat-killer/lain/wiki/weather) + +Users contributed +---------------- + +- [ccurr](https://github.com/copycat-killer/lain/wiki/ccurr) +- [kbdlayout](https://github.com/copycat-killer/lain/wiki/kbdlayout) +- [moc](https://github.com/copycat-killer/lain/wiki/moc) +- [redshift](https://github.com/copycat-killer/lain/wiki/redshift) +- [task](https://github.com/copycat-killer/lain/wiki/task) +- [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat) diff --git a/awesome/.config/awesome/lain/wiki/abase.md b/awesome/.config/awesome/lain/wiki/abase.md @@ -0,0 +1,36 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +The [asynchronous](https://github.com/copycat-killer/lain/issues/128) version of `base`: + + myasyncbase = lain.widgets.abase() + +Read [here](https://github.com/copycat-killer/lain/wiki/base) for the rest. + +Use case examples +======== +*Do you wrote a widget that could be useful to others as well? Feel free to add it here.* + +cmus +---- + +```lua +cmuswidget = lain.widgets.abase({ + cmd = "cmus-remote -Q", + settings = function() + cmus_now = { + state = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A" + } + + for w in string.gmatch(output, "(.-)tag") do + a, b = w:match("(%w+) (.-)\n") + cmus_now[a] = b + end + + -- customize here + widget:set_text(cmus_now.artist .. " - " .. cmus_now.title) + end +}) +``` +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/alsa.md b/awesome/.config/awesome/lain/wiki/alsa.md @@ -0,0 +1,64 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows and controls ALSA volume with a textbox. + + volumewidget = lain.widgets.alsa() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 5 +`cmd` | Alsa mixer command | string | "amixer" +`channel` | Mixer channel | string | "Master" +`settings` | User settings | function | empty function + +`cmd` is useful if you need to pass additional arguments to amixer. For instance, users with multiple sound cards may define `cmd = "amixer -c X"` in order to set amixer with card `X`. + +`settings` can use the following variables: + +Variable | Meaning | Type | Values +--- | --- | --- | --- +`volume_now.level` | Volume level | int | 0-100 +`volume_now.status` | Device status | string | "on", "off" + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`channel` | Alsa channel | string +`update` | Update `widget` | function + +You can control the widget with key bindings like these: + +```lua + -- ALSA volume control + awful.key({ altkey }, "Up", + function () + os.execute(string.format("amixer set %s 1%%+", volumewidget.channel)) + volumewidget.update() + end), + awful.key({ altkey }, "Down", + function () + os.execute(string.format("amixer set %s 1%%-", volumewidget.channel)) + volumewidget.update() + end), + awful.key({ altkey }, "m", + function () + os.execute(string.format("amixer set %s toggle", volumewidget.channel)) + volumewidget.update() + end), + awful.key({ altkey, "Control" }, "m", + function () + os.execute(string.format("amixer set %s 100%%", volumewidget.channel)) + volumewidget.update() + end), +``` + +where `altkey = "Mod1"`. + +Toggle mute issue +----------------- + +Problems unmuting PCM? Check [here](https://github.com/copycat-killer/awesome-copycats/issues/95). +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/alsabar.md b/awesome/.config/awesome/lain/wiki/alsabar.md @@ -0,0 +1,100 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows and controls alsa volume with a progressbar; provides tooltips, notifications, and color changes at mute/unmute switch. + + volume = lain.widgets.alsabar() + +* Left click: Launch `alsamixer` in your `terminal`. +* Right click: Mute/unmute. +* Scroll wheel: Increase/decrase volume. + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 5 +`settings` | User settings | function | empty function +`width` | Bar width | int | 63 +`height` | Bar height | int | 1 +`ticks` | Set bar ticks on | boolean | false +`ticks_size` | Ticks size | int | 7 +`vertical` | Set the bar vertical | boolean | false +`command` | ALSA mixer command | string | "amixer" +`channel` | Mixer channel | string | "Master" +`step` | Step at which volume is increased/decreased | string | "2%" +`colors` | Bar colors | table | see **colors** +`notifications` | Notifications settings | table | see **notifications** +`followmouse` | Notification behaviour | bool | false + +`command` is useful if you need to pass additional arguments to amixer. For instance, users with multiple sound cards may define `command = "amixer -c X"` in order to set amixer with card `X`. + +### colors + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`background` | Bar backgrund color | string | `beautiful.bg_normal` +`mute` | Bar mute color | string | "#EB8F8F" +`unmute` | Bar unmute color | string | "#A4CE8A" + +### notifications + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`font` | Notifications font | string | The one defined in `beautiful.font` +`font_size` | Notifications font size | string | "11" +`color` | Notifications color | string | `beautiful.fg_normal` +`bar_size` | Wibox height | int | 18 +`screen` | Notifications screen | int | 1 + +It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height. + +`settings` can use the following variables: + +Variable | Meaning | Type | Values +--- | --- | --- | --- +`volume_now.level` | Self explained | int | 0-100 +`volume_now.status` | Device status | string | "on", "off" +### output table + +Variable | Meaning | Type +--- | --- | --- +`bar` | The widget | `awful.widget.progressbar` +`channel` | Alsa channel | string +`card` | Alsa card | string +`step` | Increase/decrease step | string +`notify` | The notification | function + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen when the widget is hovered with the mouse. By setting `followmouse` to `true` it will be shown on the same screen containing the widget. + +You can control the widget with key bindings like these: + +```lua + -- ALSA volume control + awful.key({ altkey }, "Up", + function () + os.execute(string.format("amixer set %s %s+", volume.channel, volume.step)) + volume.update() + end), + awful.key({ altkey }, "Down", + function () + os.execute(string.format("amixer set %s %s-", volume.channel, volume.step)) + volume.update() + end), + awful.key({ altkey }, "m", + function () + os.execute(string.format("amixer set %s toggle", volume.channel)) + volume.update() + end), + awful.key({ altkey, "Control" }, "m", + function () + os.execute(string.format("amixer set %s 100%%", volume.channel)) + volume.update() + end), +``` + +where `altkey = "Mod1"`. + +Toggle mute issue +----------------- + +Problems unmuting PCM? Check [here](https://github.com/copycat-killer/awesome-copycats/issues/95). +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/base.md b/awesome/.config/awesome/lain/wiki/base.md @@ -0,0 +1,26 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +This is a simple template widget. + +Basically, all it does is to execute an input `cmd`, and to fill its textbox with the output. + + mybase = lain.widgets.base() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 5 +`cmd` | The command to execute | string | empty string +`settings` | User settings | function | empty function + +`settings` can use the string `output`, which is the output of `cmd`. + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`update` | Update `widget` | function + +The `update` function can be used to refresh the widget before `timeout` expires. diff --git a/awesome/.config/awesome/lain/wiki/bat.md b/awesome/.config/awesome/lain/wiki/bat.md @@ -0,0 +1,71 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows in a textbox the remaining time and percentage capacity of your laptop battery, as well as +the current wattage. + +Displays a notification when battery is low or critical. + + mybattery = lain.widgets.bat() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 30 +`battery` | Identifier of the battery | string | "BAT0" +`ac` | AC | string | "AC0" +`notify` | Enable notifications | string | "on" +`settings` | User settings | function | empty function + +To disable warning notifications, set `notify` to `"off"`. + +`settings` can use the `bat_now` table, which contains the following strings: + +- `status` ("Not present", "Charging", "Discharging"); +- `ac_status` (0 or 1, meaning absent/present); +- `perc`; +- `time`; +- `watt`. + +and can modify the following two tables, which will be the preset for the naughty notifications: +* `bat_notification_low_preset`(used if battery charge level <= 15) +* `bat_notification_critical_preset` (used if battery charge level <= 5) + +Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables they can contain. + +**Default definition:** +```lua +bat_notification_low_preset = { + title = "Battery low", + text = "Plug the cable!", + timeout = 15, + fg = "#202020", + bg = "#CDCDCD" +} +``` +```lua +bat_notification_critical_preset = { + title = "Battery exhausted", + text = "Shutdown imminent", + timeout = 15, + fg = "#000000", + bg = "#FFFFFF" +} +``` + +### output + +A textbox. + +### Notes +* Another common identifier for `ac` is `ACAD`. +* If your widget is always on "N/A" with default settings, then `BAT0` is not your battery file. Locate the right one in `/sys/class/power_supply/` and set `battery` properly. +For instance, with `BAT1`: + +```lua +batwidget = lain.widgets.bat({ + battery = "BAT1", + -- [...] +}) + +``` diff --git a/awesome/.config/awesome/lain/wiki/borderbox.md b/awesome/.config/awesome/lain/wiki/borderbox.md @@ -0,0 +1,49 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Creates a thin wibox at a position relative to another wibox. + +This allows to create "borders" for your wiboxes. + + lain.widget.borderbox(relbox, s, args) + +`relbox` and `s` (an integer being screen number) are required arguments, `args` is an optional table +which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`position` | Position of the additional box | string | "above" +`color` | Color of the additional box | string | `#FFFFFF` +`size` | Size in pixels of the additional box | int | 1 + +Possible values for `.position`: `top`, `bottom`, `left` and `right`. + +### Example usage + +Think of this as a wibox: + + [======================] + +If `args.position = "above"`, then you'll get an additional wibox below +the existing one: + + ________________________ + [======================] + +It'll match position and size of the existing wibox. + +If your main wiboxes are stored in a table called `mywibox` (one wibox +for each screen) and are located at the bottom of your screen, then this +adds a borderbox on top of them: + + -- Layout section + for s = 1, screen.count() do + ... + + -- Most likely, you'll want to do this as well: + awful.screen.padding(screen[s], "bottom") + + -- Create the box and place it above the existing box. + lain.widgets.borderbox(mywibox[s], s ) + + ... + end +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/calendar.md b/awesome/.config/awesome/lain/wiki/calendar.md @@ -0,0 +1,46 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Attaches a calendar notification to a widget. + + lain.widgets.calendar:attach(widget, args) + +- Left click: switch to previous month. +- Right click: switch to next month. + +`args` is an optional table which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`cal` | custom call for `cal` \* | string | "/usr/bin/cal" +`icons` | Path to calendar icons | string | [lain/icons/cal/white](https://github.com/copycat-killer/lain/tree/master/icons/cal/white) +`font` | Calendar font | string | `beautiful.font` +`font_size` | Calendar font size | int | 12 +`fg` | Calendar foreground color | string | `beautiful.fg_normal` +`bg` | Calendar background color | string | `beautiful.bg_normal` +`position` | Calendar position | string | "top_right" +`scr_pos` | Notification screen | int | 1 +`followmouse` | Notification behaviour | boolean | false + +\* `cal` program options may vary depending on the operating system: you may need to set this variable properly (`/usr/bin/cal -h` [for instance](https://github.com/copycat-killer/lain/pull/34)) in order to display the current day highlighting. + +`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify). + +Notification will show an icon displaying current day, and formatted output +from ``cal`` with current day highlighted. + +You can call the notification with a key binding like this: + + awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7) end), + +where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. + +You can also call it defining a notification screen with a third argument like this: + + awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7, 0, my_scr_number) end), + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen when the widget is hovered with the mouse. By setting `followmouse` to `true` it will be shown on the same screen containing the widget. + +### Note + +* Naughty notification requires `font` to be **monospaced**, in order to correctly display the output. +* If you have UTF-8 rendering issues in the popup, it's probably because `cal` always colors the output. Try setting `cal = "/usr/bin/cal --color=never"` diff --git a/awesome/.config/awesome/lain/wiki/ccurr.md b/awesome/.config/awesome/lain/wiki/ccurr.md @@ -0,0 +1,23 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows in a textbox the current prices of Bitcoin to USD and Dogecoin to USD using Coinbase and Cryptsy's APIs. + + ccurrwidget = lain.widgets.contrib.ccurr() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 600 +`btc_url` | URL to Json Bitcoin data | string | Coinbase API +`doge_url` | URL to Json Dogecoin data | string | Cryptsy API +`settings` | User settings | function | empty function + +`settings` can use the `price_now` table, which contains the following strings: + +- `btc`; +- `doge`. + +### output + +A textbox. +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/cpu.md b/awesome/.config/awesome/lain/wiki/cpu.md @@ -0,0 +1,21 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows in a textbox the current CPU usage, both in general and per core. + + mycpuusage = lain.widgets.cpu() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 +`settings` | User settings | function | empty function + +`settings` can use these strings: + +* `cpu_now.usage`, the general use percentage; +* `cpu_now[i].usage`, the i-th core use percentage, with `i` starting from 1. + +### output + +A textbox. diff --git a/awesome/.config/awesome/lain/wiki/fs.md b/awesome/.config/awesome/lain/wiki/fs.md @@ -0,0 +1,52 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows disk space usage for a set partition. + +Displays a notification when the partition is full or has low space. + + mypartition = lain.widgets.fs() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds -| int | 600 +`partition` | Partition to monitor | string | "/" +`notification_preset` | Notification preset | table | {fg = beautiful.fg_normal} +`followmouse` | Display the notification on mouse screen | boolean | false +`settings` | User settings | function | empty function + +`settings` can use the following `partition` related float values: `fs_now.used`, `fs_now.available`, `fs_now.size_mb`, `fs_now.size_gb`. + +Within `settings`, you can obtain other partition values from internal `fs_info` table. For each partition, there are four index: + +* `fs_info[other_partition .. " used_p"]` +* `fs_info[other_partition .. " avail_p"]` +* `fs_info[other_partition .. " size_mb"]` +* `fs_info[other_partition .. " size_gb"]` + +just like the variables of `fs_now`. See [here](https://github.com/copycat-killer/lain/issues/103) for an usage example. + +Also, `settings` can modify `fs_notification_preset` table. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: + + fs_notification_preset = { fg = beautiful.fg_normal } + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen when the widget is hovered with the mouse. By setting `followmouse` to `true` it will be shown on the same screen containing the widget. + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`show` | The notification | function + +You can display the notification with a key binding like this: + + awful.key({ altkey }, "h", function () mypartition.show(seconds, scr) end), + +where ``altkey = "Mod1"`` and ``show`` arguments, both optional, are: + +* `seconds`, notification time in seconds; +* `screen`, screen in which display the notification. + +**Note that** naughty notification requires `beautiful.font` or `fs_notification_preset.font` to be monospaced, in order to correctly display the output. +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/imap.md b/awesome/.config/awesome/lain/wiki/imap.md @@ -0,0 +1,73 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows mail count in a textbox fetching over IMAP. + + myimapcheck = lain.widgets.imap(args) + +New mails are notified like this: + + +--------------------------------------------+ + | +---+ | + | |\ /| donald@disney.org has 3 new messages | + | +---+ | + +--------------------------------------------+ + +The function takes a table as argument. Required table parameters are: + +Variable | Meaning | Type +--- | --- | --- +`server` | Mail server | string +`mail` | User mail | string +`password` | User password | string + +while the optional are: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`port` | IMAP port | int | 993 +`timeout` | Refresh timeout seconds | int | 60 +`is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false +`followmouse` | Notification behaviour | boolean | false +`settings` | User settings | function | empty function + +Let's focus better on `is_plain`. + +The reason why it's false by default is to discourage the habit of storing passwords in plain. + +So you can set your password in plain like this: + + myimapcheck = lain.widgets.imap({ + is_plain = true, + password = "myplainpassword", + [...] + }) + +and you'll have the same security provided by `~/.netrc`. + +**Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring): + + myimapcheck = lain.widgets.imap({ + password = "keyring get mymail", + [...] + }) + +When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. + +`settings` can use the value `mailcount`, an integer greater or equal to zero, and can modify `mail_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. + +Default definition: + + mail_notification _preset = { + icon = lain/icons/mail.png, + position = "top_left" + } + +Note that `mailcount` is 0 either if there are no new mails or credentials are invalid, so make sure you get the right settings. + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen. By setting `followmouse` to `true` it will be shown on the current mouse screen. + +***This widget is asynchronous***, so you can have multiple instances at the same time. + +### output + +A textbox. +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/kbdlayout.md b/awesome/.config/awesome/lain/wiki/kbdlayout.md @@ -0,0 +1,70 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows and controls keyboard layouts and variants using `setxkbmap`. + + mykbdlayout = lain.widgets.contrib.kbdlayout() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`layouts` | Keyboard layouts and variants to switch between | table | **none** +`add_us_secondary` | Whether to add `us` as a secondary layout | boolean | true +`timeout` | Refresh timeout (in seconds) | int | 10 +`settings` | User settings | function | empty function + +- `layouts` + + A table (array) which contains tables with keys indicating layout and (optionally) variant. This argument is **mandatory**. + +- `add_us_secondary` + + A boolean controlling whether to add `us` as a secondary layout. This is needed in order for keyboard shortcuts to work in certain applications, i.e. Firefox, while using a non-US keyboard layout. + +- `timeout` + + An integer which determines the interval at which the widget will be updated, in case the keyboard layout was changed by other means. + +- `settings` + + A "callback" function in which the user is expected to set the text widget up. The widget itself is available as the global variable `widget`, while layout information is available as `kbdlayout_now`. `kbdlayout_now` contains two keys, `layout` containing the primary layout, and `variant`, containing the variant. If there is no variant, `variant` is `nil`. + +## output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget (textbox) | `awful.widget.textbox` +`update` | Function to update the widget and call `settings` | function +`set` | Function taking an index as an argument to manually set the layout given by that index | function +`next` | Change to the next layout | function +`prev` | Change to the prev layout | function + +## usage + +The textbox can be added to the layout via standard means: + + right_layout:add(mykbdlayout) + +By default, left-clicking the textbox calls `next`, and right-clicking calls `prev`. You can set up additional key- or mouse-bindings. See the example below. + +## example + + -- Switch between US Dvorak and DE layouts. + mykbdlayout = lain.widgets.contrib.kbdlayout({ + layouts = {{ layout="us", variant="dvorak" }, + { layout="de" }}, + settings = function () + if kbdlayout_now.variant then + widget:set_text(" " .. kbdlayout_now.layout .. "/" .. kbdlayout_now.variant .. " ") + else + widget:set_text(" " .. kbdlayout_now.layout .. " ") + end + end + }) + + -- Add to the layout. + right_layout:add(mykbdlayout) + + -- Add this key binding to your global keys to + -- add traditional Alt+Shift switching. + awful.key({ "Mod1" }, "Shift_L", function () mykbdlayout.next() end) diff --git a/awesome/.config/awesome/lain/wiki/maildir.md b/awesome/.config/awesome/lain/wiki/maildir.md @@ -0,0 +1,49 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows maildirs status in a textbox. + +Maildirs are structured as follows: + + ~/Mail + . + |-- arch + | |-- cur + | |-- new + | `-- tmp + |-- gmail + | |-- cur + | |-- new + | `-- tmp + . + . + . + +therefore the widget checks whether there are files in the `new` directories. +If there's new mails, the textbox will say something like "mail: bugs(3), system(1)", otherwise it says +"no mail". + + mymaildir = lain.widgets.maildir(args) + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 60 +`mailpath` | Path to your maildir | string | "~/Mail" +`ignore_boxes` | Boxes to ignore | table of strings | empty table +`external_mail_cmd` | External mail update command | string | empty string +`settings` | User settings | function | empty function + +`settings` can use the string `newmail`, which format will be something like defined above, or "no mail". +`external_mail_cmd` can be used to run a mail update command, for instance: + +```lua +mailwidget = lain.widgets.maildir({ + external_mail_cmd = "mbsync -q account1 account2 account3", + -- [...] +}) +``` + +### output + +A textbox. +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/mem.md b/awesome/.config/awesome/lain/wiki/mem.md @@ -0,0 +1,18 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows memory status (in MiB) in a textbox. + + mymem = lain.widgets.mem() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 +`settings` | User settings | function | empty function + +`settings` can use the strings `mem_now.used` (memory used MB) and `mem_now.swapused` (swap used MB). + +### output + +A textbox. diff --git a/awesome/.config/awesome/lain/wiki/moc.md b/awesome/.config/awesome/lain/wiki/moc.md @@ -0,0 +1,88 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +A widget for showing the current song track's information from MOC (Music On Console). Also provides next track notifications using naughty + + mocwidget = lain.widgets.contrib.moc() + +Now playing songs are notified like this: + + +--------------------------------------------------------+ + | +-------+ | + | |/^\_/^\| Now playing | + | |\ O O /| Cannibal Corpse (Hammer Smashed Face) - 1993 | + | | '.o.' | Hammer Smashed Face (Radio Disney Version) | + | +-------+ | + +--------------------------------------------------------+ + +You need a file like this + + (Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif) + +in the album folder in order to show album art too. + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 1 +`music_dir` | Music directory | string | "~/Music" +`cover_size` | Album art notification size | int | 100 +`default_art` | Default art | string | "" +`followmouse` | Notification behaviour | boolean | false +`settings` | User settings | function | empty function + +Pay attention to case sensitivity when defining `music_dir`. + +`settings` can use `moc_now` table, which contains the following string values: + +- state (possible values: "PLAY", "PAUSE", "STOP") +- file +- artist +- title +- album +- elapsed (Time elapsed for the current track) +- total (The current track's total time) + +and can modify `moc_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: + + moc_notification_preset = { + title = "Now playing", + timeout = 6, + text = string.format("%s (%s) - %s\n%s", moc_now.artist, + moc_now.album, moc_now.elapsed, moc_now.title) + } + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen. By setting `followmouse` to `true` it will be shown on the same screen containing the widget. + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The textbox | `wibox.widget.textbox` +`update` | The notification | function + +You can control the widget with key bindings like these: + + -- MOC control + awful.key({ altkey, "Control" }, "Up", + function () + awful.util.spawn_with_shell("mocp -G") + mocwidget.update() + end), + awful.key({ altkey, "Control" }, "Down", + function () + awful.util.spawn_with_shell("mocp -s") + mocwidget.update() + end), + awful.key({ altkey, "Control" }, "Left", + function () + awful.util.spawn_with_shell("mocp -r") + mocwidget.update() + end), + awful.key({ altkey, "Control" }, "Right", + function () + awful.util.spawn_with_shell("mocp -f") + mocwidget.update() + end), + +where `altkey = "Mod1"`. +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/mpd.md b/awesome/.config/awesome/lain/wiki/mpd.md @@ -0,0 +1,98 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows MPD status in a textbox. + + mpdwidget = lain.widgets.mpd() + +Now playing songs are notified like this: + + +--------------------------------------------------------+ + | +-------+ | + | |/^\_/^\| Now playing | + | |\ O O /| Cannibal Corpse (Hammer Smashed Face) - 1993 | + | | '.o.' | Hammer Smashed Face (Radio Disney Version) | + | +-------+ | + +--------------------------------------------------------+ + +You need a file like this + + (Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif) + +in the album folder in order to show album art too. + +**Note:** if MPD is turned off or not set correctly, the widget will constantly display "N/A N/A". + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 +`password` | MPD password | string | "" +`host` | MPD server | string | "127.0.0.1" +`port` | MPD port | string | "6600" +`music_dir` | Music directory | string | "~/Music" +`cover_size` | Album art notification size | int | 100 +`default_art` | Default art | string | "" +`followmouse` | Notification behaviour | boolean | false +`echo_cmd` | custom call for `echo`* | string | "echo" +`settings` | User settings | function | empty function + +\* `echo` implementation is shell dependent, you may need to set this variable properly (`echo -e` [for instance](https://github.com/copycat-killer/lain/issues/112)) in order for the widget to fetch the data correctly. + +Pay attention to case sensitivity when defining `music_dir`. + +`settings` can use `mpd_now` table, which contains the following string values: + +- state (possible values: "play", "pause", "stop") +- file +- artist +- title +- [name](https://github.com/copycat-killer/lain/pull/142) +- album +- date +- [time](https://github.com/copycat-killer/lain/pull/90) +- [elapsed](https://github.com/copycat-killer/lain/pull/90) (seconds) + +and can modify `mpd_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: + + mpd_notification_preset = { + title = "Now playing", + timeout = 6, + text = string.format("%s (%s) - %s\n%s", mpd_now.artist, + mpd_now.album, mpd_now.date, mpd_now.title) + } + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen. By setting `followmouse` to `true` it will be shown on the current mouse screen. + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The textbox | `wibox.widget.textbox` +`update` | The notification | function + +You can control the widget with key bindings like these: + + -- MPD control + awful.key({ altkey, "Control" }, "Up", + function () + awful.util.spawn_with_shell("mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle") + mpdwidget.update() + end), + awful.key({ altkey, "Control" }, "Down", + function () + awful.util.spawn_with_shell("mpc stop || ncmpcpp stop || ncmpc stop || pms stop") + mpdwidget.update() + end), + awful.key({ altkey, "Control" }, "Left", + function () + awful.util.spawn_with_shell("mpc prev || ncmpcpp prev || ncmpc prev || pms prev") + mpdwidget.update() + end), + awful.key({ altkey, "Control" }, "Right", + function () + awful.util.spawn_with_shell("mpc next || ncmpcpp next || ncmpc next || pms next") + mpdwidget.update() + end), + +where `altkey = "Mod1"`. diff --git a/awesome/.config/awesome/lain/wiki/net.md b/awesome/.config/awesome/lain/wiki/net.md @@ -0,0 +1,42 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Monitors network interfaces and shows current traffic in a textbox. + + mynet = lain.widgets.net() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 +`iface` | Network device | string | autodetected +`units` | Units | int | 1024 (kilobytes) +`notify` | Display "no carrier" notifications | string | "on" +`screen` | Notifications screen | int | 1 +`settings` | User settings | function | empty function + +Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), and so on. + +If `notify = "off"` is set, the widget won't display a notification when there's no carrier. + +`settings` can use the following `iface` related strings: + +- `net_now.carrier` ("0", "1"); +- `net_now.state` ("up", "down"); +- `net_now.sent` and `net_now.received` (numbers). + +### output + +A textbox. + +### Setting `iface` manually + +If the widget [spawns a "no carrier" notification and you are sure to have an active network device](https://github.com/copycat-killer/lain/issues/102), then autodetection is probably not working. In this case you can set `iface` manually. You can see which device is **UP** with the following command: + +```shell +ip link show +``` + +### Two widgets for upload/download rates from the same `iface` + +[Read here](https://github.com/copycat-killer/lain/issues/61). +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/pulseaudio.md b/awesome/.config/awesome/lain/wiki/pulseaudio.md @@ -0,0 +1,79 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows and controls PulseAudio volume with a textbox. + + volumewidget = lain.widgets.pulseaudio() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 5 +`cmd` | PulseAudio command | string | ```pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p'``` +`scallback` | PulseAudio Sink callback | function | nil +`settings` | User settings | function | empty function + +`cmd` catch infos from current used sink. You can redefine it, being sure that the ouput is something like this: + +```shell + * index: 0 + volume: 0: 100% 1: 100% + muted: no +``` + +If `sed` doesn't work, you can try with `grep`: + +```shell +pacmd list-sinks | grep -e $(pactl info | grep -e 'ink' | cut -d' ' -f3) -e 'volume: front' -e 'muted' +``` + +`scallback` is a callback function to update `cmd`, in case you switch between audio channels and therefore PulseAudio sink changes. If default `cmd` works for you, you can tell `scallback` to work in the same way: + +```lua +scallback = function() + return "pacmd list-sinks | sed -n -e '0,/*/d' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p'" +end +``` + +`settings` can use the following variables: + +Variable | Meaning | Type | Values +--- | --- | --- | --- +`volume_now.left` | Front left level | int | 0-100 +`volume_now.right` | Front right level | int | 0-100 +`volume_now.muted` | Sink mute status | string | "yes", "no" + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`sink` | PulseAudio sink | int +`update` | Update `widget` | function + +You can control the widget with key bindings like these: + +```lua +-- PulseAudio volume control +awful.key({ altkey }, "Up", + function () + os.execute(string.format("pactl set-sink-volume %d +1%%", volumewidget.sink)) + volumewidget.update() + end), +awful.key({ altkey }, "Down", + function () + os.execute(string.format("pactl set-sink-volume %d -1%%", volumewidget.sink)) + volumewidget.update() + end), +awful.key({ altkey }, "m", + function () + if volumewidget.muted == "yes" then + os.execute(string.format("pactl set-sink-mute %d no", volumewidget.sink)) + else + os.execute(string.format("pactl set-sink-mute %d yes", volumewidget.sink)) + end + volumewidget.update() + end), +``` + +where `altkey = "Mod1"`. +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/redshift.md b/awesome/.config/awesome/lain/wiki/redshift.md @@ -0,0 +1,141 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +### What is Redshift? # + +[**Project homepage**](http://jonls.dk/redshift/) + +>**Redshift** is an application that adjusts the computer display's color temperature based upon the Sun's apparent position in relation to the user's location on Earth. + +>The program is free software, inspired by the proprietary f.lux, and can be used to reduce eye strain as well as insomnia and delayed sleep phase syndrome. + +>The computer display's color temperature transitions evenly from night to daytime temperature to allow the user's eyes to slowly adapt. At night, the color temperature is low and is typically 3000–4000 K (default is 3500 K), preferably matching the room's lighting temperature. Typical color temperature during the daytime is 5500–6500 K (default is 5500 K). + +**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Redshift_%28software%29) + + + +### Preparations + +**Redshift must be installed** on your system if you want to use this widget. + +Packages should be available for most distributions (i.e. [Ubuntu](http://packages.ubuntu.com/search?keywords=redshift&searchon=names&suite=all§ion=all), [Arch](https://www.archlinux.org/packages/?q=redshift) or [Debian](https://packages.debian.org/jessie/redshift)). +Source code and build instructions can be found on Github [here](https://github.com/jonls/redshift). + +You also need a valid config file. Please see the [project homepage](http://jonls.dk/redshift/) for details. + +**An example redshift.conf file:** + + ; ~/.config/redshift.conf + ; Global settings for redshift + [redshift] + ; Set the day and night screen temperatures + temp-day=5700 + temp-night=3500 + + ; Enable/Disable a smooth transition between day and night + ; 0 will cause a direct change from day to night screen temperature. + ; 1 will gradually increase or decrease the screen temperature + transition=1 + + ; Set the screen brightness. Default is 1.0 + ;brightness=0.9 + ; It is also possible to use different settings for day and night since version 1.8. + ;brightness-day=0.7 + ;brightness-night=0.4 + ; Set the screen gamma (for all colors, or each color channel individually) + gamma=0.8 + ;gamma=0.8:0.7:0.8 + + ; Set the location-provider: 'geoclue', 'gnome-clock', 'manual' + ; type 'redshift -l list' to see possible values + ; The location provider settings are in a different section. + location-provider=manual + + ; Set the adjustment-method: 'randr', 'vidmode' + ; type 'redshift -m list' to see all possible values + ; 'randr' is the preferred method, 'vidmode' is an older API + ; but works in some cases when 'randr' does not. + ; The adjustment method settings are in a different section. + adjustment-method=randr + + ; Configuration of the location-provider: + ; type 'redshift -l PROVIDER:help' to see the settings + ; ex: 'redshift -l manual:help' + [manual] + lat=32.0 + lon=-40.0 + + ; Configuration of the adjustment-method + ; type 'redshift -m METHOD:help' to see the settings + ; ex: 'redshift -m randr:help' + ; In this example, vidmode is configured to adjust screen 1. + ; Note that the numbering starts from 0, so this is actually the second screen. + [vidmode] + screen=0 + +You have to match the location settings to your personal situation: +Adjust the `lat` and `lon` variables - You can use google maps or wikipedia to get the approximate coordinates. + +You might also want to modify the color temperatures to fit your preferences. + +### Using the widget + +This widget provides several functions that can be used to control Redshift: + +* `redshift:toggle()`: Toggles Redshift's color adjustments on or off. +* `redshift:on()`: Activates Redshift. +* `redshift:off()`: This will remove the current color adjustment. (It will not kill the redshift process, however!) +* `redshift:attach(widget, update_function)`: Attach to a (text or icon) widget. + Click on the widget to toggle redshift on or off. This will also auto-launch Redshift along with Awesome WM. + `update_function` can be used to modify the icon/text and will be triggered each time redshift changes its status. (See the examples below.) +* `redshift:is_active()`: Returns *true* if redshift is currently modifying the screen color. + +#### Usage examples + +##### imagebox status widget (with icon) +```lua +-- Redshift widget +icons_dir = require("lain.helpers").icons_dir +local rs_on = icons_dir .. "/redshift/redshift_on.png" +local rs_off = icons_dir .. "/redshift/redshift_off.png" + +myredshift = wibox.widget.imagebox(rs_on) +redshift:attach( + myredshift, + function () + if redshift:is_active() then + myredshift:set_image(rs_on) + else + myredshift:set_image(rs_off) + end + end +) +``` +Then add the `myredshift` widget to your panel. + +##### textbox status widget + +```lua +-- Redshift widget +myredshift = wibox.widget.textbox("RS") +redshift:attach( + myredshift, + function () + if redshift:is_active() then + myredshift:set_text("RS on") + else + myredshift:set_text("RS off") + end + end +) +``` +Then add the `myredshift` widget to your panel. + +##### keybinding + +Add this to the keybindings in your rc.lua: +```lua +-- Toggle redshift with Mod+Shift+t + awful.key({ modkey, "Shift" }, "t", function () redshift:toggle() end) , +``` + diff --git a/awesome/.config/awesome/lain/wiki/sysload.md b/awesome/.config/awesome/lain/wiki/sysload.md @@ -0,0 +1,18 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows the current system load. + + mysysload = lain.widgets.sysload() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 +`settings` | User settings | function | empty function + +`settings` can use strings `load_1`, `load_5` and `load_15`, which are loadavg over 1, 5, and 15 minutes. + +### output + +A textbox. diff --git a/awesome/.config/awesome/lain/wiki/task.md b/awesome/.config/awesome/lain/wiki/task.md @@ -0,0 +1,40 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Attaches a [taskwarrior](http://taskwarrior.org) notification to a widget, and lets to add/search tasks from the promptbox. + +```lua + lain.widgets.contrib.task:attach(widget, args) +``` + +`args` is an optional table which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`font_size` | Notifcation font size | int | 12 +`fg` | Notification popup foreground color | string | `beautiful.fg_normal` +`bg` | Notification popu background color | string | `beautiful.bg_normal` +`position` | Notification popup position | string | "top_right" +`timeout` | Notification timeout seconds | int | 7 +`scr_pos` | Notification screen | int | 1 +`followmouse` | Notification behaviour | boolean | false + +`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify). + +Notification will show the output of `task` command. + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen. By setting `followmouse` to `true` it will be shown on the same screen containing the widget. + +You can call the notification with a key binding like this: + +```lua +awful.key({ modkey, altkey }, "t", function () lain.widgets.contrib.task.show(scr) end), +``` + +where ``altkey = "Mod1"`` and `scr` indicates the screen which you want the notification in. + +And you can prompt to add/search a task with key bindings like these: + +```lua +awful.key({ modkey, }, "t", lain.widgets.contrib.task.prompt_add), +awful.key({ modkey, "Shift" }, "t", lain.widgets.contrib.task.prompt_search), +``` +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/temp.md b/awesome/.config/awesome/lain/wiki/temp.md @@ -0,0 +1,25 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows the current core temperature in a textbox. + +Reads from `/sys/class/thermal`, so value is expressed in Celsius. + + mytemp = lain.widgets.temp() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 +`tempfile` | Path of file which stores core temperature value | string | "/sys/class/thermal/thermal_zone0/temp" +`settings` | User settings | function | empty function + +`settings` can use the string `coretemp_now`, which means current core temperature, expressed in Celsius (linux standard). + +### output + +A textbox. + +### note + +Depending on the architecture, keep in mind that your temp files location [might change](https://github.com/copycat-killer/lain/issues/84#issuecomment-72751763). diff --git a/awesome/.config/awesome/lain/wiki/tpbat.md b/awesome/.config/awesome/lain/wiki/tpbat.md @@ -0,0 +1,9 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi). + +Includes hover notification with more details. + + tpbatwidget = lain.widgets.contrib.tpbat() + +Configuration is identical to [standard battery widget's](https://github.com/copycat-killer/lain/wiki/bat). +\ No newline at end of file diff --git a/awesome/.config/awesome/lain/wiki/weather.md b/awesome/.config/awesome/lain/wiki/weather.md @@ -0,0 +1,141 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Provides current weather status widgets and X-days forecast popup notifications. + +Uses [OpenWeatherMap](http://openweathermap.org/api) API. + +By default, it uses [current](http://openweathermap.org/current) for current weather data and [forecast16](http://openweathermap.org/forecast16) for forecasts. + +```lua +myweather = lain.widgets.weather() +``` + +## input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds for current weather status | int | 900 (15 min) +`timeout_forecast` | Refresh timeout seconds for forecast notification | int | 86400 (24 hrs) +`current_call` | Command to fetch weather status data from the API | string | see `default_current_call` +`forecast_call` | Command to fetch forecast data from the API | string | see `default_forecast_call` +`city_id` | API city code | int | not set +`units` | Temperature units system | string | "metric" +`lang` | API data localization | string | "en" +`cnt` | Forecast days interval | int | 5 +`date_cmd` | Forecast notification format style | string | "date -u -d @%d +'%%a %%d'" +`icons_path` | Icons path | string | `lain/icons/openweathermap` +`notification_preset` | Preset for notifications | table | empty table +`notification_text_fun` | Function to format forecast notifications | function | see `notification_text_fun` +`weather_na_markup` | Markup to be used when weather textbox is not available | text | " N/A " +`followmouse` | Notification behaviour | boolean | false +`settings` | User settings | function | empty function + +- ``default_current_call`` + + `"curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s'"` + + You can rewrite it using any fetcher solution you like. + +- ``default_forecast_call`` + + `"curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s'"` + + Like above. + If you want to use [forecast5](http://openweathermap.org/forecast5), use this API call string: + `http://api.openweathermap.org/data/2.5/forecast?id=%s&units=%s&lang=%s&cnt=%s` + +- ``city_id`` + + An integer that defines the OpenWeatherMap ID code of your city. + To obtain it go to [OpenWeatherMap](http://openweathermap.org/) and query for your city in the top search bar. The link will look like this: + + http://openweathermap.org/city/2643743 + + your `city_id` is the number at the end. + +- ``units`` + + - For temperature in Fahrenheit use `units = "imperial"` + - For temperature in Celsius use `units = "metric"` (Lain default) + - For temperature in Kelvin use `units = "standard"` (OpenWeatherMap default) + +- ``lang`` + + See *Multilingual Support* section [here](http://openweathermap.org/current). + +- ``cnt`` + + Determines how many days to show in the forecast notification. Up to 16 if you use [forecast16](http://openweathermap.org/forecast16) (default), and up to 5 if you use [forecast5](http://openweathermap.org/forecast5). + +- ``date_cmd`` + + OpenWeatherMap time is in UNIX format, so this variable uses `date` to determine how each line in the forecast notification is formatted. Default looks like this: + + day #daynumber: forecast, temp_min - temp_max + + see `man date` for your customizations. + +- ``icons_path`` + + You can set your own icons path if you don't wish to use `lain/icons/openweathermap`. Just be sure that your icons are PNGs and named exactly like [OpenWeatherMap ones](http://openweathermap.org/weather-conditions). + +- ``notification_preset`` + + Notifications preset table. See [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the details. + +- ``notification_text_fun`` + ```lua + function (wn) + local day = string.gsub(read_pipe(string.format(date_cmd, wn["dt"])), "\n", "") + local tmin = math.floor(wn["temp"]["min"]) + local tmax = math.floor(wn["temp"]["max"]) + local desc = wn["weather"][1]["description"] + + return string.format("<b>%s</b>: %s, %d - %d ", day, desc, tmin, tmax) + end + ``` + See [here](https://github.com/copycat-killer/lain/issues/186#issuecomment-203400918) for a complete customization example. + +- ``followmouse`` + + In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen when the widget is hovered with the mouse. By setting followmouse to true it will be shown on the same screen containing the widget. + +- ``settings`` + + In your `settings` function, you can use `widget` variable to refer to the textbox, and the dictionary `weather_now` to refer to data retrieved by `current_call`. The dictionary is built with [dkjson library](http://dkolf.de/src/dkjson-lua.fsl/home), and its structure is defined [here](http://openweathermap.org/weather-data). + For instance, you can retrieve current weather status and temperature [in this way](https://github.com/copycat-killer/awesome-copycats/blob/master/rc.lua.multicolor#L139-140). + +In multiple screen setups, the default behaviour is to show a visual notification pop-up window on the first screen when the widget is hovered with the mouse. By setting `followmouse` to `true` it will be shown on the same screen containing the widget. + +## Usage +The module creates an imagebox icon and a textbox widget. Add them to you wibox like this: + + right_layout:add(myweather) + right_layout:add(myweather.icon) + +### attach +You can attach the forecast notification to any widget like this: + + myweather.attach(obj) + +Hovering over ``obj`` will display the notification. + +### update + + myweather.update() + +Force fetching of current weather status data. Useful when combined with other widgets workflow (for instance, it can be called from net widget when the internet connection is restored). + +### forecast_update + + myweather.forecast_update() + +Like above, but for the forecast notification. + +### popup shortcut + +You can also create a keybinding for the weather popup like this: + + awful.key( { "Mod1" }, "w", function () myweather.show(5) end ) + +where ``show`` argument is an integer defining timeout seconds. diff --git a/awesome/.config/awesome/rc.lua b/awesome/.config/awesome/rc.lua @@ -0,0 +1,535 @@ +--[[ + + pyratesoft awesomewm config + +--]] + +-- 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") + +-- Notification library +local naughty = require("naughty") +local menubar = require("menubar") + +-- Dropdown terminal +local drop = require("scratchdrop") + +-- Extra layouts +local lain = require("lain") + +awful.util.spawn_with_shell("xcompmgr -cF &") + +vicious = require("vicious") + +-- {{{ 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 +-- }}} + +-- {{{ Variable definitions +-- Themes define colours, icons, font and wallpapers. + -- My themes: pyratesoft, algersoft, otherideas + beautiful.init("/home/dudley/.config/awesome/themes/pyratesoft/theme.lua") + + -- This is used later as the default terminal and editor to run. + terminal = "urxvt" + -- terminal = "st -f Tamsyn:pixelsize=15" + editor = os.getenv("EDITOR") or "vi" + 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. + local layouts = + { + awful.layout.suit.floating, + lain.layout.uselesstile, + awful.layout.suit.tile, + -- awful.layout.suit.magnifier + } + -- }}} + + -- {{{ Wallpaper + if beautiful.wallpaper then + for s = 1, screen.count() do + gears.wallpaper.maximized(beautiful.wallpaper, s, true) + end + end + -- }}} + + -- {{{ 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({" terminal ", " web ", " code ", " other"}, s, layouts[1]) + end + -- }}} + + -- {{{ Menu + -- Create a laucher widget and a main menu + myawesomemenu = { + { "manual", terminal .. " -e man awesome" }, + { "edit config", editor_cmd .. " " .. awesome.conffile }, + { "restart", awesome.restart }, + { "quit", awesome.quit } + } + + mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon }, + { "open terminal", terminal } + } + }) + + mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, + menu = mymainmenu }) + + -- Menubar configuration + menubar.utils.terminal = terminal -- Set the terminal for applications that require it + -- menubar.set_icon_theme("/usr/share/fonts/HighContrast/index.theme") + -- }}} + + -- {{{ Wibox + -- seperator-widget + seperator = wibox.widget.textbox() + seperator:set_markup("|") + -- spacer-widget + spacer = wibox.widget.textbox() + spacer:set_markup(" ") + + -- cpuwidget + cpuwidget = wibox.widget.textbox() + vicious.register(cpuwidget, vicious.widgets.cpu, "c:$1%") + -- memwidget (every 10 seconds) + memwidget = wibox.widget.textbox() + vicious.register(memwidget, vicious.widgets.mem, "m:$1%", 10) + -- netwidget (#5eaefe = pale blue) + netwidget = wibox.widget.textbox() + vicious.register(netwidget, vicious.widgets.net, "u:${enp0s3 up_kb} d:${enp0s3 down_kb}", 3) + -- batwidget + batwidget = wibox.widget.textbox() + vicious.register(batwidget, vicious.widgets.bat, "$1$2", 32, "BAT0") + -- datewidget + datewidget = wibox.widget.textbox() + vicious.register(datewidget, vicious.widgets.date, "%a %F %R", 60) + + -- Create a textclock widget + -- mytextclock = awful.widget.textclock() + + -- Create a wibox for each screen and add it + mywibox = {} + mypromptbox = {} + mylayoutbox = {} + mytaglist = {} + mytaglist.buttons = awful.util.table.join( + awful.button({ }, 1, awful.tag.viewonly), + awful.button({ modkey }, 1, awful.client.movetotag), + awful.button({ }, 3, awful.tag.viewtoggle), + awful.button({ modkey }, 3, awful.client.toggletag), + awful.button({ }, 4, 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({ + theme = { 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() + -- 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 }) + + -- 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(seperator) + 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(cpuwidget) + right_layout:add(spacer) + right_layout:add(seperator) + right_layout:add(spacer) + right_layout:add(memwidget) + right_layout:add(spacer) + right_layout:add(seperator) + right_layout:add(spacer) + right_layout:add(netwidget) + right_layout:add(spacer) + right_layout:add(seperator) + right_layout:add(spacer) + right_layout:add(batwidget) + right_layout:add(spacer) + right_layout:add(seperator) + right_layout:add(spacer) + right_layout:add(datewidget) + 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) + 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() 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, "Control" }, "n", awful.client.restore), + + -- Lock screen + awful.key({ modkey, }, "#94", function () awful.util.spawn("i3lock -u -c 000000") end), + + -- Audio + awful.key({ modkey, }, "#174", function () awful.util.spawn("mocp -P") end), -- Fn Stop (pauses) + awful.key({ modkey, }, "#172", function () awful.util.spawn("mocp -U") end), -- Fn Play (unpauses) + awful.key({ modkey, }, "#59", function () awful.util.spawn("mocp -v -5") end), -- comma (decrease vol by 5) + awful.key({ modkey, }, "#60", function () awful.util.spawn("mocp -P") end), -- perid (increase vol by 5) + + -- Brightness + awful.key({ modkey, }, "#232", function () awful.util.spawn("xrandr --output LVDS1 --brightness 0.8") end), -- brightness down + awful.key({ modkey, }, "#233", function () awful.util.spawn("xrandr --output LVDS1 --brightness 1") end), -- brightness up + + + -- Dropdown terminal + awful.key({ modkey, }, "`", function () drop(terminal) 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), + -- 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) + ) + + -- 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, 9 do + globalkeys = awful.util.table.join(globalkeys, + -- View tag only. + awful.key({ modkey }, "#" .. i + 9, + function () + local screen = mouse.screen + local tag = awful.tag.gettags(screen)[i] + if tag then + awful.tag.viewonly(tag) + end + end), + -- Toggle tag. + awful.key({ modkey, "Control" }, "#" .. i + 9, + function () + local screen = mouse.screen + local tag = awful.tag.gettags(screen)[i] + if tag then + awful.tag.viewtoggle(tag) + end + end), + -- Move client to tag. + awful.key({ modkey, "Shift" }, "#" .. i + 9, + function () + if client.focus then + local tag = awful.tag.gettags(client.focus.screen)[i] + if tag then + awful.client.movetotag(tag) + end + end + end), + -- Toggle tag. + awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, + function () + if client.focus then + local tag = awful.tag.gettags(client.focus.screen)[i] + if tag then + awful.client.toggletag(tag) + end + 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) + -- }}} + + -- {{{ Rules + -- Rules to apply to new clients (through the "manage" signal). + awful.rules.rules = { + -- All clients will match this rule. + { rule = { }, + properties = { border_width = beautiful.border_width, + border_color = beautiful.border_normal, + focus = awful.client.focus.filter, + raise = true, + keys = clientkeys, + buttons = clientbuttons } }, + -- + -- use `xprop` to find WM_CLASS + -- + { rule = { class = "MPlayer" }, + properties = { floating = true } }, + { rule = { class = "mpv" }, + properties = { floating = true } }, + { rule = { class = "pinentry" }, + properties = { floating = true } }, + { rule = { class = "gimp" }, + properties = { floating = true } }, + { rule = { class = "sxiv" }, + properties = { floating = true } }, + { rule = { class = "Sxiv" }, + properties = { floating = true } }, + { rule = { class = "gifview" }, + properties = { floating = true } }, + { rule = { class = "Gifview" }, + properties = { floating = true } }, + -- Set Chrome to always map on tags number 2 of screen 1. + -- { rule = { class = "Chrome" }, + -- properties = { tag = tags[1][2] } }, + -- + -- 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.connect_signal("manage", function (c, startup) + -- Enable sloppy focus + c:connect_signal("mouse::exit", 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 + + local titlebars_enabled = false + if titlebars_enabled and (c.type == "normal" or c.type == "dialog") then + -- buttons for the titlebar + local buttons = awful.util.table.join( + awful.button({ }, 1, function() + client.focus = c + c:raise() + awful.mouse.client.move(c) + end), + awful.button({ }, 3, function() + client.focus = c + c:raise() + awful.mouse.client.resize(c) + end) + ) + + -- Widgets that are aligned to the left + local left_layout = wibox.layout.fixed.horizontal() + -- left_layout:add(awful.titlebar.widget.iconwidget(c)) + left_layout:buttons(buttons) + + -- Widgets that are aligned to the right + local right_layout = wibox.layout.fixed.horizontal() + -- right_layout:add(awful.titlebar.widget.floatingbutton(c)) + right_layout:add(awful.titlebar.widget.maximizedbutton(c)) + -- right_layout:add(awful.titlebar.widget.stickybutton(c)) + -- right_layout:add(awful.titlebar.widget.ontopbutton(c)) + right_layout:add(awful.titlebar.widget.closebutton(c)) + + -- The title goes in the middle + local middle_layout = wibox.layout.flex.horizontal() + local title = awful.titlebar.widget.titlewidget(c) + title:set_align("left") + middle_layout:add(title) + middle_layout:buttons(buttons) + + -- Now bring it all together + local layout = wibox.layout.align.horizontal() + layout:set_left(left_layout) + layout:set_right(right_layout) + layout:set_middle(middle_layout) + + awful.titlebar(c):set_widget(layout) + end +end) + +client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) +client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) +-- }}} diff --git a/awesome/.config/awesome/scratchdrop/init.lua b/awesome/.config/awesome/scratchdrop/init.lua @@ -0,0 +1,133 @@ +------------------------------------------------------------------- +-- Drop-down applications manager for the awesome window manager +------------------------------------------------------------------- +-- Coded by: * Lucas de Vries <lucas@glacicle.com> +-- Hacked by: * Adrian C. (anrxc) <anrxc@sysphere.org> +-- Licensed under the WTFPL version 2 +-- * http://sam.zoy.org/wtfpl/COPYING +------------------------------------------------------------------- +-- To use this module add: +-- local scratchdrop = require("scratchdrop") +-- to the top of your rc.lua, and call it from a keybinding: +-- scratchdrop(prog, vert, horiz, width, height, sticky, screen) +-- +-- Parameters: +-- prog - Program to run; "urxvt", "gmrun", "thunderbird" +-- vert - Vertical; "bottom", "center" or "top" (default) +-- horiz - Horizontal; "left", "right" or "center" (default) +-- width - Width in absolute pixels, or width percentage +-- when <= 1 (1 (100% of the screen) by default) +-- height - Height in absolute pixels, or height percentage +-- when <= 1 (0.25 (25% of the screen) by default) +-- sticky - Visible on all tags, false by default +-- screen - Screen (optional), mouse.screen by default +------------------------------------------------------------------- + +-- Grab environment +local pairs = pairs +local awful = require("awful") +local setmetatable = setmetatable +local capi = { + mouse = mouse, + client = client, + screen = screen +} + +-- Scratchdrop: drop-down applications manager for the awesome window manager +local scratchdrop = {} -- module scratch.drop + +local dropdown = {} + +-- Create a new window for the drop-down application when it doesn't +-- exist, or toggle between hidden and visible states when it does +function toggle(prog, vert, horiz, width, height, sticky, screen) + vert = vert or "top" + horiz = horiz or "center" + width = width or 1 + height = height or 0.5 + sticky = sticky or false + screen = screen or capi.mouse.screen + + -- Determine signal usage in this version of awesome + local attach_signal = capi.client.connect_signal or capi.client.add_signal + local detach_signal = capi.client.disconnect_signal or capi.client.remove_signal + + if not dropdown[prog] then + dropdown[prog] = {} + + -- Add unmanage signal for scratchdrop programs + attach_signal("unmanage", function (c) + for scr, cl in pairs(dropdown[prog]) do + if cl == c then + dropdown[prog][scr] = nil + end + end + end) + end + + if not dropdown[prog][screen] then + spawnw = function (c) + dropdown[prog][screen] = c + + -- Scratchdrop clients are floaters + awful.client.floating.set(c, true) + + -- Client geometry and placement + local screengeom = capi.screen[screen].workarea + + if width <= 1 then width = screengeom.width * width end + if height <= 1 then height = screengeom.height * height end + + if horiz == "left" then x = screengeom.x + elseif horiz == "right" then x = screengeom.width - width + else x = screengeom.x+(screengeom.width-width)/2 end + + if vert == "bottom" then y = screengeom.height + screengeom.y - height + elseif vert == "center" then y = screengeom.y+(screengeom.height-height)/2 + else y = screengeom.y - screengeom.y end + + -- Client properties + c:geometry({ x = x, y = y + mywibox[mouse.screen].height, width = width - 2, height = height }) + c.ontop = true + c.above = true + c.skip_taskbar = true + if sticky then c.sticky = true end + if c.titlebar then awful.titlebar.remove(c) end + + c:raise() + capi.client.focus = c + detach_signal("manage", spawnw) + end + + -- Add manage signal and spawn the program + attach_signal("manage", spawnw) + awful.util.spawn(prog, false) + else + -- Get a running client + c = dropdown[prog][screen] + + -- Switch the client to the current workspace + if c:isvisible() == false then c.hidden = true + awful.client.movetotag(awful.tag.selected(screen), c) + end + + -- Focus and raise if hidden + if c.hidden then + -- Make sure it is centered + --if vert == "center" then awful.placement.center_vertical(c) end + --if horiz == "center" then awful.placement.center_horizontal(c) end + c.hidden = false + c:raise() + capi.client.focus = c + else -- Hide and detach tags if not + c.hidden = true + local ctags = c:tags() + for i, t in pairs(ctags) do + ctags[i] = nil + end + c:tags(ctags) + end + end +end + +return setmetatable(scratchdrop, { __call = function(_, ...) return toggle(...) end }) diff --git a/awesome/.config/awesome/themes/algersoft/awesome14.png b/awesome/.config/awesome/themes/algersoft/awesome14.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/awesome16.png b/awesome/.config/awesome/themes/algersoft/awesome16.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/background.jpg b/awesome/.config/awesome/themes/algersoft/background.jpg Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/background.png b/awesome/.config/awesome/themes/algersoft/background.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/background/bg.png b/awesome/.config/awesome/themes/algersoft/background/bg.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/background/bg2.png b/awesome/.config/awesome/themes/algersoft/background/bg2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/hero_twitter.jpg b/awesome/.config/awesome/themes/algersoft/hero_twitter.jpg Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/dwindle.png b/awesome/.config/awesome/themes/algersoft/layouts/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/dwindlew.png b/awesome/.config/awesome/themes/algersoft/layouts/dwindlew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/fairh.png b/awesome/.config/awesome/themes/algersoft/layouts/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/fairhw.png b/awesome/.config/awesome/themes/algersoft/layouts/fairhw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/fairv.png b/awesome/.config/awesome/themes/algersoft/layouts/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/fairvw.png b/awesome/.config/awesome/themes/algersoft/layouts/fairvw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/floating.png b/awesome/.config/awesome/themes/algersoft/layouts/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/floatingw.png b/awesome/.config/awesome/themes/algersoft/layouts/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/fullscreen.png b/awesome/.config/awesome/themes/algersoft/layouts/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/fullscreenw.png b/awesome/.config/awesome/themes/algersoft/layouts/fullscreenw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/magnifier.png b/awesome/.config/awesome/themes/algersoft/layouts/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/magnifierw.png b/awesome/.config/awesome/themes/algersoft/layouts/magnifierw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/max.png b/awesome/.config/awesome/themes/algersoft/layouts/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/maxw.png b/awesome/.config/awesome/themes/algersoft/layouts/maxw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/spiral.png b/awesome/.config/awesome/themes/algersoft/layouts/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/spiralw.png b/awesome/.config/awesome/themes/algersoft/layouts/spiralw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tile.png b/awesome/.config/awesome/themes/algersoft/layouts/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tilebottom.png b/awesome/.config/awesome/themes/algersoft/layouts/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tilebottomw.png b/awesome/.config/awesome/themes/algersoft/layouts/tilebottomw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tileleft.png b/awesome/.config/awesome/themes/algersoft/layouts/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tileleftw.png b/awesome/.config/awesome/themes/algersoft/layouts/tileleftw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tiletop.png b/awesome/.config/awesome/themes/algersoft/layouts/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tiletopw.png b/awesome/.config/awesome/themes/algersoft/layouts/tiletopw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts/tilew.png b/awesome/.config/awesome/themes/algersoft/layouts/tilew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/dwindle.png b/awesome/.config/awesome/themes/algersoft/layouts2/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/fairh.png b/awesome/.config/awesome/themes/algersoft/layouts2/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/fairv.png b/awesome/.config/awesome/themes/algersoft/layouts2/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/floating.png b/awesome/.config/awesome/themes/algersoft/layouts2/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/floating_a.png b/awesome/.config/awesome/themes/algersoft/layouts2/floating_a.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/fullscreen.png b/awesome/.config/awesome/themes/algersoft/layouts2/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/magnifier.png b/awesome/.config/awesome/themes/algersoft/layouts2/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/max.png b/awesome/.config/awesome/themes/algersoft/layouts2/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/spiral.png b/awesome/.config/awesome/themes/algersoft/layouts2/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/tile.png b/awesome/.config/awesome/themes/algersoft/layouts2/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/tilebottom.png b/awesome/.config/awesome/themes/algersoft/layouts2/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/tileleft.png b/awesome/.config/awesome/themes/algersoft/layouts2/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/layouts2/tiletop.png b/awesome/.config/awesome/themes/algersoft/layouts2/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/submenu.png b/awesome/.config/awesome/themes/algersoft/submenu.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/taglist/squarefw.png b/awesome/.config/awesome/themes/algersoft/taglist/squarefw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/taglist/squarew.png b/awesome/.config/awesome/themes/algersoft/taglist/squarew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/tasklist/floating.png b/awesome/.config/awesome/themes/algersoft/tasklist/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/tasklist/floatingw.png b/awesome/.config/awesome/themes/algersoft/tasklist/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/tasklist/square.png b/awesome/.config/awesome/themes/algersoft/tasklist/square.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/tasklist/square2.png b/awesome/.config/awesome/themes/algersoft/tasklist/square2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/theme.lua b/awesome/.config/awesome/themes/algersoft/theme.lua @@ -0,0 +1,133 @@ +-- grey-new, awesome3 theme, by Andreas Persson (greyscale, grey) + +--{{{ Main +local awful = require("awful") +awful.util = require("awful.util") + +theme = {} + +home = os.getenv("HOME") +config = awful.util.getdir("config") +shared = "/usr/share/awesome" +if not awful.util.file_readable(shared .. "/icons/awesome16.png") then + shared = "/usr/share/local/awesome" +end +sharedicons = shared .. "/icons" +sharedthemes = shared .. "/themes" +themes = config .. "/themes" +themename = "/algersoft" +if not awful.util.file_readable(themes .. themename .. "/theme.lua") then + themes = sharedthemes +end +themedir = themes .. themename + +wallpaper1 = themedir .. "/background.jpg" +wallpaper2 = themedir .. "/background.png" +wallpaper3 = sharedthemes .. "/zenburn/zenburn-background.png" +wallpaper4 = sharedthemes .. "/default/background.png" +wpscript = home .. "/.wallpaper" + +if awful.util.file_readable(wallpaper1) then + theme.wallpaper = wallpaper1 +elseif awful.util.file_readable(wallpaper2) then + theme.wallpaper = wallpaper2 +elseif awful.util.file_readable(wpscript) then + theme.wallpaper_cmd = { "sh " .. wpscript } +elseif awful.util.file_readable(wallpaper3) then + theme.wallpaper = wallpaper3 +else + theme.wallpaper = wallpaper4 +end +--}}} + +theme.font = "Tamsyn 10" +-- theme.font = "ProggyTinyTTSZ 12" + +theme.bg_normal = "#121212" +theme.bg_focus = "#212121" +theme.bg_urgent = "#212121" +theme.bg_minimize = "#121212" + +theme.fg_normal = "#5fafff" +theme.fg_focus = "#08ff07" +theme.fg_urgent = "#ff0056" +theme.fg_minimize = "#ababab" + +theme.border_width = "1" +theme.border_normal = "#515151" +theme.border_focus = "#08ff07" +theme.border_marked = "#ff0056" + +-- 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 = themedir .. "/taglist/squarefw.png" +theme.taglist_squares_unsel = themedir .. "/taglist/squarew.png" + +theme.tasklist_square = themedir .. "/tasklist/square2.png" +theme.tasklist_floating_icon = themedir .. "/tasklist/floatingw.png" + +-- Variables set for theming the menu: +-- menu_[bg|fg]_[normal|focus] +-- menu_[border_color|border_width] +theme.menu_submenu_icon = themedir .. "/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 = themedir .. "/titlebar/close_normal.png" +theme.titlebar_close_button_focus = themedir .. "/titlebar/close_focus.png" + +theme.titlebar_ontop_button_normal_inactive = themedir .. "/titlebar/ontop_normal_inactive.png" +theme.titlebar_ontop_button_focus_inactive = themedir .. "/titlebar/ontop_focus_inactive.png" +theme.titlebar_ontop_button_normal_active = themedir .. "/titlebar/ontop_normal_active.png" +theme.titlebar_ontop_button_focus_active = themedir .. "/titlebar/ontop_focus_active.png" + +theme.titlebar_sticky_button_normal_inactive = themedir .. "/titlebar/sticky_normal_inactive.png" +theme.titlebar_sticky_button_focus_inactive = themedir .. "/titlebar/sticky_focus_inactive.png" +theme.titlebar_sticky_button_normal_active = themedir .. "/titlebar/sticky_normal_active.png" +theme.titlebar_sticky_button_focus_active = themedir .. "/titlebar/sticky_focus_active.png" + +theme.titlebar_floating_button_normal_inactive = themedir .. "/titlebar/floating_normal_inactive.png" +theme.titlebar_floating_button_focus_inactive = themedir .. "/titlebar/floating_focus_inactive.png" +theme.titlebar_floating_button_normal_active = themedir .. "/titlebar/floating_normal_active.png" +theme.titlebar_floating_button_focus_active = themedir .. "/titlebar/floating_focus_active.png" + +theme.titlebar_maximized_button_normal_inactive = themedir .. "/titlebar/maximized_normal_inactive.png" +theme.titlebar_maximized_button_focus_inactive = themedir .. "/titlebar/maximized_focus_inactive.png" +theme.titlebar_maximized_button_normal_active = themedir .. "/titlebar/maximized_normal_active.png" +theme.titlebar_maximized_button_focus_active = themedir .. "/titlebar/maximized_focus_active.png" + +-- You can use your own layout icons like this: +theme.layout_fairh = themedir .. "/layouts2/fairh.png" +theme.layout_fairv = themedir .. "/layouts2/fairv.png" +theme.layout_floating = themedir .. "/layouts2/floating.png" +theme.layout_magnifier = themedir .. "/layouts2/magnifier.png" +theme.layout_max = themedir .. "/layouts2/max.png" +theme.layout_fullscreen = themedir .. "/layouts2/fullscreen.png" +theme.layout_tilebottom = themedir .. "/layouts2/tilebottom.png" +theme.layout_tileleft = themedir .. "/layouts2/tileleft.png" +theme.layout_tile = themedir .. "/layouts2/tile.png" +theme.layout_tiletop = themedir .. "/layouts2/tiletop.png" +theme.layout_spiral = themedir .. "/layouts2/spiral.png" +theme.layout_dwindle = themedir .. "/layouts2/dwindle.png" + +theme.awesome_icon = themedir .. "/awesome14.png" + +-- lain related +theme.useless_gap_width = 10 + +return theme diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/close_focus.png b/awesome/.config/awesome/themes/algersoft/titlebar/close_focus.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/close_normal.png b/awesome/.config/awesome/themes/algersoft/titlebar/close_normal.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/floating_focus_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/floating_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/floating_focus_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/floating_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/floating_normal_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/floating_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/floating_normal_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/floating_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/maximized_focus_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/maximized_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/maximized_focus_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/maximized_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/maximized_normal_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/maximized_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/maximized_normal_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/maximized_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/ontop_focus_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/ontop_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/ontop_focus_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/ontop_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/ontop_normal_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/ontop_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/ontop_normal_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/ontop_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/sticky_focus_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/sticky_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/sticky_focus_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/sticky_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/sticky_normal_active.png b/awesome/.config/awesome/themes/algersoft/titlebar/sticky_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/algersoft/titlebar/sticky_normal_inactive.png b/awesome/.config/awesome/themes/algersoft/titlebar/sticky_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/awesome14.png b/awesome/.config/awesome/themes/otherideas/awesome14.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/awesome16.png b/awesome/.config/awesome/themes/otherideas/awesome16.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/background.jpg b/awesome/.config/awesome/themes/otherideas/background.jpg Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/background.png b/awesome/.config/awesome/themes/otherideas/background.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/background/bg.png b/awesome/.config/awesome/themes/otherideas/background/bg.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/background/bg2.png b/awesome/.config/awesome/themes/otherideas/background/bg2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/dwindle.png b/awesome/.config/awesome/themes/otherideas/layouts/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/dwindlew.png b/awesome/.config/awesome/themes/otherideas/layouts/dwindlew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/fairh.png b/awesome/.config/awesome/themes/otherideas/layouts/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/fairhw.png b/awesome/.config/awesome/themes/otherideas/layouts/fairhw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/fairv.png b/awesome/.config/awesome/themes/otherideas/layouts/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/fairvw.png b/awesome/.config/awesome/themes/otherideas/layouts/fairvw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/floating.png b/awesome/.config/awesome/themes/otherideas/layouts/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/floatingw.png b/awesome/.config/awesome/themes/otherideas/layouts/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/fullscreen.png b/awesome/.config/awesome/themes/otherideas/layouts/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/fullscreenw.png b/awesome/.config/awesome/themes/otherideas/layouts/fullscreenw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/magnifier.png b/awesome/.config/awesome/themes/otherideas/layouts/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/magnifierw.png b/awesome/.config/awesome/themes/otherideas/layouts/magnifierw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/max.png b/awesome/.config/awesome/themes/otherideas/layouts/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/maxw.png b/awesome/.config/awesome/themes/otherideas/layouts/maxw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/spiral.png b/awesome/.config/awesome/themes/otherideas/layouts/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/spiralw.png b/awesome/.config/awesome/themes/otherideas/layouts/spiralw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tile.png b/awesome/.config/awesome/themes/otherideas/layouts/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tilebottom.png b/awesome/.config/awesome/themes/otherideas/layouts/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tilebottomw.png b/awesome/.config/awesome/themes/otherideas/layouts/tilebottomw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tileleft.png b/awesome/.config/awesome/themes/otherideas/layouts/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tileleftw.png b/awesome/.config/awesome/themes/otherideas/layouts/tileleftw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tiletop.png b/awesome/.config/awesome/themes/otherideas/layouts/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tiletopw.png b/awesome/.config/awesome/themes/otherideas/layouts/tiletopw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts/tilew.png b/awesome/.config/awesome/themes/otherideas/layouts/tilew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/dwindle.png b/awesome/.config/awesome/themes/otherideas/layouts2/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/fairh.png b/awesome/.config/awesome/themes/otherideas/layouts2/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/fairv.png b/awesome/.config/awesome/themes/otherideas/layouts2/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/floating.png b/awesome/.config/awesome/themes/otherideas/layouts2/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/floating_a.png b/awesome/.config/awesome/themes/otherideas/layouts2/floating_a.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/fullscreen.png b/awesome/.config/awesome/themes/otherideas/layouts2/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/magnifier.png b/awesome/.config/awesome/themes/otherideas/layouts2/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/max.png b/awesome/.config/awesome/themes/otherideas/layouts2/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/spiral.png b/awesome/.config/awesome/themes/otherideas/layouts2/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/tile.png b/awesome/.config/awesome/themes/otherideas/layouts2/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/tilebottom.png b/awesome/.config/awesome/themes/otherideas/layouts2/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/tileleft.png b/awesome/.config/awesome/themes/otherideas/layouts2/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/layouts2/tiletop.png b/awesome/.config/awesome/themes/otherideas/layouts2/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/submenu.png b/awesome/.config/awesome/themes/otherideas/submenu.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/taglist/squarefw.png b/awesome/.config/awesome/themes/otherideas/taglist/squarefw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/taglist/squarew.png b/awesome/.config/awesome/themes/otherideas/taglist/squarew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/tasklist/floating.png b/awesome/.config/awesome/themes/otherideas/tasklist/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/tasklist/floatingw.png b/awesome/.config/awesome/themes/otherideas/tasklist/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/tasklist/square.png b/awesome/.config/awesome/themes/otherideas/tasklist/square.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/tasklist/square2.png b/awesome/.config/awesome/themes/otherideas/tasklist/square2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/theme.lua b/awesome/.config/awesome/themes/otherideas/theme.lua @@ -0,0 +1,133 @@ +-- otherideas, awesome3 theme, by Andreas Persson (greyscale, grey) + +--{{{ Main +local awful = require("awful") +awful.util = require("awful.util") + +theme = {} + +home = os.getenv("HOME") +config = awful.util.getdir("config") +shared = "/usr/share/awesome" +if not awful.util.file_readable(shared .. "/icons/awesome16.png") then + shared = "/usr/share/local/awesome" +end +sharedicons = shared .. "/icons" +sharedthemes = shared .. "/themes" +themes = config .. "/themes" +themename = "/otherideas" +if not awful.util.file_readable(themes .. themename .. "/theme.lua") then + themes = sharedthemes +end +themedir = themes .. themename + +wallpaper1 = themedir .. "/background.jpg" +wallpaper2 = themedir .. "/background.png" +wallpaper3 = sharedthemes .. "/zenburn/zenburn-background.png" +wallpaper4 = sharedthemes .. "/default/background.png" +wpscript = home .. "/.wallpaper" + +if awful.util.file_readable(wallpaper1) then + theme.wallpaper = wallpaper1 +elseif awful.util.file_readable(wallpaper2) then + theme.wallpaper = wallpaper2 +elseif awful.util.file_readable(wpscript) then + theme.wallpaper_cmd = { "sh " .. wpscript } +elseif awful.util.file_readable(wallpaper3) then + theme.wallpaper = wallpaper3 +else + theme.wallpaper = wallpaper4 +end +--}}} + +theme.font = "Tamsyn 11" +-- theme.font = "ProggyTinyTTSZ 12" + +theme.bg_normal = "#121212" +theme.bg_focus = "#212121" +theme.bg_urgent = "#212121" +theme.bg_minimize = "#121212" + +theme.fg_normal = "#5fafff" +theme.fg_focus = "#ff8700" +theme.fg_urgent = "#ff0056" +theme.fg_minimize = "#ababab" + +theme.border_width = "1" +theme.border_normal = "#515151" +theme.border_focus = "#ff8700" +theme.border_marked = "#ff0056" + +-- 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 = themedir .. "/taglist/squarefw.png" +theme.taglist_squares_unsel = themedir .. "/taglist/squarew.png" + +theme.tasklist_square = themedir .. "/tasklist/square2.png" +theme.tasklist_floating_icon = themedir .. "/tasklist/floatingw.png" + +-- Variables set for theming the menu: +-- menu_[bg|fg]_[normal|focus] +-- menu_[border_color|border_width] +theme.menu_submenu_icon = themedir .. "/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 = themedir .. "/titlebar/close_normal.png" +theme.titlebar_close_button_focus = themedir .. "/titlebar/close_focus.png" + +theme.titlebar_ontop_button_normal_inactive = themedir .. "/titlebar/ontop_normal_inactive.png" +theme.titlebar_ontop_button_focus_inactive = themedir .. "/titlebar/ontop_focus_inactive.png" +theme.titlebar_ontop_button_normal_active = themedir .. "/titlebar/ontop_normal_active.png" +theme.titlebar_ontop_button_focus_active = themedir .. "/titlebar/ontop_focus_active.png" + +theme.titlebar_sticky_button_normal_inactive = themedir .. "/titlebar/sticky_normal_inactive.png" +theme.titlebar_sticky_button_focus_inactive = themedir .. "/titlebar/sticky_focus_inactive.png" +theme.titlebar_sticky_button_normal_active = themedir .. "/titlebar/sticky_normal_active.png" +theme.titlebar_sticky_button_focus_active = themedir .. "/titlebar/sticky_focus_active.png" + +theme.titlebar_floating_button_normal_inactive = themedir .. "/titlebar/floating_normal_inactive.png" +theme.titlebar_floating_button_focus_inactive = themedir .. "/titlebar/floating_focus_inactive.png" +theme.titlebar_floating_button_normal_active = themedir .. "/titlebar/floating_normal_active.png" +theme.titlebar_floating_button_focus_active = themedir .. "/titlebar/floating_focus_active.png" + +theme.titlebar_maximized_button_normal_inactive = themedir .. "/titlebar/maximized_normal_inactive.png" +theme.titlebar_maximized_button_focus_inactive = themedir .. "/titlebar/maximized_focus_inactive.png" +theme.titlebar_maximized_button_normal_active = themedir .. "/titlebar/maximized_normal_active.png" +theme.titlebar_maximized_button_focus_active = themedir .. "/titlebar/maximized_focus_active.png" + +-- You can use your own layout icons like this: +theme.layout_fairh = themedir .. "/layouts2/fairh.png" +theme.layout_fairv = themedir .. "/layouts2/fairv.png" +theme.layout_floating = themedir .. "/layouts2/floating.png" +theme.layout_magnifier = themedir .. "/layouts2/magnifier.png" +theme.layout_max = themedir .. "/layouts2/max.png" +theme.layout_fullscreen = themedir .. "/layouts2/fullscreen.png" +theme.layout_tilebottom = themedir .. "/layouts2/tilebottom.png" +theme.layout_tileleft = themedir .. "/layouts2/tileleft.png" +theme.layout_tile = themedir .. "/layouts2/tile.png" +theme.layout_tiletop = themedir .. "/layouts2/tiletop.png" +theme.layout_spiral = themedir .. "/layouts2/spiral.png" +theme.layout_dwindle = themedir .. "/layouts2/dwindle.png" + +theme.awesome_icon = themedir .. "/awesome14.png" + +-- lain related +theme.useless_gap_width = 10 + +return theme diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/close_focus.png b/awesome/.config/awesome/themes/otherideas/titlebar/close_focus.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/close_normal.png b/awesome/.config/awesome/themes/otherideas/titlebar/close_normal.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/floating_focus_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/floating_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/floating_focus_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/floating_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/floating_normal_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/floating_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/floating_normal_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/floating_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/maximized_focus_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/maximized_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/maximized_focus_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/maximized_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/maximized_normal_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/maximized_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/maximized_normal_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/maximized_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/ontop_focus_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/ontop_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/ontop_focus_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/ontop_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/ontop_normal_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/ontop_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/ontop_normal_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/ontop_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/sticky_focus_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/sticky_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/sticky_focus_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/sticky_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/sticky_normal_active.png b/awesome/.config/awesome/themes/otherideas/titlebar/sticky_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/otherideas/titlebar/sticky_normal_inactive.png b/awesome/.config/awesome/themes/otherideas/titlebar/sticky_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/awesome14.png b/awesome/.config/awesome/themes/pyratesoft/awesome14.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/awesome16.png b/awesome/.config/awesome/themes/pyratesoft/awesome16.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/background.jpg b/awesome/.config/awesome/themes/pyratesoft/background.jpg Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/background.png b/awesome/.config/awesome/themes/pyratesoft/background.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/background/bg.png b/awesome/.config/awesome/themes/pyratesoft/background/bg.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/background/bg2.png b/awesome/.config/awesome/themes/pyratesoft/background/bg2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/dwindle.png b/awesome/.config/awesome/themes/pyratesoft/layouts/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/dwindlew.png b/awesome/.config/awesome/themes/pyratesoft/layouts/dwindlew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/fairh.png b/awesome/.config/awesome/themes/pyratesoft/layouts/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/fairhw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/fairhw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/fairv.png b/awesome/.config/awesome/themes/pyratesoft/layouts/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/fairvw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/fairvw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/floating.png b/awesome/.config/awesome/themes/pyratesoft/layouts/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/floatingw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/fullscreen.png b/awesome/.config/awesome/themes/pyratesoft/layouts/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/fullscreenw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/fullscreenw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/magnifier.png b/awesome/.config/awesome/themes/pyratesoft/layouts/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/magnifierw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/magnifierw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/max.png b/awesome/.config/awesome/themes/pyratesoft/layouts/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/maxw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/maxw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/spiral.png b/awesome/.config/awesome/themes/pyratesoft/layouts/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/spiralw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/spiralw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tile.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tilebottom.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tilebottomw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tilebottomw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tileleft.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tileleftw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tileleftw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tiletop.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tiletopw.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tiletopw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts/tilew.png b/awesome/.config/awesome/themes/pyratesoft/layouts/tilew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/dwindle.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/fairh.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/fairv.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/floating.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/floating_a.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/floating_a.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/fullscreen.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/magnifier.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/max.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/spiral.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/tile.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/tilebottom.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/tileleft.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/layouts2/tiletop.png b/awesome/.config/awesome/themes/pyratesoft/layouts2/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/submenu.png b/awesome/.config/awesome/themes/pyratesoft/submenu.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/taglist/squarefw.png b/awesome/.config/awesome/themes/pyratesoft/taglist/squarefw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/taglist/squarew.png b/awesome/.config/awesome/themes/pyratesoft/taglist/squarew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/tasklist/floating.png b/awesome/.config/awesome/themes/pyratesoft/tasklist/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/tasklist/floatingw.png b/awesome/.config/awesome/themes/pyratesoft/tasklist/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/tasklist/square.png b/awesome/.config/awesome/themes/pyratesoft/tasklist/square.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/tasklist/square2.png b/awesome/.config/awesome/themes/pyratesoft/tasklist/square2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/theme.lua b/awesome/.config/awesome/themes/pyratesoft/theme.lua @@ -0,0 +1,134 @@ +-- futuremyth-min, awesome3 theme, by pyratebeard +-- A minimal theme + +--{{{ Main +local awful = require("awful") +awful.util = require("awful.util") + +theme = {} + +home = os.getenv("HOME") +config = awful.util.getdir("config") +shared = "/usr/share/awesome" +if not awful.util.file_readable(shared .. "/icons/awesome16.png") then + shared = "/usr/share/local/awesome" +end +sharedicons = shared .. "/icons" +sharedthemes = shared .. "/themes" +themes = config .. "/themes" +themename = "/pyratesoft" +if not awful.util.file_readable(themes .. themename .. "/theme.lua") then + themes = sharedthemes +end +themedir = themes .. themename + +wallpaper1 = themedir .. "/background.jpg" +wallpaper2 = themedir .. "/background.png" +wallpaper3 = sharedthemes .. "/zenburn/zenburn-background.png" +wallpaper4 = sharedthemes .. "/default/background.png" +wpscript = home .. "/.wallpaper" + +if awful.util.file_readable(wallpaper1) then + theme.wallpaper = wallpaper1 +elseif awful.util.file_readable(wallpaper2) then + theme.wallpaper = wallpaper2 +elseif awful.util.file_readable(wpscript) then + theme.wallpaper_cmd = { "sh " .. wpscript } +elseif awful.util.file_readable(wallpaper3) then + theme.wallpaper = wallpaper3 +else + theme.wallpaper = wallpaper4 +end +--}}} + +theme.font = "Tamsyn 11" +-- theme.font = "ProggyTinyTTSZ 12" + +theme.bg_normal = "#121212" +theme.bg_focus = "#212121" +theme.bg_urgent = "#212121" +theme.bg_minimize = "#121212" + +theme.fg_normal = "#d9d9d9" +theme.fg_focus = "#01c8e5" +theme.fg_urgent = "#ff0056" +theme.fg_minimize = "#ababab" + +theme.border_width = "2" +theme.border_normal = "#515151" +theme.border_focus = "#01c8e5" +theme.border_marked = "#ff0056" + +-- 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 = themedir .. "/taglist/squarefw.png" +theme.taglist_squares_unsel = themedir .. "/taglist/squarew.png" + +theme.tasklist_square = themedir .. "/tasklist/square2.png" +theme.tasklist_floating_icon = themedir .. "/tasklist/floatingw.png" + +-- Variables set for theming the menu: +-- menu_[bg|fg]_[normal|focus] +-- menu_[border_color|border_width] +theme.menu_submenu_icon = themedir .. "/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 = themedir .. "/titlebar/close_normal.png" +theme.titlebar_close_button_focus = themedir .. "/titlebar/close_focus.png" + +theme.titlebar_ontop_button_normal_inactive = themedir .. "/titlebar/ontop_normal_inactive.png" +theme.titlebar_ontop_button_focus_inactive = themedir .. "/titlebar/ontop_focus_inactive.png" +theme.titlebar_ontop_button_normal_active = themedir .. "/titlebar/ontop_normal_active.png" +theme.titlebar_ontop_button_focus_active = themedir .. "/titlebar/ontop_focus_active.png" + +theme.titlebar_sticky_button_normal_inactive = themedir .. "/titlebar/sticky_normal_inactive.png" +theme.titlebar_sticky_button_focus_inactive = themedir .. "/titlebar/sticky_focus_inactive.png" +theme.titlebar_sticky_button_normal_active = themedir .. "/titlebar/sticky_normal_active.png" +theme.titlebar_sticky_button_focus_active = themedir .. "/titlebar/sticky_focus_active.png" + +theme.titlebar_floating_button_normal_inactive = themedir .. "/titlebar/floating_normal_inactive.png" +theme.titlebar_floating_button_focus_inactive = themedir .. "/titlebar/floating_focus_inactive.png" +theme.titlebar_floating_button_normal_active = themedir .. "/titlebar/floating_normal_active.png" +theme.titlebar_floating_button_focus_active = themedir .. "/titlebar/floating_focus_active.png" + +theme.titlebar_maximized_button_normal_inactive = themedir .. "/titlebar/maximized_normal_inactive.png" +theme.titlebar_maximized_button_focus_inactive = themedir .. "/titlebar/maximized_focus_inactive.png" +theme.titlebar_maximized_button_normal_active = themedir .. "/titlebar/maximized_normal_active.png" +theme.titlebar_maximized_button_focus_active = themedir .. "/titlebar/maximized_focus_active.png" + +-- You can use your own layout icons like this: +theme.layout_fairh = themedir .. "/layouts2/fairh.png" +theme.layout_fairv = themedir .. "/layouts2/fairv.png" +theme.layout_floating = themedir .. "/layouts2/floating.png" +theme.layout_magnifier = themedir .. "/layouts2/magnifier.png" +theme.layout_max = themedir .. "/layouts2/max.png" +theme.layout_fullscreen = themedir .. "/layouts2/fullscreen.png" +theme.layout_tilebottom = themedir .. "/layouts2/tilebottom.png" +theme.layout_tileleft = themedir .. "/layouts2/tileleft.png" +theme.layout_tile = themedir .. "/layouts2/tile.png" +theme.layout_tiletop = themedir .. "/layouts2/tiletop.png" +theme.layout_spiral = themedir .. "/layouts2/spiral.png" +theme.layout_dwindle = themedir .. "/layouts2/dwindle.png" + +theme.awesome_icon = themedir .. "/awesome14.png" + +-- lain related +theme.useless_gap_width = 10 + +return theme diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/close_focus.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/close_focus.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/close_normal.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/close_normal.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_focus_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_focus_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_normal_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_normal_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/floating_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_focus_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_focus_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_normal_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_normal_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/maximized_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_focus_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_focus_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_normal_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_normal_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/ontop_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_focus_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_focus_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_focus_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_focus_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_normal_active.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_normal_active.png Binary files differ. diff --git a/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_normal_inactive.png b/awesome/.config/awesome/themes/pyratesoft/titlebar/sticky_normal_inactive.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/awesome14.png b/awesome/.config/awesome/themes/watchdog/awesome14.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/awesome16.png b/awesome/.config/awesome/themes/watchdog/awesome16.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/background.jpg b/awesome/.config/awesome/themes/watchdog/background.jpg Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/background.png b/awesome/.config/awesome/themes/watchdog/background.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/background/bg.png b/awesome/.config/awesome/themes/watchdog/background/bg.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/background/bg2.png b/awesome/.config/awesome/themes/watchdog/background/bg2.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/dwindle.png b/awesome/.config/awesome/themes/watchdog/layouts/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/dwindlew.png b/awesome/.config/awesome/themes/watchdog/layouts/dwindlew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/fairh.png b/awesome/.config/awesome/themes/watchdog/layouts/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/fairhw.png b/awesome/.config/awesome/themes/watchdog/layouts/fairhw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/fairv.png b/awesome/.config/awesome/themes/watchdog/layouts/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/fairvw.png b/awesome/.config/awesome/themes/watchdog/layouts/fairvw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/floating.png b/awesome/.config/awesome/themes/watchdog/layouts/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/floatingw.png b/awesome/.config/awesome/themes/watchdog/layouts/floatingw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/fullscreen.png b/awesome/.config/awesome/themes/watchdog/layouts/fullscreen.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/fullscreenw.png b/awesome/.config/awesome/themes/watchdog/layouts/fullscreenw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/magnifier.png b/awesome/.config/awesome/themes/watchdog/layouts/magnifier.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/magnifierw.png b/awesome/.config/awesome/themes/watchdog/layouts/magnifierw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/max.png b/awesome/.config/awesome/themes/watchdog/layouts/max.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/maxw.png b/awesome/.config/awesome/themes/watchdog/layouts/maxw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/spiral.png b/awesome/.config/awesome/themes/watchdog/layouts/spiral.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/spiralw.png b/awesome/.config/awesome/themes/watchdog/layouts/spiralw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tile.png b/awesome/.config/awesome/themes/watchdog/layouts/tile.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tilebottom.png b/awesome/.config/awesome/themes/watchdog/layouts/tilebottom.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tilebottomw.png b/awesome/.config/awesome/themes/watchdog/layouts/tilebottomw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tileleft.png b/awesome/.config/awesome/themes/watchdog/layouts/tileleft.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tileleftw.png b/awesome/.config/awesome/themes/watchdog/layouts/tileleftw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tiletop.png b/awesome/.config/awesome/themes/watchdog/layouts/tiletop.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tiletopw.png b/awesome/.config/awesome/themes/watchdog/layouts/tiletopw.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts/tilew.png b/awesome/.config/awesome/themes/watchdog/layouts/tilew.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts2/dwindle.png b/awesome/.config/awesome/themes/watchdog/layouts2/dwindle.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts2/fairh.png b/awesome/.config/awesome/themes/watchdog/layouts2/fairh.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts2/fairv.png b/awesome/.config/awesome/themes/watchdog/layouts2/fairv.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts2/floating.png b/awesome/.config/awesome/themes/watchdog/layouts2/floating.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts2/floating_a.png b/awesome/.config/awesome/themes/watchdog/layouts2/floating_a.png Binary files differ. diff --git a/awesome/.config/awesome/themes/watchdog/layouts2/fullscreen.png b/awesome/.config/awesome/themes/watchdog/layouts2/fullscreen.png Binary files diffe