diff --git a/src/window/controlcenter/bluetooth.py b/src/window/controlcenter/bluetooth.py index 2b7735d..5551bde 100644 --- a/src/window/controlcenter/bluetooth.py +++ b/src/window/controlcenter/bluetooth.py @@ -1,6 +1,6 @@ from enum import Enum, auto -from fabric.utils import Gdk, GLib, Gtk, exec_shell_command, logger +from fabric.utils import Gdk, GLib, Gtk, logger from fabric.widgets.box import Box from fabric.widgets.button import Button from fabric.widgets.centerbox import CenterBox @@ -46,17 +46,6 @@ def get_battery_theme_icon(percentage: float, charging: bool = False) -> str: def set_bluetooth_enabled_with_fallback(client, enabled: bool): - if enabled: - command = "rfkill unblock bluetooth" - else: - command = "rfkill block bluetooth" - - result = exec_shell_command(command) - if result is False: - logger.error(f"rfkill fallback failed: command '{command}' returned False") - elif isinstance(result, str) and result.strip(): - logger.warning(f"rfkill command output: {result.strip()}") - try: if hasattr(client, "set_enabled"): client.set_enabled(enabled) @@ -481,6 +470,7 @@ class BluetoothConnections(Box): def handle_user_toggle(self, active: bool): self._switch_lock = True set_bluetooth_enabled_with_fallback(self.client, active) + self.toggle_button.set_active(active) GLib.timeout_add(1500, self._unlock_switch) def _unlock_switch(self): diff --git a/src/window/controlcenter/main.py b/src/window/controlcenter/main.py index d9f2129..93a4918 100644 --- a/src/window/controlcenter/main.py +++ b/src/window/controlcenter/main.py @@ -107,8 +107,14 @@ class ModusControlCenter(AppletWindow): wlan = modus_service.wlan if modus_service.wlan else "No Connection" bluetooth = modus_service.bluetooth if modus_service.bluetooth else "Off" + if wlan.startswith("connected:"): + parts = wlan.split(":") + wlan_display = parts[1] if len(parts) >= 2 else "Connected" + else: + wlan_display = wlan + self.wlan_label = Label( - label=wlan, + label=wlan_display, name="wifi-widget-label", max_chars_width=15, h_align="start", @@ -487,8 +493,10 @@ class ModusControlCenter(AppletWindow): ], ) - # Initialize managers directly like working version - self.wifi_man = WifiConnections(self) + # Initialize network service upfront so WifiConnections can use it + self.network_service = NetworkClient() + self.network_service.connect("device-ready", self.on_network_ready) + self.wifi_man = WifiConnections(self, network_service=self.network_service) self.bluetooth_man = BluetoothConnections(self) self.has_bluetooth_open = False @@ -565,11 +573,8 @@ class ModusControlCenter(AppletWindow): try: logger.debug("Initializing control center resources...") - # Initialize network service lazily - if self.network_service is None: - self.network_service = NetworkClient() - # Connect network signal - self.network_service.connect("device-ready", self.on_network_ready) + # Connect network signal (service created earlier in __init__) + self.network_service.connect("device-ready", self.on_network_ready) # Check initial states lazily (only when needed) self._check_initial_states() @@ -896,29 +901,35 @@ class ModusControlCenter(AppletWindow): return try: if hasattr(self, "bluetooth_man") and hasattr(self.bluetooth_man, "client"): - current_state = self.bluetooth_man.client.enabled - set_bluetooth_enabled_with_fallback( - self.bluetooth_man.client, not current_state + client = self.bluetooth_man.client + target = not client.enabled + set_bluetooth_enabled_with_fallback(client, target) + client.notify("enabled") + self.bluetooth_svg.dynamic_file( + "applets/bluetooth.svg" if target else "applets/bluetooth-off.svg" ) + self.bluetooth_label.set_label("On" if target else "Off") else: logger.warning("Bluetooth client not available for toggling") except Exception as e: logger.warning(f"Failed to toggle bluetooth: {e}") def on_network_ready(self, *_): - if self._network_ready_fired: + if self._network_ready_fired and self.wifi_service: + return + wifi = self.network_service.wifi_device + if not wifi: return self._network_ready_fired = True - self.wifi_service = self.network_service.wifi_device - if self.wifi_service: - self._signal_connections.append( - ( - self.wifi_service, - self.wifi_service.connect( - "notify::wireless-enabled", self.update_wifi_icon - ), - ) + self.wifi_service = wifi + self._signal_connections.append( + ( + self.wifi_service, + self.wifi_service.connect( + "notify::wireless-enabled", self.update_wifi_icon + ), ) + ) def update_wifi_icon(self, *_): try: @@ -935,8 +946,8 @@ class ModusControlCenter(AppletWindow): return try: if self.wifi_service: - self.wifi_service.toggle_wifi() - GLib.timeout_add(100, self.update_wifi_icon) + target = not self.wifi_service.enabled + self.wifi_service.enabled = target else: logger.warning("WiFi device not available for toggling") except Exception as e: diff --git a/src/window/controlcenter/nightlight.py b/src/window/controlcenter/nightlight.py index cfa93af..9e5d88f 100644 --- a/src/window/controlcenter/nightlight.py +++ b/src/window/controlcenter/nightlight.py @@ -33,8 +33,9 @@ def create_night_light_widget(control_center): ) def toggle_ui(*_): + nonlocal is_active if toggle_night_light(): - is_active = is_night_light_active() + is_active = not is_active night_light_icon.dynamic_file( "applets/redshift-status-on.svg" if is_active diff --git a/src/window/controlcenter/wifi.py b/src/window/controlcenter/wifi.py index fcd6ee5..b335c39 100644 --- a/src/window/controlcenter/wifi.py +++ b/src/window/controlcenter/wifi.py @@ -260,7 +260,7 @@ class WifiNetworkSlot(Box): class WifiConnections(Box): - def __init__(self, parent, show_back_button=True, **kwargs): + def __init__(self, parent, show_back_button=True, network_service=None, **kwargs): super().__init__( spacing=8, orientation="vertical", @@ -269,20 +269,24 @@ class WifiConnections(Box): ) self.parent = parent - self.network_service = NetworkClient() + self.network_service = network_service or NetworkClient() self.wifi_service = None self.is_scanning = False # Track scanning state self._update_in_progress = False # Prevent concurrent updates self._destroyed = False # Track if widget is destroyed self._signal_ids = [] # Track all service signal IDs for cleanup self._network_ready_fired = False # Guard against duplicate device-ready + self._pending_toggle = None # Force toggle to target after stale revert - self._signal_ids.append( - ( - self.network_service, - self.network_service.connect("device-ready", self.on_network_ready), + if network_service and network_service.wifi_device: + self.on_network_ready() + else: + self._signal_ids.append( + ( + self.network_service, + self.network_service.connect("device-ready", self.on_network_ready), + ) ) - ) # Create pull-to-refresh indicator self.refresh_indicator = Label( @@ -438,41 +442,49 @@ class WifiConnections(Box): def on_network_ready(self, *_): """Called when network service is ready""" - if self._network_ready_fired: + if self._network_ready_fired and self.wifi_service: + return + wifi = self.network_service.wifi_device + if not wifi: return self._network_ready_fired = True - self.wifi_service = self.network_service.wifi_device - if self.wifi_service: - self.toggle_button.set_active(self.wifi_service.enabled) + self.wifi_service = wifi + self.toggle_button.set_active(self.wifi_service.enabled) - self._signal_ids.append( - ( - self.wifi_service, - self.wifi_service.connect( - "notify::enabled", self.on_wifi_enabled_changed - ), - ) + self._signal_ids.append( + ( + self.wifi_service, + self.wifi_service.connect( + "notify::enabled", self.on_wifi_enabled_changed + ), ) - self._signal_ids.append( - ( - self.wifi_service, - self.wifi_service.connect("changed", self.update_networks), - ) + ) + self._signal_ids.append( + ( + self.wifi_service, + self.wifi_service.connect("changed", self.update_networks), ) + ) - # Initial network update - self.update_networks() + # Initial network update + self.update_networks() def on_toggle_changed(self, toggle_button, *_): """Handle WiFi toggle button changes""" if self.wifi_service: - new_state = toggle_button.get_active() - self.wifi_service.enabled = new_state + target = toggle_button.get_active() + self._pending_toggle = target + self.wifi_service.enabled = target + self.toggle_button.set_active(target) def on_wifi_enabled_changed(self, *_): """Handle WiFi enabled state changes""" if self.wifi_service: - self.toggle_button.set_active(self.wifi_service.enabled) + if self._pending_toggle is not None: + self.toggle_button.set_active(self._pending_toggle) + self._pending_toggle = None + else: + self.toggle_button.set_active(self.wifi_service.enabled) def open_network_settings(self, *_): """Open NetworkManager connection editor"""