mirror of
https://github.com/Relz/awesome-wm-theme.git
synced 2026-09-10 07:26:41 -04:00
Add bluetooth widget
This commit is contained in:
parent
ba7c276fec
commit
3685d1c7f7
13
README.md
13
README.md
|
|
@ -93,6 +93,19 @@ You can switch theme mode in menu.
|
|||
|
||||
PS: also in rc.lua and theme.lua you can make your own experiments, suggestions are appreciated. For example, you can create widget for bluetooth, add calendar popup to ClockCalendarWidget, extend theme modes. Let's make the world better together!
|
||||
|
||||
## Extend connected bluetooth device info with battery level
|
||||
|
||||
Bluetooth widget shows alias name for connected bluetooth device. There is a way to show battery level also. This feature is not enabled by default. You have to turn on it manually. To do it, edit `bluetooth.service` file by adding `--experimental` flag to bluetooth daemon executing:
|
||||
|
||||
```ini
|
||||
ExecStart=/usr/lib/bluetooth/bluetoothd
|
||||
```
|
||||
change to
|
||||
|
||||
```ini
|
||||
ExecStart=/usr/lib/bluetooth/bluetoothd --experimental
|
||||
```
|
||||
|
||||
## Subscribe to Direct Rendering Manager change event
|
||||
|
||||
There is `update_screens` function in rc.lua that configures _xrandr_ output. It's useful to call this function when external monitors is connected/disconnected.
|
||||
|
|
|
|||
95
modules/widgets/bluetooth_widget.lua
Normal file
95
modules/widgets/bluetooth_widget.lua
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
local wibox = require("wibox")
|
||||
local gears = require("gears")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
BluetoothWidget_prototype = function()
|
||||
local this = {}
|
||||
|
||||
this.__public_static = {
|
||||
-- Public Static Variables
|
||||
-- Public Static Funcs
|
||||
}
|
||||
|
||||
this.__private_static = {
|
||||
-- Private Static Variables
|
||||
config_path = gears.filesystem.get_configuration_dir()
|
||||
-- Private Static Funcs
|
||||
}
|
||||
|
||||
this.__public = {
|
||||
-- Public Variables
|
||||
name = "BluetoothWidget",
|
||||
icon = wibox.widget.imagebox(),
|
||||
value = wibox.container.background()
|
||||
-- Public Funcs
|
||||
}
|
||||
|
||||
this.__private = {
|
||||
-- Private Variables
|
||||
bluetooth_status = false,
|
||||
bluetooth_device = nil,
|
||||
-- Private Funcs
|
||||
update = function()
|
||||
get_bluetooth_device(function(bluetooth_device)
|
||||
this.__private.bluetooth_device = bluetooth_device
|
||||
|
||||
local icon_file_name = "bluetooth"
|
||||
if not this.__private.bluetooth_status then
|
||||
icon_file_name = icon_file_name .. "_off"
|
||||
elseif bluetooth_device.connected then
|
||||
icon_file_name = icon_file_name .. "_connected"
|
||||
end
|
||||
this.__public.icon.image = gears.color.recolor_image(this.__private_static.config_path .. "/themes/relz/icons/widgets/bluetooth/" .. icon_file_name .. ".svg", beautiful.text_color)
|
||||
|
||||
if this.__private.show_text and bluetooth_device ~= nil then
|
||||
this.__public.value.text = ""
|
||||
if bluetooth_device.alias ~= nil then
|
||||
this.__public.value.text = bluetooth_device.alias
|
||||
end
|
||||
if bluetooth_device.battery_percentage ~= nil then
|
||||
if this.__public.value.text ~= "" then
|
||||
this.__public.value.text = this.__public.value.text .. " "
|
||||
end
|
||||
this.__public.value.text = this.__public.value.text .. string.rep(" ", 3 - get_percent_number_digits_count(bluetooth_device.battery_percentage)) .. bluetooth_device.battery_percentage .. "%"
|
||||
end
|
||||
if this.__public.value.text ~= "" then
|
||||
this.__public.value.text = " " .. this.__public.value.text .. " "
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
this.__construct = function(show_text)
|
||||
-- Constructor
|
||||
this.__private.show_text = show_text
|
||||
|
||||
if this.__private.show_text then
|
||||
this.__public.value = wibox.widget.textbox()
|
||||
this.__public.value.font = beautiful.font_family_mono .. "Bold 9"
|
||||
end
|
||||
|
||||
subscribe_bluetooth_status(function(bluetooth_status)
|
||||
this.__private.bluetooth_status = bluetooth_status
|
||||
this.__private.update()
|
||||
end)
|
||||
|
||||
dbus.add_match("system", "interface='org.freedesktop.DBus.Properties'")
|
||||
dbus.connect_signal("org.freedesktop.DBus.Properties", function(data, interface, chprop)
|
||||
if interface == "org.bluez.Device1" then
|
||||
if chprop.Connected ~= nil then
|
||||
local mac_address = data.path:match("dev_(.+)"):gsub("_", ":")
|
||||
if chprop.Connected or mac_address == this.__private.bluetooth_device.mac_address then
|
||||
this.__private.update()
|
||||
end
|
||||
end
|
||||
elseif interface == "org.bluez.MediaControl1"and data.member == "PropertiesChanged" then
|
||||
this.__private.update()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
return this
|
||||
end
|
||||
|
||||
BluetoothWidget = createClass(BluetoothWidget_prototype)
|
||||
|
|
@ -148,7 +148,7 @@ MicrophoneWidget_prototype = function()
|
|||
local port = nil
|
||||
if device.active_port ~= nil and device.ports[device.active_port] ~= nil then
|
||||
port = device.ports[device.active_port]
|
||||
elseif device.monitor_sink ~= nil then
|
||||
elseif device.monitor_sink ~= nil and device.monitor_sink.active_port ~= nil then
|
||||
port = device.monitor_sink.ports[device.monitor_sink.active_port]
|
||||
end
|
||||
|
||||
|
|
|
|||
3
rc.lua
3
rc.lua
|
|
@ -6,6 +6,7 @@ require("modules/panel")
|
|||
require("modules/widgets/cpu_widget")
|
||||
require("modules/widgets/memory_widget")
|
||||
require("modules/widgets/network_widget")
|
||||
require("modules/widgets/bluetooth_widget")
|
||||
require("modules/widgets/brightness_widget")
|
||||
require("modules/widgets/battery_widget")
|
||||
require("modules/widgets/calendar_widget")
|
||||
|
|
@ -67,6 +68,7 @@ local calendar_widget = CalendarWidget(calendar_command)
|
|||
local clock_widget = ClockWidget(calendar_command)
|
||||
local menu_widget = MenuWidget(session_lock_command)
|
||||
local network_widget = NetworkWidget(false, network_configuration_command)
|
||||
local bluetooth_widget = BluetoothWidget(true)
|
||||
local volume_widget = VolumeWidget(true)
|
||||
local microphone_widget = MicrophoneWidget(true)
|
||||
local keyboard_layout_widget = KeyboardLayoutWidget()
|
||||
|
|
@ -137,6 +139,7 @@ screen_0_panel.widgets = {
|
|||
cpu_widget,
|
||||
memory_widget,
|
||||
network_widget,
|
||||
bluetooth_widget,
|
||||
volume_widget,
|
||||
microphone_widget,
|
||||
brightness_widget,
|
||||
|
|
|
|||
10
themes/relz/icons/widgets/bluetooth/bluetooth.svg
Normal file
10
themes/relz/icons/widgets/bluetooth/bluetooth.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_404_2)">
|
||||
<path d="M17.71 7.71L12 2H11V9.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L11 14.41V22H12L17.71 16.29L13.41 12L17.71 7.71ZM13 5.83L14.88 7.71L13 9.59V5.83ZM14.88 16.29L13 18.17V14.41L14.88 16.29Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_404_2">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 451 B |
10
themes/relz/icons/widgets/bluetooth/bluetooth_connected.svg
Normal file
10
themes/relz/icons/widgets/bluetooth/bluetooth_connected.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_405_2)">
|
||||
<path d="M7 12L5 10L3 12L5 14L7 12ZM17.71 7.71L12 2H11V9.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L11 14.41V22H12L17.71 16.29L13.41 12L17.71 7.71ZM13 5.83L14.88 7.71L13 9.59V5.83ZM14.88 16.29L13 18.17V14.41L14.88 16.29V16.29ZM19 10L17 12L19 14L21 12L19 10Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_405_2">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 514 B |
10
themes/relz/icons/widgets/bluetooth/bluetooth_off.svg
Normal file
10
themes/relz/icons/widgets/bluetooth/bluetooth_off.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_404_5)">
|
||||
<path d="M13 5.83L14.88 7.71L13.28 9.31L14.69 10.72L17.71 7.7L12 2H11V7.03L13 9.03V5.83ZM5.41 4L4 5.41L10.59 12L5 17.59L6.41 19L11 14.41V22H12L16.29 17.71L18.59 20L20 18.59L5.41 4ZM13 18.17V14.41L14.88 16.29L13 18.17Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_404_5">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 475 B |
59
utils.lua
59
utils.lua
|
|
@ -672,7 +672,64 @@ audio_stop = function()
|
|||
awful.spawn("dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Stop", false)
|
||||
end
|
||||
|
||||
-- Keyboard layout
|
||||
-- Bluetooth
|
||||
|
||||
local get_bluetooth_adapter_index = function(callback)
|
||||
awful.spawn.easy_async("rfkill list bluetooth", function(rfkill_list_bluetooth_output)
|
||||
callback(string.match(rfkill_list_bluetooth_output, "^(%d+): "))
|
||||
end)
|
||||
end
|
||||
|
||||
local bluetooth_status_subscribers = {}
|
||||
|
||||
subscribe_bluetooth_status = function(callback)
|
||||
table.insert(bluetooth_status_subscribers, callback)
|
||||
|
||||
if #bluetooth_status_subscribers == 1 then
|
||||
get_bluetooth_adapter_index(function(index)
|
||||
awful.spawn.with_line_callback("rfkill event", {
|
||||
stdout = function(line)
|
||||
if string.match(line, "idx " .. index .. " ") then
|
||||
for _,bluetooth_status_subscriber in ipairs(bluetooth_status_subscribers) do
|
||||
bluetooth_status_subscriber(string.match(line, "soft 0 hard 0") ~= nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
is_bluetooth_device_connected = function(callback)
|
||||
awful.spawn.easy_async("bluetoothctl info", function(bluetoothctl_info_output)
|
||||
callback(string.match(bluetoothctl_info_output, "Missing device address argument\n") == nil)
|
||||
end)
|
||||
end
|
||||
|
||||
get_bluetooth_device = function(callback)
|
||||
is_bluetooth_device_connected(function(is_connected)
|
||||
if not is_connected then
|
||||
callback({
|
||||
connected = false
|
||||
})
|
||||
end
|
||||
|
||||
awful.spawn.easy_async("bluetoothctl info", function(bluetoothctl_info_output)
|
||||
local bluetooth_device = {
|
||||
mac_address = bluetoothctl_info_output:match("^Device (.-) "),
|
||||
name = bluetoothctl_info_output:match("Name: (.-)\n"),
|
||||
alias = bluetoothctl_info_output:match("Alias: (.-)\n"),
|
||||
paired = bluetoothctl_info_output:match("Paired: yes") ~= nil,
|
||||
bonded = bluetoothctl_info_output:match("Bonded: yes") ~= nil,
|
||||
trusted = bluetoothctl_info_output:match("Trusted: yes") ~= nil,
|
||||
blocked = bluetoothctl_info_output:match("Blocked: yes") ~= nil,
|
||||
connected = bluetoothctl_info_output:match("Connected: yes") ~= nil,
|
||||
battery_percentage = tonumber(bluetoothctl_info_output:match("Battery Percentage: %w+ %((%d-)%)"))
|
||||
}
|
||||
callback(bluetooth_device)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Show help
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue