Commit Graph
100 Commits
Author SHA1 Message Date
sankalp fe3ccd913b refactor(brightness): replace 500ms poll with GLib.FileMonitor
- Use Gio.FileMonitor on sysfs brightness file
- Event-driven via inotify instead of periodic polling
- _on_brightness_file_changed callback for file modifications
2026-07-18 21:48:11 +05:45
sankalp 8f6a040bb7 refactor(dock): replace 300ms occlusion poll with Hyprland events
- Subscribe to openwindow, closewindow, movewindow, workspace, fullscreen
- 50ms debounce to batch rapid successive events
- Event-driven check instead of continuous polling
- Proper cleanup with _disconnect_occlusion_signals()
2026-07-18 21:43:36 +05:45
sankalp 44f1103259 refactor(per_app_volume): remove redundant 2s polling
- stream-added/stream-removed signals already handle app list updates
- Removed _auto_refresh(), _on_map/_on_unmap timer management
- Removed _last_app_names tracking (unused without polling)
2026-07-18 21:43:29 +05:45
sankalp 2a9964a8e5 refactor(mpris): replace Fabricator with direct GLib.timeout_add
- Remove Fabricator dependency from position/status polling
- Position polling: _pos_source_id + _on_pos_poll() (2s interval)
- Status polling: _status_source_id + _on_status_poll() (5s interval)
- Simplified cleanup with direct source_remove calls
2026-07-18 21:43:22 +05:45
sankalp 6286343272 feat(gamemode): add opacity and rounding overrides for fullscreen
- active_opacity=1.0, inactive_opacity=1.0
- active_rounding=0
2026-07-18 21:43:16 +05:45
sankalp 8ee6003241 style: replace solid accent hover/active with glass effect
- glass-hover: alpha(@foreground,0.08) → alpha(white,0.10)
- glass-active: alpha(@foreground,0.14) → alpha(white,0.50)
- panel, settings, dropdown, tray, notification hover → glass-hover
- battery, wifi, bluetooth connected icons → glass-active
- wifi-icon-box base dimmed to glass-hover for contrast
2026-07-18 21:23:28 +05:45
sankalp 2ba5cc9ccc style(src/styles/window): replace @glass-overlay-dark with #000000 in lock.css and panel.css 2026-07-18 19:39:45 +05:45
sankalp f0643a5b03 docs(faqs): add screencapture keybinds and fix plugin paths 2026-07-18 19:29:48 +05:45
sankalp a403b5a649 docs(plugins): add icon_data field and fix duplicate heading
- Add icon_data field to SearchResult documentation
- Remove duplicate 'How It Works' heading
- Fix plugin directory path references
2026-07-18 19:29:45 +05:45
sankalp 5afada35a4 docs(arch): add missing components and services
- Add notification, osd, wallpaper components
- Add 12 missing services to the services table
- Fix plugin directory path
2026-07-18 19:29:40 +05:45
sankalp c0870dacef docs(config): add missing config.toml keys and mods.toml options 2026-07-18 19:29:34 +05:45
sankalp d06768cb85 docs(install): update package list and fix config reference 2026-07-18 19:29:28 +05:45
sankalp 5544367c2c docs(readme): update package list and fix config reference
- Sync package list with install.sh PACKAGES
- Fix modus.conf reference to modus.lua
2026-07-18 19:29:23 +05:45
sankalp 0b2f5be80e docs(styling): fix CSS paths to match actual directory structure 2026-07-18 19:29:17 +05:45
sankalp f4bfb52ba6 fix(install): fix matugen output path and remove unused variable
- Fix matugen output_path from src/shared/styles/ to src/styles/
- Remove unused BULLET variable (shellcheck SC2034)
2026-07-18 19:29:10 +05:45
sankalp 2482078a3f style: simplify section comments to plain # style in notch.py and keyboard_layout.py 2026-07-18 19:06:32 +05:45
sankalp 0fd5d3ea28 style(install): simplify section comments to plain # style 2026-07-18 19:03:23 +05:45
sankalp 591017f6e5 fix(install): fix spinner exit check, remove dead code, fix launch logic
- 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.
2026-07-18 18:51:24 +05:45
sankalp 713f73f45c fix(install): remove install mode selection, keep simple
Removed Full/Minimal/Custom mode picker. Script now always installs
all packages. Kept -n dry-run and -y auto-yes flags.
2026-07-18 15:16:31 +05:45
sankalp ab9b9df4e1 feat(install): rewrite install.sh with interactive mode selection
- 3 install modes: Full, Minimal, Custom (pick categories)
- Dry-run flag (-n) to preview packages without installing
- Progress bar with percentage during package install
- Better visual hierarchy with section headers and dividers
- Package categories: Core, Shell, Hyprland, UI, Hardware, Network, Audio, Build
- Failed package summary at end
- Cleaner banner and completion output
2026-07-18 15:12:21 +05:45
sankalp 6d9057cd06 fix(install): remove wayland from required packages 2026-07-18 14:52:41 +05:45
sankalp c15d023f7d fix(install): use libqalculate instead of qalculate-gtk 2026-07-18 14:51:52 +05:45
sankalp c3179a8065 fix(install): remove flatpak from required packages 2026-07-18 14:50:35 +05:45
sankalp 716054fd58 fix(install): add missing runtime and build dependencies
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
2026-07-18 14:42:14 +05:45
sankalp 82a5ff91af fix(app-capture): make gobject-introspection optional in meson build
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.
2026-07-18 14:28:04 +05:45
sankalp 2a04a17ad7 fix(install): resolve shellcheck warnings in install.sh
- Quote  in kill -0 (SC2086)
- Use %b/%s printf format instead of variable interpolation (SC2059)
- Quote pkg-config command substitution (SC2046)
2026-07-18 14:22:42 +05:45
sankalp 732dd9c0ee fix: formating 2026-07-18 14:21:24 +05:45
sankalp 71c9d30c2c fix(osd): log exception when removing hide timer source
except Exception: pass was hiding stale ID errors.
2026-07-18 14:14:16 +05:45
sankalp 4d90a1ab52 fix(spotlight): log exception when removing stale GLib source IDs
except Exception: pass was hiding errors during pipeline cancellation.
2026-07-18 14:14:09 +05:45
sankalp 1d3cecc255 fix(dialogs): log exception in wifi password connection timeout handler
except Exception: pass was hiding UI state errors during timeout
handling.
2026-07-18 14:13:56 +05:45
sankalp 50e15db2de fix(controlcenter): move inline GLib/os imports to top-level
GLib was imported inline 4 times in seek-bar handlers that fire on
every user seek. os was imported inline in a fallback path. All moved
to top-level.
2026-07-18 14:13:48 +05:45
sankalp 2d982cf286 fix(shared): add tick_widget=self to AnimatedScrollable height_animator
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).
2026-07-18 14:13:44 +05:45
sankalp c00236fc69 fix(dock): remove pointless del svg_w, add warning on trash SVG failure
The del was a no-op (GC handles scope exit). The bare except Exception
hid real rendering errors — now logs at warning level.
2026-07-18 14:13:36 +05:45
sankalp 6a75ea84d9 fix(controlcenter): remove duplicate device-ready signal connection
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).
2026-07-18 14:13:27 +05:45
sankalp ee904cce04 fix(notification): null _spring_timer_id after first remove in on_resolved
on_resolved removed the GLib source but didn't null the ID, causing
double-remove crash when destroy() later tried to clean up the same
stale source.
2026-07-18 14:13:17 +05:45
sankalp 6cd1a2c71a fix(utils): quote kill_process args, replace subprocess which with shutil
- 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
2026-07-18 14:13:11 +05:45
sankalp ef685ab34a fix(globalmenu): remove shell=True from gcc compilation command
Use list form with shlex.split() for pkg-config flags instead of
shell=True string interpolation. Eliminates command injection vector.
2026-07-18 14:13:03 +05:45
sankalp 80c7af79db fix(network): add missing get_connectivity() call and widen NM import guard
- 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
2026-07-18 14:12:56 +05:45
sankalp 476ed7e4fb fix(workspace): replace broken _config_handlers import with off_config_change
Same silent ImportError leak as panel/main.py — callbacks were never
unregistered on widget destroy.
2026-07-18 14:12:44 +05:45
sankalp 6ef48af963 fix(panel): replace broken _config_handlers import with off_config_change
Panel destroy was importing nonexistent _config_handlers from config,
causing silent ImportError and leaked reload callbacks.
2026-07-18 14:12:37 +05:45
sankalp c47009addd fix(config): add unregister_reload_callback and harden singleton init
- 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
2026-07-18 14:12:26 +05:45
sankalp 5e542eed4f style: replace raw colors.css refs with glass tokens from constant.css
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.
2026-07-17 22:28:10 +05:45
sankalp aeccbe3089 fix(osd): show OSD at 100% via fabric-cli exec from keybinds
- 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
2026-07-17 12:24:34 +05:45
sankalp 4f36ada1c5 fix(controlcenter): flush stale-cache races in toggle UI
- 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
2026-07-17 11:23:42 +05:45
sankalp 14c00c4504 refactor(window/switcher): make item box height adapt automatically 2026-07-16 17:54:34 +05:45
sankalp 5708a475dd chore: remove commitlint configuration 2026-07-16 17:47:37 +05:45
sankalp de0f5f1d07 chore: remove dependency audit workflow 2026-07-16 17:45:19 +05:45
sankalp 0ef2a036dd chore(.github/workflows): add system dependencies for pycairo
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.
2026-07-16 17:43:12 +05:45
sankalp 700b29a465 fix(/.github/workflows): correct inputs parameter for dependency audit action 2026-07-16 17:41:02 +05:45
sankalp 619db0e512 refactor(config/hypr): change keybinding for locking screen from Ctrl+L to Super+L 2026-07-16 17:39:33 +05:45
sankalp a383c484b6 chore: add commitlint.config.js 2026-07-16 17:39:14 +05:45
sankalp d1866cc699 chore(.github/workflows): add CI workflows for commit lint, dependency audit, and install script testing 2026-07-16 17:38:53 +05:45
sankalp 6e9cb8efc8 refactor(src/window/spotlight/plugins): improve emoji annotation download using curl for better error handling 2026-07-16 17:27:52 +05:45
sankalp e3b8ae0c45 refactor(services): simplify GoogleLens upload implementation using curl 2026-07-16 17:10:50 +05:45
sankalp 41cb9afa07 fix(src/window/notification): stop polling when revealer is closing/destroyed
The callback may execute after _on_notification_finished has fired, causing errors.
2026-07-16 12:13:19 +05:45
sankalp 83af1829c4 refactor(src/window/dock/canvas): reorganize client lookup and tooltip generation to prevent stale references 2026-07-16 12:13:01 +05:45
sankalp e840917621 fix(src/window/controlcenter): add guard for destroyed state and adjust return value 2026-07-16 12:12:43 +05:45
sankalp 843c33786f fix(src/services): handle race condition in artwork generation and daemon cleanup 2026-07-16 12:12:15 +05:45
sankalp 19046cd1ee feat(optional): add libmediaart to PACKAGES 2026-07-16 12:11:57 +05:45
sankalp 1c119535d5 chore(config/hypr): correct uv command to run python script 2026-07-16 12:04:22 +05:45
sankalp a47abda55a fix: resolve wifi crashes, shell injections, race conditions, and add debug mode
- Remove transient NEED_AUTH/DISCONNECTED error paths from wifi connect
- Guard double-callback in connect_wifi_bssid/connect_wifi_with_password
- Shell-quote user paths in wallpaper, screenshot, screenrecorder services
- Fix OSD hide-timer use-after-free and applet_window stale source ID
- Fix brightness poll timer leak on read failure
- Fix spotlight search stale idle source removal
- Lock dbusmenu _cache mutation under _registry_lock
- Fix entry.revision written outside _registry_lock scope
- Add fabric-cli exec wrapper for lock screen (lock_screen.lock())
- Replace hyprlock with lock screen in power menu and dropdown
- Add debug mode toggle in settings (controls log verbosity)
- Add diagnostic logging to globalmenu click chain
2026-07-16 11:47:53 +05:45
sankalp 4378959131 fix(controlcenter): refresh player state on resume
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.
2026-07-15 21:22:51 +05:45
sankalp 42ede60800 refactor: drop unused SettingsRow definitions from SettingsWindow
Removed three SettingsRow widgets that were no longer needed, cleaning up the UI configuration.
2026-07-15 19:37:22 +05:45
sankalp 6442161f40 refactor(src/window/globalmenu): simplify caching logic and remove dynamic menu method selection 2026-07-15 19:37:02 +05:45
sankalp 11603990ee refactor(src/utils): remove unused global_menu_method and global_menu_cache_enabled from constants.py 2026-07-15 19:36:44 +05:45
sankalp 016d18090d refactor(src/window/spotlight/plugins): increase timeout interval to 50ms for clipboard and emoji paste actions 2026-07-15 11:30:46 +05:45
sankalp e6c471a9f8 fix(src/window/spotlight): add error handling around action invocation
Prevent crashes when result.action() raises exceptions and log warnings.
2026-07-15 11:30:23 +05:45
sankalp 211a428cca feat(src/utils): replace clipboard implementation with wl-copy and enhance copy_image support 2026-07-15 11:30:01 +05:45
sankalp 2c9a050bbb fix(spotlight): run immediate search on Enter when debounced results empty
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.
2026-07-15 10:52:44 +05:45
sankalp 4503130be3 fix(spotlight): activate first result before on_submit in entry accept
_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.
2026-07-15 10:49:43 +05:45
sankalp 9eb62d7ea3 feat(config): wire up wallpapers_dir, osd, window_switcher, global_menu settings
- 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
2026-07-15 10:31:28 +05:45
sankalp e63a2c04a5 refactor: extract reusable utils, remove screencapture facade
- Add ManagedTimer to replace repeated source_remove/timeout_add boilerplate
- Add EvdevLockService base class for numlock/capslock (cut 154→28 lines)
- Add BaseNotchIndicator for 5 near-identical indicator classes (cut 404→171 lines)
- Add load_pixbuf_thumbnail and resolve_monitor to utils
- Delete screencapture.py facade; callers use Screenshot/ScreenRecorder directly
2026-07-15 10:01:40 +05:45
sankalp ebe1238b3d feat(src/window/spotlight/plugins): implement is_active detection and notification handling for caffeine plugin
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.
2026-07-15 09:04:00 +05:45
sankalp cdccb9e726 feat(src/window/controlcenter): implement caffeine inhibitor toggling
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.
2026-07-15 09:03:39 +05:45
sankalp cda8f55109 feat!: rename inhibit_changed to inhibit-changed and add enable_timed method 2026-07-15 09:03:08 +05:45
sankalp ddacdea3eb refactor(src/window/controlcenter): replace svg_file imports with Image and simplify battery icon handling 2026-07-14 23:26:21 +05:45
sankalp f2517ee9f3 feat(src/window/notification): add action buttons creation and improve UI alignment 2026-07-14 23:11:19 +05:45
sankalp e4e1d3a291 style(src/styles/notification): adjust mac- CSS for notification UI 2026-07-14 23:11:02 +05:45
sankalp e7c49d7dda refactor(src/window/notification): simplify hover handling and close‑button styling for notifications 2026-07-14 22:46:18 +05:45
sankalp 5dd3abb3b4 style(src/styles/notification): refine notification button styling and hover behavior 2026-07-14 22:45:55 +05:45
sankalp 4df8b93e6c fix(src/window/panel/components/globalmenu): correct active window detection to exclude Modus 2026-07-14 22:00:10 +05:45
sankalp 5668c5153e feat(src/utils): rename default app name from Finder to Modus
build(release): bump version to 2.0.0
2026-07-14 21:59:52 +05:45
sankalp 3d355482c6 refactor(src/services): replace default active app name from "Finder" to "Modus"
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.
2026-07-14 21:59:34 +05:45
sankalp 04ac938dd2 refactor(src/window/dock): replace manual drawing of shadows, borders, and backgrounds with Gtk.render_background and Gtk.render_frame 2026-07-14 21:58:35 +05:45
sankalp 3ace1a1bd2 style(src/styles/window): add .dock-background styling 2026-07-14 21:58:16 +05:45
sankalp 59e9c8498e style(src/styles/window): migrate to glass color variables 2026-07-14 21:43:39 +05:45
sankalp 9f192cdc56 refactor(styles/widgets): update CSS color variables to use glass theming 2026-07-14 21:43:22 +05:45
sankalp ef7b200c74 style(src/styles/notification): switch notification background colors to glass tokens 2026-07-14 21:43:04 +05:45
sankalp 21e8a3e7da chore(src/styles): migrate to glass surface color tokens
Remove legacy color definition blocks and replace with new glass-surface, glass-panel, and interactive state tokens. Update all component styles to reference new variables.
2026-07-14 21:42:46 +05:45
sankalp 50640d33aa refactor(config/hypr): remove noise setting and enable ignore_opacity 2026-07-14 21:42:28 +05:45
sankalp 6a5287d039 feat(config): enhance hypridle lock command and modus visual settings 2026-07-14 18:46:18 +05:45
sankalp 6f2d0bf444 chore: refactor imports and adopt new utils utilities 2026-07-14 18:45:52 +05:45
sankalp b2114f52b1 refactor: migrate globalmenu implementation to src/window/globalmenu and adjust documentation paths 2026-07-14 18:45:35 +05:45
sankalp a782d30f15 refactor: reorganize globalmenu into src/window 2026-07-14 18:45:14 +05:45
sankalp 22b239f33c chore: update labeler.yml to correct glob pattern for globalmenu files 2026-07-14 18:44:57 +05:45
sankalp 0496100788 feat(spotlight): add Caffeine plugin to inhibit idle/sleep
Uses systemd-inhibit with a pinned sleep process and PID file so
the inhibition survives Spotlight dismiss. Supports on/off and
duration presets (5m/15m/30m/1h) plus free-form parsing.
2026-07-14 13:47:58 +05:45
sankalp 2d22df94ca refactor: drive UI from service signals, drop redundant polling
- bluetooth.py / wifi.py: remove 5s periodic refresh timers; rely on
  service `changed`/`device-added`/`device-removed`/`notify` signals
- expanded_player.py: remove 500ms metadata poll; rely on
  `meta-change`/`artwork-change` signals
- player.py (notch): connect previously dangling `artwork-change` handler
- popup_win.py: silence harmless "nothing connected" warning on destroy()

No behaviour change; eliminates dead timers and log spam.
2026-07-14 13:46:21 +05:45
sankalp 9ff5ebc95c refactor(spotlight): replace raw socket IPC with Fabric Service over DBus
SpotlightWindow now exposed via SpotlightService (fabric Service) on the
session bus (dev.modus.Spotlight /Toggle). On-demand process forwards to
the running instance over DBus instead of a unix socket; still quits on
dismiss. Behaviour unchanged.
2026-07-14 13:02:26 +05:45
sankalp f72542a231 refactor: log swallowed exceptions across src/
Replace silent swallow-excepts (pass/return/continue) with
logger.warning recording the caught error, preserving behaviour.
2026-07-14 13:02:21 +05:45
sankalp c0a4b1b792 refactor(src/window/dock): improve desktop file search matching logic
Check exact desktop file name first and enhance matching algorithm to prioritize exact matches, compute relevance scores, and return the best match.
2026-07-14 02:36:20 +05:45