Better widgets

This commit is contained in:
Thomas Forgione 2018-11-28 15:31:35 +01:00
parent 0801659f6c
commit eff92f7e09
No known key found for this signature in database
GPG Key ID: 203DAEA747F48F41
70 changed files with 2564 additions and 5 deletions

43
awesome-wm-widgets/.gitignore vendored Normal file
View File

@ -0,0 +1,43 @@
# Compiled Lua sources
luac.out
# luarocks build files
*.src.rock
*.zip
*.tar.gz
# Object files
*.o
*.os
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
*.def
*.exp
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# IDEA files
.idea

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2017
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.

View File

@ -0,0 +1,80 @@
# Awesome WM widgets
Set of super simple widgets compatible with Awesome Window Manager v.4+.
![screenshot](./screenshot.png)
or with separators
![screenshot](./screenshot_with_sprtrs.png)
Some more screenshots in this reddit [post](https://www.reddit.com/r/unixporn/comments/8qijmx/awesomewm_dark_theme/)
From left to right:
- [spotify-widget](https://github.com/streetturtle/AwesomeWM/tree/master/spotify-widget) / [rhythmbox-widget](https://github.com/streetturtle/AwesomeWM/tree/master/rhythmbox-widget)
- [cpu-widget](https://github.com/streetturtle/AwesomeWM/tree/master/cpu-widget)
- [weather-widget](https://github.com/streetturtle/AwesomeWM/tree/master/weather-widget)
- [email-widget](https://github.com/streetturtle/AwesomeWM/tree/master/email-widget)
- [brightness-widget](https://github.com/streetturtle/AwesomeWM/tree/master/brightness-widget)
- [volume-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volume-widget)
- [volumebar-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volumebar-widget)
- [volumearc-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volumearc-widget)
- [batteryarc-widget](https://github.com/streetturtle/AwesomeWM/tree/master/batteryarc-widget)
- [battery-widget](https://github.com/streetturtle/AwesomeWM/tree/master/battery-widget)
- [ram-widget](https://github.com/streetturtle/AwesomeWM/tree/master/ram-widget)
- [translate-widget](https://github.com/streetturtle/AwesomeWM/tree/master/translate-widget) (not on the screenshot)
- [spotify-shell](https://github.com/streetturtle/AwesomeWM/tree/master/spotify-shell)
Some of these widgets use [Arc icon theme](https://github.com/horst3180/arc-icon-theme) by default but it could be easily
changed to any other icon theme or custom icons. If you want to have separators between widgets like on the screenshot create text widget with ` : ` and place it between widgets:
```lua
...
sprtr = wibox.widget.textbox()
sprtr:set_text(" : ")
...
sprtr,
volume_icon,
sprtr,
battery_widget,
sprtr,
...
```
# Installation
Clone the repo under **~/.config/awesome/**, then in **rc.lua** add the import of the widget you'd like to use in "require" section on the top of the file:
```lua
local battery_widget = require("awesome-wm-widgets.battery-widget.battery")
```
and then add widget to the wibox (you can search for **mytextclock** and add widget before):
```lua
-- Add widgets to the wibox
s.mywibox:setup {
layout = wibox.layout.align.horizontal,
{ -- Left widgets
...
},
s.mytasklist, -- Middle widget
{ -- Right widgets
...
battery_widget,
mytextclock
...
}
```
You will also need to install [Arc icon theme](https://github.com/horst3180/arc-icon-theme) if widget uses icons. By default it should be installed under **/usr/share/icons/Arc**. If you prefer different installation folder then you'll have to change path to the icons in the source code of the widget you want to use.
# Icons
If you don't want to install Arc icon theme you can just download the icons which are used from the [Arc repository](https://github.com/horst3180/arc-theme).
Or create your own icons with the same name.
In case of any questions/suggestions don't hesitate to contact me, I would be happy to help :)
PRs/issues and st★rs are welcome!

View File

@ -0,0 +1,29 @@
# Battery widget
Simple and easy-to-install widget for Awesome Window Manager.
This widget consists of:
- an icon which shows the battery level:
![Battery Widget](./bat-wid-1.png)
- a pop-up window, which shows up when you hover over an icon:
![Battery Widget](./bat-wid-2.png)
Alternatively you can use a tooltip (check the code):
![Battery Widget](./bat-wid-22.png)
- a pop-up warning message which appears on bottom right corner when battery level is less that 15% (you can get the image [here](https://vk.com/images/stickers/1933/512.png)):
![Battery Widget](./bat-wid-3.png)
Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder.
## Installation
This widget reads the output of acpi tool.
- install `acpi` and check the output:
```bash
$ sudo apt-get install acpi
$ acpi
Battery 0: Discharging, 66%, 02:34:06 remaining
```
Then refer to the [installation](https://github.com/streetturtle/awesome-wm-widgets#installation) section of the repo.

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,135 @@
-------------------------------------------------
-- Battery Widget for Awesome Window Manager
-- Shows the battery status using the ACPI tool
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/battery-widget
-- @author Pavel Makhov
-- @copyright 2017 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local naughty = require("naughty")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
-- acpi sample outputs
-- Battery 0: Discharging, 75%, 01:51:38 remaining
-- Battery 0: Charging, 53%, 00:57:43 until charged
local PATH_TO_ICONS = "/usr/share/icons/Arc/status/symbolic/"
local HOME = os.getenv("HOME")
local battery_widget = wibox.widget {
{
id = "icon",
widget = wibox.widget.imagebox,
resize = false
},
layout = wibox.container.margin(_, 0, 0, 3)
}
-- Popup with battery info
-- One way of creating a pop-up notification - naughty.notify
local notification
local function show_battery_status()
awful.spawn.easy_async([[bash -c 'acpi']],
function(stdout, _, _, _)
notification = naughty.notify{
text = stdout,
title = "Battery status",
timeout = 5, hover_timeout = 0.5,
width = 200,
}
end
)
end
-- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one
--battery_popup = awful.tooltip({objects = {battery_widget}})
-- To use colors from beautiful theme put
-- following lines in rc.lua before require("battery"):
-- beautiful.tooltip_fg = beautiful.fg_normal
-- beautiful.tooltip_bg = beautiful.bg_normal
local function show_battery_warning()
naughty.notify{
icon = HOME .. "/.config/awesome/nichosi.png",
icon_size=100,
text = "Huston, we have a problem",
title = "Battery is dying",
timeout = 5, hover_timeout = 0.5,
position = "bottom_right",
bg = "#F06060",
fg = "#EEE9EF",
width = 300,
}
end
local last_battery_check = os.time()
watch("acpi -i", 10,
function(widget, stdout, stderr, exitreason, exitcode)
local batteryType
local battery_info = {}
local capacities = {}
for s in stdout:gmatch("[^\r\n]+") do
local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*')
if status ~= nil then
table.insert(battery_info, {status = status, charge = tonumber(charge_str)})
else
local cap_str = string.match(s, '.+:.+last full capacity (%d+)')
table.insert(capacities, tonumber(cap_str))
end
end
local capacity = 0
for i, cap in ipairs(capacities) do
capacity = capacity + cap
end
local charge = 0
local status
for i, batt in ipairs(battery_info) do
if batt.charge >= charge then
status = batt.status -- use most charged battery status
-- this is arbitrary, and maybe another metric should be used
end
charge = charge + batt.charge * capacities[i]
end
charge = charge / capacity
if (charge >= 0 and charge < 15) then
batteryType = "battery-empty%s-symbolic"
if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then
-- if 5 minutes have elapsed since the last warning
last_battery_check = time()
show_battery_warning()
end
elseif (charge >= 15 and charge < 40) then batteryType = "battery-caution%s-symbolic"
elseif (charge >= 40 and charge < 60) then batteryType = "battery-low%s-symbolic"
elseif (charge >= 60 and charge < 80) then batteryType = "battery-good%s-symbolic"
elseif (charge >= 80 and charge <= 100) then batteryType = "battery-full%s-symbolic"
end
if status == 'Charging' then
batteryType = string.format(batteryType, '-charging')
else
batteryType = string.format(batteryType, '')
end
widget.icon:set_image(PATH_TO_ICONS .. batteryType .. ".svg")
-- Update popup text
-- battery_popup.text = string.gsub(stdout, "\n$", "")
end,
battery_widget)
battery_widget:connect_signal("mouse::enter", function() show_battery_status() end)
battery_widget:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
return battery_widget

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,45 @@
# Batteryarc widget
This widget is more informative version of [battery widget](https://github.com/streetturtle/awesome-wm-widgets/tree/master/battery-widget).
Depending of the battery status it could look following ways:
- ![10_d](./10_d.png) - less than 15 percent
- ![10_c](./10_c.png) - less than 15 percent, charging
- ![20_d](./20_d.png) - between 15 and 40 percent
- ![20_c](./20_c.png) - between 15 and 40 percent, charging
- ![80_d](./80_d.png) - more than 40 percent
- ![80_c](./80_c.png) - more than 40 percent, charging
Widget uses following beautiful variables with values:
```lua
theme.widget_main_color = "#74aeab"
theme.widget_red = "#e53935"
theme.widget_yellow = "#c0ca33"
theme.widget_green = "#43a047"
theme.widget_black = "#000000"
theme.widget_transparent = "#00000000"
```
which means that you need to copy the code above and paste it in your **theme.lua**. Otherwise you can change colors directly in the widget.
## Installation
Clone repo, include widget and use it in **rc.lua**:
```lua
local batteryarc_widget = require("awesome-wm-widgets.batteryarc-widget.batteryarc")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
batteryarc_widget,
...
```
You can get the icon for warning popup [here](https://vk.com/images/stickers/1933/512.png)
## Troubleshooting
In case of any doubts or questions don't hesitate to raise an [issue](https://github.com/streetturtle/awesome-wm-widgets/issues/new).

View File

@ -0,0 +1,147 @@
local awful = require("awful")
local beautiful = require("beautiful")
local naughty = require("naughty")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local HOME = os.getenv("HOME")
-- only text
local text = wibox.widget {
id = "txt",
font = "Play 5",
widget = wibox.widget.textbox
}
-- mirror the text, because the whole widget will be mirrored after
local mirrored_text = wibox.container.mirror(text, { horizontal = true })
-- mirrored text with background
local mirrored_text_with_background = wibox.container.background(mirrored_text)
local batteryarc = wibox.widget {
mirrored_text_with_background,
max_value = 1,
rounded_edge = true,
thickness = 2,
start_angle = 4.71238898, -- 2pi*3/4
forced_height = 17,
forced_width = 17,
bg = "#ffffff11",
paddings = 2,
widget = wibox.container.arcchart,
set_value = function(self, value)
self.value = value
end,
}
-- mirror the widget, so that chart value increases clockwise
local batteryarc_widget = wibox.container.mirror(batteryarc, { horizontal = true })
local last_battery_check = os.time()
watch("acpi -i", 10,
function(widget, stdout, stderr, exitreason, exitcode)
local batteryType
local battery_info = {}
local capacities = {}
for s in stdout:gmatch("[^\r\n]+") do
local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*')
if status ~= nil then
table.insert(battery_info, {status = status, charge = tonumber(charge_str)})
else
local cap_str = string.match(s, '.+:.+last full capacity (%d+)')
table.insert(capacities, tonumber(cap_str))
end
end
local capacity = 0
for i, cap in ipairs(capacities) do
capacity = capacity + cap
end
local charge = 0
local status
for i, batt in ipairs(battery_info) do
if batt.charge >= charge then
status = batt.status -- use most charged battery status
-- this is arbitrary, and maybe another metric should be used
end
charge = charge + batt.charge * capacities[i]
end
charge = charge / capacity
widget.value = charge / 100
if status == 'Charging' then
mirrored_text_with_background.bg = beautiful.widget_green
mirrored_text_with_background.fg = beautiful.widget_black
else
mirrored_text_with_background.bg = beautiful.widget_transparent
mirrored_text_with_background.fg = beautiful.widget_main_color
end
text.text = charge
if charge < 15 then
batteryarc.colors = { beautiful.widget_red }
if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then
-- if 5 minutes have elapsed since the last warning
last_battery_check = time()
show_battery_warning()
end
elseif charge > 15 and charge < 40 then
batteryarc.colors = { beautiful.widget_yellow }
else
batteryarc.colors = { beautiful.widget_main_color }
end
end,
batteryarc)
-- Popup with battery info
-- One way of creating a pop-up notification - naughty.notify
local notification
function show_battery_status()
awful.spawn.easy_async([[bash -c 'acpi']],
function(stdout, _, _, _)
notification = naughty.notify {
text = stdout,
title = "Battery status",
timeout = 5,
hover_timeout = 0.5,
width = 200,
}
end)
end
batteryarc:connect_signal("mouse::enter", function() show_battery_status() end)
batteryarc:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
-- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one
--battery_popup = awful.tooltip({objects = {battery_widget}})
-- To use colors from beautiful theme put
-- following lines in rc.lua before require("battery"):
-- beautiful.tooltip_fg = beautiful.fg_normal
-- beautiful.tooltip_bg = beautiful.bg_normal
--[[ Show warning notification ]]
function show_battery_warning()
naughty.notify {
icon = HOME .. "/.config/awesome/nichosi.png",
icon_size = 100,
text = "Huston, we have a problem",
title = "Battery is dying",
timeout = 5,
hover_timeout = 0.5,
position = "bottom_right",
bg = "#F06060",
fg = "#EEE9EF",
width = 300,
}
end
return batteryarc_widget

View File

@ -0,0 +1,56 @@
# Brightness widget
![Brightness widget](./br-wid-1.png)
This widget represents current brightness level.
## Installation
Firstly you need to get the current brightness level. There are two options:
- using `xbacklight` command (depending on your video card (I guess) it may or may not work)
To check if it works install xbackligth and check if it works:
```bash
sudo apt-get install xbacklight
xbacklight -get
```
If there is no output it means that it doesn't work, but there is a second option:
- using `light` command
Install it from this git repo: [github.com/haikarainen/light](https://github.com/haikarainen/light) and check if it works but running
```bash
git clone https://github.com/haikarainen/light.git && \
cd ./light && \
sudo make && sudo make install \
light -G
49.18
```
Depending on the chosen option change `GET_BRIGHTNESS_CMD` variable in **brightness.lua**.
Then in **rc.lua** add the import on top of the file and then add widget to the wibox:
```lua
require("awesome-wm-widgets.brightness-widget.brightness")
...
-- Add widgets to the wibox
s.mywibox:setup {
...
{ -- Right widgets
...
brightness_widget
```
## Controls
In order to change brightness by shortcuts you can add them to the `globalkeys` table in the **rc.lua**:
```lua
awful.key({ modkey }, ";", function () awful.spawn("light -A 5") end, {description = "increase brightness", group = "custom"}),
awful.key({ modkey, "Shift"}, ";", function () awful.spawn("light -U 5") end, {description = "decrease brightness", group = "custom"}),
```
On laptop you can use `XF86MonBrightnessUp` and `XF86MonBrightnessDown` keys.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,56 @@
-------------------------------------------------
-- Brightness Widget for Awesome Window Manager
-- Shows the brightness level of the laptop display
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/brightness-widget
-- @author Pavel Makhov
-- @copyright 2017 Pavel Makhov
-------------------------------------------------
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local spawn = require("awful.spawn")
local PATH_TO_ICON = "/usr/share/icons/Arc/status/symbolic/display-brightness-symbolic.svg"
local GET_BRIGHTNESS_CMD = "light -G" -- "xbacklight -get"
local INC_BRIGHTNESS_CMD = "light -A 1" -- "xbacklight -inc 5"
local DEC_BRIGHTNESS_CMD = "light -U 1" -- "xbacklight -dec 5"
local brightness_text = wibox.widget.textbox()
brightness_text:set_font('Play 9')
local brightness_icon = wibox.widget {
{
image = PATH_TO_ICON,
resize = false,
widget = wibox.widget.imagebox,
},
top = 3,
widget = wibox.container.margin
}
local brightness_widget = wibox.widget {
brightness_icon,
brightness_text,
layout = wibox.layout.fixed.horizontal,
}
local update_widget = function(widget, stdout, stderr, exitreason, exitcode)
local brightness_level = tonumber(string.format("%.0f", stdout))
widget:set_text(" " .. brightness_level .. "%")
end,
brightness_widget:connect_signal("button::press", function(_,_,_,button)
if (button == 4) then spawn(INC_BRIGHTNESS_CMD, false)
elseif (button == 5) then spawn(DEC_BRIGHTNESS_CMD, false)
end
spawn.easy_async(GET_BRIGHTNESS_CMD, function(stdout, stderr, exitreason, exitcode)
update_widget(brightness_widget, stdout, stderr, exitreason, exitcode)
end)
end)
watch(GET_BRIGHTNESS_CMD, 1, update_widget, brightness_text)
return brightness_widget

View File

@ -0,0 +1,34 @@
# CPU widget
This widget shows the average CPU load among all cores of the machine:
![screenshot](out.gif)
When the load is more than 80% the graph becomes red. You can easily customize the widget by changing colors, step width, step spacing, width and interval.
## How it works
To measure the load I took Paul Colby's bash [script](http://colby.id.au/calculating-cpu-usage-from-proc-stat/) and rewrote it in Lua, which was quite simple.
So awesome simply reads the first line of /proc/stat:
```bash
$ cat /proc/stat | grep '^cpu '
cpu 197294 718 50102 2002182 3844 0 2724 0 0 0
```
and calculates the percentage.
## Installation
Clone/download repo and use widget in **rc.lua**:
```lua
require("awesome-wm-widgets.cpu-widget.cpu-widget")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
cpu_widget,
...
```

View File

@ -0,0 +1,52 @@
-------------------------------------------------
-- CPU Widget for Awesome Window Manager
-- Shows the current CPU utilization
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/cpu-widget
-- @author Pavel Makhov
-- @copyright 2017 Pavel Makhov
-------------------------------------------------
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local beautiful = require("beautiful")
local cpugraph_widget = wibox.widget {
max_value = 100,
background_color = "#00000000",
forced_width = 50,
step_width = 2,
step_spacing = 1,
widget = wibox.widget.graph
}
--- By default graph widget goes from left to right, so we mirror it and push up a bit
local cpu_widget = wibox.container.margin(wibox.container.mirror(cpugraph_widget, { horizontal = true }), 0, 0, 0, 2)
local total_prev = 0
local idle_prev = 0
watch([[bash -c "cat /proc/stat | grep '^cpu '"]], 1,
function(widget, stdout, stderr, exitreason, exitcode)
local user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice =
stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s')
local total = user + nice + system + idle + iowait + irq + softirq + steal
local diff_idle = idle - idle_prev
local diff_total = total - total_prev
local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10
widget:set_color(diff_usage > 80 and beautiful.widget_red
or beautiful.widget_main_color)
widget:add_value(diff_usage)
total_prev = total
idle_prev = idle
end,
cpugraph_widget
)
return cpu_widget

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,35 @@
# Email widget
This widget consists of an icon with counter which shows number of unread emails: ![email icon](./em-wid-1.png)
and a popup message which appears when mouse hovers over an icon: ![email popup](./em-wid-2.png)
Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder.
## Installation
To install it put **email.lua** and **email-widget** folder under **~/.config/awesome**. Then
- in **email.lua** cahnge path to python scripts;
- in python scripts add your credentials (note that password should be encrypted using pgp for example);
- add widget to awesome:
```lua
require("email")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
email_icon,
email_widget,
...
```
## How it works
This widget uses the output of two python scripts, first is called every 20 seconds - it returns number of unread emails and second is called when mouse hovers over an icon and displays content of those emails. For both of them you'll need to provide your credentials and imap server. For testing they can simply be called from console:
``` bash
python ~/.config/awesome/email/count_unread_emails.py
python ~/.config/awesome/email/read_emails.py
```

View File

@ -0,0 +1,16 @@
#!/usr/bin/python
import imaplib
import email
M=imaplib.IMAP4_SSL("mail.teenagemutantninjaturtles.com", 993)
M.login("mickey@tmnt.com","cowabunga")
status, counts = M.status("INBOX","(MESSAGES UNSEEN)")
if status == "OK":
unread = counts[0].split()[4][:-1]
else:
unread = "N/A"
print(unread)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,42 @@
local wibox = require("wibox")
local awful = require("awful")
local naughty = require("naughty")
local watch = require("awful.widget.watch")
local path_to_icons = "/usr/share/icons/Arc/actions/22/"
email_widget = wibox.widget.textbox()
email_widget:set_font('Play 9')
email_icon = wibox.widget.imagebox()
email_icon:set_image(path_to_icons .. "/mail-mark-new.png")
watch(
"python /home/<username>/.config/awesome/email-widget/count_unread_emails.py", 20,
function(widget, stdout, stderr, exitreason, exitcode)
local unread_emails_num = tonumber(stdout) or 0
if (unread_emails_num > 0) then
email_icon:set_image(path_to_icons .. "/mail-mark-unread.png")
email_widget:set_text(stdout)
elseif (unread_emails_num == 0) then
email_icon:set_image(path_to_icons .. "/mail-message-new.png")
email_widget:set_text("")
end
end
)
function show_emails()
awful.spawn.easy_async([[bash -c 'python /home/<username>/.config/awesome/email-widget/read_unread_emails.py']],
function(stdout, stderr, reason, exit_code)
naughty.notify{
text = stdout,
title = "Unread Emails",
timeout = 5, hover_timeout = 0.5,
width = 400,
}
end
)
end
email_icon:connect_signal("mouse::enter", function() show_emails() end)

View File

@ -0,0 +1,42 @@
#!/usr/bin/python
import imaplib
import email
import datetime
def process_mailbox(M):
rv, data = M.search(None, "(UNSEEN)")
if rv != 'OK':
print "No messages found!"
return
for num in data[0].split():
rv, data = M.fetch(num, '(BODY.PEEK[])')
if rv != 'OK':
print "ERROR getting message", num
return
msg = email.message_from_string(data[0][1])
print 'From:', msg['From']
print 'Subject: %s' % (msg['Subject'])
date_tuple = email.utils.parsedate_tz(msg['Date'])
if date_tuple:
local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
print "Local Date:", local_date.strftime("%a, %d %b %Y %H:%M:%S")
# with code below you can process text of email
# if msg.is_multipart():
# for payload in msg.get_payload():
# if payload.get_content_maintype() == 'text':
# print payload.get_payload()
# else:
# print msg.get_payload()
M=imaplib.IMAP4_SSL("mail.teenagemutantninjaturtles.com", 993)
M.login("mickey@tmnt.com","cowabunga")
rv, data = M.select("INBOX")
if rv == 'OK':
process_mailbox(M)
M.close()
M.logout()

View File

@ -0,0 +1,26 @@
# MPD Widget
Music Player Daemon widget by @raphaelfournier.
# Prerequisite
Install `mpd` (Music Player Daemon itself) and `mpc` (Music Player Client - program for controlling mpd), both should be available in repo, e.g for Ubuntu:
```bash
sudo apt-get install mpd mpc
```
## Installation
To use this widget clone repo under **~/.config/awesome/** and then add it in **rc.lua**:
```lua
local mpdarc_widget = require("awesome-wm-widgets.mpdarc-widget.mpdarc")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
mpdarc_widget,
...
```

View File

@ -0,0 +1,119 @@
-------------------------------------------------
-- mpd Arc Widget for Awesome Window Manager
-- Modelled after Pavel Makhov's work
-- @author Raphaël Fournier-S'niehotta
-- @copyright 2018 Raphaël Fournier-S'niehotta
-------------------------------------------------
local awful = require("awful")
local beautiful = require("beautiful")
local spawn = require("awful.spawn")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local naughty = require("naughty")
local GET_MPD_CMD = "mpc status"
local TOGGLE_MPD_CMD = "mpc toggle"
local PAUSE_MPD_CMD = "mpc pause"
local STOP_MPD_CMD = "mpc stop"
local NEXT_MPD_CMD = "mpc next"
local PREV_MPD_CMD = "mpc prev"
local PATH_TO_ICONS = "/usr/share/icons/Arc"
local PAUSE_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_pause.png"
local PLAY_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_play.png"
local STOP_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_stop.png"
local icon = wibox.widget {
id = "icon",
widget = wibox.widget.imagebox,
image = PLAY_ICON_NAME
}
local mirrored_icon = wibox.container.mirror(icon, { horizontal = true })
local mpdarc = wibox.widget {
mirrored_icon,
max_value = 1,
value = 0.75,
thickness = 2,
start_angle = 4.71238898, -- 2pi*3/4
forced_height = 32,
forced_width = 32,
rounded_edge = true,
bg = "#ffffff11",
paddings = 0,
widget = wibox.container.arcchart
}
local mpdarc_icon_widget = wibox.container.mirror(mpdarc, { horizontal = true })
local mpdarc_current_song_widget = wibox.widget {
id = 'current_song',
widget = wibox.widget.textbox,
font = 'Play 9'
}
local update_graphic = function(widget, stdout, _, _, _)
local current_song = string.gmatch(stdout, "[^\r\n]+")()
stdout = string.gsub(stdout, "\n", "")
local mpdpercent = string.match(stdout, "(%d%d)%%")
local mpdstatus = string.match(stdout, "%[(%a+)%]")
if mpdstatus == "playing" then
icon.image = PLAY_ICON_NAME
widget.colors = { beautiful.widget_main_color }
widget.value = tonumber((100-mpdpercent)/100)
mpdarc_current_song_widget.markup = current_song
elseif mpdstatus == "paused" then
icon.image = PAUSE_ICON_NAME
widget.colors = { beautiful.widget_main_color }
widget.value = tonumber(mpdpercent/100)
mpdarc_current_song_widget.markup = current_song
else
icon.image = STOP_ICON_NAME
if string.len(stdout) == 0 then -- MPD is not running
mpdarc_current_song_widget.markup = "MPD is not running"
else
widget.colors = { beautiful.widget_red }
mpdarc_current_song_widget.markup = ""
end
end
end
mpdarc:connect_signal("button::press", function(_, _, _, button)
if (button == 1) then awful.spawn(TOGGLE_MPD_CMD, false) -- left click
elseif (button == 2) then awful.spawn(STOP_MPD_CMD, false)
elseif (button == 3) then awful.spawn(PAUSE_MPD_CMD, false)
elseif (button == 4) then awful.spawn(NEXT_MPD_CMD, false) -- scroll up
elseif (button == 5) then awful.spawn(PREV_MPD_CMD, false) -- scroll down
end
spawn.easy_async(GET_MPD_CMD, function(stdout, stderr, exitreason, exitcode)
update_graphic(mpdarc, stdout, stderr, exitreason, exitcode)
end)
end)
local notification
function show_MPD_status()
spawn.easy_async(GET_MPD_CMD,
function(stdout, _, _, _)
notification = naughty.notify {
text = stdout,
title = "MPD",
timeout = 5,
hover_timeout = 0.5,
width = 600,
}
end)
end
mpdarc:connect_signal("mouse::enter", function() show_MPD_status() end)
mpdarc:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
watch(GET_MPD_CMD, 1, update_graphic, mpdarc)
local mpdarc_widget = {
mpdarc_icon_widget,
mpdarc_current_song_widget,
layout = wibox.layout.align.horizontal,
}
return mpdarc_widget

View File

@ -0,0 +1,16 @@
# Pomodoro Widget
:construction: This widget is under construction :construction_worker:
## Installation
This widget is based on [@jsspencer](https://github.com/jsspencer)' [pomo](https://github.com/jsspencer/pomo) - a simple pomodoro timer.
So first install/clone it anywhere you like, then either
- in widget's code provide path to the pomo.sh, or
- add pomo.sh to the PATH, or
- make a soft link in /usr/local/bin/ to it:
```bash
sudo ln -sf /opt/pomodoro/pomo.sh /usr/local/bin/pomo
```
Note that by default widget's code expects third way and calls script by `pomo`.

View File

@ -0,0 +1,135 @@
-------------------------------------------------
-- Pomodoro Arc Widget for Awesome Window Manager
-- Modelled after Pavel Makhov's work
-- @author Raphaël Fournier-S'niehotta
-- @copyright 2018 Raphaël Fournier-S'niehotta
-------------------------------------------------
local awful = require("awful")
local beautiful = require("beautiful")
local spawn = require("awful.spawn")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local naughty = require("naughty")
local GET_pomodoro_CMD = "pomo clock"
local PAUSE_pomodoro_CMD = "pomo pause"
local START_pomodoro_CMD = "pomo start"
local STOP_pomodoro_CMD = "pomo stop"
local text = wibox.widget {
id = "txt",
--font = "Play 12",
font = "Inconsolata Medium 13",
widget = wibox.widget.textbox
}
-- mirror the text, because the whole widget will be mirrored after
local mirrored_text = wibox.container.margin(wibox.container.mirror(text, { horizontal = true }))
mirrored_text.right = 5 -- pour centrer le texte dans le rond
--
--local mirrored_text = wibox.container.mirror(text, { horizontal = true })
-- mirrored text with background
local mirrored_text_with_background = wibox.container.background(mirrored_text)
local pomodoroarc = wibox.widget {
mirrored_text_with_background,
max_value = 1,
thickness = 2,
start_angle = 4.71238898, -- 2pi*3/4
forced_height = 32,
forced_width = 32,
rounded_edge = true,
bg = "#ffffff11",
paddings = 0,
widget = wibox.container.arcchart
}
local pomodoroarc_widget = wibox.container.mirror(pomodoroarc, { horizontal = true })
local update_graphic = function(widget, stdout, _, _, _)
local pomostatus = string.match(stdout, " (%D?%D?):%D?%D?")
if pomostatus == "--" then
text.font = "Inconsolata Medium 13"
widget.colors = { beautiful.widget_main_color }
text.text = "25"
widget.value = 1
else
text.font = "Inconsolata Medium 13"
local pomomin = string.match(stdout, "[ P]?[BW](%d?%d?):%d?%d?")
local pomosec = string.match(stdout, "[ P]?[BW]%d?%d?:(%d?%d?)")
local pomodoro = pomomin * 60 + pomosec
local status = string.match(stdout, "([ P]?)[BW]%d?%d?:%d?%d?")
local workbreak = string.match(stdout, "[ P]?([BW])%d?%d?:%d?%d?")
text.text = pomomin
-- Helps debugging
--naughty.notify {
--text = pomomin,
--title = "pomodoro debug",
--timeout = 5,
--hover_timeout = 0.5,
--width = 200,
--}
if status == " " then -- clock ticking
if workbreak == "W" then
widget.value = tonumber(pomodoro/(25*60))
if tonumber(pomomin) < 5 then -- last 5 min of pomo
widget.colors = { beautiful.widget_red }
else
widget.colors = { beautiful.widget_blue }
end
elseif workbreak == "B" then -- color during pause
widget.colors = { beautiful.widget_green }
widget.value = tonumber(pomodoro/(5*60))
end
elseif status == "P" then -- paused
if workbreak == "W" then
widget.colors = { beautiful.widget_yellow }
widget.value = tonumber(pomodoro/(25*60))
text.font = "Inconsolata Medium 13"
text.text = "PW"
elseif workbreak == "B" then
widget.colors = { beautiful.widget_yellow }
widget.value = tonumber(pomodoro/(5*60))
text.font = "Inconsolata Medium 13"
text.text = "PB"
end
end
end
end
pomodoroarc:connect_signal("button::press", function(_, _, _, button)
if (button == 2) then awful.spawn(PAUSE_pomodoro_CMD, false)
elseif (button == 1) then awful.spawn(START_pomodoro_CMD, false)
elseif (button == 3) then awful.spawn(STOP_pomodoro_CMD, false)
end
spawn.easy_async(GET_pomodoro_CMD, function(stdout, stderr, exitreason, exitcode)
update_graphic(pomodoroarc, stdout, stderr, exitreason, exitcode)
end)
end)
local notification
function show_pomodoro_status()
spawn.easy_async(GET_pomodoro_CMD,
function(stdout, _, _, _)
notification = naughty.notify {
text = stdout,
title = "pomodoro status",
timeout = 5,
hover_timeout = 0.5,
width = 200,
}
end)
end
pomodoroarc:connect_signal("mouse::enter", function() show_pomodoro_status() end)
pomodoroarc:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
watch(GET_pomodoro_CMD, 1, update_graphic, pomodoroarc)
return pomodoroarc_widget

View File

@ -0,0 +1,9 @@
# Ram widget
This widget shows the RAM usage. When clicked another widget appears with more detailed information:
![screenshot](./out.gif)
## Installation
Please refer to the [installation](https://github.com/streetturtle/awesome-wm-widgets#installation) section of the repo.

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -0,0 +1,78 @@
local awful = require("awful")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
--- Main ram widget shown on wibar
local ramgraph_widget = wibox.widget {
border_width = 0,
colors = {
'#74aeab', '#26403f'
},
display_labels = false,
forced_width = 25,
widget = wibox.widget.piechart
}
--- Widget which is shown when user clicks on the ram widget
local w = wibox {
height = 200,
width = 400,
ontop = true,
expand = true,
bg = '#1e252c',
max_widget_size = 500
}
w:setup {
border_width = 0,
colors = {
'#5ea19d',
'#55918e',
'#4b817e',
},
display_labels = false,
forced_width = 25,
id = 'pie',
widget = wibox.widget.piechart
}
local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap
local function getPercentage(value)
return math.floor(value / (total+total_swap) * 100 + 0.5) .. '%'
end
watch('bash -c "free | grep -z Mem.*Swap.*"', 1,
function(widget, stdout, stderr, exitreason, exitcode)
total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap =
stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)')
widget.data = { used, total-used } widget.data = { used, total-used }
if w.visible then
w.pie.data_list = {
{'used ' .. getPercentage(used + used_swap), used + used_swap},
{'free ' .. getPercentage(free + free_swap), free + free_swap},
{'buff_cache ' .. getPercentage(buff_cache), buff_cache}
}
end
end,
ramgraph_widget
)
ramgraph_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function()
awful.placement.top_right(w, { margins = {top = 25, right = 10}, parent = awful.screen.focused() })
w.pie.data_list = {
{'used ' .. getPercentage(used + used_swap), used + used_swap},
{'free ' .. getPercentage(free + free_swap), free + free_swap},
{'buff_cache ' .. getPercentage(buff_cache), buff_cache}
}
w.pie.display_labels = true
w.visible = not w.visible
end)
)
)
return ramgraph_widget

View File

@ -0,0 +1,16 @@
local wibox = require("wibox")
local awful = require("awful")
local watch = require("awful.widget.watch")
rhythmbox_widget = wibox.widget.textbox()
rhythmbox_widget:set_font('Play 9')
rhythmbox_icon = wibox.widget.imagebox()
rhythmbox_icon:set_image("/usr/share/icons/Arc/devices/22/audio-speakers.png")
watch(
"rhythmbox-client --no-start --print-playing", 1,
function(widget, stdout, stderr, exitreason, exitcode)
rhythmbox_widget:set_text(stdout)
end
)

View File

@ -0,0 +1,91 @@
-------------------------------------------------
-- Run Shell for Awesome Window Manager
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/run-shell
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local gfs = require("gears.filesystem")
local wibox = require("wibox")
local gears = require("gears")
local naughty = require("naughty")
local completion = require("awful.completion")
local run_shell = awful.widget.prompt()
local w = wibox {
visible = false,
ontop = true,
height = 1060,
width = 1920
}
w:setup {
{
{
{
{
text = '',
font = 'Play 18',
widget = wibox.widget.textbox,
},
id = 'icon',
top = 9,
left = 10,
layout = wibox.container.margin
},
{
run_shell,
left = 10,
layout = wibox.container.margin,
},
id = 'left',
layout = wibox.layout.fixed.horizontal
},
widget = wibox.container.background,
bg = '#333333',
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 3)
end,
shape_border_color = '#74aeab',
shape_border_width = 1,
forced_width = 200,
forced_height = 50
},
layout = wibox.container.place
}
local function launch(s)
awful.spawn.with_line_callback(os.getenv("HOME") .. "/.config/awesome/awesome-wm-widgets/run-shell/scratch_6.sh " .. tostring(awful.screen.focused().geometry.x), {
stdout = function(line)
w.visible = true
w.bgimage = '/tmp/i3lock-' .. line .. '.png'
awful.placement.top(w, { margins = { top = 20 }, parent = awful.screen.focused() })
awful.prompt.run {
prompt = "<b>Run</b>: ",
bg_cursor = '#74aeab',
textbox = run_shell.widget,
completion_callback = completion.shell,
exe_callback = function(...)
run_shell:spawn_and_handle_error(...)
end,
history_path = gfs.get_cache_dir() .. "/history",
done_callback = function()
-- w.bgimage=''
w.visible = false
awful.spawn([[bash -c 'rm -f /tmp/i3lock*']])
end
}
end,
stderr = function(line)
naughty.notify { text = "ERR:" .. line }
end,
})
end
return {
launch = launch
}

View File

@ -0,0 +1,40 @@
#!/usr/bin/env bash
#IMAGE=/tmp/i3lock.png
#SCREENSHOT="scrot -u $IMAGE" # 0.46s
#
## Alternate screenshot method with imagemagick. NOTE: it is much slower
## SCREENSHOT="import -window root $IMAGE" # 1.35s
#
## Here are some imagemagick blur types
## Uncomment one to use, if you have multiple, the last one will be used
#
## All options are here: http://www.imagemagick.org/Usage/blur/#blur_args
##BLURTYPE="0x5" # 7.52s
##BLURTYPE="0x2" # 4.39s
##BLURTYPE="5x2" # 3.80s
#BLURTYPE="2x8" # 2.90s
##BLURTYPE="2x3" # 2.92s
#
## Get the screenshot, add the blur and lock the screen with it
#$SCREENSHOT
#convert $IMAGE -blur $BLURTYPE $IMAGE
#echo 'done'
# --------------------------
#RES=$(xrandr --current | grep '*' | uniq | awk '{print $1}')
RNDM=$(uuidgen)
IMAGE="/tmp/i3lock-$RNDM.png"
#ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+0,20 -filter_complex "boxblur=9" -vframes 1 $IMAGE
#ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+0,20 -vf frei0r=pixeliz0r -vframes 1 $IMAGE
ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+$1,20 -vf frei0r=pixeliz0r -vframes 1 $IMAGE
#ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+0,20 -filter_complex "boxblur=9" -vframes 1 "/tmp/i3lock$(uuidgen).png"
echo $RNDM
#lock screen
#ffmpeg -loglevel panic -f x11grab -video_size $(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/') -y -i :0.0+$1,20 -vf frei0r=pixeliz0r -vframes 1 /tmp/test.png ; i3lock -i /tmp/test.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -0,0 +1,15 @@
-------------------------------------------------
-- Allows to store API keys in one place
--
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
--------------------------------------------
local secrets = {
-- Yandex.Translate API key - https://tech.yandex.com/translate/
translate_widget_api_key = '<API_KEY>',
-- OpenWeatherMap API key - https://openweathermap.org/appid
weather_widget_api_key = '<API_KEY>'
}
return secrets

View File

@ -0,0 +1,73 @@
# Spotify Shell
![demo](./demo.gif)
## Features
1. Supports following commands (same as `sp` client):
- `play`/`pause`/`next`;
- any other string will start a search and play the first result for a given search query;
- feh - shows the current artwork with `feh`;
1. Stores history and allows navigate through it;
1. Highly customizable
## Controls
Keyboard navigation (copied from [`awful.prompt`](https://awesomewm.org/doc/api/libraries/awful.prompt.html) API documentation page):
| Name | Usage |
|---|---|
| CTRL+A | beginning-of-line |
| CTRL+B | backward-char |
| CTRL+C | cancel |
| CTRL+D | delete-char |
| CTRL+E | end-of-line |
| CTRL+J | accept-line |
| CTRL+M | accept-line |
| CTRL+F | move-cursor-right |
| CTRL+H | backward-delete-char |
| CTRL+K | kill-line |
| CTRL+U | unix-line-discard |
| CTRL+W | unix-word-rubout |
| CTRL+BACKSPAC | unix-word-rubout |
| SHIFT+INSERT | paste |
| HOME | beginning-of-line |
| END | end-of-line |
| CTRL+R | reverse history search, matches any history entry containing search term. |
| CTRL+S | forward history search, matches any history entry containing search term. |
| CTRL+UP | ZSH up line or search, matches any history entry starting with search term. |
| CTRL+DOWN | ZSH down line or search, matches any history entry starting with search term. |
| CTRL+DELETE | delete the currently visible history entry from history file. This does not delete new commands or history entries under user editing. |
## Installation
1. Install [sp](https://gist.github.com/streetturtle/fa6258f3ff7b17747ee3) - CLI client for [Spotify for Linux](https://www.spotify.com/ca-en/download/linux/):
```bash
$ sudo git clone https://gist.github.com/fa6258f3ff7b17747ee3.git ~/dev/
$ sudo ln -s ~/dev/sp /usr/local/bin/
```
Check if it works by running `sp help`.
1. Get an 'id' and 'secret' from [developer.spotify.com](https://beta.developer.spotify.com/documentation/general/guides/app-settings/) and paste it in the header of the `sp` (`SP_ID` and `SP_SECRET`) - this enables search feature.
1. Clone this repo under **~/.config/awesome/**
1. Require spotify-shell at the beginning of **rc.lua**:
```lua
local spotify_shell = require("awesome-wm-widgets.spotify-shell.spotify-shell")
```
1. Add a shortcut which will show Spotify Shell widget:
```lua
awful.key({ modkey, }, "d", function () spotify_shell.launch() end, {description = "spotify shell", group = "music"}),
```
1. It uses icon from [Papirus Icon Theme](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme). So you should either install this icon theme, or download an icon you want to use and provide path to it in **spotify-shell.lua**.

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -0,0 +1,75 @@
-------------------------------------------------
-- Spotify Shell for Awesome Window Manager
-- Simplifies interaction with Spotify for Linux
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/spotify-shell
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local gfs = require("gears.filesystem")
local wibox = require("wibox")
local gears = require("gears")
local ICON = '/usr/share/icons/Papirus-Light/32x32/apps/spotify-linux-48x48.svg'
local spotify_shell = awful.widget.prompt()
local w = wibox {
bg = '#1e252c',
border_width = 1,
border_color = '#84bd00',
max_widget_size = 500,
ontop = true,
height = 50,
width = 250,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 3)
end
}
w:setup {
{
{
image = ICON,
widget = wibox.widget.imagebox,
resize = false
},
id = 'icon',
top = 9,
left = 10,
layout = wibox.container.margin
},
{
layout = wibox.container.margin,
left = 10,
spotify_shell,
},
id = 'left',
layout = wibox.layout.fixed.horizontal
}
local function launch()
w.visible = true
awful.placement.top(w, { margins = {top = 40}, parent = awful.screen.focused()})
awful.prompt.run{
prompt = "<b>Spotify Shell</b>: ",
bg_cursor = '#84bd00',
textbox = spotify_shell.widget,
history_path = gfs.get_dir('cache') .. '/spotify_history',
exe_callback = function(input_text)
if not input_text or #input_text == 0 then return end
awful.spawn("sp " .. input_text)
end,
done_callback = function()
w.visible = false
end
}
end
return {
launch = launch
}

View File

@ -0,0 +1,33 @@
# Spotify widget
This widget displays currently playing song on [Spotify for Linux](https://www.spotify.com/download/linux/) client: ![screenshot](./spo-wid-1.png) and consists of two parts:
- status icon which shows if music is currently playing
- artist and name of the current song playing
## Controls
- left click - play/pause
- scroll up - play next song
- scroll down - play previous song
## Dependencies
Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder.
## Installation
First you need to have spotify CLI installed. Here is how you can do it (except widget part): [pavelmakhov.com/2016/02/awesome-wm-spotify](http://pavelmakhov.com/2016/02/awesome-wm-spotify)
To use this widget clone repo under **~/.config/awesome/** and then add it in **rc.lua**:
```lua
local spotify_widget = require("awesome-wm-widgets.spotify-widget.spotify")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
spotify_widget,
...
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,72 @@
-------------------------------------------------
-- Spotify Widget for Awesome Window Manager
-- Shows currently playing song on Spotify for Linux client
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/spotify-widget
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local GET_SPOTIFY_STATUS_CMD = 'sp status'
local GET_CURRENT_SONG_CMD = 'sp current-oneline'
local PATH_TO_ICONS = "/usr/share/icons/Arc"
local spotify_widget = wibox.widget {
{
id = "icon",
widget = wibox.widget.imagebox,
},
{
id = 'current_song',
widget = wibox.widget.textbox,
font = 'Play 9'
},
layout = wibox.layout.align.horizontal,
set_status = function(self, is_playing)
self.icon.image = PATH_TO_ICONS ..
(is_playing and "/actions/24/player_play.png"
or "/actions/24/player_pause.png")
end,
set_text = function(self, path)
self.current_song.markup = path
end,
}
local update_widget_icon = function(widget, stdout, _, _, _)
stdout = string.gsub(stdout, "\n", "")
widget:set_status(stdout == 'Playing' and true or false)
end
local update_widget_text = function(widget, stdout, _, _, _)
if string.find(stdout, 'Error: Spotify is not running.') ~= nil then
widget:set_text('')
widget:set_visible(false)
else
widget:set_text(stdout)
widget:set_visible(true)
end
end
watch(GET_SPOTIFY_STATUS_CMD, 1, update_widget_icon, spotify_widget)
watch(GET_CURRENT_SONG_CMD, 1, update_widget_text, spotify_widget)
--- Adds mouse controls to the widget:
-- - left click - play/pause
-- - scroll up - play next song
-- - scroll down - play previous song
spotify_widget:connect_signal("button::press", function(_, _, _, button)
if (button == 1) then awful.spawn("sp play", false) -- left click
elseif (button == 4) then awful.spawn("sp next", false) -- scroll up
elseif (button == 5) then awful.spawn("sp prev", false) -- scroll down
end
awful.spawn.easy_async(GET_SPOTIFY_STATUS_CMD, function(stdout, stderr, exitreason, exitcode)
update_widget_icon(spotify_widget, stdout, stderr, exitreason, exitcode)
end)
end)
return spotify_widget

View File

@ -0,0 +1,28 @@
# Translate Widget
This widget allows quickly translate words or phrases without opening a browser - just using Awesome. To provide direction of the translation add the 2 letters code of the source and target languages at the end of the phrase, for example _hello enfr_ will translate _hello_ from English to French. This widget is based on [Yandex.Translate API](https://tech.yandex.com/translate/).
![demo](./demo.gif)
## Controls
- <kbd>Mod4</kbd> + <kbd>c</kbd> - opens a translate prompt;
- left click on the popup widget - copies the translation to the clipboard and closes widget;
- right click on the popup widget - copies text to translate to the clipboard and closes widget.
## Installation
1. Clone repo under **~/.config/awesome/**
1. Get an [API key](https://translate.yandex.com/developers/keys) and paste it in **translate.lua** as value of the `API_KEY` variable
1. Require widget in **rc.lua**:
```lua
local translate = require("awesome-wm-widgets.translate-widget.translate")
```
1. Add a shortcut to run translate prompt:
```lua
awful.key({ modkey }, "c", function() translate.show_translate_prompt() end, { description = "run translate prompt", group = "launcher" }),
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,196 @@
-------------------------------------------------
-- Translate Widget based on the Yandex.Translate API
-- https://tech.yandex.com/translate/
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local capi = {keygrabber = keygrabber }
local https = require("ssl.https")
local json = require("json")
local naughty = require("naughty")
local wibox = require("wibox")
local gears = require("gears")
local gfs = require("gears.filesystem")
local API_KEY = '<your api key>'
local BASE_URL = 'https://translate.yandex.net/api/v1.5/tr.json/translate'
local ICON = '/usr/share/icons/Papirus-Dark/48x48/apps/gnome-translate.svg'
--- Returns two values - string to translate and direction:
-- 'dog enfr' -> 'dog', 'en-fr'
-- @param input_string user's input which consists of
-- text to translate and direction, 'dog enfr'
local function extract(input_string)
local word, lang = input_string:match('^(.+)%s(%a%a%a%a)$')
if word ~= nill and lang ~= nill then
lang = lang:sub(1, 2) .. '-' .. lang:sub(3)
end
return word, lang
end
--- Simple url encoder - replaces spaces with '+' sign
-- @param url to encode
local function urlencode(url)
if (url) then
url = string.gsub(url, " ", "+")
end
return url
end
local w = wibox {
width = 300,
border_width = 1,
border_color = '#66ccff',
ontop = true,
expand = true,
bg = '#1e252c',
max_widget_size = 500,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 3)
end
}
w:setup {
{
{
image = ICON,
widget = wibox.widget.imagebox,
resize = false
},
id = 'img',
layout = wibox.container.margin(_, 0, 0, 10)
},
{
{
id = 'header',
widget = wibox.widget.textbox
},
{
id = 'src',
widget = wibox.widget.textbox
},
{
id = 'res',
widget = wibox.widget.textbox
},
id = 'text',
layout = wibox.layout.fixed.vertical,
},
id = 'left',
layout = wibox.layout.fixed.horizontal
}
--- Main function - takes the user input and shows the widget with translation
-- @param request_string - user input (dog enfr)
local function translate(to_translate, lang)
local urll = BASE_URL .. '?lang=' .. lang .. '&text=' .. urlencode(to_translate) .. '&key=' .. API_KEY
local resp_json, code = https.request(urll)
if (code == 200 and resp_json ~= nil) then
local resp = json.decode(resp_json).text[1]
w.left.text.header:set_markup('<big>' .. lang .. '</big>')
w.left.text.src:set_markup('<b>' .. lang:sub(1,2) .. '</b>: <span color="#FFFFFF"> ' .. to_translate .. '</span>')
w.left.text.res:set_markup('<b>' .. lang:sub(4) .. '</b>: <span color="#FFFFFF"> ' .. resp .. '</span>')
awful.placement.top(w, { margins = {top = 40}})
local h1 = w.left.text.header:get_height_for_width(w.width, w.screen)
local h2 = w.left.text.src:get_height_for_width(w.width, w.screen)
local h3 = w.left.text.res:get_height_for_width(w.width, w.screen)
-- calculate height of the widget
w.height = h1 + h2 + h3 + 20
-- try to vetrtically align the icon
w.left.img:set_top((h1 + h2 + h3 + 20 - 48)/2)
w.visible = true
w:buttons(
awful.util.table.join(
awful.button({}, 1, function()
awful.spawn.with_shell("echo '" .. resp .. "' | xclip -selection clipboard")
w.visible = false
end),
awful.button({}, 3, function()
awful.spawn.with_shell("echo '" .. to_translate .."' | xclip -selection clipboard")
w.visible = false
end)
)
)
capi.keygrabber.run(function(_, key, event)
if event == "release" then return end
if key then
capi.keygrabber.stop()
w.visible = false
end
end)
else
naughty.notify({
preset = naughty.config.presets.critical,
title = 'Translate Widget Error',
text = resp_json,
})
end
end
local input_widget = wibox {
width = 300,
ontop = true,
screen = mouse.screen,
expand = true,
bg = '#1e252c',
max_widget_size = 500,
border_width = 1;
border_width = 1,
border_color = '#66ccff',
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 3)
end
}
local prompt = awful.widget.prompt()
input_widget:setup {
layout = wibox.container.margin,
prompt,
left = 10
}
local function show_translate_prompt()
awful.placement.top(input_widget, { margins = {top = 40}, parent = awful.screen.focused()})
input_widget.height = 40
input_widget.visible = true
awful.prompt.run {
prompt = "<b>Translate</b>: ",
textbox = prompt.widget,
history_path = gfs.get_dir('cache') .. '/translate_history',
bg_cursor = '#66ccff',
exe_callback = function(text)
if not text or #text == 0 then return end
local to_translate, lang = extract(text)
if not to_translate or #to_translate==0 or not lang or #lang == 0 then
naughty.notify({
preset = naughty.config.presets.critical,
title = 'Translate Widget Error',
text = 'Language is not provided',
})
return
end
translate(to_translate, lang)
end,
done_callback = function()
input_widget.visible = false
end
}
end
return {
show_translate_prompt = show_translate_prompt
}

View File

@ -0,0 +1,44 @@
# Volume widget
Simple and easy-to-install widget for Awesome Window Manager which represents the sound level: ![Volume Widget](
./vol-widget-1.png)
Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder.
## Installation
- clone/copy **volume.lua** file;
- include `volume.lua` and add volume widget to your wibox in rc.lua:
```lua
require("volume")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
volume_widget,
...
```
- _Optional step._ In Arc icon theme the muted audio level icon (![Volume-widget](./audio-volume-muted-symbolic.png)) looks like 0 level icon, which could be a bit misleading.
So I decided to use original muted icon for low audio level, and the same icon, but colored in red for muted audio level. Fortunately icons are in svg format, so you can easily recolor them with `sed`, so it would look like this (![Volume Widget](./audio-volume-muted-symbolic_red.png)):
```bash
cd /usr/share/icons/Arc/status/symbolic &&
sudo cp audio-volume-muted-symbolic.svg audio-volume-muted-symbolic_red.svg &&
sudo sed -i 's/bebebe/ed4737/g' ./audio-volume-muted-symbolic_red.svg
```
## Control volume
To mute/unmute click on the widget. To increase/decrease volume scroll up or down when mouse cursor is over the widget.
If you want to control volume level by keyboard shortcuts add following lines in shortcut section of the **rc.lua** (the commands could be slightly different depending on your PC configuration):
```lua
awful.key({ modkey}, "[", function () awful.spawn("amixer -D pulse sset Master 5%+") end, {description = "increase volume", group = "custom"}),
awful.key({ modkey}, "]", function () awful.spawn("amixer -D pulse sset Master 5%-") end, {description = "decrease volume", group = "custom"}),
awful.key({ modkey}, "\", function () awful.spawn("amixer -D pulse set Master +1 toggle") end, {description = "mute volume", group = "custom"}),
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
viewBox="0 0 16 16"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="audio-volume-muted-symbolic.svg">
<metadata
id="metadata30">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1215"
inkscape:window-height="776"
id="namedview28"
showgrid="true"
inkscape:zoom="38.125"
inkscape:cx="3.4229508"
inkscape:cy="7.947541"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
showguides="true"
inkscape:snap-intersection-paths="false"
inkscape:object-paths="false">
<inkscape:grid
type="xygrid"
id="grid4158" />
</sodipodi:namedview>
<defs
id="defs4" />
<path
d="M 6,2 2,6 2,10 6,14 6,9 7,8 6,7 Z"
id="path18"
inkscape:connector-curvature="0"
style="fill:#bebebe"
sodipodi:nodetypes="cccccccc" />
<path
d="M 1.300003,5 C 0.216589,5 0,6.163269 0,7.4 L 0,8.6 C 0,9.836747 0.24312,11 1.300003,11 L 3,11 3,5 Z"
id="path20"
inkscape:connector-curvature="0"
style="fill:#bebebe"
sodipodi:nodetypes="ssssccs" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
id="path4508"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
id="path4529"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
id="path4569"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscccc" />
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
viewBox="0 0 16 16"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.92.2 2405546, 2018-03-11"
sodipodi:docname="audio-volume-muted-symbolic-shan.svg">
<metadata
id="metadata30">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1438"
inkscape:window-height="858"
id="namedview28"
showgrid="true"
inkscape:zoom="38.125"
inkscape:cx="3.4229508"
inkscape:cy="7.947541"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
showguides="true"
inkscape:snap-intersection-paths="false"
inkscape:object-paths="false">
<inkscape:grid
type="xygrid"
id="grid4158" />
</sodipodi:namedview>
<defs
id="defs4" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
id="path4508"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
id="path4529"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
id="path4569"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscccc" />
<path
style="opacity:0.3;fill:#bebebe;fill-opacity:1;stroke-width:0.02622951"
d="M 4.5036936,12.482983 3.0218135,11.000927 2.1430379,11.000775 C 1.6597113,11.000691 1.1955581,10.989371 1.1115864,10.975618 0.56198086,10.885606 0.24352693,10.462909 0.07812436,9.603862 0.03708101,9.390696 0.03147539,9.196108 0.03147539,7.984533 c 0,-1.217172 0.0054766,-1.405527 0.04717053,-1.622335 0.132109,-0.686963 0.3489491,-1.058742 0.7259726,-1.244702 L 0.97448297,5.033716 1.9849464,5.026316 2.9954098,5.018916 4.4970492,3.518184 5.9986885,2.0174522 V 4.5094289 7.001406 l 0.4983672,0.497849 0.498367,0.497849 -0.4982329,0.498725 -0.498233,0.498725 -0.00669,2.485223 -0.00669,2.485223 z"
id="path819"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
viewBox="0 0 16 16"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="audio-volume-muted-symbolic.svg">
<metadata
id="metadata30">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1215"
inkscape:window-height="776"
id="namedview28"
showgrid="true"
inkscape:zoom="38.125"
inkscape:cx="3.4229508"
inkscape:cy="7.947541"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
showguides="true"
inkscape:snap-intersection-paths="false"
inkscape:object-paths="false">
<inkscape:grid
type="xygrid"
id="grid4158" />
</sodipodi:namedview>
<defs
id="defs4" />
<path
d="M 6,2 2,6 2,10 6,14 6,9 7,8 6,7 Z"
id="path18"
inkscape:connector-curvature="0"
style="fill:#ed4737"
sodipodi:nodetypes="cccccccc" />
<path
d="M 1.300003,5 C 0.216589,5 0,6.163269 0,7.4 L 0,8.6 C 0,9.836747 0.24312,11 1.300003,11 L 3,11 3,5 Z"
id="path20"
inkscape:connector-curvature="0"
style="fill:#ed4737"
sodipodi:nodetypes="ssssccs" />
<path
style="opacity:0.3;fill:#ed4737;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 13.140638,1 11.726417,2.413582 C 12.808349,3.4955144 13.990412,5.4467621 14,8 c 0,2.551493 -1.192916,4.505751 -2.273583,5.586418 L 13.140638,15 C 14.595711,13.544927 16.019176,11 16,8 16.035061,5 14.595117,2.4544787 13.140638,1 Z"
id="path4508"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:0.3;fill:#ed4737;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 11,3.1156678 9.5897193,4.5261118 C 10.372347,5.3087395 11,6.5690611 11,8 11,9.4309388 10.372767,10.690952 9.5897193,11.474 L 11,12.884 C 12.275645,11.608355 13,9.854095 13,8 13,6.1543677 12.273068,4.3887355 11,3.1156678 Z"
id="path4529"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:0.3;fill:#ed4737;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 8.629,5 7.2094668,6.4096296 C 8,7.05621 8,7.805653 8,8 8,8.1932576 7.982199,8.9408674 7.209,9.59 L 8.6289063,11 C 9.8466375,9.952694 10,8.5984701 10,8 10,7.400497 9.854476,6.062891 8.629,5 Z"
id="path4569"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscccc" />
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

View File

@ -0,0 +1,67 @@
-------------------------------------------------
-- Volume Widget for Awesome Window Manager
-- Shows the current volume level
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/volume-widget
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local spawn = require("awful.spawn")
local path_to_icons = "/usr/share/icons/Arc/status/symbolic/"
local GET_VOLUME_CMD = 'amixer -D pulse sget Master'
local INC_VOLUME_CMD = 'amixer -D pulse sset Master 5%+'
local DEC_VOLUME_CMD = 'amixer -D pulse sset Master 5%-'
local TOG_VOLUME_CMD = 'amixer -D pulse sset Master toggle'
local volume_widget = wibox.widget {
{
id = "icon",
image = path_to_icons .. "audio-volume-muted-symbolic.svg",
resize = false,
widget = wibox.widget.imagebox,
},
layout = wibox.container.margin(_, _, _, 3),
set_image = function(self, path)
self.icon.image = path
end
}
local update_graphic = function(widget, stdout, _, _, _)
local mute = string.match(stdout, "%[(o%D%D?)%]")
local volume = string.match(stdout, "(%d?%d?%d)%%")
volume = tonumber(string.format("% 3d", volume))
local volume_icon_name
if mute == "off" then volume_icon_name="audio-volume-muted-symbolic_red"
elseif (volume >= 0 and volume < 25) then volume_icon_name="audio-volume-muted-symbolic"
elseif (volume < 50) then volume_icon_name="audio-volume-low-symbolic"
elseif (volume < 75) then volume_icon_name="audio-volume-medium-symbolic"
elseif (volume <= 100) then volume_icon_name="audio-volume-high-symbolic"
end
widget.image = path_to_icons .. volume_icon_name .. ".svg"
end
--[[ allows control volume level by:
- clicking on the widget to mute/unmute
- scrolling when cursor is over the widget
]]
volume_widget:connect_signal("button::press", function(_,_,_,button)
if (button == 4) then awful.spawn(INC_VOLUME_CMD, false)
elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD, false)
elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD, false)
end
spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode)
update_graphic(volume_widget, stdout, stderr, exitreason, exitcode)
end)
end)
watch(GET_VOLUME_CMD, 1, update_graphic, volume_widget)
return volume_widget

View File

@ -0,0 +1,25 @@
# Volumearc widget
Almost the same as [volumebar widget](https://github.com/streetturtle/awesome-wm-widgets/tree/master/volumebar-widget), but using arcchart:
![screenshot](out.gif)
Supports:
- scroll up - increase volume,
- scroll down - decrease volume,
- left click - mute/unmute.
## Installation
Clone repo, include widget and use it in **rc.lua**:
```lua
require("volumearc")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
volumearc_widget,
...
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -0,0 +1,59 @@
-------------------------------------------------
-- Volume Arc Widget for Awesome Window Manager
-- Shows the current volume level
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/volumearc-widget
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local beautiful = require("beautiful")
local spawn = require("awful.spawn")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local GET_VOLUME_CMD = 'amixer -D pulse sget Master'
local INC_VOLUME_CMD = 'amixer -D pulse sset Master 5%+'
local DEC_VOLUME_CMD = 'amixer -D pulse sset Master 5%-'
local TOG_VOLUME_CMD = 'amixer -D pulse sset Master toggle'
local volumearc = wibox.widget {
max_value = 1,
thickness = 2,
start_angle = 4.71238898, -- 2pi*3/4
forced_height = 17,
forced_width = 17,
bg = "#ffffff11",
paddings = 2,
widget = wibox.container.arcchart
}
local volumearc_widget = wibox.container.mirror(volumearc, { horizontal = true })
local update_graphic = function(widget, stdout, _, _, _)
local mute = string.match(stdout, "%[(o%D%D?)%]")
local volume = string.match(stdout, "(%d?%d?%d)%%")
volume = tonumber(string.format("% 3d", volume))
widget.value = volume / 100;
widget.colors = mute == 'off' and { beautiful.widget_red }
or { beautiful.widget_main_color }
end
volumearc:connect_signal("button::press", function(_, _, _, button)
if (button == 4) then awful.spawn(INC_VOLUME_CMD, false)
elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD, false)
elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD, false)
end
spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode)
update_graphic(volumearc, stdout, stderr, exitreason, exitcode)
end)
end)
watch(GET_VOLUME_CMD, 1, update_graphic, volumearc)
return volumearc_widget

View File

@ -0,0 +1,29 @@
# Volumebar widget
Almost the same as volume widget, but more minimalistic:
![screenshot](out.gif)
Supports
- scroll up - increase volume,
- scroll down - decrease volume,
- left click - mute/unmute.
## Installation
Clone repo, include widget and use it in **rc.lua**:
```lua
require("volumebar")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
volumebar_widget,
...
```
## Troubleshooting
If the bar is not showing up, try to decrease top or bottom margin - widget uses hardcoded margins for vertical alignment, so if your wibox is too small then bar is simply hidden by the margins.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,66 @@
-------------------------------------------------
-- Volume Bar Widget for Awesome Window Manager
-- Shows the current volume level
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/volumebar-widget
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local gears = require("gears")
local spawn = require("awful.spawn")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local GET_VOLUME_CMD = 'amixer sget Master'
local INC_VOLUME_CMD = 'amixer sset Master 5%+'
local DEC_VOLUME_CMD = 'amixer sset Master 5%-'
local TOG_VOLUME_CMD = 'amixer sset Master toggle'
local bar_color = "#74aeab"
local mute_color = "#ff0000"
local background_color = "#3a3a3a"
local volumebar_widget = wibox.widget {
max_value = 1,
forced_width = 50,
paddings = 0,
border_width = 0.5,
color = bar_color,
background_color = background_color,
shape = gears.shape.bar,
clip = true,
margins = {
top = 8,
bottom = 8,
},
widget = wibox.widget.progressbar
}
local update_graphic = function(widget, stdout, _, _, _)
local mute = string.match(stdout, "%[(o%D%D?)%]")
local volume = string.match(stdout, "(%d?%d?%d)%%")
volume = tonumber(string.format("% 3d", volume))
widget.value = volume / 100;
widget.color = mute == "off" and mute_color
or bar_color
end
volumebar_widget:connect_signal("button::press", function(_,_,_,button)
if (button == 4) then awful.spawn(INC_VOLUME_CMD)
elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD)
elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD)
end
spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode)
update_graphic(volumebar_widget, stdout, stderr, exitreason, exitcode)
end)
end)
watch(GET_VOLUME_CMD, 1, update_graphic, volumebar_widget)
return volumebar_widget

View File

@ -0,0 +1,17 @@
# Weather widget
![Weather Widget](./weather-widget.png)
Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder.
## Installation
- install lua socket
```bash
$ sudo apt-get install lua-socket
```
- download json parser for lua: https://github.com/rxi/json.lua
- get Open Weather Map app id here: https://openweathermap.org/appid
You can read how it works in more details [here](http://pavelmakhov.com/2017/02/weather-widget-for-awesome-wm)

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,132 @@
-------------------------------------------------
-- Weather Widget based on the OpenWeatherMap
-- https://openweathermap.org/
--
-- @author Pavel Makhov
-- @copyright 2018 Pavel Makhov
-------------------------------------------------
local http = require("socket.http")
local json = require("json")
local naughty = require("naughty")
local wibox = require("wibox")
local city = os.getenv("AWW_WEATHER_CITY") or "Montreal,ca"
local open_map_key = os.getenv("AWW_WEATHER_API_KEY") or 'c3d7320b359da4e48c2d682a04076576'
local path_to_icons = "/usr/share/icons/Arc/status/symbolic/"
local icon_widget = wibox.widget {
{
id = "icon",
resize = false,
widget = wibox.widget.imagebox,
},
layout = wibox.container.margin(_ , 0, 0, 3),
set_image = function(self, path)
self.icon.image = path
end,
}
local temp_widget = wibox.widget{
font = "Play 9",
widget = wibox.widget.textbox,
}
local weather_widget = wibox.widget {
icon_widget,
temp_widget,
layout = wibox.layout.fixed.horizontal,
}
--- Maps openWeatherMap icons to Arc icons
local icon_map = {
["01d"] = "weather-clear-symbolic.svg",
["02d"] = "weather-few-clouds-symbolic.svg",
["03d"] = "weather-clouds-symbolic.svg",
["04d"] = "weather-overcast-symbolic.svg",
["09d"] = "weather-showers-scattered-symbolic.svg",
["10d"] = "weather-showers-symbolic.svg",
["11d"] = "weather-storm-symbolic.svg",
["13d"] = "weather-snow-symbolic.svg",
["50d"] = "weather-fog-symbolic.svg",
["01n"] = "weather-clear-night-symbolic.svg",
["02n"] = "weather-few-clouds-night-symbolic.svg",
["03n"] = "weather-clouds-night-symbolic.svg",
["04n"] = "weather-overcast-symbolic.svg",
["09n"] = "weather-showers-scattered-symbolic.svg",
["10n"] = "weather-showers-symbolic.svg",
["11n"] = "weather-storm-symbolic.svg",
["13n"] = "weather-snow-symbolic.svg",
["50n"] = "weather-fog-symbolic.svg"
}
--- handy function to convert temperature from Kelvin to Celcius
function to_celcius(kelvin)
return math.floor(tonumber(kelvin) - 273.15)
end
--- Return wind direction as a string.
function to_direction(degrees)
-- Ref: https://www.campbellsci.eu/blog/convert-wind-directions
if degrees == nil then
return "Unknown dir"
end
local directions = {
"N",
"NNE",
"NE",
"ENE",
"E",
"ESE",
"SE",
"SSE",
"S",
"SSW",
"SW",
"WSW",
"W",
"WNW",
"NW",
"NNW",
"N",
}
return directions[math.floor((degrees % 360) / 22.5) + 1]
end
local weather_timer = timer({ timeout = 60 })
local resp
weather_timer:connect_signal("timeout", function ()
local resp_json = http.request("https://api.openweathermap.org/data/2.5/weather?q=" .. city .."&appid=" .. open_map_key)
if (resp_json ~= nil) then
resp = json.decode(resp_json)
icon_widget.image = path_to_icons .. icon_map[resp.weather[1].icon]
temp_widget:set_text(to_celcius(resp.main.temp) .. "°C")
end
end)
weather_timer:start()
weather_timer:emit_signal("timeout")
--- Notification with weather information. Popups when mouse hovers over the icon
local notification
weather_widget:connect_signal("mouse::enter", function()
notification = naughty.notify{
icon = path_to_icons .. icon_map[resp.weather[1].icon],
icon_size=20,
text =
'<big>' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')</big><br>' ..
'<b>Humidity:</b> ' .. resp.main.humidity .. '%<br>' ..
'<b>Temperature: </b>' .. to_celcius(resp.main.temp) .. '<br>' ..
'<b>Pressure: </b>' .. resp.main.pressure .. 'hPa<br>' ..
'<b>Clouds: </b>' .. resp.clouds.all .. '%<br>' ..
'<b>Wind: </b>' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')',
timeout = 5, hover_timeout = 10,
width = 200
}
end)
weather_widget:connect_signal("mouse::leave", function()
naughty.destroy(notification)
end)
return weather_widget

17
rc.lua
View File

@ -13,6 +13,11 @@ local beautiful = require("beautiful")
local naughty = require("naughty")
local menubar = require("menubar")
local hotkeys_popup = require("awful.hotkeys_popup").widget
local volume_widget = require("awesome-wm-widgets.volume-widget.volume")
local volume_bar_widget = require("awesome-wm-widgets.volumebar-widget.volumebar")
local cpu_widget = require("awesome-wm-widgets.cpu-widget.cpu-widget")
local battery_widget = require("awesome-wm-widgets.battery-widget.battery")
local ram_widget = require("awesome-wm-widgets.ram-widget.ram-widget")
-- Custom imports
local options = require("options")
@ -201,13 +206,12 @@ local tasklist_buttons = awful.util.table.join(
awful.client.focus.byidx(-1)
end))
local battery = require('battery')
local volume = require('volume')
local calendar = require('calendar')
local launchbar = require('launchbar')
local music = require('music')
-- local background = require('background_widget')
local delimiter = wibox.widget.textbox(" | ")
local delimiter2 = wibox.widget.textbox(" ")
local function set_wallpaper(s)
-- Wallpaper
@ -268,7 +272,13 @@ awful.screen.connect_for_each_screen(function(s)
music.icon_widget,
music.text_widget,
delimiter,
ram_widget,
delimiter2,
cpu_widget,
delimiter,
volume_widget,
delimiter2,
volume_bar_widget,
delimiter,
battery_widget,
delimiter,
@ -398,17 +408,14 @@ globalkeys = awful.util.table.join(
-- Custom shortcuts
awful.key({ }, "XF86AudioRaiseVolume", function()
awful.util.spawn("amixer set Master 3%+", false)
update_volume()
end, {description = "increase the volume by 3%", group="custom"}),
awful.key({ }, "XF86AudioLowerVolume", function()
awful.util.spawn("amixer set Master 3%-", false)
update_volume()
end, {description = "decrease the volume by 3%", group="custom"}),
awful.key({ }, "XF86AudioMute", function()
awful.util.spawn("amixer set Master toggle", false)
update_volume()
end, {description = "mute sound", group="custom"}),
awful.key({ }, "XF86MonBrightnessDown", function ()