- Timeouts are expected for services without introspection support
- _dbus_get_pid and _dbus_introspect now log at debug level
- Cache already stores empty results; invalidation on service appear
causes retries which is correct behavior
- Replace system-search-symbolic with misc/search.svg
- Add _ICON_SVG_MAP for GTK theme to SVG path resolution
- Move all imports to top of file (fix E402)
- Replace GTK theme notifications icon with SVG
- Fix load_and_cache_theme_icon to use Gtk.IconTheme directly
instead of IconResolver (designed for app IDs, not theme names)
- Add suffix fallbacks for theme icon resolution
- Replace GTK theme battery icons with SVG from assets/icons/battery/
- Replace back button icon with misc/chevron-left.svg
- Remove unused get_battery_theme_icon function
- Add attach_battery_proxy() for devices where Battery1 appears after Device1
- Handle BLUEZ_BATTERY_IFACE in InterfacesAdded signal
- Search existing devices by object path to attach late battery proxy
- 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
Switch from the abandoned package to .
Patch into sys.modules before importing pam since
python-pam uses it internally but doesn't declare it as a dependency.
Update authenticate call to use pam.pam().authenticate().
This commit fully migrates the Python network service away from external wlan0: connected to Amar 2GNet
"MEDIATEK MT7921 802.11ax"
wifi (mt7921e), 2C:98:11:76:9B:2B, hw, mtu 1500
ip4 default, ip6 default
inet4 192.168.18.70/24
route4 192.168.18.0/24 metric 600
route4 default via 192.168.18.1 metric 600
inet6 2405:acc0:1306:351c:ac94:2135:f9a8:5c89/64
inet6 fe80::4057:8edd:a684:5e33/64
route6 fe80::/64 metric 1024
route6 2405:acc0:1306:351c::/64 metric 600
route6 default via fe80::1 metric 600
lo: connected (externally) to lo
"lo"
loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536
inet4 127.0.0.1/8
inet6 ::1/128
docker0: connected (externally) to docker0
"docker0"
bridge, 0A:89:72:7F:4D:75, sw, mtu 1500
inet4 172.17.0.1/16
route4 172.17.0.0/16 metric 0
p2p-dev-wlan0: disconnected
"p2p-dev-wlan0"
wifi-p2p, hw
enp2s0: unavailable
"Realtek RTL8111/8168/8211/8411"
ethernet (r8169), 40:C2:BA:53:D5:E4, hw, mtu 1500
DNS configuration:
servers: 192.168.18.1
interface: wlan0
servers: fe80::1
interface: wlan0
Use "nmcli device show" to get complete information about known devices and
"nmcli connection show" to get an overview on active connection profiles.
Consult nmcli(1) and nmcli-examples(7) manual pages for complete usage details.
subprocess calls, implementing native D-Bus communication for a more robust and
integrated architecture.
Key changes:
- :
- Implemented native D-Bus methods for , , and .
- Updated to track , , and state.
- Fixed a bug where D-Bus returned a tuple, preventing known networks from being parsed correctly.
- :
- Wired UI events to the new D-Bus connection methods.
- Fixed a race condition in initialization where it missed the synchronous signal, leaving the UI permanently disabled.
- Removed the early-return optimization in that was preventing the active CSS state from applying to already-known networks.
- Cleaned up unused variables to satisfy linting and removed redundant blocks.
- :
- Removed the 5-second timeout hack, as the new D-Bus service properly fires callbacks upon connection success/failure.
- Removed hardcoded WPA2 text to make the dialog security-type agnostic.
- :
- Cleaned up active state styling so only the SVG icon box highlights (using ) when a network is connected.
Use raw D-Bus via Gio.DBusProxy instead of libplayerctl. All MPRIS
interactions now go through standard D-Bus property reads and method calls.
- Filter out playerctld proxy (duplicates active player)
- Validate art URLs (http/https/file only)
- Track failed cover downloads to avoid retry loops
- Remove excessive try/except around safe property reads
- Add public metadata property for consumers
- Fix consumer references to removed _player.props.metadata
- Merge game-mode/charge-limit CSS into shared selectors
- Rewrite Battery service with IntEnum states and charge-limit support
- Add ChargeLimitButton with active-state styling
- Drop ddcutil from dependencies (unused)
- Use org.freedesktop.login1.Session.SetBrightness for kernel backlight
- Remove ddcutil dependency entirely
- Fix OSD: use signal percentage value directly (like audio OSD)
- Fix controlcenter: stop dividing percentage by max_screen again
- Run uv sync before launch to install Python deps
- cd into install dir for uv run (fixes ModuleNotFoundError)
- Handle commented modus.lua lines in hyprland config
- Use Gio.FileMonitor on sysfs brightness file
- Event-driven via inotify instead of periodic polling
- _on_brightness_file_changed callback for file modifications
- spinner now checks exit code and shows cross on failure
- Removed unused print_packages function
- Fixed launch: backgrounded uwsm always returned 0, else branch was
dead code. Now runs in background and checks with pgrep.
Added 13 packages required by the codebase:
- networkmanager, network-manager-applet: network management + GI bindings
- blueman: bluetooth manager GUI
- qalculate-gtk: spotlight calculator engine
- wtype: Wayland keyboard paste simulation
- pipewire, libpulse: audio playback and volume control
- pciutils: GPU detection in About dialog
- gtk-layer-shell: Wayland layer-shell for popup windows
- librsvg: SVG rendering for dock icons
- flatpak: flatpak app registration for global menu
- wayland: wayland-client/wayland-scanner for app-capture build
- gobject-introspection: GIR compilation for app-capture typelib
CI Arch container doesn't have g-i installed. The GIR/typelib is only
needed for Python bindings — shared library builds fine without it.
Both gir dependency and g-ir-compiler are now required: false.
Without tick_widget the Animator falls back to GLib.timeout_add which
fires even when the widget is hidden, wasting CPU on invisible scroll
windows (WiFi/BT connection lists).
Handler was connected twice — once in __init__ and again in
_initialize_resources. Every device-ready event fired on_network_ready
twice. Removed the __init__ connection (the lazy one is correct).
- shlex.quote() in kill_process prevents shell injection
- find_binary now uses shutil.which() instead of spawning 'which'
- Add shell_split() helper for environment.py
- Remove inline import re from escape_markup_text
- get_connectivity was compared as method object (always True), wired
icon always showed no-route when activated
- NM import now catches GLib.Error and ImportError, not just ValueError
- Sets NM = None on failure instead of leaving undefined
- Move _initialized flag to end of __init__ so partial construction
leaves the singleton retryable
- Add unregister_reload_callback() method and off_config_change() helper
- Enables proper cleanup of reload listeners on widget destroy
Replace @foreground, @primary, @error, @outline, @shadow, @secondary
and their var() equivalents with semantic glass-* tokens across 22 files.
Colors without glass equivalents (@on-primary, @cyan, etc.) left as-is.
- Add osd_show_audio/osd_show_brightness methods on OSDWindow
- Register as standalone functions in __main__ for fabric-cli exec
- Keybinds now chain fabric-cli exec after wpctl/brightnessctl
- Emit brightness signal on threshold bypass for small changes
- Drop rfkill from bluetooth toggle (redundant with D-Bus Powered,
was causing stale cache on next read)
- Force toggle switch and icon to target state immediately after
setting, don't wait for D-Bus callback
- Fix nightlight icon race: flip local is_active instead of
re-querying async kill state
- Guard wifi on_network_ready against ethernet-first device loop
(emits device-ready per device; wifi_device None on first)
- Share single NetworkClient between main panel and wifi popup
(eliminates async-init race of two independent instances)
- Strip connected: prefix from wlan label initial display
- Add _pending_toggle pattern to wifi notify handler to
suppress stale-cache revert; same for bluetooth switch lock
Add libcairo2-dev and pkg-config to the dependency-audit.yml workflow so that pycairo can be installed correctly on CI runners. This prevents the build error when installing Python packages that require the Cairo library.