135 lines
4.7 KiB
Python
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)
|