Commit Graph

182 Commits

Author SHA1 Message Date
5196255594 chore(aur): update owlry 1.0.4, owlry-core 1.1.2 2026-03-28 11:19:05 +01:00
b87447156e chore(owlry-core): bump version to 1.1.2 owlry-core-v1.1.2 owlry-v1.0.4 2026-03-28 11:18:27 +01:00
12d554959a chore(owlry): bump version to 1.0.4 2026-03-28 11:18:26 +01:00
83fa22d84c feat(ui): add result highlighting and remove window shadow
Highlighting:
- Dynamic plugin results (calculator, converter, websearch, filesearch)
  get a subtle accent left-border + background tint when auto-detected
- Exact name matches (case-insensitive) are highlighted the same way
- Exact match on apps gets a higher score boost (50k) than other
  providers (30k), so apps rank first when names match exactly

Shadow:
- Removed hardcoded box-shadow from all theme CSS files
- Added --owlry-shadow variable in base.css (defaults to none)
- Themes can opt into shadow via --owlry-shadow if desired

CSS class: .owlry-result-highlight on ResultRow
2026-03-28 11:17:45 +01:00
ade5d3aeef fix(ui): check icon theme exists on disk before fallback
has_icon() returns true even for broken themes since it checks all
search paths. Instead, verify the theme directory actually exists
in the search path. Falls back to Adwaita only when the configured
theme is genuinely missing from disk.
2026-03-28 11:08:01 +01:00
617c943147 fix: aur-stage glob handling for packages without .install files 2026-03-28 10:51:46 +01:00
1b1e12124b chore(aur): update owlry PKGBUILD to 1.0.3 2026-03-28 10:49:57 +01:00
94556f1fe0 chore(owlry): bump version to 1.0.3 owlry-v1.0.3 2026-03-28 10:48:55 +01:00
2b98f0651c fix(ui): fall back to Adwaita when system icon theme is broken
If the configured icon theme (e.g. Sweet-Blue) doesn't exist on disk,
GTK falls back to hicolor which has almost no icons. Detect this by
probing for a standard icon, and set Adwaita as the theme — it's
guaranteed to exist as a GTK4 dependency.

This replaces the broken add_search_path("/usr/share/icons/Adwaita")
approach which doesn't work because search paths are scoped to the
active theme name, not the directory name.
2026-03-28 10:48:39 +01:00
75fa770c94 chore: overhaul justfile for current deployment pipeline
Key fixes:
- aur-update-pkg uses correct per-crate tag URLs ({crate}-v{version})
- tag-crate creates per-crate tags instead of generic v{version}
- aur-stage handles embedded .git dirs in AUR subdirectories
- aur-commit stages all AUR files with .git workaround
- release-crate does full pipeline: bump → push → tag → AUR update → publish
- Removed stale release-core recipe that used wrong tag format
2026-03-28 10:31:32 +01:00
c6ba91f06d fix(aur): restrict owlry-core check() to unit tests
The integration test (server_test) loads native plugins which segfault
in the clean makepkg build environment. Use --lib to run only unit tests.
2026-03-28 10:06:07 +01:00
235103e854 fix(aur): correct b2sums for owlry and owlry-core tarballs 2026-03-28 09:54:12 +01:00
8ccaaf28c8 docs: update README for client/daemon package split
- Separate package tables for core, plugins, and meta bundles
- Add owlry-plugin-converter to plugin list and meta-essentials
- Fix build instructions: plugins are in owlry-plugins repo
- Update plugin count to 14
- Remove dead link to gitignored CLAUDE.md
2026-03-28 09:51:29 +01:00
cfd143fe4a chore: track AUR package files (PKGBUILD, .SRCINFO)
The aur/ directory was entirely gitignored, preventing PKGBUILD and
.SRCINFO files from being tracked. Fix .gitignore to only ignore
build artifacts and nested .git dirs, matching the owlry-plugins
repo convention.
2026-03-28 09:34:21 +01:00
10a685c62f chore(owlry): bump version to 1.0.2 owlry-core-v1.1.1 owlry-v1.0.2 2026-03-28 09:16:40 +01:00
34db33c75f chore(owlry-core): bump version to 1.1.1 2026-03-28 09:16:38 +01:00
4bff83b5e6 perf(ui): eliminate redundant results.clone() in search handlers
The full results Vec was cloned into lazy_state.all_results and then
separately consumed for current_results. Now we slice for current_results
and move the original into lazy_state, avoiding one full Vec allocation
per query.
2026-03-28 09:14:11 +01:00
8f7501038d perf(ui): move search IPC off the GTK main thread
Search queries in daemon mode now run on a background thread via
DaemonHandle::query_async(). Results are posted back to the main
thread via glib::spawn_future_local + futures_channel::oneshot.
The GTK event loop is never blocked by IPC, eliminating perceived
input lag.

Local mode (dmenu) continues to use synchronous search since it
has no IPC overhead.
2026-03-28 09:12:20 +01:00
4032205800 perf(ui): defer initial query to after window.present()
update_results('') was called inside MainWindow::new(), blocking the
window from appearing until the daemon responded. Move it to a
glib::idle_add_local_once callback scheduled after present() so the
window renders immediately.
2026-03-28 08:51:33 +01:00
99985c7f3b perf(ui): use tracked count in scroll_to_row instead of child walk
scroll_to_row walked all GTK children via first_child/next_sibling
to count rows. The count is already available in LazyLoadState, so
use that directly. Eliminates O(n) widget traversal per arrow key.
2026-03-28 08:48:52 +01:00
6113217f7b perf(core): sample Utc::now() once per search instead of per-item
get_score() called Utc::now() inside calculate_frecency() for every
item in the search loop. Added get_score_at() that accepts a pre-sampled
timestamp. Eliminates hundreds of unnecessary clock_gettime syscalls
per keystroke.
2026-03-28 08:45:21 +01:00
558d415e12 perf(config): replace which subprocesses with in-process PATH scan
detect_terminal() was spawning up to 17 'which' subprocesses sequentially
on every startup. Replace with std::env::split_paths + is_file() check.
Eliminates 200-500ms of fork+exec overhead on cold cache.
2026-03-28 08:40:22 +01:00
6bde1504b1 chore: add .worktrees/ to gitignore 2026-03-28 08:35:51 +01:00
ffe04f3c54 docs: add per-crate tagging convention to CLAUDE.md owlry-core-v1.1.0 owlry-lua-v1.1.0 owlry-rune-v1.1.0 owlry-v1.0.1 plugin-api-v1.0.1 2026-03-26 18:57:09 +01:00
5c0e63f94c chore(owlry-rune): bump version to 1.1.0 2026-03-26 18:51:20 +01:00
5441011d6b chore(owlry-lua): bump version to 1.1.0 2026-03-26 18:51:20 +01:00
317572634f chore(owlry): bump version to 1.0.1 2026-03-26 18:51:12 +01:00
449dc010db chore(owlry-core): bump version to 1.1.0 2026-03-26 18:51:04 +01:00
7273cd3ba7 chore(owlry-plugin-api): bump version to 1.0.1 2026-03-26 18:50:58 +01:00
f8388a4327 docs: update CLAUDE.md with script runtime loading, hot-reload, dynamic prefixes 2026-03-26 18:47:05 +01:00
fa671ebd77 feat: dynamic prefix fallback for user plugin prefixes (e.g. :hs for hyprshutdown) 2026-03-26 18:40:23 +01:00
d63c7d170b fix: build Rune provider registrations from manifest [[providers]] declarations 2026-03-26 18:37:33 +01:00
5f14ed2b3b fix: register Rune Item type under owlry crate path 2026-03-26 18:35:41 +01:00
83f551dd7f fix: use rune::function attribute for Item constructor and builder methods 2026-03-26 18:30:39 +01:00
9b1eada1ee fix: set accept_all when no CLI mode restriction so user plugins appear in default filter 2026-03-26 18:27:50 +01:00
677e6d7fa9 fix: send accept_all filter as None in IPC so runtime plugins appear in results 2026-03-26 18:21:32 +01:00
f0741f4128 fix: store Lua provider callbacks for refresh, fix Rune Item::new parameter types 2026-03-26 18:12:07 +01:00
7da8f3c249 fix: align Lua ProviderInfo ABI, implement Rune Item type and refresh/query 2026-03-26 18:07:46 +01:00
38dda8c44c fix: watcher startup grace period, defensive runtime drop on reload 2026-03-26 17:59:32 +01:00
ab2d3cfe55 feat: add filesystem watcher for automatic user plugin hot-reload
Watch ~/.config/owlry/plugins/ for changes using notify-debouncer-mini
(500ms debounce) and trigger a full runtime reload on file modifications.
Respects OWLRY_SKIP_RUNTIMES=1 to skip watcher in tests.
2026-03-26 17:48:15 +01:00
e2939e266c feat: wire script runtime loading into daemon ProviderManager 2026-03-26 17:44:33 +01:00
651166a9f3 feat: change default entry points to main.lua/main.rn, add entry_point alias 2026-03-26 17:33:54 +01:00
a2eb7d1b0d fix: align runtime ABI — shrink Lua RuntimeInfo, pass owlry_version to init
- Shrink Lua RuntimeInfo from 5 fields to 2 (name, version), matching
  core and Rune. The mismatch caused SIGSEGV across the ABI boundary.
- Add owlry_version parameter to vtable init in all three crates
  (core, Lua, Rune) so runtimes receive the version at init time
  instead of hardcoding it.
- Remove unused Lua constants (RUNTIME_ID, RUNTIME_NAME, etc.) and
  LUA_RUNTIME_API_VERSION.
- Update plugin_commands.rs call sites to pass CARGO_PKG_VERSION.
2026-03-26 17:31:23 +01:00
8073d27df2 docs: update LuaProvider safety comment for RwLock architecture 2026-03-26 16:51:55 +01:00
3349350bf6 fix: robustness — RwLock for concurrent reads, log malformed JSON requests
Replace Mutex with RwLock for ProviderManager and FrecencyStore in the
IPC server. Most request types (Query, Providers, Submenu, PluginAction)
only need read access and can now proceed concurrently. Only Launch
(frecency write) and Refresh (provider write) acquire exclusive locks.

Also adds a warn!() log for malformed JSON requests before sending the
error response, improving observability for debugging client issues.

Provider trait now requires Send + Sync to satisfy RwLock's Sync bound
on the inner type. RuntimeProvider and LuaProvider gain the
corresponding unsafe impl Sync.
2026-03-26 16:39:10 +01:00
3aaeafde8b fix: security — socket perms 0600, signal handler logging, client read timeout 2026-03-26 16:32:06 +01:00
7ce6de17aa fix: soundness — OnceLock for HOST_API, IPC size limits, mutex poisoning recovery 2026-03-26 16:29:47 +01:00
91da177f46 feat: architecture split — client/daemon with independent plugin repo owlry-core-v1.0.0 owlry-lua-v1.0.0 owlry-rune-v1.0.0 owlry-v1.0.0 plugin-api-v1.0.0 2026-03-26 13:40:24 +01:00
f5d83f1372 chore: format, fix clippy warnings, bump all crates to 1.0.0 2026-03-26 13:37:55 +01:00
50caa1ff0d fix(owlry-core): make ProviderFilter dynamically accept all plugin types
Replace hardcoded list of 13 plugin IDs in ProviderFilter::all() with
an accept_all flag. When set, is_active()/is_enabled() return true for
any ProviderType, so dynamically loaded plugins are accepted without
maintaining a static list. Prefix-based filtering still narrows scope
as before, and from_mode_strings() still filters to explicit modes only.
2026-03-26 13:30:51 +01:00