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.
on_entry_changed uses @debounce(300). When user presses Enter before
debounce fires, _current_results is empty so nothing activates.
Now on_entry_accept triggers an immediate search_single when active
plugin has no results, and activates the first result on callback.
_on_entry_accept checked _active_plugin_entry before _current_results.
Keyword plugins (emoji, clipboard) are always active when prefix typed,
so on_submit (no-op base) swallowed Enter before result.action() fired.
Now results are checked first. on_submit only as fallback when no results.
- wallpapers_dir: read from config, fallback ~/Pictures/Wallpapers
- osd: skip show_audio_osd/show_brightness_osd when disabled
- window_switcher: skip show_switcher when disabled
- global_menu_cache_enabled: bypass GTK class cache when false
- global_menu_method: control discovery strategies (auto/hyprland/dbus)
All keys added to constants.py defaults, settings UI, and config.toml
Add CaptureNotifier import and send notifications when caffeine is enabled or disabled. Introduce is_active() static method to check inhibition status via PID file and process cmdline. Replace previous _read_pid() usage with is_active(). Enhance _humanize to properly format "0s" and hour-only durations. Update activation logic to use the new method and trigger appropriate notifications.
Add support for managing systemd‑inhibit processes via a PID file; introduce _caffeine_is_active helper; modify _check_initial_states and toggle_caffeine to start/stop inhibition and update UI icons and labels.
Modified default active app name in ModusService initialization and update logic to "Modus" to align with the project's branding and avoid confusion with macOS Finder.