mirror of
https://github.com/vincentbernat/i3wm-configuration.git
synced 2025-06-21 09:35:40 +02:00
i3-companion: push bluetooth status to polybar
This commit is contained in:
parent
e79b7291ad
commit
2fd855e191
2 changed files with 132 additions and 7 deletions
130
bin/i3-companion
130
bin/i3-companion
|
@ -59,14 +59,27 @@ application_icons = {
|
||||||
"zoom": icon(2, ""),
|
"zoom": icon(2, ""),
|
||||||
}
|
}
|
||||||
icons = {
|
icons = {
|
||||||
|
"access-point": icon(2, ""),
|
||||||
|
"bluetooth": icon(2, ""),
|
||||||
|
"car": icon(2, "🚘"),
|
||||||
|
"gamepad": icon(2, "🎮"),
|
||||||
|
"headphones": icon(2, "🎧"),
|
||||||
|
"headset": icon(2, ""),
|
||||||
|
"keyboard": icon(2, "⌨"),
|
||||||
|
"laptop": icon(2, "💻"),
|
||||||
|
"loudspeaker": icon(2, ""),
|
||||||
|
"microphone": icon(2, ""),
|
||||||
|
"mouse": icon(2, ""),
|
||||||
|
"notifications-disabled": icon(2, "🔕"),
|
||||||
|
"notifications-enabled": icon(2, ""),
|
||||||
"nowifi": icon(2, ""),
|
"nowifi": icon(2, ""),
|
||||||
|
"phone": icon(2, "📞"),
|
||||||
|
"unknown": icon(2, ""),
|
||||||
"vpn": icon(2, ""),
|
"vpn": icon(2, ""),
|
||||||
|
"wifi-high": icon(2, ""),
|
||||||
"wifi-low": icon(2, ""),
|
"wifi-low": icon(2, ""),
|
||||||
"wifi-medium": icon(2, ""),
|
"wifi-medium": icon(2, ""),
|
||||||
"wifi-high": icon(2, ""),
|
|
||||||
"wired": icon(2, ""),
|
"wired": icon(2, ""),
|
||||||
"notifications-enabled": icon(2, ""),
|
|
||||||
"notifications-disabled": icon(2, "🔕"),
|
|
||||||
}
|
}
|
||||||
application_icons_nomatch = icon(2, "")
|
application_icons_nomatch = icon(2, "")
|
||||||
application_icons_alone = {application_icons[k] for k in {"vbeterm"}}
|
application_icons_alone = {application_icons[k] for k in {"vbeterm"}}
|
||||||
|
@ -595,6 +608,102 @@ async def bluetooth_notifications(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@on(
|
||||||
|
StartEvent,
|
||||||
|
DBusSignal(
|
||||||
|
system=True,
|
||||||
|
path="/org/bluez",
|
||||||
|
interface="org.freedesktop.DBus.Properties",
|
||||||
|
member="PropertiesChanged",
|
||||||
|
signature="sa{sv}as",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@static(last=None)
|
||||||
|
async def bluetooth_status(i3, event, *args):
|
||||||
|
"""Update bluetooth status for polybar."""
|
||||||
|
if event is StartEvent:
|
||||||
|
# Do we have a bluetooth device?
|
||||||
|
if not os.path.exists("/sys/class/bluetooth"):
|
||||||
|
logger.info("no bluetooth detected")
|
||||||
|
polybar("bluetooth", "")
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Is it a change for an adapter or a device?
|
||||||
|
_, interface, changed, invalid = args
|
||||||
|
if not (
|
||||||
|
interface == "org.bluez.Device1"
|
||||||
|
and "Connected" in changed
|
||||||
|
or interface == "org.bluez.Adapter1"
|
||||||
|
and "Powered" not in changed
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
# OK, get the info
|
||||||
|
conn = i3.system_bus["org.bluez"]
|
||||||
|
om = await conn["/"].get_async_interface(
|
||||||
|
"org.freedesktop.DBus.ObjectManager"
|
||||||
|
)
|
||||||
|
objects = await om.GetManagedObjects()
|
||||||
|
objects = objects[0]
|
||||||
|
powered = False
|
||||||
|
devices = []
|
||||||
|
for path, interfaces in objects.items():
|
||||||
|
if "org.bluez.Adapter1" in interfaces:
|
||||||
|
# We get an adapter!
|
||||||
|
adapter = interfaces["org.bluez.Adapter1"]
|
||||||
|
if adapter["Powered"][1]:
|
||||||
|
powered = True
|
||||||
|
elif "org.bluez.Device1" in interfaces:
|
||||||
|
# We have a device!
|
||||||
|
device = interfaces["org.bluez.Device1"]
|
||||||
|
if not device["Connected"][1]:
|
||||||
|
continue
|
||||||
|
device_class = device["Class"][1]
|
||||||
|
major = (device_class & 0x1F00) >> 8
|
||||||
|
minor = (device_class & 0xFC) >> 2
|
||||||
|
devices.append((major, minor))
|
||||||
|
if not powered:
|
||||||
|
polybar("bluetooth", "")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Generate output
|
||||||
|
# See: https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Baseband.pdf
|
||||||
|
output = [icons["bluetooth"]]
|
||||||
|
for major, minor in devices:
|
||||||
|
if major == 1:
|
||||||
|
output.append(icons["laptop"])
|
||||||
|
elif major == 2:
|
||||||
|
output.append(icons["phone"])
|
||||||
|
elif major == 3:
|
||||||
|
output.append(icons["access-point"])
|
||||||
|
elif major == 4 and minor in {1, 2}:
|
||||||
|
output.append(icons["headset"])
|
||||||
|
elif major == 4 and minor == 4:
|
||||||
|
output.append(icons["microphone"])
|
||||||
|
elif major == 4 and minor in {5, 7, 10}:
|
||||||
|
output.append(icons["loudspeaker"])
|
||||||
|
elif major == 4 and minor == 6:
|
||||||
|
output.append(icons["headphones"])
|
||||||
|
elif major == 4 and minor == 8:
|
||||||
|
output.append(icons["car"])
|
||||||
|
elif major == 5 and minor in {1, 2}:
|
||||||
|
output.append(icons["gamepad"])
|
||||||
|
elif major == 5 and minor & 0x10:
|
||||||
|
output.append(icons["keyboard"])
|
||||||
|
elif major == 5 and minor & 0x20:
|
||||||
|
output.append(icons["mouse"])
|
||||||
|
else:
|
||||||
|
output.append(icons["unknown"])
|
||||||
|
output = "|".join(output)
|
||||||
|
|
||||||
|
# Update polybar
|
||||||
|
if bluetooth_status.last != output:
|
||||||
|
logger.info("updated bluetooth status")
|
||||||
|
polybar("bluetooth", output)
|
||||||
|
bluetooth_status.last = output
|
||||||
|
|
||||||
|
|
||||||
@on(
|
@on(
|
||||||
DBusSignal(
|
DBusSignal(
|
||||||
system=False,
|
system=False,
|
||||||
|
@ -824,7 +933,10 @@ async def main(options):
|
||||||
args_keyword="args",
|
args_keyword="args",
|
||||||
)
|
)
|
||||||
async def wrapped(path, args):
|
async def wrapped(path, args):
|
||||||
return await fn(i3, event, path, *args)
|
try:
|
||||||
|
return await fn(i3, event, path, *args)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"during {fn}: %s", e)
|
||||||
|
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
@ -837,10 +949,18 @@ async def main(options):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Run events that should run on start
|
# Run events that should run on start
|
||||||
|
start_tasks = []
|
||||||
for fn, events in on.functions.items():
|
for fn, events in on.functions.items():
|
||||||
for event in events:
|
for event in events:
|
||||||
if event is StartEvent:
|
if event is StartEvent:
|
||||||
asyncio.create_task(fn(i3, event))
|
|
||||||
|
async def wrapped(fn, event):
|
||||||
|
try:
|
||||||
|
return await fn(i3, event)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"during {fn}: %s", e)
|
||||||
|
|
||||||
|
start_tasks.append(asyncio.create_task(wrapped(fn, event)))
|
||||||
|
|
||||||
await i3.main()
|
await i3.main()
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,11 @@ modules-center = date
|
||||||
|
|
||||||
[bar/alone]
|
[bar/alone]
|
||||||
inherit = bar/common
|
inherit = bar/common
|
||||||
modules-right = cpu memory brightness battery network disk dunst pulseaudio
|
modules-right = cpu memory brightness battery bluetooth network disk dunst pulseaudio
|
||||||
|
|
||||||
[bar/primary]
|
[bar/primary]
|
||||||
inherit = bar/common
|
inherit = bar/common
|
||||||
modules-right = cpu memory brightness battery network disk dunst pulseaudio
|
modules-right = cpu memory brightness battery bluetooth network disk dunst pulseaudio
|
||||||
|
|
||||||
[bar/secondary]
|
[bar/secondary]
|
||||||
inherit = bar/common
|
inherit = bar/common
|
||||||
|
@ -106,6 +106,11 @@ type = custom/ipc
|
||||||
hook-0 = cat $XDG_RUNTIME_DIR/i3/network.txt 2> /dev/null
|
hook-0 = cat $XDG_RUNTIME_DIR/i3/network.txt 2> /dev/null
|
||||||
initial = 1
|
initial = 1
|
||||||
|
|
||||||
|
[module/bluetooth]
|
||||||
|
type = custom/ipc
|
||||||
|
hook-0 = cat $XDG_RUNTIME_DIR/i3/bluetooth.txt 2> /dev/null
|
||||||
|
initial = 1
|
||||||
|
|
||||||
[module/dunst]
|
[module/dunst]
|
||||||
type = custom/ipc
|
type = custom/ipc
|
||||||
hook-0 = cat $XDG_RUNTIME_DIR/i3/dunst.txt 2> /dev/null
|
hook-0 = cat $XDG_RUNTIME_DIR/i3/dunst.txt 2> /dev/null
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue