103
awesome/widgets/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
Widgets
|
||||
-------
|
||||
This directory contains a list of widget that you can use in your theme.
|
||||
|
||||
## Existing Widgets
|
||||
|
||||
### Temperature
|
||||
A widget that shows current CPU temperature and changes color as the temperature gets higher. It even warns the user when the temperature reaches critical levels.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
In case you don't notice the red icon, the widget will grab your attention via a message:
|
||||

|
||||
|
||||
To use this widget, simply add the following to your `rc.lua`:
|
||||
|
||||
myTempWidget = load_widget({
|
||||
widget = "widgets.temperature.widget"
|
||||
})
|
||||
|
||||
And then add the widget to your wibox (here is an example, although your code may look different):
|
||||
|
||||
right_layout:add(myTempWidget)
|
||||
|
||||
You could also add an optional callback to `load_widget` that determines when to show/hide the temperature widget:
|
||||
|
||||
myTempWidget = load_widget({
|
||||
widget = "widgets.temperature.temp",
|
||||
zenstate = function(t) if t < 60 then return true end return false end,
|
||||
})
|
||||
|
||||
The above example will hide temperature widget when the temperature falls below 60 degrees and show it when it goes above.
|
||||
|
||||
|
||||
### Volume
|
||||
Allow user to control volume via the keyboard volume keys and see feedback. This widget is compatible with pulseaudio and automatically gets volume of the relevant output (i.e. if you've switched to HDMI, you'll be controlling the HDMI volume).
|
||||

|
||||

|
||||

|
||||
|
||||
Install this widget the usual way:
|
||||
|
||||
volume = load_widget({
|
||||
widget = "widgets.volume.widget"
|
||||
})
|
||||
|
||||
Since this widget has no icon, `zenstate` does nothing (I use Maato's volumeicon for icon instead, which works great as an icon but not so well with actual audio controls, which is where this widget excels). To map this widget to your volume keys, add the following in your rc.lua clientkeys section:
|
||||
|
||||
awful.key({ }, "XF86AudioRaiseVolume", volume.up),
|
||||
awful.key({ }, "XF86AudioLowerVolume", volume.down),
|
||||
awful.key({ }, "XF86AudioMute", volume.toggle),
|
||||
|
||||
|
||||
## Memory Usage
|
||||
Display memory usage as a percentage and show more detail, including biggest-offending processes when user hovers over. Like temperature widget, color adjusts automatically based on how much memory you use and informs you when the status reaches critical.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
As with temperature widget, the widget will notify you when the memory usage gets uncomfortably high but before the point of no return:
|
||||
|
||||

|
||||
|
||||
Hover example:
|
||||
|
||||

|
||||
|
||||
To use this widget, simply add the following to your `rc.lua`:
|
||||
|
||||
memoryWidget = load_widget({
|
||||
widget = "widgets.memory.widget"
|
||||
})
|
||||
|
||||
As with temperature widget, this widget accepts a zenstate parameter telling it when to hide, if ever.
|
||||
|
||||
|
||||
## Adding New Widgets
|
||||
Interested in adding your own widget to `Zen` library? Great!
|
||||
|
||||
Make sure your widget follows these `Zen` guidelines, otherwise your pull request may get rejected:
|
||||
|
||||
- Your widget must embrace `Zen` philosophy (it must be as minimalistic as possible, remember that "less is more", don't confuse user with excessive options and prompts, don't take up unnecessary real estate on the screen, try to minimize the number of dependencies your widget brings in)
|
||||
- Your widget must catch all errors that it could generate (It doesn't matter if `awesome` or `bash` is at fault, if as a result of adding your widget user will start seeing occasional red notifications from awesome, your widget will be rejected)
|
||||
- Your widget must not be dominated by an existing `Zen` widget or perform identical functionality (there is no reason to have 50 volume widgets, for example, they just add clutter and confusion, but if you think your widget is superior to an existing widget by all means submit it). I don't want this repository to become another widget graveyard.
|
||||
- Your widget must follow `Zen` architecture, it must conform to the `load_widget` options. That basically means the following:
|
||||
- You must include a handler for user-defined `zenstate` callback, a function that determines when the widget can hide or change state (you can define inputs for the callback and document them in this README, the function will return a boolean identifying true (show) and false (hide) states)
|
||||
- Your widget must be named `widget` by the end of your script, since this is what `load_widget` script assumes as the name and returns to the user
|
||||
- You must include a brief description and screenshot or two of your widget, awesome WM is cluttered with undocumented widgets that users have no way of previewing before installing. Once again, I don't want this repository to become another widget graveyard.
|
||||
|
||||
|
||||
## To Add
|
||||
- CPU Usage
|
||||
- Audio Player
|
||||
- Calendar
|
||||
- Battery
|
||||
- Network
|
||||
- Define/Search Word
|
||||
|
||||
|
||||
BIN
awesome/widgets/memory/1.png
Normal file
|
After Width: | Height: | Size: 510 B |
BIN
awesome/widgets/memory/2.png
Normal file
|
After Width: | Height: | Size: 730 B |
BIN
awesome/widgets/memory/3.png
Normal file
|
After Width: | Height: | Size: 851 B |
BIN
awesome/widgets/memory/hover_example.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
awesome/widgets/memory/max.png
Normal file
|
After Width: | Height: | Size: 925 B |
15
awesome/widgets/memory/mem.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 Alexander Tsepkov
|
||||
|
||||
#
|
||||
colorize_title='1s/\(.*\)/<span foreground="#669900"><b>\1<\/b><\/span>/'
|
||||
case "$1" in
|
||||
simple)
|
||||
free | grep Mem | awk '{printf("%.1f\n", $3/$2 * 100)}'
|
||||
;;
|
||||
summary)
|
||||
free -h | sed -e "$colorize_title"
|
||||
echo ''
|
||||
ps -eo pid:6,time:10,pmem:6,rss:8,comm --sort -rss | head -n 20 | sed -e "$colorize_title"
|
||||
;;
|
||||
esac
|
||||
BIN
awesome/widgets/memory/notification_example.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
85
awesome/widgets/memory/widget.lua
Normal file
@@ -0,0 +1,85 @@
|
||||
-- Alexander Tsepkov, 2015
|
||||
--
|
||||
-- Memory Monitor for awesome that changes color as the memory usage goes up
|
||||
-- dependency: FontAwesome
|
||||
|
||||
|
||||
local awful = require("awful")
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
|
||||
local last_id
|
||||
widget = wibox.widget.textbox()
|
||||
function testmem()
|
||||
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/widgets/memory/mem.sh simple")
|
||||
if fd then
|
||||
-- occasionally awesome craps out for no reason running the operation
|
||||
-- and fd is nil, do nothing in that case (aside from ignoring the value
|
||||
-- rather than throwing an error), it will fix itself next run
|
||||
local memstr = fd:read("*all")
|
||||
local mem = tonumber(memstr)
|
||||
fd:close()
|
||||
local color
|
||||
local font = "<span font='FontAwesome 8' "
|
||||
if mem > 94 then
|
||||
color = font .. "color='#FF0000'>"
|
||||
last_id = naughty.notify({
|
||||
title = "High Memory Usage",
|
||||
text = "Consider closing some processes to prevent miserable experience.",
|
||||
preset = naughty.config.presets.critical,
|
||||
replaces_id = last_id,
|
||||
icon = os.getenv("HOME") .. "/.config/awesome/widgets/memory/" .. "max.png"
|
||||
}).id
|
||||
elseif mem > 85 then
|
||||
color = font .. "color='#FF8000'>"
|
||||
elseif mem > 75 then
|
||||
color = font .. "color='#F5F549'>"
|
||||
else
|
||||
color = font .. "color='#669900'>"
|
||||
end
|
||||
|
||||
if widget.zenstate ~= nil then
|
||||
if widget.zenstate(mem) then
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
return color .. "" .. mem .. " </span>"
|
||||
end
|
||||
return "N/A " -- something failed
|
||||
end
|
||||
|
||||
-- to display on hover event
|
||||
local summary = nil
|
||||
function show_tooltip()
|
||||
local font = 'monospace 8'
|
||||
local text_color = '#FFFFFF'
|
||||
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/widgets/memory/mem.sh summary")
|
||||
local str = fd:read("*all")
|
||||
local content = string.format('<span font="%s" foreground="%s">%s</span>', font, text_color, str)
|
||||
summary = naughty.notify({
|
||||
-- title = "Memory Usage",
|
||||
text = content,
|
||||
timeout = 0,
|
||||
hover_timeout = 0.5,
|
||||
width = 60*8
|
||||
})
|
||||
end
|
||||
|
||||
function hide_tooltip()
|
||||
if summary ~= nil then
|
||||
naughty.destroy(summary)
|
||||
end
|
||||
end
|
||||
|
||||
widget:set_markup(testmem())
|
||||
widget:connect_signal("mouse::enter", show_tooltip)
|
||||
widget:connect_signal("mouse::leave", hide_tooltip)
|
||||
|
||||
-- update every 30 secs
|
||||
memtimer = timer({ timeout = 30 })
|
||||
memtimer:connect_signal("timeout", function()
|
||||
widget:set_markup(testmem())
|
||||
end)
|
||||
memtimer:start()
|
||||
BIN
awesome/widgets/temperature/1.png
Normal file
|
After Width: | Height: | Size: 654 B |
BIN
awesome/widgets/temperature/2.png
Normal file
|
After Width: | Height: | Size: 639 B |
BIN
awesome/widgets/temperature/3.png
Normal file
|
After Width: | Height: | Size: 675 B |
BIN
awesome/widgets/temperature/4.png
Normal file
|
After Width: | Height: | Size: 602 B |
BIN
awesome/widgets/temperature/hot.png
Normal file
|
After Width: | Height: | Size: 859 B |
BIN
awesome/widgets/temperature/notification_example.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
4
awesome/widgets/temperature/sensors.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2015 Alexander Tsepkov
|
||||
|
||||
sensors | awk '/^Core/ {t=substr($3,2,4);if (t>max) max=t} END {print max}'
|
||||
56
awesome/widgets/temperature/widget.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
-- Alexander Tsepkov, 2015
|
||||
--
|
||||
-- Temperature Monitor for awesome that changes color as the temperature goes up
|
||||
-- dependency: FontAwesome
|
||||
|
||||
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local last_id
|
||||
widget = wibox.widget.textbox()
|
||||
function testtemps()
|
||||
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/widgets/temperature/sensors.sh")
|
||||
if fd then
|
||||
-- occasionally awesome craps out for no reason running the operation
|
||||
-- and fd is nil, do nothing in that case (aside from ignoring the value
|
||||
-- rather than throwing an error), it will fix itself next run
|
||||
local tempstr = fd:read("*all")
|
||||
local temp = tonumber(tempstr)
|
||||
fd:close()
|
||||
local color
|
||||
local font = "<span font='FontAwesome 8' "
|
||||
if temp > 90 then
|
||||
color = font .. "color='#FF0000'>"
|
||||
last_id = naughty.notify({
|
||||
title = "Temperature Critical",
|
||||
text = "CPU temperature is dangerously hot, turn it off to prevent damage.",
|
||||
preset = naughty.config.presets.critical,
|
||||
replaces_id = last_id,
|
||||
icon = os.getenv("HOME") .. "/.config/awesome/widgets/temperature/" .. "hot.png"
|
||||
}).id
|
||||
elseif temp > 80 then
|
||||
color = font .. "color='#FF8000'>"
|
||||
elseif temp > 70 then
|
||||
color = font .. "color='#F5F549'>"
|
||||
else
|
||||
color = font .. "color='#669900'>"
|
||||
end
|
||||
|
||||
if widget.zenstate ~= nil then
|
||||
if widget.zenstate(temp) then
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
return color .. "" .. temp .. " </span>"
|
||||
end
|
||||
return "N/A " -- something failed
|
||||
end
|
||||
|
||||
widget:set_markup(testtemps())
|
||||
|
||||
-- update every 30 secs
|
||||
temptimer = timer({ timeout = 30 })
|
||||
temptimer:connect_signal("timeout", function() widget:set_markup(testtemps()) end)
|
||||
temptimer:start()
|
||||
BIN
awesome/widgets/volume/1.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
awesome/widgets/volume/2.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
awesome/widgets/volume/3.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
awesome/widgets/volume/audio-0.png
Normal file
|
After Width: | Height: | Size: 1015 B |
BIN
awesome/widgets/volume/audio-1.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
awesome/widgets/volume/audio-2.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
awesome/widgets/volume/audio-3.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
awesome/widgets/volume/audio-muted.png
Normal file
|
After Width: | Height: | Size: 872 B |
52
awesome/widgets/volume/pa-vol.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 Alexander Tsepkov
|
||||
|
||||
|
||||
#SINK_NAME="alsa_output.pci-0000_00_1b.0.analog-stereo"
|
||||
#SINK_NAME="alsa_output.pci-0000_00_1b.0.hdmi-stereo"
|
||||
SOUND_DEVICE=`pacmd dump | grep -P "^set-card-profile" | grep stereo | cut -d: -f2 | cut -d+ -f1`
|
||||
SINK_NAME="alsa_output.pci-0000_00_1b.0.$SOUND_DEVICE"
|
||||
VOL_STEP="0x01000"
|
||||
|
||||
MUTE_STATE=`pacmd dump | grep -P "^set-sink-mute $SINK_NAME\s+" | perl -p -i -e 's/.+\s(yes|no)$/$1/'`
|
||||
VOL_NOW=`pacmd dump | grep -P "^set-sink-volume $SINK_NAME\s+" | perl -p -i -e 's/.+\s(.x.+)$/$1/'`
|
||||
VOL_MAX=$((0x10000))
|
||||
|
||||
case "$1" in
|
||||
plus)
|
||||
if [ $MUTE_STATE = yes ]; then
|
||||
echo "Muted"
|
||||
else
|
||||
VOL_NEW=$((VOL_NOW + VOL_STEP))
|
||||
if [ $VOL_NEW -gt $VOL_MAX ]
|
||||
then
|
||||
VOL_NEW=$VOL_MAX
|
||||
fi
|
||||
pactl set-sink-volume $SINK_NAME `printf "0x%X" $VOL_NEW`
|
||||
echo "$((100*VOL_NEW / VOL_MAX))%"
|
||||
fi
|
||||
|
||||
;;
|
||||
minus)
|
||||
if [ $MUTE_STATE = yes ]; then
|
||||
echo "Muted"
|
||||
else
|
||||
VOL_NEW=$((VOL_NOW - VOL_STEP))
|
||||
if [ $(($VOL_NEW)) -lt $((0x00000)) ]
|
||||
then
|
||||
VOL_NEW=$((0x00000))
|
||||
fi
|
||||
pactl set-sink-volume $SINK_NAME `printf "0x%X" $VOL_NEW`
|
||||
echo "$((100*VOL_NEW / VOL_MAX))%"
|
||||
fi
|
||||
|
||||
;;
|
||||
mute)
|
||||
if [ $MUTE_STATE = no ]; then
|
||||
pactl set-sink-mute $SINK_NAME 1
|
||||
echo "Muted"
|
||||
elif [ $MUTE_STATE = yes ]; then
|
||||
pactl set-sink-mute $SINK_NAME 0
|
||||
echo "$((100*VOL_NOW / VOL_MAX))%"
|
||||
fi
|
||||
esac
|
||||
52
awesome/widgets/volume/widget.lua
Normal file
@@ -0,0 +1,52 @@
|
||||
-- Alexander Tsepkov, 2015
|
||||
--
|
||||
-- Minimalistic Volume Widget that works with multiple output sources
|
||||
-- dependency: FontAwesome
|
||||
|
||||
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
|
||||
local last_id
|
||||
local vol_muted
|
||||
function mixercommand(command)
|
||||
local fd = io.popen(os.getenv("HOME") .. "/.config/awesome/pa-vol.sh " .. command)
|
||||
local status = fd:read("*all")
|
||||
fd:close()
|
||||
local pic = os.getenv("HOME") .. "/.config/awesome/widgets/volume/"
|
||||
local value
|
||||
if status == "Muted\n" then
|
||||
pic = pic .. "audio-muted.png"
|
||||
else
|
||||
-- dividing by 26 is a little cheat to prevent overflow on 100%
|
||||
value = math.floor(tonumber(string.sub(status:gsub("%s+$", ""), 0, -2)) / 26)
|
||||
pic = pic .. "audio-" .. value .. ".png"
|
||||
end
|
||||
last_id = naughty.notify({
|
||||
title = "Volume",
|
||||
text = status,
|
||||
replaces_id = last_id,
|
||||
icon = pic,
|
||||
}).id
|
||||
end
|
||||
function volumeup()
|
||||
mixercommand("plus")
|
||||
end
|
||||
|
||||
function volumedown()
|
||||
mixercommand("minus")
|
||||
end
|
||||
|
||||
function volumetoggle()
|
||||
mixercommand("mute")
|
||||
end
|
||||
|
||||
-- zenstate not applicable bescause there is no volume icon for this widget at all
|
||||
|
||||
-- this widget doesn't have an icon, I use volumeicon instead but I prefer the messages/control through this
|
||||
-- widget instead
|
||||
widget = {
|
||||
up = volumeup,
|
||||
down = volumedown,
|
||||
toggle = volumetoggle,
|
||||
}
|
||||