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.
When control center hides, PlayerBox.suspend() blocks all signal
handlers. On resume(), clearing the flag wasn't enough — stale
state lingered until next fabricator poll (up to 5s). Now resume()
immediately syncs play/pause icon, metadata, and artwork.