diff options
author | Pavel Makhov <pmakhov@theoctavegroup.com> | 2019-09-17 15:29:36 -0400 |
---|---|---|
committer | Pavel Makhov <pmakhov@theoctavegroup.com> | 2019-09-17 15:29:36 -0400 |
commit | 6fd76c254b296da86619b43db619ccebcd521853 (patch) | |
tree | a005c8045bbee2998642c55fd5edadb258ea87de | |
parent | 372ae3c9e7cab4b64b8dcaf31d9d2d921a723585 (diff) | |
parent | 2e211937a116102c3647b85070718102192ddc54 (diff) |
Merge branch '74-externalize-config'
Note: breaking change, now widgets should be created with parentheses, i.e. battery(), instead of battery. Read more in README of the widget.
28 files changed, 1207 insertions, 685 deletions
diff --git a/battery-widget/battery.lua b/battery-widget/battery.lua index 6d9f086..aa3623d 100644 --- a/battery-widget/battery.lua +++ b/battery-widget/battery.lua @@ -109,7 +109,7 @@ watch("acpi -i", 10, batteryType = "battery-empty%s-symbolic" if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then -- if 5 minutes have elapsed since the last warning - last_battery_check = time() + last_battery_check = os.time() show_battery_warning() end diff --git a/batteryarc-widget/README.md b/batteryarc-widget/README.md index cb73e09..026180e 100644 --- a/batteryarc-widget/README.md +++ b/batteryarc-widget/README.md @@ -11,18 +11,27 @@ Depending of the battery status it could look following ways: - ![80_d](./80_d.png) - more than 40 percent - ![80_c](./80_c.png) - more than 40 percent, charging -Widget uses following beautiful variables with values: +If a battery level is low then warning popup will show up: -```lua -theme.widget_main_color = "#74aeab" -theme.widget_red = "#e53935" -theme.widget_yellow = "#c0ca33" -theme.widget_green = "#43a047" -theme.widget_black = "#000000" -theme.widget_transparent = "#00000000" -``` +![warning](./warning.png) + +## Customization -which means that you need to copy the code above and paste it in your **theme.lua**. Otherwise you can change colors directly in the widget. +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `font` | Font | Play 6 | +| `arc_thickness` | 2 | Thickness of the arc | +| `show_current_level`| false | Show current charge level | +| `main_color` | `beautiful.fg_color` | Color of the text with the current charge level and the arc | +| `low_level_color` | #e53935 | Arc color when battery charge is less that 15% | +| `medium_level_color` | #c0ca33 | Arc color when battery charge is between 15% and 40% | +| `charging` | `beautiful.fg_color` | Color of the circle inside the arc when charging | +| `warning_msg_title` | _Huston, we have a problem_ | Title of the warning popup | +| `warning_msg_text` | _Battery is dying_ | Text of the warning popup | +| `warning_msg_position` | `bottom_right` | Position of the warning popup | +| `warning_msg_icon` | ~/.config/awesome/awesome-wm-widgets/batteryarc-widget/spaceman.jpg | Icon of the warning popup | ## Installation @@ -35,11 +44,17 @@ s.mytasklist, -- Middle widget { -- Right widgets layout = wibox.layout.fixed.horizontal, ... - batteryarc_widget, - ... + --[[default]] + batteryarc_widget(), + --[[or customized]] + batteryarc_widget({ + show_current_level = true, + thickness = '1', + }), + } + ... ``` -You can get the icon for warning popup [here](https://vk.com/images/stickers/1933/512.png) ## Troubleshooting -In case of any doubts or questions don't hesitate to raise an [issue](https://github.com/streetturtle/awesome-wm-widgets/issues/new). +In case of any doubts or questions please raise an [issue](https://github.com/streetturtle/awesome-wm-widgets/issues/new). diff --git a/batteryarc-widget/batteryarc.lua b/batteryarc-widget/batteryarc.lua index a15151f..7a7109f 100644 --- a/batteryarc-widget/batteryarc.lua +++ b/batteryarc-widget/batteryarc.lua @@ -16,151 +16,185 @@ local watch = require("awful.widget.watch") local HOME = os.getenv("HOME") -local text = wibox.widget { - id = "txt", - font = "Play 6", - align = 'center', -- align the text - valign = 'center', - widget = wibox.widget.textbox -} - -local text_with_background = wibox.container.background(text) - -local batteryarc = wibox.widget { - text_with_background, - max_value = 1, - rounded_edge = true, - thickness = 2, - start_angle = 4.71238898, -- 2pi*3/4 - forced_height = 18, - forced_width = 18, - bg = "#ffffff11", - paddings = 2, - widget = wibox.container.arcchart, - set_value = function(self, value) - self.value = value - end, -} - -local last_battery_check = os.time() - -watch("acpi -i", 10, - function(widget, stdout) - local batteryType - - local battery_info = {} - local capacities = {} - for s in stdout:gmatch("[^\r\n]+") do - local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*') - if string.match(s, 'rate information') then - -- ignore such line - elseif status ~= nil then - table.insert(battery_info, {status = status, charge = tonumber(charge_str)}) +local widget = {} + +local function worker(args) + + local args = args or {} + + local font = args.font or 'Play 6' + local arc_thickness = args.thickness or 2 + local show_current_level = args.show_current_level or false + + local main_color = args.main_color or beautiful.fg_color + local low_level_color = args.low_level_color or '#e53935' + local medium_level_color = args.medium_level_color or '#c0ca33' + local charging_color = args.charging_color or '#43a047' + + local warning_msg_title = args.warning_msg_title or '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 text = wibox.widget { + id = "txt", + font = font, + align = 'center', -- align the text + valign = 'center', + widget = wibox.widget.textbox + } + + local text_with_background = wibox.container.background(text) + + widget = wibox.widget { + text_with_background, + max_value = 1, + rounded_edge = true, + thickness = arc_thickness, + start_angle = 4.71238898, -- 2pi*3/4 + forced_height = 18, + forced_width = 18, + bg = "#ffffff11", + paddings = 2, + widget = wibox.container.arcchart, + set_value = function(self, value) + self.value = value + end, + } + + local last_battery_check = os.time() + + watch("acpi -i", 10, + function(widget, stdout) + local batteryType + + local battery_info = {} + local capacities = {} + for s in stdout:gmatch("[^\r\n]+") do + local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*') + if string.match(s, 'rate information') then + -- ignore such line + elseif status ~= nil then + table.insert(battery_info, { status = status, charge = tonumber(charge_str) }) + else + local cap_str = string.match(s, '.+:.+last full capacity (%d+)') + table.insert(capacities, tonumber(cap_str)) + end + end + + local capacity = 0 + for i, cap in ipairs(capacities) do + capacity = capacity + cap + end + + local charge = 0 + local status + for i, batt in ipairs(battery_info) do + if batt.charge >= charge then + -- use most charged battery status. This is arbitrary, and maybe another metric should be used + status = batt.status + end + + charge = charge + batt.charge * capacities[i] + end + + local charge_percentage + if capacity > 5 then + charge = charge / capacity + charge_percentage = charge / 100 + else + -- when widget.value is < 0.04, the widget shows a full circle (as widget.value=1) + charge_percentage = 0.05 + end + + widget.value = charge / 100 + + if status == 'Charging' then + text_with_background.bg = charging_color + text_with_background.fg = '#000000' else - local cap_str = string.match(s, '.+:.+last full capacity (%d+)') - table.insert(capacities, tonumber(cap_str)) + text_with_background.bg = '#00000000' + text_with_background.fg = main_color end - end - - local capacity = 0 - for i, cap in ipairs(capacities) do - capacity = capacity + cap - end - - local charge = 0 - local status - for i, batt in ipairs(battery_info) do - if batt.charge >= charge then - -- use most charged battery status. This is arbitrary, and maybe another metric should be used - status = batt.status + + if show_current_level == true then + --- if battery is fully charged (100) there is not enough place for three digits, so we don't show any text + text.text = charge == 100 + and '' + or string.format('%d', charge) + else + text.text = '' end - charge = charge + batt.charge * capacities[i] - end - - local charge_percentage - if capacity > 5 then - charge = charge / capacity - charge_percentage = charge / 100 - else - -- when widget.value is < 0.04, the widget shows a full circle (as widget.value=1) - charge_percentage = 0.05 - end - - widget.value = charge / 100 - - if status == 'Charging' then - text_with_background.bg = beautiful.widget_green - text_with_background.fg = beautiful.widget_black - else - text_with_background.bg = beautiful.widget_transparent - text_with_background.fg = beautiful.widget_main_color - end - - --- if battery is fully charged (100) there is not enough place for three digits, so we don't show any text - text.text = charge == 100 - and '' - or string.format('%d', charge) - - if charge < 15 then - batteryarc.colors = { beautiful.widget_red } - if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then - -- if 5 minutes have elapsed since the last warning - last_battery_check = os.time() - - show_battery_warning() + if charge < 15 then + widget.colors = { low_level_color } + if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then + -- if 5 minutes have elapsed since the last warning + last_battery_check = os.time() + + show_battery_warning() + end + elseif charge > 15 and charge < 40 then + widget.colors = { medium_level_color } + else + widget.colors = { main_color } end - elseif charge > 15 and charge < 40 then - batteryarc.colors = { beautiful.widget_yellow } - else - batteryarc.colors = { beautiful.widget_main_color } - end - end, - batteryarc) - --- Popup with battery info --- One way of creating a pop-up notification - naughty.notify -local notification -function show_battery_status() - awful.spawn.easy_async([[bash -c 'acpi']], - function(stdout, _, _, _) - naughty.destroy(notification) - notification = naughty.notify { - text = stdout, - title = "Battery status", - timeout = 5, - hover_timeout = 0.5, - width = 200, - } - end) -end + end, + widget) + + -- Popup with battery info + -- One way of creating a pop-up notification - naughty.notify + local notification + function show_battery_status() + awful.spawn.easy_async([[bash -c 'acpi']], + function(stdout, _, _, _) + naughty.destroy(notification) + notification = naughty.notify { + 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) + + -- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one + + --battery_popup = awful.tooltip({objects = {battery_widget}}) + + -- To use colors from beautiful theme put + -- following lines in rc.lua before require("battery"): + -- beautiful.tooltip_fg = beautiful.fg_normal + -- beautiful.tooltip_bg = beautiful.bg_normal + + --[[ Show warning notification ]] + function show_battery_warning() + naughty.notify { + icon = 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 + + return widget -batteryarc:connect_signal("mouse::enter", function() show_battery_status() end) -batteryarc:connect_signal("mouse::leave", function() naughty.destroy(notification) end) - --- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one - ---battery_popup = awful.tooltip({objects = {battery_widget}}) - --- To use colors from beautiful theme put --- following lines in rc.lua before require("battery"): --- beautiful.tooltip_fg = beautiful.fg_normal --- beautiful.tooltip_bg = beautiful.bg_normal - ---[[ Show warning notification ]] -function show_battery_warning() - naughty.notify { - icon = HOME .. "/.config/awesome/awesome-wm-widgets/batteryarc-widget/spaceman.jpg", - icon_size = 100, - text = "Battery is dying", -- switch text and title - title = "Huston, we have a problem", - timeout = 25, -- show the warning for a longer time - hover_timeout = 0.5, - position = "bottom_right", - bg = "#F06060", - fg = "#EEE9EF", - width = 300, - } end -return batteryarc +return setmetatable(widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/batteryarc-widget/warning.png b/batteryarc-widget/warning.png Binary files differnew file mode 100644 index 0000000..55ca790 --- /dev/null +++ b/batteryarc-widget/warning.png diff --git a/brightness-widget/README.md b/brightness-widget/README.md index 5d592b6..7b05d2f 100644 --- a/brightness-widget/README.md +++ b/brightness-widget/README.md @@ -2,6 +2,29 @@ This widget represents current brightness level: ![Brightness widget](./br-wid-1.png) +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `get_brightness_cmd` | `light -G` | Get current screen brightness | +| `inc_brightness_cmd` | `light -A 5` | Increase brightness | +| `dec_brightness_cmd` | `light -U 5`| Decrease brightness | +| `path_to_icon` | `/usr/share/icons/Arc/status/symbolic/display-brightness-symbolic.svg` | Path to the icon | +| `font` | `Play 9` | Font | + +### Example: + +```lua +brightness_widget({ + get_brightness_cmd = 'xbacklight -get', + inc_brightness_cmd = 'xbacklight -inc 5', + dec_brightness_cmd = 'xbacklight -dec 5' +}) +``` + + ## Installation First you need to get the current brightness level. There are two options: @@ -29,8 +52,6 @@ First you need to get the current brightness level. There are two options: 49.18 ``` -Depending on the chosen option change `GET_BRIGHTNESS_CMD` variable in **brightness.lua**. - Then clone this repo under **~/.config/awesome/**: ```bash @@ -50,7 +71,15 @@ s.mytasklist, -- Middle widget { -- Right widgets layout = wibox.layout.fixed.horizontal, ... - brightness_widget, + -- default + brightness_widget(), + -- or customized + brightness_widget({ + get_brightness_cmd = 'xbacklight -get', + inc_brightness_cmd = 'xbacklight -inc 5', + dec_brightness_cmd = 'xbacklight -dec 5' + }) + } ... ``` diff --git a/brightness-widget/brightness.lua b/brightness-widget/brightness.lua index 075765c..28e7015 100644 --- a/brightness-widget/brightness.lua +++ b/brightness-widget/brightness.lua @@ -5,7 +5,7 @@ -- https://github.com/streetturtle/awesome-wm-widgets/tree/master/brightness-widget -- @author Pavel Makhov --- @copyright 2017 Pavel Makhov +-- @copyright 2017-2019 Pavel Makhov ------------------------------------------------- local wibox = require("wibox") @@ -17,36 +17,55 @@ 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 brightness_text = wibox.widget.textbox() -brightness_text:set_font('Play 9') - -local brightness_icon = wibox.widget { - { - image = PATH_TO_ICON, - resize = false, - widget = wibox.widget.imagebox, - }, - top = 3, - widget = wibox.container.margin -} - -local brightness_widget = wibox.widget { - brightness_icon, - brightness_text, - layout = wibox.layout.fixed.horizontal, -} - -local update_widget = function(widget, stdout, stderr, exitreason, exitcode) - local brightness_level = tonumber(string.format("%.0f", stdout)) - widget:set_text(" " .. brightness_level .. "%") -end, - -brightness_widget:connect_signal("button::press", function(_,_,_,button) - if (button == 4) then spawn(INC_BRIGHTNESS_CMD, false) - elseif (button == 5) then spawn(DEC_BRIGHTNESS_CMD, false) - end -end) - -watch(GET_BRIGHTNESS_CMD, 1, update_widget, brightness_text) - -return brightness_widget +local widget = {} + +local function worker(args) + + local args = 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 + local dec_brightness_cmd = args.dec_brightness_cmd or DEC_BRIGHTNESS_CMD + local path_to_icon = args.path_to_icon or PATH_TO_ICON + local font = args.font or 'Play 9' + + local brightness_text = wibox.widget.textbox() + brightness_text:set_font(font) + + local brightness_icon = wibox.widget { + { + image = path_to_icon, + resize = false, + widget = wibox.widget.imagebox, + }, + top = 3, + widget = wibox.container.margin + } + + widget = wibox.widget { + brightness_icon, + brightness_text, + layout = wibox.layout.fixed.horizontal, + } + + local update_widget = function(widget, stdout, _, _, _) + local brightness_level = tonumber(string.format("%.0f", stdout)) + widget:set_text(" " .. brightness_level .. "%") + end, + + widget:connect_signal("button::press", function(_, _, _, button) + if (button == 4) then + spawn(inc_brightness_cmd, false) + elseif (button == 5) then + spawn(dec_brightness_cmd, false) + end + end) + + watch(get_brightness_cmd, 1, update_widget, brightness_text) + + return widget +end + +return setmetatable(widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/brightnessarc-widget/README.md b/brightnessarc-widget/README.md index fa123c1..e63f0dd 100644 --- a/brightnessarc-widget/README.md +++ b/brightnessarc-widget/README.md @@ -1,12 +1,34 @@ # Brightness widget -![Brightness widget](./br-wid-1.png) +This widget represents current brightness level: ![Brightness widget](./br-wid-1.png) + +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `get_brightness_cmd` | `light -G` | Get current screen brightness | +| `inc_brightness_cmd` | `light -A 5` | Increase brightness | +| `dec_brightness_cmd` | `light -U 5`| Decrease brightness | +| `color` | `beautiful.fg_color` | Color of the arc | +| `path_to_icon` | `/usr/share/icons/Arc/status/symbolic/display-brightness-symbolic.svg` | Path to the icon | + +### Example: + +```lua +brightnessarc_widget({ + get_brightness_cmd = 'xbacklight -get', + inc_brightness_cmd = 'xbacklight -inc 5', + dec_brightness_cmd = 'xbacklight -dec 5' + color = '/usr/share/icons/Arc/status/symbolic/brightness-display-symbolic.svg' +}) +``` -This widget represents current brightness level. ## Installation -Firstly you need to get the current brightness level. There are two options: +First you need to get the current brightness level. There are two options: - using `xbacklight` command (depending on your video card (I guess) it may or may not work) @@ -30,19 +52,36 @@ Firstly you need to get the current brightness level. There are two options: light -G 49.18 ``` -Depending on the chosen option change `GET_BRIGHTNESS_CMD` variable in **brightness.lua**. -Then in **rc.lua** add the import on top of the file and then add widget to the wibox: +Then clone this repo under **~/.config/awesome/**: + +```bash +git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/awesome/ +``` + +Require widget at the beginning of **rc.lua**: + +```lua +local brightnessarc_widget = require("awesome-wm-widgets.brightnessarc-widget.brightnessarc") +``` + +Add widget to the tasklist: ```lua -require("awesome-wm-widgets.brightness-widget.brightness") -... --- Add widgets to the wibox -s.mywibox:setup { -... -{ -- Right widgets -... -brightness_widget +s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + ... + -- default + brightnessarc_widget(), + -- or customized + brightnessarc_widget({ + get_brightness_cmd = 'xbacklight -get', + inc_brightness_cmd = 'xbacklight -inc 5', + dec_brightness_cmd = 'xbacklight -dec 5' + }) + } + ... ``` ## Controls diff --git a/brightnessarc-widget/brightnessarc.lua b/brightnessarc-widget/brightnessarc.lua index 7633218..3c4641e 100644 --- a/brightnessarc-widget/brightnessarc.lua +++ b/brightnessarc-widget/brightnessarc.lua @@ -2,7 +2,7 @@ -- Brightness Widget for Awesome Window Manager -- Shows the brightness level of the laptop display -- More details could be found here: --- https://github.com/streetturtle/awesome-wm-widgets/tree/master/brightnessarc-widget +-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/widget-widget -- @author Pavel Makhov -- @copyright 2019 Pavel Makhov @@ -11,44 +11,65 @@ local wibox = require("wibox") local watch = require("awful.widget.watch") local spawn = require("awful.spawn") +local beautiful = require("beautiful") local PATH_TO_ICON = "/usr/share/icons/Arc/status/symbolic/display-brightness-symbolic.svg" local GET_BRIGHTNESS_CMD = "light -G" -- "xbacklight -get" local INC_BRIGHTNESS_CMD = "light -A 5" -- "xbacklight -inc 5" local DEC_BRIGHTNESS_CMD = "light -U 5" -- "xbacklight -dec 5" -local icon = { - id = "icon", - image = PATH_TO_ICON, - resize = true, - widget = wibox.widget.imagebox, -} - -local brightnessarc = wibox.widget { - icon, - max_value = 1, - thickness = 2, - start_angle = 4.71238898, -- 2pi*3/4 - forced_height = 18, - forced_width = 18, - bg = "#ffffff11", - paddings = 2, - widget = wibox.container.arcchart -} - -local update_widget = function(widget, stdout) - local brightness_level = string.match(stdout, "(%d?%d?%d?)") - brightness_level = tonumber(string.format("% 3d", brightness_level)) - - widget.value = brightness_level / 100; -end, - -brightnessarc:connect_signal("button::press", function(_, _, _, button) - if (button == 4) then spawn(INC_BRIGHTNESS_CMD, false) - elseif (button == 5) then spawn(DEC_BRIGHTNESS_CMD, false) - end -end) - -watch(GET_BRIGHTNESS_CMD, 1, update_widget, brightnessarc) - -return brightnessarc +local widget = {} + +local function worker(args) + + local args = 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 + local dec_brightness_cmd = args.dec_brightness_cmd or DEC_BRIGHTNESS_CMD + local color = args.color or beautiful.fg_color + local path_to_icon = args.path_to_icon or PATH_TO_ICON + + local icon = { + id = "icon", + image = path_to_icon, + resize = true, + widget = wibox.widget.imagebox, + } + + widget = wibox.widget { + icon, + max_value = 1, + thickness = 2, + start_angle = 4.71238898, -- 2pi*3/4 + forced_height = 18, + forced_width = 18, + bg = "#ffffff11", + paddings = 2, + colors = {color}, + widget = wibox.container.arcchart + } + + local update_widget = function(widget, stdout) + local brightness_level = string.match(stdout, "(%d?%d?%d?)") + brightness_level = tonumber(string.format("% 3d", brightness_level)) + + widget.value = brightness_level / 100; + end, + + widget:connect_signal("button::press", function(_, _, _, button) + if (button == 4) then + spawn(inc_brightness_cmd, false) + elseif (button == 5) then + spawn(dec_brightness_cmd, false) + end + end) + + watch(get_brightness_cmd, 1, update_widget, widget) + + return widget +end + +return setmetatable(widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/cpu-widget/README.md b/cpu-widget/README.md index 500e1b9..31fb0d6 100644 --- a/cpu-widget/README.md +++ b/cpu-widget/README.md @@ -2,9 +2,7 @@ This widget shows the average CPU load among all cores of the machine: -![screenshot](out.gif) - -When the load is more than 80% the graph becomes red. You can easily customize the widget by changing colors, step width, step spacing, width and interval. +![screenshot](cpu.gif) ## How it works @@ -18,6 +16,32 @@ cpu 197294 718 50102 2002182 3844 0 2724 0 0 0 and calculates the percentage. +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `width` | 50 | Width of the widget | +| `step_width` | 2 | Width of the step | +| `step_spacing` | 1 | Space size between steps | +| `color` | `beautiful.fg_normal` | Color of the graph | + +### Example + +```lua +cpu_widget({ + width = 70, + step_width = 2, + step_spacing = 0, + color = '#434c5e' +}) +``` + +The config above results in the following widget: + +![custom](./custom.png) + ## Installation Clone/download repo and use widget in **rc.lua**: @@ -29,6 +53,14 @@ s.mytasklist, -- Middle widget { -- Right widgets layout = wibox.layout.fixed.horizontal, ... - cpu_widget, + -- default + cpu_widget(), + -- or custom + cpu_widget({ + width = 70, + step_width = 2, + step_spacing = 0, + color = '#434c5e' + }) ... ``` diff --git a/cpu-widget/cpu-widget.lua b/cpu-widget/cpu-widget.lua index 88ebea9..0e027dd 100644 --- a/cpu-widget/cpu-widget.lua +++ b/cpu-widget/cpu-widget.lua @@ -10,40 +10,58 @@ local watch = require("awful.widget.watch") local wibox = require("wibox") +local beautiful = require("beautiful") -local cpugraph_widget = wibox.widget { - max_value = 100, - background_color = "#00000000", - forced_width = 50, - step_width = 2, - step_spacing = 1, - widget = wibox.widget.graph, - color = "linear:0,0:0,22:0,#FF0000:0.3,#FFFF00:0.5,#74aeab" -} +local widget = {} ---- By default graph widget goes from left to right, so we mirror it and push up a bit -local cpu_widget = wibox.container.margin(wibox.container.mirror(cpugraph_widget, { horizontal = true }), 0, 0, 0, 2) +local function worker(args) -local total_prev = 0 -local idle_prev = 0 + local args = args or {} -watch([[bash -c "cat /proc/stat | grep '^cpu '"]], 1, - function(widget, stdout) - local user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice = - stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s') + local width = args.width or 50 + local step_width = args.step_width or 2 + local step_spacing = args.step_spacing or 1 + local color= args.color or beautiful.fg_normal - local total = user + nice + system + idle + iowait + irq + softirq + steal + local cpugraph_widget = wibox.widget { + max_value = 100, + background_color = "#00000000", + forced_width = width, + step_width = step_width, + step_spacing = step_spacing, + widget = wibox.widget.graph, + color = "linear:0,0:0,20:0,#FF0000:0.3,#FFFF00:0.6," .. color + } - local diff_idle = idle - idle_prev - local diff_total = total - total_prev - local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 + --- 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) - widget:add_value(diff_usage) + local total_prev = 0 + local idle_prev = 0 - total_prev = total - idle_prev = idle - end, - cpugraph_widget -) + watch([[bash -c "cat /proc/stat | grep '^cpu '"]], 1, + function(widget, stdout) + local user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice = + stdout:match('(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)%s') -return cpu_widget + local total = user + nice + system + idle + iowait + irq + softirq + steal + + local diff_idle = idle - idle_prev + local diff_total = total - total_prev + local diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 + + widget:add_value(diff_usage) + + total_prev = total + idle_prev = idle + end, + cpugraph_widget + ) + + return cpu_widget + +end + +return setmetatable(widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/cpu-widget/cpu.gif b/cpu-widget/cpu.gif Binary files differnew file mode 100644 index 0000000..086e618 --- /dev/null +++ b/cpu-widget/cpu.gif diff --git a/cpu-widget/custom.png b/cpu-widget/custom.png Binary files differnew file mode 100644 index 0000000..be275e4 --- /dev/null +++ b/cpu-widget/custom.png diff --git a/ram-widget/ram-widget.lua b/ram-widget/ram-widget.lua index 3072068..d8cb11f 100644 --- a/ram-widget/ram-widget.lua +++ b/ram-widget/ram-widget.lua @@ -2,77 +2,89 @@ local awful = require("awful") local watch = require("awful.widget.watch") local wibox = require("wibox") ---- Main ram widget shown on wibar -local ramgraph_widget = wibox.widget { - border_width = 0, - colors = { - '#74aeab', '#26403f' - }, - display_labels = false, - forced_width = 25, - widget = wibox.widget.piechart -} +local ramgraph_widget = {} ---- 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 -} +local function worker(args) -w:setup { - border_width = 0, - colors = { - '#5ea19d', - '#55918e', - '#4b817e', - }, - display_labels = false, - forced_width = 25, - id = 'pie', - widget = wibox.widget.piechart -} + local args = args or {} -local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap + --- Main ram widget shown on wibar + ramgraph_widget = wibox.widget { + border_width = 0, + colors = { + '#74aeab', '#26403f' + }, + display_labels = false, + forced_width = 25, + widget = wibox.widget.piechart + } -local function getPercentage(value) - return math.floor(value / (total+total_swap) * 100 + 0.5) .. '%' -end + --- Widget which is shown when user clicks on the ram widget + local w = wibox { + height = 200, + width = 400, + ontop = true, + expand = true, + bg = '#1e252c', + max_widget_size = 500 + } + + w:setup { + border_width = 0, + colors = { + '#5ea19d', + '#55918e', + '#4b817e', + }, + display_labels = false, + forced_width = 25, + id = 'pie', + widget = wibox.widget.piechart + } + + local total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap + + local function getPercentage(value) + return math.floor(value / (total+total_swap) * 100 + 0.5) .. '%' + end -watch('bash -c "free | grep -z Mem.*Swap.*"', 1, - function(widget, stdout, stderr, exitreason, exitcode) - total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = - stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)') + watch('bash -c "LANGUAGE=en_US.UTF-8 free | grep -z Mem.*Swap.*"', 1, + function(widget, stdout, stderr, exitreason, exitcode) + total, used, free, shared, buff_cache, available, total_swap, used_swap, free_swap = + stdout:match('(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*(%d+)%s*Swap:%s*(%d+)%s*(%d+)%s*(%d+)') - widget.data = { used, total-used } widget.data = { used, total-used } + widget.data = { used, total-used } widget.data = { used, total-used } - if w.visible then - w.pie.data_list = { - {'used ' .. getPercentage(used + used_swap), used + used_swap}, - {'free ' .. getPercentage(free + free_swap), free + free_swap}, - {'buff_cache ' .. getPercentage(buff_cache), buff_cache} - } - end - end, - ramgraph_widget -) + if w.visible then + w.pie.data_list = { + {'used ' .. getPercentage(used + used_swap), used + used_swap}, + {'free ' .. getPercentage(free + free_swap), free + free_swap}, + {'buff_cache ' .. getPercentage(buff_cache), buff_cache} + } + end + end, + ramgraph_widget + ) -ramgraph_widget:buttons( - awful.util.table.join( - awful.button({}, 1, function() - awful.placement.top_right(w, { margins = {top = 25, right = 10}, parent = awful.screen.focused() }) - w.pie.data_list = { - {'used ' .. getPercentage(used + used_swap), used + used_swap}, - {'free ' .. getPercentage(free + free_swap), free + free_swap}, - {'buff_cache ' .. getPercentage(buff_cache), buff_cache} - } - w.pie.display_labels = true - w.visible = not w.visible - end) + ramgraph_widget:buttons( + awful.util.table.join( + awful.button({}, 1, function() + awful.placement.top_right(w, { margins = {top = 25, right = 10}, parent = awful.screen.focused() }) + w.pie.data_list = { + {'used ' .. getPercentage(used + used_swap), used + used_swap}, + {'free ' .. getPercentage(free + free_swap), free + free_swap}, + {'buff_cache ' .. getPercentage(buff_cache), buff_cache} + } + w.pie.display_labels = true + w.visible = not w.visible + end) + ) ) -) -return ramgraph_widget + + return ramgraph_widget +end + +return setmetatable(ramgraph_widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/secrets.lua b/secrets.lua deleted file mode 100644 index 19f35b8..0000000 --- a/secrets.lua +++ /dev/null @@ -1,18 +0,0 @@ -------------------------------------------------- --- Allows to store client specific settings in one place --- --- @author Pavel Makhov --- @copyright 2019 Pavel Makhov --------------------------------------------- - -local secrets = { - -- Yandex.Translate API key - https://tech.yandex.com/translate/ - translate_widget_api_key = os.getenv('AWW_TRANSLATE_API_KEY') or 'API_KEY', - - -- OpenWeatherMap API key - https://openweathermap.org/appid - weather_widget_api_key = os.getenv('AWW_WEATHER_API_KEY') or 'API_KEY', - weather_widget_city = os.getenv('AWW_WEATHER_CITY') or 'Montreal,ca', - weather_widget_units = os.getenv('AWW_WEATHER_UNITS') or 'metric' -- for celsius, or 'imperial' for fahrenheit -} - -return secrets diff --git a/spotify-widget/README.md b/spotify-widget/README.md index eff3027..083963f 100644 --- a/spotify-widget/README.md +++ b/spotify-widget/README.md @@ -1,9 +1,9 @@ # Spotify widget -This widget displays currently playing song on [Spotify for Linux](https://www.spotify.com/download/linux/) client: ![screenshot](./spo-wid-1.png) and consists of two parts: +This widget displays currently playing song on [Spotify for Linux](https://www.spotify.com/download/linux/) client: ![screenshot](./spo-wid-default.png) and consists of two parts: - status icon which shows if music is currently playing - - artist and name of the current song playing + - artist and name of the current song ## Controls @@ -15,11 +15,42 @@ This widget displays currently playing song on [Spotify for Linux](https://www.s Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder. +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `play_icon` | `/usr/share/icons/Arc/actions/24/player_play.png` | Play icon | +| `pause_icon` | `/usr/share/icons/Arc/actions/24/player_pause.png` | Pause icon | +| `font` | `Play 9`| Font | + +### Example: + +```lua +spotify_widget({ + font = 'Ubuntu Mono 9', + play_icon = '/usr/share/icons/Papirus-Light/24x24/categories/spotify.svg', + pause_icon = '/usr/share/icons/Papirus-Dark/24x24/panel/spotify-indicator.svg' +}) +``` + +Gives following widget: + +![screenshot](./spo-wid-custom.png) + ## Installation -First you need to have spotify CLI installed. Here is how you can do it (except widget part): [pavelmakhov.com/2016/02/awesome-wm-spotify](http://pavelmakhov.com/2016/02/awesome-wm-spotify) +First you need to have spotify CLI installed, it uses dbus to communicate with spotify-client: + +```bash +git clone https://gist.github.com/fa6258f3ff7b17747ee3.git +cd ./fa6258f3ff7b17747ee3 +chmod +x sp +sudo cp ./sp /usr/local/bin/ +``` -To use this widget clone repo under **~/.config/awesome/** and then add it in **rc.lua**: +Then clone repo under **~/.config/awesome/** and add widget in **rc.lua**: ```lua local spotify_widget = require("awesome-wm-widgets.spotify-widget.spotify") @@ -28,6 +59,13 @@ s.mytasklist, -- Middle widget { -- Right widgets layout = wibox.layout.fixed.horizontal, ... - spotify_widget, + -- default + spotify_widget(), + -- customized + spotify_widget({ + font = 'Ubuntu Mono 9', + play_icon = '/usr/share/icons/Papirus-Light/24x24/categories/spotify.svg', + pause_icon = '/usr/share/icons/Papirus-Dark/24x24/panel/spotify-indicator.svg' + }), ... ``` diff --git a/spotify-widget/spo-wid-custom.png b/spotify-widget/spo-wid-custom.png Binary files differnew file mode 100644 index 0000000..979ad31 --- /dev/null +++ b/spotify-widget/spo-wid-custom.png diff --git a/spotify-widget/spo-wid-default.png b/spotify-widget/spo-wid-default.png Binary files differnew file mode 100644 index 0000000..67785f2 --- /dev/null +++ b/spotify-widget/spo-wid-default.png diff --git a/spotify-widget/spotify.lua b/spotify-widget/spotify.lua index c6f2188..e826de9 100644 --- a/spotify-widget/spotify.lua +++ b/spotify-widget/spotify.lua @@ -14,59 +14,75 @@ local watch = require("awful.widget.watch") local GET_SPOTIFY_STATUS_CMD = 'sp status' local GET_CURRENT_SONG_CMD = 'sp current-oneline' -local PATH_TO_ICONS = "/usr/share/icons/Arc" -local spotify_widget = wibox.widget { - { - id = "icon", - widget = wibox.widget.imagebox, - }, - { - id = 'current_song', - widget = wibox.widget.textbox, - font = 'Play 9' - }, - layout = wibox.layout.align.horizontal, - set_status = function(self, is_playing) - self.icon.image = PATH_TO_ICONS .. - (is_playing and "/actions/24/player_play.png" - or "/actions/24/player_pause.png") - end, - set_text = function(self, path) - self.current_song.markup = path - end, -} +local spotify_widget = {} -local update_widget_icon = function(widget, stdout, _, _, _) - stdout = string.gsub(stdout, "\n", "") - widget:set_status(stdout == 'Playing' and true or false) -end +local function worker(args) -local update_widget_text = function(widget, stdout, _, _, _) - if string.find(stdout, 'Error: Spotify is not running.') ~= nil then - widget:set_text('') - widget:set_visible(false) - else - widget:set_text(stdout) - widget:set_visible(true) - end -end + local args = args or {} -watch(GET_SPOTIFY_STATUS_CMD, 1, update_widget_icon, spotify_widget) -watch(GET_CURRENT_SONG_CMD, 1, update_widget_text, spotify_widget) + 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' + local font = args.font or 'Play 9' + + spotify_widget = wibox.widget { + { + id = "icon", + widget = wibox.widget.imagebox, + }, + { + id = 'current_song', + widget = wibox.widget.textbox, + font = font + }, + layout = wibox.layout.align.horizontal, + set_status = function(self, is_playing) + self.icon.image = (is_playing and play_icon or pause_icon) + end, + set_text = function(self, path) + self.current_song.markup = path + end, + } + + local update_widget_icon = function(widget, stdout, _, _, _) + stdout = string.gsub(stdout, "\n", "") + widget:set_status(stdout == 'Playing' and true or false) + end ---- Adds mouse controls to the widget: --- - left click - play/pause --- - scroll up - play next song --- - scroll down - play previous song -spotify_widget:connect_signal("button::press", function(_, _, _, button) - if (button == 1) then awful.spawn("sp play", false) -- left click - elseif (button == 4) then awful.spawn("sp next", false) -- scroll up - elseif (button == 5) then awful.spawn("sp prev", false) -- scroll down + local update_widget_text = function(widget, stdout, _, _, _) + if string.find(stdout, 'Error: Spotify is not running.') ~= nil then + widget:set_text('') + widget:set_visible(false) + else + widget:set_text(stdout) + widget:set_visible(true) + end end - awful.spawn.easy_async(GET_SPOTIFY_STATUS_CMD, function(stdout, stderr, exitreason, exitcode) - update_widget_icon(spotify_widget, stdout, stderr, exitreason, exitcode) + + watch(GET_SPOTIFY_STATUS_CMD, 1, update_widget_icon, spotify_widget) + watch(GET_CURRENT_SONG_CMD, 1, update_widget_text, spotify_widget) + + --- Adds mouse controls to the widget: + -- - left click - play/pause + -- - scroll up - play next song + -- - scroll down - play previous song + spotify_widget:connect_signal("button::press", function(_, _, _, button) + if (button == 1) then + awful.spawn("sp play", false) -- left click + elseif (button == 4) then + awful.spawn("sp next", false) -- scroll up + elseif (button == 5) then + awful.spawn("sp prev", false) -- scroll down + end + awful.spawn.easy_async(GET_SPOTIFY_STATUS_CMD, function(stdout, stderr, exitreason, exitcode) + update_widget_icon(spotify_widget, stdout, stderr, exitreason, exitcode) + end) end) -end) -return spotify_widget + return spotify_widget + +end + +return setmetatable(spotify_widget, { __call = function(_, ...) + return worker(...) +end })
\ No newline at end of file diff --git a/volume-widget/README.md b/volume-widget/README.md index 118abc6..24c2d76 100644 --- a/volume-widget/README.md +++ b/volume-widget/README.md @@ -1,10 +1,18 @@ # Volume widget -Simple and easy-to-install widget for Awesome Window Manager which represents the sound level: ![Volume Widget]( +Simple and easy-to-install widget for Awesome Window Manager which shows the sound level: ![Volume Widget]( ./vol-widget-1.png) Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder. +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `volume_audio_controller` | `pulse` | audio device | + ## Installation - clone/copy **volume.lua** file; @@ -18,7 +26,7 @@ s.mytasklist, -- Middle widget { -- Right widgets layout = wibox.layout.fixed.horizontal, ... - volume_widget, + volume_widget(), ... ``` @@ -31,6 +39,43 @@ s.mytasklist, -- Middle widget sudo sed -i 's/bebebe/ed4737/g' ./audio-volume-muted-symbolic_red.svg ``` +### Pulse or ALSA only + +Try running this command: + +```bash +amixer -D pulse sget Master +``` + +If that prints something like this, then the default setting of 'pulse' is probably fine: + +``` +Simple mixer control 'Master',0 + Capabilities: pvolume pvolume-joined pswitch pswitch-joined + Playback channels: Mono + Limits: Playback 0 - 64 + Mono: Playback 64 [100%] [0.00dB] [on] + +``` + +If it prints something like this: + +```bash +$ amixer -D pulse sget Master +ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused + +amixer: Mixer attach pulse error: Connection refused +``` +then set `volume_audio_controller` to `alsa_only` in widget constructor: + +```lua +volume_widget({ + volume_audio_controller = 'alsa_only' +}) +``` + +. + ## Control volume To mute/unmute click on the widget. To increase/decrease volume scroll up or down when mouse cursor is over the widget. diff --git a/volume-widget/volume.lua b/volume-widget/volume.lua index 8124bcf..6172f5e 100644 --- a/volume-widget/volume.lua +++ b/volume-widget/volume.lua @@ -15,53 +15,70 @@ local spawn = require("awful.spawn") local path_to_icons = "/usr/share/icons/Arc/status/symbolic/" -local GET_VOLUME_CMD = 'amixer -D pulse sget Master' -local INC_VOLUME_CMD = 'amixer -D pulse sset Master 5%+' -local DEC_VOLUME_CMD = 'amixer -D pulse sset Master 5%-' -local TOG_VOLUME_CMD = 'amixer -D pulse sset Master toggle' - -local volume_widget = wibox.widget { - { - id = "icon", - image = path_to_icons .. "audio-volume-muted-symbolic.svg", - resize = false, - widget = wibox.widget.imagebox, - }, - layout = wibox.container.margin(_, _, _, 3), - set_image = function(self, path) - self.icon.image = path - end -} - -local update_graphic = function(widget, stdout, _, _, _) - local mute = string.match(stdout, "%[(o%D%D?)%]") - local volume = string.match(stdout, "(%d?%d?%d)%%") - volume = tonumber(string.format("% 3d", volume)) - local volume_icon_name - if mute == "off" then volume_icon_name="audio-volume-muted-symbolic_red" - elseif (volume >= 0 and volume < 25) then volume_icon_name="audio-volume-muted-symbolic" - elseif (volume < 50) then volume_icon_name="audio-volume-low-symbolic" - elseif (volume < 75) then volume_icon_name="audio-volume-medium-symbolic" - elseif (volume <= 100) then volume_icon_name="audio-volume-high-symbolic" +local volume_widget = {} + +local function worker(args) + + local args = args or {} + + local volume_audio_controller = args.volume_audio_controller or 'pulse' + + local device_arg = '' + if volume_audio_controller == 'pulse' then + device_arg = '-D pulse' end - widget.image = path_to_icons .. volume_icon_name .. ".svg" -end ---[[ allows control volume level by: -- clicking on the widget to mute/unmute -- scrolling when cursor is over the widget -]] -volume_widget:connect_signal("button::press", function(_,_,_,button) - if (button == 4) then awful.spawn(INC_VOLUME_CMD, false) - elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD, false) - elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD, false) + local GET_VOLUME_CMD = 'amixer ' .. device_arg .. ' sget Master' + local INC_VOLUME_CMD = 'amixer ' .. device_arg .. ' sset Master 5%+' + local DEC_VOLUME_CMD = 'amixer ' .. device_arg .. ' sset Master 5%-' + local TOG_VOLUME_CMD = 'amixer ' .. device_arg .. ' sset Master toggle' + + + volume_widget = wibox.widget { + { + id = "icon", + image = path_to_icons .. "audio-volume-muted-symbolic.svg", + resize = false, + widget = wibox.widget.imagebox, + }, + layout = wibox.container.margin(_, _, _, 3), + set_image = function(self, path) + self.icon.image = path + end + } + + local update_graphic = function(widget, stdout, _, _, _) + local mute = string.match(stdout, "%[(o%D%D?)%]") + local volume = string.match(stdout, "(%d?%d?%d)%%") + volume = tonumber(string.format("% 3d", volume)) + local volume_icon_name + if mute == "off" then volume_icon_name="audio-volume-muted-symbolic_red" + elseif (volume >= 0 and volume < 25) then volume_icon_name="audio-volume-muted-symbolic" + elseif (volume < 50) then volume_icon_name="audio-volume-low-symbolic" + elseif (volume < 75) then volume_icon_name="audio-volume-medium-symbolic" + elseif (volume <= 100) then volume_icon_name="audio-volume-high-symbolic" + end + widget.image = path_to_icons .. volume_icon_name .. ".svg" end - spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode) - update_graphic(volume_widget, stdout, stderr, exitreason, exitcode) + --[[ allows control volume level by: + - clicking on the widget to mute/unmute + - scrolling when cursor is over the widget + ]] + volume_widget:connect_signal("button::press", function(_,_,_,button) + if (button == 4) then awful.spawn(INC_VOLUME_CMD, false) + elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD, false) + elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD, false) + end + + spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode) + update_graphic(volume_widget, stdout, stderr, exitreason, exitcode) + end) end) -end) -watch(GET_VOLUME_CMD, 1, update_graphic, volume_widget) + watch(GET_VOLUME_CMD, 1, update_graphic, volume_widget) + + return volume_widget +end -return volume_widget
\ No newline at end of file +return setmetatable(volume_widget, { __call = function(_, ...) return worker(...) end }) diff --git a/volumearc-widget/README.md b/volumearc-widget/README.md index 702b486..0ae17b4 100644 --- a/volumearc-widget/README.md +++ b/volumearc-widget/README.md @@ -1,17 +1,54 @@ # Volumearc widget -Almost the same as [volumebar widget](https://github.com/streetturtle/awesome-wm-widgets/tree/master/volumebar-widget), but using arcchart: +Almost the same as [volumebar widget](https://github.com/streetturtle/awesome-wm-widgets/tree/master/volumebar-widget), but using [arcchart](https://awesomewm.org/doc/api/classes/wibox.container.arcchart.html): ![screenshot](out.gif) -Supports: - - scroll up - increase volume, - - scroll down - decrease volume, +Supports + - scroll up - increase volume, + - scroll down - decrease volume, - left click - mute/unmute. +## 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 arc | +| `mute_color` | `beautiful.fg_urgent` | Color of the arc when mute | +| `path_to_icon` | /usr/share/icons/Arc/status/symbolic/audio-volume-muted-symbolic.svg | Path to the icon | +| `thickness` | 2 | The arc thickness | +| `height` | `beautiful.fg_normal` | Widget height | +| `get_volume_cmd` | `amixer -D pulse sget Master` | Get current volume level | +| `inc_volume_cmd` | `amixer -D pulse sset Master 5%+` | Increase volume level | +| `dec_volume_cmd` | `amixer -D pulse sset Master 5%-` | Descrease volume level | +| `tog_volume_cmd` | `amixer -D pulse sset Master toggle` | Mute / unmute | + +### Example: + +```lua +volumearc_widget({ + main_color = '#af13f7', + mute_color = '#ff0000', + thickness = 5, + height = 25 +}) +``` + +The config above results in the following widget: + +![custom](./custom.png) + ## Installation -Clone repo, include widget and use it in **rc.lua**: +1. Clone this repo under **~/.config/awesome/** + + ```bash + git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/awesome/ + ``` + +1. Require volumearc widget at the beginning of **rc.lua**: ```lua require("volumearc") diff --git a/volumearc-widget/custom.png b/volumearc-widget/custom.png Binary files differnew file mode 100644 index 0000000..f187345 --- /dev/null +++ b/volumearc-widget/custom.png diff --git a/volumearc-widget/volumearc.lua b/volumearc-widget/volumearc.lua index 63500bc..62b18ab 100644 --- a/volumearc-widget/volumearc.lua +++ b/volumearc-widget/volumearc.lua @@ -21,47 +21,67 @@ local TOG_VOLUME_CMD = 'amixer -D pulse sset Master toggle' local PATH_TO_ICON = "/usr/share/icons/Arc/status/symbolic/audio-volume-muted-symbolic.svg" -local icon = { - id = "icon", - image = PATH_TO_ICON, - resize = true, - widget = wibox.widget.imagebox, -} - -local volumearc = wibox.widget { - icon, - max_value = 1, - thickness = 2, - start_angle = 4.71238898, -- 2pi*3/4 - forced_height = 18, - forced_width = 18, - bg = "#ffffff11", - paddings = 2, - widget = wibox.container.arcchart -} - -local update_graphic = function(widget, stdout, _, _, _) - local mute = string.match(stdout, "%[(o%D%D?)%]") - local volume = string.match(stdout, "(%d?%d?%d)%%") - volume = tonumber(string.format("% 3d", volume)) - - widget.value = volume / 100; - widget.colors = mute == 'off' and { beautiful.widget_red } - or { beautiful.widget_main_color } +local widget = {} -end +local function worker(args) + + local args = args or {} + + local main_color = args.main_color or beautiful.fg_color + 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 get_volume_cmd = args.get_volume_cmd or GET_VOLUME_CMD + local inc_volume_cmd = args.inc_volume_cmd or INC_VOLUME_CMD + local dec_volume_cmd = args.dec_volume_cmd or DEC_VOLUME_CMD + local tog_volume_cmd = args.tog_volume_cmd or TOG_VOLUME_CMD + + local icon = { + id = "icon", + image = path_to_icon, + resize = true, + widget = wibox.widget.imagebox, + } -volumearc:connect_signal("button::press", function(_, _, _, button) - if (button == 4) then awful.spawn(INC_VOLUME_CMD, false) - elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD, false) - elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD, false) + local volumearc = wibox.widget { + icon, + max_value = 1, + thickness = thickness, + start_angle = 4.71238898, -- 2pi*3/4 + forced_height = height, + forced_width = height, + bg = "#ffffff11", + paddings = 2, + widget = wibox.container.arcchart + } + + local update_graphic = function(widget, 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)) + + widget.value = volume / 100; + widget.colors = mute == 'off' + and { mute_color } + or { main_color } end - spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode) - update_graphic(volumearc, stdout, stderr, exitreason, exitcode) + volumearc:connect_signal("button::press", function(_, _, _, button) + if (button == 4) then awful.spawn(inc_volume_cmd, false) + elseif (button == 5) then awful.spawn(dec_volume_cmd, false) + elseif (button == 1) then awful.spawn(tog_volume_cmd, false) + end + + spawn.easy_async(get_volume_cmd, function(stdout, stderr, exitreason, exitcode) + update_graphic(volumearc, stdout, stderr, exitreason, exitcode) + end) end) -end) -watch(GET_VOLUME_CMD, 1, update_graphic, volumearc) + watch(get_volume_cmd, 1, update_graphic, volumearc) + + return volumearc +end -return volumearc
\ No newline at end of file +return setmetatable(widget, { __call = function(_, ...) return worker(...) end }) diff --git a/volumebar-widget/README.md b/volumebar-widget/README.md index d6b9117..35169b7 100644 --- a/volumebar-widget/README.md +++ b/volumebar-widget/README.md @@ -9,21 +9,75 @@ Supports - scroll down - decrease volume, - left click - mute/unmute. - ## Installation - - Clone repo, include widget and use it in **rc.lua**: +## 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 bar | +| `mute_color` | `beautiful.fg_urgent` | Color of the bar when mute | +| `width` | 50 | The bar width | +| `shape` | `bar` | [gears.shape](https://awesomewm.org/doc/api/libraries/gears.shape.html), could be `octogon`, `hexagon`, `powerline`, etc | +| `margin` | `10` | Top and bottom margin (if your wibar is 22 px high, bar will be 2 px (22 - 2*10)) | +| `get_volume_cmd` | `amixer -D pulse sget Master` | Get current volume level | +| `inc_volume_cmd` | `amixer -D pulse sset Master 5%+` | Increase volume level | +| `dec_volume_cmd` | `amixer -D pulse sset Master 5%-` | Descrease volume level | +| `tog_volume_cmd` | `amixer -D pulse sset Master toggle` | Mute / unmute | + +### Example: + ```lua -local volumebar_widget = require("awesome-wm-widgets.volumebar-widget.volumebar") -... -s.mytasklist, -- Middle widget - { -- Right widgets - layout = wibox.layout.fixed.horizontal, - ... - volumebar_widget, - ... + volumebar_widget({ + main_color = '#af13f7', + mute_color = '#ff0000', + width = 80, + shape = 'rounded_bar', + margins = 8 +}) ``` +Above config results in following widget: + +![custom](./custom.png) + + +## Installation + +1. Clone this repo under **~/.config/awesome/** + + ```bash + git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/awesome/ + ``` + +1. Require volumebar widget at the beginning of **rc.lua**: + + ```lua + local volumebar_widget = require("awesome-wm-widgets.volumebar-widget.volumebar") + ``` + +1. Add widget to the tasklist: + + ```lua + s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + ... + --[[default]] + volumebar_widget(), + --[[or customized]] + volumebar_widget({ + main_color = '#af13f7', + mute_color = '#ff0000', + width = 80, + shape = 'rounded_bar', -- octogon, hexagon, powerline, etc + -- bar's height = wibar's height minus 2x margins + margins = 8 + }), + + ... + ``` + ## Troubleshooting If the bar is not showing up, try to decrease top or bottom margin - widget uses hardcoded margins for vertical alignment, so if your wibox is too small then bar is simply hidden by the margins. diff --git a/volumebar-widget/custom.png b/volumebar-widget/custom.png Binary files differnew file mode 100644 index 0000000..d86143b --- /dev/null +++ b/volumebar-widget/custom.png diff --git a/volumebar-widget/volumebar.lua b/volumebar-widget/volumebar.lua index 9fd6a99..18e0f40 100644 --- a/volumebar-widget/volumebar.lua +++ b/volumebar-widget/volumebar.lua @@ -9,6 +9,7 @@ ------------------------------------------------- local awful = require("awful") +local beautiful = require("beautiful") local gears = require("gears") local spawn = require("awful.spawn") local watch = require("awful.widget.watch") @@ -19,48 +20,66 @@ 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 bar_color = "#74aeab" -local mute_color = "#ff0000" -local background_color = "#3a3a3a" - -local volumebar_widget = wibox.widget { - max_value = 1, - forced_width = 50, - paddings = 0, - border_width = 0.5, - color = bar_color, - background_color = background_color, - shape = gears.shape.bar, - clip = true, - margins = { - top = 10, - bottom = 10, - }, - widget = wibox.widget.progressbar -} - -local update_graphic = function(widget, stdout, _, _, _) - local mute = string.match(stdout, "%[(o%D%D?)%]") - local volume = string.match(stdout, "(%d?%d?%d)%%") - volume = tonumber(string.format("% 3d", volume)) - - widget.value = volume / 100; - widget.color = mute == "off" and mute_color - or bar_color +local widget = {} -end +local function worker(args) + + local args = args or {} + + local main_color = args.main_color or beautiful.fg_normal + local mute_color = args.mute_color or beautiful.fg_urgent + local width = args.width or 50 + local shape = args.shape or 'bar' + local margins = args.margins or 10 + + local get_volume_cmd = args.get_volume_cmd or GET_VOLUME_CMD + local inc_volume_cmd = args.inc_volume_cmd or INC_VOLUME_CMD + local dec_volume_cmd = args.dec_volume_cmd or DEC_VOLUME_CMD + local tog_volume_cmd = args.tog_volume_cmd or TOG_VOLUME_CMD + + local volumebar_widget = wibox.widget { + max_value = 1, + forced_width = width, + color = main_color, + background_color = '#ffffff11', + shape = gears.shape[shape], + margins = { + top = margins, + bottom = margins, + }, + widget = wibox.widget.progressbar + } + + local update_graphic = function(widget, 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)) + + widget.value = volume / 100; + widget.color = mute == "off" + and mute_color + or main_color -volumebar_widget:connect_signal("button::press", function(_,_,_,button) - if (button == 4) then awful.spawn(INC_VOLUME_CMD) - elseif (button == 5) then awful.spawn(DEC_VOLUME_CMD) - elseif (button == 1) then awful.spawn(TOG_VOLUME_CMD) end - spawn.easy_async(GET_VOLUME_CMD, function(stdout, stderr, exitreason, exitcode) - update_graphic(volumebar_widget, stdout, stderr, exitreason, exitcode) + volumebar_widget:connect_signal("button::press", function(_, _, _, button) + if (button == 4) then + awful.spawn(inc_volume_cmd) + elseif (button == 5) then + awful.spawn(dec_volume_cmd) + elseif (button == 1) then + awful.spawn(tog_volume_cmd) + end + + spawn.easy_async(get_volume_cmd, function(stdout, stderr, exitreason, exitcode) + update_graphic(volumebar_widget, stdout, stderr, exitreason, exitcode) + end) end) -end) -watch(GET_VOLUME_CMD, 1, update_graphic, volumebar_widget) + watch(get_volume_cmd, 1, update_graphic, volumebar_widget) + + return volumebar_widget +end + +return setmetatable(widget, { __call = function(_, ...) return worker(...) end }) -return volumebar_widget
\ No newline at end of file diff --git a/weather-widget/README.md b/weather-widget/README.md index ef7282f..6464fcc 100644 --- a/weather-widget/README.md +++ b/weather-widget/README.md @@ -4,6 +4,30 @@ Note that widget uses the Arc icon theme, so it should be [installed](https://github.com/horst3180/arc-icon-theme#installation) first under **/usr/share/icons/Arc/** folder. +## Customization + +It is possible to customize widget by providing a table with all or some of the following config parameters: + +| Name | Default | Description | +|---|---|---| +| `font` | `Play 9` | Font | +| `city` | `Montreal,ca` | City name and country code, [more info](https://openweathermap.org/current) | +| `api_key` | none| API key, required | +| `units` | `metric` | `metric` for celsius, `imperial` for fahrenheit | +| `both_units_widget` | `false` | show temperature in both units (15°C (59°F)) or in one (15°C) | +| `both_units_popup` | `false` | same as above but for popup | + +### Example: + +```lua +weather_widget({ + api_key = 'your-api-key', + units = 'imperial', + font = 'Ubuntu Mono 9' +}), +``` + + ## Installation 1. Install lua socket - to make HTTP calls to get the weather information. @@ -24,7 +48,7 @@ Note that widget uses the Arc icon theme, so it should be [installed](https://gi git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/awesome/ ``` -1. Get Open Weather Map app id here: [openweathermap.org/appid](https://openweathermap.org/appid) and place it in **~/.config/awesome/awesome-wm-widgets/secrets.lua**, or directly in the widget. Don't forget to set also your city and units - C/F. +1. Get Open Weather Map app id here: [openweathermap.org/appid](https://openweathermap.org/appid). 1. Require weather widget at the beginning of **rc.lua**: @@ -39,7 +63,14 @@ Note that widget uses the Arc icon theme, so it should be [installed](https://gi { -- Right widgets layout = wibox.layout.fixed.horizontal, ... - weather_widget, + --default + weather_widget({api_key = 'your-api-key'}), + --customized + weather_widget({ + api_key = 'your-api-key', + units = 'imperial', + font = 'Ubuntu Mono 9' + }) ... ``` diff --git a/weather-widget/weather.lua b/weather-widget/weather.lua index 2d80947..b0aa070 100644 --- a/weather-widget/weather.lua +++ b/weather-widget/weather.lua @@ -14,153 +14,197 @@ local naughty = require("naughty") local wibox = require("wibox") local gears = require("gears") -local secrets = require("awesome-wm-widgets.secrets") +local path_to_icons = "/usr/share/icons/Arc/status/symbolic/" -local weather_api_url = ( - 'https://api.openweathermap.org/data/2.5/weather' - .. '?q=' .. secrets.weather_widget_city - .. '&appid=' .. secrets.weather_widget_api_key - .. '&units=' .. secrets.weather_widget_units -) +local weather_widget = {} -local path_to_icons = "/usr/share/icons/Arc/status/symbolic/" +local function worker(args) -local icon_widget = wibox.widget { - { - id = "icon", - resize = false, - widget = wibox.widget.imagebox, - }, - layout = wibox.container.margin(_ , 0, 0, 3), - set_image = function(self, path) - self.icon.image = path - end, -} - -local temp_widget = wibox.widget{ - font = "Play 9", - widget = wibox.widget.textbox, -} - -local weather_widget = wibox.widget { - icon_widget, - temp_widget, - layout = wibox.layout.fixed.horizontal, -} - ---- Maps openWeatherMap icons to Arc icons -local icon_map = { - ["01d"] = "weather-clear-symbolic.svg", - ["02d"] = "weather-few-clouds-symbolic.svg", - ["03d"] = "weather-clouds-symbolic.svg", - ["04d"] = "weather-overcast-symbolic.svg", - ["09d"] = "weather-showers-scattered-symbolic.svg", - ["10d"] = "weather-showers-symbolic.svg", - ["11d"] = "weather-storm-symbolic.svg", - ["13d"] = "weather-snow-symbolic.svg", - ["50d"] = "weather-fog-symbolic.svg", - ["01n"] = "weather-clear-night-symbolic.svg", - ["02n"] = "weather-few-clouds-night-symbolic.svg", - ["03n"] = "weather-clouds-night-symbolic.svg", - ["04n"] = "weather-overcast-symbolic.svg", - ["09n"] = "weather-showers-scattered-symbolic.svg", - ["10n"] = "weather-showers-symbolic.svg", - ["11n"] = "weather-storm-symbolic.svg", - ["13n"] = "weather-snow-symbolic.svg", - ["50n"] = "weather-fog-symbolic.svg" -} - ---- Return wind direction as a string. -local function to_direction(degrees) - -- Ref: https://www.campbellsci.eu/blog/convert-wind-directions - if degrees == nil then - return "Unknown dir" - end - local directions = { - "N", - "NNE", - "NE", - "ENE", - "E", - "ESE", - "SE", - "SSE", - "S", - "SSW", - "SW", - "WSW", - "W", - "WNW", - "NW", - "NNW", - "N", + local args = args or {} + + local font = args.font or 'Play 9' + local city = args.city or 'Montreal,ca' + local api_key = args.api_key or naughty.notify{preset = naughty.config.presets.critical, text = 'OpenweatherMap API key is not set'} + local units = args.units or 'metric' + local both_units_widget = args.both_units_widget or false + local both_units_popup = args.both_units_popup or false + + local weather_api_url = ( + 'https://api.openweathermap.org/data/2.5/weather' + .. '?q=' .. city + .. '&appid=' .. api_key + .. '&units=' .. units + ) + + local icon_widget = wibox.widget { + { + id = "icon", + resize = false, + widget = wibox.widget.imagebox, + }, + layout = wibox.container.margin(_, 0, 0, 3), + set_image = function(self, path) + self.icon.image = path + end, } - return directions[math.floor((degrees % 360) / 22.5) + 1] -end -local weather_timer = gears.timer({ timeout = 60 }) -local resp - -weather_timer:connect_signal("timeout", function () - local resp_json = {} - local res, status = http.request{ - url=weather_api_url, - sink=ltn12.sink.table(resp_json), - -- ref: - -- http://w3.impa.br/~diego/software/luasocket/old/luasocket-2.0/http.html - create=function() - -- ref: https://stackoverflow.com/a/6021774/595220 - local req_sock = socket.tcp() - -- 't' — overall timeout - req_sock:settimeout(0.2, 't') - -- 'b' — block timeout - req_sock:settimeout(0.001, 'b') - return req_sock - end + local temp_widget = wibox.widget { + font = font, + widget = wibox.widget.textbox, } - if (resp_json ~= nil) then - resp_json = table.concat(resp_json) - end - if (status ~= 200 and resp_json ~= nil and resp_json ~= '') then - local err_resp = json.decode(resp_json) - naughty.notify{ - title = 'Weather Widget Error', - text = err_resp.message, - preset = naughty.config.presets.critical, + weather_widget = wibox.widget { + icon_widget, + temp_widget, + layout = wibox.layout.fixed.horizontal, + } + + --- Maps openWeatherMap icons to Arc icons + local icon_map = { + ["01d"] = "weather-clear-symbolic.svg", + ["02d"] = "weather-few-clouds-symbolic.svg", + ["03d"] = "weather-clouds-symbolic.svg", + ["04d"] = "weather-overcast-symbolic.svg", + ["09d"] = "weather-showers-scattered-symbolic.svg", + ["10d"] = "weather-showers-symbolic.svg", + ["11d"] = "weather-storm-symbolic.svg", + ["13d"] = "weather-snow-symbolic.svg", + ["50d"] = "weather-fog-symbolic.svg", + ["01n"] = "weather-clear-night-symbolic.svg", + ["02n"] = "weather-few-clouds-night-symbolic.svg", + ["03n"] = "weather-clouds-night-symbolic.svg", + ["04n"] = "weather-overcast-symbolic.svg", + ["09n"] = "weather-showers-scattered-symbolic.svg", + ["10n"] = "weather-showers-symbolic.svg", + ["11n"] = "weather-storm-symbolic.svg", + ["13n"] = "weather-snow-symbolic.svg", + ["50n"] = "weather-fog-symbolic.svg" + } + + --- Return wind direction as a string. + local function to_direction(degrees) + -- Ref: https://www.campbellsci.eu/blog/convert-wind-directions + if degrees == nil then + return "Unknown dir" + end + local directions = { + "N", + "NNE", + "NE", + "ENE", + "E", + "ESE", + "SE", + "SSE", + "S", + "SSW", + "SW", + "WSW", + "W", + "WNW", + "NW", + "NNW", + "N", } - elseif (resp_json ~= nil and resp_json ~= '') then - resp = json.decode(resp_json) - icon_widget.image = path_to_icons .. icon_map[resp.weather[1].icon] - temp_widget:set_text(string.gsub(resp.main.temp, "%.%d+", "") - .. '°' - .. (secrets.weather_widget_units == 'metric' and 'C' or 'F')) + return directions[math.floor((degrees % 360) / 22.5) + 1] + end + + -- Convert degrees Celsius to Fahrenheit + local function celsius_to_fahrenheit(c) + return c*9/5+32 end -end) -weather_timer:start() -weather_timer:emit_signal("timeout") - ---- Notification with weather information. Popups when mouse hovers over the icon -local notification -weather_widget:connect_signal("mouse::enter", function() - notification = naughty.notify{ - icon = path_to_icons .. icon_map[resp.weather[1].icon], - icon_size=20, - text = - '<big>' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')</big><br>' .. - '<b>Humidity:</b> ' .. resp.main.humidity .. '%<br>' .. - '<b>Temperature:</b> ' .. resp.main.temp .. '°' - .. (secrets.weather_widget_units == 'metric' and 'C' or 'F') .. '<br>' .. - '<b>Pressure:</b> ' .. resp.main.pressure .. 'hPa<br>' .. - '<b>Clouds:</b> ' .. resp.clouds.all .. '%<br>' .. - '<b>Wind:</b> ' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')', - timeout = 5, hover_timeout = 10, - width = 200 - } -end) -weather_widget:connect_signal("mouse::leave", function() - naughty.destroy(notification) -end) + -- Convert degrees Fahrenheit to Celsius + local function fahrenheit_to_celsius(f) + return (f-32)*5/9 + end + + local weather_timer = gears.timer({ timeout = 60 }) + local resp + + local function gen_temperature_str(temp, fmt_str, show_other_units) + local temp_str = string.format(fmt_str, temp) + local s = temp_str .. '°' .. (units == 'metric' and 'C' or 'F') + + if (show_other_units) then + local temp_conv, units_conv + if (units == 'metric') then + temp_conv = celsius_to_fahrenheit(temp) + units_conv = 'F' + else + temp_conv = fahrenheit_to_celsius(temp) + units_conv = 'C' + end + + local temp_conv_str = string.format(fmt_str, temp_conv) + s = s .. ' ' .. '('.. temp_conv_str .. '°' .. units_conv .. ')' + end + return s + end + + weather_timer:connect_signal("timeout", function () + local resp_json = {} + local res, status = http.request{ + url=weather_api_url, + sink=ltn12.sink.table(resp_json), + -- ref: + -- http://w3.impa.br/~diego/software/luasocket/old/luasocket-2.0/http.html + create=function() + -- ref: https://stackoverflow.com/a/6021774/595220 + local req_sock = socket.tcp() + -- 't' — overall timeout + req_sock:settimeout(0.2, 't') + -- 'b' — block timeout + req_sock:settimeout(0.001, 'b') + return req_sock + end + } + if (resp_json ~= nil) then + resp_json = table.concat(resp_json) + end + + if (status ~= 200 and resp_json ~= nil and resp_json ~= '') then + local err_resp = json.decode(resp_json) + naughty.notify{ + title = 'Weather Widget Error', + text = err_resp.message, + preset = naughty.config.presets.critical, + } + elseif (resp_json ~= nil and resp_json ~= '') then + resp = json.decode(resp_json) + icon_widget.image = path_to_icons .. icon_map[resp.weather[1].icon] + temp_widget:set_text(gen_temperature_str(resp.main.temp, '%.0f', both_units_widget)) + end + end) + weather_timer:start() + weather_timer:emit_signal("timeout") + + --- Notification with weather information. Popups when mouse hovers over the icon + local notification + weather_widget:connect_signal("mouse::enter", function() + notification = naughty.notify{ + icon = path_to_icons .. icon_map[resp.weather[1].icon], + icon_size=20, + text = + '<big>' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')</big><br>' .. + '<b>Humidity:</b> ' .. resp.main.humidity .. '%<br>' .. + '<b>Temperature:</b> ' .. gen_temperature_str(resp.main.temp, '%.1f', + both_units_popup) .. '<br>' .. + '<b>Pressure:</b> ' .. resp.main.pressure .. 'hPa<br>' .. + '<b>Clouds:</b> ' .. resp.clouds.all .. '%<br>' .. + '<b>Wind:</b> ' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')', + timeout = 5, hover_timeout = 10, + width = (both_units_popup == true and 210 or 200) + } + end) + + weather_widget:connect_signal("mouse::leave", function() + naughty.destroy(notification) + end) + + return weather_widget +end -return weather_widget +return setmetatable(weather_widget, { __call = function(_, ...) + return worker(...) +end }) |