[awesome] Fixing the weather: cleanup
This commit is contained in:
parent
f4e2633363
commit
f5621990e1
22 changed files with 2 additions and 2786 deletions
|
@ -1,134 +0,0 @@
|
|||
---------------------------
|
||||
-- Default awesome theme --
|
||||
---------------------------
|
||||
|
||||
local theme_assets = require("beautiful.theme_assets")
|
||||
local xresources = require("beautiful.xresources")
|
||||
local dpi = xresources.apply_dpi
|
||||
|
||||
local gfs = require("gears.filesystem")
|
||||
local themes_path = gfs.get_themes_dir()
|
||||
|
||||
local theme = {}
|
||||
|
||||
theme.font = "Fantasque Sans Mono 8"
|
||||
|
||||
theme.bg_normal = "#222222"
|
||||
theme.bg_focus = "#535d6c"
|
||||
theme.bg_urgent = "#ff0000"
|
||||
theme.bg_minimize = "#444444"
|
||||
theme.bg_systray = theme.bg_normal
|
||||
|
||||
theme.fg_normal = "#aaaaaa"
|
||||
theme.fg_focus = "#ffffff"
|
||||
theme.fg_urgent = "#ffffff"
|
||||
theme.fg_minimize = "#ffffff"
|
||||
|
||||
theme.useless_gap = dpi(0)
|
||||
theme.border_width = dpi(1)
|
||||
theme.border_normal = "#000000"
|
||||
theme.border_focus = "#535d6c"
|
||||
theme.border_marked = "#91231c"
|
||||
|
||||
-- There are other variable sets
|
||||
-- overriding the default one when
|
||||
-- defined, the sets are:
|
||||
-- taglist_[bg|fg]_[focus|urgent|occupied|empty|volatile]
|
||||
-- tasklist_[bg|fg]_[focus|urgent]
|
||||
-- titlebar_[bg|fg]_[normal|focus]
|
||||
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
|
||||
-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
|
||||
-- prompt_[fg|bg|fg_cursor|bg_cursor|font]
|
||||
-- hotkeys_[bg|fg|border_width|border_color|shape|opacity|modifiers_fg|label_bg|label_fg|group_margin|font|description_font]
|
||||
-- Example:
|
||||
--theme.taglist_bg_focus = "#ff0000"
|
||||
|
||||
-- Generate taglist squares:
|
||||
local taglist_square_size = dpi(4)
|
||||
theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
|
||||
taglist_square_size, theme.fg_normal
|
||||
)
|
||||
theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
|
||||
taglist_square_size, theme.fg_normal
|
||||
)
|
||||
|
||||
-- Variables set for theming notifications:
|
||||
-- notification_font
|
||||
theme.notification_font = "Liberation Sans 8"
|
||||
-- notification_[bg|fg]
|
||||
theme.notification_bg = "#00ff00"
|
||||
theme.notification_fg = "#600060"
|
||||
-- notification_[width|height|margin]
|
||||
-- notification_[border_color|border_width|shape|opacity]
|
||||
|
||||
-- Variables set for theming the menu:
|
||||
-- menu_[bg|fg]_[normal|focus]
|
||||
-- menu_[border_color|border_width]
|
||||
theme.menu_submenu_icon = themes_path.."default/submenu.png"
|
||||
theme.menu_height = dpi(15)
|
||||
theme.menu_width = dpi(100)
|
||||
|
||||
-- You can add as many variables as
|
||||
-- you wish and access them by using
|
||||
-- beautiful.variable in your rc.lua
|
||||
--theme.bg_widget = "#cc0000"
|
||||
|
||||
-- Define the image to load
|
||||
theme.titlebar_close_button_normal = themes_path.."default/titlebar/close_normal.png"
|
||||
theme.titlebar_close_button_focus = themes_path.."default/titlebar/close_focus.png"
|
||||
|
||||
theme.titlebar_minimize_button_normal = themes_path.."default/titlebar/minimize_normal.png"
|
||||
theme.titlebar_minimize_button_focus = themes_path.."default/titlebar/minimize_focus.png"
|
||||
|
||||
theme.titlebar_ontop_button_normal_inactive = themes_path.."default/titlebar/ontop_normal_inactive.png"
|
||||
theme.titlebar_ontop_button_focus_inactive = themes_path.."default/titlebar/ontop_focus_inactive.png"
|
||||
theme.titlebar_ontop_button_normal_active = themes_path.."default/titlebar/ontop_normal_active.png"
|
||||
theme.titlebar_ontop_button_focus_active = themes_path.."default/titlebar/ontop_focus_active.png"
|
||||
|
||||
theme.titlebar_sticky_button_normal_inactive = themes_path.."default/titlebar/sticky_normal_inactive.png"
|
||||
theme.titlebar_sticky_button_focus_inactive = themes_path.."default/titlebar/sticky_focus_inactive.png"
|
||||
theme.titlebar_sticky_button_normal_active = themes_path.."default/titlebar/sticky_normal_active.png"
|
||||
theme.titlebar_sticky_button_focus_active = themes_path.."default/titlebar/sticky_focus_active.png"
|
||||
|
||||
theme.titlebar_floating_button_normal_inactive = themes_path.."default/titlebar/floating_normal_inactive.png"
|
||||
theme.titlebar_floating_button_focus_inactive = themes_path.."default/titlebar/floating_focus_inactive.png"
|
||||
theme.titlebar_floating_button_normal_active = themes_path.."default/titlebar/floating_normal_active.png"
|
||||
theme.titlebar_floating_button_focus_active = themes_path.."default/titlebar/floating_focus_active.png"
|
||||
|
||||
theme.titlebar_maximized_button_normal_inactive = themes_path.."default/titlebar/maximized_normal_inactive.png"
|
||||
theme.titlebar_maximized_button_focus_inactive = themes_path.."default/titlebar/maximized_focus_inactive.png"
|
||||
theme.titlebar_maximized_button_normal_active = themes_path.."default/titlebar/maximized_normal_active.png"
|
||||
theme.titlebar_maximized_button_focus_active = themes_path.."default/titlebar/maximized_focus_active.png"
|
||||
|
||||
theme.wallpaper = themes_path.."default/background.png"
|
||||
|
||||
-- You can use your own layout icons like this:
|
||||
theme.layout_fairh = themes_path.."default/layouts/fairhw.png"
|
||||
theme.layout_fairv = themes_path.."default/layouts/fairvw.png"
|
||||
theme.layout_floating = themes_path.."default/layouts/floatingw.png"
|
||||
theme.layout_magnifier = themes_path.."default/layouts/magnifierw.png"
|
||||
theme.layout_max = themes_path.."default/layouts/maxw.png"
|
||||
theme.layout_fullscreen = themes_path.."default/layouts/fullscreenw.png"
|
||||
theme.layout_tilebottom = themes_path.."default/layouts/tilebottomw.png"
|
||||
theme.layout_tileleft = themes_path.."default/layouts/tileleftw.png"
|
||||
theme.layout_tile = themes_path.."default/layouts/tilew.png"
|
||||
theme.layout_tiletop = themes_path.."default/layouts/tiletopw.png"
|
||||
theme.layout_spiral = themes_path.."default/layouts/spiralw.png"
|
||||
theme.layout_dwindle = themes_path.."default/layouts/dwindlew.png"
|
||||
theme.layout_cornernw = themes_path.."default/layouts/cornernww.png"
|
||||
theme.layout_cornerne = themes_path.."default/layouts/cornernew.png"
|
||||
theme.layout_cornersw = themes_path.."default/layouts/cornersww.png"
|
||||
theme.layout_cornerse = themes_path.."default/layouts/cornersew.png"
|
||||
|
||||
-- Generate Awesome icon:
|
||||
theme.awesome_icon = theme_assets.awesome_icon(
|
||||
theme.menu_height, theme.bg_focus, theme.fg_focus
|
||||
)
|
||||
|
||||
-- Define the icon theme for application icons. If not set then the icons
|
||||
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
|
||||
theme.icon_theme = nil
|
||||
|
||||
return theme
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -1,692 +0,0 @@
|
|||
-- If LuaRocks is installed, make sure that packages installed through it are
|
||||
-- found (e.g. lgi). If LuaRocks is not installed, do nothing.
|
||||
pcall(require, "luarocks.loader")
|
||||
|
||||
-- Standard awesome library
|
||||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
require("awful.autofocus")
|
||||
-- Widget and layout library
|
||||
local wibox = require("wibox")
|
||||
-- Theme handling library
|
||||
local beautiful = require("beautiful")
|
||||
-- Notification library
|
||||
local naughty = require("naughty")
|
||||
local menubar = require("menubar")
|
||||
local lain = require("lain")
|
||||
-- local ruled = require("ruled")
|
||||
local hotkeys_popup = require("awful.hotkeys_popup")
|
||||
-- Enable hotkeys help widget for VIM and other apps
|
||||
-- when client with a matching name is opened:
|
||||
require("awful.hotkeys_popup.keys")
|
||||
|
||||
-- {{{ Error handling
|
||||
-- Check if awesome encountered an error during startup and fell back to
|
||||
-- another config (This code will only ever execute for the fallback config)
|
||||
if awesome.startup_errors then
|
||||
naughty.notify({
|
||||
preset = naughty.config.presets.critical,
|
||||
title = "Oops, there were errors during startup!",
|
||||
text = awesome.startup_errors,
|
||||
})
|
||||
end
|
||||
|
||||
-- Handle runtime errors after startup
|
||||
do
|
||||
local in_error = false
|
||||
awesome.connect_signal("debug::error", function(err)
|
||||
-- Make sure we don't go into an endless error loop
|
||||
if in_error then
|
||||
return
|
||||
end
|
||||
in_error = true
|
||||
|
||||
naughty.notify({
|
||||
preset = naughty.config.presets.critical,
|
||||
title = "Oops, an error happened!",
|
||||
text = tostring(err),
|
||||
})
|
||||
in_error = false
|
||||
end)
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ Variable definitions
|
||||
-- Themes define colours, icons, font and wallpapers.
|
||||
-- beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
|
||||
beautiful.init(gears.filesystem.get_configuration_dir() .. "mytheme.lua")
|
||||
|
||||
-- This is used later as the default terminal and editor to run.
|
||||
-- local terminal = "wezterm"
|
||||
--[[
|
||||
terminal = function()
|
||||
local is_running = os.execute("pgrep alacritty")
|
||||
if is_running == nil then
|
||||
return "/usr/sbin/alacritty --socket /run/user/1000/alacritty-main.sock"
|
||||
else
|
||||
return "/usr/sbin/alacritty msg --socket /run/user/1000/alacritty-main.sock create-window"
|
||||
end
|
||||
end
|
||||
]]
|
||||
--
|
||||
local terminal = function()
|
||||
local is_running = os.execute("pgrep wezterm")
|
||||
if is_running == nil then
|
||||
return "/usr/sbin/wezterm start"
|
||||
else
|
||||
return "/usr/sbin/wezterm cli spawn --new-window"
|
||||
end
|
||||
end
|
||||
local editor = os.getenv("EDITOR") or "nano"
|
||||
local editor_cmd = terminal() .. " -- " .. editor
|
||||
-- local editor_cmd = terminal .. " -e " .. editor
|
||||
|
||||
-- Default modkey.
|
||||
-- Usually, Mod4 is the key with a logo between Control and Alt.
|
||||
-- If you do not like this or do not have such a key,
|
||||
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
|
||||
-- However, you can use another modifier like Mod1, but it may interact with others.
|
||||
modkey = "Mod4"
|
||||
|
||||
-- Table of layouts to cover with awful.layout.inc, order matters.
|
||||
-- awful.layout.layouts = {
|
||||
awful.layout.append_default_layouts({
|
||||
-- awful.layout.suit.tile,
|
||||
awful.layout.suit.max,
|
||||
awful.layout.suit.max.fullscreen,
|
||||
awful.layout.suit.tile.left,
|
||||
awful.layout.suit.tile.bottom,
|
||||
awful.layout.suit.tile.top,
|
||||
awful.layout.suit.fair,
|
||||
awful.layout.suit.fair.horizontal,
|
||||
awful.layout.suit.spiral,
|
||||
awful.layout.suit.spiral.dwindle,
|
||||
awful.layout.suit.magnifier,
|
||||
awful.layout.suit.corner.nw,
|
||||
awful.layout.suit.floating,
|
||||
-- awful.layout.suit.corner.ne,
|
||||
-- awful.layout.suit.corner.sw,
|
||||
-- awful.layout.suit.corner.se,
|
||||
})
|
||||
-- }}}
|
||||
|
||||
-- {{{ Menu
|
||||
-- Create a launcher widget and a main menu
|
||||
myawesomemenu = {
|
||||
{
|
||||
"hotkeys",
|
||||
function()
|
||||
hotkeys_popup.show_help(nil, awful.screen.focused())
|
||||
end,
|
||||
},
|
||||
{ "manual", terminal() .. " -e man awesome" },
|
||||
{ "edit config", editor_cmd .. " " .. awesome.conffile },
|
||||
{ "restart", awesome.restart },
|
||||
{
|
||||
"quit",
|
||||
function()
|
||||
awesome.quit()
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
mymainmenu = awful.menu({
|
||||
items = {
|
||||
{ "awesome", myawesomemenu, beautiful.awesome_icon },
|
||||
{ "open terminal", terminal() },
|
||||
},
|
||||
})
|
||||
|
||||
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, menu = mymainmenu })
|
||||
|
||||
-- Menubar configuration
|
||||
menubar.utils.terminal = terminal() -- Set the terminal for applications that require it
|
||||
-- }}}
|
||||
|
||||
-- Keyboard map indicator and switcher
|
||||
mykeyboardlayout = awful.widget.keyboardlayout()
|
||||
|
||||
-- {{{ Wibar
|
||||
-- Create a textclock widget
|
||||
mytextclock = wibox.widget.textclock()
|
||||
|
||||
-- Create a wibox for each screen and add it
|
||||
local taglist_buttons = gears.table.join(
|
||||
awful.button({}, 1, function(t)
|
||||
t:view_only()
|
||||
end),
|
||||
awful.button({ modkey }, 1, function(t)
|
||||
if client.focus then
|
||||
client.focus:move_to_tag(t)
|
||||
end
|
||||
end),
|
||||
awful.button({}, 3, awful.tag.viewtoggle),
|
||||
awful.button({ modkey }, 3, function(t)
|
||||
if client.focus then
|
||||
client.focus:toggle_tag(t)
|
||||
end
|
||||
end),
|
||||
awful.button({}, 4, function(t)
|
||||
awful.tag.viewnext(t.screen)
|
||||
end),
|
||||
awful.button({}, 5, function(t)
|
||||
awful.tag.viewprev(t.screen)
|
||||
end)
|
||||
)
|
||||
|
||||
local tasklist_buttons = gears.table.join(
|
||||
awful.button({}, 1, function(c)
|
||||
if c == client.focus then
|
||||
c.minimized = true
|
||||
else
|
||||
c:emit_signal("request::activate", "tasklist", { raise = true })
|
||||
end
|
||||
end),
|
||||
awful.button({}, 3, function()
|
||||
awful.menu.client_list({ theme = { width = 250 } })
|
||||
end),
|
||||
awful.button({}, 4, function()
|
||||
awful.client.focus.byidx(1)
|
||||
end),
|
||||
awful.button({}, 5, function()
|
||||
awful.client.focus.byidx(-1)
|
||||
end)
|
||||
)
|
||||
|
||||
local function set_wallpaper(s)
|
||||
-- Wallpaper
|
||||
if beautiful.wallpaper then
|
||||
-- local wallpaper = beautiful.wallpaper
|
||||
local wallpaper = "/home/adam/Pictures/wallpapers/shared/montauk-light-01.jpg"
|
||||
-- If wallpaper is a function, call it with the screen
|
||||
if type(wallpaper) == "function" then
|
||||
wallpaper = wallpaper(s)
|
||||
end
|
||||
gears.wallpaper.maximized(wallpaper, s, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Notifications
|
||||
--[[
|
||||
ruled.notification.connect_signal("request::rules", function()
|
||||
-- Add a red background for urgent notifications.
|
||||
ruled.notification.append_rule {
|
||||
rule = { urgency = "critical" },
|
||||
properties = { bg = "#ff0000", fg = "#32cd32", timeout = 0 }
|
||||
}
|
||||
|
||||
-- Or green background for normal ones.
|
||||
ruled.notification.append_rule {
|
||||
rule = { urgency = "normal" },
|
||||
properties = { bg = "#32cd32", fg = "#800080"}
|
||||
}
|
||||
ruled.notification.append_rule {
|
||||
rule = { urgency = "low" },
|
||||
properties = { bg = "#bbccff", fg = "#191970"}
|
||||
}
|
||||
end)
|
||||
--]]
|
||||
|
||||
-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
|
||||
screen.connect_signal("property::geometry", set_wallpaper)
|
||||
|
||||
local mymem = lain.widget.mem({
|
||||
settings = function()
|
||||
local mem_spacer = ""
|
||||
local swp_spacer = ""
|
||||
local swp_display = math.floor((mem_now.swapused / mem_now.swap) * 100)
|
||||
if mem_now.perc < 10 then
|
||||
mem_spacer = " "
|
||||
end
|
||||
if swp_display < 10 then
|
||||
swp_spacer = " "
|
||||
end
|
||||
widget:set_markup(" mem " .. mem_spacer .. mem_now.perc .. " swp " .. swp_spacer .. swp_display .. " ")
|
||||
end,
|
||||
})
|
||||
|
||||
local mycpu = lain.widget.cpu({
|
||||
settings = function()
|
||||
local cpu_spacer = ""
|
||||
if cpu_now.usage < 10 then
|
||||
cpu_spacer = " "
|
||||
end
|
||||
widget:set_markup(" cpu " .. cpu_spacer .. cpu_now.usage)
|
||||
end,
|
||||
})
|
||||
|
||||
local myweather = lain.widget.weather({
|
||||
APPID = "f6497dd133dd22b541abc8bbe8360f3b",
|
||||
lat = 40.651,
|
||||
lon = -73.949,
|
||||
units = "imperial",
|
||||
notification_text_fun = function(wn)
|
||||
local day = os.date("%a %d", wn["dt"])
|
||||
local temp = math.floor(wn["main"]["temp"])
|
||||
local desc = wn["weather"][1]["description"]
|
||||
return string.format("<b>%s</b>: %s, %d ", day, desc, temp)
|
||||
end,
|
||||
settings = function()
|
||||
units = math.floor(weather_now["main"]["temp"])
|
||||
widget:set_markup(" " .. units .. " ")
|
||||
end,
|
||||
})
|
||||
|
||||
awful.screen.connect_for_each_screen(function(s)
|
||||
-- Wallpaper
|
||||
set_wallpaper(s)
|
||||
|
||||
-- Each screen has its own tag table.
|
||||
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
|
||||
|
||||
-- Create a promptbox for each screen
|
||||
s.mypromptbox = awful.widget.prompt()
|
||||
-- Create an imagebox widget which will contain an icon indicating which layout we're using.
|
||||
-- We need one layoutbox per screen.
|
||||
s.mylayoutbox = awful.widget.layoutbox(s)
|
||||
s.mylayoutbox:buttons(gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
awful.layout.inc(1)
|
||||
end),
|
||||
awful.button({}, 3, function()
|
||||
awful.layout.inc(-1)
|
||||
end),
|
||||
awful.button({}, 4, function()
|
||||
awful.layout.inc(1)
|
||||
end),
|
||||
awful.button({}, 5, function()
|
||||
awful.layout.inc(-1)
|
||||
end)
|
||||
))
|
||||
-- Create a taglist widget
|
||||
s.mytaglist = awful.widget.taglist({
|
||||
screen = s,
|
||||
filter = awful.widget.taglist.filter.all,
|
||||
buttons = taglist_buttons,
|
||||
})
|
||||
|
||||
-- Create a tasklist widget
|
||||
s.mytasklist = awful.widget.tasklist({
|
||||
screen = s,
|
||||
filter = awful.widget.tasklist.filter.currenttags,
|
||||
buttons = tasklist_buttons,
|
||||
})
|
||||
|
||||
-- Create the wibox
|
||||
s.mywibox = awful.wibar({ position = "top", screen = s })
|
||||
|
||||
-- Add widgets to the wibox
|
||||
s.mywibox:setup({
|
||||
layout = wibox.layout.align.horizontal,
|
||||
{ -- Left widgets
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
mylauncher,
|
||||
s.mytaglist,
|
||||
s.mypromptbox,
|
||||
},
|
||||
s.mytasklist, -- Middle widget
|
||||
{ -- Right widgets
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
mycpu.widget,
|
||||
mymem.widget,
|
||||
wibox.widget.systray(),
|
||||
myweather.icon,
|
||||
myweather.widget,
|
||||
mytextclock,
|
||||
s.mylayoutbox,
|
||||
},
|
||||
})
|
||||
end)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Mouse bindings
|
||||
root.buttons(gears.table.join(
|
||||
awful.button({}, 3, function()
|
||||
mymainmenu:toggle()
|
||||
end),
|
||||
awful.button({}, 4, awful.tag.viewnext),
|
||||
awful.button({}, 5, awful.tag.viewprev)
|
||||
))
|
||||
-- }}}
|
||||
|
||||
-- {{{ Key bindings
|
||||
globalkeys = gears.table.join(
|
||||
awful.key({ modkey }, "s", hotkeys_popup.show_help, { description = "show help", group = "awesome" }),
|
||||
awful.key({ modkey }, "Left", awful.tag.viewprev, { description = "view previous", group = "tag" }),
|
||||
awful.key({ modkey }, "Right", awful.tag.viewnext, { description = "view next", group = "tag" }),
|
||||
awful.key({ modkey }, "Escape", awful.tag.history.restore, { description = "go back", group = "tag" }),
|
||||
|
||||
awful.key({ modkey }, "j", function()
|
||||
awful.client.focus.byidx(1)
|
||||
end, { description = "focus next by index", group = "client" }),
|
||||
awful.key({ modkey }, "k", function()
|
||||
awful.client.focus.byidx(-1)
|
||||
end, { description = "focus previous by index", group = "client" }),
|
||||
awful.key({ modkey }, "w", function()
|
||||
mymainmenu:show()
|
||||
end, { description = "show main menu", group = "awesome" }),
|
||||
|
||||
-- Layout manipulation
|
||||
awful.key({ modkey, "Shift" }, "j", function()
|
||||
awful.client.swap.byidx(1)
|
||||
end, { description = "swap with next client by index", group = "client" }),
|
||||
awful.key({ modkey, "Shift" }, "k", function()
|
||||
awful.client.swap.byidx(-1)
|
||||
end, { description = "swap with previous client by index", group = "client" }),
|
||||
awful.key({ modkey, "Control" }, "j", function()
|
||||
awful.screen.focus_relative(1)
|
||||
end, { description = "focus the next screen", group = "screen" }),
|
||||
awful.key({ modkey, "Control" }, "k", function()
|
||||
awful.screen.focus_relative(-1)
|
||||
end, { description = "focus the previous screen", group = "screen" }),
|
||||
awful.key({ modkey }, "u", awful.client.urgent.jumpto, { description = "jump to urgent client", group = "client" }),
|
||||
awful.key({ modkey }, "Tab", function()
|
||||
awful.client.focus.history.previous()
|
||||
if client.focus then
|
||||
client.focus:raise()
|
||||
end
|
||||
end, { description = "go back", group = "client" }),
|
||||
|
||||
-- Standard program
|
||||
awful.key({ modkey }, "Return", function()
|
||||
awful.spawn(terminal())
|
||||
end, { description = "open a terminal", group = "launcher" }),
|
||||
awful.key({ modkey, "Control" }, "r", awesome.restart, { description = "reload awesome", group = "awesome" }),
|
||||
awful.key({ modkey, "Shift" }, "q", awesome.quit, { description = "quit awesome", group = "awesome" }),
|
||||
|
||||
awful.key({ modkey }, "l", function()
|
||||
awful.tag.incmwfact(0.05)
|
||||
end, { description = "increase master width factor", group = "layout" }),
|
||||
awful.key({ modkey }, "h", function()
|
||||
awful.tag.incmwfact(-0.05)
|
||||
end, { description = "decrease master width factor", group = "layout" }),
|
||||
awful.key({ modkey, "Shift" }, "h", function()
|
||||
awful.tag.incnmaster(1, nil, true)
|
||||
end, { description = "increase the number of master clients", group = "layout" }),
|
||||
awful.key({ modkey, "Shift" }, "l", function()
|
||||
awful.tag.incnmaster(-1, nil, true)
|
||||
end, { description = "decrease the number of master clients", group = "layout" }),
|
||||
awful.key({ modkey, "Control" }, "h", function()
|
||||
awful.tag.incncol(1, nil, true)
|
||||
end, { description = "increase the number of columns", group = "layout" }),
|
||||
awful.key({ modkey, "Control" }, "l", function()
|
||||
awful.tag.incncol(-1, nil, true)
|
||||
end, { description = "decrease the number of columns", group = "layout" }),
|
||||
awful.key({ modkey }, "space", function()
|
||||
awful.layout.inc(1)
|
||||
end, { description = "select next", group = "layout" }),
|
||||
awful.key({ modkey, "Shift" }, "space", function()
|
||||
awful.layout.inc(-1)
|
||||
end, { description = "select previous", group = "layout" }),
|
||||
|
||||
awful.key({ modkey, "Control" }, "n", function()
|
||||
local c = awful.client.restore()
|
||||
-- Focus restored client
|
||||
if c then
|
||||
c:emit_signal("request::activate", "key.unminimize", { raise = true })
|
||||
end
|
||||
end, { description = "restore minimized", group = "client" }),
|
||||
|
||||
-- Prompt
|
||||
awful.key({ modkey }, "r", function()
|
||||
awful.screen.focused().mypromptbox:run()
|
||||
end, { description = "run prompt", group = "launcher" }),
|
||||
|
||||
awful.key({ modkey }, "x", function()
|
||||
awful.prompt.run({
|
||||
prompt = "Run Lua code: ",
|
||||
textbox = awful.screen.focused().mypromptbox.widget,
|
||||
exe_callback = awful.util.eval,
|
||||
history_path = awful.util.get_cache_dir() .. "/history_eval",
|
||||
})
|
||||
end, { description = "lua execute prompt", group = "awesome" }),
|
||||
-- Menubar
|
||||
awful.key({ modkey }, "p", function()
|
||||
os.execute("dmenu_run")
|
||||
end, { description = "show the menubar", group = "launcher" }),
|
||||
awful.key({}, "XF86MonBrightnessUp", function()
|
||||
awful.spawn("xbacklight -inc 10")
|
||||
end, { description = "Brighten the screen", group = "monitor" }),
|
||||
awful.key({}, "XF86MonBrightnessDown", function()
|
||||
awful.spawn("xbacklight -dec 10")
|
||||
end, { description = "Brighten the screen", group = "monitor" })
|
||||
)
|
||||
|
||||
clientkeys = gears.table.join(
|
||||
awful.key({ modkey }, "f", function(c)
|
||||
c.fullscreen = not c.fullscreen
|
||||
c:raise()
|
||||
end, { description = "toggle fullscreen", group = "client" }),
|
||||
awful.key({ modkey, "Shift" }, "c", function(c)
|
||||
c:kill()
|
||||
end, { description = "close", group = "client" }),
|
||||
awful.key(
|
||||
{ modkey, "Control" },
|
||||
"space",
|
||||
awful.client.floating.toggle,
|
||||
{ description = "toggle floating", group = "client" }
|
||||
),
|
||||
awful.key({ modkey, "Control" }, "Return", function(c)
|
||||
c:swap(awful.client.getmaster())
|
||||
end, { description = "move to master", group = "client" }),
|
||||
awful.key({ modkey }, "o", function(c)
|
||||
c:move_to_screen()
|
||||
end, { description = "move to screen", group = "client" }),
|
||||
awful.key({ modkey }, "t", function(c)
|
||||
c.ontop = not c.ontop
|
||||
end, { description = "toggle keep on top", group = "client" }),
|
||||
awful.key({ modkey }, "n", function(c)
|
||||
-- The client currently has the input focus, so it cannot be
|
||||
-- minimized, since minimized clients can't have the focus.
|
||||
c.minimized = true
|
||||
end, { description = "minimize", group = "client" }),
|
||||
awful.key({ modkey }, "m", function(c)
|
||||
c.maximized = not c.maximized
|
||||
c:raise()
|
||||
end, { description = "(un)maximize", group = "client" }),
|
||||
awful.key({ modkey, "Control" }, "m", function(c)
|
||||
c.maximized_vertical = not c.maximized_vertical
|
||||
c:raise()
|
||||
end, { description = "(un)maximize vertically", group = "client" }),
|
||||
awful.key({ modkey, "Shift" }, "m", function(c)
|
||||
c.maximized_horizontal = not c.maximized_horizontal
|
||||
c:raise()
|
||||
end, { description = "(un)maximize horizontally", group = "client" })
|
||||
)
|
||||
|
||||
-- Bind all key numbers to tags.
|
||||
-- Be careful: we use keycodes to make it work on any keyboard layout.
|
||||
-- This should map on the top row of your keyboard, usually 1 to 9.
|
||||
for i = 1, 9 do
|
||||
globalkeys = gears.table.join(
|
||||
globalkeys,
|
||||
-- View tag only.
|
||||
awful.key({ modkey }, "#" .. i + 9, function()
|
||||
local screen = awful.screen.focused()
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
tag:view_only()
|
||||
end
|
||||
end, { description = "view tag #" .. i, group = "tag" }),
|
||||
-- Toggle tag display.
|
||||
awful.key({ modkey, "Control" }, "#" .. i + 9, function()
|
||||
local screen = awful.screen.focused()
|
||||
local tag = screen.tags[i]
|
||||
if tag then
|
||||
awful.tag.viewtoggle(tag)
|
||||
end
|
||||
end, { description = "toggle tag #" .. i, group = "tag" }),
|
||||
-- Move client to tag.
|
||||
awful.key({ modkey, "Shift" }, "#" .. i + 9, function()
|
||||
if client.focus then
|
||||
local tag = client.focus.screen.tags[i]
|
||||
if tag then
|
||||
client.focus:move_to_tag(tag)
|
||||
end
|
||||
end
|
||||
end, { description = "move focused client to tag #" .. i, group = "tag" }),
|
||||
-- Toggle tag on focused client.
|
||||
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, function()
|
||||
if client.focus then
|
||||
local tag = client.focus.screen.tags[i]
|
||||
if tag then
|
||||
client.focus:toggle_tag(tag)
|
||||
end
|
||||
end
|
||||
end, { description = "toggle focused client on tag #" .. i, group = "tag" })
|
||||
)
|
||||
end
|
||||
|
||||
clientbuttons = gears.table.join(
|
||||
awful.button({}, 1, function(c)
|
||||
c:emit_signal("request::activate", "mouse_click", { raise = true })
|
||||
end),
|
||||
awful.button({ modkey }, 1, function(c)
|
||||
c:emit_signal("request::activate", "mouse_click", { raise = true })
|
||||
awful.mouse.client.move(c)
|
||||
end),
|
||||
awful.button({ modkey }, 3, function(c)
|
||||
c:emit_signal("request::activate", "mouse_click", { raise = true })
|
||||
awful.mouse.client.resize(c)
|
||||
end)
|
||||
)
|
||||
|
||||
-- Set keys
|
||||
root.keys(globalkeys)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Rules
|
||||
-- Rules to apply to new clients (through the "manage" signal).
|
||||
awful.rules.rules = {
|
||||
-- All clients will match this rule.
|
||||
{
|
||||
rule = {},
|
||||
properties = {
|
||||
border_width = beautiful.border_width,
|
||||
border_color = beautiful.border_normal,
|
||||
focus = awful.client.focus.filter,
|
||||
raise = true,
|
||||
keys = clientkeys,
|
||||
buttons = clientbuttons,
|
||||
screen = awful.screen.preferred,
|
||||
placement = awful.placement.no_overlap + awful.placement.no_offscreen,
|
||||
},
|
||||
},
|
||||
|
||||
-- Floating clients.
|
||||
{
|
||||
rule_any = {
|
||||
instance = {
|
||||
"DTA", -- Firefox addon DownThemAll.
|
||||
"copyq", -- Includes session name in class.
|
||||
"pinentry",
|
||||
},
|
||||
class = {
|
||||
"Arandr",
|
||||
"Blueman-manager",
|
||||
"Gpick",
|
||||
"Kruler",
|
||||
"MessageWin", -- kalarm.
|
||||
"Sxiv",
|
||||
"Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
|
||||
"Wpa_gui",
|
||||
"veromix",
|
||||
"xtightvncviewer",
|
||||
},
|
||||
|
||||
-- Note that the name property shown in xprop might be set slightly after creation of the client
|
||||
-- and the name shown there might not match defined rules here.
|
||||
name = {
|
||||
"Event Tester", -- xev.
|
||||
},
|
||||
role = {
|
||||
"AlarmWindow", -- Thunderbird's calendar.
|
||||
"ConfigManager", -- Thunderbird's about:config.
|
||||
"pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
|
||||
},
|
||||
},
|
||||
properties = { floating = true },
|
||||
},
|
||||
|
||||
-- Add titlebars to normal clients and dialogs
|
||||
{ rule_any = { type = { "normal", "dialog" } }, properties = { titlebars_enabled = true } },
|
||||
|
||||
-- Set Firefox to always map on the tag named "2" on screen 1.
|
||||
-- { rule = { class = "Firefox" },
|
||||
-- properties = { screen = 1, tag = "2" } },
|
||||
{ rule = { class = "KeePassXC" }, properties = { screen = 1, tag = "2" } },
|
||||
{ rule = { class = "btop" }, properties = { screen = 1, tag = "9" } },
|
||||
{ rule = { class = "qutebrowser" }, properties = { screen = 1, tag = "2" } },
|
||||
{ rule = { class = "librewolf" }, properties = { screen = 1, tag = "2" } },
|
||||
{ rule = { class = "wezterm" }, properties = { screen = 1, tag = "1" } },
|
||||
}
|
||||
-- }}}
|
||||
|
||||
-- {{{ Signals
|
||||
-- Signal function to execute when a new client appears.
|
||||
client.connect_signal("manage", function(c)
|
||||
-- Set the windows at the slave,
|
||||
-- i.e. put it at the end of others instead of setting it master.
|
||||
-- if not awesome.startup then awful.client.setslave(c) end
|
||||
|
||||
if awesome.startup and not c.size_hints.user_position and not c.size_hints.program_position then
|
||||
-- Prevent clients from being unreachable after screen count changes.
|
||||
awful.placement.no_offscreen(c)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Add a titlebar if titlebars_enabled is set to true in the rules.
|
||||
client.connect_signal("request::titlebars", function(c)
|
||||
-- buttons for the titlebar
|
||||
local buttons = gears.table.join(
|
||||
awful.button({}, 1, function()
|
||||
c:emit_signal("request::activate", "titlebar", { raise = true })
|
||||
awful.mouse.client.move(c)
|
||||
end),
|
||||
awful.button({}, 3, function()
|
||||
c:emit_signal("request::activate", "titlebar", { raise = true })
|
||||
awful.mouse.client.resize(c)
|
||||
end)
|
||||
)
|
||||
|
||||
awful.titlebar(c):setup({
|
||||
{ -- Left
|
||||
awful.titlebar.widget.iconwidget(c),
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.fixed.horizontal,
|
||||
},
|
||||
{ -- Middle
|
||||
{ -- Title
|
||||
align = "center",
|
||||
widget = awful.titlebar.widget.titlewidget(c),
|
||||
},
|
||||
buttons = buttons,
|
||||
layout = wibox.layout.flex.horizontal,
|
||||
},
|
||||
{ -- Right
|
||||
awful.titlebar.widget.floatingbutton(c),
|
||||
awful.titlebar.widget.maximizedbutton(c),
|
||||
awful.titlebar.widget.stickybutton(c),
|
||||
awful.titlebar.widget.ontopbutton(c),
|
||||
awful.titlebar.widget.closebutton(c),
|
||||
layout = wibox.layout.fixed.horizontal(),
|
||||
},
|
||||
layout = wibox.layout.align.horizontal,
|
||||
})
|
||||
end)
|
||||
|
||||
-- Autostart items
|
||||
awful.spawn.with_shell("~/.config/awesome/autorun.sh")
|
||||
|
||||
-- Enable sloppy focus, so that focus follows mouse.
|
||||
client.connect_signal("mouse::enter", function(c)
|
||||
c:emit_signal("request::activate", "mouse_enter", { raise = false })
|
||||
end)
|
||||
|
||||
client.connect_signal("focus", function(c)
|
||||
c.border_color = beautiful.border_focus
|
||||
end)
|
||||
client.connect_signal("unfocus", function(c)
|
||||
c.border_color = beautiful.border_normal
|
||||
end)
|
||||
-- }}}
|
3
awesome/lina/.gitmodules
vendored
3
awesome/lina/.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
|||
[submodule "lain.wiki"]
|
||||
path = wiki
|
||||
url = https://github.com/lcpz/lain.wiki.git
|
|
@ -1,54 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2010, Adrian C. <anrxc@sysphere.org>
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
|
||||
-- ALSA volume
|
||||
-- lina.widget.alsa
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
local alsa = { widget = args.widget or wibox.widget.textbox() }
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
|
||||
alsa.cmd = args.cmd or "amixer"
|
||||
alsa.channel = args.channel or "Master"
|
||||
alsa.togglechannel = args.togglechannel
|
||||
|
||||
local format_cmd = string.format("%s get %s", alsa.cmd, alsa.channel)
|
||||
|
||||
if alsa.togglechannel then
|
||||
format_cmd = { shell, "-c", string.format("%s get %s; %s get %s",
|
||||
alsa.cmd, alsa.channel, alsa.cmd, alsa.togglechannel) }
|
||||
end
|
||||
|
||||
alsa.last = {}
|
||||
|
||||
function alsa.update()
|
||||
helpers.async(format_cmd, function(mixer)
|
||||
local l,s = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
|
||||
l = tonumber(l)
|
||||
if alsa.last.level ~= l or alsa.last.status ~= s then
|
||||
volume_now = { level = l, status = s }
|
||||
widget = alsa.widget
|
||||
settings()
|
||||
alsa.last = volume_now
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.newtimer(string.format("alsa-%s-%s", alsa.cmd, alsa.channel), timeout, alsa.update)
|
||||
|
||||
return alsa
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,166 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2013, Rman
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local math = math
|
||||
local string = string
|
||||
local type = type
|
||||
local tonumber = tonumber
|
||||
|
||||
-- ALSA volume bar
|
||||
-- lina.widget.alsabar
|
||||
|
||||
local function factory(args)
|
||||
local alsabar = {
|
||||
colors = {
|
||||
background = "#000000",
|
||||
mute = "#EB8F8F",
|
||||
unmute = "#A4CE8A"
|
||||
},
|
||||
|
||||
_current_level = 0,
|
||||
_playback = "off"
|
||||
}
|
||||
|
||||
args = args or {}
|
||||
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
local width = args.width or 63
|
||||
local height = args.height or 1
|
||||
local margins = args.margins or 1
|
||||
local ticks = args.ticks or false
|
||||
local ticks_size = args.ticks_size or 7
|
||||
local tick = args.tick or "|"
|
||||
local tick_pre = args.tick_pre or "["
|
||||
local tick_post = args.tick_post or "]"
|
||||
local tick_none = args.tick_none or " "
|
||||
|
||||
alsabar.cmd = args.cmd or "amixer"
|
||||
alsabar.channel = args.channel or "Master"
|
||||
alsabar.togglechannel = args.togglechannel
|
||||
alsabar.colors = args.colors or alsabar.colors
|
||||
alsabar.followtag = args.followtag or false
|
||||
alsabar.notification_preset = args.notification_preset
|
||||
|
||||
if not alsabar.notification_preset then
|
||||
alsabar.notification_preset = { font = "Monospace 10" }
|
||||
end
|
||||
|
||||
local format_cmd = string.format("%s get %s", alsabar.cmd, alsabar.channel)
|
||||
|
||||
if alsabar.togglechannel then
|
||||
format_cmd = { awful.util.shell, "-c", string.format("%s get %s; %s get %s",
|
||||
alsabar.cmd, alsabar.channel, alsabar.cmd, alsabar.togglechannel) }
|
||||
end
|
||||
|
||||
alsabar.bar = wibox.widget {
|
||||
color = alsabar.colors.unmute,
|
||||
background_color = alsabar.colors.background,
|
||||
forced_height = height,
|
||||
forced_width = width,
|
||||
margins = margins,
|
||||
paddings = margins,
|
||||
ticks = ticks,
|
||||
ticks_size = ticks_size,
|
||||
widget = wibox.widget.progressbar
|
||||
}
|
||||
|
||||
alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
|
||||
|
||||
function alsabar.update(callback)
|
||||
helpers.async(format_cmd, function(mixer)
|
||||
local vol, playback = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
|
||||
|
||||
if not vol or not playback then return end
|
||||
|
||||
if vol ~= alsabar._current_level or playback ~= alsabar._playback then
|
||||
alsabar._current_level = tonumber(vol)
|
||||
alsabar.bar:set_value(alsabar._current_level / 100)
|
||||
if alsabar._current_level == 0 or playback == "off" then
|
||||
alsabar._playback = playback
|
||||
alsabar.tooltip:set_text("[Muted]")
|
||||
alsabar.bar.color = alsabar.colors.mute
|
||||
else
|
||||
alsabar._playback = "on"
|
||||
alsabar.tooltip:set_text(string.format("%s: %s", alsabar.channel, vol))
|
||||
alsabar.bar.color = alsabar.colors.unmute
|
||||
end
|
||||
|
||||
volume_now = {
|
||||
level = alsabar._current_level,
|
||||
status = alsabar._playback
|
||||
}
|
||||
|
||||
settings()
|
||||
|
||||
if type(callback) == "function" then callback() end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function alsabar.notify()
|
||||
alsabar.update(function()
|
||||
local preset = alsabar.notification_preset
|
||||
|
||||
preset.title = string.format("%s - %s%%", alsabar.channel, alsabar._current_level)
|
||||
|
||||
if alsabar._playback == "off" then
|
||||
preset.title = preset.title .. " Muted"
|
||||
end
|
||||
|
||||
-- tot is the maximum number of ticks to display in the notification
|
||||
local tot = alsabar.notification_preset.max_ticks
|
||||
|
||||
if not tot then
|
||||
local wib = awful.screen.focused().mywibox
|
||||
-- if we can grab mywibox, tot is defined as its height if
|
||||
-- horizontal, or width otherwise
|
||||
if wib then
|
||||
if wib.position == "left" or wib.position == "right" then
|
||||
tot = wib.width
|
||||
else
|
||||
tot = wib.height
|
||||
end
|
||||
-- fallback: default horizontal wibox height
|
||||
else
|
||||
tot = 20
|
||||
end
|
||||
end
|
||||
|
||||
local int = math.modf((alsabar._current_level / 100) * tot)
|
||||
preset.text = string.format(
|
||||
"%s%s%s%s",
|
||||
tick_pre,
|
||||
string.rep(tick, int),
|
||||
string.rep(tick_none, tot - int),
|
||||
tick_post
|
||||
)
|
||||
|
||||
if alsabar.followtag then preset.screen = awful.screen.focused() end
|
||||
|
||||
if not alsabar.notification then
|
||||
alsabar.notification = naughty.notify {
|
||||
preset = preset,
|
||||
destroy = function() alsabar.notification = nil end
|
||||
}
|
||||
else
|
||||
naughty.replace_text(alsabar.notification, preset.title, preset.text)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.newtimer(string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel), timeout, alsabar.update)
|
||||
|
||||
return alsabar
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,236 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2010-2012, Peter Hofmann
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local fs = require("gears.filesystem")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local math = math
|
||||
local string = string
|
||||
local ipairs = ipairs
|
||||
local tonumber = tonumber
|
||||
|
||||
-- Battery infos
|
||||
-- lina.widget.bat
|
||||
|
||||
local function factory(args)
|
||||
local pspath = args.pspath or "/sys/class/power_supply/"
|
||||
|
||||
if not fs.is_dir(pspath) then
|
||||
naughty.notify { text = "lina.widget.bat: invalid power supply path", timeout = 0 }
|
||||
return
|
||||
end
|
||||
|
||||
args = args or {}
|
||||
|
||||
local bat = { widget = args.widget or wibox.widget.textbox() }
|
||||
local timeout = args.timeout or 30
|
||||
local notify = args.notify or "on"
|
||||
local full_notify = args.full_notify or notify
|
||||
local n_perc = args.n_perc or { 5, 15 }
|
||||
local batteries = args.batteries or (args.battery and {args.battery}) or {}
|
||||
local ac = args.ac or "AC0"
|
||||
local settings = args.settings or function() end
|
||||
|
||||
function bat.get_batteries()
|
||||
helpers.line_callback("ls -1 " .. pspath, function(line)
|
||||
local bstr = string.match(line, "BAT%w+")
|
||||
if bstr then
|
||||
batteries[#batteries + 1] = bstr
|
||||
else
|
||||
ac = string.match(line, "A%w+") or ac
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if #batteries == 0 then bat.get_batteries() end
|
||||
|
||||
bat_notification_critical_preset = {
|
||||
title = "Battery exhausted",
|
||||
text = "Shutdown imminent",
|
||||
timeout = 15,
|
||||
fg = "#000000",
|
||||
bg = "#FFFFFF"
|
||||
}
|
||||
|
||||
bat_notification_low_preset = {
|
||||
title = "Battery low",
|
||||
text = "Plug the cable!",
|
||||
timeout = 15,
|
||||
fg = "#202020",
|
||||
bg = "#CDCDCD"
|
||||
}
|
||||
|
||||
bat_notification_charged_preset = {
|
||||
title = "Battery full",
|
||||
text = "You can unplug the cable",
|
||||
timeout = 15,
|
||||
fg = "#202020",
|
||||
bg = "#CDCDCD"
|
||||
}
|
||||
|
||||
bat_now = {
|
||||
status = "N/A",
|
||||
ac_status = "N/A",
|
||||
perc = "N/A",
|
||||
time = "N/A",
|
||||
watt = "N/A",
|
||||
capacity = "N/A"
|
||||
}
|
||||
|
||||
bat_now.n_status = {}
|
||||
bat_now.n_perc = {}
|
||||
bat_now.n_capacity = {}
|
||||
for i = 1, #batteries do
|
||||
bat_now.n_status[i] = "N/A"
|
||||
bat_now.n_perc[i] = 0
|
||||
bat_now.n_capacity[i] = 0
|
||||
end
|
||||
|
||||
-- used to notify full charge only once before discharging
|
||||
local fullnotification = false
|
||||
|
||||
function bat.update()
|
||||
-- luacheck: globals bat_now
|
||||
local sum_rate_current = 0
|
||||
local sum_rate_voltage = 0
|
||||
local sum_rate_power = 0
|
||||
local sum_rate_energy = 0
|
||||
local sum_energy_now = 0
|
||||
local sum_energy_full = 0
|
||||
local sum_charge_full = 0
|
||||
local sum_charge_design = 0
|
||||
|
||||
for i, battery in ipairs(batteries) do
|
||||
local bstr = pspath .. battery
|
||||
local present = helpers.first_line(bstr .. "/present")
|
||||
|
||||
if tonumber(present) == 1 then
|
||||
-- current_now(I)[uA], voltage_now(U)[uV], power_now(P)[uW]
|
||||
local rate_current = tonumber(helpers.first_line(bstr .. "/current_now"))
|
||||
local rate_voltage = tonumber(helpers.first_line(bstr .. "/voltage_now"))
|
||||
local rate_power = tonumber(helpers.first_line(bstr .. "/power_now"))
|
||||
local charge_full = tonumber(helpers.first_line(bstr .. "/charge_full"))
|
||||
local charge_design = tonumber(helpers.first_line(bstr .. "/charge_full_design"))
|
||||
|
||||
-- energy_now(P)[uWh], charge_now(I)[uAh]
|
||||
local energy_now = tonumber(helpers.first_line(bstr .. "/energy_now") or
|
||||
helpers.first_line(bstr .. "/charge_now"))
|
||||
|
||||
-- energy_full(P)[uWh], charge_full(I)[uAh]
|
||||
local energy_full = tonumber(helpers.first_line(bstr .. "/energy_full") or
|
||||
charge_full)
|
||||
|
||||
local energy_percentage = tonumber(helpers.first_line(bstr .. "/capacity")) or
|
||||
math.floor((energy_now / energy_full) * 100)
|
||||
|
||||
bat_now.n_status[i] = helpers.first_line(bstr .. "/status") or "N/A"
|
||||
bat_now.n_perc[i] = energy_percentage or bat_now.n_perc[i]
|
||||
|
||||
if not charge_design or charge_design == 0 then
|
||||
bat_now.n_capacity[i] = 0
|
||||
else
|
||||
bat_now.n_capacity[i] = math.floor((charge_full / charge_design) * 100)
|
||||
end
|
||||
|
||||
sum_rate_current = sum_rate_current + (rate_current or 0)
|
||||
sum_rate_voltage = sum_rate_voltage + (rate_voltage or 0)
|
||||
sum_rate_power = sum_rate_power + (rate_power or 0)
|
||||
sum_rate_energy = sum_rate_energy + (rate_power or (((rate_voltage or 0) * (rate_current or 0)) / 1e6))
|
||||
sum_energy_now = sum_energy_now + (energy_now or 0)
|
||||
sum_energy_full = sum_energy_full + (energy_full or 0)
|
||||
sum_charge_full = sum_charge_full + (charge_full or 0)
|
||||
sum_charge_design = sum_charge_design + (charge_design or 0)
|
||||
end
|
||||
end
|
||||
|
||||
bat_now.capacity = math.floor(math.min(100, (sum_charge_full / sum_charge_design) * 100))
|
||||
|
||||
-- When one of the battery is charging, others' status are either
|
||||
-- "Full", "Unknown" or "Charging". When the laptop is not plugged in,
|
||||
-- one or more of the batteries may be full, but only one battery
|
||||
-- discharging suffices to set global status to "Discharging".
|
||||
bat_now.status = bat_now.n_status[1] or "N/A"
|
||||
for _,status in ipairs(bat_now.n_status) do
|
||||
if status == "Discharging" or status == "Charging" then
|
||||
bat_now.status = status
|
||||
end
|
||||
end
|
||||
bat_now.ac_status = tonumber(helpers.first_line(string.format("%s%s/online", pspath, ac))) or "N/A"
|
||||
|
||||
if bat_now.status ~= "N/A" then
|
||||
if bat_now.status ~= "Full" and sum_rate_power == 0 and bat_now.ac_status == 1 then
|
||||
bat_now.perc = math.floor(math.min(100, (sum_energy_now / sum_energy_full) * 100))
|
||||
bat_now.time = "00:00"
|
||||
bat_now.watt = 0
|
||||
|
||||
-- update {perc,time,watt} iff battery not full and rate > 0
|
||||
elseif bat_now.status ~= "Full" then
|
||||
local rate_time = 0
|
||||
-- Calculate time and watt if rates are greater then 0
|
||||
if (sum_rate_power > 0 or sum_rate_current > 0) then
|
||||
local div = (sum_rate_power > 0 and sum_rate_power) or sum_rate_current
|
||||
|
||||
if bat_now.status == "Charging" then
|
||||
rate_time = (sum_energy_full - sum_energy_now) / div
|
||||
else -- Discharging
|
||||
rate_time = sum_energy_now / div
|
||||
end
|
||||
|
||||
if 0 < rate_time and rate_time < 0.01 then -- check for magnitude discrepancies (#199)
|
||||
rate_time_magnitude = math.abs(math.floor(math.log10(rate_time)))
|
||||
rate_time = rate_time * 10^(rate_time_magnitude - 2)
|
||||
end
|
||||
end
|
||||
|
||||
local hours = math.floor(rate_time)
|
||||
local minutes = math.floor((rate_time - hours) * 60)
|
||||
bat_now.perc = math.floor(math.min(100, (sum_energy_now / sum_energy_full) * 100))
|
||||
bat_now.time = string.format("%02d:%02d", hours, minutes)
|
||||
bat_now.watt = tonumber(string.format("%.2f", sum_rate_energy / 1e6))
|
||||
elseif bat_now.status == "Full" then
|
||||
bat_now.perc = 100
|
||||
bat_now.time = "00:00"
|
||||
bat_now.watt = 0
|
||||
end
|
||||
end
|
||||
|
||||
widget = bat.widget
|
||||
settings()
|
||||
|
||||
-- notifications for critical, low, and full levels
|
||||
if notify == "on" then
|
||||
if bat_now.status == "Discharging" then
|
||||
if tonumber(bat_now.perc) <= n_perc[1] then
|
||||
bat.id = naughty.notify({
|
||||
preset = bat_notification_critical_preset,
|
||||
replaces_id = bat.id
|
||||
}).id
|
||||
elseif tonumber(bat_now.perc) <= n_perc[2] then
|
||||
bat.id = naughty.notify({
|
||||
preset = bat_notification_low_preset,
|
||||
replaces_id = bat.id
|
||||
}).id
|
||||
end
|
||||
fullnotification = false
|
||||
elseif bat_now.status == "Full" and full_notify == "on" and not fullnotification then
|
||||
bat.id = naughty.notify({
|
||||
preset = bat_notification_charged_preset,
|
||||
replaces_id = bat.id
|
||||
}).id
|
||||
fullnotification = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
helpers.newtimer("batteries", timeout, bat.update)
|
||||
|
||||
return bat
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,191 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2018, Luca CPZ
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local markup = require("lina.util.markup")
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local floor = math.floor
|
||||
local os = os
|
||||
local pairs = pairs
|
||||
local string = string
|
||||
local tconcat = table.concat
|
||||
local type = type
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
|
||||
-- Calendar notification
|
||||
-- lina.widget.cal
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
local cal = {
|
||||
attach_to = args.attach_to or {},
|
||||
week_start = args.week_start or 2,
|
||||
three = args.three or false,
|
||||
followtag = args.followtag or false,
|
||||
week_number = args.week_number or "none",
|
||||
week_number_format = args.week_number_format or args.week_number == "left" and "%3d | " or "| %-3d",
|
||||
icons = args.icons or helpers.icons_dir .. "cal/white/",
|
||||
notification_preset = args.notification_preset or {
|
||||
font = "Monospace 10", fg = "#FFFFFF", bg = "#000000"
|
||||
}
|
||||
}
|
||||
|
||||
function cal.get_week_number(m, st_day, x)
|
||||
local date = os.date("*t", m)
|
||||
|
||||
local week_step = (x ~= 0 and floor((x + st_day) / 7) - 1 or 0);
|
||||
|
||||
local display_time = os.time {
|
||||
year = date.year, month = date.month, day = date.day + 7 * week_step
|
||||
}
|
||||
|
||||
return string.format(cal.week_number_format, os.date("%V", display_time))
|
||||
end
|
||||
|
||||
function cal.sum_week_days(x, y)
|
||||
return (x + y) % 7
|
||||
end
|
||||
|
||||
function cal.build(month, year)
|
||||
local current_month, current_year = tonumber(os.date("%m")), tonumber(os.date("%Y"))
|
||||
local is_current_month = (not month or not year) or (month == current_month and year == current_year)
|
||||
local today = is_current_month and tonumber(os.date("%d")) -- otherwise nil and not highlighted
|
||||
local t = os.time { year = year or current_year, month = month and month+1 or current_month+1, day = 0 }
|
||||
local d = os.date("*t", t)
|
||||
local mth_days, st_day, this_month = d.day, (d.wday-d.day-cal.week_start+1)%7, os.date("%B %Y", t)
|
||||
local notifytable = { [1] = string.format("%s%s\n", string.rep(" ", floor((28 - this_month:len())/2)), markup.bold(this_month)) }
|
||||
for day_num = 0, 6 do
|
||||
notifytable[#notifytable+1] = string.format("%3s ", os.date("%a", os.time { year = 2006, month = 1, day = day_num + cal.week_start }))
|
||||
end
|
||||
notifytable[#notifytable] = string.format("%s\n%s", notifytable[#notifytable]:sub(1, -2), string.rep(" ", st_day*4))
|
||||
local strx
|
||||
for x = 1,mth_days do
|
||||
strx = x
|
||||
if x == today then
|
||||
if x < 10 then x = " " .. x end
|
||||
strx = markup.bold(markup.color(cal.notification_preset.bg, cal.notification_preset.fg, x) .. " ")
|
||||
end
|
||||
strx = string.format("%s%s", string.rep(" ", 3 - tostring(x):len()), strx)
|
||||
notifytable[#notifytable+1] = string.format("%-4s%s", strx, (x+st_day)%7==0 and x ~= mth_days and "\n" or "")
|
||||
end
|
||||
if string.len(cal.icons or "") > 0 and today then cal.icon = cal.icons .. today .. ".png" end
|
||||
cal.month, cal.year = d.month, d.year
|
||||
|
||||
if cal.week_number ~= "none" then
|
||||
local m = os.time { year = year or current_year, month = month and month or current_month, day = 1 }
|
||||
local head_prepend = string.rep(" ", tostring(string.format(cal.week_number_format, 0)):len())
|
||||
|
||||
if cal.week_number == "left" then
|
||||
notifytable[1] = head_prepend .. notifytable[1] -- month-year row
|
||||
notifytable[2] = head_prepend .. notifytable[2] -- weekdays row
|
||||
notifytable[8] = notifytable[8]:gsub("\n", "\n" .. cal.get_week_number(m, st_day, 0)) -- first week of the month
|
||||
|
||||
for x = 10,#notifytable do
|
||||
if cal.sum_week_days(st_day, x) == 2 then
|
||||
notifytable[x] = cal.get_week_number(m, st_day, x) .. notifytable[x]
|
||||
end
|
||||
end
|
||||
elseif cal.week_number == "right" then
|
||||
notifytable[8] = notifytable[8]:gsub("\n", head_prepend .. "\n") -- weekdays row
|
||||
for x = 9,#notifytable do
|
||||
if cal.sum_week_days(st_day, x) == 1 then
|
||||
notifytable[x] = notifytable[x]:gsub("\n", cal.get_week_number(m, st_day, x - 7) .. "\n")
|
||||
end
|
||||
end
|
||||
-- last week of the month
|
||||
local end_days = cal.sum_week_days(st_day, mth_days)
|
||||
if end_days ~= 0 then end_days = 7 - end_days end
|
||||
notifytable[#notifytable] = notifytable[#notifytable] .. string.rep(" ", 4 * end_days) .. cal.get_week_number(m, st_day, mth_days + end_days)
|
||||
end
|
||||
end
|
||||
|
||||
return notifytable
|
||||
end
|
||||
|
||||
function cal.getdate(month, year, offset)
|
||||
if not month or not year then
|
||||
month = tonumber(os.date("%m"))
|
||||
year = tonumber(os.date("%Y"))
|
||||
end
|
||||
|
||||
month = month + offset
|
||||
|
||||
while month > 12 do
|
||||
month = month - 12
|
||||
year = year + 1
|
||||
end
|
||||
|
||||
while month < 1 do
|
||||
month = month + 12
|
||||
year = year - 1
|
||||
end
|
||||
|
||||
return month, year
|
||||
end
|
||||
|
||||
function cal.hide()
|
||||
if not cal.notification then return end
|
||||
naughty.destroy(cal.notification)
|
||||
cal.notification = nil
|
||||
end
|
||||
|
||||
function cal.show(seconds, month, year, scr)
|
||||
local text = tconcat(cal.build(month, year))
|
||||
|
||||
if cal.three then
|
||||
local current_month, current_year = cal.month, cal.year
|
||||
local prev_month, prev_year = cal.getdate(cal.month, cal.year, -1)
|
||||
local next_month, next_year = cal.getdate(cal.month, cal.year, 1)
|
||||
text = string.format("%s\n\n%s\n\n%s",
|
||||
tconcat(cal.build(prev_month, prev_year)), text,
|
||||
tconcat(cal.build(next_month, next_year)))
|
||||
cal.month, cal.year = current_month, current_year
|
||||
end
|
||||
|
||||
if cal.notification then
|
||||
local title = cal.notification_preset.title or nil
|
||||
naughty.replace_text(cal.notification, title, text)
|
||||
return
|
||||
end
|
||||
|
||||
cal.notification = naughty.notify {
|
||||
preset = cal.notification_preset,
|
||||
screen = cal.followtag and awful.screen.focused() or scr or 1,
|
||||
icon = cal.icon,
|
||||
timeout = type(seconds) == "number" and seconds or cal.notification_preset.timeout or 5,
|
||||
text = text
|
||||
}
|
||||
end
|
||||
|
||||
function cal.hover_on() cal.show(0) end
|
||||
function cal.move(offset)
|
||||
offset = offset or 0
|
||||
cal.month, cal.year = cal.getdate(cal.month, cal.year, offset)
|
||||
cal.show(0, cal.month, cal.year)
|
||||
end
|
||||
function cal.prev() cal.move(-1) end
|
||||
function cal.next() cal.move( 1) end
|
||||
|
||||
function cal.attach(widget)
|
||||
widget:connect_signal("mouse::enter", cal.hover_on)
|
||||
widget:connect_signal("mouse::leave", cal.hide)
|
||||
widget:buttons(awful.util.table.join(
|
||||
awful.button({}, 1, cal.prev),
|
||||
awful.button({}, 3, cal.next),
|
||||
awful.button({}, 2, cal.hover_on),
|
||||
awful.button({}, 5, cal.prev),
|
||||
awful.button({}, 4, cal.next)))
|
||||
end
|
||||
|
||||
for _, widget in pairs(cal.attach_to) do cal.attach(widget) end
|
||||
|
||||
return cal
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,18 +0,0 @@
|
|||
--[[
|
||||
|
||||
Lina
|
||||
Layouts, widgets and utilities for Awesome WM
|
||||
|
||||
Users contributed widgets section
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
|
||||
--]]
|
||||
|
||||
local wrequire = require("lina.helpers").wrequire
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local widget = { _NAME = "lina.widget.contrib" }
|
||||
|
||||
return setmetatable(widget, { __index = wrequire })
|
|
@ -1,97 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2014, anticlockwise <http://github.com/anticlockwise>
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local focused = require("awful.screen").focused
|
||||
local escape_f = require("awful.util").escape
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local os = os
|
||||
local string = string
|
||||
|
||||
-- MOC audio player
|
||||
-- lina.widget.contrib.moc
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local moc = { widget = args.widget or wibox.widget.textbox() }
|
||||
local timeout = args.timeout or 2
|
||||
local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
|
||||
local cover_pattern = args.cover_pattern or "*\\.(jpg|jpeg|png|gif)$"
|
||||
local cover_size = args.cover_size or 100
|
||||
local default_art = args.default_art or ""
|
||||
local followtag = args.followtag or false
|
||||
local settings = args.settings or function() end
|
||||
|
||||
moc_notification_preset = { title = "Now playing", timeout = 6 }
|
||||
|
||||
helpers.set_map("current moc track", nil)
|
||||
|
||||
function moc.update()
|
||||
helpers.async("mocp -i", function(f)
|
||||
moc_now = {
|
||||
state = "N/A",
|
||||
file = "N/A",
|
||||
artist = "N/A",
|
||||
title = "N/A",
|
||||
album = "N/A",
|
||||
elapsed = "N/A",
|
||||
total = "N/A"
|
||||
}
|
||||
|
||||
for line in string.gmatch(f, "[^\n]+") do
|
||||
for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
|
||||
if k == "State" then moc_now.state = v
|
||||
elseif k == "File" then moc_now.file = v
|
||||
elseif k == "Artist" then moc_now.artist = escape_f(v)
|
||||
elseif k == "SongTitle" then moc_now.title = escape_f(v)
|
||||
elseif k == "Album" then moc_now.album = escape_f(v)
|
||||
elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v)
|
||||
elseif k == "TotalTime" then moc_now.total = escape_f(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist,
|
||||
moc_now.album, moc_now.total, moc_now.title)
|
||||
widget = moc.widget
|
||||
settings()
|
||||
|
||||
if moc_now.state == "PLAY" then
|
||||
if moc_now.title ~= helpers.get_map("current moc track") then
|
||||
helpers.set_map("current moc track", moc_now.title)
|
||||
|
||||
if followtag then moc_notification_preset.screen = focused() end
|
||||
|
||||
local common = {
|
||||
preset = moc_notification_preset,
|
||||
icon = default_art,
|
||||
icon_size = cover_size,
|
||||
replaces_id = moc.id,
|
||||
}
|
||||
|
||||
local path = string.format("%s/%s", music_dir, string.match(moc_now.file, ".*/"))
|
||||
local cover = string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'", path, cover_pattern)
|
||||
helpers.async({ shell, "-c", cover }, function(current_icon)
|
||||
common.icon = current_icon:gsub("\n", "")
|
||||
moc.id = naughty.notify(common).id
|
||||
end)
|
||||
end
|
||||
elseif moc_now.state ~= "PAUSE" then
|
||||
helpers.set_map("current moc track", nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
moc.timer = helpers.newtimer("moc", timeout, moc.update, true, true)
|
||||
|
||||
return moc
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,54 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2017, Luca CPZ
|
||||
* (c) 2014, blueluke <http://github.com/blueluke>
|
||||
|
||||
--]]
|
||||
|
||||
local async = require("lina.helpers").async
|
||||
local awful = require("awful")
|
||||
local execute = os.execute
|
||||
local type = type
|
||||
|
||||
-- Redshift
|
||||
-- lina.widget.contrib.redshift
|
||||
local redshift = { active = false, pid = nil }
|
||||
|
||||
function redshift.start()
|
||||
execute("pkill redshift")
|
||||
awful.spawn.with_shell("redshift -x") -- clear adjustments
|
||||
redshift.pid = awful.spawn.with_shell("redshift")
|
||||
redshift.active = true
|
||||
if type(redshift.update_fun) == "function" then
|
||||
redshift.update_fun(redshift.active)
|
||||
end
|
||||
end
|
||||
|
||||
function redshift.toggle()
|
||||
async({ awful.util.shell, "-c", string.format("ps -p %d -o pid=", redshift.pid) }, function(f)
|
||||
if f and #f > 0 then -- redshift is running
|
||||
-- Sending -USR1 toggles redshift (See project website)
|
||||
execute("pkill -USR1 redshift")
|
||||
redshift.active = not redshift.active
|
||||
else -- not started or killed, (re)start it
|
||||
redshift.start()
|
||||
end
|
||||
redshift.update_fun(redshift.active)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Attach to a widget
|
||||
-- Provides a button which toggles redshift on/off on click
|
||||
-- @param widget: Widget to attach to.
|
||||
-- @param fun: Function to be run each time redshift is toggled (optional).
|
||||
-- Use it to update widget text or icons on status change.
|
||||
function redshift.attach(widget, fun)
|
||||
redshift.update_fun = fun or function() end
|
||||
if not redshift.pid then redshift.start() end
|
||||
if widget then
|
||||
widget:buttons(awful.util.table.join(awful.button({}, 1, function () redshift.toggle() end)))
|
||||
end
|
||||
end
|
||||
|
||||
return redshift
|
|
@ -1,92 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Jan Xie
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local markup = require("lina.util").markup
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local mouse = mouse
|
||||
|
||||
-- Taskwarrior notification
|
||||
-- lina.widget.contrib.task
|
||||
local task = {}
|
||||
|
||||
function task.hide()
|
||||
if not task.notification then return end
|
||||
naughty.destroy(task.notification)
|
||||
task.notification = nil
|
||||
end
|
||||
|
||||
function task.show(scr)
|
||||
task.notification_preset.screen = task.followtag and awful.screen.focused() or scr or 1
|
||||
|
||||
helpers.async({ awful.util.shell, "-c", task.show_cmd }, function(f)
|
||||
local widget_focused = true
|
||||
|
||||
if mouse.current_widgets then
|
||||
widget_focused = false
|
||||
for _,v in ipairs(mouse.current_widgets) do
|
||||
if task.widget == v then
|
||||
widget_focused = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if widget_focused then
|
||||
task.hide()
|
||||
task.notification = naughty.notify {
|
||||
preset = task.notification_preset,
|
||||
title = "task next",
|
||||
text = markup.font(task.notification_preset.font,
|
||||
awful.util.escape(f:gsub("\n*$", "")))
|
||||
}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function task.prompt()
|
||||
awful.prompt.run {
|
||||
prompt = task.prompt_text,
|
||||
textbox = awful.screen.focused().mypromptbox.widget,
|
||||
exe_callback = function(t)
|
||||
helpers.async(t, function(f)
|
||||
naughty.notify {
|
||||
preset = task.notification_preset,
|
||||
title = t,
|
||||
text = markup.font(task.notification_preset.font,
|
||||
awful.util.escape(f:gsub("\n*$", "")))
|
||||
}
|
||||
end)
|
||||
end,
|
||||
history_path = awful.util.getdir("cache") .. "/history_task"
|
||||
}
|
||||
end
|
||||
|
||||
function task.attach(widget, args)
|
||||
args = args or {}
|
||||
|
||||
task.show_cmd = args.show_cmd or "task next"
|
||||
task.prompt_text = args.prompt_text or "Enter task command: "
|
||||
task.followtag = args.followtag or false
|
||||
task.notification_preset = args.notification_preset
|
||||
task.widget = widget
|
||||
|
||||
if not task.notification_preset then
|
||||
task.notification_preset = {
|
||||
font = "Monospace 10",
|
||||
icon = helpers.icons_dir .. "/taskwarrior.png"
|
||||
}
|
||||
end
|
||||
|
||||
if widget then
|
||||
widget:connect_signal("mouse::enter", function () task.show() end)
|
||||
widget:connect_signal("mouse::leave", function () task.hide() end)
|
||||
end
|
||||
end
|
||||
|
||||
return task
|
|
@ -1,147 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2018, Luca CPZ
|
||||
* (c) 2013, Conor Heine
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local focused = require("awful.screen").focused
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
local type = type
|
||||
|
||||
-- ThinkPad battery infos and widget creator
|
||||
-- http://www.thinkwiki.org/wiki/Tp_smapi
|
||||
-- lina.widget.contrib.tp_smapi
|
||||
|
||||
local function factory(apipath)
|
||||
local tp_smapi = {
|
||||
path = apipath or "/sys/devices/platform/smapi"
|
||||
}
|
||||
|
||||
function tp_smapi.get(batid, feature)
|
||||
return helpers.first_line(string.format("%s/%s/%s", tp_smapi.path, batid or "BAT0", feature or ""))
|
||||
end
|
||||
|
||||
function tp_smapi.installed(batid)
|
||||
return tp_smapi.get(batid, "installed") == "1"
|
||||
end
|
||||
|
||||
function tp_smapi.status(batid)
|
||||
return tp_smapi.get(batid, "state")
|
||||
end
|
||||
|
||||
function tp_smapi.percentage(batid)
|
||||
return tp_smapi.get(batid, "remaining_percent")
|
||||
end
|
||||
|
||||
-- either running or charging time
|
||||
function tp_smapi.time(batid)
|
||||
local status = tp_smapi.status(batid)
|
||||
local mins_left = tp_smapi.get(batid, string.match(string.lower(status), "discharging") and "remaining_running_time" or "remaining_charging_time")
|
||||
if not string.find(mins_left, "^%d+") then return "N/A" end
|
||||
return string.format("%02d:%02d", math.floor(mins_left / 60), mins_left % 60) -- HH:mm
|
||||
end
|
||||
|
||||
function tp_smapi.hide()
|
||||
if not tp_smapi.notification then return end
|
||||
naughty.destroy(tp_smapi.notification)
|
||||
tp_smapi.notification = nil
|
||||
end
|
||||
|
||||
function tp_smapi.show(batid, seconds, scr)
|
||||
if not tp_smapi.installed(batid) then return end
|
||||
|
||||
local mfgr = tp_smapi.get(batid, "manufacturer") or "no_mfgr"
|
||||
local model = tp_smapi.get(batid, "model") or "no_model"
|
||||
local chem = tp_smapi.get(batid, "chemistry") or "no_chem"
|
||||
local status = tp_smapi.get(batid, "state")
|
||||
local time = tp_smapi.time(batid)
|
||||
local msg
|
||||
|
||||
if status and status ~= "idle" then
|
||||
msg = string.format("[%s] %s %s", status, time ~= "N/A" and time or "unknown remaining time",
|
||||
string.lower(status):gsub(" ", ""):gsub("\n", "") == "charging" and " until charged" or " remaining")
|
||||
else
|
||||
msg = "On AC power"
|
||||
end
|
||||
|
||||
tp_smapi.hide()
|
||||
tp_smapi.notification = naughty.notify {
|
||||
title = string.format("%s: %s %s (%s)", batid, mfgr, model, chem),
|
||||
text = msg,
|
||||
timeout = type(seconds) == "number" and seconds or 0,
|
||||
screen = scr or focused()
|
||||
}
|
||||
end
|
||||
|
||||
function tp_smapi.create_widget(args)
|
||||
args = args or {}
|
||||
|
||||
local pspath = args.pspath or "/sys/class/power_supply/"
|
||||
local batteries = args.batteries or (args.battery and {args.battery}) or {}
|
||||
local timeout = args.timeout or 30
|
||||
local settings = args.settings or function() end
|
||||
|
||||
if #batteries == 0 then
|
||||
helpers.line_callback("ls -1 " .. pspath, function(line)
|
||||
local bstr = string.match(line, "BAT%w+")
|
||||
if bstr then batteries[#batteries + 1] = bstr end
|
||||
end)
|
||||
end
|
||||
|
||||
local all_batteries_installed = true
|
||||
|
||||
for _, battery in ipairs(batteries) do
|
||||
if not tp_smapi.installed(battery) then
|
||||
naughty.notify {
|
||||
preset = naughty.config.critical,
|
||||
title = "tp_smapi: error while creating widget",
|
||||
text = string.format("battery %s is not installed", battery)
|
||||
}
|
||||
all_batteries_installed = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not all_batteries_installed then return end
|
||||
|
||||
tpbat = {
|
||||
batteries = batteries,
|
||||
widget = args.widget or wibox.widget.textbox()
|
||||
}
|
||||
|
||||
function tpbat.update()
|
||||
tpbat_now = {
|
||||
n_status = {},
|
||||
n_perc = {},
|
||||
n_time = {},
|
||||
status = "N/A"
|
||||
}
|
||||
|
||||
for i = 1, #batteries do
|
||||
tpbat_now.n_status[i] = tp_smapi.status(batteries[i]) or "N/A"
|
||||
tpbat_now.n_perc[i] = tp_smapi.percentage(batteries[i])
|
||||
tpbat_now.n_time[i] = tp_smapi.time(batteries[i]) or "N/A"
|
||||
|
||||
if not tpbat_now.n_status[i]:lower():match("full") then
|
||||
tpbat_now.status = tpbat_now.n_status[i]
|
||||
end
|
||||
end
|
||||
|
||||
widget = tpbat.widget -- backwards compatibility
|
||||
settings()
|
||||
end
|
||||
|
||||
helpers.newtimer("thinkpad-batteries", timeout, tpbat.update)
|
||||
|
||||
return tpbat
|
||||
end
|
||||
|
||||
return tp_smapi
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,156 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2018, Uli Schlacter
|
||||
* (c) 2018, Otto Modinos
|
||||
* (c) 2013, Luca CPZ
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local Gio = require("lgi").Gio
|
||||
local focused = require("awful.screen").focused
|
||||
local wibox = require("wibox")
|
||||
local naughty = require("naughty")
|
||||
local gears = require("gears")
|
||||
local math = math
|
||||
local string = string
|
||||
local tconcat = table.concat
|
||||
local type = type
|
||||
local query_size = Gio.FILE_ATTRIBUTE_FILESYSTEM_SIZE
|
||||
local query_free = Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE
|
||||
local query_used = Gio.FILE_ATTRIBUTE_FILESYSTEM_USED
|
||||
local query = query_size .. "," .. query_free .. "," .. query_used
|
||||
|
||||
-- File systems info
|
||||
-- lina.widget.fs
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local fs = {
|
||||
widget = args.widget or wibox.widget.textbox(),
|
||||
units = {
|
||||
[1] = "Kb", [2] = "Mb", [3] = "Gb",
|
||||
[4] = "Tb", [5] = "Pb", [6] = "Eb",
|
||||
[7] = "Zb", [8] = "Yb"
|
||||
}
|
||||
}
|
||||
|
||||
function fs.hide()
|
||||
if not fs.notification then return end
|
||||
naughty.destroy(fs.notification)
|
||||
fs.notification = nil
|
||||
end
|
||||
|
||||
function fs.show(seconds, scr)
|
||||
fs.hide()
|
||||
fs.update(function()
|
||||
fs.notification_preset.screen = fs.followtag and focused() or scr or 1
|
||||
fs.notification = naughty.notify {
|
||||
preset = fs.notification_preset,
|
||||
timeout = type(seconds) == "number" and seconds or 5
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
local timeout = args.timeout or 600
|
||||
local partition = args.partition
|
||||
local threshold = args.threshold or 99
|
||||
local showpopup = args.showpopup or "on"
|
||||
local settings = args.settings or function() end
|
||||
|
||||
fs.followtag = args.followtag or false
|
||||
fs.notification_preset = args.notification_preset
|
||||
|
||||
if not fs.notification_preset then
|
||||
fs.notification_preset = {
|
||||
font = "Monospace 10",
|
||||
fg = "#FFFFFF",
|
||||
bg = "#000000"
|
||||
}
|
||||
end
|
||||
|
||||
local function update_synced()
|
||||
local pathlen = 10
|
||||
fs_now = {}
|
||||
|
||||
local notifypaths = {}
|
||||
for _, mount in ipairs(Gio.unix_mounts_get()) do
|
||||
local path = Gio.unix_mount_get_mount_path(mount)
|
||||
local root = Gio.File.new_for_path(path)
|
||||
local info = root:query_filesystem_info(query)
|
||||
|
||||
if info then
|
||||
local size = info:get_attribute_uint64(query_size)
|
||||
local used = info:get_attribute_uint64(query_used)
|
||||
local free = info:get_attribute_uint64(query_free)
|
||||
|
||||
if size > 0 then
|
||||
local units = math.floor(math.log(size)/math.log(1024))
|
||||
|
||||
fs_now[path] = {
|
||||
units = fs.units[units],
|
||||
percentage = math.floor(100 * used / size), -- used percentage
|
||||
size = size / math.pow(1024, units),
|
||||
used = used / math.pow(1024, units),
|
||||
free = free / math.pow(1024, units)
|
||||
}
|
||||
|
||||
if fs_now[path].percentage > 0 then -- don't notify unused file systems
|
||||
notifypaths[#notifypaths+1] = path
|
||||
|
||||
if #path > pathlen then
|
||||
pathlen = #path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
widget = fs.widget
|
||||
settings()
|
||||
|
||||
if partition and fs_now[partition] and fs_now[partition].percentage >= threshold then
|
||||
if not helpers.get_map(partition) then
|
||||
naughty.notify {
|
||||
preset = naughty.config.presets.critical,
|
||||
title = "Warning",
|
||||
text = string.format("%s is above %d%% (%d%%)", partition, threshold, fs_now[partition].percentage)
|
||||
}
|
||||
helpers.set_map(partition, true)
|
||||
else
|
||||
helpers.set_map(partition, false)
|
||||
end
|
||||
end
|
||||
|
||||
local fmt = "%-" .. tostring(pathlen) .. "s %4s\t%6s\t%6s\n"
|
||||
local notifytable = { [1] = string.format(fmt, "path", "used", "free", "size") }
|
||||
fmt = "\n%-" .. tostring(pathlen) .. "s %3s%%\t%6.2f\t%6.2f %s"
|
||||
for _, path in ipairs(notifypaths) do
|
||||
notifytable[#notifytable+1] = string.format(fmt, path, fs_now[path].percentage, fs_now[path].free, fs_now[path].size, fs_now[path].units)
|
||||
end
|
||||
|
||||
fs.notification_preset.text = tconcat(notifytable)
|
||||
end
|
||||
|
||||
function fs.update(callback)
|
||||
Gio.Async.start(gears.protected_call.call)(function()
|
||||
update_synced()
|
||||
if type(callback) == "function" and callback then
|
||||
callback()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if showpopup == "on" then
|
||||
fs.widget:connect_signal('mouse::enter', function () fs.show(0) end)
|
||||
fs.widget:connect_signal('mouse::leave', function () fs.hide() end)
|
||||
end
|
||||
|
||||
helpers.newtimer(partition or "fs", timeout, fs.update)
|
||||
|
||||
return fs
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,115 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local awful = require("awful")
|
||||
local string = string
|
||||
local type = type
|
||||
local tonumber = tonumber
|
||||
|
||||
-- Mail IMAP check
|
||||
-- lina.widget.imap
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local imap = { widget = args.widget or wibox.widget.textbox() }
|
||||
local server = args.server
|
||||
local mail = args.mail
|
||||
local password = args.password
|
||||
local port = args.port or 993
|
||||
local timeout = args.timeout or 60
|
||||
local pwdtimeout = args.pwdtimeout or 10
|
||||
local is_plain = args.is_plain or false
|
||||
local followtag = args.followtag or false
|
||||
local notify = args.notify or "on"
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local head_command = "curl --connect-timeout 3 -fsm 3"
|
||||
local request = "-X 'STATUS INBOX (MESSAGES RECENT UNSEEN)'"
|
||||
|
||||
if not server or not mail or not password then
|
||||
return
|
||||
end
|
||||
|
||||
mail_notification_preset = {
|
||||
icon = helpers.icons_dir .. "mail.png",
|
||||
position = "top_left",
|
||||
}
|
||||
|
||||
helpers.set_map(mail, 0)
|
||||
|
||||
if not is_plain then
|
||||
if type(password) == "string" or type(password) == "table" then
|
||||
helpers.async(password, function(f)
|
||||
password = f:gsub("\n", "")
|
||||
end)
|
||||
elseif type(password) == "function" then
|
||||
imap.pwdtimer = helpers.newtimer(mail .. "-password", pwdtimeout, function()
|
||||
local retrieved_password, try_again = password()
|
||||
if not try_again then
|
||||
imap.pwdtimer:stop() -- stop trying to retrieve
|
||||
password = retrieved_password or "" -- failsafe
|
||||
end
|
||||
end, true, true)
|
||||
end
|
||||
end
|
||||
|
||||
function imap.update()
|
||||
-- do not update if the password has not been retrieved yet
|
||||
if type(password) ~= "string" then
|
||||
return
|
||||
end
|
||||
|
||||
local curl = string.format(
|
||||
"%s --url imaps://%s:%s/INBOX -u %s:'%s' %s -k",
|
||||
head_command,
|
||||
server,
|
||||
port,
|
||||
mail,
|
||||
password,
|
||||
request
|
||||
)
|
||||
|
||||
helpers.async(curl, function(f)
|
||||
imap_now = { ["MESSAGES"] = 0, ["RECENT"] = 0, ["UNSEEN"] = 0 }
|
||||
|
||||
for s, d in f:gmatch("(%w+)%s+(%d+)") do
|
||||
imap_now[s] = tonumber(d)
|
||||
end
|
||||
mailcount = imap_now["UNSEEN"] -- backwards compatibility
|
||||
widget = imap.widget
|
||||
|
||||
settings()
|
||||
|
||||
if notify == "on" and mailcount and mailcount >= 1 and mailcount > helpers.get_map(mail) then
|
||||
if followtag then
|
||||
mail_notification_preset.screen = awful.screen.focused()
|
||||
end
|
||||
naughty.notify({
|
||||
preset = mail_notification_preset,
|
||||
text = string.format(
|
||||
"%s has <b>%d</b> new message%s",
|
||||
mail,
|
||||
mailcount,
|
||||
mailcount == 1 and "" or "s"
|
||||
),
|
||||
})
|
||||
end
|
||||
|
||||
helpers.set_map(mail, imap_now["UNSEEN"])
|
||||
end)
|
||||
end
|
||||
|
||||
imap.timer = helpers.newtimer(mail, timeout, imap.update, true, true)
|
||||
|
||||
return imap
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,135 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2010, Adrian C. <anrxc@sysphere.org>
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local escape_f = require("awful.util").escape
|
||||
local focused = require("awful.screen").focused
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local os = os
|
||||
local string = string
|
||||
|
||||
-- MPD infos
|
||||
-- lina.widget.mpd
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local mpd = { widget = args.widget or wibox.widget.textbox() }
|
||||
local timeout = args.timeout or 2
|
||||
local password = (args.password and #args.password > 0 and string.format("password %s\\n", args.password)) or ""
|
||||
local host = args.host or os.getenv("MPD_HOST") or "127.0.0.1"
|
||||
local port = args.port or os.getenv("MPD_PORT") or "6600"
|
||||
local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
|
||||
local cover_pattern = args.cover_pattern or "*\\.(jpg|jpeg|png|gif)$"
|
||||
local cover_size = args.cover_size or 100
|
||||
local default_art = args.default_art
|
||||
local notify = args.notify or "on"
|
||||
local followtag = args.followtag or false
|
||||
local settings = args.settings or function() end
|
||||
|
||||
local mpdh = string.format("telnet://%s:%s", host, port)
|
||||
local echo = string.format("printf \"%sstatus\\ncurrentsong\\nclose\\n\"", password)
|
||||
local cmd = string.format("%s | curl --connect-timeout 1 -fsm 3 %s", echo, mpdh)
|
||||
|
||||
mpd_notification_preset = { title = "Now playing", timeout = 6 }
|
||||
|
||||
helpers.set_map("current mpd track", nil)
|
||||
|
||||
function mpd.update()
|
||||
helpers.async({ shell, "-c", cmd }, function(f)
|
||||
mpd_now = {
|
||||
random_mode = false,
|
||||
single_mode = false,
|
||||
repeat_mode = false,
|
||||
consume_mode = false,
|
||||
pls_pos = "N/A",
|
||||
pls_len = "N/A",
|
||||
state = "N/A",
|
||||
file = "N/A",
|
||||
name = "N/A",
|
||||
artist = "N/A",
|
||||
title = "N/A",
|
||||
album = "N/A",
|
||||
genre = "N/A",
|
||||
track = "N/A",
|
||||
date = "N/A",
|
||||
time = "N/A",
|
||||
elapsed = "N/A",
|
||||
volume = "N/A"
|
||||
}
|
||||
|
||||
for line in string.gmatch(f, "[^\n]+") do
|
||||
for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
|
||||
if k == "state" then mpd_now.state = v
|
||||
elseif k == "file" then mpd_now.file = v
|
||||
elseif k == "Name" then mpd_now.name = escape_f(v)
|
||||
elseif k == "Artist" then mpd_now.artist = escape_f(v)
|
||||
elseif k == "Title" then mpd_now.title = escape_f(v)
|
||||
elseif k == "Album" then mpd_now.album = escape_f(v)
|
||||
elseif k == "Genre" then mpd_now.genre = escape_f(v)
|
||||
elseif k == "Track" then mpd_now.track = escape_f(v)
|
||||
elseif k == "Date" then mpd_now.date = escape_f(v)
|
||||
elseif k == "Time" then mpd_now.time = v
|
||||
elseif k == "elapsed" then mpd_now.elapsed = string.match(v, "%d+")
|
||||
elseif k == "song" then mpd_now.pls_pos = v
|
||||
elseif k == "playlistlength" then mpd_now.pls_len = v
|
||||
elseif k == "repeat" then mpd_now.repeat_mode = v ~= "0"
|
||||
elseif k == "single" then mpd_now.single_mode = v ~= "0"
|
||||
elseif k == "random" then mpd_now.random_mode = v ~= "0"
|
||||
elseif k == "consume" then mpd_now.consume_mode = v ~= "0"
|
||||
elseif k == "volume" then mpd_now.volume = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
|
||||
mpd_now.album, mpd_now.date, mpd_now.title)
|
||||
widget = mpd.widget
|
||||
settings()
|
||||
|
||||
if mpd_now.state == "play" then
|
||||
if notify == "on" and mpd_now.title ~= helpers.get_map("current mpd track") then
|
||||
helpers.set_map("current mpd track", mpd_now.title)
|
||||
|
||||
if followtag then mpd_notification_preset.screen = focused() end
|
||||
|
||||
local common = {
|
||||
preset = mpd_notification_preset,
|
||||
icon = default_art,
|
||||
icon_size = cover_size,
|
||||
replaces_id = mpd.id
|
||||
}
|
||||
|
||||
if not string.match(mpd_now.file, "http.*://") then -- local file instead of http stream
|
||||
local path = string.format("%s/%s", music_dir, string.match(mpd_now.file, ".*/"))
|
||||
local cover = string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'",
|
||||
path:gsub("'", "'\\''"), cover_pattern)
|
||||
helpers.async({ shell, "-c", cover }, function(current_icon)
|
||||
common.icon = current_icon:gsub("\n", "")
|
||||
if #common.icon == 0 then common.icon = nil end
|
||||
mpd.id = naughty.notify(common).id
|
||||
end)
|
||||
else
|
||||
mpd.id = naughty.notify(common).id
|
||||
end
|
||||
|
||||
end
|
||||
elseif mpd_now.state ~= "pause" then
|
||||
helpers.set_map("current mpd track", nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
mpd.timer = helpers.newtimer("mpd", timeout, mpd.update, true, true)
|
||||
|
||||
return mpd
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,122 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2010-2012, Peter Hofmann
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
|
||||
-- Network infos
|
||||
-- lina.widget.net
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local net = { widget = args.widget or wibox.widget.textbox(), devices = {} }
|
||||
local timeout = args.timeout or 2
|
||||
local units = args.units or 1024 -- KB
|
||||
local notify = args.notify or "on"
|
||||
local wifi_state = args.wifi_state or "off"
|
||||
local eth_state = args.eth_state or "off"
|
||||
local screen = args.screen or 1
|
||||
local format = args.format or "%.1f"
|
||||
local settings = args.settings or function() end
|
||||
|
||||
-- Compatibility with old API where iface was a string corresponding to 1 interface
|
||||
net.iface = (args.iface and (type(args.iface) == "string" and {args.iface}) or
|
||||
(type(args.iface) == "table" and args.iface)) or {}
|
||||
|
||||
function net.get_devices()
|
||||
net.iface = {} -- reset at every call
|
||||
helpers.line_callback("ip link", function(line)
|
||||
net.iface[#net.iface + 1] = not string.match(line, "LOOPBACK") and string.match(line, "(%w+): <") or nil
|
||||
end)
|
||||
end
|
||||
|
||||
if #net.iface == 0 then net.get_devices() end
|
||||
|
||||
function net.update()
|
||||
-- These are the totals over all specified interfaces
|
||||
net_now = {
|
||||
devices = {},
|
||||
-- Bytes since last iteration
|
||||
sent = 0,
|
||||
received = 0
|
||||
}
|
||||
|
||||
for _, dev in ipairs(net.iface) do
|
||||
local dev_now = {}
|
||||
local dev_before = net.devices[dev] or { last_t = 0, last_r = 0 }
|
||||
local now_t = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/tx_bytes", dev)) or 0)
|
||||
local now_r = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/rx_bytes", dev)) or 0)
|
||||
|
||||
dev_now.carrier = helpers.first_line(string.format("/sys/class/net/%s/carrier", dev)) or "0"
|
||||
dev_now.state = helpers.first_line(string.format("/sys/class/net/%s/operstate", dev)) or "down"
|
||||
|
||||
dev_now.sent = (now_t - dev_before.last_t) / timeout / units
|
||||
dev_now.received = (now_r - dev_before.last_r) / timeout / units
|
||||
|
||||
net_now.sent = net_now.sent + dev_now.sent
|
||||
net_now.received = net_now.received + dev_now.received
|
||||
|
||||
dev_now.sent = string.format(format, dev_now.sent)
|
||||
dev_now.received = string.format(format, dev_now.received)
|
||||
|
||||
dev_now.last_t = now_t
|
||||
dev_now.last_r = now_r
|
||||
|
||||
if wifi_state == "on" and helpers.first_line(string.format("/sys/class/net/%s/uevent", dev)) == "DEVTYPE=wlan" then
|
||||
dev_now.wifi = true
|
||||
if string.match(dev_now.carrier, "1") then
|
||||
dev_now.signal = tonumber(string.match(helpers.lines_from("/proc/net/wireless")[3], "(%-%d+%.)")) or nil
|
||||
end
|
||||
else
|
||||
dev_now.wifi = false
|
||||
end
|
||||
|
||||
if eth_state == "on" and helpers.first_line(string.format("/sys/class/net/%s/uevent", dev)) ~= "DEVTYPE=wlan" then
|
||||
dev_now.ethernet = true
|
||||
else
|
||||
dev_now.ethernet = false
|
||||
end
|
||||
|
||||
net.devices[dev] = dev_now
|
||||
|
||||
-- Notify only once when connection is lost
|
||||
if string.match(dev_now.carrier, "0") and notify == "on" and helpers.get_map(dev) then
|
||||
naughty.notify {
|
||||
title = dev,
|
||||
text = "No carrier",
|
||||
icon = helpers.icons_dir .. "no_net.png",
|
||||
screen = screen
|
||||
}
|
||||
helpers.set_map(dev, false)
|
||||
elseif string.match(dev_now.carrier, "1") then
|
||||
helpers.set_map(dev, true)
|
||||
end
|
||||
|
||||
net_now.carrier = dev_now.carrier
|
||||
net_now.state = dev_now.state
|
||||
net_now.devices[dev] = dev_now
|
||||
-- net_now.sent and net_now.received will be
|
||||
-- the totals across all specified devices
|
||||
end
|
||||
|
||||
net_now.sent = string.format(format, net_now.sent)
|
||||
net_now.received = string.format(format, net_now.received)
|
||||
|
||||
widget = net.widget
|
||||
settings()
|
||||
end
|
||||
|
||||
helpers.newtimer("network", timeout, net.update)
|
||||
|
||||
return net
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,58 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2016, Luca CPZ
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
local type = type
|
||||
|
||||
-- PulseAudio volume
|
||||
-- lina.widget.pulse
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local pulse = { widget = args.widget or wibox.widget.textbox(), device = "N/A" }
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
|
||||
pulse.devicetype = args.devicetype or "sink"
|
||||
pulse.cmd = args.cmd or "pacmd list-" .. pulse.devicetype .. "s | sed -n -e '/*/,$!d' -e '/index/p' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
|
||||
|
||||
function pulse.update()
|
||||
helpers.async({ shell, "-c", type(pulse.cmd) == "string" and pulse.cmd or pulse.cmd() },
|
||||
function(s)
|
||||
volume_now = {
|
||||
index = string.match(s, "index: (%S+)") or "N/A",
|
||||
device = string.match(s, "device.string = \"(%S+)\"") or "N/A",
|
||||
muted = string.match(s, "muted: (%S+)") or "N/A"
|
||||
}
|
||||
|
||||
pulse.device = volume_now.index
|
||||
|
||||
local ch = 1
|
||||
volume_now.channel = {}
|
||||
for v in string.gmatch(s, ":.-(%d+)%%") do
|
||||
volume_now.channel[ch] = v
|
||||
ch = ch + 1
|
||||
end
|
||||
|
||||
volume_now.left = volume_now.channel[1] or "N/A"
|
||||
volume_now.right = volume_now.channel[2] or "N/A"
|
||||
|
||||
widget = pulse.widget
|
||||
settings()
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.newtimer("pulse", timeout, pulse.update)
|
||||
|
||||
return pulse
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,175 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2013, Rman
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local math = math
|
||||
local string = string
|
||||
local type = type
|
||||
local tonumber = tonumber
|
||||
|
||||
-- PulseAudio volume bar
|
||||
-- lina.widget.pulsebar
|
||||
|
||||
local function factory(args)
|
||||
local pulsebar = {
|
||||
colors = {
|
||||
background = "#000000",
|
||||
mute_background = "#000000",
|
||||
mute = "#EB8F8F",
|
||||
unmute = "#A4CE8A"
|
||||
},
|
||||
|
||||
_current_level = 0,
|
||||
_mute = "no",
|
||||
device = "N/A"
|
||||
}
|
||||
|
||||
args = args or {}
|
||||
|
||||
local timeout = args.timeout or 5
|
||||
local settings = args.settings or function() end
|
||||
local width = args.width or 63
|
||||
local height = args.height or 1
|
||||
local margins = args.margins or 1
|
||||
local paddings = args.paddings or 1
|
||||
local ticks = args.ticks or false
|
||||
local ticks_size = args.ticks_size or 7
|
||||
local tick = args.tick or "|"
|
||||
local tick_pre = args.tick_pre or "["
|
||||
local tick_post = args.tick_post or "]"
|
||||
local tick_none = args.tick_none or " "
|
||||
|
||||
pulsebar.colors = args.colors or pulsebar.colors
|
||||
pulsebar.followtag = args.followtag or false
|
||||
pulsebar.notification_preset = args.notification_preset
|
||||
pulsebar.devicetype = args.devicetype or "sink"
|
||||
pulsebar.cmd = args.cmd or "pacmd list-" .. pulsebar.devicetype .. "s | sed -n -e '/*/,$!d' -e '/index/p' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
|
||||
|
||||
if not pulsebar.notification_preset then
|
||||
pulsebar.notification_preset = {
|
||||
font = "Monospace 10"
|
||||
}
|
||||
end
|
||||
|
||||
pulsebar.bar = wibox.widget {
|
||||
color = pulsebar.colors.unmute,
|
||||
background_color = pulsebar.colors.background,
|
||||
forced_height = height,
|
||||
forced_width = width,
|
||||
margins = margins,
|
||||
paddings = paddings,
|
||||
ticks = ticks,
|
||||
ticks_size = ticks_size,
|
||||
widget = wibox.widget.progressbar,
|
||||
}
|
||||
|
||||
pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
|
||||
|
||||
function pulsebar.update(callback)
|
||||
helpers.async({ awful.util.shell, "-c", type(pulsebar.cmd) == "string" and pulsebar.cmd or pulsebar.cmd() },
|
||||
function(s)
|
||||
volume_now = {
|
||||
index = string.match(s, "index: (%S+)") or "N/A",
|
||||
device = string.match(s, "device.string = \"(%S+)\"") or "N/A",
|
||||
muted = string.match(s, "muted: (%S+)") or "N/A"
|
||||
}
|
||||
|
||||
pulsebar.device = volume_now.index
|
||||
|
||||
local ch = 1
|
||||
volume_now.channel = {}
|
||||
for v in string.gmatch(s, ":.-(%d+)%%") do
|
||||
volume_now.channel[ch] = v
|
||||
ch = ch + 1
|
||||
end
|
||||
|
||||
volume_now.left = volume_now.channel[1] or "N/A"
|
||||
volume_now.right = volume_now.channel[2] or "N/A"
|
||||
|
||||
local volu = volume_now.left
|
||||
local mute = volume_now.muted
|
||||
|
||||
if volu:match("N/A") or mute:match("N/A") then return end
|
||||
|
||||
if volu ~= pulsebar._current_level or mute ~= pulsebar._mute then
|
||||
pulsebar._current_level = tonumber(volu)
|
||||
pulsebar.bar:set_value(pulsebar._current_level / 100)
|
||||
if pulsebar._current_level == 0 or mute == "yes" then
|
||||
pulsebar._mute = mute
|
||||
pulsebar.tooltip:set_text ("[muted]")
|
||||
pulsebar.bar.color = pulsebar.colors.mute
|
||||
pulsebar.bar.background_color = pulsebar.colors.mute_background
|
||||
else
|
||||
pulsebar._mute = "no"
|
||||
pulsebar.tooltip:set_text(string.format("%s %s: %s", pulsebar.devicetype, pulsebar.device, volu))
|
||||
pulsebar.bar.color = pulsebar.colors.unmute
|
||||
pulsebar.bar.background_color = pulsebar.colors.background
|
||||
end
|
||||
|
||||
settings()
|
||||
|
||||
if type(callback) == "function" then callback() end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function pulsebar.notify()
|
||||
pulsebar.update(function()
|
||||
local preset = pulsebar.notification_preset
|
||||
|
||||
preset.title = string.format("%s %s - %s%%", pulsebar.devicetype, pulsebar.device, pulsebar._current_level)
|
||||
|
||||
if pulsebar._mute == "yes" then
|
||||
preset.title = preset.title .. " muted"
|
||||
end
|
||||
|
||||
-- tot is the maximum number of ticks to display in the notification
|
||||
-- fallback: default horizontal wibox height
|
||||
local wib, tot = awful.screen.focused().mywibox, 20
|
||||
|
||||
-- if we can grab mywibox, tot is defined as its height if
|
||||
-- horizontal, or width otherwise
|
||||
if wib then
|
||||
if wib.position == "left" or wib.position == "right" then
|
||||
tot = wib.width
|
||||
else
|
||||
tot = wib.height
|
||||
end
|
||||
end
|
||||
|
||||
local int = math.modf((pulsebar._current_level / 100) * tot)
|
||||
preset.text = string.format(
|
||||
"%s%s%s%s",
|
||||
tick_pre,
|
||||
string.rep(tick, int),
|
||||
string.rep(tick_none, tot - int),
|
||||
tick_post
|
||||
)
|
||||
|
||||
if pulsebar.followtag then preset.screen = awful.screen.focused() end
|
||||
|
||||
if not pulsebar.notification then
|
||||
pulsebar.notification = naughty.notify {
|
||||
preset = preset,
|
||||
destroy = function() pulsebar.notification = nil end
|
||||
}
|
||||
else
|
||||
naughty.replace_text(pulsebar.notification, preset.title, preset.text)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.newtimer(string.format("pulsebar-%s-%s", pulsebar.devicetype, pulsebar.device), timeout, pulsebar.update)
|
||||
|
||||
return pulsebar
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,39 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
* (c) 2010-2012, Peter Hofmann
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local wibox = require("wibox")
|
||||
local open, match = io.open, string.match
|
||||
|
||||
-- System load
|
||||
-- lina.widget.sysload
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local sysload = { widget = args.widget or wibox.widget.textbox() }
|
||||
local timeout = args.timeout or 2
|
||||
local settings = args.settings or function() end
|
||||
|
||||
function sysload.update()
|
||||
local f = open("/proc/loadavg")
|
||||
local ret = f:read("*all")
|
||||
f:close()
|
||||
|
||||
load_1, load_5, load_15 = match(ret, "([^%s]+) ([^%s]+) ([^%s]+)")
|
||||
|
||||
widget = sysload.widget
|
||||
settings()
|
||||
end
|
||||
|
||||
helpers.newtimer("sysload", timeout, sysload.update)
|
||||
|
||||
return sysload
|
||||
end
|
||||
|
||||
return factory
|
|
@ -1,50 +0,0 @@
|
|||
--[[
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
* (c) 2013, Luca CPZ
|
||||
|
||||
--]]
|
||||
|
||||
local helpers = require("lina.helpers")
|
||||
local wibox = require("wibox")
|
||||
local tonumber = tonumber
|
||||
|
||||
-- {thermal,core} temperature info
|
||||
-- lina.widget.temp
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
||||
local temp = { widget = args.widget or wibox.widget.textbox() }
|
||||
local timeout = args.timeout or 30
|
||||
local tempfile = args.tempfile or "/sys/devices/virtual/thermal/thermal_zone0/temp"
|
||||
local format = args.format or "%.1f"
|
||||
local settings = args.settings or function() end
|
||||
|
||||
function temp.update()
|
||||
helpers.async({"find", "/sys/devices", "-type", "f", "-name", "*temp*"}, function(f)
|
||||
temp_now = {}
|
||||
local temp_fl, temp_value
|
||||
for t in f:gmatch("[^\n]+") do
|
||||
temp_fl = helpers.first_line(t)
|
||||
if temp_fl then
|
||||
temp_value = tonumber(temp_fl)
|
||||
temp_now[t] = temp_value and temp_value/1e3 or temp_fl
|
||||
end
|
||||
end
|
||||
if temp_now[tempfile] then
|
||||
coretemp_now = string.format(format, temp_now[tempfile])
|
||||
else
|
||||
coretemp_now = "N/A"
|
||||
end
|
||||
widget = temp.widget
|
||||
settings()
|
||||
end)
|
||||
end
|
||||
|
||||
helpers.newtimer("thermal", timeout, temp.update)
|
||||
|
||||
return temp
|
||||
end
|
||||
|
||||
return factory
|
|
@ -14,7 +14,6 @@ local math = math
|
|||
local os = os
|
||||
local string = string
|
||||
local type = type
|
||||
local tonumber = tonumber
|
||||
|
||||
-- PirateWeather
|
||||
-- current weather and X-days forecast
|
||||
|
@ -33,7 +32,6 @@ local function factory(args)
|
|||
local lat = args.lat or 0 -- placeholder
|
||||
local lon = args.lon or 0 -- placeholder
|
||||
local units = args.units or "metric"
|
||||
local lang = args.lang or "en"
|
||||
local cnt = args.cnt or 5
|
||||
local icons_path = args.icons_path or helpers.icons_dir .. "openweathermap/"
|
||||
local notification_preset = args.notification_preset or {}
|
||||
|
@ -98,10 +96,10 @@ local function factory(args)
|
|||
|
||||
if not err and type(weather_now) == "table" then
|
||||
weather.notification_text = ""
|
||||
for i = 1, 5 do -- TODO: Don't hardcode this table length at 5
|
||||
for i = 1, cnt do
|
||||
weather.notification_text = weather.notification_text
|
||||
.. notification_text_fun(weather_now["daily"]["data"][i])
|
||||
if i < 5 then
|
||||
if i < cnt then
|
||||
weather.notification_text = weather.notification_text .. "\n"
|
||||
end
|
||||
end
|
||||
|
@ -109,66 +107,19 @@ local function factory(args)
|
|||
end)
|
||||
end
|
||||
|
||||
function weather.is_daytime()
|
||||
local sun_position_cmd = string.format(forecast_call, APPID, lat, lon, units)
|
||||
|
||||
local is_daytime
|
||||
local icon
|
||||
local err
|
||||
helpers.async(sun_position_cmd, function(f)
|
||||
sun_position, _, err = json.decode(f, 1, nil)
|
||||
print("****DEBUG**** icon: ", sun_position["daily"]["icon"])
|
||||
|
||||
if not err and type(sun_position) == "table" then
|
||||
local sunrise = tonumber(sun_position["daily"]["data"][1]["sunriseTime"])
|
||||
local sunset = tonumber(sun_position["daily"]["data"][1]["sunsetTime"])
|
||||
icon = sun_position["daily"]["icon"]
|
||||
local loc_now = os.time()
|
||||
|
||||
if sunrise <= loc_now and loc_now <= sunset then
|
||||
is_daytime, icon, err = true, icon, nil
|
||||
else
|
||||
is_daytime, icon, err = false, icon, nil
|
||||
end
|
||||
else
|
||||
is_daytime, icon, err = true, icon, err
|
||||
end
|
||||
end)
|
||||
return is_daytime, icon, err
|
||||
end
|
||||
|
||||
function weather.update()
|
||||
local cmd = string.format(current_call, APPID, lat, lon, units)
|
||||
|
||||
helpers.async(cmd, function(f)
|
||||
local err
|
||||
weather_now, _, err = json.decode(f, 1, nil)
|
||||
print("****DEBUG**** weather_now: ", weather_now["currently"]["temperature"])
|
||||
|
||||
if not err and type(weather_now) == "table" then
|
||||
--[[
|
||||
is_daytime, icon, err = weather.is_daytime()
|
||||
print("****DEBUG**** is_daytime, icon, err: ", is_daytime, icon, err)
|
||||
print("****DEBUG**** weather-now-icon: ", weather_now["currently"]["icon"])
|
||||
if
|
||||
not err --[[and type(icon) == "string"
|
||||
then
|
||||
current_hour = os.date("*t").hour
|
||||
if current_hour >= 6 and current_hour <= 18 then
|
||||
icon = string.gsub(weather_now["currently"]["icon"], "night", "day")
|
||||
else
|
||||
icon = string.gsub(weather_now["currently"]["icon"], "day", "night")
|
||||
end
|
||||
--]]
|
||||
|
||||
icon = weather_now["currently"]["icon"]
|
||||
weather.icon_path = icons_path .. icon .. ".png"
|
||||
print("****DEBUG**** weather_update if-arm")
|
||||
widget = weather.widget
|
||||
settings()
|
||||
-- end
|
||||
else
|
||||
print("****DEBUG**** err: " .. err .. " ; type: " .. type(weather_now))
|
||||
weather.icon_path = icons_path .. "na.png"
|
||||
weather.widget:set_markup(weather_na_markup)
|
||||
end
|
||||
|
|
|
@ -270,7 +270,6 @@ local myweather = lina.widget.weather({
|
|||
end,
|
||||
settings = function()
|
||||
units = math.floor(weather_now["currently"]["temperature"])
|
||||
print("*****DEBUG**** settings: units: " .. units)
|
||||
widget:set_markup(" " .. units .. " ")
|
||||
end,
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue