Files
Modus/modules/bar/components/system_indicators.py
T

135 lines
4.7 KiB
Python

import subprocess
from fabric import Fabricator
from fabric.widgets.label import Label
from fabric.widgets.box import Box
from fabric.bluetooth import BluetoothClient
from services import NetworkClient, audio
import utils.icons as icons
class SystemIndicators(Box):
def __init__(self, **kwargs):
super().__init__(orientation="h", spacing=2, **kwargs)
self.bluetooth_icon = Label(name="system-indicator-icon")
self.wifi_icon = Label(name="system-indicator-icon")
self.volume_icon_button = Label(name="system-indicator-icon")
self.microphone_icon = Label(name="system-indicator-icon")
self.idle_label = Label(name="system-indicator-icon")
self.night_label = Label(name="system-indicator-icon")
for widget in [
self.bluetooth_icon,
self.wifi_icon,
self.volume_icon_button,
self.microphone_icon,
self.idle_label,
self.night_label,
]:
self.add(widget)
self.audio_service = audio
self.bluetooth_client = BluetoothClient()
self.network_client = NetworkClient()
# Connect signals
self.bluetooth_client.connect("changed", self.update_bluetooth_status)
self.audio_service.connect("microphone_changed", self.update_mic_status)
self.audio_service.connect("changed", self.update_volume_status)
self.network_client.connect("device_ready", self.update_network_status)
if self.network_client.wifi_device:
self.network_client.wifi_device.connect(
"changed", self.update_network_status
)
if self.network_client.ethernet_device:
self.network_client.ethernet_device.connect(
"changed", self.update_network_status
)
Fabricator(interval=1000, poll_from=self.update_all_statuses)
self.update_bluetooth_status()
def update_all_statuses(self, *_args):
self.update_idle_night_status()
self.update_network_status()
def update_idle_night_status(self, *_):
"""Updates the idle and night mode status icons."""
self.idle_label.set_markup(
icons.coffee
if subprocess.run(
["pgrep", "-x", "wlinhibit"], capture_output=True
).returncode
== 0
else ""
)
self.night_label.set_markup(
icons.night
if subprocess.run(
["pgrep", "-x", "hyprsunset"], capture_output=True
).returncode
== 0
else ""
)
def update_volume_status(self, *_):
"""Updates the volume icon based on speaker status."""
stream = self.audio_service.speaker
if stream:
volume_level = stream.volume
self.volume_icon_button.set_markup(
icons.vol_off
if stream.muted
else (
icons.vol_mute
if volume_level < 1
else (icons.vol_medium if volume_level >= 1 else icons.vol_high)
)
)
def update_mic_status(self, *_):
"""Updates the microphone icon based on mute status."""
mic = self.audio_service.microphone
self.microphone_icon.set_markup(icons.mic_off if mic and mic.muted else "")
self.microphone_icon.set_visible(bool(mic))
def update_bluetooth_status(self, *_):
"""Updates the Bluetooth icon based on enabled status."""
self.bluetooth_icon.set_markup(
icons.bluetooth if self.bluetooth_client.enabled else icons.bluetooth_off
)
def update_network_status(self, *_):
primary_device = self.network_client.primary_device
if primary_device == "wifi" and self.network_client.wifi_device:
wifi_device = self.network_client.wifi_device
self.set_tooltip_text(self.network_client.wifi_device.ssid)
if wifi_device.enabled:
wifi_strength = wifi_device.strength
if wifi_strength == -1: # No active connection
icon_label = icons.wifi_off
else:
icon_label = {
80: icons.wifi,
60: icons.good_signal,
40: icons.moderate_signal,
20: icons.weak_signal,
0: icons.no_signal,
}.get(min(80, 20 * round(wifi_strength / 20)), icons.wifi_off)
else:
icon_label = icons.wifi_off
elif primary_device == "wired":
icon_label = icons.lan
else:
icon_label = icons.wifi_off
self.wifi_icon.set_markup(icon_label)