Initial commit

This commit is contained in:
Stefano Mazzucco 2016-10-04 22:56:52 +01:00
commit 1ff669a2a6
4 changed files with 371 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*~
luacov.*
*.rock

96
README.md Normal file
View File

@ -0,0 +1,96 @@
# A widget for the Awesome Window Manager to monitor the network with Connman
This widget uses the
[`connman_dbus`](https://luarocks.org/modules/stefano-m/connman_dbus)
library.
# Requirements
In addition to the requirements listed in the `rockspec` file, you will need
the [Awesome Window Manager](https://awesomewm.org)
and Connman (for more information about this, see the
[`connman_dbus`](https://luarocks.org/modules/stefano-m/connman_dbus)
documentation).
You will also need the DBus headers (`dbus.h`) installed.
For example, Debian and Ubuntu provide the DBus headers with the `libdbus-1-dev`
package, Fedora, RedHad and CentOS provide them with the `dbus-devel` package,
while Arch provides them (alongside the binaries) with the `libdbus` package.
# Installation
## Using Luarocks
Probably, the easiest way to install this widget is to use `luarocks`:
luarocks install connman_widget
You can use the `--local` option if you don't want or can't install
it system-wide
This will ensure that all its dependencies are installed.
### A note about ldbus
This module depends on the [`ldbus`](https://github.com/daurnimator/ldbus)
module that provides the low-level DBus bindings
luarocks install --server=http://luarocks.org/manifests/daurnimator \
ldbus \
DBUS_INCDIR=/usr/include/dbus-1.0/ \
DBUS_ARCH_INCDIR=/usr/lib/dbus-1.0/include
As usual, you can use the `--local` option if you don't want or can't install
it system-wide.
## From source
Alternatively, you can copy the `connman_widget.lua` file in your
`~/.config/awesome` folder. You will have to install all the dependencies
manually though (see the `rockspec` file for more information).
# Configuration
The widget displays network icons that are searched in the folder defined
by `beautiful.connman_icon_theme_dir` with extension
`beautiful.connman_icon_extension`.
The default is to look into `"/usr/share/icons/Adwaita/scalable"` for
icons whose extension is `".svg"`.
Depending on your network devices, you may need some or all of the icons
whose name starts with `network-`.
You can specify a GUI client to be launched when the widget is right-clicked.
This can be done by changing the `gui_client` field of the widget. The default
is [econnman-bin](https://git.enlightenment.org/apps/econnman.git/) that needs
the [EFL libraries and their Python bindings](https://www.enlightenment.org/);
other [Desktop clients are also available](https://wiki.archlinux.org/index.php/Connman#Desktop_clients).
# Mouse controls
When the widget is focused:
* Right button: launches GUI client (defined by the `gui_client` field; defaults to `econnman-bin`)
# Tooltip
A tooltip with the currently connected network is shown. It will simply
say `Wired` for a wired connection, or it will show the WiFi SSID and signal
strenght for a wireless connection.
# Usage
Add the following to your `~/.config/awesome/rc.lua`:
Require the module:
-- require *after* `beautiful.init` or the theme will be inconsistent!
local connman = require("connman_widget")
Add the widget to your layout:
right_layout:add(connman)
# Limitations
Currently, only wired (ethernet) and WiFi connections are supported.

View File

@ -0,0 +1,23 @@
package = "connman_widget"
version = "devel-1"
source = {
url = "git://github.com/stefano-m/awesome-connman_widget",
tag = "master"
}
description = {
summary = "A Connman widget for the Awesome Window Manager",
detailed = [[
Monitor your network devices in Awesome with Connman and DBus.
]],
homepage = "https://github.com/stefano-m/awesome-connman_widget",
license = "GPL v3"
}
dependencies = {
"lua >= 5.1",
"connman_dbus",
}
supported_platforms = { "linux" }
build = {
type = "builtin",
modules = { connman_widget = "connman_widget.lua" },
}

249
connman_widget.lua Normal file
View File

@ -0,0 +1,249 @@
-- Connman network widget
local awful = require("awful")
local beautiful = require("beautiful")
local naughty = require("naughty")
local wibox = require("wibox")
-- Awesome DBus C API
local cdbus = dbus -- luacheck: ignore
local Manager = require("connman_dbus")
local spawn_with_shell = awful.util.spawn_with_shell or awful.spawn.with_shell
local icon_theme_dir = "/usr/share/icons/Adwaita/scalable/"
local icon_theme_extension = ".svg"
icon_theme_dir = beautiful.connman_icon_theme_dir or icon_theme_dir
icon_theme_extension = beautiful.connman_icon_theme_extension or icon_theme_extension
local function default_table(t, default_value)
t = t or {}
local mt = {
__index = function (tbl, key)
if type(default_value) == "table" then
-- create a new table for each new key
default_value = {}
end
rawset(tbl, key, default_value)
return default_value
end
}
setmetatable(t, mt)
return t
end
local icon_statuses = default_table(
{
cellular = {
three_g = "status/network-cellular-3g-symbolic",
four_g = "status/network-cellular-4g-symbolic",
acquiring = "status/network-cellular-acquiring-symbolic",
connected = "status/network-cellular-connected-symbolic",
edge = "status/network-cellular-edge-symbolic",
gprs = "status/network-cellular-gprs-symbolic",
hspa = "status/network-cellular-hspa-symbolic",
no_route = "status/network-cellular-no-route-symbolic",
offline = "status/network-cellular-offline-symbolic",
signal = {
excellent = "status/network-cellular-signal-excellent-symbolic",
good = "status/network-cellular-signal-good-symbolic",
none = "status/network-cellular-signal-none-symbolic",
ok = "status/network-cellular-signal-ok-symbolic",
weak = "status/network-cellular-signal-weak-symbolic",
}
},
unspecified = {
err = "status/network-error-symbolic",
idle = "status/network-idle-symbolic",
no_route = "status/network-no-route-symbolic",
offline = "status/network-offline-symbolic",
receive = "status/network-receive-symbolic",
transmis_receive = "status/network-transmit-receive-symbolic",
transmit = "status/network-transmit-symbolic",
},
vpn = {
acquiring = "status/network-vpn-acquiring-symbolic",
connected = "status/network-vpn-symbolic",
},
ethernet = {
acquiring = "network-wired-acquiring-symbolic",
disconnected = "status/network-wired-disconnected-symbolic",
no_route = "status/network-wired-no-route-symbolic",
offline = "status/network-wired-offline-symbolic",
connected = "devices/network-wired-symbolic", -- this is different!
},
wifi = {
acquiring = "status/network-wireless-acquiring-symbolic",
connected = "status/network-wireless-connected-symbolic",
encrypted = "status/network-wireless-encrypted-symbolic",
hotspot = "status/network-wireless-hotspot-symbolic",
no_route = "status/network-wireless-no-route-symbolic",
offline = "status/network-wireless-offline-symbolic",
signal = {
excellent = "status/network-wireless-signal-excellent-symbolic",
good = "status/network-wireless-signal-good-symbolic",
ok = "status/network-wireless-signal-ok-symbolic",
weak = "status/network-wireless-signal-weak-symbolic",
none = "status/network-wireless-signal-none-symbolic",
},
},
},
{})
local show_signal = {ready = true, online = true}
local function build_icon_path(name)
return icon_theme_dir .. name .. icon_theme_extension
end
local function get_wifi_icon(service)
local states = {
idle = "no_route", -- is this correct?
failure = "offline",
association = "acquiring",
configuration = "acquiring",
disconnect = "offline",
}
if show_signal[service.State] then
local s = service.Strength
local v
if s <= 0 then
v = "none"
elseif s <= 25 then
v = "weak"
elseif s <= 50 then
v = "ok"
elseif s <= 75 then
v = "good"
else
v = "excellent"
end
return build_icon_path(icon_statuses.wifi.signal[v])
else
return build_icon_path(icon_statuses.wifi[states[service.State]])
end
end
local function get_wired_icon(service)
local states = {
idle = "no_route", -- is this correct?
failure = "offline",
association = "acquiring",
configuration = "acquiring",
ready = "connected",
disconnect = "disconnected",
online = "connected",
}
return build_icon_path(icon_statuses.ethernet[states[service.State]])
end
local service_types = {
ethernet = get_wired_icon,
wifi = get_wifi_icon
}
local function update_tooltip(tooltip, mgr)
if mgr.current_service.dbus.path ~= "/invalid" then
local service = mgr.current_service
local msg = tostring(service.Name)
if service.Type == "wifi" and show_signal[service.State] then
msg = msg .. "::" .. service.Strength .. "%"
end
tooltip:set_text(msg)
else
tooltip:set_text(mgr.State)
end
end
local function get_status_icon(mgr)
if mgr.State == "offline" then
return build_icon_path(icon_statuses.unspecified.offline)
elseif mgr.State == "idle" then
return build_icon_path(icon_statuses.unspecified.idle)
elseif mgr.current_service then
local service = mgr.current_service
return service_types[service.Type](service)
else
return build_icon_path(icon_statuses.unspecified.err)
end
end
local widget = wibox.widget.imagebox()
widget.tooltip = awful.tooltip({ objects = { widget },})
widget.gui_client = "econnman-bin"
function widget:update(mgr)
self:set_image(get_status_icon(mgr))
update_tooltip(self.tooltip, mgr)
end
widget:buttons(awful.util.table.join(
awful.button({ }, 3,
function ()
spawn_with_shell(widget.gui_client)
end
)))
local function get_manager()
return Manager:init()
end
local status, manager = pcall(get_manager)
if not status then
naughty.notify({preset=naughty.config.presets.critical,
title="Could not initialize connman",
text=manager})
return widget
end
widget:update(manager)
cdbus.add_match("system", "type=signal,interface=" .. manager.dbus.interface)
cdbus.add_match(
"system",
"type=signal"..
",interface=" .. manager.current_service.dbus.interface ..
",path=" .. manager.current_service.dbus.path ..
",member=PropertyChanged")
cdbus.connect_signal(manager.current_service.dbus.interface,
function (info)
if info.member == "PropertyChanged" and info.path == manager.current_service.dbus.path then
-- Strength is uint8 but Awesome returns a string
-- so I cannot use the name/value pair passed to the function.
-- Instead, I have to update all services again :-(
manager:update_services()
widget:update(manager)
end
end)
cdbus.connect_signal(
manager.dbus.interface,
function (info)
-- for some reasone Awesome does not return the object path
-- of the services with the signal but it sets it to nil :-(
if info.member == "ServicesChanged" then
local path_before = manager.current_service.dbus.path
manager:update_services()
local path_after = manager.current_service.dbus.path
if path_before ~= path_after then
cdbus.remove_match(
"system",
"type=signal,interface=" ..
manager.current_service.dbus.interface .. ",path=" ..
path_before .. ",member=PropertyChanged")
cdbus.add_match(
"system",
"type=signal,interface=" ..
manager.current_service.dbus.interface .. ",path=" ..
path_after .. ",member=PropertyChanged")
end
elseif info.member == "PropertyChanged" then
manager:update_properties()
end
widget:update(manager)
end)
return widget