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) -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. +## Customization + +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 widget = {} -local text_with_background = wibox.container.background(text) +local function worker(args) -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 args = args or {} -local last_battery_check = os.time() + local font = args.font or 'Play 6' + local arc_thickness = args.thickness or 2 + local show_current_level = args.show_current_level or false -watch("acpi -i", 10, - function(widget, stdout) - local batteryType + 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 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 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 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 = 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() - 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 - -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, + 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 + text_with_background.bg = '#00000000' + text_with_background.fg = main_color + end + + if show_current_level == true then + --- if battery is fully charged (100) there is not enough place for three digits, so we don't show any text + text.text = charge == 100 + and '' + or string.format('%d', charge) + else + text.text = '' + end + + if charge < 15 then + widget.colors = { low_level_color } + if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then + -- if 5 minutes have elapsed since the last warning + last_battery_check = os.time() + + show_battery_warning() + end + elseif charge > 15 and charge < 40 then + widget.colors = { medium_level_color } + else + widget.colors = { main_color } + end + end, + 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 + end -return batteryarc +return setmetatable(widget, { __call = function(_, ...) + return worker(...) +end }) diff --git a/batteryarc-widget/warning.png b/batteryarc-widget/warning.png new file mode 100644 index 0000000..55ca790 Binary files /dev/null and b/batteryarc-widget/warning.png differ diff --git a/brightnessarc-widget/README.md b/brightnessarc-widget/README.md index d122d3a..e63f0dd 100644 --- a/brightnessarc-widget/README.md +++ b/brightnessarc-widget/README.md @@ -11,6 +11,7 @@ It is possible to customize widget by providing a table with all or some of the | `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: @@ -20,6 +21,7 @@ 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' }) ``` @@ -60,7 +62,7 @@ git clone https://github.com/streetturtle/awesome-wm-widgets.git ~/.config/aweso Require widget at the beginning of **rc.lua**: ```lua -local brightness_widget = require("awesome-wm-widgets.brightness-widget.brightness") +local brightnessarc_widget = require("awesome-wm-widgets.brightnessarc-widget.brightnessarc") ``` Add widget to the tasklist: diff --git a/brightnessarc-widget/brightnessarc.lua b/brightnessarc-widget/brightnessarc.lua index dac08e4..3c4641e 100644 --- a/brightnessarc-widget/brightnessarc.lua +++ b/brightnessarc-widget/brightnessarc.lua @@ -11,6 +11,7 @@ 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" @@ -26,6 +27,7 @@ local function worker(args) 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 = { @@ -44,6 +46,7 @@ local function worker(args) forced_width = 18, bg = "#ffffff11", paddings = 2, + colors = {color}, widget = wibox.container.arcchart } 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 new file mode 100644 index 0000000..086e618 Binary files /dev/null and b/cpu-widget/cpu.gif differ diff --git a/cpu-widget/custom.png b/cpu-widget/custom.png new file mode 100644 index 0000000..be275e4 Binary files /dev/null and b/cpu-widget/custom.png differ 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: -To use this widget clone repo under **~/.config/awesome/** and then add it in **rc.lua**: +```bash +git clone https://gist.github.com/fa6258f3ff7b17747ee3.git +cd ./fa6258f3ff7b17747ee3 +chmod +x sp +sudo cp ./sp /usr/local/bin/ +``` + +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 new file mode 100644 index 0000000..979ad31 Binary files /dev/null and b/spotify-widget/spo-wid-custom.png differ diff --git a/spotify-widget/spo-wid-default.png b/spotify-widget/spo-wid-default.png new file mode 100644 index 0000000..67785f2 Binary files /dev/null and b/spotify-widget/spo-wid-default.png differ 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) + local args = 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' + 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 -end -watch(GET_SPOTIFY_STATUS_CMD, 1, update_widget_icon, spotify_widget) -watch(GET_CURRENT_SONG_CMD, 1, update_widget_text, spotify_widget) - ---- Adds mouse controls to the widget: --- - left click - play/pause --- - scroll up - play next song --- - scroll down - play previous song -spotify_widget:connect_signal("button::press", function(_, _, _, button) - if (button == 1) then awful.spawn("sp play", false) -- left click - elseif (button == 4) then awful.spawn("sp next", false) -- scroll up - elseif (button == 5) then awful.spawn("sp prev", false) -- scroll down + 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/volumearc-widget/README.md b/volumearc-widget/README.md index 0bcd7c7..9f1a60e 100644 --- a/volumearc-widget/README.md +++ b/volumearc-widget/README.md @@ -36,7 +36,7 @@ volumearc_widget({ }) ``` -Above config results in following widget: +The config above results in the following widget: ![custom](./custom.png) diff --git a/weather-widget/README.md b/weather-widget/README.md index ef7282f..a7e67e5 100644 --- a/weather-widget/README.md +++ b/weather-widget/README.md @@ -4,6 +4,28 @@ 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 | + +### 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 +46,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 +61,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 d5f07f8..d060fd2 100644 --- a/weather-widget/weather.lua +++ b/weather-widget/weather.lua @@ -16,126 +16,141 @@ local secrets = require("awesome-wm-widgets.secrets") local path_to_icons = "/usr/share/icons/Arc/status/symbolic/" -local icon_widget = wibox.widget { - { - id = "icon", - resize = false, - widget = wibox.widget.imagebox, - }, - layout = wibox.container.margin(_ , 0, 0, 3), - set_image = function(self, path) - self.icon.image = path - end, -} +local weather_widget = {} -local temp_widget = wibox.widget{ - font = "Play 9", - widget = wibox.widget.textbox, -} +local function worker(args) -local weather_widget = wibox.widget { - icon_widget, - temp_widget, - layout = wibox.layout.fixed.horizontal, -} + local args = args or {} ---- 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" -} + 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' ---- 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 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] + + local temp_widget = wibox.widget { + font = font, + widget = wibox.widget.textbox, + } + + 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", + } + 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, status = http.request('https://api.openweathermap.org/data/2.5/weather?q=' + .. city + .. '&appid=' .. api_key + .. '&units=' .. units) + if (status ~= 200 and resp_json ~= nil) 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) 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+", "") + .. '°' + .. (units == 'metric' and 'C' or 'F')) + 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 = '' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')
' .. + 'Humidity: ' .. resp.main.humidity .. '%
' .. + 'Temperature: ' .. resp.main.temp .. '°' + .. (secrets.weather_widget_units == 'metric' and 'C' or 'F') .. '
' .. + 'Pressure: ' .. resp.main.pressure .. 'hPa
' .. + 'Clouds: ' .. resp.clouds.all .. '%
' .. + 'Wind: ' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')', + timeout = 5, hover_timeout = 10, + width = 200 + } + end) + + weather_widget:connect_signal("mouse::leave", function() + naughty.destroy(notification) + end) + + return weather_widget end -local weather_timer = gears.timer({ timeout = 60 }) -local resp - -weather_timer:connect_signal("timeout", function () - local resp_json, status = http.request('https://api.openweathermap.org/data/2.5/weather?q=' - .. secrets.weather_widget_city - .. '&appid=' .. secrets.weather_widget_api_key - .. '&units=' .. secrets.weather_widget_units) - if (status ~= 200 and resp_json ~= nil) 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) 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')) - 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 = - '' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')
' .. - 'Humidity: ' .. resp.main.humidity .. '%
' .. - 'Temperature: ' .. resp.main.temp .. '°' - .. (secrets.weather_widget_units == 'metric' and 'C' or 'F') .. '
' .. - 'Pressure: ' .. resp.main.pressure .. 'hPa
' .. - 'Clouds: ' .. resp.clouds.all .. '%
' .. - 'Wind: ' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')', - timeout = 5, hover_timeout = 10, - width = 200 - } -end) - -weather_widget:connect_signal("mouse::leave", function() - naughty.destroy(notification) -end) - -return weather_widget +return setmetatable(weather_widget, { __call = function(_, ...) + return worker(...) +end })