diff options
64 files changed, 1544 insertions, 560 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..5bd55b0 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: streetturtle diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1bfeee3 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,28 @@ +# 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: + - '*' + 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 diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..e4f47fa --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,24 @@ +self = false + +globals = { + "screen", + "mouse", + "root", + "client" +} + +read_globals = { + "awesome", + "button", + "dbus", + "drawable", + "drawin", + "key", + "keygrabber", + "mousegrabber", + "selection", + "tag", + "window", + "table.unpack", + "math.atan2", +}
\ No newline at end of file @@ -6,14 +6,16 @@ <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 super simple widgets compatible with Awesome Window Manager v.4+. +Set of super simple widgets compatible with Awesome Window Manager v.4+. -## Screenshots +## Screenshots Spotify, CPU, RAM, brightness-arc, volume-arc and battery-arc widgets: @@ -34,19 +36,20 @@ Some more screenshots in this reddit [post](https://www.reddit.com/r/unixporn/co From left to right: - [spotify-widget](https://github.com/streetturtle/AwesomeWM/tree/master/spotify-widget) / [rhythmbox-widget](https://github.com/streetturtle/AwesomeWM/tree/master/rhythmbox-widget) -- [cpu-widget](https://github.com/streetturtle/AwesomeWM/tree/master/cpu-widget) +- [cpu-widget](https://github.com/streetturtle/AwesomeWM/tree/master/cpu-widget) - [weather-widget](https://github.com/streetturtle/AwesomeWM/tree/master/weather-widget) - [email-widget](https://github.com/streetturtle/AwesomeWM/tree/master/email-widget) - [brightness-widget](https://github.com/streetturtle/AwesomeWM/tree/master/brightness-widget) - [volume-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volume-widget) -- [volumebar-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volumebar-widget) -- [volumearc-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volumearc-widget) -- [batteryarc-widget](https://github.com/streetturtle/AwesomeWM/tree/master/batteryarc-widget) +- [volumebar-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volumebar-widget) +- [volumearc-widget](https://github.com/streetturtle/AwesomeWM/tree/master/volumearc-widget) +- [batteryarc-widget](https://github.com/streetturtle/AwesomeWM/tree/master/batteryarc-widget) - [battery-widget](https://github.com/streetturtle/AwesomeWM/tree/master/battery-widget) - [ram-widget](https://github.com/streetturtle/AwesomeWM/tree/master/ram-widget) - [translate-widget](https://github.com/streetturtle/AwesomeWM/tree/master/translate-widget) (not on the screenshot) - [spotify-shell](https://github.com/streetturtle/AwesomeWM/tree/master/spotify-shell) (not on the screenshot) - [run-shell](https://github.com/streetturtle/AwesomeWM/tree/master/run-shell) (not on the screenshot) +- [mpris-widget](https://github.com/streetturtle/AwesomeWM/tree/master/mpris-widget) (not on the screenshot) # Installation @@ -55,3 +58,14 @@ Clone the repo under **~/.config/awesome/**, then follow an Installation section # 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 don't hesitate to create an issue. Or try [Discussions](https://github.com/streetturtle/awesome-wm-widgets/discussions)! + +# 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) diff --git a/battery-widget/battery.lua b/battery-widget/battery.lua index 8a6982a..b0a71e7 100644 --- a/battery-widget/battery.lua +++ b/battery-widget/battery.lua @@ -20,10 +20,11 @@ local dpi = require('beautiful').xresources.apply_dpi -- 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(args) - local args = args or {} +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/" @@ -39,7 +40,7 @@ local function worker(args) 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 HOME .. '/.config/awesome/awesome-wm-widgets/batteryarc-widget/spaceman.jpg' + 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 @@ -59,7 +60,8 @@ local function worker(args) widget = wibox.widget.imagebox, resize = false }, - layout = wibox.container.margin(_, 0, 0, 3) + bottom = 3, + layout = wibox.container.margin } local level_widget = wibox.widget { font = font, @@ -119,11 +121,11 @@ local function worker(args) local batteryType = "battery-good-symbolic" watch("acpi -i", timeout, - function(widget, stdout, stderr, exitreason, exitcode) + function(widget, stdout) local battery_info = {} local capacities = {} for s in stdout:gmatch("[^\r\n]+") do - local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?(.*)') + 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 @@ -133,7 +135,7 @@ local function worker(args) end local capacity = 0 - for i, cap in ipairs(capacities) do + for _, cap in ipairs(capacities) do capacity = capacity + cap end @@ -184,12 +186,12 @@ local function worker(args) 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) + 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 diff --git a/batteryarc-widget/README.md b/batteryarc-widget/README.md index 1a2a397..a257b2f 100644 --- a/batteryarc-widget/README.md +++ b/batteryarc-widget/README.md @@ -38,6 +38,7 @@ It is possible to customize widget by providing a table with all or some of the | `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 diff --git a/batteryarc-widget/batteryarc.lua b/batteryarc-widget/batteryarc.lua index 916c7b1..1b6752a 100644 --- a/batteryarc-widget/batteryarc.lua +++ b/batteryarc-widget/batteryarc.lua @@ -15,18 +15,20 @@ 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 widget = {} +local batteryarc_widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + 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' @@ -37,7 +39,7 @@ local function worker(args) 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 HOME .. '/.config/awesome/awesome-wm-widgets/batteryarc-widget/spaceman.jpg' + 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 @@ -52,7 +54,7 @@ local function worker(args) local text_with_background = wibox.container.background(text) - widget = wibox.widget { + batteryarc_widget = wibox.widget { text_with_background, max_value = 100, rounded_edge = true, @@ -67,11 +69,27 @@ local function worker(args) 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, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?(.*)') + 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 @@ -115,11 +133,11 @@ local function worker(args) end end - watch("acpi", timeout, update_widget, widget) + watch("acpi", timeout, update_widget, batteryarc_widget) -- Popup with battery info local notification - function show_battery_status() + local function show_battery_status() awful.spawn.easy_async([[bash -c 'acpi']], function(stdout, _, _, _) naughty.destroy(notification) @@ -127,39 +145,24 @@ local function worker(args) text = stdout, title = "Battery status", timeout = 5, - hover_timeout = 0.5, width = 200, } end) end - widget:connect_signal("mouse::enter", function() - show_battery_status() - end) - widget:connect_signal("mouse::leave", function() - naughty.destroy(notification) - end) - - --[[ Show warning notification ]] - 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, - } + 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 widget + return batteryarc_widget end -return setmetatable(widget, { __call = function(_, ...) +return setmetatable(batteryarc_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/bitbucket-widget/README.md b/bitbucket-widget/README.md index a0cae0a..7f82e73 100644 --- a/bitbucket-widget/README.md +++ b/bitbucket-widget/README.md @@ -4,9 +4,9 @@ The widget shows the number of pull requests assigned to the user and when click ## 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 to store basic auth credentials in a .netrc file in home folder. +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. +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 @@ -15,15 +15,19 @@ It is possible to customize widget by providing a table with all or some of the | Name | Default | Description | |---|---|---| | `icon` | `~/.config/awesome/awesome-wm-widgets/bitbucket-widget/bitbucket-icon-gradient-blue.svg` | Path to the icon | -| `host` | Required | Ex: _http://api.bitbucket.org_ | -| `uuid` | Required | UUID | +| `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: +Create a **.netrc** file in you home directory with following content: ```bash machine api.bitbucket.org @@ -56,7 +60,7 @@ s.mytasklist, -- Middle widget -- default bitbucket_widget({ host = 'https://api.bitbucket.org', - uuid = 'your-uuid', + uuid = '{123e4567-e89b-12d3-a456-426614174000}', workspace = 'workspace', repo_slug = 'slug' diff --git a/bitbucket-widget/bitbucket.lua b/bitbucket-widget/bitbucket.lua index 8d47f2f..b85e653 100644 --- a/bitbucket-widget/bitbucket.lua +++ b/bitbucket-widget/bitbucket.lua @@ -21,7 +21,12 @@ 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 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 { @@ -71,7 +76,7 @@ local popup = awful.popup{ --- 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, mil = date_str:match(pattern) + 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 @@ -111,9 +116,9 @@ local function count_approves(participants) return res end -local function worker(args) +local function worker(user_args) - local args = args or {} + 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') @@ -279,11 +284,8 @@ local function worker(args) } if not gfs.file_readable(path_to_avatar) then - spawn.easy_async(string.format( - DOWNLOAD_AVATAR_CMD, - HOME_DIR, - pr.author.uuid, - pr.author.links.avatar.href), function() row:get_children_by_id('avatar')[1]:set_image(path_to_avatar) end) + 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 @@ -299,34 +301,36 @@ local function worker(args) ) ) 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) - ) + 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(c) + 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(c) + 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) - local old_cursor, old_wibox - row:get_children_by_id('avatar')[1]:connect_signal("mouse::enter", function(c) + 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(c) + row:get_children_by_id('avatar')[1]:connect_signal("mouse::leave", function() if old_wibox then old_wibox.cursor = old_cursor old_wibox = nil diff --git a/brightness-widget/brightness.lua b/brightness-widget/brightness.lua index 0cfbea4..4686041 100644 --- a/brightness-widget/brightness.lua +++ b/brightness-widget/brightness.lua @@ -17,11 +17,11 @@ local GET_BRIGHTNESS_CMD = "light -G" -- "xbacklight -get" local INC_BRIGHTNESS_CMD = "light -A 5" -- "xbacklight -inc 5" local DEC_BRIGHTNESS_CMD = "light -U 5" -- "xbacklight -dec 5" -local widget = {} +local brightness_widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local get_brightness_cmd = args.get_brightness_cmd or GET_BRIGHTNESS_CMD local inc_brightness_cmd = args.inc_brightness_cmd or INC_BRIGHTNESS_CMD @@ -43,7 +43,7 @@ local function worker(args) widget = wibox.container.margin } - widget = wibox.widget { + brightness_widget = wibox.widget { brightness_icon, brightness_text, layout = wibox.layout.fixed.horizontal, @@ -52,9 +52,9 @@ local function worker(args) local update_widget = function(widget, stdout, _, _, _) local brightness_level = tonumber(string.format("%.0f", stdout)) widget:set_text(" " .. brightness_level .. "%") - end, + end - widget:connect_signal("button::press", function(_, _, _, button) + brightness_widget:connect_signal("button::press", function(_, _, _, button) if (button == 4) then spawn(inc_brightness_cmd, false) elseif (button == 5) then @@ -64,9 +64,9 @@ local function worker(args) watch(get_brightness_cmd, timeout, update_widget, brightness_text) - return widget + return brightness_widget end -return setmetatable(widget, { __call = function(_, ...) +return setmetatable(brightness_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/brightnessarc-widget/brightnessarc.lua b/brightnessarc-widget/brightnessarc.lua index ee93482..fd37894 100644 --- a/brightnessarc-widget/brightnessarc.lua +++ b/brightnessarc-widget/brightnessarc.lua @@ -18,11 +18,11 @@ local GET_BRIGHTNESS_CMD = "light -G" -- "xbacklight -get" local INC_BRIGHTNESS_CMD = "light -A 5" -- "xbacklight -inc 5" local DEC_BRIGHTNESS_CMD = "light -U 5" -- "xbacklight -dec 5" -local widget = {} +local brightness_widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local get_brightness_cmd = args.get_brightness_cmd or GET_BRIGHTNESS_CMD local inc_brightness_cmd = args.inc_brightness_cmd or INC_BRIGHTNESS_CMD @@ -39,7 +39,7 @@ local function worker(args) widget = wibox.widget.imagebox, } - widget = wibox.widget { + brightness_widget = wibox.widget { icon, max_value = 1, thickness = 2, @@ -57,9 +57,9 @@ local function worker(args) brightness_level = tonumber(string.format("% 3d", brightness_level)) widget.value = brightness_level / 100; - end, + end - widget:connect_signal("button::press", function(_, _, _, button) + brightness_widget:connect_signal("button::press", function(_, _, _, button) if (button == 4) then spawn(inc_brightness_cmd, false) elseif (button == 5) then @@ -67,11 +67,11 @@ local function worker(args) end end) - watch(get_brightness_cmd, timeout, update_widget, widget) + watch(get_brightness_cmd, timeout, update_widget, brightness_widget) - return widget + return brightness_widget end -return setmetatable(widget, { __call = function(_, ...) +return setmetatable(brightness_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/calendar-widget/README.md b/calendar-widget/README.md index c30fef6..77b8fe7 100644 --- a/calendar-widget/README.md +++ b/calendar-widget/README.md @@ -9,10 +9,11 @@ Calendar widget for Awesome WM - slightly improved version of the `wibox.widget. | Name | Screenshot | |---|---| - |nord (default) | ![nord_theme](./nord.png) | + | nord (default) | ![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 @@ -45,6 +46,7 @@ local cw = calendar_widget() local cw = calendar_widget({ theme = 'outrun', placement = 'bottom_right' + radius = 8 }) mytextclock:connect_signal("button::press", function(_, _, _, button) diff --git a/calendar-widget/calendar.lua b/calendar-widget/calendar.lua index e15d094..b39b563 100644 --- a/calendar-widget/calendar.lua +++ b/calendar-widget/calendar.lua @@ -16,7 +16,7 @@ local naughty = require("naughty") local calendar_widget = {} -local function worker(args) +local function worker(user_args) local calendar_themes = { nord = { @@ -68,21 +68,33 @@ local function worker(args) 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 = args or {} + 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 = 'nord' + args.theme = 'naughty' end - local theme = args.theme or 'nord' + local theme = args.theme or 'naughty' local placement = args.placement or 'top' + local radius = args.radius or 8 local styles = {} @@ -142,7 +154,9 @@ local function worker(args) -- 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 default_bg = (weekday == 0 or weekday == 6) + and calendar_themes[theme].weekend_day_bg + or calendar_themes[theme].bg local ret = wibox.widget { { { @@ -175,7 +189,7 @@ local function worker(args) local popup = awful.popup { ontop = true, visible = false, - shape = gears.shape.rounded_rect, + shape = rounded_shape(radius), offset = { y = 5 }, border_width = 1, border_color = calendar_themes[theme].border, @@ -216,7 +230,8 @@ local function worker(args) 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() }) + 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 diff --git a/cpu-widget/cpu-widget.lua b/cpu-widget/cpu-widget.lua index 317ef0a..bed40fe 100644 --- a/cpu-widget/cpu-widget.lua +++ b/cpu-widget/cpu-widget.lua @@ -14,10 +14,13 @@ 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"]] + local HOME_DIR = os.getenv("HOME") local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/cpu-widget' -local widget = {} +local cpu_widget = {} local cpu_rows = { spacing = 4, layout = wibox.layout.fixed.vertical, @@ -86,9 +89,9 @@ local function create_kill_process_button() } end -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local width = args.width or 50 local step_width = args.step_width or 2 @@ -120,8 +123,8 @@ local function worker(args) } -- Do not update process rows when mouse cursor is over the widget - popup:connect_signal("mouse::enter", function(c) is_update = false end) - popup:connect_signal("mouse::leave", function(c) is_update = true end) + 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( @@ -136,155 +139,162 @@ local function worker(args) ) --- By default graph widget goes from left to right, so we mirror it and push up a bit - local cpu_widget = wibox.container.margin(wibox.container.mirror(cpugraph_widget, { horizontal = true }), 0, 0, 0, 2) + cpu_widget = wibox.widget { + { + cpugraph_widget, + reflection = {horizontal = true}, + layout = wibox.container.mirror + }, + bottom = 2, + widget = wibox.container.margin + } local cpus = {} - watch([[bash -c "grep '^cpu.' /proc/stat; ps -eo '%p|%c|%C|' -o "%mem" -o '|%a' --sort=-%cpu | head -11 | tail -n +2"]], timeout, - function(widget, stdout) - local i = 1 - local j = 1 - for line in stdout:gmatch("[^\r\n]+") do - if starts_with(line, 'cpu') then + watch(CMD, timeout, function(widget, 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 + if cpus[i] == nil then cpus[i] = {} end - local name, user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice = - line:match('(%w+)%s+(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)') + 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 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 + 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 + cpus[i]['total_prev'] = total + cpus[i]['idle_prev'] = idle - if i == 1 then - widget:add_value(diff_usage) - end + if i == 1 then + widget:add_value(diff_usage) + end + + 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, - local row = wibox.widget + }, + 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 = 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(c) kill_proccess_button.icon.opacity = 1 end) - row:connect_signal("mouse::leave", function(c) 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 + 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) - 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 + 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 - 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, - cpugraph_widget + + 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, + cpugraph_widget ) return cpu_widget end -return setmetatable(widget, { __call = function(_, ...) +return setmetatable(cpu_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/docker-widget/docker.lua b/docker-widget/docker.lua index 6e04d8a..6ea0179 100644 --- a/docker-widget/docker.lua +++ b/docker-widget/docker.lua @@ -19,7 +19,8 @@ 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}}'"]] +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) @@ -62,7 +63,6 @@ local parse_container = function(line) else actual_status = status end how_long = how_long:gsub('%s?%(.*%)%s?', '') - -- if how_long:find('seconds') then how_long = 'less than a minute ago' end local container = { name = name, @@ -84,9 +84,9 @@ local status_to_icon_name = { Paused = ICONS_DIR .. 'pause.svg' } -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local icon = args.icon or ICONS_DIR .. 'docker.svg' local number_of_containers = args.number_of_containers or -1 @@ -98,15 +98,15 @@ local function worker(args) layout = wibox.layout.fixed.vertical, } - local function rebuild_widget(stdout, stderr, _, _) - if stderr ~= '' then - show_warning(stderr) + 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 stdout:gmatch("[^\r\n]+") do + for line in containers:gmatch("[^\r\n]+") do local container = parse_container(line) @@ -122,20 +122,36 @@ local function worker(args) 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 + { + 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 }, - 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) @@ -148,10 +164,12 @@ local function worker(args) status_icon:set_opacity(0.2) status_icon:emit_signal('widget::redraw_needed') - awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(stdout, stderr) - if stderr ~= '' then show_warning(stderr) end - spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers), function(stdout, stderr) - rebuild_widget(stdout, stderr) end) + 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 @@ -163,21 +181,36 @@ local function worker(args) 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 + { + 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 }, - 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) @@ -190,16 +223,68 @@ local function worker(args) status_icon:set_opacity(0.2) status_icon:emit_signal('widget::redraw_needed') - awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(stdout, stderr) + 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, stderr) - rebuild_widget(stdout, 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( + awful.util.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 { { @@ -237,9 +322,10 @@ local function worker(args) { start_stop_button, pause_unpause_button, + delete_button, layout = wibox.layout.align.horizontal }, - forced_width = 60, + forced_width = 90, valign = 'center', haligh = 'center', layout = wibox.container.place, @@ -270,10 +356,11 @@ local function worker(args) if popup.visible then popup.visible = not popup.visible else - 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) + 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) ) diff --git a/docker-widget/icons/trash-btn.svg b/docker-widget/icons/trash-btn.svg new file mode 100644 index 0000000..78d8035 --- /dev/null +++ b/docker-widget/icons/trash-btn.svg @@ -0,0 +1 @@ +<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>
\ No newline at end of file diff --git a/email-widget/email.lua b/email-widget/email.lua index d6619f9..f7656fb 100644 --- a/email-widget/email.lua +++ b/email-widget/email.lua @@ -5,30 +5,30 @@ local watch = require("awful.widget.watch") local path_to_icons = "/usr/share/icons/Arc/actions/22/" -email_widget = wibox.widget.textbox() +local email_widget = wibox.widget.textbox() email_widget:set_font('Play 9') -email_icon = wibox.widget.imagebox() +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(widget, stdout, stderr, exitreason, exitcode) + 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_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 + email_icon:set_image(path_to_icons .. "/mail-message-new.png") + email_widget:set_text("") + end end ) -function show_emails() +local function show_emails() awful.spawn.easy_async([[bash -c 'python /home/<username>/.config/awesome/email-widget/read_unread_emails.py']], - function(stdout, stderr, reason, exit_code) + function(stdout) naughty.notify{ text = stdout, title = "Unread Emails", diff --git a/experiments/spotify-player/spotify-player.lua b/experiments/spotify-player/spotify-player.lua index 9fb725b..a6c53df 100644 --- a/experiments/spotify-player/spotify-player.lua +++ b/experiments/spotify-player/spotify-player.lua @@ -6,7 +6,7 @@ -- @author Pavel Makhov -- @copyright 2020 Pavel Makhov ------------------------------------------------- - +--luacheck:ignore local awful = require("awful") local wibox = require("wibox") local watch = require("awful.widget.watch") diff --git a/experiments/volume/README.md b/experiments/volume/README.md new file mode 100644 index 0000000..1210ced --- /dev/null +++ b/experiments/volume/README.md @@ -0,0 +1,81 @@ +# Volume widget + +Volume widget based on [amixer](https://linux.die.net/man/1/amixer) (is used for controlling the audio volume) and [pacmd](https://linux.die.net/man/1/pacmd) (is used for selecting a sink/source). Also, the widget provides an easy way to customize how it looks, following types are supported out-of-the-box: + +![types](./screenshots/variations.png) + +From left to right: `horizontal_bar`, `vertical_bar`, `icon`, `icon_and_text`, `arc` + +A right-click on the widget opens a popup where you can choose a sink/source: +![sink-sources](./screenshots/volume-sink-sources.png) + +### Features + + - switch between sinks/sources by right clicking on the widget; + - more responsive than previous versions of volume widget, which were refreshed once a second; + - 5 predefined looks (check the screenshots below); + +## 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 | +|---|---|---| +| `type`| `icon_and_text`| Widget type, one of `horizontal_bar`, `vertical_bar`, `icon`, `icon_and_text`, `arc` | + +### `icon` parameters + +| Name | Default | Description | +|---|---|---| +| `icon_dir`| `./icons`| Path to the folder with icons | + +_Note:_ if you are changing icons, the folder should contain following .svg images: + - audio-volume-high-symbolic + - audio-volume-medium-symbolic + - audio-volume-low-symbolic + - audio-volume-muted-symbolic + +### `icon_and_text` parameters + +| Name | Default | Description | +|---|---|---| +| `icon_dir`| `./icons`| Path to the folder with icons | +| `font` | `beautiful.font` | Font name and size, like `Play 12` | + +### `arc` parameters + +| Name | Default | Description | +|---|---|---| +| `thickness` | 2 | Thickness of the arc | +| `main_color` | `beautiful.fg_color` | Color of the arc | +| `bg_color` | `#ffffff11` | Color of the arc's background | +| `mute_color` | `beautiful.fg_urgent` | Color of the arc when mute | +| `size` | 18 | Size of the widget | + +### `horizontal_bar` parameters + +| Name | Default | Description | +|---|---|---| +| `main_color` | `beautiful.fg_normal` | Color of the bar | +| `mute_color` | `beautiful.fg_urgent` | Color of the bar when mute | +| `bg_color` | `'#ffffff11'` | Color of the bar's background | +| `width` | `50` | The bar width | +| `margins` | `10` | Top and bottom margins (if your wibar is 22 px high, bar will be 2 px = 22 - 2*10) | +| `shape` | `'bar'` | [gears.shape](https://awesomewm.org/doc/api/libraries/gears.shape.html), could be `octogon`, `hexagon`, `powerline`, etc | +| `with_icon` | `true` | Show volume icon| + +_Note:_ I didn't figure out how does the `forced_height` property of progressbar widget work (maybe it doesn't work at all), thus there is a workaround with margins. + +### `vertical_bar` parameters + +| Name | Default | Description | +|---|---|---| +| `main_color` | `beautiful.fg_normal` | Color of the bar | +| `mute_color` | `beautiful.fg_urgent` | Color of the bar when mute | +| `bg_color` | `'#ffffff11'` | Color of the bar's background | +| `width` | `10` | The bar width | +| `margins` | `20` | Top and bottom margins (if your wibar is 22 px high, bar will be 2 px = 22 - 2*10) | +| `shape` | `'bar'` | [gears.shape](https://awesomewm.org/doc/api/libraries/gears.shape.html), could be `octogon`, `hexagon`, `powerline`, etc | +| `with_icon` | `true` | Show volume icon| diff --git a/experiments/volume/screenshots/variations.png b/experiments/volume/screenshots/variations.png Binary files differnew file mode 100644 index 0000000..21d7ead --- /dev/null +++ b/experiments/volume/screenshots/variations.png diff --git a/experiments/volume/screenshots/volume-sink-sources.png b/experiments/volume/screenshots/volume-sink-sources.png Binary files differnew file mode 100644 index 0000000..7d010bc --- /dev/null +++ b/experiments/volume/screenshots/volume-sink-sources.png diff --git a/experiments/volume/utils.lua b/experiments/volume/utils.lua index dcaeb84..417a666 100644 --- a/experiments/volume/utils.lua +++ b/experiments/volume/utils.lua @@ -1,5 +1,4 @@ -local json = require("json") local utils = {} diff --git a/experiments/volume/volume.lua b/experiments/volume/volume.lua index 9110a45..7daeb40 100644 --- a/experiments/volume/volume.lua +++ b/experiments/volume/volume.lua @@ -18,15 +18,17 @@ local utils = require("awesome-wm-widgets.experiments.volume.utils") local LIST_DEVICES_CMD = [[sh -c "pacmd list-sinks; pacmd list-sources"]] local GET_VOLUME_CMD = 'amixer -D pulse sget Master' -local INC_VOLUME_CMD = 'amixer -q -D pulse sset Master 5%+' -local DEC_VOLUME_CMD = 'amixer -q -D pulse sset Master 5%-' -local TOG_VOLUME_CMD = 'amixer -q -D pulse sset Master toggle' +local INC_VOLUME_CMD = 'amixer -D pulse sset Master 5%+' +local DEC_VOLUME_CMD = 'amixer -D pulse sset Master 5%-' +local TOG_VOLUME_CMD = 'amixer -D pulse sset Master toggle' local widget_types = { icon_and_text = require("awesome-wm-widgets.experiments.volume.widgets.icon-and-text-widget"), icon = require("awesome-wm-widgets.experiments.volume.widgets.icon-widget"), - arc = require("awesome-wm-widgets.experiments.volume.widgets.arc-widget") + arc = require("awesome-wm-widgets.experiments.volume.widgets.arc-widget"), + horizontal_bar = require("awesome-wm-widgets.experiments.volume.widgets.horizontal-bar-widget"), + vertical_bar = require("awesome-wm-widgets.experiments.volume.widgets.vertical-bar-widget") } local volume_widget = wibox.widget{} @@ -58,17 +60,17 @@ local function build_rows(devices, on_checkbox_click, device_type) for _, device in pairs(devices) do local checkbox = wibox.widget { - checked = device.is_default, - color = beautiful.bg_normal, - paddings = 2, - shape = gears.shape.circle, + checked = device.is_default, + color = beautiful.bg_normal, + paddings = 2, + shape = gears.shape.circle, forced_width = 20, forced_height = 20, check_color = beautiful.fg_urgent, - widget = wibox.widget.checkbox + widget = wibox.widget.checkbox } - checkbox:connect_signal("button::press", function(c) + checkbox:connect_signal("button::press", function() spawn.easy_async(string.format([[sh -c 'pacmd set-default-%s "%s"']], device_type, device.name), function() on_checkbox_click() end) @@ -105,19 +107,19 @@ local function build_rows(devices, on_checkbox_click, device_type) row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end) local old_cursor, old_wibox - row:connect_signal("mouse::enter", function(c) + row:connect_signal("mouse::enter", function() local wb = mouse.current_wibox old_cursor, old_wibox = wb.cursor, wb wb.cursor = "hand1" end) - row:connect_signal("mouse::leave", function(c) + row:connect_signal("mouse::leave", function() if old_wibox then old_wibox.cursor = old_cursor old_wibox = nil end end) - row:connect_signal("button::press", function(c) + row:connect_signal("button::press", function() spawn.easy_async(string.format([[sh -c 'pacmd set-default-%s "%s"']], device_type, device.name), function() on_checkbox_click() end) @@ -158,16 +160,27 @@ local function rebuild_popup() end -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local widget_type = args.widget_type + local refresh_rate = args.refresh_rate or 1 if widget_types[widget_type] == nil then - volume_widget = widget_types['icon_and_text'].get_widget() + volume_widget = widget_types['icon_and_text'].get_widget(user_args.icon_and_text_args) else - volume_widget = widget_types[widget_type].get_widget() + volume_widget = widget_types[widget_type].get_widget(args) + end + + local function update_graphic(widget, stdout) + local mute = string.match(stdout, "%[(o%D%D?)%]") -- \[(o\D\D?)\] - [on] or [off] + if mute == 'off' then widget:mute() + elseif mute == 'on' then widget:unmute() + end + local volume = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%) + volume = string.format("% 3d", volume) + widget:set_volume_level(volume) end volume_widget:buttons( @@ -180,23 +193,19 @@ local function worker(args) popup:move_next_to(mouse.current_widget_geometry) end end), - awful.button({}, 4, function() awful.spawn(INC_VOLUME_CMD, false) end), - awful.button({}, 5, function() awful.spawn(DEC_VOLUME_CMD, false) end), - awful.button({}, 1, function() awful.spawn(TOG_VOLUME_CMD, false) end) + awful.button({}, 4, function() + spawn.easy_async(INC_VOLUME_CMD, function(stdout) update_graphic(volume_widget, stdout) end) + end), + awful.button({}, 5, function() + spawn.easy_async(DEC_VOLUME_CMD, function(stdout) update_graphic(volume_widget, stdout) end) + end), + awful.button({}, 1, function() + spawn.easy_async(TOG_VOLUME_CMD, function(stdout) update_graphic(volume_widget, stdout) end) + end) ) ) - local function update_graphic(widget, stdout) - local mute = string.match(stdout, "%[(o%D%D?)%]") -- \[(o\D\D?)\] - [on] or [off] - if mute == 'off' then volume_widget:mute() - elseif mute == 'on' then volume_widget:unmute() - end - local volume = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%) - volume = string.format("% 3d", volume) - widget:set_volume_level(volume) - end - - watch(GET_VOLUME_CMD, 1, update_graphic, volume_widget) + watch(GET_VOLUME_CMD, refresh_rate, update_graphic, volume_widget) return volume_widget end diff --git a/experiments/volume/widgets/arc-widget.lua b/experiments/volume/widgets/arc-widget.lua index d7a3b1f..b6c9d22 100644 --- a/experiments/volume/widgets/arc-widget.lua +++ b/experiments/volume/widgets/arc-widget.lua @@ -5,7 +5,14 @@ local ICON_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/exper local widget = {} -function widget.get_widget() +function widget.get_widget(widgets_args) + local args = widgets_args or {} + + local thickness = args.thickness or 2 + local main_color = args.main_color or beautiful.fg_color + local bg_color = args.bg_color or '#ffffff11' + local mute_color = args.mute_color or beautiful.fg_urgent + local size = args.size or 18 return wibox.widget { { @@ -15,21 +22,21 @@ function widget.get_widget() widget = wibox.widget.imagebox, }, max_value = 100, - thickness = 2, + thickness = thickness, start_angle = 4.71238898, -- 2pi*3/4 - forced_height = 18, - forced_width = 18, - bg = '#ffffff11', + forced_height = size, + forced_width = size, + bg = bg_color, paddings = 2, widget = wibox.container.arcchart, set_volume_level = function(self, new_value) self.value = new_value end, mute = function(self) - self.colors = {'#BF616A'} + self.colors = { mute_color } end, unmute = function(self) - self.colors = {beautiful.fg_color} + self.colors = { main_color } end } diff --git a/experiments/volume/widgets/horizontal-bar-widget.lua b/experiments/volume/widgets/horizontal-bar-widget.lua new file mode 100644 index 0000000..1a1c8a4 --- /dev/null +++ b/experiments/volume/widgets/horizontal-bar-widget.lua @@ -0,0 +1,58 @@ +local wibox = require("wibox") +local beautiful = require('beautiful') +local gears = require("gears") + +local ICON_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/' + +local widget = {} + +function widget.get_widget(widgets_args) + local args = widgets_args or {} + + local main_color = args.main_color or beautiful.fg_normal + local mute_color = args.mute_color or beautiful.fg_urgent + local bg_color = args.bg_color or '#ffffff11' + local width = args.width or 50 + local margins = args.margins or 10 + local shape = args.shape or 'bar' + local with_icon = args.with_icon == true and true or false + + local bar = wibox.widget { + { + { + id = "icon", + image = ICON_DIR .. 'audio-volume-high-symbolic.svg', + resize = false, + widget = wibox.widget.imagebox, + }, + valign = 'center', + visible = with_icon, + layout = wibox.container.place, + }, + { + id = 'bar', + max_value = 100, + forced_width = width, + color = main_color, + margins = { top = margins, bottom = margins }, + background_color = bg_color, + shape = gears.shape[shape], + widget = wibox.widget.progressbar, + }, + spacing = 4, + layout = wibox.layout.fixed.horizontal, + set_volume_level = function(self, new_value) + self:get_children_by_id('bar')[1]:set_value(tonumber(new_value)) + end, + mute = function(self) + self:get_children_by_id('bar')[1]:set_color(mute_color) + end, + unmute = function(self) + self:get_children_by_id('bar')[1]:set_color(main_color) + end + } + + return bar +end + +return widget diff --git a/experiments/volume/widgets/icon-and-text-widget.lua b/experiments/volume/widgets/icon-and-text-widget.lua index 5517f11..74044fb 100644 --- a/experiments/volume/widgets/icon-and-text-widget.lua +++ b/experiments/volume/widgets/icon-and-text-widget.lua @@ -1,10 +1,15 @@ local wibox = require("wibox") +local beautiful = require('beautiful') local widget = {} -local WIDGET_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/' +local ICON_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/' -function widget.get_widget() +function widget.get_widget(widgets_args) + local args = widgets_args or {} + + local font = args.font or beautiful.font + local icon_dir = args.icon_dir or ICON_DIR return wibox.widget { { @@ -18,15 +23,15 @@ function widget.get_widget() }, { id = 'txt', + font = font, widget = wibox.widget.textbox }, layout = wibox.layout.fixed.horizontal, - is_muted = true, set_volume_level = function(self, new_value) self:get_children_by_id('txt')[1]:set_text(new_value) - local volume_icon_name = '' + local volume_icon_name if self.is_muted then - volume_icon_name = 'audio-volume-muted-symbolic.svg' + volume_icon_name = 'audio-volume-muted-symbolic' else local new_value_num = tonumber(new_value) if (new_value_num >= 0 and new_value_num < 33) then @@ -37,16 +42,16 @@ function widget.get_widget() volume_icon_name="audio-volume-high-symbolic" end end - self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. volume_icon_name .. '.svg') + self:get_children_by_id('icon')[1]:set_image(icon_dir .. volume_icon_name .. '.svg') end, mute = function(self) + print("called") self.is_muted = true - self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. 'audio-volume-muted-symbolic.svg') + self:get_children_by_id('icon')[1]:set_image(icon_dir .. 'audio-volume-muted-symbolic.svg') end, unmute = function(self) self.is_muted = false - end, - + end } end diff --git a/experiments/volume/widgets/icon-widget.lua b/experiments/volume/widgets/icon-widget.lua index 2a20dde..f2aca26 100644 --- a/experiments/volume/widgets/icon-widget.lua +++ b/experiments/volume/widgets/icon-widget.lua @@ -2,9 +2,12 @@ local wibox = require("wibox") local widget = {} -local WIDGET_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/' +local ICON_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/' -function widget.get_widget() +function widget.get_widget(widgets_args) + local args = widgets_args or {} + + local icon_dir = args.icon_dir or ICON_DIR return wibox.widget { { @@ -15,9 +18,9 @@ function widget.get_widget() valign = 'center', layout = wibox.container.place, set_volume_level = function(self, new_value) - local volume_icon_name = '' + local volume_icon_name if self.is_muted then - volume_icon_name = 'audio-volume-muted-symbolic.svg' + volume_icon_name = 'audio-volume-muted-symbolic' else local new_value_num = tonumber(new_value) if (new_value_num >= 0 and new_value_num < 33) then @@ -28,11 +31,11 @@ function widget.get_widget() volume_icon_name="audio-volume-high-symbolic" end end - self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. volume_icon_name .. '.svg') + self:get_children_by_id('icon')[1]:set_image(icon_dir .. volume_icon_name .. '.svg') end, mute = function(self) self.is_muted = true - self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. 'audio-volume-muted-symbolic.svg') + self:get_children_by_id('icon')[1]:set_image(icon_dir .. 'audio-volume-muted-symbolic.svg') end, unmute = function(self) self.is_muted = false diff --git a/experiments/volume/widgets/vertical-bar-widget.lua b/experiments/volume/widgets/vertical-bar-widget.lua new file mode 100644 index 0000000..82f4b8a --- /dev/null +++ b/experiments/volume/widgets/vertical-bar-widget.lua @@ -0,0 +1,64 @@ +local wibox = require("wibox") +local beautiful = require('beautiful') +local gears = require("gears") + +local ICON_DIR = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/experiments/volume/icons/' + +local widget = {} + +function widget.get_widget(widgets_args) + local args = widgets_args or {} + + local main_color = args.main_color or beautiful.fg_normal + local mute_color = args.mute_color or beautiful.fg_urgent + local bg_color = args.bg_color or '#ffffff11' + local width = args.width or 10 + local margins = args.height or 2 + local shape = args.shape or 'bar' + local with_icon = args.with_icon == true and true or false + + local bar = wibox.widget { + { + { + id = "icon", + image = ICON_DIR .. 'audio-volume-high-symbolic.svg', + resize = false, + widget = wibox.widget.imagebox, + }, + valign = 'center', + visible = with_icon, + layout = wibox.container.place, + }, + { + { + id = 'bar', + max_value = 100, + forced_width = width, + forced_height = 5, + margins = { top = margins, bottom = margins }, + color = main_color, + background_color = bg_color, + shape = gears.shape[shape], + widget = wibox.widget.progressbar, + }, + forced_width = width, + direction = 'east', + layout = wibox.container.rotate, + }, + spacing = 4, + layout = wibox.layout.fixed.horizontal, + set_volume_level = function(self, new_value) + self:get_children_by_id('bar')[1]:set_value(tonumber(new_value)) + end, + mute = function(self) + self:get_children_by_id('bar')[1]:set_color(mute_color) + end, + unmute = function(self) + self:get_children_by_id('bar')[1]:set_color(main_color) + end + } + + return bar +end + +return widget diff --git a/fs-widget/README.md b/fs-widget/README.md index 5cda048..f134b05 100644 --- a/fs-widget/README.md +++ b/fs-widget/README.md @@ -1,10 +1,21 @@ # Filesystem Widget -This widget shows disk usage. 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. +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) + +## Cusomizations + +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") @@ -13,12 +24,6 @@ with different mounts as arguments. s.mytasklist, -- Middle widget { -- Right widgets fs_widget(), --default - wibox.widget.textbox(':'), - fs_widget({ mounts = { '/', '/mnt/musicj' } }), -- multiple mounts + fs_widget({ mounts = { '/', '/mnt/music' } }), -- multiple mounts ... - ``` - -## Installation - -Please refer to the [installation](https://github.com/streetturtle/awesome-wm-widgets#installation) section of the repo. diff --git a/fs-widget/fs-widget.lua b/fs-widget/fs-widget.lua index 613c472..0c12a3a 100644 --- a/fs-widget/fs-widget.lua +++ b/fs-widget/fs-widget.lua @@ -6,8 +6,8 @@ local gears = require("gears") local storage_bar_widget = {} -local function worker(args) - local args = args or {} +local function worker(user_args) + local args = user_args or {} local mounts = args.mounts or {'/'} local timeout = args.timeout or 60 @@ -17,7 +17,8 @@ local function worker(args) forced_width = 35, paddings = 1, margins = 4, - border_width = 0.5, + border_width = 1, + border_radius = 2, border_color = beautiful.fg_normal, background_color = beautiful.bg_normal, bar_border_width = 1, @@ -61,8 +62,6 @@ local function worker(args) offset = { y = 5 }, widget = {} } - popup:connect_signal("mouse::enter", function(c) is_update = false end) - popup:connect_signal("mouse::leave", function(c) is_update = true end) storage_bar_widget:buttons( awful.util.table.join( diff --git a/fs-widget/out.gif b/fs-widget/out.gif Binary files differdeleted file mode 100644 index 736f894..0000000 --- a/fs-widget/out.gif +++ /dev/null diff --git a/fs-widget/screenshot.png b/fs-widget/screenshot.png Binary files differnew file mode 100644 index 0000000..41e6ccc --- /dev/null +++ b/fs-widget/screenshot.png diff --git a/gerrit-widget/gerrit.lua b/gerrit-widget/gerrit.lua index ad5d7a6..682eb0f 100644 --- a/gerrit-widget/gerrit.lua +++ b/gerrit-widget/gerrit.lua @@ -27,13 +27,13 @@ local DOWNLOAD_AVATAR_CMD = [[bash -c "curl --create-dirs -o %s %s"]] local gerrit_widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + 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, + preset = naughty.config.presets.critical, title = 'Gerrit Widget', text = 'Gerrit host is unknown' } @@ -93,11 +93,12 @@ local function worker(args) 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, stderr, reason, exit_code) + 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)) + 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 @@ -124,7 +125,8 @@ local function worker(args) 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', + 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 @@ -174,7 +176,7 @@ local function worker(args) widget = wibox.container.background } - row:connect_signal("button::release", function(_, _, _, button) + row:connect_signal("button::release", function() spawn.with_shell("xdg-open " .. host .. '/' .. review._number) end) diff --git a/github-activity-widget/github-activity-widget.lua b/github-activity-widget/github-activity-widget.lua index 84b5320..5374081 100644 --- a/github-activity-widget/github-activity-widget.lua +++ b/github-activity-widget/github-activity-widget.lua @@ -22,9 +22,12 @@ local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/github-activ local ICONS_DIR = WIDGET_DIR .. '/icons/' local CACHE_DIR = HOME_DIR .. '/.cache/awmw/github-activity-widget' -local GET_EVENTS_CMD = [[bash -c "cat %s/activity.json | jq '.[:%d] | [.[] | {type: .type, actor: .actor, repo: .repo, action: .payload.action, issue_url: .payload.issue.html_url, pr_url: .payload.pull_request.html_url, created_at: .created_at}]'"]] -local DOWNLOAD_AVATAR_CMD = [[bash -c "curl -n --create-dirs -o %s/avatars/%s %s"]] -local UPDATE_EVENTS_CMD = [[bash -c "curl -s --show-error https://api.github.com/users/%s/received_events > %s/activity.json"]] +local GET_EVENTS_CMD = [[sh -c "cat %s/activity.json | jq '.[:%d] | [.[] ]] + .. [[| {type: .type, actor: .actor, repo: .repo, action: .payload.action, issue_url: .payload.issue.html_url, ]] + .. [[pr_url: .payload.pull_request.html_url, created_at: .created_at}]'"]] +local DOWNLOAD_AVATAR_CMD = [[sh -c "curl -n --create-dirs -o %s/avatars/%s %s"]] +local UPDATE_EVENTS_CMD = [[sh -c "curl -s --show-error https://api.github.com/users/%s/received_events ]] + ..[[> %s/activity.json"]] --- Utility function to show warning messages local function show_warning(message) @@ -37,7 +40,7 @@ end --- 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, mil = date_str:match(pattern) + 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 @@ -129,13 +132,13 @@ local github_widget = wibox.widget { } -local function worker(args) +local function worker(user_args) if not gfs.dir_readable(CACHE_DIR) then gfs.make_directories(CACHE_DIR) end - local args = args or {} + local args = user_args or {} local icon = args.icon or ICONS_DIR .. 'github.png' local username = args.username or show_warning('No username provided') @@ -147,7 +150,7 @@ local function worker(args) layout = wibox.layout.fixed.vertical, } - local rebuild_widget = function(widget, stdout, stderr, _, _) + local rebuild_widget = function(stdout, stderr, _, _) if stderr ~= '' then show_warning(stderr) return @@ -197,7 +200,8 @@ local function worker(args) local repo_info = wibox.widget { { - markup = '<b> ' .. event.actor.display_login .. '</b> ' .. action_and_link.action_string .. ' <b>' .. event.repo.name .. '</b>', + markup = '<b> ' .. event.actor.display_login .. '</b> ' .. action_and_link.action_string + .. ' <b>' .. event.repo.name .. '</b>', wrap = 'word', widget = wibox.widget.textbox }, @@ -261,10 +265,11 @@ local function worker(args) if popup.visible then popup.visible = not popup.visible else - spawn.easy_async(string.format(GET_EVENTS_CMD, CACHE_DIR, number_of_events), function (stdout, stderr) - rebuild_widget(github_widget, stdout, stderr) - popup:move_next_to(mouse.current_widget_geometry) - end) + spawn.easy_async(string.format(GET_EVENTS_CMD, CACHE_DIR, number_of_events), + function (stdout, stderr) + rebuild_widget(stdout, stderr) + popup:move_next_to(mouse.current_widget_geometry) + end) end end) ) @@ -276,7 +281,7 @@ local function worker(args) call_now = true, autostart = true, callback = function() - spawn.easy_async(string.format(UPDATE_EVENTS_CMD, username, CACHE_DIR), function(stdout, stderr) + spawn.easy_async(string.format(UPDATE_EVENTS_CMD, username, CACHE_DIR), function(_, stderr) if stderr ~= '' then show_warning(stderr) return end end) end diff --git a/github-contributions-widget/github-contributions-widget.lua b/github-contributions-widget/github-contributions-widget.lua index b462299..5a45fcb 100644 --- a/github-contributions-widget/github-contributions-widget.lua +++ b/github-contributions-widget/github-contributions-widget.lua @@ -13,7 +13,8 @@ local naughty = require("naughty") local wibox = require("wibox") local widget_themes = require("awesome-wm-widgets.github-contributions-widget.themes") -local GET_CONTRIBUTIONS_CMD = [[bash -c "curl -s https://github-contributions.now.sh/api/v1/%s | jq -r '[.contributions[] | select ( .date | strptime(\"%%Y-%%m-%%d\") | mktime < now)][:%s]| .[].color'"]] +local GET_CONTRIBUTIONS_CMD = [[bash -c "curl -s https://github-contributions.now.sh/api/v1/%s]] + .. [[ | jq -r '[.contributions[] | select ( .date | strptime(\"%%Y-%%m-%%d\") | mktime < now)][:%s]| .[].color'"]] local github_contributions_widget = wibox.widget{ reflection = { @@ -30,9 +31,9 @@ local function show_warning(message) text = message} end -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local username = args.username or 'streetturtle' local days = args.days or 365 @@ -62,10 +63,10 @@ local function worker(args) local r, g, b = hex2rgb(color) return wibox.widget{ - fit = function(self, context, width, height) + fit = function() return 3, 3 end, - draw = function(self, context, cr, width, height) + draw = function(_, _, cr, _, _) cr:set_source_rgb(r/255, g/255, b/255) cr:rectangle(0, 0, with_border and 2 or 3, with_border and 2 or 3) cr:fill() @@ -77,11 +78,11 @@ local function worker(args) local col = {layout = wibox.layout.fixed.vertical} local row = {layout = wibox.layout.fixed.horizontal} local a = 5 - os.date('%w') - for i = 0, a do + for _ = 0, a do table.insert(col, get_square(color_of_empty_cells)) end - local update_widget = function(widget, stdout, _, _, _) + local update_widget = function(_, stdout, _, _, _) for colors in stdout:gmatch("[^\r\n]+") do if a%7 == 0 then table.insert(row, col) @@ -100,7 +101,7 @@ local function worker(args) end awful.spawn.easy_async(string.format(GET_CONTRIBUTIONS_CMD, username, days), - function(stdout, stderr) + function(stdout) update_widget(github_contributions_widget, stdout) end) diff --git a/gitlab-widget/gitlab.lua b/gitlab-widget/gitlab.lua index 3482347..2ab65b6 100644 --- a/gitlab-widget/gitlab.lua +++ b/gitlab-widget/gitlab.lua @@ -21,8 +21,9 @@ local color = require("gears.color") local HOME_DIR = os.getenv("HOME") local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/gitlab-widget/' -local GET_PRS_CMD= [[bash -c "curl -s --connect-timeout 5 --show-error --header 'PRIVATE-TOKEN: %s' '%s/api/v4/merge_requests?state=opened'"]] -local DOWNLOAD_AVATAR_CMD = [[bash -c "curl -L --create-dirs -o %s/.cache/awmw/gitlab-widget/avatars/%s %s"]] +local GET_PRS_CMD= [[sh -c "curl -s --connect-timeout 5 --show-error --header 'PRIVATE-TOKEN: %s']] + ..[[ '%s/api/v4/merge_requests?state=opened'"]] +local DOWNLOAD_AVATAR_CMD = [[sh -c "curl -L --create-dirs -o %s/.cache/awmw/gitlab-widget/avatars/%s %s"]] local gitlab_widget = wibox.widget { { @@ -33,7 +34,7 @@ local gitlab_widget = wibox.widget { }, { id = 'error_marker', - draw = function(self, context, cr, width, height) + draw = function(_, _, cr, _, height) cr:set_source(color(beautiful.fg_urgent)) cr:arc(height/4, height/4, height/4, 0, math.pi*2) cr:fill() @@ -96,7 +97,7 @@ local popup = awful.popup{ --- 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, mil = date_str:match(pattern) + 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 @@ -134,9 +135,9 @@ local tooltip = awful.tooltip { preferred_positions = {'bottom'}, } -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local icon = args.icon or WIDGET_DIR .. '/icons/gitlab-icon.svg' local api_token = args.api_token or show_warning('API Token is not set') @@ -318,7 +319,9 @@ local function worker(args) DOWNLOAD_AVATAR_CMD, HOME_DIR, pr.author.id, - pr.author.avatar_url), function() row:get_children_by_id('avatar')[1]:set_image(path_to_avatar) end) + pr.author.avatar_url), 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) @@ -342,25 +345,24 @@ local function worker(args) ) local old_cursor, old_wibox - row:get_children_by_id('title')[1]:connect_signal("mouse::enter", function(c) + 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(c) + 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) - local old_cursor, old_wibox - row:get_children_by_id('avatar')[1]:connect_signal("mouse::enter", function(c) + 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(c) + row:get_children_by_id('avatar')[1]:connect_signal("mouse::leave", function() if old_wibox then old_wibox.cursor = old_cursor old_wibox = nil diff --git a/jira-widget/jira.lua b/jira-widget/jira.lua index 7f0ceb6..9a89a0d 100644 --- a/jira-widget/jira.lua +++ b/jira-widget/jira.lua @@ -17,12 +17,12 @@ local naughty = require("naughty") local gears = require("gears") local beautiful = require("beautiful") local gfs = require("gears.filesystem") -local gs = require("gears.string") local color = require("gears.color") local HOME_DIR = os.getenv("HOME") -local GET_ISSUES_CMD = [[bash -c "curl -s --show-error -X GET -n '%s/rest/api/2/search?%s&fields=id,assignee,summary,status'"]] +local GET_ISSUES_CMD = + [[bash -c "curl -s --show-error -X GET -n '%s/rest/api/2/search?%s&fields=id,assignee,summary,status'"]] local DOWNLOAD_AVATAR_CMD = [[bash -c "curl -n --create-dirs -o %s/.cache/awmw/jira-widget/avatars/%s %s"]] local function show_warning(message) @@ -41,7 +41,7 @@ local jira_widget = wibox.widget { }, { id = 'd', - draw = function(self, context, cr, width, height) + draw = function(_, _, cr, _, height) cr:set_source(color(beautiful.fg_urgent)) cr:arc(height/4, height/4, height/4, 0, math.pi*2) cr:fill() @@ -100,9 +100,9 @@ local tooltip = awful.tooltip { preferred_positions = {'bottom'}, } -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local icon = args.icon or HOME_DIR .. '/.config/awesome/awesome-wm-widgets/jira-widget/jira-mark-gradient-blue.svg' local host = args.host or show_warning('Jira host is unknown') @@ -149,7 +149,7 @@ local function worker(args) for i = 0, #rows do rows[i]=nil end for _, issue in ipairs(result.issues) do - local path_to_avatar = os.getenv("HOME") ..'/.cache/awmw/jira-widget/avatars/' .. issue.fields.assignee.accountId + local path_to_avatar = HOME_DIR ..'/.cache/awmw/jira-widget/avatars/' .. issue.fields.assignee.accountId if not gfs.file_readable(path_to_avatar) then spawn.easy_async(string.format( diff --git a/logout-widget/logout.lua b/logout-widget/logout.lua index 9fcc9fe..512ac23 100644 --- a/logout-widget/logout.lua +++ b/logout-widget/logout.lua @@ -54,8 +54,8 @@ local function create_button(icon_name, action_name, color, onclick, icon_size, capi.keygrabber.stop() end } - button:connect_signal("mouse::enter", function(c) action:set_text(action_name) end) - button:connect_signal("mouse::leave", function(c) action:set_text(' ') end) + button:connect_signal("mouse::enter", function() action:set_text(action_name) end) + button:connect_signal("mouse::leave", function() action:set_text(' ') end) return button end @@ -76,7 +76,8 @@ local function launch(args) w:set_bg(bg_color) if #phrases > 0 then - phrase_widget:set_markup('<span color="'.. text_color .. '" size="20000">' .. phrases[ math.random( #phrases ) ] .. '</span>') + phrase_widget:set_markup( + '<span color="'.. text_color .. '" size="20000">' .. phrases[ math.random( #phrases ) ] .. '</span>') end w:setup { diff --git a/mpdarc-widget/mpdarc.lua b/mpdarc-widget/mpdarc.lua index d70e6ee..f1d6930 100644 --- a/mpdarc-widget/mpdarc.lua +++ b/mpdarc-widget/mpdarc.lua @@ -25,7 +25,7 @@ local PAUSE_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_pause.png" local PLAY_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_play.png" local STOP_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_stop.png" -local icon = wibox.widget { +local icon = wibox.widget { id = "icon", widget = wibox.widget.imagebox, image = PLAY_ICON_NAME @@ -58,7 +58,7 @@ local update_graphic = function(widget, stdout, _, _, _) stdout = string.gsub(stdout, "\n", "") local mpdpercent = string.match(stdout, "(%d%d)%%") local mpdstatus = string.match(stdout, "%[(%a+)%]") - if mpdstatus == "playing" then + if mpdstatus == "playing" then icon.image = PLAY_ICON_NAME widget.colors = { beautiful.widget_main_color } widget.value = tonumber((100-mpdpercent)/100) @@ -93,7 +93,7 @@ mpdarc:connect_signal("button::press", function(_, _, _, button) end) local notification -function show_MPD_status() +local function show_MPD_status() spawn.easy_async(GET_MPD_CMD, function(stdout, _, _, _) notification = naughty.notify { diff --git a/mpris-widget/README.md b/mpris-widget/README.md new file mode 100644 index 0000000..1978914 --- /dev/null +++ b/mpris-widget/README.md @@ -0,0 +1,26 @@ +# MPRIS Widget (In progress) + +Music Player Info widget cy @mgabs + +# Prerequisite + +Install `playerctl` (mpris implementation), should be available in repo, e.g for Ubuntu: + +```bash +sudo apt-get install playerctl +``` + +## Installation + +To use this widget clone repo under **~/.config/awesome/** and then add it in **rc.lua**: + +```lua +local mpris_widget = require("awesome-wm-widgets.mpris-widget") +... +s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + ... + mpris_widget, + ... +``` diff --git a/mpris-widget/init.lua b/mpris-widget/init.lua new file mode 100644 index 0000000..1b6dcfc --- /dev/null +++ b/mpris-widget/init.lua @@ -0,0 +1,267 @@ +------------------------------------------------- +-- mpris based Arc Widget for Awesome Window Manager +-- Modelled after Pavel Makhov's work +-- @author Mohammed Gaber +-- requires - playerctl +-- @copyright 2020 +------------------------------------------------- +local awful = require("awful") +local beautiful = require("beautiful") +local spawn = require("awful.spawn") +local watch = require("awful.widget.watch") +local wibox = require("wibox") +local naughty = require("naughty") +local gears = require("gears") + +local GET_MPD_CMD = "playerctl -p %s -f '{{status}};{{xesam:artist}};{{xesam:title}};{{mpris:artUrl}}' metadata" + +local TOGGLE_MPD_CMD = "playerctl play-pause" +local PAUSE_MPD_CMD = "playerctl pause" +local STOP_MPD_CMD = "playerctl stop" +local NEXT_MPD_CMD = "playerctl next" +local PREV_MPD_CMD = "playerctl previous" +local LIST_PLAYERS_CMD = "playerctl -l" + +local PATH_TO_ICONS = "/usr/share/icons/Arc" +local PAUSE_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_pause.png" +local PLAY_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_play.png" +local STOP_ICON_NAME = PATH_TO_ICONS .. "/actions/24/player_stop.png" +local LIBRARY_ICON_NAME = PATH_TO_ICONS .. "/actions/24/music-library.png" + +local default_player = '' + +local mpris_widget = wibox.widget{ + { + id = 'artist', + widget = wibox.widget.textbox + }, + { + max_value = 1, + value = 0, + thickness = 2, + start_angle = 4.71238898, -- 2pi*3/4 + forced_height = 24, + forced_width = 24, + rounded_edge = true, + bg = "#ffffff11", + paddings = 0, + widget = wibox.container.arcchart + }, + { + id = 'title', + widget = wibox.widget.textbox + }, + layout = wibox.layout.fixed.horizontal, + set_text = function(self, artis, title) + self:get_children_by_id('artist')[1]:set_text(artis) + self:get_children_by_id('title')[1]:set_text(title) + end +} + +local rows = { layout = wibox.layout.fixed.vertical } + +local popup = awful.popup{ + bg = beautiful.bg_normal, + 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 function rebuild_popup() + awful.spawn.easy_async(LIST_PLAYERS_CMD, function(stdout, _, _, _) + for player_name in stdout:gmatch("[^\r\n]+") do + if player_name ~='' or player_name ~=nil then + for i = 0, #rows do rows[i]=nil end + + local checkbox = wibox.widget{ + { + checked = player_name == default_player, + color = beautiful.bg_normal, + paddings = 2, + shape = gears.shape.circle, + forced_width = 20, + forced_height = 20, + check_color = beautiful.fg_urgent, + widget = wibox.widget.checkbox + }, + valign = 'center', + layout = wibox.container.place, + } + + checkbox:connect_signal("button::press", function(c) + default_player = player_name + rebuild_popup() + end) + + table.insert(rows, wibox.widget { + { + { + checkbox, + { + { + text = player_name, + align = 'left', + widget = wibox.widget.textbox + }, + left = 10, + layout = wibox.container.margin + }, + spacing = 8, + layout = wibox.layout.align.horizontal + }, + margins = 4, + layout = wibox.container.margin + }, + bg = beautiful.bg_normal, + widget = wibox.container.background + }) + end + end + end) + + popup:setup(rows) +end + +local function worker() + + -- retriving song info + local current_song, artist, mpdstatus, art, artUrl + + local icon = wibox.widget { + id = "icon", + widget = wibox.widget.imagebox, + image = PLAY_ICON_NAME + } + local mirrored_icon = wibox.container.mirror(icon, {horizontal = true}) + + local mpdarc = wibox.widget { + mirrored_icon, + -- max_value = 1, + -- value = 0, + thickness = 2, + start_angle = 4.71238898, -- 2pi*3/4 + forced_height = 24, + forced_width = 24, + rounded_edge = true, + bg = "#ffffff11", + paddings = 0, + widget = wibox.container.arcchart + } + + local mpdarc_icon_widget = wibox.container.mirror(mpdarc, {horizontal = true}) + local mpdarc_current_song_widget = wibox.widget { + id = 'current_song', + widget = wibox.widget.textbox, + font = 'Play 10' + } + + local update_graphic = function(widget, stdout, _, _, _) + -- mpdstatus, artist, current_song = stdout:match("(%w+)%;+(.-)%;(.*)") + local words = {} + for w in stdout:gmatch("([^;]*)") do table.insert(words, w) end + + mpdstatus = words[1] + artist = words[2] + current_song = words[3] + art = words[4] + if current_song ~= nil then + if string.len(current_song) > 18 then + current_song = string.sub(current_song, 0, 9) .. ".." + end + end + + if art ~= nil then artUrl = string.sub(art, 8, -1) end + + if mpdstatus == "Playing" then + mpdarc_icon_widget.visible = true + icon.image = PLAY_ICON_NAME + widget.colors = {beautiful.widget_main_color} + mpdarc_current_song_widget.markup = current_song + widget:set_text(artist, current_song) + elseif mpdstatus == "Paused" then + mpdarc_icon_widget.visible = true + icon.image = PAUSE_ICON_NAME + widget.colors = {beautiful.widget_main_color} + mpdarc_current_song_widget.markup = current_song + widget.set_text(artist, current_song) + elseif mpdstatus == "Stopped" then + mpdarc_icon_widget.visible = true + icon.image = STOP_ICON_NAME + mpdarc_current_song_widget.markup = "" + else -- no player is running + icon.image = LIBRARY_ICON_NAME + mpdarc_icon_widget.visible = false + mpdarc_current_song_widget.markup = "" + widget.colors = {beautiful.widget_red} + end + end + + mpdarc:connect_signal("button::press", function(_, _, _, button) + if (button == 1) then + awful.spawn(TOGGLE_MPD_CMD, false) -- left click + elseif (button == 2) then + awful.spawn(STOP_MPD_CMD, false) + elseif (button == 3) then + awful.spawn(PAUSE_MPD_CMD, false) + elseif (button == 4) then + awful.spawn(NEXT_MPD_CMD, false) -- scroll up + elseif (button == 5) then + awful.spawn(PREV_MPD_CMD, false) -- scroll down + end + + -- spawn.easy_async(string.format(GET_MPD_CMD, "'" .. default_player .. "'"), function(stdout, stderr, exitreason, exitcode) + -- update_graphic(mpdarc, stdout, stderr, exitreason, exitcode) + -- end) + end) + + mpris_widget:buttons( + awful.util.table.join( + awful.button({}, 3, function() + if popup.visible then + popup.visible = not popup.visible + else + rebuild_popup() + popup:move_next_to(mouse.current_widget_geometry) + end + end), + awful.button({}, 4, function() awful.spawn(NEXT_MPD_CMD, false) end), + awful.button({}, 5, function() awful.spawn(PREV_MPD_CMD, false) end), + awful.button({}, 1, function() awful.spawn(TOGGLE_MPD_CMD, false) end) + ) + ) + + + + local notification + local function show_MPD_status() + spawn.easy_async(GET_MPD_CMD, function() + notification = naughty.notification { + margin = 10, + timeout = 5, + hover_timeout = 0.5, + width = 240, + height = 90, + title = "<b>" .. mpdstatus .. "</b>", + text = current_song .. " <b>by</b> " .. artist, + image = artUrl + } + end) + end + + mpdarc:connect_signal("mouse::enter", function() + if current_song ~= nil and artist ~= nil then show_MPD_status() end + end) + mpdarc:connect_signal("mouse::leave", function() naughty.destroy(notification) end) + + watch(string.format(GET_MPD_CMD, "'" .. default_player .. "'"), 1, update_graphic, mpris_widget) + + return mpris_widget + +end + +return setmetatable(mpris_widget, {__call = function(_, ...) return worker(...) end}) diff --git a/net-speed-widget/net-speed.lua b/net-speed-widget/net-speed.lua index 846898c..409e03d 100644 --- a/net-speed-widget/net-speed.lua +++ b/net-speed-widget/net-speed.lua @@ -8,7 +8,6 @@ -- @copyright 2020 Pavel Makhov ------------------------------------------------- -local naughty = require("naughty") local watch = require("awful.widget.watch") local wibox = require("wibox") @@ -16,14 +15,6 @@ local HOME_DIR = os.getenv("HOME") local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/net-speed-widget/' local ICONS_DIR = WIDGET_DIR .. 'icons/' -local function show_warning(message) - naughty.notify { - preset = naughty.config.presets.critical, - title = 'Net Speed Widget', - text = message - } -end - local net_speed_widget = wibox.widget { { id = 'rx_speed', @@ -91,21 +82,21 @@ local function split(string_to_split, separator) return t end -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local interface = args.interface or '*' local timeout = args.timeout or 1 - local update_widget = function(widget, stdout, stderr) + local update_widget = function(widget, stdout) local cur_vals = split(stdout, '\r\n') local cur_rx = 0 local cur_tx = 0 - for i, v in ipairs(cur_vals) do + for i, _ in ipairs(cur_vals) do if i%2 == 1 then cur_rx = cur_rx + cur_vals[i] end if i%2 == 0 then cur_tx = cur_tx + cur_vals[i] end end @@ -120,7 +111,8 @@ local function worker(args) prev_tx = cur_tx end - watch(string.format([[bash -c "cat /sys/class/net/%s/statistics/*_bytes"]], interface), timeout, update_widget, net_speed_widget) + watch(string.format([[bash -c "cat /sys/class/net/%s/statistics/*_bytes"]], interface), + timeout, update_widget, net_speed_widget) return net_speed_widget diff --git a/pomodoroarc-widget/pomodoroarc.lua b/pomodoroarc-widget/pomodoroarc.lua index dab8c3a..497a208 100644 --- a/pomodoroarc-widget/pomodoroarc.lua +++ b/pomodoroarc-widget/pomodoroarc.lua @@ -92,7 +92,7 @@ text.font = "Inconsolata Medium 13" widget.value = tonumber(pomodoro/(25*60)) text.font = "Inconsolata Medium 13" text.text = "PW" - elseif workbreak == "B" then + elseif workbreak == "B" then widget.colors = { beautiful.widget_yellow } widget.value = tonumber(pomodoro/(5*60)) text.font = "Inconsolata Medium 13" @@ -114,7 +114,7 @@ pomodoroarc:connect_signal("button::press", function(_, _, _, button) end) local notification -function show_pomodoro_status() +local function show_pomodoro_status() spawn.easy_async(GET_pomodoro_CMD, function(stdout, _, _, _) notification = naughty.notify { diff --git a/ram-widget/ram-widget.lua b/ram-widget/ram-widget.lua index 55b6fd7..49a7d3b 100644 --- a/ram-widget/ram-widget.lua +++ b/ram-widget/ram-widget.lua @@ -1,19 +1,23 @@ local awful = require("awful") +local beautiful = require("beautiful") +local gears = require("gears") local watch = require("awful.widget.watch") local wibox = require("wibox") + local ramgraph_widget = {} -local function worker(args) - local args = args or {} +local function worker(user_args) + local args = user_args or {} local timeout = args.timeout or 1 --- Main ram widget shown on wibar ramgraph_widget = wibox.widget { border_width = 0, colors = { - '#74aeab', '#26403f' + beautiful.bg_urgent, -- used + beautiful.fg_normal -- free }, display_labels = false, forced_width = 25, @@ -21,28 +25,26 @@ local function worker(args) } --- Widget which is shown when user clicks on the ram widget - local w = wibox { - height = 200, - width = 400, - ontop = true, - expand = true, - bg = '#1e252c', - max_widget_size = 500 - } - - w:setup { - border_width = 0, - colors = { - '#5ea19d', - '#55918e', - '#4b817e', - }, - display_labels = false, - forced_width = 25, - id = 'pie', - widget = wibox.widget.piechart + local popup = awful.popup{ + ontop = true, + visible = false, + widget = { + widget = wibox.widget.piechart, + forced_height = 200, + forced_width = 400, + colors = { + beautiful.bg_urgent, -- used + beautiful.fg_normal, -- free + beautiful.border_color_active, -- buf_cache + }, + }, + shape = gears.shape.rounded_rect, + border_color = beautiful.border_color_active, + border_width = 1, + offset = { y = 5 }, } + --luacheck:ignore 231 local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap local function getPercentage(value) @@ -50,17 +52,17 @@ local function worker(args) end watch('bash -c "LANGUAGE=en_US.UTF-8 free | grep -z Mem.*Swap.*"', timeout, - function(widget, stdout, stderr, exitreason, exitcode) + function(widget, stdout) total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)') - widget.data = { used, total-used } widget.data = { used, total-used } + widget.data = { used, total-used } - if w.visible then - w.pie.data_list = { - {'used ' .. getPercentage(used + used_swap), used + used_swap}, - {'free ' .. getPercentage(free + free_swap), free + free_swap}, - {'buff_cache ' .. getPercentage(buff_cache), buff_cache} + if popup.visible then + popup:get_widget().data_list = { + {'used ' .. getPercentage(used + used_swap), used + used_swap}, + {'free ' .. getPercentage(free + free_swap), free + free_swap}, + {'buff_cache ' .. getPercentage(buff_cache), buff_cache} } end end, @@ -69,23 +71,26 @@ local function worker(args) ramgraph_widget:buttons( awful.util.table.join( - awful.button({}, 1, function() - awful.placement.top_right(w, { margins = {top = 25, right = 10}, parent = awful.screen.focused() }) - w.pie.data_list = { + awful.button({}, 1, function() + popup:get_widget().data_list = { {'used ' .. getPercentage(used + used_swap), used + used_swap}, {'free ' .. getPercentage(free + free_swap), free + free_swap}, {'buff_cache ' .. getPercentage(buff_cache), buff_cache} } - w.pie.display_labels = true - w.visible = not w.visible + + if popup.visible then + popup.visible = not popup.visible + else + popup:move_next_to(mouse.current_widget_geometry) + end end) ) ) - return ramgraph_widget end + return setmetatable(ramgraph_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/rhythmbox-widget/rhythmbox.lua b/rhythmbox-widget/rhythmbox.lua deleted file mode 100644 index 1287587..0000000 --- a/rhythmbox-widget/rhythmbox.lua +++ /dev/null @@ -1,16 +0,0 @@ -local wibox = require("wibox") -local awful = require("awful") -local watch = require("awful.widget.watch") - -rhythmbox_widget = wibox.widget.textbox() -rhythmbox_widget:set_font('Play 9') - -rhythmbox_icon = wibox.widget.imagebox() -rhythmbox_icon:set_image("/usr/share/icons/Arc/devices/22/audio-speakers.png") - -watch( - "rhythmbox-client --no-start --print-playing", 1, - function(widget, stdout, stderr, exitreason, exitcode) - rhythmbox_widget:set_text(stdout) - end -)
\ No newline at end of file diff --git a/run-shell-3/run-shell.lua b/run-shell-3/run-shell.lua index 9bd575b..0015232 100644 --- a/run-shell-3/run-shell.lua +++ b/run-shell-3/run-shell.lua @@ -8,10 +8,6 @@ -- @copyright 2019 Pavel Makhov ------------------------------------------------- -local capi = { - screen = screen, - client = client, -} local awful = require("awful") local gfs = require("gears.filesystem") local wibox = require("wibox") @@ -26,8 +22,10 @@ local widget = {} function widget.new() local widget_instance = { _cached_wiboxes = {}, - _cmd_pixelate = [[bash -c 'ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+%s,20 -vf frei0r=pixeliz0r -vframes 1 /tmp/i3lock-%s.png ; echo done']], - _cmd_blur = [[bash -c 'ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+%s,20 -filter_complex "boxblur=9" -vframes 1 /tmp/i3lock-%s.png ; echo done']] + _cmd_pixelate = [[sh -c 'ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+%s,20 -vf ]] + .. [[frei0r=pixeliz0r -vframes 1 /tmp/i3lock-%s.png ; echo done']], + _cmd_blur = [[sh -c 'ffmpeg -loglevel panic -f x11grab -video_size 1920x1060 -y -i :0.0+%s,20 ]] + .. [[-filter_complex "boxblur=9" -vframes 1 /tmp/i3lock-%s.png ; echo done']] } function widget_instance:_create_wibox() @@ -74,22 +72,19 @@ function widget.new() return w end - function widget_instance:launch(s, c) - c = c or capi.client.focus - s = mouse.screen - -- naughty.notify { text = 'screen ' .. s.index } + function widget_instance:launch() + local s = mouse.screen if not self._cached_wiboxes[s] then self._cached_wiboxes[s] = {} - -- naughty.notify { text = 'nope' } end if not self._cached_wiboxes[s][1] then self._cached_wiboxes[s][1] = self:_create_wibox() - -- naughty.notify { text = 'nope' } end local w = self._cached_wiboxes[s][1] local rnd = math.random() - awful.spawn.with_line_callback(string.format(self._cmd_blur, tostring(awful.screen.focused().geometry.x), rnd), { - stdout = function(line) + awful.spawn.with_line_callback( + string.format(self._cmd_blur, tostring(awful.screen.focused().geometry.x), rnd), { + stdout = function() w.visible = true w.bgimage = '/tmp/i3lock-' .. rnd ..'.png' awful.placement.top(w, { margins = { top = 20 }, parent = awful.screen.focused() }) diff --git a/run-shell/run-shell.lua b/run-shell/run-shell.lua index 2fda71b..a43c4d5 100644 --- a/run-shell/run-shell.lua +++ b/run-shell/run-shell.lua @@ -45,6 +45,7 @@ function widget.new() widget = wibox.widget.imagebox, resize = false, opacity = 0.2, + --luacheck:ignore 432 set_hover = function(self, opacity) self.opacity = opacity self.image = '/usr/share/icons/Arc/actions/symbolic/system-shutdown-symbolic.svg' diff --git a/spotify-widget/spotify.lua b/spotify-widget/spotify.lua index fb903e8..bd2309f 100644 --- a/spotify-widget/spotify.lua +++ b/spotify-widget/spotify.lua @@ -11,7 +11,6 @@ local awful = require("awful") local wibox = require("wibox") local watch = require("awful.widget.watch") -local naughty = require("naughty") local GET_SPOTIFY_STATUS_CMD = 'sp status' local GET_CURRENT_SONG_CMD = 'sp current' @@ -24,9 +23,9 @@ end local spotify_widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local play_icon = args.play_icon or '/usr/share/icons/Arc/actions/24/player_play.png' local pause_icon = args.pause_icon or '/usr/share/icons/Arc/actions/24/player_pause.png' @@ -100,7 +99,7 @@ local function worker(args) end local escaped = string.gsub(stdout, "&", '&') - local album, album_artist, artist, title = + local album, _, artist, title = string.match(escaped, 'Album%s*(.*)\nAlbumArtist%s*(.*)\nArtist%s*(.*)\nTitle%s*(.*)\n') if album ~= nil and title ~=nil and artist ~= nil then diff --git a/stackoverflow-widget/stackoverflow.lua b/stackoverflow-widget/stackoverflow.lua index af89105..15d2837 100644 --- a/stackoverflow-widget/stackoverflow.lua +++ b/stackoverflow-widget/stackoverflow.lua @@ -18,13 +18,15 @@ local beautiful = require("beautiful") local HOME_DIR = os.getenv("HOME") -local GET_QUESTIONS_CMD = [[bash -c "curl --compressed -s -X GET 'http://api.stackexchange.com/2.2/questions/no-answers?page=1&pagesize=%s&order=desc&sort=activity&tagged=%s&site=stackoverflow'"]] +local GET_QUESTIONS_CMD = [[bash -c "curl --compressed -s -X GET]] + .. [[ 'http://api.stackexchange.com/2.2/questions/no-answers]] + .. [[?page=1&pagesize=%s&order=desc&sort=activity&tagged=%s&site=stackoverflow'"]] local stackoverflow_widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local icon = args.icon or HOME_DIR .. '/.config/awesome/awesome-wm-widgets/stackoverflow-widget/so-icon.svg' local limit = args.limit or 5 @@ -43,7 +45,7 @@ local function worker(args) border_width = 1, border_color = beautiful.bg_focus, maximum_width = 400, - preferred_positions = top, + preferred_positions = 'top', offset = { y = 5 }, widget = {} } @@ -63,7 +65,7 @@ local function worker(args) end, } - local update_widget = function(widget, stdout, stderr, _, _) + local update_widget = function(_, stdout, _, _, _) local result = json.decode(stdout) @@ -91,7 +93,7 @@ local function worker(args) widget = wibox.container.background } - row:connect_signal("button::release", function(_, _, _, button) + row:connect_signal("button::release", function() spawn.with_shell("xdg-open " .. item.link) popup.visible = false end) diff --git a/todo-widget/todo.lua b/todo-widget/todo.lua index 71484b2..b8ce3cf 100644 --- a/todo-widget/todo.lua +++ b/todo-widget/todo.lua @@ -11,7 +11,6 @@ local awful = require("awful") local wibox = require("wibox") 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") @@ -24,7 +23,7 @@ local GET_TODO_ITEMS = 'bash -c "cat ' .. STORAGE .. '"' local rows = { layout = wibox.layout.fixed.vertical } local todo_widget = {} - +local update_widget todo_widget.widget = wibox.widget { { { @@ -89,7 +88,7 @@ local add_button = wibox.widget { widget = wibox.container.background } -add_button:connect_signal("button::press", function(c) +add_button:connect_signal("button::press", function() local pr = awful.widget.prompt() table.insert(rows, wibox.widget { @@ -116,7 +115,7 @@ add_button:connect_signal("button::press", function(c) local res = json.decode(stdout) table.insert(res.todo_items, {todo_item = input_text, status = false}) spawn.easy_async_with_shell("echo '" .. json.encode(res) .. "' > " .. STORAGE, function() - spawn.easy_async(GET_TODO_ITEMS, function(stdout) update_widget(stdout) end) + spawn.easy_async(GET_TODO_ITEMS, function(items) update_widget(items) end) end) end) end @@ -126,9 +125,9 @@ end) add_button:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end) add_button:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end) -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local icon = args.icon or WIDGET_DIR .. '/checkbox-checked-symbolic.svg' @@ -200,41 +199,41 @@ local function worker(args) widget = wibox.container.background } - trash_button:connect_signal("button::press", function(c) + trash_button:connect_signal("button::press", function() table.remove(result.todo_items, i) spawn.easy_async_with_shell("printf '" .. json.encode(result) .. "' > " .. STORAGE, function () - spawn.easy_async(GET_TODO_ITEMS, function(stdout) update_widget(stdout) end) + spawn.easy_async(GET_TODO_ITEMS, function(items) update_widget(items) end) end) end) local move_up = wibox.widget { - image = WIDGET_DIR .. '/up.png', + image = WIDGET_DIR .. '/chevron-up.svg', resize = false, widget = wibox.widget.imagebox } - move_up:connect_signal("button::press", function(c) + move_up:connect_signal("button::press", function() local temp = result.todo_items[i] result.todo_items[i] = result.todo_items[i-1] result.todo_items[i-1] = temp spawn.easy_async_with_shell("printf '" .. json.encode(result) .. "' > " .. STORAGE, function () - spawn.easy_async(GET_TODO_ITEMS, function(stdout) update_widget(stdout) end) + spawn.easy_async(GET_TODO_ITEMS, function(items) update_widget(items) end) end) end) local move_down = wibox.widget { - image = WIDGET_DIR .. '/down.png', + image = WIDGET_DIR .. '/chevron-down.svg', resize = false, widget = wibox.widget.imagebox } - move_down:connect_signal("button::press", function(c) + move_down:connect_signal("button::press", function() local temp = result.todo_items[i] result.todo_items[i] = result.todo_items[i+1] result.todo_items[i+1] = temp spawn.easy_async_with_shell("printf '" .. json.encode(result) .. "' > " .. STORAGE, function () - spawn.easy_async(GET_TODO_ITEMS, function(stdout) update_widget(stdout) end) + spawn.easy_async(GET_TODO_ITEMS, function(items) update_widget(items) end) end) end) @@ -243,13 +242,11 @@ local function worker(args) layout = wibox.layout.fixed.vertical } - if 1 == #result.todo_items then - -- one item, no need in arrows - elseif i == 1 then + if i == 1 and #result.todo_items > 1 then table.insert(move_buttons, move_down) - elseif i == #result.todo_items then + elseif i == #result.todo_items and #result.todo_items > 1 then table.insert(move_buttons, move_up) - else + elseif #result.todo_items > 1 then table.insert(move_buttons, move_up) table.insert(move_buttons, move_down) end @@ -322,7 +319,8 @@ local function worker(args) end if not gfs.file_readable(STORAGE) then - spawn.easy_async(string.format([[bash -c "dirname %s | xargs mkdir -p && echo '{\"todo_items\":{}}' > %s"]], STORAGE, STORAGE)) + spawn.easy_async(string.format([[bash -c "dirname %s | xargs mkdir -p && echo '{\"todo_items\":{}}' > %s"]], + STORAGE, STORAGE)) end return setmetatable(todo_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/translate-widget/README.MD b/translate-widget/README.MD index 2c783a0..a82fda7 100644 --- a/translate-widget/README.MD +++ b/translate-widget/README.MD @@ -1,6 +1,6 @@ # Translate Widget -This widget allows quickly translate words or phrases without opening a browser - just using Awesome. To provide direction of the translation add the 2 letters code of the source and target languages at the end of the phrase, for example _hello enfr_ will translate _hello_ from English to French. This widget is based on [Yandex.Translate API](https://tech.yandex.com/translate/). +This widget allows quickly translate words or phrases without opening a browser - just using Awesome. To provide direction of the translation add the 2 letters code of the source and target languages at the end of the phrase, for example _hello enfr_ will translate _hello_ from English to French. This widget is based on [Watson Language Translator](https://www.ibm.com/watson/services/language-translator/) from IBM. ![demo](./demo.gif) @@ -13,7 +13,8 @@ This widget allows quickly translate words or phrases without opening a browser ## Installation 1. Clone repo under **~/.config/awesome/** -1. Get an [API key](https://translate.yandex.com/developers/keys) +1. Create an IBM Cloud API key at [cloud.ibm.com/iam/apikeys](https://cloud.ibm.com/iam/apikeys) +1. Copy a service URL by going to [resource list](https://cloud.ibm.com/resources), then under "Services" select "Language Translator" option, and then copy URL from the "Credentials" section 1. Require widget in **rc.lua**: ```lua @@ -23,8 +24,15 @@ This widget allows quickly translate words or phrases without opening a browser 1. Add a shortcut to run translate prompt: ```lua - awful.key({ modkey }, "c", - function() translate.show_translate_prompt('<api-key>') end, - { description = "run translate prompt", group = "launcher" }), - ``` + awful.key({ modkey }, "c", function() + translate.launch{api_key = '<api-key>', url = 'url'} + end, { description = "run translate prompt", group = "launcher" }) + ``` + + + + + + + diff --git a/translate-widget/translate.lua b/translate-widget/translate.lua index 9352ac9..1499333 100644 --- a/translate-widget/translate.lua +++ b/translate-widget/translate.lua @@ -16,7 +16,8 @@ local wibox = require("wibox") local gears = require("gears") local gfs = require("gears.filesystem") -local TRANSLATE_CMD = [[bash -c 'curl -s -u "apikey:%s" -H "Content-Type: application/json" -d '\''{"text": ["%s"], "model_id":"%s"}'\'' "%s/v3/translate?version=2018-05-01"']] +local TRANSLATE_CMD = [[bash -c 'curl -s -u "apikey:%s" -H "Content-Type: application/json"]] + ..[[ -d '\''{"text": ["%s"], "model_id":"%s"}'\'' "%s/v3/translate?version=2018-05-01"']] local ICON = os.getenv("HOME") .. '/.config/awesome/awesome-wm-widgets/translate-widget/gnome-translate.svg' --- Returns two values - string to translate and direction: @@ -82,12 +83,14 @@ local function translate(to_translate, lang, api_key, url) { { id = 'src', - markup = '<b>' .. lang:sub(1,2) .. '</b>: <span color="#FFFFFF"> ' .. to_translate .. '</span>', + markup = '<b>' .. lang:sub(1,2) .. '</b>: <span color="#FFFFFF"> ' + .. to_translate .. '</span>', widget = wibox.widget.textbox }, { id = 'res', - markup = '<b>' .. lang:sub(4) .. '</b>: <span color="#FFFFFF"> ' .. resp.translations[1].translation .. '</span>', + markup = '<b>' .. lang:sub(4) .. '</b>: <span color="#FFFFFF"> ' + .. resp.translations[1].translation .. '</span>', widget = wibox.widget.textbox }, id = 'text', @@ -110,11 +113,11 @@ local function translate(to_translate, lang, api_key, url) w:buttons( awful.util.table.join( awful.button({}, 1, function() - awful.spawn.with_shell("echo '" .. resp.translations[1].translation .. "' | xclip -selection clipboard") + spawn.with_shell("echo '" .. resp.translations[1].translation .. "' | xclip -selection clipboard") w.visible = false end), awful.button({}, 3, function() - awful.spawn.with_shell("echo '" .. to_translate .."' | xclip -selection clipboard") + spawn.with_shell("echo '" .. to_translate .."' | xclip -selection clipboard") w.visible = false end) ) @@ -159,9 +162,9 @@ input_widget:setup{ widget = wibox.container.margin } -local function launch(args) +local function launch(user_args) - local args = args or {} + local args = user_args or {} local api_key = args.api_key local url = args.url diff --git a/volume-widget/volume.lua b/volume-widget/volume.lua index 0e13f38..cb8c21d 100644 --- a/volume-widget/volume.lua +++ b/volume-widget/volume.lua @@ -9,7 +9,6 @@ ------------------------------------------------- local wibox = require("wibox") -local watch = require("awful.widget.watch") local spawn = require("awful.spawn") local naughty = require("naughty") local gfs = require("gears.filesystem") @@ -19,7 +18,13 @@ local PATH_TO_ICONS = "/usr/share/icons/Arc/status/symbolic/" local volume_icon_name="audio-volume-high-symbolic" local GET_VOLUME_CMD = 'amixer sget Master' -local volume = {device = '', display_notification = false, display_notification_onClick = true, notification = nil, delta = 5} +local volume = { + device = '', + display_notification = false, + display_notification_onClick = true, + notification = nil, + delta = 5 +} function volume:toggle() volume:_cmd('amixer ' .. volume.device .. ' sset Master toggle') @@ -88,9 +93,9 @@ end --}}} -local function worker(args) +local function worker(user_args) --{{{ Args - local args = args or {} + local args = user_args or {} local volume_audio_controller = args.volume_audio_controller or 'pulse' volume.display_notification = args.display_notification or false @@ -120,7 +125,8 @@ local function worker(args) resize = false, widget = wibox.widget.imagebox, }, - layout = wibox.container.margin(_, _, _, 3), + margins = 3, + layout = wibox.container.margin, set_image = function(self, path) self.icon.image = path end @@ -136,7 +142,7 @@ local function worker(args) local function show() spawn.easy_async(GET_VOLUME_CMD, function(stdout, _, _, _) - txt = parse_output(stdout) + local txt = parse_output(stdout) notif(txt, true) end ) @@ -165,7 +171,7 @@ local function worker(args) --}}} --{{{ Set initial icon - spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode) + spawn.easy_async(GET_VOLUME_CMD, function(stdout) parse_output(stdout) volume.widget.image = PATH_TO_ICONS .. volume_icon_name .. ".svg" end) diff --git a/volumearc-widget/volumearc.lua b/volumearc-widget/volumearc.lua index 91ae763..86f3a14 100644 --- a/volumearc-widget/volumearc.lua +++ b/volumearc-widget/volumearc.lua @@ -13,6 +13,7 @@ local beautiful = require("beautiful") local spawn = require("awful.spawn") local watch = require("awful.widget.watch") local wibox = require("wibox") +local gears = require("gears") local GET_VOLUME_CMD = 'amixer -D pulse sget Master' local INC_VOLUME_CMD = 'amixer -q -D pulse sset Master 5%+' @@ -23,16 +24,30 @@ local PATH_TO_ICON = "/usr/share/icons/Arc/status/symbolic/audio-volume-muted-sy local widget = {} -local function worker(args) - - local args = args or {} +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 rows = { + { widget = wibox.widget.textbox }, + layout = wibox.layout.fixed.vertical, +} +local function worker(user_args) + + local args = user_args or {} local main_color = args.main_color or beautiful.fg_color local bg_color = args.bg_color or '#ffffff11' local mute_color = args.mute_color or beautiful.fg_urgent local path_to_icon = args.path_to_icon or PATH_TO_ICON local thickness = args.thickness or 2 - local height = args.height or 18 + local margins = args.height or 18 local timeout = args.timeout or 1 local get_volume_cmd = args.get_volume_cmd or GET_VOLUME_CMD @@ -52,14 +67,14 @@ local function worker(args) max_value = 1, thickness = thickness, start_angle = 4.71238898, -- 2pi*3/4 - forced_height = height, - forced_width = height, + forced_height = margins, + forced_width = margins, bg = bg_color, paddings = 2, widget = wibox.container.arcchart } - local update_graphic = function(widget, stdout, _, _, _) + local update_graphic = function(_, stdout, _, _, _) local mute = string.match(stdout, "%[(o%D%D?)%]") -- \[(o\D\D?)\] - [on] or [off] local volume = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%) volume = tonumber(string.format("% 3d", volume)) @@ -70,7 +85,7 @@ local function worker(args) or { main_color } end - local button_press = args.button_press or function(_, _, _, button) + local button_press = args.button_press or function(_, _, _, button) if (button == 4) then awful.spawn(inc_volume_cmd, false) elseif (button == 5) then awful.spawn(dec_volume_cmd, false) elseif (button == 1) then awful.spawn(tog_volume_cmd, false) @@ -82,6 +97,38 @@ local function worker(args) end volumearc:connect_signal("button::press", button_press) + local rebuild_widget = function(stdout, stderr) + for i = 0, #rows do rows[i]=nil end + + for line in stdout:gmatch("[^\r\n]+") do + + local row = wibox.widget { + text = line, + widget = wibox.widget.textbox + } + table.insert(rows, row) + end + + popup:setup(rows) + end + + volumearc:buttons( + awful.util.table.join( + awful.button({}, 3, function() + if popup.visible then + popup.visible = not popup.visible + else + spawn.easy_async([[bash -c "cat /proc/asound/cards"]], function(stdout, stderr) + rebuild_widget(stdout, stderr) + popup:move_next_to(mouse.current_widget_geometry) + end) + end + end) + ) + ) + + + watch(get_volume_cmd, timeout, update_graphic, volumearc) return volumearc diff --git a/volumebar-widget/volumebar.lua b/volumebar-widget/volumebar.lua index 19238de..e7ee64d 100644 --- a/volumebar-widget/volumebar.lua +++ b/volumebar-widget/volumebar.lua @@ -22,9 +22,9 @@ local TOG_VOLUME_CMD = 'amixer -D pulse sset Master toggle' local widget = {} -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} local main_color = args.main_color or beautiful.fg_normal local mute_color = args.mute_color or beautiful.fg_urgent @@ -52,7 +52,7 @@ local function worker(args) widget = wibox.widget.progressbar } - local update_graphic = function(widget, stdout, _, _, _) + local update_graphic = function(_, stdout, _, _, _) local mute = string.match(stdout, "%[(o%D%D?)%]") -- \[(o\D\D?)\] - [on] or [off] local volume = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%) volume = tonumber(string.format("% 3d", volume)) diff --git a/weather-widget/weather.lua b/weather-widget/weather.lua index 0317746..e58efb1 100644 --- a/weather-widget/weather.lua +++ b/weather-widget/weather.lua @@ -27,7 +27,6 @@ end local weather_widget = {} local warning_shown = false -local notification local tooltip = awful.tooltip { mode = 'outside', preferred_positions = {'bottom'} @@ -115,9 +114,9 @@ local function uvi_index_color(uvi) return '<span weight="bold" foreground="' .. color .. '">' .. uvi .. '</span>' end -local function worker(args) +local function worker(user_args) - local args = args or {} + local args = user_args or {} --- Validate required parameters if args.coordinates == nil or args.api_key == nil then @@ -139,6 +138,7 @@ local function worker(args) local icons_extension = args.icons_extension or '.png' local timeout = args.timeout or 120 + local ICONS_DIR = WIDGET_DIR .. '/icons/' .. icon_pack_name .. '/' local owm_one_cal_api = ('https://api.openweathermap.org/data/2.5/onecall' .. '?lat=' .. coordinates[1] .. '&lon=' .. coordinates[2] .. '&appid=' .. api_key .. @@ -241,11 +241,14 @@ local function worker(args) forced_width = 300, layout = wibox.layout.flex.horizontal, update = function(self, weather) - self:get_children_by_id('icon')[1]:set_image(WIDGET_DIR .. '/icons/' .. icon_pack_name .. '/' .. icon_map[weather.weather[1].icon] .. icons_extension) + self:get_children_by_id('icon')[1]:set_image( + ICONS_DIR .. icon_map[weather.weather[1].icon] .. icons_extension) self:get_children_by_id('temp')[1]:set_text(gen_temperature_str(weather.temp, '%.0f', false, units)) - self:get_children_by_id('feels_like_temp')[1]:set_text('Feels like ' .. gen_temperature_str(weather.feels_like, '%.0f', false, units)) + self:get_children_by_id('feels_like_temp')[1]:set_text( + 'Feels like ' .. gen_temperature_str(weather.feels_like, '%.0f', false, units)) self:get_children_by_id('description')[1]:set_text(weather.weather[1].description) - self:get_children_by_id('wind')[1]:set_markup('Wind: <b>' .. weather.wind_speed .. 'm/s (' .. to_direction(weather.wind_deg) .. ')</b>') + self:get_children_by_id('wind')[1]:set_markup( + 'Wind: <b>' .. weather.wind_speed .. 'm/s (' .. to_direction(weather.wind_deg) .. ')</b>') self:get_children_by_id('humidity')[1]:set_markup('Humidity: <b>' .. weather.humidity .. '%</b>') self:get_children_by_id('uv')[1]:set_markup('UV: ' .. uvi_index_color(weather.uvi)) end @@ -270,7 +273,7 @@ local function worker(args) { { { - image = WIDGET_DIR .. '/icons/' .. icon_pack_name .. '/' .. icon_map[day.weather[1].icon] .. icons_extension, + image = ICONS_DIR .. icon_map[day.weather[1].icon] .. icons_extension, resize = true, forced_width = 48, forced_height = 48, @@ -384,7 +387,7 @@ local function worker(args) hourly_forecast_negative_graph:set_max_value(math.abs(min_temp)) hourly_forecast_negative_graph:set_min_value(max_temp < 0 and math.abs(max_temp) * 0.7 or 0) - for i, value in ipairs(values) do + for _, value in ipairs(values) do if value >= 0 then hourly_forecast_graph:add_value(value) hourly_forecast_negative_graph:add_value(0) @@ -470,12 +473,9 @@ local function worker(args) local function update_widget(widget, stdout, stderr) if stderr ~= '' then if not warning_shown then - if ( - stderr ~= 'curl: (52) Empty reply from server' and - stderr ~= 'curl: (28) Failed to connect to api.openweathermap.org port 443: Connection timed out' and - stderr:find( - '^curl: %(18%) transfer closed with %d+ bytes remaining to read$' - ) ~= nil + if (stderr ~= 'curl: (52) Empty reply from server' + and stderr ~= 'curl: (28) Failed to connect to api.openweathermap.org port 443: Connection timed out' + and stderr:find('^curl: %(18%) transfer closed with %d+ bytes remaining to read$') ~= nil ) then show_warning(stderr) end @@ -494,7 +494,7 @@ local function worker(args) local result = json.decode(stdout) - widget:set_image(WIDGET_DIR .. '/icons/' .. icon_pack_name .. '/' .. icon_map[result.current.weather[1].icon] .. icons_extension) + widget:set_image(ICONS_DIR .. icon_map[result.current.weather[1].icon] .. icons_extension) widget:set_text(gen_temperature_str(result.current.temp, '%.0f', both_units_widget, units)) current_weather_widget:update(result.current) diff --git a/word-clock-widget/README.md b/word-clock-widget/README.md new file mode 100644 index 0000000..9bf1032 --- /dev/null +++ b/word-clock-widget/README.md @@ -0,0 +1,74 @@ +# word clock widget + +Widget displaying current time using words: + +![screenshot](./screenshots/halfpastthree.png) + +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| main_color | `beautiful.fg_normal` | Color of the word on odd position | +| accent_color | `beautiful.fg_urgent` | Color of the word on even position | +| font | `beautiful.font` | Font (`Play 20`) | +| is_human_readable | `false` | _nine fifteen_ or _fifteen past nine_ | +| military_time | `false` | 12 or 24 time format | +| with_spaces | `false` | Separate words with spaces | + +## Installation + +Clone repo, include widget and use it in **rc.lua**: + +```lua +local word_clock = require("awesome-wm-widgets.word-clock-widget.word-clock") +... +s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + ... + word_clock(), + ... +``` + +# Screenshots + +```lua + word_clock{ + font = 'Carter One 12', + accent_color = '#ff79c6', + main_color = '#8be9fd', + is_human_readable = true, +} +``` +![](./screenshots/halfpastthree_color.png) + + +```lua +word_clock{ + font = 'Carter One 12', + is_human_readable = true, +} +``` +![](./screenshots/twentythreepastnine.png) + + +```lua +word_clock{ + font = 'Carter One 12', + is_human_readable = true, + military_time = true +} +``` +![](./screenshots/twentythreepasttwentyone.png) + + +```lua +word_clock{ + font = 'Carter One 12', + accent_color = '#f00', + main_color = '#0f0', +} +``` +![](./screenshots/onetwentyseven.png) diff --git a/word-clock-widget/screenshots/halfpastthree.png b/word-clock-widget/screenshots/halfpastthree.png Binary files differnew file mode 100644 index 0000000..af9e0d9 --- /dev/null +++ b/word-clock-widget/screenshots/halfpastthree.png diff --git a/word-clock-widget/screenshots/halfpastthree_color.png b/word-clock-widget/screenshots/halfpastthree_color.png Binary files differnew file mode 100644 index 0000000..3c2cdd7 --- /dev/null +++ b/word-clock-widget/screenshots/halfpastthree_color.png diff --git a/word-clock-widget/screenshots/onetwentyseven.png b/word-clock-widget/screenshots/onetwentyseven.png Binary files differnew file mode 100644 index 0000000..08e852c --- /dev/null +++ b/word-clock-widget/screenshots/onetwentyseven.png diff --git a/word-clock-widget/screenshots/testpasttwentyone.png b/word-clock-widget/screenshots/testpasttwentyone.png Binary files differnew file mode 100644 index 0000000..41d266f --- /dev/null +++ b/word-clock-widget/screenshots/testpasttwentyone.png diff --git a/word-clock-widget/screenshots/twentythreepastnine.png b/word-clock-widget/screenshots/twentythreepastnine.png Binary files differnew file mode 100644 index 0000000..7d18e22 --- /dev/null +++ b/word-clock-widget/screenshots/twentythreepastnine.png diff --git a/word-clock-widget/screenshots/twentythreepasttwentyone.png b/word-clock-widget/screenshots/twentythreepasttwentyone.png Binary files differnew file mode 100644 index 0000000..8a8218f --- /dev/null +++ b/word-clock-widget/screenshots/twentythreepasttwentyone.png diff --git a/word-clock-widget/word-clock.lua b/word-clock-widget/word-clock.lua new file mode 100644 index 0000000..12d5d83 --- /dev/null +++ b/word-clock-widget/word-clock.lua @@ -0,0 +1,140 @@ +------------------------------------------------- +-- Text Clock Widget for Awesome Window Manager +-- Shows current time in words, e.g. 11.54 -> eleven fifty four +-- More details could be found here: +-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/text-clock-widget + +-- @author Pavel Makhov +-- @copyright 2020 Pavel Makhov +------------------------------------------------- + +local wibox = require("wibox") +local beautiful = require("beautiful") +local gears = require("gears") + +local function tablelength(T) + local count = 0 + for _ in pairs(T) do count = count + 1 end + return count +end + +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 + +local function convertNumberToName(num) + local lowNames = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", + "eighteen", "nineteen"}; + local tensNames = {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"} + local tens, ones, result + + if num < tablelength(lowNames) then + result = lowNames[num + 1]; + else + tens = math.floor(num / 10); + ones = num % 10; + if (tens <= 9) then + result = tensNames[tens - 2 + 1]; + if (ones > 0) then + result = result .. " " .. lowNames[ones + 1]; + end + else + result = "unknown" + end + end + return result; +end + +local text_clock = {} + +local function worker(user_args) + + local args = user_args or {} + + local main_color = args.main_color or beautiful.fg_normal + local accent_color = args.accent_color or beautiful.fg_urgent + local font = args.font or beautiful.font + local is_human_readable = args.is_human_readable + local military_time = args.military_time + local with_spaces = args.with_spaces + + if military_time == nil then military_time = false end + if with_spaces == nil then with_spaces = false end + if is_human_readable == nil then is_human_readable = false end + + text_clock = wibox.widget { + { + id = 'clock', + font = font, + widget = wibox.widget.textbox, + }, + layout = wibox.layout.align.horizontal, + set_text = function(self, time) + local t = split(time) + local res = '' + for i, v in ipairs(t) do + res = res .. '<span color="' + .. ((i % 2 == 0) and accent_color or main_color) + .. '">' .. v .. '</span>' + .. (with_spaces and ' ' or '') + end + self:get_children_by_id('clock')[1]:set_markup(res) + end + } + + gears.timer { + timeout = 1, + call_now = true, + autostart = true, + callback = function() + local time = os.date((military_time and '%H' or '%I') .. ':%M') + local h,m = time:match('(%d+):(%d+)') + local min = tonumber(m) + local hour = tonumber(h) + + if is_human_readable then + + if min == 0 then + text_clock:set_text(convertNumberToName(hour) .. " o'clock") + else + local mm + if min == 15 or min == 45 then + mm = 'quater' + elseif min == 30 then + mm = 'half' + else + mm = convertNumberToName((min < 31) and min or 60 - min) + end + + local to_past + + if min < 31 then + to_past = 'past' + else + to_past = 'to' + hour = hour + 1 + end + + text_clock:set_text(mm .. ' ' .. to_past .. ' ' .. convertNumberToName(hour)) + end + else + text_clock:set_text(convertNumberToName(hour) .. ' ' .. convertNumberToName(min)) + end + end + } + + return text_clock + +end + +return setmetatable(text_clock, { __call = function(_, ...) + return worker(...) +end })
\ No newline at end of file |