Changes repo name

This commit is contained in:
Kristofers Solo 2022-05-11 15:20:59 +03:00
parent 5b841abc4f
commit 4814ea6260
285 changed files with 0 additions and 13364 deletions

View File

@ -1 +0,0 @@
@streetturtle

View File

@ -1 +0,0 @@
github: streetturtle

View File

@ -1,30 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: luacheck
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches:
- '*'
paths:
- '**.lua'
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v2
- name: Run Luacheck
uses: nebularg/actions-luacheck@v1.1.0

View File

@ -1,43 +0,0 @@
name: update site
on:
push:
branches:
- 'master'
paths:
- '**/README.md'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Generate md
run: ./scripts/update_site.sh
- name: Push to gh-pages branch
run: |
git config --global user.name 'GitHub Action'
git config --global user.email 'action@github.com'
git add ./_widgets
git add ./assets/img/widgets
git stash
git fetch
echo "git checkout gh-pages"
git checkout gh-pages
rm -rf ./_widgets
rm -rf ./assets/img/widgets
ls -alF
echo "git stash pop"
git checkout stash -- ./_widgets
git checkout stash -- ./assets/img/widgets
git add ./_widgets
git add ./assets/img/widgets
git commit -m "update from master"
git push origin gh-pages

View File

@ -1,48 +0,0 @@
# 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
# vscode files
.history
/_site/
/.jekyll-cache/

View File

@ -1,24 +0,0 @@
self = false
globals = {
"screen",
"mouse",
"root",
"client"
}
read_globals = {
"awesome",
"button",
"dbus",
"drawable",
"drawin",
"key",
"keygrabber",
"mousegrabber",
"selection",
"tag",
"window",
"table.unpack",
"math.atan2",
}

View File

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

@ -1,63 +0,0 @@
<p align="center">
<img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/awesome-o.png" alt="logo" style="max-width:100%;">
</p>
<p align="center">
<img src="https://img.shields.io/github/stars/streetturtle/awesome-wm-widgets.svg">
<img src="https://img.shields.io/github/forks/streetturtle/awesome-wm-widgets.svg">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/streetturtle/awesome-wm-widgets">
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/streetturtle/awesome-wm-widgets/luacheck">
<a href="https://www.buymeacoffee.com/streetturtle"><img src="https://img.shields.io/badge/-buy%20me%20a%20coffee-3B4252?style=flat&logo=Buy-Me-A-Coffee"></a>
<a href="https://twitter.com/intent/tweet?text=Check%20out%20these%20awesome%20widgets%20for%20Awesome Window Manager%20&url=https://github.com/streetturtle/awesome-wm-widgets">
<img src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social">
</a>
</p>
Set of widgets compatible with Awesome Window Manager v.4.3+.
## Screenshots
Spotify, CPU, RAM, brightness-arc, volume-arc and battery-arc widgets:
<p align="center">
<img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/Screenshot%20from%202019-03-01%2014-28-18.png">
</p>
Brightness, volume and battery widgets:
<p align="center">
<img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/widgets-icons.png">
</p>
![screenshot](./screenshot.png)
Some more screenshots in this reddit [post](https://www.reddit.com/r/unixporn/comments/8qijmx/awesomewm_dark_theme/)
# Installation
Clone the repo under **~/.config/awesome/**, then follow an Installation section of widget's readme file.
# Stargazers
[![Stargazers over time](https://starchart.cc/streetturtle/awesome-wm-widgets.svg)](https://starchart.cc/streetturtle/awesome-wm-widgets)
# Troubleshooting
In case of any doubts/questions/problems:
- create an [issue](https://github.com/streetturtle/awesome-wm-widgets/issues/new/choose)
- raise a question on [Discussions](https://github.com/streetturtle/awesome-wm-widgets/discussions)!
- ping me on AwesomeWM's discord, here's an [invite](https://discord.gg/XYvn8R5)
# Support
If you find anything useful here, you can:
- star a repo - this really motivates me to work on this project
- or <a class="social-link" href="https://www.buymeacoffee.com/streetturtle"><img style="display:inline" src="https://img.shields.io/badge/-buy%20me%20a%20coffee-3B4252?style=flat&logo=Buy-Me-A-Coffee"></a>
- or even become a [sponsor](https://github.com/sponsors/streetturtle)
# Contributors
<a href="https://github.com/streetturtle/awesome-wm-widgets/graphs/contributors">
<img src="https://contrib.rocks/image?repo=streetturtle/awesome-wm-widgets" />
</a>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@ -1,27 +0,0 @@
# APT widget
Widget which shows a list of APT packages to be updated:
![screenshot](./screenshots/screenshot.gif)
Features:
- scrollable list !!! (thanks to this [post](https://www.reddit.com/r/awesomewm/comments/isx89x/scrolling_a_layout_fixed_flexed_layout_widget/) of reddit)
- update single package
- update multiple packages
## Installation
Clone the repo under ~/.config/awesome/ folder, then in rc.lua add the following:
```lua
local apt_widget = require("awesome-wm-widgets.apt-widget.apt-widget")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
apt_widget(),
...
```

View File

@ -1,349 +0,0 @@
-------------------------------------------------
-- APT Widget for Awesome Window Manager
-- Lists containers and allows to manage them
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/apt-widget
-- @author Pavel Makhov
-- @copyright 2021 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/apt-widget'
local ICONS_DIR = WIDGET_DIR .. '/icons/'
local LIST_PACKAGES = [[sh -c "apt list --upgradable 2>/dev/null"]]
--- Utility function to show warning messages
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = 'Docker Widget',
text = message}
end
local wibox_popup = wibox {
ontop = true,
visible = false,
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 4)
end,
border_width = 1,
border_color = beautiful.bg_focus,
max_widget_size = 500,
height = 500,
width = 300,
}
local apt_widget = wibox.widget {
{
{
id = 'icon',
widget = wibox.widget.imagebox
},
margins = 4,
layout = wibox.container.margin
},
layout = wibox.layout.fixed.horizontal,
set_icon = function(self, new_icon)
self:get_children_by_id("icon")[1].image = new_icon
end
}
--- Parses the line and creates the package table out of it
--- yaru-theme-sound/focal-updates,focal-updates 20.04.10.1 all [upgradable from: 20.04.8]
local parse_package = function(line)
local name,_,nv,type,ov = line:match('(.*)%/(.*)%s(.*)%s(.*)%s%[upgradable from: (.*)]')
if name == nil then return nil end
local package = {
name = name,
new_version = nv,
type = type,
old_version = ov
}
return package
end
local function worker(user_args)
local args = user_args or {}
local icon = args.icon or ICONS_DIR .. 'white-black.svg'
apt_widget:set_icon(icon)
local pointer = 0
local min_widgets = 5
local carousel = false
local function rebuild_widget(containers, errors, _, _)
local to_update = {}
if errors ~= '' then
show_warning(errors)
return
end
local rows = wibox.layout.fixed.vertical()
rows:connect_signal("button::press", function(_,_,_,button)
if carousel then
if button == 4 then -- up scrolling
local cnt = #rows.children
local first_widget = rows.children[1]
rows:insert(cnt+1, first_widget)
rows:remove(1)
elseif button == 5 then -- down scrolling
local cnt = #rows.children
local last_widget = rows.children[cnt]
rows:insert(1, last_widget)
rows:remove(cnt+1)
end
else
if button == 5 then -- up scrolling
if pointer < #rows.children and ((#rows.children - pointer) >= min_widgets) then
pointer = pointer + 1
rows.children[pointer].visible = false
end
elseif button == 4 then -- down scrolling
if pointer > 0 then
rows.children[pointer].visible = true
pointer = pointer - 1
end
end
end
end)
for line in containers:gmatch("[^\r\n]+") do
local package = parse_package(line)
if package ~= nil then
local refresh_button = wibox.widget {
{
{
id = 'icon',
image = ICONS_DIR .. 'refresh-cw.svg',
resize = false,
widget = wibox.widget.imagebox
},
margins = 4,
widget = wibox.container.margin
},
shape = gears.shape.circle,
opacity = 0.5,
widget = wibox.container.background
}
local old_cursor, old_wibox
refresh_button:connect_signal("mouse::enter", function(c)
c:set_opacity(1)
c:emit_signal('widget::redraw_needed')
local wb = mouse.current_wibox
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
end)
refresh_button:connect_signal("mouse::leave", function(c)
c:set_opacity(0.5)
c:emit_signal('widget::redraw_needed')
if old_wibox then
old_wibox.cursor = old_cursor
old_wibox = nil
end
end)
local row = wibox.widget {
{
{
{
{
id = 'checkbox',
checked = false,
color = beautiful.bg_normal,
paddings = 2,
shape = gears.shape.circle,
forced_width = 20,
forced_height = 20,
check_color = beautiful.fg_urgent,
border_color = beautiful.bg_urgent,
border_width = 1,
widget = wibox.widget.checkbox
},
valign = 'center',
layout = wibox.container.place,
},
{
{
id = 'name',
markup = '<b>' .. package['name'] .. '</b>',
widget = wibox.widget.textbox
},
halign = 'left',
layout = wibox.container.place
},
{
refresh_button,
halign = 'right',
valign = 'center',
fill_horizontal = true,
layout = wibox.container.place,
},
spacing = 8,
layout = wibox.layout.fixed.horizontal
},
margins = 8,
layout = wibox.container.margin
},
id = 'row',
bg = beautiful.bg_normal,
widget = wibox.container.background,
click = function(self, checked)
local a = self:get_children_by_id('checkbox')[1]
if checked == nil then
a:set_checked(not a.checked)
else
a:set_checked(checked)
end
if a.checked then
to_update[package['name']] = self
else
to_update[package['name']] = false
end
end,
update = function(self)
refresh_button:get_children_by_id('icon')[1]:set_image(ICONS_DIR .. 'watch.svg')
self:get_children_by_id('name')[1]:set_opacity(0.4)
self:get_children_by_id('name')[1]:emit_signal('widget::redraw_needed')
spawn.easy_async(
string.format([[sh -c 'yes | aptdcon --hide-terminal -u %s']], package['name']),
function(stdout, stderr) -- luacheck:ignore 212
rows:remove_widgets(self)
end)
end
}
row:connect_signal("mouse::enter", function(c)
c:set_bg(beautiful.bg_focus)
end)
row:connect_signal("mouse::leave", function(c)
c:set_bg(beautiful.bg_normal)
end)
row:connect_signal("button::press", function(c, _, _, button)
if button == 1 then c:click() end
end)
refresh_button:buttons(awful.util.table.join(awful.button({}, 1, function()
row:update()
end)))
rows:add(row)
end
end
local header_checkbox = wibox.widget {
checked = false,
color = beautiful.bg_normal,
paddings = 2,
shape = gears.shape.circle,
forced_width = 20,
forced_height = 20,
check_color = beautiful.fg_urgent,
border_color = beautiful.bg_urgent,
border_width = 1,
widget = wibox.widget.checkbox
}
header_checkbox:connect_signal("button::press", function(c)
c:set_checked(not c.checked)
local cbs = rows.children
for _,v in ipairs(cbs) do
v:click(c.checked)
end
end)
local header_refresh_icon = wibox.widget {
image = ICONS_DIR .. 'refresh-cw.svg',
resize = false,
widget = wibox.widget.imagebox
}
header_refresh_icon:buttons(awful.util.table.join(awful.button({}, 1, function()
print(#to_update)
for _,v in pairs(to_update) do
if v ~= nil then
v:update()
end
end
end)))
local header_row = wibox.widget {
{
{
{
header_checkbox,
valign = 'center',
layout = wibox.container.place,
},
{
{
id = 'name',
markup = '<b>' .. #rows.children .. '</b> packages to update',
widget = wibox.widget.textbox
},
halign = 'center',
layout = wibox.container.place
},
{
header_refresh_icon,
halign = 'right',
valign = 'center',
layout = wibox.container.place,
},
layout = wibox.layout.align.horizontal
},
margins = 8,
layout = wibox.container.margin
},
bg = beautiful.bg_normal,
widget = wibox.container.background
}
wibox_popup:setup {
header_row,
rows,
layout = wibox.layout.fixed.vertical
}
end
apt_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function()
if wibox_popup.visible then
wibox_popup.visible = not wibox_popup.visible
else
spawn.easy_async(LIST_PACKAGES,
function(stdout, stderr)
rebuild_widget(stdout, stderr)
wibox_popup.visible = true
awful.placement.top(wibox_popup, { margins = { top = 20 }, parent = mouse})
end)
end
end)
)
)
return apt_widget
end
return setmetatable(apt_widget, { __call = function(_, ...) return worker(...) end })

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="circle_of_friends__x5F__black"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="425.197px"
height="425.197px" viewBox="0 0 425.197 425.197" enable-background="new 0 0 425.197 425.197" xml:space="preserve">
<g>
<path d="M354.331,212.595c0,78.279-63.45,141.735-141.729,141.735c-78.279,0-141.735-63.456-141.735-141.735
c0-78.274,63.457-141.728,141.735-141.728C290.881,70.867,354.331,134.32,354.331,212.595z"/>
<path fill="#FFFFFF" d="M139.043,212.595c0,10.064-8.159,18.225-18.23,18.225c-10.059,0-18.218-8.16-18.218-18.225
c0-10.06,8.159-18.219,18.218-18.219C130.884,194.376,139.043,202.535,139.043,212.595z M242.717,301.201
c5.033,8.709,16.173,11.696,24.889,6.67c8.715-5.033,11.701-16.179,6.669-24.895c-5.032-8.715-16.173-11.695-24.888-6.663
C240.671,281.346,237.685,292.486,242.717,301.201z M274.274,142.219c5.032-8.717,2.052-19.86-6.669-24.887
c-8.71-5.032-19.855-2.046-24.889,6.667c-5.032,8.715-2.046,19.857,6.67,24.889C258.102,153.92,269.248,150.934,274.274,142.219z
M212.602,160.632c27.153,0,49.434,20.814,51.761,47.364l26.372-0.416c-1.252-19.727-9.809-37.469-22.995-50.551
c-6.98,2.693-15.079,2.327-22.066-1.71c-6.992-4.037-11.359-10.871-12.514-18.275c-6.554-1.78-13.448-2.733-20.558-2.733
c-12.471,0-24.259,2.916-34.727,8.103l12.832,23.043C197.357,162.367,204.784,160.632,212.602,160.632z M160.633,212.595
c0-17.577,8.734-33.121,22.097-42.52l-13.54-22.634c-15.684,10.474-27.367,26.451-32.296,45.183
c5.833,4.697,9.57,11.897,9.57,19.972c0,8.08-3.738,15.28-9.57,19.978c4.929,18.731,16.612,34.708,32.296,45.188l13.54-22.634
C169.367,245.722,160.633,230.184,160.633,212.595z M212.602,264.568c-7.817,0-15.244-1.734-21.895-4.83l-12.832,23.043
c10.468,5.191,22.255,8.104,34.727,8.104c7.109,0,14.004-0.946,20.558-2.729c1.154-7.409,5.521-14.243,12.514-18.273
c6.987-4.037,15.086-4.404,22.066-1.711c13.187-13.088,21.743-30.83,22.995-50.557l-26.372-0.409
C262.035,243.749,239.755,264.568,212.602,264.568z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>

Before

Width:  |  Height:  |  Size: 365 B

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="circle_of_friends__x5F__orange"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="425.197px"
height="425.197px" viewBox="0 0 425.197 425.197" enable-background="new 0 0 425.197 425.197" xml:space="preserve">
<g>
<path fill="#E95420" d="M354.331,212.595c0,78.279-63.45,141.735-141.729,141.735c-78.279,0-141.735-63.456-141.735-141.735
c0-78.274,63.457-141.728,141.735-141.728C290.881,70.867,354.331,134.32,354.331,212.595z"/>
<path fill="#FFFFFF" d="M139.043,212.595c0,10.064-8.159,18.225-18.23,18.225c-10.059,0-18.218-8.16-18.218-18.225
c0-10.06,8.159-18.219,18.218-18.219C130.884,194.376,139.043,202.535,139.043,212.595z M242.717,301.201
c5.033,8.709,16.173,11.696,24.889,6.67c8.715-5.033,11.701-16.179,6.669-24.895c-5.032-8.715-16.173-11.695-24.888-6.663
C240.671,281.346,237.685,292.486,242.717,301.201z M274.274,142.219c5.032-8.717,2.052-19.86-6.669-24.887
c-8.71-5.032-19.855-2.046-24.889,6.667c-5.032,8.715-2.046,19.857,6.67,24.889C258.102,153.92,269.248,150.934,274.274,142.219z
M212.602,160.632c27.153,0,49.434,20.814,51.761,47.364l26.372-0.416c-1.252-19.727-9.809-37.469-22.995-50.551
c-6.98,2.693-15.079,2.327-22.066-1.71c-6.992-4.037-11.359-10.871-12.514-18.275c-6.554-1.78-13.448-2.733-20.558-2.733
c-12.471,0-24.259,2.916-34.727,8.103l12.832,23.043C197.357,162.367,204.784,160.632,212.602,160.632z M160.633,212.595
c0-17.577,8.734-33.121,22.097-42.52l-13.54-22.634c-15.684,10.474-27.367,26.451-32.296,45.183
c5.833,4.697,9.57,11.897,9.57,19.972c0,8.08-3.738,15.28-9.57,19.978c4.929,18.731,16.612,34.708,32.296,45.188l13.54-22.634
C169.367,245.722,160.633,230.184,160.633,212.595z M212.602,264.568c-7.817,0-15.244-1.734-21.895-4.83l-12.832,23.043
c10.468,5.191,22.255,8.104,34.727,8.104c7.109,0,14.004-0.946,20.558-2.729c1.154-7.409,5.521-14.243,12.514-18.273
c6.987-4.037,15.086-4.404,22.066-1.711c13.187-13.088,21.743-30.83,22.995-50.557l-26.372-0.409
C262.035,243.749,239.755,264.568,212.602,264.568z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-refresh-cw"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>

Before

Width:  |  Height:  |  Size: 395 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-watch"><circle cx="12" cy="12" r="7"></circle><polyline points="12 9 12 12 13.5 13.5"></polyline><path d="M16.51 17.35l-.35 3.83a2 2 0 0 1-2 1.82H9.83a2 2 0 0 1-2-1.82l-.35-3.83m.01-10.7l.35-3.83A2 2 0 0 1 9.83 1h4.35a2 2 0 0 1 2 1.82l.35 3.83"></path></svg>

Before

Width:  |  Height:  |  Size: 457 B

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="circle_of_friends__x5F__white"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="425.197px"
height="425.197px" viewBox="0 0 425.197 425.197" enable-background="new 0 0 425.197 425.197" xml:space="preserve">
<g>
<path fill="#FFFFFF" d="M354.331,212.595c0,78.279-63.45,141.735-141.729,141.735c-78.279,0-141.735-63.456-141.735-141.735
c0-78.274,63.457-141.728,141.735-141.728C290.881,70.867,354.331,134.32,354.331,212.595z"/>
<path d="M139.043,212.595c0,10.064-8.159,18.225-18.23,18.225c-10.059,0-18.218-8.16-18.218-18.225
c0-10.06,8.159-18.219,18.218-18.219C130.884,194.376,139.043,202.535,139.043,212.595z M242.717,301.201
c5.033,8.709,16.173,11.696,24.889,6.67c8.715-5.033,11.701-16.179,6.669-24.895c-5.032-8.715-16.173-11.695-24.888-6.663
C240.671,281.346,237.685,292.486,242.717,301.201z M274.274,142.219c5.032-8.717,2.052-19.86-6.669-24.887
c-8.71-5.032-19.855-2.046-24.889,6.667c-5.032,8.715-2.046,19.857,6.67,24.889C258.102,153.92,269.248,150.934,274.274,142.219z
M212.602,160.632c27.153,0,49.434,20.814,51.761,47.364l26.372-0.416c-1.252-19.727-9.809-37.469-22.995-50.551
c-6.98,2.693-15.079,2.327-22.066-1.71c-6.992-4.037-11.359-10.871-12.514-18.275c-6.554-1.78-13.448-2.733-20.558-2.733
c-12.471,0-24.259,2.916-34.727,8.103l12.832,23.043C197.357,162.367,204.784,160.632,212.602,160.632z M160.633,212.595
c0-17.577,8.734-33.121,22.097-42.52l-13.54-22.634c-15.684,10.474-27.367,26.451-32.296,45.183
c5.833,4.697,9.57,11.897,9.57,19.972c0,8.08-3.738,15.28-9.57,19.978c4.929,18.731,16.612,34.708,32.296,45.188l13.54-22.634
C169.367,245.722,160.633,230.184,160.633,212.595z M212.602,264.568c-7.817,0-15.244-1.734-21.895-4.83l-12.832,23.043
c10.468,5.191,22.255,8.104,34.727,8.104c7.109,0,14.004-0.946,20.558-2.729c1.154-7.409,5.521-14.243,12.514-18.273
c6.987-4.037,15.086-4.404,22.066-1.711c13.187-13.088,21.743-30.83,22.995-50.557l-26.372-0.409
C262.035,243.749,239.755,264.568,212.602,264.568z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="circle_of_friends__x5F__white_x26_orange"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="425.197px"
height="425.197px" viewBox="0 0 425.197 425.197" enable-background="new 0 0 425.197 425.197" xml:space="preserve">
<g>
<path fill="#FFFFFF" d="M354.331,212.595c0,78.279-63.45,141.735-141.729,141.735c-78.279,0-141.735-63.456-141.735-141.735
c0-78.274,63.457-141.728,141.735-141.728C290.881,70.867,354.331,134.32,354.331,212.595z"/>
<path fill="#E95420" d="M139.043,212.595c0,10.064-8.159,18.225-18.23,18.225c-10.059,0-18.218-8.16-18.218-18.225
c0-10.06,8.159-18.219,18.218-18.219C130.884,194.376,139.043,202.535,139.043,212.595z M242.717,301.201
c5.033,8.709,16.173,11.696,24.889,6.67c8.715-5.033,11.701-16.179,6.669-24.895c-5.032-8.715-16.173-11.695-24.888-6.663
C240.671,281.346,237.685,292.486,242.717,301.201z M274.274,142.219c5.032-8.717,2.052-19.86-6.669-24.887
c-8.71-5.032-19.855-2.046-24.889,6.667c-5.032,8.715-2.046,19.857,6.67,24.889C258.102,153.92,269.248,150.934,274.274,142.219z
M212.602,160.632c27.153,0,49.434,20.814,51.761,47.364l26.372-0.416c-1.252-19.727-9.809-37.469-22.995-50.551
c-6.98,2.693-15.079,2.327-22.066-1.71c-6.992-4.037-11.359-10.871-12.514-18.275c-6.554-1.78-13.448-2.733-20.558-2.733
c-12.471,0-24.259,2.916-34.727,8.103l12.832,23.043C197.357,162.367,204.784,160.632,212.602,160.632z M160.633,212.595
c0-17.577,8.734-33.121,22.097-42.52l-13.54-22.634c-15.684,10.474-27.367,26.451-32.296,45.183
c5.833,4.697,9.57,11.897,9.57,19.972c0,8.08-3.738,15.28-9.57,19.978c4.929,18.731,16.612,34.708,32.296,45.188l13.54-22.634
C169.367,245.722,160.633,230.184,160.633,212.595z M212.602,264.568c-7.817,0-15.244-1.734-21.895-4.83l-12.832,23.043
c10.468,5.191,22.255,8.104,34.727,8.104c7.109,0,14.004-0.946,20.558-2.729c1.154-7.409,5.521-14.243,12.514-18.273
c6.987-4.037,15.086-4.404,22.066-1.711c13.187-13.088,21.743-30.83,22.995-50.557l-26.372-0.409
C262.035,243.749,239.755,264.568,212.602,264.568z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

View File

@ -1,75 +0,0 @@
# 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.
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `font` | Play 8 | Fond |
| `path_to_icons` | `/usr/share/icons/Arc/status/symbolic/` | Path to the folder with icons* |
| `show_current_level`| false | Show current charge level |
| `margin_right`|0| The right margin of the widget|
| `margin_left`|0| The left margin of the widget|
| `display_notification` | `false` | Display a notification on mouseover |
| `notification_position` | `top_right` | The notification position |
| `timeout` | 10 | How often in seconds the widget refreshes |
| `warning_msg_title` | _Huston, we have a problem_ | Title of the warning popup |
| `warning_msg_text` | _Battery is dying_ | Text of the warning popup |
| `warning_msg_position` | `bottom_right` | Position of the warning popup |
| `warning_msg_icon` | ~/.config/awesome/awesome-wm-widgets/battery-widget/spaceman.jpg | Icon of the warning popup |
| `enable_battery_warning` | `true` | Display low battery warning |
*Note: the widget expects following icons to be present in the folder:
- battery-caution-charging-symbolic.svg
- battery-empty-charging-symbolic.svg
- battery-full-charged-symbolic.svg
- battery-full-symbolic.svg
- battery-good-symbolic.svg
- battery-low-symbolic.svg
- battery-caution-symbolic.svg
- battery-empty-symbolic.svg
- battery-full-charging-symbolic.svg
- battery-good-charging-symbolic.svg
- battery-low-charging-symbolic.svg
- battery-missing-symbolic.svg
## 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
```
```lua
local battery_widget = require("awesome-wm-widgets.battery-widget.battery")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
battery_widget(),
...
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,200 +0,0 @@
-------------------------------------------------
-- 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")
local gfs = require("gears.filesystem")
local dpi = require('beautiful').xresources.apply_dpi
-- acpi sample outputs
-- Battery 0: Discharging, 75%, 01:51:38 remaining
-- Battery 0: Charging, 53%, 00:57:43 until charged
local HOME = os.getenv("HOME")
local WIDGET_DIR = HOME .. '/.config/awesome/awesome-wm-widgets/battery-widget'
local battery_widget = {}
local function worker(user_args)
local args = user_args or {}
local font = args.font or 'Play 8'
local path_to_icons = args.path_to_icons or "/usr/share/icons/Arc/status/symbolic/"
local show_current_level = args.show_current_level or false
local margin_left = args.margin_left or 0
local margin_right = args.margin_right or 0
local display_notification = args.display_notification or false
local display_notification_onClick = args.display_notification_onClick or true
local position = args.notification_position or "top_right"
local timeout = args.timeout or 10
local warning_msg_title = args.warning_msg_title or 'Huston, we have a problem'
local warning_msg_text = args.warning_msg_text or 'Battery is dying'
local warning_msg_position = args.warning_msg_position or 'bottom_right'
local warning_msg_icon = args.warning_msg_icon or WIDGET_DIR .. '/spaceman.jpg'
local enable_battery_warning = args.enable_battery_warning
if enable_battery_warning == nil then
enable_battery_warning = true
end
if not gfs.dir_readable(path_to_icons) then
naughty.notify{
title = "Battery Widget",
text = "Folder with icons doesn't exist: " .. path_to_icons,
preset = naughty.config.presets.critical
}
end
local icon_widget = wibox.widget {
{
id = "icon",
widget = wibox.widget.imagebox,
resize = false
},
valign = 'center',
layout = wibox.container.place,
}
local level_widget = wibox.widget {
font = font,
widget = wibox.widget.textbox
}
battery_widget = wibox.widget {
icon_widget,
level_widget,
layout = wibox.layout.fixed.horizontal,
}
-- Popup with battery info
-- One way of creating a pop-up notification - naughty.notify
local notification
local function show_battery_status(batteryType)
awful.spawn.easy_async([[bash -c 'acpi']],
function(stdout, _, _, _)
naughty.destroy(notification)
notification = naughty.notify{
text = stdout,
title = "Battery status",
icon = path_to_icons .. batteryType .. ".svg",
icon_size = dpi(16),
position = position,
timeout = 5, hover_timeout = 0.5,
width = 200,
screen = mouse.screen
}
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 = warning_msg_icon,
icon_size = 100,
text = warning_msg_text,
title = warning_msg_title,
timeout = 25, -- show the warning for a longer time
hover_timeout = 0.5,
position = warning_msg_position,
bg = "#F06060",
fg = "#EEE9EF",
width = 300,
screen = mouse.screen
}
end
local last_battery_check = os.time()
local batteryType = "battery-good-symbolic"
watch("acpi -i", timeout,
function(widget, stdout)
local battery_info = {}
local capacities = {}
for s in stdout:gmatch("[^\r\n]+") do
local status, charge_str, _ = 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 _, cap in ipairs(capacities) do
capacity = capacity + cap
end
local charge = 0
local status
for i, batt in ipairs(battery_info) do
if capacities[i] ~= nil then
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
end
charge = charge / capacity
if show_current_level then
level_widget.text = string.format('%d%%', charge)
end
if (charge >= 0 and charge < 15) then
batteryType = "battery-empty%s-symbolic"
if enable_battery_warning and status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then
-- if 5 minutes have elapsed since the last warning
last_battery_check = os.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,
icon_widget)
if display_notification then
battery_widget:connect_signal("mouse::enter", function() show_battery_status(batteryType) end)
battery_widget:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
elseif display_notification_onClick then
battery_widget:connect_signal("button::press", function(_,_,_,button)
if (button == 3) then show_battery_status(batteryType) end
end)
battery_widget:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
end
return wibox.container.margin(battery_widget, margin_left, margin_right)
end
return setmetatable(battery_widget, { __call = function(_, ...) return worker(...) end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,72 +0,0 @@
# Batteryarc widget
[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/batteryarc)](https://github.com/streetturtle/awesome-wm-widgets/labels/batteryarc)
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
If a battery level is low then warning popup will show up:
![warning](./warning.png)
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `font` | Play 6 | Font |
| `arc_thickness` | 2 | Thickness of the arc |
| `show_current_level`| false | Show current charge level |
| `size`| 18 | Size of the widget |
| `timeout` | 10 | How often in seconds the widget refreshes |
| `main_color` | `beautiful.fg_color` | Color of the text with the current charge level and the arc |
| `bg_color` | `#ffffff11` | Color of the charge level background |
| `low_level_color` | `#e53935` | Arc color when battery charge is less that 15% |
| `medium_level_color` | `#c0ca33` | Arc color when battery charge is between 15% and 40% |
| `charging_color` | `#43a047` | Color of the circle inside the arc when charging |
| `warning_msg_title` | _Huston, we have a problem_ | Title of the warning popup |
| `warning_msg_text` | _Battery is dying_ | Text of the warning popup |
| `warning_msg_position` | `bottom_right` | Position of the warning popup |
| `warning_msg_icon` | ~/.config/awesome/awesome-wm-widgets/batteryarc-widget/spaceman.jpg | Icon of the warning popup |
| `enable_battery_warning` | `true` | Display low battery warning |
| `show_notification_mode` | `on_hover` | How to trigger a notification with the battery status: `on_hover`, `on_click` or `off` |
## Requirements
This widget requires the `acpi` command to be available to retrieve battery and
power information.
## 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,
...
--[[default]]
batteryarc_widget(),
--[[or customized]]
batteryarc_widget({
show_current_level = true,
arc_thickness = 1,
}),
}
...
```
## Troubleshooting
In case of any doubts or questions please raise an [issue](https://github.com/streetturtle/awesome-wm-widgets/issues/new).

View File

@ -1,168 +0,0 @@
-------------------------------------------------
-- Battery Arc Widget for Awesome Window Manager
-- Shows the battery level of the laptop
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/batteryarc-widget
-- @author Pavel Makhov
-- @copyright 2020 Pavel Makhov
-------------------------------------------------
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")
local WIDGET_DIR = HOME .. '/.config/awesome/awesome-wm-widgets/batteryarc-widget'
local batteryarc_widget = {}
local function worker(user_args)
local args = user_args or {}
local font = args.font or 'Play 6'
local arc_thickness = args.arc_thickness or 2
local show_current_level = args.show_current_level or false
local size = args.size or 18
local timeout = args.timeout or 10
local show_notification_mode = args.show_notification_mode or 'on_hover' -- on_hover / on_click
local main_color = args.main_color or beautiful.fg_color
local bg_color = args.bg_color or '#ffffff11'
local low_level_color = args.low_level_color or '#e53935'
local medium_level_color = args.medium_level_color or '#c0ca33'
local charging_color = args.charging_color or '#43a047'
local warning_msg_title = args.warning_msg_title or 'Houston, we have a problem'
local warning_msg_text = args.warning_msg_text or 'Battery is dying'
local warning_msg_position = args.warning_msg_position or 'bottom_right'
local warning_msg_icon = args.warning_msg_icon or WIDGET_DIR .. '/spaceman.jpg'
local enable_battery_warning = args.enable_battery_warning
if enable_battery_warning == nil then
enable_battery_warning = true
end
local text = wibox.widget {
font = font,
align = 'center',
valign = 'center',
widget = wibox.widget.textbox
}
local text_with_background = wibox.container.background(text)
batteryarc_widget = wibox.widget {
text_with_background,
max_value = 100,
rounded_edge = true,
thickness = arc_thickness,
start_angle = 4.71238898, -- 2pi*3/4
forced_height = size,
forced_width = size,
bg = bg_color,
paddings = 2,
widget = wibox.container.arcchart
}
local last_battery_check = os.time()
--[[ Show warning notification ]]
local function show_battery_warning()
naughty.notify {
icon = warning_msg_icon,
icon_size = 100,
text = warning_msg_text,
title = warning_msg_title,
timeout = 25, -- show the warning for a longer time
hover_timeout = 0.5,
position = warning_msg_position,
bg = "#F06060",
fg = "#EEE9EF",
width = 300,
}
end
local function update_widget(widget, stdout)
local charge = 0
local status
for s in stdout:gmatch("[^\r\n]+") do
local cur_status, charge_str, _ = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?(.*)')
if cur_status ~= nil and charge_str ~=nil then
local cur_charge = tonumber(charge_str)
if cur_charge > charge then
status = cur_status
charge = cur_charge
end
end
end
widget.value = charge
if status == 'Charging' then
text_with_background.bg = charging_color
text_with_background.fg = '#000000'
else
text_with_background.bg = '#00000000'
text_with_background.fg = main_color
end
if show_current_level == true then
--- if battery is fully charged (100) there is not enough place for three digits, so we don't show any text
text.text = charge == 100
and ''
or string.format('%d', charge)
else
text.text = ''
end
if charge < 15 then
widget.colors = { low_level_color }
if enable_battery_warning and status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then
-- if 5 minutes have elapsed since the last warning
last_battery_check = os.time()
show_battery_warning()
end
elseif charge > 15 and charge < 40 then
widget.colors = { medium_level_color }
else
widget.colors = { main_color }
end
end
watch("acpi", timeout, update_widget, batteryarc_widget)
-- Popup with battery info
local notification
local function show_battery_status()
awful.spawn.easy_async([[bash -c 'acpi']],
function(stdout, _, _, _)
naughty.destroy(notification)
notification = naughty.notify {
text = stdout,
title = "Battery status",
timeout = 5,
width = 200,
}
end)
end
if show_notification_mode == 'on_hover' then
batteryarc_widget:connect_signal("mouse::enter", function() show_battery_status() end)
batteryarc_widget:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
elseif show_notification_mode == 'on_click' then
batteryarc_widget:connect_signal('button::press', function(_, _, _, button)
if (button == 1) then show_battery_status() end
end)
end
return batteryarc_widget
end
return setmetatable(batteryarc_widget, { __call = function(_, ...)
return worker(...)
end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,69 +0,0 @@
# Bitbucket widget
The widget shows the number of pull requests assigned to the user and when clicked shows them in the list with some additional information. When item in the list is clicked - it opens the pull request in the browser.
## How it works
Widget uses cURL to query Bitbucket's [REST API](https://developer.atlassian.com/bitbucket/api/2/reference/). In order to be authenticated, widget uses a [netrc](https://ec.haxx.se/usingcurl/usingcurl-netrc) feature of the cURL, which is basically allows storing basic auth credentials in a **.netrc** file in home folder.
Bitbucket allows using [App Passwords](https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html) (available in the account settings) - simply generate one for the widget and use it as password in **.netrc** file.
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `icon` | `~/.config/awesome/awesome-wm-widgets/bitbucket-widget/bitbucket-icon-gradient-blue.svg` | Path to the icon |
| `host` | Required | e.g _http://api.bitbucket.org_ |
| `uuid` | Required | e.g _{123e4567-e89b-12d3-a456-426614174000}_ |
| `workspace` | Required | Workspace ID|
| `repo_slug` | Required | Repository slug |
| `timeout` | 60 | How often in seconds the widget refreshes |
Note:
- host most likely should start with _api._
- to get your UUID you may call `curl -s -n 'https://api.bitbucket.org/2.0/user'`
## Installation
Create a **.netrc** file in you home directory with following content:
```bash
machine api.bitbucket.org
login mikey@tmnt.com
password cowabunga
```
Then change file's permissions to 600 (so only you can read/write it):
```bash
chmod 600 ~/.netrc
```
And test if it works by calling the API:
```bash
curl -s -n 'https://api.bitbucket.org/2.0/repositories/'
```
Also, to properly setup required parameters you can use `test_bitbucket_api.sh` script - it uses the same curl call as widget.
Then clone/download repo and use widget in **rc.lua**:
```lua
local bitbucket_widget = require("awesome-wm-widgets.bitbucket-widget.bitbucket")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
-- default
bitbucket_widget({
host = 'https://api.bitbucket.org',
uuid = '{123e4567-e89b-12d3-a456-426614174000}',
workspace = 'workspace',
repo_slug = 'slug'
}}),
...
```

View File

@ -1 +0,0 @@
<svg id="Logos" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="80" height="80" viewBox="0 0 80 80"><defs><style>.cls-1{fill:none;}.cls-2{fill:#2684ff;}.cls-3{fill:url(#New_Gradient_Swatch_1);}</style><linearGradient id="New_Gradient_Swatch_1" x1="71.61" y1="36.15" x2="41.78" y2="59.43" gradientUnits="userSpaceOnUse"><stop offset="0.18" stop-color="#0052cc"/><stop offset="1" stop-color="#2684ff"/></linearGradient></defs><title>bitbucket-icon-gradient-blue</title><polygon class="cls-1" points="33.81 48.88 46.36 48.88 49.39 31.2 30.47 31.2 33.81 48.88"/><path class="cls-2" d="M12,13.06a1.92,1.92,0,0,0-1.9,2.23l8.14,49.56A2.62,2.62,0,0,0,20.78,67H60a1.93,1.93,0,0,0,1.9-1.62L70,15.3a1.92,1.92,0,0,0-1.9-2.23ZM46.36,48.88H33.81L30.47,31.2H49.39Z"/><path class="cls-3" d="M67.44,31.2h-18l-3,17.68H33.81L19.1,66.4a2.61,2.61,0,0,0,1.68.63H60a1.93,1.93,0,0,0,1.9-1.62Z"/></svg>

Before

Width:  |  Height:  |  Size: 914 B

View File

@ -1,371 +0,0 @@
-------------------------------------------------
-- Bitbucket Widget for Awesome Window Manager
-- Shows the number of currently assigned pull requests
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/bitbucket-widget
-- @author Pavel Makhov
-- @copyright 2020 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local json = require("json")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
local gfs = require("gears.filesystem")
local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/bitbucket-widget/'
local GET_PRS_CMD= [[bash -c "curl -s --show-error -n ]]
.. [['%s/2.0/repositories/%s/%s/pullrequests]]
.. [[?fields=values.participants.approved,values.title,values.links.html,values.author.display_name,]]
.. [[values.author.uuid,values.author.links.avatar,values.source.branch,values.destination.branch,]]
.. [[values.comment_count,values.created_on&q=reviewers.uuid+%%3D+%%22%s%%22+AND+state+%%3D+%%22OPEN%%22']]
.. [[ | jq '.[] '"]]
local DOWNLOAD_AVATAR_CMD = [[bash -c "curl -L -n --create-dirs -o %s/.cache/awmw/bitbucket-widget/avatars/%s %s"]]
local bitbucket_widget = wibox.widget {
{
{
id = 'icon',
widget = wibox.widget.imagebox
},
margins = 4,
layout = wibox.container.margin
},
{
id = "txt",
widget = wibox.widget.textbox
},
{
id = "new_pr",
widget = wibox.widget.textbox
},
layout = wibox.layout.fixed.horizontal,
set_text = function(self, new_value)
self.txt.text = new_value
end,
set_icon = function(self, new_value)
self:get_children_by_id('icon')[1]:set_image(new_value)
end
}
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = 'Bitbucket Widget',
text = message}
end
local popup = awful.popup{
ontop = true,
visible = false,
shape = gears.shape.rounded_rect,
border_width = 1,
border_color = beautiful.bg_focus,
maximum_width = 400,
offset = { y = 5 },
widget = {}
}
--- Converts string representation of date (2020-06-02T11:25:27Z) to date
local function parse_date(date_str)
local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)%Z"
local y, m, d, h, min, sec, _ = date_str:match(pattern)
return os.time{year = y, month = m, day = d, hour = h, min = min, sec = sec}
end
--- Converts seconds to "time ago" represenation, like '1 hour ago'
local function to_time_ago(seconds)
local days = seconds / 86400
if days > 1 then
days = math.floor(days + 0.5)
return days .. (days == 1 and ' day' or ' days') .. ' ago'
end
local hours = (seconds % 86400) / 3600
if hours > 1 then
hours = math.floor(hours + 0.5)
return hours .. (hours == 1 and ' hour' or ' hours') .. ' ago'
end
local minutes = ((seconds % 86400) % 3600) / 60
if minutes > 1 then
minutes = math.floor(minutes + 0.5)
return minutes .. (minutes == 1 and ' minute' or ' minutes') .. ' ago'
end
end
local function ellipsize(text, length)
return (text:len() > length and length > 0)
and text:sub(0, length - 3) .. '...'
or text
end
local function count_approves(participants)
local res = 0
for i = 1, #participants do
if participants[i]['approved'] then res = res + 1 end
end
return res
end
local function worker(user_args)
local args = user_args or {}
local icon = args.icon or WIDGET_DIR .. '/bitbucket-icon-gradient-blue.svg'
local host = args.host or show_warning('Bitbucket host is not set')
local uuid = args.uuid or show_warning('UUID is not set')
local workspace = args.workspace or show_warning('Workspace is not set')
local repo_slug = args.repo_slug or show_warning('Repo slug is not set')
local timeout = args.timeout or 60
local current_number_of_prs
local to_review_rows = {layout = wibox.layout.fixed.vertical}
local my_review_rows = {layout = wibox.layout.fixed.vertical}
local rows = {layout = wibox.layout.fixed.vertical}
bitbucket_widget:set_icon(icon)
local update_widget = function(widget, stdout, stderr, _, _)
if stderr ~= '' then
show_warning(stderr)
return
end
local result = json.decode(stdout)
current_number_of_prs = rawlen(result)
if current_number_of_prs == 0 then
widget:set_visible(false)
return
end
widget:set_visible(true)
widget:set_text(current_number_of_prs)
for i = 0, #rows do rows[i]=nil end
for i = 0, #to_review_rows do to_review_rows[i]=nil end
table.insert(to_review_rows, {
{
markup = '<span size="large" color="#ffffff">PRs to review</span>',
align = 'center',
forced_height = 20,
widget = wibox.widget.textbox
},
bg = beautiful.bg_normal,
widget = wibox.container.background
})
for i = 0, #my_review_rows do my_review_rows[i]=nil end
table.insert(my_review_rows, {
{
markup = '<span size="large" color="#ffffff">My PRs</span>',
align = 'center',
forced_height = 20,
widget = wibox.widget.textbox
},
bg = beautiful.bg_normal,
widget = wibox.container.background
})
local current_time = os.time(os.date("!*t"))
for _, pr in ipairs(result) do
local path_to_avatar = os.getenv("HOME") ..'/.cache/awmw/bitbucket-widget/avatars/' .. pr.author.uuid
local number_of_approves = count_approves(pr.participants)
local row = wibox.widget {
{
{
{
{
resize = true,
image = path_to_avatar,
forced_width = 40,
forced_height = 40,
widget = wibox.widget.imagebox
},
id = 'avatar',
margins = 8,
layout = wibox.container.margin
},
{
{
id = 'title',
markup = '<b>' .. ellipsize(pr.title, 50) .. '</b>',
widget = wibox.widget.textbox,
forced_width = 400
},
{
{
{
{
text = ellipsize(pr.source.branch.name, 30),
widget = wibox.widget.textbox
},
{
text = '->',
widget = wibox.widget.textbox
},
{
text = pr.destination.branch.name,
widget = wibox.widget.textbox
},
spacing = 8,
layout = wibox.layout.fixed.horizontal
},
{
{
text = pr.author.display_name,
widget = wibox.widget.textbox
},
{
text = to_time_ago(os.difftime(current_time, parse_date(pr.created_on))),
widget = wibox.widget.textbox
},
spacing = 8,
expand = 'none',
layout = wibox.layout.fixed.horizontal
},
forced_width = 285,
layout = wibox.layout.fixed.vertical
},
{
{
{
image = WIDGET_DIR .. '/check.svg',
resize = false,
widget = wibox.widget.imagebox
},
{
text = number_of_approves,
widget = wibox.widget.textbox
},
layout = wibox.layout.fixed.horizontal
},
{
{
image = WIDGET_DIR .. '/message-circle.svg',
resize = false,
widget = wibox.widget.imagebox
},
{
text = pr.comment_count,
widget = wibox.widget.textbox
},
layout = wibox.layout.fixed.horizontal
},
layout = wibox.layout.fixed.vertical
},
layout = wibox.layout.fixed.horizontal
},
spacing = 8,
layout = wibox.layout.fixed.vertical
},
spacing = 8,
layout = wibox.layout.fixed.horizontal
},
margins = 8,
layout = wibox.container.margin
},
bg = beautiful.bg_normal,
widget = wibox.container.background
}
if not gfs.file_readable(path_to_avatar) then
local cmd = string.format(DOWNLOAD_AVATAR_CMD, HOME_DIR, pr.author.uuid, pr.author.links.avatar.href)
spawn.easy_async(cmd, function() row:get_children_by_id('avatar')[1]:set_image(path_to_avatar) end)
end
row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
row:get_children_by_id('title')[1]:buttons(
awful.util.table.join(
awful.button({}, 1, function()
spawn.with_shell("xdg-open " .. pr.links.html.href)
popup.visible = false
end)
)
)
row:get_children_by_id('avatar')[1]:buttons(
awful.util.table.join(
awful.button({}, 1, function()
spawn.with_shell(
string.format('xdg-open "https://bitbucket.org/%s/%s/pull-requests?state=OPEN&author=%s"',
workspace, repo_slug, pr.author.uuid)
)
popup.visible = false
end)
)
)
local old_cursor, old_wibox
row:get_children_by_id('title')[1]:connect_signal("mouse::enter", function()
local wb = mouse.current_wibox
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
end)
row:get_children_by_id('title')[1]:connect_signal("mouse::leave", function()
if old_wibox then
old_wibox.cursor = old_cursor
old_wibox = nil
end
end)
row:get_children_by_id('avatar')[1]:connect_signal("mouse::enter", function()
local wb = mouse.current_wibox
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
end)
row:get_children_by_id('avatar')[1]:connect_signal("mouse::leave", function()
if old_wibox then
old_wibox.cursor = old_cursor
old_wibox = nil
end
end)
if (pr.author.uuid == '{' .. uuid .. '}') then
table.insert(my_review_rows, row)
else
table.insert(to_review_rows, row)
end
end
table.insert(rows, to_review_rows)
if (#my_review_rows > 1) then
table.insert(rows, my_review_rows)
end
popup:setup(rows)
end
bitbucket_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function()
if popup.visible then
popup.visible = not popup.visible
else
popup:move_next_to(mouse.current_widget_geometry)
end
end)
)
)
watch(string.format(GET_PRS_CMD, host, workspace, repo_slug, uuid, uuid),
timeout, update_widget, bitbucket_widget)
return bitbucket_widget
end
return setmetatable(bitbucket_widget, { __call = function(_, ...) return worker(...) end })

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#A3BE8C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg>

Before

Width:  |  Height:  |  Size: 257 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>

Before

Width:  |  Height:  |  Size: 366 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-copy"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>

Before

Width:  |  Height:  |  Size: 346 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-git-pull-request"><circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M13 6h3a2 2 0 0 1 2 2v7"></path><line x1="6" y1="9" x2="6" y2="21"></line></svg>

Before

Width:  |  Height:  |  Size: 382 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-message-circle"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg>

Before

Width:  |  Height:  |  Size: 423 B

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
HOST='https://api.bitbucket.org'
ACCOUNT_ID=''
WORKSPACE=''
REPO_SLUG=''
curl -s -n "${HOST}/2.0/repositories/${WORKSPACE}/${REPO_SLUG}/pullrequests?fields=values.title,values.links.html,values.author.display_name,values.author.links.avatar&q=reviewers.account_id+%3D+%22${ACCOUNT_ID}%22"

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ECEFF4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>

Before

Width:  |  Height:  |  Size: 308 B

View File

@ -1,93 +0,0 @@
# Brightness widget
This widget represents current brightness level, depending on config parameters could be an arcchart or icon with text: ![Brightness widget](./br-wid-1.png)
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `type`| `arc` | The widget type. Could be `arc` or `icon_and_text` |
| `program` | `light` | The program used to control the brightness, either `light`, `xbacklight`, or `brightnessctl`. |
| `step` | 5 | Step |
| `base` | 20 | Base level to set brightness to on left click. |
| `path_to_icon` | `/usr/share/icons/Arc/status/symbolic/display-brightness-symbolic.svg` | Path to the icon |
| `font` | `Play 9` | Font |
| `timeout` | 1 | How often in seconds the widget refreshes. Check the note below |
| `tooltip` | false | Display brightness level in a tooltip when the mouse cursor hovers the widget |
_Note:_ If brightness is controlled only by the widget (either by a mouse, or by a shortcut, then the `timeout` could be quite big, as there is no reason to synchronize the brightness level).
## Installation
To choose the right `program` argument, first you need to check which of them works better for you.
- using `xbacklight`:
Install (on Ubuntu it's available in the apt repository) it and check if it works by running:
```bash
xbacklight -get
```
If there is no output it means that it doesn't work, you can either try to fix it, or try to use `light`.
- using `light` command:
Install (on Ubuntu it's available in the apt repository) from the repo: [github.com/haikarainen/light](https://github.com/haikarainen/light) and check if it works by running
```bash
light -G
49.18
light -A 5
```
If you're on Ubuntu/debian and if the brightness level doesn't change, try to do this: https://github.com/haikarainen/light/issues/113#issuecomment-632638436.
- using `brightnessctl`:
On Ubuntu it is available in the apt repository. Install and check the ouptut of the following command.
```bash
brightnessctl --list
```
Then clone this repo under **~/.config/awesome/**:
```bash
git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/awesome/awesome-wm-widgets
```
Require widget at the beginning of **rc.lua**:
```lua
local brightness_widget = require("awesome-wm-widgets.brightness-widget.brightness")
```
Add the widget to the tasklist:
```lua
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
-- default
brightness_widget(),
-- or customized
brightness_widget{
type = 'icon_and_text',
program = 'xbacklight',
step = 2,
}
}
...
```
## 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 () brightness_widget:inc() end, {description = "increase brightness", group = "custom"}),
awful.key({ modkey, "Shift"}, ";", function () brightness_widget:dec() end, {description = "decrease brightness", group = "custom"}),
```
On a laptop you can use `XF86MonBrightnessUp` and `XF86MonBrightnessDown` keys.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -1,186 +0,0 @@
-------------------------------------------------
-- 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 2021 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local ICON_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/brightness-widget/'
local get_brightness_cmd
local set_brightness_cmd
local inc_brightness_cmd
local dec_brightness_cmd
local brightness_widget = {}
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = 'Brightness Widget',
text = message}
end
local function worker(user_args)
local args = user_args or {}
local type = args.type or 'arc' -- arc or icon_and_text
local path_to_icon = args.path_to_icon or ICON_DIR .. 'brightness.svg'
local font = args.font or 'Play 9'
local timeout = args.timeout or 100
local program = args.program or 'light'
local step = args.step or 5
local base = args.base or 20
local current_level = 0 -- current brightness value
local tooltip = args.tooltip or false
if program == 'light' then
get_brightness_cmd = 'light -G'
set_brightness_cmd = 'light -S %d' -- <level>
inc_brightness_cmd = 'light -A ' .. step
dec_brightness_cmd = 'light -U ' .. step
elseif program == 'xbacklight' then
get_brightness_cmd = 'xbacklight -get'
set_brightness_cmd = 'xbacklight -set %d' -- <level>
inc_brightness_cmd = 'xbacklight -inc ' .. step
dec_brightness_cmd = 'xbacklight -dec ' .. step
elseif program == 'brightnessctl' then
get_brightness_cmd = 'bash -c "brightnessctl -m | cut -d, -f4 | tr -d %"'
set_brightness_cmd = 'brightnessctl set %d%%' -- <level>
inc_brightness_cmd = 'brightnessctl set +' .. step .. '%'
dec_brightness_cmd = 'brightnessctl set ' .. step .. '-%'
else
show_warning(program .. " command is not supported by the widget")
return
end
if type == 'icon_and_text' then
brightness_widget.widget = wibox.widget {
{
{
image = path_to_icon,
resize = false,
widget = wibox.widget.imagebox,
},
valign = 'center',
layout = wibox.container.place
},
{
id = 'txt',
font = font,
widget = wibox.widget.textbox
},
spacing = 4,
layout = wibox.layout.fixed.horizontal,
set_value = function(self, level)
self:get_children_by_id('txt')[1]:set_text(level .. '%')
end
}
elseif type == 'arc' then
brightness_widget.widget = wibox.widget {
{
{
image = path_to_icon,
resize = true,
widget = wibox.widget.imagebox,
},
valign = 'center',
layout = wibox.container.place
},
max_value = 100,
thickness = 2,
start_angle = 4.71238898, -- 2pi*3/4
forced_height = 18,
forced_width = 18,
paddings = 2,
widget = wibox.container.arcchart,
set_value = function(self, level)
self:set_value(level)
end
}
else
show_warning(type .. " type is not supported by the widget")
return
end
local update_widget = function(widget, stdout, _, _, _)
local brightness_level = tonumber(string.format("%.0f", stdout))
current_level = brightness_level
widget:set_value(brightness_level)
end
function brightness_widget:set(value)
current_level = value
spawn.easy_async(string.format(set_brightness_cmd, value), function()
spawn.easy_async(get_brightness_cmd, function(out)
update_widget(brightness_widget.widget, out)
end)
end)
end
local old_level = 0
function brightness_widget:toggle()
if old_level < 0.1 then
-- avoid toggling between '0' and 'almost 0'
old_level = 1
end
if current_level < 0.1 then
-- restore previous level
current_level = old_level
else
-- save current brightness for later
old_level = current_level
current_level = 0
end
brightness_widget:set(current_level)
end
function brightness_widget:inc()
spawn.easy_async(inc_brightness_cmd, function()
spawn.easy_async(get_brightness_cmd, function(out)
update_widget(brightness_widget.widget, out)
end)
end)
end
function brightness_widget:dec()
spawn.easy_async(dec_brightness_cmd, function()
spawn.easy_async(get_brightness_cmd, function(out)
update_widget(brightness_widget.widget, out)
end)
end)
end
brightness_widget.widget:buttons(
awful.util.table.join(
awful.button({}, 1, function() brightness_widget:set(base) end),
awful.button({}, 3, function() brightness_widget:toggle() end),
awful.button({}, 4, function() brightness_widget:inc() end),
awful.button({}, 5, function() brightness_widget:dec() end)
)
)
watch(get_brightness_cmd, timeout, update_widget, brightness_widget.widget)
if tooltip then
awful.tooltip {
objects = { brightness_widget.widget },
timer_function = function()
return current_level .. " %"
end,
}
end
return brightness_widget.widget
end
return setmetatable(brightness_widget, { __call = function(_, ...)
return worker(...)
end })

View File

@ -1,153 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
height="16"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.91 r13725"
version="1.0"
sodipodi:docname="display-brightness-symbolic.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
style="display:inline">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#e7e7e7"
borderopacity="1"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="44.218752"
inkscape:cx="12.155025"
inkscape:cy="7.6228779"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:showpageshadow="false"
showguides="false"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1029"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:snap-global="true">
<sodipodi:guide
orientation="1,0"
position="0,112"
id="guide2383" />
<sodipodi:guide
orientation="0,1"
position="26.278146,128"
id="guide2385" />
<sodipodi:guide
orientation="1,0"
position="128,54.082119"
id="guide2387" />
<sodipodi:guide
orientation="0,1"
position="78.156291,0"
id="guide2389" />
<sodipodi:guide
orientation="0,1"
position="60.863576,64.084768"
id="guide2391" />
<inkscape:grid
type="xygrid"
id="grid3672"
visible="true"
enabled="true"
empspacing="8"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Icon"
inkscape:groupmode="layer"
id="layer1"
style="display:inline"
transform="translate(0,-6)">
<path
style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m -12,6 -1,3 2,0 -1,-3 z m -5.65625,2.34375 1.40625,2.8125 1.40625,-1.40625 -2.8125,-1.40625 z m 11.3125,0 L -9.15625,9.75 -7.75,11.15625 -6.34375,8.34375 z M -12,10 c -2.209139,0 -4,1.790861 -4,4 0,2.209139 1.790861,4 4,4 2.209139,0 4,-1.790861 4,-4 0,-2.209139 -1.790861,-4 -4,-4 z m 0,1.5 c 1.380712,0 2.5,1.119288 2.5,2.5 0,1.380712 -1.119288,2.5 -2.5,2.5 -1.380712,0 -2.5,-1.119288 -2.5,-2.5 0,-1.380712 1.119288,-2.5 2.5,-2.5 z m -5,1.5 -3,1 3,1 0,-2 z m 10,0 0,2 3,-1 -3,-1 z m -9.25,3.84375 -1.40625,2.8125 2.8125,-1.40625 -1.40625,-1.40625 z m 8.5,0 -1.40625,1.40625 2.8125,1.40625 L -7.75,16.84375 z M -13,19 l 1,3 1,-3 -2,0 z"
id="path3085"
inkscape:connector-curvature="0" />
<path
id="path3102"
d="m 8,30 c -2.209139,0 -4,1.790861 -4,4 0,2.209139 1.790861,4 4,4 2.209139,0 4,-1.790861 4,-4 0,-2.209139 -1.790861,-4 -4,-4 z m 0,2 c 1.1045695,0 2,0.89543 2,2 0,1.104569 -0.8954305,2 -2,2 -1.1045695,0 -2,-0.895431 -2,-2 0,-1.10457 0.8954305,-2 2,-2 z"
style="opacity:0.35;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
inkscape:transform-center-y="-6.5"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3104"
d="m 6,29 4,0 -2,-3 z"
style="fill:#808080;stroke:none" />
<path
inkscape:transform-center-y="-2.4999999"
inkscape:transform-center-x="-5.1291655"
style="fill:#808080;stroke:none"
d="m 11.330127,29.767949 2,3.464102 L 14.928204,30 z"
id="path3106"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3108"
d="m 13.330127,34.767949 -2,3.464102 L 14.928203,38 z"
style="fill:#808080;stroke:none"
inkscape:transform-center-x="-5.129165"
inkscape:transform-center-y="2.5" />
<path
inkscape:transform-center-y="6.5"
style="fill:#808080;stroke:none"
d="m 10,39 -4.0000002,0 2.0000001,3 z"
id="path3110"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
inkscape:transform-center-x="5.1291651"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3112"
d="M 4.6698729,38.232051 2.6698728,34.767949 1.0717967,38 z"
style="fill:#808080;stroke:none"
inkscape:transform-center-y="2.5" />
<path
inkscape:transform-center-y="-2.5"
style="fill:#808080;stroke:none"
d="M 2.6698727,33.232051 4.669873,29.767949 1.0717967,30 z"
id="path3114"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:transform-center-x="5.129165" />
<path
style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 5.84375 0 L 5.09375 2.96875 L 2.15625 2.15625 L 2.96875 5.09375 L 0 5.84375 L 2.1875 8 L 0 10.15625 L 2.96875 10.90625 L 2.15625 13.84375 L 5.09375 13.03125 L 5.84375 16 L 8 13.8125 L 10.15625 16 L 10.90625 13.03125 L 13.84375 13.84375 L 13.03125 10.90625 L 16 10.15625 L 13.8125 8 L 16 5.84375 L 13.03125 5.09375 L 13.84375 2.15625 L 10.90625 2.96875 L 10.15625 0 L 8 2.1875 L 5.84375 0 z M 8 3 C 10.761424 3 13 5.2385763 13 8 C 13 10.761424 10.761424 13 8 13 L 8 3 z "
transform="translate(0,6)"
id="path3075" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -1,89 +0,0 @@
# Calendar Widget
Calendar widget for Awesome WM - slightly improved version of the `wibox.widget.calendar`.
## Features
### Customization
| Name | Default | Description |
|---|---|---|
| theme | `naughty` | The theme to use |
| placement | `top` | The position of the popup |
| radius | 8 | The popup radius |
| start_sunday | false | Start the week on Sunday |
- themes:
| Name | Screenshot |
|---|---|
| nord | ![nord_theme](./nord.png) |
| outrun | ![outrun_theme](./outrun.png) |
| light | ![outrun_theme](./light.png) |
| dark | ![outrun_theme](./dark.png) |
| naughty (default) | from local theme |
- setup widget placement
top center - in case you clock is centered:
![calendar_top](./calendar_top.png)
top right - for default awesome config:
![calendar_top_right](./calendar_top_right.png)
bottom right - in case your wibar at the bottom:
![calendar_bottom_right](./calendar_bottom_right.png)
- setup first day of week
By setting `start_sunday` to true:
![calendar_start_sunday](./calendar_start_sunday.png)
- mouse support:
move to the next and previous month. Using mouse buttons or scroll wheel.
You can configure this by specifying the button to move to next/previous.
Usually these are configured as follows. If you want to use other mouse buttons, you can find their number using `xev`.
| number | button |
|--------|---------------|
| 4 | scroll up |
| 5 | scroll down |
| 1 | left click |
| 2 | right click |
| 3 | middles click |
By default `previous_month_button` is 5, `next_month_button` is 4.
## How to use
This widget needs an 'anchor' - another widget which triggers visibility of the calendar. Default `mytextclock` is the perfect candidate!
Just after mytextclock is instantiated, create the widget and add the mouse listener to it.
```lua
local calendar_widget = require("awesome-wm-widgets.calendar-widget.calendar")
-- ...
-- Create a textclock widget
mytextclock = wibox.widget.textclock()
-- default
local cw = calendar_widget()
-- or customized
local cw = calendar_widget({
theme = 'outrun',
placement = 'bottom_right',
start_sunday = true,
radius = 8,
-- with customized next/previous (see table above)
previous_month_button = 1,
next_month_button = 3,
})
mytextclock:connect_signal("button::press",
function(_, _, _, button)
if button == 1 then cw.toggle() end
end)
```

View File

@ -1,253 +0,0 @@
-------------------------------------------------
-- Calendar Widget for Awesome Window Manager
-- Shows the current month and supports scroll up/down to switch month
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/calendar-widget
-- @author Pavel Makhov
-- @copyright 2019 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local beautiful = require("beautiful")
local wibox = require("wibox")
local gears = require("gears")
local naughty = require("naughty")
local calendar_widget = {}
local function worker(user_args)
local calendar_themes = {
nord = {
bg = '#2E3440',
fg = '#D8DEE9',
focus_date_bg = '#88C0D0',
focus_date_fg = '#000000',
weekend_day_bg = '#3B4252',
weekday_fg = '#88C0D0',
header_fg = '#E5E9F0',
border = '#4C566A'
},
outrun = {
bg = '#0d0221',
fg = '#D8DEE9',
focus_date_bg = '#650d89',
focus_date_fg = '#2de6e2',
weekend_day_bg = '#261447',
weekday_fg = '#2de6e2',
header_fg = '#f6019d',
border = '#261447'
},
dark = {
bg = '#000000',
fg = '#ffffff',
focus_date_bg = '#ffffff',
focus_date_fg = '#000000',
weekend_day_bg = '#444444',
weekday_fg = '#ffffff',
header_fg = '#ffffff',
border = '#333333'
},
light = {
bg = '#ffffff',
fg = '#000000',
focus_date_bg = '#000000',
focus_date_fg = '#ffffff',
weekend_day_bg = '#AAAAAA',
weekday_fg = '#000000',
header_fg = '#000000',
border = '#CCCCCC'
},
monokai = {
bg = '#272822',
fg = '#F8F8F2',
focus_date_bg = '#AE81FF',
focus_date_fg = '#ffffff',
weekend_day_bg = '#75715E',
weekday_fg = '#FD971F',
header_fg = '#F92672',
border = '#75715E'
},
naughty = {
bg = beautiful.notification_bg or beautiful.bg,
fg = beautiful.notification_fg or beautiful.fg,
focus_date_bg = beautiful.notification_fg or beautiful.fg,
focus_date_fg = beautiful.notification_bg or beautiful.bg,
weekend_day_bg = beautiful.bg_focus,
weekday_fg = beautiful.fg,
header_fg = beautiful.fg,
border = beautiful.border_normal
}
}
local args = user_args or {}
if args.theme ~= nil and calendar_themes[args.theme] == nil then
naughty.notify({
preset = naughty.config.presets.critical,
title = 'Calendar Widget',
text = 'Theme "' .. args.theme .. '" not found, fallback to default'})
args.theme = 'naughty'
end
local theme = args.theme or 'naughty'
local placement = args.placement or 'top'
local radius = args.radius or 8
local next_month_button = args.next_month_button or 4
local previous_month_button = args.previous_month_button or 5
local start_sunday = args.start_sunday or false
local styles = {}
local function rounded_shape(size)
return function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, size)
end
end
styles.month = {
padding = 4,
bg_color = calendar_themes[theme].bg,
border_width = 0,
}
styles.normal = {
markup = function(t) return t end,
shape = rounded_shape(4)
}
styles.focus = {
fg_color = calendar_themes[theme].focus_date_fg,
bg_color = calendar_themes[theme].focus_date_bg,
markup = function(t) return '<b>' .. t .. '</b>' end,
shape = rounded_shape(4)
}
styles.header = {
fg_color = calendar_themes[theme].header_fg,
bg_color = calendar_themes[theme].bg,
markup = function(t) return '<b>' .. t .. '</b>' end
}
styles.weekday = {
fg_color = calendar_themes[theme].weekday_fg,
bg_color = calendar_themes[theme].bg,
markup = function(t) return '<b>' .. t .. '</b>' end,
}
local function decorate_cell(widget, flag, date)
if flag == 'monthheader' and not styles.monthheader then
flag = 'header'
end
-- highlight only today's day
if flag == 'focus' then
local today = os.date('*t')
if not (today.month == date.month and today.year == date.year) then
flag = 'normal'
end
end
local props = styles[flag] or {}
if props.markup and widget.get_text and widget.set_markup then
widget:set_markup(props.markup(widget:get_text()))
end
-- Change bg color for weekends
local d = { year = date.year, month = (date.month or 1), day = (date.day or 1) }
local weekday = tonumber(os.date('%w', os.time(d)))
local default_bg = (weekday == 0 or weekday == 6)
and calendar_themes[theme].weekend_day_bg
or calendar_themes[theme].bg
local ret = wibox.widget {
{
{
widget,
halign = 'center',
widget = wibox.container.place
},
margins = (props.padding or 2) + (props.border_width or 0),
widget = wibox.container.margin
},
shape = props.shape,
shape_border_color = props.border_color or '#000000',
shape_border_width = props.border_width or 0,
fg = props.fg_color or calendar_themes[theme].fg,
bg = props.bg_color or default_bg,
widget = wibox.container.background
}
return ret
end
local cal = wibox.widget {
date = os.date('*t'),
font = beautiful.get_font(),
fn_embed = decorate_cell,
long_weekdays = true,
start_sunday = start_sunday,
widget = wibox.widget.calendar.month
}
local popup = awful.popup {
ontop = true,
visible = false,
shape = rounded_shape(radius),
offset = { y = 5 },
border_width = 1,
border_color = calendar_themes[theme].border,
widget = cal
}
popup:buttons(
awful.util.table.join(
awful.button({}, next_month_button, function()
local a = cal:get_date()
a.month = a.month + 1
cal:set_date(nil)
cal:set_date(a)
popup:set_widget(cal)
end),
awful.button({}, previous_month_button, function()
local a = cal:get_date()
a.month = a.month - 1
cal:set_date(nil)
cal:set_date(a)
popup:set_widget(cal)
end)
)
)
function calendar_widget.toggle()
if popup.visible then
-- to faster render the calendar refresh it and just hide
cal:set_date(nil) -- the new date is not set without removing the old one
cal:set_date(os.date('*t'))
popup:set_widget(nil) -- just in case
popup:set_widget(cal)
popup.visible = not popup.visible
else
if placement == 'top' then
awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() })
elseif placement == 'top_right' then
awful.placement.top_right(popup, { margins = { top = 30, right = 10}, parent = awful.screen.focused() })
elseif placement == 'bottom_right' then
awful.placement.bottom_right(popup, { margins = { bottom = 30, right = 10},
parent = awful.screen.focused() })
else
awful.placement.top(popup, { margins = { top = 30 }, parent = awful.screen.focused() })
end
popup.visible = true
end
end
return calendar_widget
end
return setmetatable(calendar_widget, { __call = function(_, ...)
return worker(...)
end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -1,51 +0,0 @@
# Cmus widget
Cmus widget that shows the current playing track.
![widget](./screenshots/cmus-widget.png)
Left click toggles playback.
## Installation
Clone the repo under **~/.config/awesome/** and add widget in **rc.lua**:
```lua
local cmus_widget = require('awesome-wm-widgets.cmus-widget.cmus')
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
-- default
cmus_widget(),
-- customized
cmus_widget{
space = 5,
timeout = 5
},
```
### Shortcuts
To improve responsiveness of the widget when playback is changed by a shortcut use corresponding methods of the widget:
```lua
awful.key({ modkey, "Shift" },
"p",
function() cmus_widget:play_pause() end,
{description = "play/pause cmus", group = "custom"}),
```
## Customization
It is possible to customize the widget by providing a table with all or some of the following config parameters:
### Generic parameter
| Name | Default | Description |
|---|---|---|
| `font` | `Play 9` | Font used for the track title |
| `path_to_icons` | `/usr/share/icons/Arc/actions/symbolic/` | Alternative path for the icons |
| `timeout`| `10` | Refresh cooldown |
| `space` | `3` | Space between icon and track title |

View File

@ -1,127 +0,0 @@
-------------------------------------------------
-- Cmus Widget for Awesome Window Manager
-- Show what's playing, play/pause, etc
-- @author Augusto Gunsch
-- @copyright 2022 Augusto Gunsch
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local cmus_widget = {}
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = "Cmus Widget",
text = message}
end
local function worker(user_args)
local args = user_args or {}
local font = args.font or "Play 9"
local path_to_icons = args.path_to_icons or "/usr/share/icons/Arc/actions/symbolic/"
local timeout = args.timeout or 10
local space = args.space or 3
cmus_widget.widget = wibox.widget {
{
{
id = "playback_icon",
resize = false,
widget = wibox.widget.imagebox,
},
layout = wibox.container.place
},
{
id = "text",
font = font,
widget = wibox.widget.textbox
},
layout = wibox.layout.fixed.horizontal,
update_icon = function(self, name)
self:get_children_by_id("playback_icon")[1]:set_image(path_to_icons .. name)
end,
set_title = function(self, title)
self:get_children_by_id("text")[1]:set_text(title)
end
}
function update_widget(widget, stdout, _, _, code)
if code == 0 then
local cmus_info = {}
for s in stdout:gmatch("[^\r\n]+") do
local key, val = string.match(s, "^tag (%a+) (.+)$")
if key and val then
cmus_info[key] = val
else
local key, val = string.match(s, "^set (%a+) (.+)$")
if key and val then
cmus_info[key] = val
else
local key, val = string.match(s, "^(%a+) (.+)$")
if key and val then
cmus_info[key] = val
end
end
end
end
local title = cmus_info.title
if not title and cmus_info.file then
title = cmus_info.file:gsub("%..-$", "")
title = title:gsub("^.+/", "")
end
if title then
if cmus_info["status"] == "playing" then
widget:update_icon("media-playback-start-symbolic.svg")
elseif cmus_info["status"] == "paused" then
widget:update_icon("media-playback-pause-symbolic.svg")
else
widget:update_icon("media-playback-stop-symbolic.svg")
end
widget:set_title(title)
widget.visible = true
else
widget.visible = false
widget.width = 0
end
else
widget.visible = false
end
end
function cmus_widget:play_pause()
spawn("cmus-remote -u")
spawn.easy_async("cmus-remote -Q",
function(stdout, _, _, code)
update_widget(cmus_widget.widget, stdout, _, _, code)
end)
end
cmus_widget.widget:buttons(
awful.util.table.join(
awful.button({}, 1, function() cmus_widget:play_pause() end)
)
)
watch("cmus-remote -Q", timeout, update_widget, cmus_widget.widget)
return cmus_widget.widget
end
return setmetatable(cmus_widget, { __call = function(_, ...)
return worker(...)
end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -1,71 +0,0 @@
# CPU widget
[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/cpu)](https://github.com/streetturtle/awesome-wm-widgets/labels/cpu)
This widget shows the average CPU load among all cores of the machine:
![screenshot](./cpu.gif)
## 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.
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `width` | 50 | Width of the widget |
| `step_width` | 2 | Width of the step |
| `step_spacing` | 1 | Space size between steps |
| `color` | `beautiful.fg_normal` | Color of the graph |
| `enable_kill_button` | `false` | Show button which kills the process |
| `process_info_max_length` | `-1` | Truncate the process information. Some processes may have a very long list of parameters which won't fit in the screen, this options allows to truncate it to the given length. |
| `timeout` | 1 | How often in seconds the widget refreshes |
### Example
```lua
cpu_widget({
width = 70,
step_width = 2,
step_spacing = 0,
color = '#434c5e'
})
```
The config above results in the following widget:
![custom](./custom.png)
## Installation
Clone/download repo and use widget in **rc.lua**:
```lua
local cpu_widget = require("awesome-wm-widgets.cpu-widget.cpu-widget")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
-- default
cpu_widget(),
-- or custom
cpu_widget({
width = 70,
step_width = 2,
step_spacing = 0,
color = '#434c5e'
})
...
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

View File

@ -1,339 +0,0 @@
-------------------------------------------------
-- 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 2020 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local beautiful = require("beautiful")
local gears = require("gears")
local CMD = [[sh -c "grep '^cpu.' /proc/stat; ps -eo '%p|%c|%C|' -o "%mem" -o '|%a' --sort=-%cpu ]]
.. [[| head -11 | tail -n +2"]]
-- A smaller command, less resource intensive, used when popup is not shown.
local CMD_slim = [[grep --max-count=1 '^cpu.' /proc/stat]]
local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/cpu-widget'
local cpu_widget = {}
local cpu_rows = {
spacing = 4,
layout = wibox.layout.fixed.vertical,
}
local is_update = true
local process_rows = {
layout = wibox.layout.fixed.vertical,
}
-- Splits the string by separator
-- @return table with separated substrings
local function split(string_to_split, separator)
if separator == nil then separator = "%s" end
local t = {}
for str in string.gmatch(string_to_split, "([^".. separator .."]+)") do
table.insert(t, str)
end
return t
end
-- Checks if a string starts with a another string
local function starts_with(str, start)
return str:sub(1, #start) == start
end
local function create_textbox(args)
return wibox.widget{
text = args.text,
align = args.align or 'left',
markup = args.markup,
forced_width = args.forced_width or 40,
widget = wibox.widget.textbox
}
end
local function create_process_header(params)
local res = wibox.widget{
create_textbox{markup = '<b>PID</b>'},
create_textbox{markup = '<b>Name</b>'},
{
create_textbox{markup = '<b>%CPU</b>'},
create_textbox{markup = '<b>%MEM</b>'},
params.with_action_column and create_textbox{forced_width = 20} or nil,
layout = wibox.layout.align.horizontal
},
layout = wibox.layout.ratio.horizontal
}
res:ajust_ratio(2, 0.2, 0.47, 0.33)
return res
end
local function create_kill_process_button()
return wibox.widget{
{
id = "icon",
image = WIDGET_DIR .. '/window-close-symbolic.svg',
resize = false,
opacity = 0.1,
widget = wibox.widget.imagebox
},
widget = wibox.container.background
}
end
local function worker(user_args)
local args = user_args or {}
local width = args.width or 50
local step_width = args.step_width or 2
local step_spacing = args.step_spacing or 1
local color = args.color or beautiful.fg_normal
local background_color = args.background_color or "#00000000"
local enable_kill_button = args.enable_kill_button or false
local process_info_max_length = args.process_info_max_length or -1
local timeout = args.timeout or 1
local cpugraph_widget = wibox.widget {
max_value = 100,
background_color = background_color,
forced_width = width,
step_width = step_width,
step_spacing = step_spacing,
widget = wibox.widget.graph,
color = "linear:0,0:0,20:0,#FF0000:0.3,#FFFF00:0.6," .. color
}
-- This timer periodically executes the heavy command while the popup is open.
-- It is stopped when the popup is closed and only the slim command is run then.
-- This greatly improves performance while the popup is closed at the small cost
-- of a slightly longer popup opening time.
local popup_timer = gears.timer {
timeout = timeout
}
local popup = awful.popup{
ontop = true,
visible = false,
shape = gears.shape.rounded_rect,
border_width = 1,
border_color = beautiful.bg_normal,
maximum_width = 300,
offset = { y = 5 },
widget = {}
}
-- Do not update process rows when mouse cursor is over the widget
popup:connect_signal("mouse::enter", function() is_update = false end)
popup:connect_signal("mouse::leave", function() is_update = true end)
cpugraph_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function()
if popup.visible then
popup.visible = not popup.visible
-- When the popup is not visible, stop the timer
popup_timer:stop()
else
popup:move_next_to(mouse.current_widget_geometry)
-- Restart the timer, when the popup becomes visible
-- Emit the signal to start the timer directly and not wait the timeout first
popup_timer:start()
popup_timer:emit_signal("timeout")
end
end)
)
)
--- By default graph widget goes from left to right, so we mirror it and push up a bit
cpu_widget = wibox.widget {
{
cpugraph_widget,
reflection = {horizontal = true},
layout = wibox.container.mirror
},
bottom = 2,
color = background_color,
widget = wibox.container.margin
}
-- This part runs constantly, also when the popup is closed.
-- It updates the graph widget in the bar.
local maincpu = {}
watch(CMD_slim, timeout, function(widget, stdout)
local _, user, nice, system, idle, iowait, irq, softirq, steal, _, _ =
stdout:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)')
local total = user + nice + system + idle + iowait + irq + softirq + steal
local diff_idle = idle - tonumber(maincpu['idle_prev'] == nil and 0 or maincpu['idle_prev'])
local diff_total = total - tonumber(maincpu['total_prev'] == nil and 0 or maincpu['total_prev'])
local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10
maincpu['total_prev'] = total
maincpu['idle_prev'] = idle
widget:add_value(diff_usage)
end,
cpugraph_widget
)
-- This part runs whenever the timer is fired.
-- It therefore only runs when the popup is open.
local cpus = {}
popup_timer:connect_signal('timeout', function()
awful.spawn.easy_async(CMD, function(stdout, _, _, _)
local i = 1
local j = 1
for line in stdout:gmatch("[^\r\n]+") do
if starts_with(line, 'cpu') then
if cpus[i] == nil then cpus[i] = {} end
local name, user, nice, system, idle, iowait, irq, softirq, steal, _, _ =
line:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)')
local total = user + nice + system + idle + iowait + irq + softirq + steal
local diff_idle = idle - tonumber(cpus[i]['idle_prev'] == nil and 0 or cpus[i]['idle_prev'])
local diff_total = total - tonumber(cpus[i]['total_prev'] == nil and 0 or cpus[i]['total_prev'])
local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10
cpus[i]['total_prev'] = total
cpus[i]['idle_prev'] = idle
local row = wibox.widget
{
create_textbox{text = name},
create_textbox{text = math.floor(diff_usage) .. '%'},
{
max_value = 100,
value = diff_usage,
forced_height = 20,
forced_width = 150,
paddings = 1,
margins = 4,
border_width = 1,
border_color = beautiful.bg_focus,
background_color = beautiful.bg_normal,
bar_border_width = 1,
bar_border_color = beautiful.bg_focus,
color = "linear:150,0:0,0:0,#D08770:0.3,#BF616A:0.6," .. beautiful.fg_normal,
widget = wibox.widget.progressbar,
},
layout = wibox.layout.ratio.horizontal
}
row:ajust_ratio(2, 0.15, 0.15, 0.7)
cpu_rows[i] = row
i = i + 1
else
if is_update == true then
local columns = split(line, '|')
local pid = columns[1]
local comm = columns[2]
local cpu = columns[3]
local mem = columns[4]
local cmd = columns[5]
local kill_proccess_button = enable_kill_button and create_kill_process_button() or nil
local pid_name_rest = wibox.widget{
create_textbox{text = pid},
create_textbox{text = comm},
{
create_textbox{text = cpu, align = 'center'},
create_textbox{text = mem, align = 'center'},
kill_proccess_button,
layout = wibox.layout.fixed.horizontal
},
layout = wibox.layout.ratio.horizontal
}
pid_name_rest:ajust_ratio(2, 0.2, 0.47, 0.33)
local row = wibox.widget {
{
pid_name_rest,
top = 4,
bottom = 4,
widget = wibox.container.margin
},
widget = wibox.container.background
}
row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
if enable_kill_button then
row:connect_signal("mouse::enter", function() kill_proccess_button.icon.opacity = 1 end)
row:connect_signal("mouse::leave", function() kill_proccess_button.icon.opacity = 0.1 end)
kill_proccess_button:buttons(
awful.util.table.join( awful.button({}, 1, function()
row:set_bg('#ff0000')
awful.spawn.with_shell('kill -9 ' .. pid)
end) ) )
end
awful.tooltip {
objects = { row },
mode = 'outside',
preferred_positions = {'bottom'},
timer_function = function()
local text = cmd
if process_info_max_length > 0 and text:len() > process_info_max_length then
text = text:sub(0, process_info_max_length - 3) .. '...'
end
return text
:gsub('%s%-', '\n\t-') -- put arguments on a new line
:gsub(':/', '\n\t\t:/') -- java classpath uses : to separate jars
end,
}
process_rows[j] = row
j = j + 1
end
end
end
popup:setup {
{
cpu_rows,
{
orientation = 'horizontal',
forced_height = 15,
color = beautiful.bg_focus,
widget = wibox.widget.separator
},
create_process_header{with_action_column = enable_kill_button},
process_rows,
layout = wibox.layout.fixed.vertical,
},
margins = 8,
widget = wibox.container.margin
}
end)
end)
return cpu_widget
end
return setmetatable(cpu_widget, { __call = function(_, ...)
return worker(...)
end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
id="svg7384"
version="1.1"
height="16"
width="16"
inkscape:version="0.48.5 r10040"
sodipodi:docname="window-close-symbolic.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="723"
id="namedview15"
showgrid="true"
inkscape:zoom="14.75"
inkscape:cx="14.600061"
inkscape:cy="10.005214"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="1"
inkscape:current-layer="svg7384">
<inkscape:grid
type="xygrid"
id="grid2992" />
</sodipodi:namedview>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<metadata
id="metadata90">
<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>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs7386" />
<g
transform="translate(-60,-518)"
id="layer9"
style="display:inline" />
<g
transform="translate(-60,-518)"
id="layer10" />
<g
transform="translate(-60,-518)"
id="layer11" />
<g
id="g2996"
transform="matrix(0.75,0,0,0.75,2,2.0546875)">
<g
id="layer12"
transform="translate(-60,-518)">
<g
style="display:inline"
id="layer4-4-1"
transform="translate(19,-242)">
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.78124988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
id="path10839-9"
d="m 45,764 1,0 c 0.01037,-1.2e-4 0.02079,-4.6e-4 0.03125,0 0.254951,0.0112 0.50987,0.12858 0.6875,0.3125 L 49,766.59375 51.3125,764.3125 C 51.578125,764.082 51.759172,764.007 52,764 l 1,0 0,1 c 0,0.28647 -0.03434,0.55065 -0.25,0.75 l -2.28125,2.28125 2.25,2.25 C 52.906938,770.46942 52.999992,770.7347 53,771 l 0,1 -1,0 c -0.265301,-10e-6 -0.530586,-0.0931 -0.71875,-0.28125 L 49,769.4375 46.71875,771.71875 C 46.530586,771.90694 46.26529,772 46,772 l -1,0 0,-1 c -3e-6,-0.26529 0.09306,-0.53058 0.28125,-0.71875 l 2.28125,-2.25 L 45.28125,765.75 C 45.070508,765.55537 44.97809,765.28075 45,765 l 0,-1 z"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
<g
transform="translate(-60,-518)"
id="layer13" />
<g
transform="translate(-60,-518)"
id="layer14" />
<g
transform="translate(-60,-518)"
id="layer15" />
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1,38 +0,0 @@
# Docker Widget
[![GitHub issues by-label](https://img.shields.io/github/issues-raw/streetturtle/awesome-wm-widgets/docker)](https://github.com/streetturtle/awesome-wm-widgets/labels/docker)
![Twitter URL](https://img.shields.io/twitter/url?url=https%3A%2F%2Fgithub.com%2Fstreetturtle%2Fawesome-wm-widgets%2Fedit%2Fmaster%2Fdocker-widget)
The widget allows to manage docker containers, namely start/stop/pause/unpause:
<p align="center">
<img src="https://github.com/streetturtle/awesome-wm-widgets/raw/master/docker-widget/docker.gif"/>
</p>
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `icon` | `./docker-widget/icons/docker.svg` | Path to the icon |
| `number_of_containers` | `-1` | Number of last created containers to show |
## Installation
Clone the repo under **~/.config/awesome/** and add widget in **rc.lua**:
```lua
local docker_widget = require("awesome-wm-widgets.docker-widget.docker")
...
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
-- default
docker_widget(),
-- customized
docker_widget{
number_of_containers = 5
},
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 KiB

View File

@ -1,377 +0,0 @@
-------------------------------------------------
-- Docker Widget for Awesome Window Manager
-- Lists containers and allows to manage them
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/docker-widget
-- @author Pavel Makhov
-- @copyright 2020 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/docker-widget'
local ICONS_DIR = WIDGET_DIR .. '/icons/'
local LIST_CONTAINERS_CMD = [[bash -c "docker container ls -a -s -n %s]]
.. [[ --format '{{.Names}}::{{.ID}}::{{.Image}}::{{.Status}}::{{.Size}}'"]]
--- Utility function to show warning messages
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = 'Docker Widget',
text = message}
end
local popup = awful.popup{
ontop = true,
visible = false,
shape = gears.shape.rounded_rect,
border_width = 1,
border_color = beautiful.bg_focus,
maximum_width = 400,
offset = { y = 5 },
widget = {}
}
local docker_widget = wibox.widget {
{
{
id = 'icon',
widget = wibox.widget.imagebox
},
margins = 4,
layout = wibox.container.margin
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 4)
end,
widget = wibox.container.background,
set_icon = function(self, new_icon)
self:get_children_by_id("icon")[1].image = new_icon
end
}
local parse_container = function(line)
local name, id, image, status, how_long, size = line:match('(.*)::(.*)::(.*)::(%w*) (.*)::(.*)')
local actual_status
if status == 'Up' and how_long:find('Paused') then actual_status = 'Paused'
else actual_status = status end
how_long = how_long:gsub('%s?%(.*%)%s?', '')
local container = {
name = name,
id = id,
image = image,
status = actual_status,
how_long = how_long,
size = size,
is_up = function() return status == 'Up' end,
is_paused = function() return actual_status:find('Paused') end,
is_exited = function() return status == 'Exited' end
}
return container
end
local status_to_icon_name = {
Up = ICONS_DIR .. 'play.svg',
Exited = ICONS_DIR .. 'square.svg',
Paused = ICONS_DIR .. 'pause.svg'
}
local function worker(user_args)
local args = user_args or {}
local icon = args.icon or ICONS_DIR .. 'docker.svg'
local number_of_containers = args.number_of_containers or -1
docker_widget:set_icon(icon)
local rows = {
{ widget = wibox.widget.textbox },
layout = wibox.layout.fixed.vertical,
}
local function rebuild_widget(containers, errors, _, _)
if errors ~= '' then
show_warning(errors)
return
end
for i = 0, #rows do rows[i]=nil end
for line in containers:gmatch("[^\r\n]+") do
local container = parse_container(line)
local status_icon = wibox.widget {
image = status_to_icon_name[container['status']],
resize = false,
widget = wibox.widget.imagebox
}
local start_stop_button
if container.is_up() or container.is_exited() then
start_stop_button = wibox.widget {
{
{
id = 'icon',
image = ICONS_DIR .. (container:is_up() and 'stop-btn.svg' or 'play-btn.svg'),
opacity = 0.4,
resize = false,
widget = wibox.widget.imagebox
},
left = 2,
right = 2,
layout = wibox.container.margin
},
shape = gears.shape.circle,
bg = '#00000000',
widget = wibox.container.background
}
local old_cursor, old_wibox
start_stop_button:connect_signal("mouse::enter", function(c)
c:set_bg('#3B4252')
local wb = mouse.current_wibox
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
c:get_children_by_id("icon")[1]:set_opacity(1)
c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed') end)
start_stop_button:connect_signal("mouse::leave", function(c)
c:set_bg('#00000000')
if old_wibox then
old_wibox.cursor = old_cursor
old_wibox = nil
end
c:get_children_by_id("icon")[1]:set_opacity(0.4)
c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
end)
start_stop_button:buttons(
gears.table.join( awful.button({}, 1, function()
local command
if container:is_up() then command = 'stop' else command = 'start' end
status_icon:set_opacity(0.2)
status_icon:emit_signal('widget::redraw_needed')
spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function()
if errors ~= '' then show_warning(errors) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
function(stdout, stderr)
rebuild_widget(stdout, stderr)
end)
end)
end) ) )
else
start_stop_button = nil
end
local pause_unpause_button
if container.is_up() then
pause_unpause_button = wibox.widget {
{
{
id = 'icon',
image = ICONS_DIR .. (container:is_paused() and 'unpause-btn.svg' or 'pause-btn.svg'),
opacity = 0.4,
resize = false,
widget = wibox.widget.imagebox
},
left = 2,
right = 2,
layout = wibox.container.margin
},
shape = gears.shape.circle,
bg = '#00000000',
widget = wibox.container.background
}
local old_cursor, old_wibox
pause_unpause_button:connect_signal("mouse::enter", function(c)
c:set_bg('#3B4252')
local wb = mouse.current_wibox
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
c:get_children_by_id("icon")[1]:set_opacity(1)
c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
end)
pause_unpause_button:connect_signal("mouse::leave", function(c)
c:set_bg('#00000000')
if old_wibox then
old_wibox.cursor = old_cursor
old_wibox = nil
end
c:get_children_by_id("icon")[1]:set_opacity(0.4)
c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
end)
pause_unpause_button:buttons(
gears.table.join( awful.button({}, 1, function()
local command
if container:is_paused() then command = 'unpause' else command = 'pause' end
status_icon:set_opacity(0.2)
status_icon:emit_signal('widget::redraw_needed')
awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(_, stderr)
if stderr ~= '' then show_warning(stderr) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
function(stdout, container_errors)
rebuild_widget(stdout, container_errors)
end)
end)
end) ) )
else
pause_unpause_button = nil
end
local delete_button
if not container.is_up() then
delete_button = wibox.widget {
{
{
id = 'icon',
image = ICONS_DIR .. 'trash-btn.svg',
opacity = 0.4,
resize = false,
widget = wibox.widget.imagebox
},
margins = 4,
layout = wibox.container.margin
},
shape = gears.shape.circle,
bg = '#00000000',
widget = wibox.container.background
}
delete_button:buttons(
gears.table.join( awful.button({}, 1, function()
awful.spawn.easy_async('docker rm ' .. container['name'], function(_, rm_stderr)
if rm_stderr ~= '' then show_warning(rm_stderr) end
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
function(lc_stdout, lc_stderr)
rebuild_widget(lc_stdout, lc_stderr) end)
end)
end)))
local old_cursor, old_wibox
delete_button:connect_signal("mouse::enter", function(c)
c:set_bg('#3B4252')
local wb = mouse.current_wibox
old_cursor, old_wibox = wb.cursor, wb
wb.cursor = "hand1"
c:get_children_by_id("icon")[1]:set_opacity(1)
c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
end)
delete_button:connect_signal("mouse::leave", function(c)
c:set_bg('#00000000')
if old_wibox then
old_wibox.cursor = old_cursor
old_wibox = nil
end
c:get_children_by_id("icon")[1]:set_opacity(0.4)
c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
end)
else
delete_button = nil
end
local row = wibox.widget {
{
{
{
{
status_icon,
margins = 8,
layout = wibox.container.margin
},
valign = 'center',
layout = wibox.container.place
},
{
{
{
markup = '<b>' .. container['name'] .. '</b>',
widget = wibox.widget.textbox
},
{
text = container['size'],
widget = wibox.widget.textbox
},
{
text = container['how_long'],
widget = wibox.widget.textbox
},
forced_width = 180,
layout = wibox.layout.fixed.vertical
},
valign = 'center',
layout = wibox.container.place
},
{
{
start_stop_button,
pause_unpause_button,
delete_button,
layout = wibox.layout.align.horizontal
},
forced_width = 90,
valign = 'center',
haligh = 'center',
layout = wibox.container.place,
},
spacing = 8,
layout = wibox.layout.align.horizontal
},
margins = 8,
layout = wibox.container.margin
},
bg = beautiful.bg_normal,
widget = wibox.container.background
}
row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
table.insert(rows, row)
end
popup:setup(rows)
end
docker_widget:buttons(
gears.table.join(
awful.button({}, 1, function()
if popup.visible then
docker_widget:set_bg('#00000000')
popup.visible = not popup.visible
else
docker_widget:set_bg(beautiful.bg_focus)
spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
function(stdout, stderr)
rebuild_widget(stdout, stderr)
popup:move_next_to(mouse.current_widget_geometry)
end)
end
end)
)
)
return docker_widget
end
return setmetatable(docker_widget, { __call = function(_, ...) return worker(...) end })

View File

@ -1 +0,0 @@
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>Docker icon</title><path fill="#D8DEE9" d="M13.983 11.078h2.119a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.119a.185.185 0 00-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 00.186-.186V3.574a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 00.186-.186V6.29a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 00.184-.186V6.29a.185.185 0 00-.185-.185H8.1a.185.185 0 00-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 00.185-.186V6.29a.185.185 0 00-.185-.185H5.136a.186.186 0 00-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 00.185-.185V9.006a.185.185 0 00-.184-.186h-2.12a.186.186 0 00-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51-.338.001-.676.03-1.01.087-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199-.226.327c-.284.438-.49.922-.612 1.43-.23.97-.09 1.882.403 2.661-.595.332-1.55.413-1.744.42H.751a.751.751 0 00-.75.748 11.376 11.376 0 00.692 4.062c.545 1.428 1.355 2.48 2.41 3.124 1.18.723 3.1 1.137 5.275 1.137.983.003 1.963-.086 2.93-.266a12.248 12.248 0 003.823-1.389c.98-.567 1.86-1.288 2.61-2.136 1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009.309-.293.55-.65.707-1.046l.098-.288Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,10 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M11 7H8V17H11V7Z" fill="#D8DEE9" />
<path d="M13 17H16V7H13V17Z" fill="#D8DEE9" />
</svg>

Before

Width:  |  Height:  |  Size: 209 B

View File

@ -1,16 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M9 9H11V15H9V9Z" fill="#EBCB8B" />
<path d="M15 15H13V9H15V15Z" fill="#EBCB8B" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z"
fill="#EBCB8B"
/>
</svg>

Before

Width:  |  Height:  |  Size: 523 B

View File

@ -1,9 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M9 17L17 12L9 7V17Z" fill="#D8DEE9" />
</svg>

Before

Width:  |  Height:  |  Size: 163 B

View File

@ -1,9 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M15 12.3301L9 16.6603L9 8L15 12.3301Z" fill="#D8DEE9" />
</svg>

Before

Width:  |  Height:  |  Size: 181 B

View File

@ -1,15 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23Z"
fill="#A3BE8C"
/>
<path d="M16 12L10 16.3301V7.66987L16 12Z" fill="#A3BE8C" />
</svg>

Before

Width:  |  Height:  |  Size: 491 B

View File

@ -1,15 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M15 9H9V15H15V9Z" fill="#BF616A" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z"
fill="#BF616A"
/>
</svg>

Before

Width:  |  Height:  |  Size: 475 B

View File

@ -1,10 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7 7H17V17H7V7Z" fill="#D8DEE9" />
</svg>

Before

Width:  |  Height:  |  Size: 161 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#BF616A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-trash-2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>

Before

Width:  |  Height:  |  Size: 443 B

View File

@ -1,10 +0,0 @@
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M6 17L14 12L6 7V17Z" fill="#D8DEE9" />
<path d="M18 7H15V12V17H18V7Z" fill="#D8DEE9" />
</svg>

Before

Width:  |  Height:  |  Size: 214 B

View File

@ -1,36 +0,0 @@
# 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** change 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
local email_widget, email_icon = 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

@ -1,16 +0,0 @@
#!/usr/bin/python
import imaplib
import re
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 = re.search(r'UNSEEN\s(\d+)', counts[0].decode('utf-8')).group(1)
else:
unread = "N/A"
print(unread)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1,44 +0,0 @@
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/"
local email_widget = wibox.widget.textbox()
email_widget:set_font('Play 9')
local 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(_, stdout)
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
)
local function show_emails()
awful.spawn.easy_async([[bash -c 'python /home/<username>/.config/awesome/email-widget/read_unread_emails.py']],
function(stdout)
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)
return email_widget, email_icon

View File

@ -1,44 +0,0 @@
#!/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_bytes(data[0][1])
for header in [ 'From', 'Subject', 'Date' ]:
hdr = email.header.make_header(email.header.decode_header(msg[header]))
if header == 'Date':
date_tuple = email.utils.parsedate_tz(str(hdr))
if date_tuple:
local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
print("{}: {}".format(header, local_date.strftime("%a, %d %b %Y %H:%M:%S")))
else:
print('{}: {}'.format(header, hdr))
# 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

@ -1,5 +0,0 @@
# Spotify Player
In progress
![spotify-player](./spotify-player.png)

View File

@ -1,8 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#dfdfdf; } .ColorScheme-Highlight { color:#4285f4; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="m 12,4 c -4.4182999,0 -7.9999999,3.5816996 -7.9999999,8 0,4.4183 3.5817,8 7.9999999,8 4.4183,0 8,-3.5817 8,-8 0,-4.4183004 -3.5817,-8 -8,-8 z m -1.484375,4.001953 c 0.135577,-0.0025 0.273043,-0.00125 0.40625,0 3.196934,0.043793 5.685547,1.3710939 5.685547,1.3710939 0.32387,0.1720431 0.478757,0.6868991 0.34375,1.0996091 -0.135016,0.41271 -0.551129,0.642746 -0.875,0.470703 0,0 -4.055029,-2.1406733 -8.1835939,-0.824218 -0.347652,0.145366 -0.785915,-0.135667 -0.875,-0.587891 -0.08907,-0.452224 0.170933,-0.9774967 0.53125,-1.0585939 1.017797,-0.3245495 2.017773,-0.4508522 2.9667969,-0.4707031 z m 0.435547,3 c 0.112731,-10e-4 0.212326,-0.0042 0.322266,0 2.638513,0.09188 4.466796,1.550781 4.466796,1.550781 0.234052,0.185402 0.328171,0.661373 0.207032,1.019532 -0.121139,0.358115 -0.441752,0.53892 -0.675782,0.353515 0,0 -2.907877,-2.344468 -6.6425779,-0.974609 -0.262497,0.124051 -0.553359,-0.122359 -0.617187,-0.53125 -0.06386,-0.40893 0.141317,-0.858788 0.412109,-0.929688 0.897365,-0.329138 1.7382149,-0.481181 2.5273439,-0.488281 z M 11.265625,14 c 1.291618,0.02495 2.442203,0.50401 3.542969,1.154297 0.164454,0.107427 0.243604,0.411344 0.152344,0.628906 -0.09126,0.217545 -0.337279,0.284734 -0.486329,0.140625 0,0 -2.036051,-1.658526 -5.0566399,-0.734375 -0.17338,0.07498 -0.372018,-0.06945 -0.41211,-0.314453 -0.04008,-0.245057 0.10336,-0.525057 0.283204,-0.560547 C 9.9993371,14.09714 10.660752,13.996 11.265625,14 Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,192 +0,0 @@
-------------------------------------------------
-- Spotify Player Widget for Awesome Window Manager
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/spotify-player
-- @author Pavel Makhov
-- @copyright 2021 Pavel Makhov
-------------------------------------------------
--luacheck:ignore
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
local gfs = require("gears.filesystem")
local gs = require("gears.string")
local awesomebuttons = require("awesome-buttons.awesome-buttons")
local HOME_DIR = os.getenv("HOME")
local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/experiments/spotify-player/'
local ICON_DIR = WIDGET_DIR
local spotify_player = {}
local function show_warning(message)
naughty.notify{
preset = naughty.config.presets.critical,
title = 'Spotify Player Widget',
text = message}
end
local function worker(user_args)
local args = user_args or {}
local artwork_size = args.artwork_size or 300
local timeout = args.timeout or 1
local popup = awful.popup{
ontop = true,
bg = beautiful.bg_normal .. '88',
visible = false,
shape = gears.shape.rounded_rect,
border_width = 1,
border_color = beautiful.bg_focus,
width = artwork_size,
maximum_width = 300,
offset = { y = 5 },
widget = {}
}
local rows = {
expand = 'none',
layout = wibox.layout.align.vertical,
}
spotify_player.widget = wibox.widget {
image = ICON_DIR .. 'spotify-indicator.svg',
widget = wibox.widget.imagebox
}
local artwork_widget = wibox.widget {
forced_height = artwork_size,
forced_width = artwork_size,
widget = wibox.widget.imagebox
}
local artist_w = wibox.widget {
align = 'center',
widget = wibox.widget.textbox,
set_artist = function(self, artist)
self:set_markup('<span size="large" color="#ffffff">' .. artist .. '</span>')
end
}
local title_w = wibox.widget {
align = 'center',
forced_height = 30,
widget = wibox.widget.textbox,
set_title = function(self, title)
self:set_markup('<span size="x-large" font_weight="bold" color="#ffffff">' .. title .. '</span>')
end
}
local play_pause_btn = awesomebuttons.with_icon{ type = 'outline', icon = 'play', icon_size = 32, icon_margin = 8, color = '#1DB954', shape = 'circle', onclick = function()
spawn.with_shell('sp play')
end}
local buttons_w = wibox.widget {
{
awesomebuttons.with_icon{ icon = 'rewind', icon_size = 32, icon_margin = 8, color = '#18800000', shape = 'circle', onclick = function()
spawn.with_shell('sp prev')
end},
play_pause_btn,
awesomebuttons.with_icon{ icon = 'fast-forward', icon_size = 32, icon_margin = 8, color = '#18800000', shape = 'circle', onclick = function()
spawn.with_shell('sp next')
end},
spacing = 16,
layout = wibox.layout.fixed.horizontal
},
halign = 'center',
layout = wibox.container.place,
}
local some_w = wibox.widget {
artwork_widget,
{
{
{
{
title_w,
artist_w,
buttons_w,
layout = wibox.layout.fixed.vertical
},
top = 8,
bottom = 8,
widget = wibox.container.margin
},
bg = '#33333388',
widget = wibox.container.background
},
valign = 'bottom',
content_fill_horizontal = true,
layout = wibox.container.place,
},
layout = wibox.layout.stack
}
popup:setup({
some_w,
layout = wibox.layout.fixed.vertical,
})
local update_widget = function(widget, stdout, stderr, _, _)
for i = 0, #rows do rows[i]=nil end
if string.find(stdout, 'Error: Spotify is not running.') ~= nil then
return
end
local track_id, length, art_url, album, album_artist, artist, auto_rating, disc_number, title, track_number, url =
string.match(stdout, 'trackid|(.*)\nlength|(.*)\nartUrl|(.*)\nalbum|(.*)\nalbumArtist|(.*)\nartist|(.*)\nautoRating|(.*)\ndiscNumber|(.*)\ntitle|(.*)\ntrackNumber|(.*)\nurl|(.*)')
title = string.gsub(title, "&", '&amp;')
artist_w:set_artist(artist)
title_w:set_title(title)
-- spotify client bug: https://community.spotify.com/t5/Desktop-Linux/MPRIS-cover-art-url-file-not-found/td-p/4920104
art_url = art_url:gsub('https://open.spotify.com', 'https://i.scdn.co')
if ((art_url ~= nil or art_url ~='') and not gfs.file_readable('/tmp/' .. track_id)) then
spawn.easy_async('touch /tmp/' .. track_id, function()
spawn.easy_async('curl -L -s --show-error --create-dirs -o /tmp/' .. track_id .. ' '.. art_url, function(stdout, stderr)
if stderr ~= '' then
show_warning(stderr)
return
end
artwork_widget:set_image('/tmp/' .. track_id)
end)
end)
else
artwork_widget:set_image('/tmp/' .. track_id)
end
end
function spotify_player:tog()
if popup.visible then
popup.visible = not popup.visible
else
popup:move_next_to(mouse.current_widget_geometry)
end
end
spotify_player.widget:buttons(
awful.util.table.join(
awful.button({}, 1, function() spotify_player:tog() end)
)
)
watch('sp metadata', timeout, update_widget)
watch('sp status', 1, function(_, stdout)
stdout = string.gsub(stdout, "\n", "")
play_pause_btn:set_icon(stdout == 'Playing' and 'pause' or 'play')
end)
return spotify_player
end
return setmetatable(spotify_player, { __call = function(_, ...) return worker(...) end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

View File

@ -1,29 +0,0 @@
# Filesystem Widget
This widget shows file system disk space usage which is based on the `df` output. When clicked another widget appears with more detailed information. By default, it monitors the "/" mount. It can be configured with a list of mounts to monitor though only the first will show in the wibar. To have multiple mounts displayed on the wibar simply define multiple `fs_widgets` with different mounts as arguments.
![](./screenshot.png)
## Customizations
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `mounts` | `{'/'}` | Table with mounts to monitor, check the output from a `df` command for available options (column 'Mounted on') |
| `timeout` | 60 | How often in seconds the widget refreshes |
## Installation
Clone/download repo and use the widget in **rc.lua**:
```lua
local fs_widget = require("awesome-wm-widgets.fs-widget.fs-widget")
...
s.mywibox:setup {
s.mytasklist, -- Middle widget
{ -- Right widgets
fs_widget(), --default
fs_widget({ mounts = { '/', '/mnt/music' } }), -- multiple mounts
...
```

View File

@ -1,190 +0,0 @@
local awful = require("awful")
local watch = require("awful.widget.watch")
local wibox = require("wibox")
local beautiful = require("beautiful")
local gears = require("gears")
local storage_bar_widget = {}
--- Table with widget configuration, consists of three sections:
--- - general - general configuration
--- - widget - configuration of the widget displayed on the wibar
--- - popup - configuration of the popup
local config = {}
-- general
config.mounts = { '/' }
config.refresh_rate = 60
-- wibar widget
config.widget_width = 40
config.widget_bar_color = '#aaaaaa'
config.widget_onclick_bg = '#ff0000'
config.widget_border_color = '#535d6c66'
config.widget_background_color = '#22222233'
-- popup
config.popup_bg = '#22222233'
config.popup_border_width = 1
config.popup_border_color = '#535d6c66'
config.popup_bar_color = '#aaaaaa'
config.popup_bar_background_color = '#22222233'
config.popup_bar_border_color = '#535d6c66'
local function worker(user_args)
local args = user_args or {}
-- Setup config for the widget instance.
-- The `_config` table will keep the first existing value after checking
-- in this order: user parameter > beautiful > module default.
local _config = {}
for prop, value in pairs(config) do
_config[prop] = args[prop] or beautiful[prop] or value
end
storage_bar_widget = wibox.widget {
{
id = 'progressbar',
color = _config.widget_bar_color,
max_value = 100,
forced_height = 20,
forced_width = _config.widget_width,
paddings = 2,
margins = 4,
border_width = 1,
border_radius = 2,
border_color = _config.widget_border_color,
background_color = _config.widget_background_color,
widget = wibox.widget.progressbar
},
shape = function(cr, width, height)
gears.shape.rounded_rect(cr, width, height, 4)
end,
widget = wibox.container.background,
set_value = function(self, new_value)
self:get_children_by_id("progressbar")[1].value = new_value
end
}
local disk_rows = {
{ widget = wibox.widget.textbox },
spacing = 4,
layout = wibox.layout.fixed.vertical,
}
local disk_header = wibox.widget {
{
markup = '<b>Mount</b>',
forced_width = 150,
align = 'left',
widget = wibox.widget.textbox,
},
{
markup = '<b>Used</b>',
align = 'left',
widget = wibox.widget.textbox,
},
layout = wibox.layout.ratio.horizontal
}
disk_header:ajust_ratio(1, 0, 0.3, 0.7)
local popup = awful.popup {
bg = _config.popup_bg,
ontop = true,
visible = false,
shape = gears.shape.rounded_rect,
border_width = _config.popup_border_width,
border_color = _config.popup_border_color,
maximum_width = 400,
offset = { y = 5 },
widget = {}
}
storage_bar_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function()
if popup.visible then
popup.visible = not popup.visible
storage_bar_widget:set_bg('#00000000')
else
storage_bar_widget:set_bg(_config.widget_background_color)
popup:move_next_to(mouse.current_widget_geometry)
end
end)
)
)
local disks = {}
watch([[bash -c "df | tail -n +2"]], _config.refresh_rate,
function(widget, stdout)
for line in stdout:gmatch("[^\r\n$]+") do
local filesystem, size, used, avail, perc, mount =
line:match('([%p%w]+)%s+([%d%w]+)%s+([%d%w]+)%s+([%d%w]+)%s+([%d]+)%%%s+([%p%w]+)')
disks[mount] = {}
disks[mount].filesystem = filesystem
disks[mount].size = size
disks[mount].used = used
disks[mount].avail = avail
disks[mount].perc = perc
disks[mount].mount = mount
if disks[mount].mount == _config.mounts[1] then
widget:set_value(tonumber(disks[mount].perc))
end
end
for k, v in ipairs(_config.mounts) do
local row = wibox.widget {
{
text = disks[v].mount,
forced_width = 150,
widget = wibox.widget.textbox
},
{
color = _config.popup_bar_color,
max_value = 100,
value = tonumber(disks[v].perc),
forced_height = 20,
paddings = 1,
margins = 4,
border_width = 1,
border_color = _config.popup_bar_border_color,
background_color = _config.popup_bar_background_color,
bar_border_width = 1,
bar_border_color = _config.popup_bar_border_color,
widget = wibox.widget.progressbar,
},
{
text = math.floor(disks[v].used / 1024 / 1024)
.. '/'
.. math.floor(disks[v].size / 1024 / 1024) .. 'GB('
.. math.floor(disks[v].perc) .. '%)',
widget = wibox.widget.textbox
},
layout = wibox.layout.ratio.horizontal
}
row:ajust_ratio(2, 0.3, 0.3, 0.4)
disk_rows[k] = row
end
popup:setup {
{
disk_header,
disk_rows,
layout = wibox.layout.fixed.vertical,
},
margins = 8,
widget = wibox.container.margin
}
end,
storage_bar_widget
)
return storage_bar_widget
end
return setmetatable(storage_bar_widget, { __call = function(_, ...)
return worker(...)
end })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,77 +0,0 @@
# Gerrit widget
It shows number of currently assigned reviews in [Gerrit](https://www.gerritcodereview.com/) to the user (by default) :
![gerrit_widget](./gerrit_widget.png)
when clicked it shows reviews in a list:
![popup](./popup.png)
left click on an item will open review in the default browser, right click will copy the review number, which you can use to checkout this review by running `git-review -d <review number>`.
Also, if a new review is assigned to the user, there will be a pop-up:
![new_review](./new_review.png)
## Customization
It is possible to customize widget by providing a table with all or some of the following config parameters:
| Name | Default | Description |
|---|---|---|
| `icon`| `/.config/awesome/awesome-wm-widgets/gerrit-widget/gerrit_icon.svg`| Path to the icon |
| `host` | Required | Ex https://gerrit.tmnt.com |
| `query` | `is:reviewer AND status:open AND NOT is:wip` | Query to retrieve reviews |
| `timeout` | 10 | How often in seconds the widget refreshes |
## Prerequisite
- [curl](https://curl.haxx.se/) - is used to communicate with gerrit's [REST API](https://gerrit-review.googlesource.com/Documentation/rest-api.html)
- setup [netrc](https://ec.haxx.se/usingcurl-netrc.html) which is used to store username and password in order to call API's endpoints.
## Installation
1. This widget relies on Gerrit [REST API](https://gerrit-review.googlesource.com/Documentation/rest-api.html), so you need to have a permission to access it. You also need to setup [netrc](https://ec.haxx.se/usingcurl-netrc.html), as widget uses curl to communicate with API and you have to be authenticated.
To test if you have access to API and netrc setup is correct run following command, you should have a json response:
```bash
curl -s --request GET --netrc https://gerrit-host.com/a/changes/\?q\=status:open+AND+NOT+is:wip+AND+is:reviewer | tail -n +2
```
Note: `tail -n +2` is needed to skip first line of the response, as gerrit returns some characters there in order to prevent XSS hacks.
1. Download json parser for lua from [github.com/rxi/json.lua](https://github.com/rxi/json.lua) and place it under **~/.config/awesome/** (don't forget to star a repo):
```bash
wget -P ~/.config/awesome/ https://raw.githubusercontent.com/rxi/json.lua/master/json.lua
```
1. Clone this repo (if not cloned yet) under **~/.config/awesome/**:
```bash
git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/awesome/
```
1. Require widget at the top of the **rc.lua**:
```lua
local gerrit_widget = require("awesome-wm-widgets.gerrit-widget.gerrit")
```
1. Add widget to the tasklist:
```lua
s.mytasklist, -- Middle widget
{ -- Right widgets
layout = wibox.layout.fixed.horizontal,
...
--default
gerrit_widget({host = 'https://gerrit.tmnt.com'}),
--customized
gerrit_widget({
host = 'https://gerrit.tmnt.com',
query = 'is:reviewer AND is:wip'
})
...
```

View File

@ -1,230 +0,0 @@
-------------------------------------------------
-- Gerrit Widget for Awesome Window Manager
-- Shows the number of currently assigned reviews
-- More details could be found here:
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/gerrit-widget
-- @author Pavel Makhov
-- @copyright 2019 Pavel Makhov
-------------------------------------------------
local awful = require("awful")
local wibox = require("wibox")
local watch = require("awful.widget.watch")
local json = require("json")
local spawn = require("awful.spawn")
local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
local gfs = require("gears.filesystem")
local HOME_DIR = os.getenv("HOME")
local PATH_TO_AVATARS = HOME_DIR .. '/.cache/awmw/gerrit-widget/avatars/'
local GET_CHANGES_CMD = [[bash -c "curl -s -X GET -n %s/a/changes/\\?q\\=%s | tail -n +2"]]
local GET_USER_CMD = [[bash -c "curl -s -X GET -n %s/accounts/%s/ | tail -n +2"]]
local DOWNLOAD_AVATAR_CMD = [[bash -c "curl --create-dirs -o %s %s"]]
local gerrit_widget = {}
local function worker(user_args)
local args = user_args or {}
local icon = args.icons or HOME_DIR .. '/.config/awesome/awesome-wm-widgets/gerrit-widget/gerrit_icon.svg'
local host = args.host or naughty.notify{
preset = naughty.config.presets.critical,
title = 'Gerrit Widget',
text = 'Gerrit host is unknown'
}
local query = args.query or 'is:reviewer AND status:open AND NOT is:wip'
local timeout = args.timeout or 10
local current_number_of_reviews
local previous_number_of_reviews = 0
local name_dict = {}
local rows = {
{ widget = wibox.widget.textbox },
layout = wibox.layout.fixed.vertical,
}
local popup = awful.popup{
ontop = true,
visible = false,
shape = gears.shape.rounded_rect,
border_width = 1,
border_color = beautiful.bg_focus,
maximum_width = 400,
offset = { y = 5 },
widget = {}
}
gerrit_widget = wibox.widget {
{
{
image = icon,
widget = wibox.widget.imagebox
},
margins = 4,
layout = wibox.container.margin
},
{
id = "txt",
widget = wibox.widget.textbox
},
{
id = "new_rev",
widget = wibox.widget.textbox
},
layout = wibox.layout.fixed.horizontal,
set_text = function(self, new_value)
self.txt.text = new_value
end,
set_unseen_review = function(self, is_new_review)
self.new_rev.text = is_new_review and '*' or ''
end
}
local function get_name_by_user_id(user_id)
if name_dict[user_id] == nil then
name_dict[user_id] = {}
end
if name_dict[user_id].username == nil then
name_dict[user_id].username = ''
spawn.easy_async(string.format(GET_USER_CMD, host, user_id), function(stdout)
local user = json.decode(stdout)
name_dict[tonumber(user_id)].username = user.name
if not gfs.file_readable(PATH_TO_AVATARS .. user_id) then
spawn.easy_async(
string.format(DOWNLOAD_AVATAR_CMD, PATH_TO_AVATARS .. user_id, user.avatars[1].url))
end
end)
return name_dict[user_id].username
end
return name_dict[user_id].username
end
local update_widget = function(widget, stdout, _, _, _)
local reviews = json.decode(stdout)
current_number_of_reviews = rawlen(reviews)
if current_number_of_reviews == 0 then
widget:set_visible(false)
return
else
widget:set_visible(true)
end
widget:set_visible(true)
if current_number_of_reviews > previous_number_of_reviews then
widget:set_unseen_review(true)
naughty.notify{
icon = HOME_DIR ..'/.config/awesome/awesome-wm-widgets/gerrit-widget/gerrit_icon.svg',
title = 'New Incoming Review',
text = reviews[1].project .. '\n' .. get_name_by_user_id(reviews[1].owner._account_id) ..
reviews[1].subject .. '\n',
run = function() spawn.with_shell("xdg-open https://" .. host .. '/' .. reviews[1]._number) end
}
end
previous_number_of_reviews = current_number_of_reviews
widget:set_text(current_number_of_reviews)
for i = 0, #rows do rows[i]=nil end
for _, review in ipairs(reviews) do
local row = wibox.widget {
{
{
{
{
resize = true,
image = PATH_TO_AVATARS .. review.owner._account_id,
forced_width = 40,
forced_height = 40,
widget = wibox.widget.imagebox
},
margins = 8,
layout = wibox.container.margin
},
{
{
markup = '<b>' .. review.project .. '</b>',
align = 'center',
widget = wibox.widget.textbox
},
{
text = '' .. review.subject,
widget = wibox.widget.textbox
},
{
text = '' .. get_name_by_user_id(review.owner._account_id),
widget = wibox.widget.textbox
},
layout = wibox.layout.align.vertical
},
spacing = 8,
layout = wibox.layout.fixed.horizontal
},
margins = 8,
layout = wibox.container.margin
},
widget = wibox.container.background
}
row:connect_signal("button::release", function()
spawn.with_shell("xdg-open " .. host .. '/' .. review._number)
end)
row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
row:buttons(
awful.util.table.join(
awful.button({}, 1, function()
spawn.with_shell("xdg-open " .. host .. '/' .. review._number)
popup.visible = false
end),
awful.button({}, 3, function()
spawn.with_shell("echo '" .. review._number .."' | xclip -selection clipboard")
popup.visible = false
end)
)
)
table.insert(rows, row)
end
popup:setup(rows)
end
gerrit_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function()
gerrit_widget:set_unseen_review(false)
if popup.visible then
popup.visible = not popup.visible
else
--local geo = mouse.current_widget_geometry
--if theme.calendar_placement == 'center' then
-- local x = geo.x + (geo.width / 2) - (popup:geometry().width / 2) -- align two widgets
-- popup:move_next_to({x = x, y = geo.y + 22, width = 0, height = geo.height})
--else
-- popup:move_next_to(geo)
--end
popup:move_next_to(mouse.current_widget_geometry)
end
end)
)
)
watch(string.format(GET_CHANGES_CMD, host, query:gsub(" ", "+")), timeout, update_widget, gerrit_widget)
return gerrit_widget
end
return setmetatable(gerrit_widget, { __call = function(_, ...) return worker(...) end })

View File

@ -1,8 +0,0 @@
<svg width="52" height="52" xmlns="http://www.w3.org/2000/svg">
<rect ry="4" rx="4" height="40" width="40" y="0" x="0" fill="#ffaaaa"/>
<rect ry="4" rx="4" height="40" width="40" y="12" x="12" fill="#aaffaa"/>
<path d="m18,22l12,0l0,4l-12,0l0,-4z" fill="#ff0000"/>
<path d="m34,22l12,0l0,4l-12,0l0,-4z" fill="#ff0000"/>
<path d="m18,36l4,0l0,-4l4,0l0,4l4,0l0,4l-4,0l0,4l-4,0l0,-4l-4,0l0,-4z" fill="#008000"/>
<path d="m34,36l4,0l0,-4l4,0l0,4l4,0l0,4l-4,0l0,4l-4,0l0,-4l-4,0l0,-4z" fill="#008000"/>
</svg>

Before

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Some files were not shown because too many files have changed in this diff Show More