fix(wifi): has_style_class crash, panel refresh, other networks
- Replace Svg.has_style_class (nonexistent) with _anim_state flag - Add on_show handler to trigger scan+refresh when wifi widget mapped - Fix other_networks snap_to_size when section visible with children - Add destroyed widget guards on connection callbacks
This commit is contained in:
1 file changed
+43
-27
@@ -34,6 +34,7 @@ class WifiNetworkSlot(Box):
|
|||||||
self.icon_name = access_point.icon
|
self.icon_name = access_point.icon
|
||||||
|
|
||||||
self.is_connected = access_point.is_active
|
self.is_connected = access_point.is_active
|
||||||
|
self._anim_state = None # "connecting" | "disconnecting" | None
|
||||||
|
|
||||||
if self.is_connected:
|
if self.is_connected:
|
||||||
self.add_style_class("connected")
|
self.add_style_class("connected")
|
||||||
@@ -89,11 +90,12 @@ class WifiNetworkSlot(Box):
|
|||||||
self.strength = access_point.strength
|
self.strength = access_point.strength
|
||||||
self.is_connected = access_point.is_active
|
self.is_connected = access_point.is_active
|
||||||
|
|
||||||
if not self.dimage.has_style_class(
|
if access_point.is_active:
|
||||||
"connecting"
|
self.dimage.remove_style_class("connecting")
|
||||||
) and not self.dimage.has_style_class("disconnecting"):
|
self.dimage.remove_style_class("disconnecting")
|
||||||
from shared.widgets.wifi_icon import get_wifi_icon_for_strength
|
self._anim_state = None
|
||||||
|
|
||||||
|
if self._anim_state is None:
|
||||||
wifi_icon_path = get_wifi_icon_for_strength(self.strength)
|
wifi_icon_path = get_wifi_icon_for_strength(self.strength)
|
||||||
self.dimage.set_from_file(wifi_icon_path)
|
self.dimage.set_from_file(wifi_icon_path)
|
||||||
|
|
||||||
@@ -106,6 +108,7 @@ class WifiNetworkSlot(Box):
|
|||||||
connecting_icon = get_wifi_connecting_icon()
|
connecting_icon = get_wifi_connecting_icon()
|
||||||
self.dimage.set_from_file(connecting_icon)
|
self.dimage.set_from_file(connecting_icon)
|
||||||
self.dimage.add_style_class("disconnecting")
|
self.dimage.add_style_class("disconnecting")
|
||||||
|
self._anim_state = "disconnecting"
|
||||||
|
|
||||||
if self.network_service:
|
if self.network_service:
|
||||||
self.network_service.disconnect_wifi()
|
self.network_service.disconnect_wifi()
|
||||||
@@ -119,27 +122,21 @@ class WifiNetworkSlot(Box):
|
|||||||
if self.access_point.requires_password and not is_saved:
|
if self.access_point.requires_password and not is_saved:
|
||||||
self._show_password_dialog()
|
self._show_password_dialog()
|
||||||
else:
|
else:
|
||||||
# Try to connect without password (for open or saved networks)
|
|
||||||
connecting_icon = get_wifi_connecting_icon()
|
connecting_icon = get_wifi_connecting_icon()
|
||||||
self.dimage.set_from_file(connecting_icon)
|
self.dimage.set_from_file(connecting_icon)
|
||||||
self.dimage.add_style_class("connecting")
|
self.dimage.add_style_class("connecting")
|
||||||
|
self._anim_state = "connecting"
|
||||||
|
|
||||||
def on_open_connection_result(success, message):
|
def on_open_connection_result(success, message):
|
||||||
"""Handle the connection result for open networks"""
|
if not self.get_parent():
|
||||||
|
return
|
||||||
if success:
|
if success:
|
||||||
self.is_connected = True
|
|
||||||
# Remove connecting state after a short delay
|
|
||||||
GLib.timeout_add(500, lambda: self._reset_connect_state())
|
GLib.timeout_add(500, lambda: self._reset_connect_state())
|
||||||
else:
|
else:
|
||||||
# Connection failed
|
|
||||||
self._reset_connect_state()
|
self._reset_connect_state()
|
||||||
# If password was wrong or auth failed, prompt the user
|
|
||||||
if message == "Wrong password":
|
if message == "Wrong password":
|
||||||
self._show_password_dialog()
|
self._show_password_dialog()
|
||||||
|
|
||||||
# Update display after connection attempt
|
|
||||||
self.on_changed()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.network_service:
|
if self.network_service:
|
||||||
self.network_service.connect_wifi(
|
self.network_service.connect_wifi(
|
||||||
@@ -150,13 +147,11 @@ class WifiNetworkSlot(Box):
|
|||||||
f"[WiFi] Failed to connect to {self.access_point.ssid}: {e}"
|
f"[WiFi] Failed to connect to {self.access_point.ssid}: {e}"
|
||||||
)
|
)
|
||||||
self._reset_connect_state()
|
self._reset_connect_state()
|
||||||
self.on_changed()
|
|
||||||
|
|
||||||
self.on_changed()
|
|
||||||
|
|
||||||
def _reset_disconnect_state(self):
|
def _reset_disconnect_state(self):
|
||||||
"""Reset visual state after disconnect operation"""
|
"""Reset visual state after disconnect operation"""
|
||||||
self.dimage.remove_style_class("disconnecting")
|
self.dimage.remove_style_class("disconnecting")
|
||||||
|
self._anim_state = None
|
||||||
wifi_icon_path = get_wifi_icon_for_strength(self.strength)
|
wifi_icon_path = get_wifi_icon_for_strength(self.strength)
|
||||||
self.dimage.set_from_file(wifi_icon_path)
|
self.dimage.set_from_file(wifi_icon_path)
|
||||||
self.on_changed()
|
self.on_changed()
|
||||||
@@ -165,6 +160,7 @@ class WifiNetworkSlot(Box):
|
|||||||
def _reset_connect_state(self):
|
def _reset_connect_state(self):
|
||||||
"""Reset visual state after connect operation"""
|
"""Reset visual state after connect operation"""
|
||||||
self.dimage.remove_style_class("connecting")
|
self.dimage.remove_style_class("connecting")
|
||||||
|
self._anim_state = None
|
||||||
wifi_icon_path = get_wifi_icon_for_strength(self.strength)
|
wifi_icon_path = get_wifi_icon_for_strength(self.strength)
|
||||||
self.dimage.set_from_file(wifi_icon_path)
|
self.dimage.set_from_file(wifi_icon_path)
|
||||||
self.on_changed()
|
self.on_changed()
|
||||||
@@ -205,9 +201,12 @@ class WifiNetworkSlot(Box):
|
|||||||
connecting_icon = get_wifi_connecting_icon()
|
connecting_icon = get_wifi_connecting_icon()
|
||||||
self.dimage.set_from_file(connecting_icon)
|
self.dimage.set_from_file(connecting_icon)
|
||||||
self.dimage.add_style_class("connecting")
|
self.dimage.add_style_class("connecting")
|
||||||
|
self._anim_state = "connecting"
|
||||||
|
|
||||||
def on_connection_result(success, message):
|
def on_connection_result(success, message):
|
||||||
"""Handle the connection result"""
|
"""Handle the connection result"""
|
||||||
|
if not self.get_parent():
|
||||||
|
return
|
||||||
if success:
|
if success:
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
|
|
||||||
@@ -289,7 +288,7 @@ class WifiConnections(Box):
|
|||||||
if show_back_button:
|
if show_back_button:
|
||||||
title_children.append(
|
title_children.append(
|
||||||
Button(
|
Button(
|
||||||
image=Image(icon_name="back", size=10),
|
image=svg_file("misc/chevron-left.svg", size=10),
|
||||||
on_clicked=lambda *_: self.parent.close_wifi(),
|
on_clicked=lambda *_: self.parent.close_wifi(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -379,6 +378,13 @@ class WifiConnections(Box):
|
|||||||
|
|
||||||
self.connect("destroy", self.on_destroy)
|
self.connect("destroy", self.on_destroy)
|
||||||
self.connect("unmap", self.on_hide)
|
self.connect("unmap", self.on_hide)
|
||||||
|
self.connect("map", self.on_show)
|
||||||
|
|
||||||
|
def on_show(self, *_):
|
||||||
|
"""Called when the widget is mapped (popup opened)"""
|
||||||
|
if self.wifi_service:
|
||||||
|
self.wifi_service.scan()
|
||||||
|
self.force_network_refresh()
|
||||||
|
|
||||||
def on_hide(self, *_):
|
def on_hide(self, *_):
|
||||||
"""Called when the widget is hidden (popup closed)"""
|
"""Called when the widget is hidden (popup closed)"""
|
||||||
@@ -508,6 +514,17 @@ class WifiConnections(Box):
|
|||||||
self._update_in_progress = True
|
self._update_in_progress = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# When WiFi is disabled, clear all network slots
|
||||||
|
if not self.wifi_service.enabled:
|
||||||
|
for child in self.known_networks.get_children():
|
||||||
|
self.known_networks.remove(child)
|
||||||
|
for child in self.other_networks.get_children():
|
||||||
|
self.other_networks.remove(child)
|
||||||
|
self.known_networks_scrolled.set_visible(True)
|
||||||
|
self.no_networks_label.set_visible(True)
|
||||||
|
self.other_networks_button.set_visible(True)
|
||||||
|
return
|
||||||
|
|
||||||
access_points = self.wifi_service.access_points
|
access_points = self.wifi_service.access_points
|
||||||
known_networks = []
|
known_networks = []
|
||||||
other_networks = []
|
other_networks = []
|
||||||
@@ -568,21 +585,13 @@ class WifiConnections(Box):
|
|||||||
for slot in existing_known.values():
|
for slot in existing_known.values():
|
||||||
if hasattr(slot, "access_point"):
|
if hasattr(slot, "access_point"):
|
||||||
slot.strength = 0
|
slot.strength = 0
|
||||||
from shared.widgets.wifi_icon import get_wifi_icon_for_strength
|
if slot._anim_state is None:
|
||||||
|
|
||||||
if not slot.dimage.has_style_class(
|
|
||||||
"connecting"
|
|
||||||
) and not slot.dimage.has_style_class("disconnecting"):
|
|
||||||
slot.dimage.set_from_file(get_wifi_icon_for_strength(0))
|
slot.dimage.set_from_file(get_wifi_icon_for_strength(0))
|
||||||
|
|
||||||
for slot in existing_other.values():
|
for slot in existing_other.values():
|
||||||
if hasattr(slot, "access_point"):
|
if hasattr(slot, "access_point"):
|
||||||
slot.strength = 0
|
slot.strength = 0
|
||||||
from shared.widgets.wifi_icon import get_wifi_icon_for_strength
|
if slot._anim_state is None:
|
||||||
|
|
||||||
if not slot.dimage.has_style_class(
|
|
||||||
"connecting"
|
|
||||||
) and not slot.dimage.has_style_class("disconnecting"):
|
|
||||||
slot.dimage.set_from_file(get_wifi_icon_for_strength(0))
|
slot.dimage.set_from_file(get_wifi_icon_for_strength(0))
|
||||||
|
|
||||||
if not self._destroyed:
|
if not self._destroyed:
|
||||||
@@ -595,6 +604,13 @@ class WifiConnections(Box):
|
|||||||
self.other_networks_button.set_visible(True) # Always visible
|
self.other_networks_button.set_visible(True) # Always visible
|
||||||
self.refresh_network_states()
|
self.refresh_network_states()
|
||||||
|
|
||||||
|
if self.other_networks.get_visible():
|
||||||
|
other_children = self.other_networks.get_children()
|
||||||
|
if other_children:
|
||||||
|
nat_h = self.other_networks.get_preferred_height()[1]
|
||||||
|
if nat_h > 0:
|
||||||
|
self.other_networks_scrolled.snap_to_size(min(nat_h, 300))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[WiFi] Error during update_networks: {e}")
|
logger.error(f"[WiFi] Error during update_networks: {e}")
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
Reference in new issue
Block a user