How mdgaziur/findex works
1. Workspace shape
- This is a Rust workspace with three core crates:
- findex: the actual launcher application.
- findex-daemon: a small helper process for external triggering.
- findex-plugin: the ABI/support crate used by dynamically loaded plugins.
- The rest of the repo is packaging, samples, and deployment glue.
2. Primary runtime: findex
- crates/findex/src/main.rs is the main executable entry point.
- It is a GTK3 desktop app for Linux that opens a launcher window, reads user input, computes results, and executes the chosen target.
- The app is split into smaller UI modules under src/gui/, which keeps the launcher shell, search input, result list, and dialog behavior separate.
3. UI composition
- The launcher UI is built from a small set of GTK widgets:
- search box (searchbox.rs)
- scrollable results list (result_list.rs, result_list_row.rs)
- dialog/window chrome (dialog.rs)
- The README’s CSS class table matches these widget boundaries, so styling is a first-class part of the UI architecture rather than an afterthought.
4. Search and result data flow
- User input flows from the search box into the launcher logic.
- Results are assembled from multiple sources:
- local application entries via app_list.rs
- plugin-provided results via the plugin subsystem
- The result list is then rendered in the GTK list view, and selection/keyboard shortcuts are used to launch the chosen result.
5. Application discovery
- app_list.rs suggests the launcher maintains a catalog of installed desktop applications, likely from standard Linux application metadata.
- This forms the built-in search corpus, separate from plugin results.
- The app list is one of the main data sources feeding the ranking/filtering path.
6. Configuration and theming boundary
- config.rs handles runtime behavior settings, loaded from user config.
- Behavior is driven by ~/.config/findex/settings.toml, while visuals come from style.css.
- The repo also includes a bundled default stylesheet under css/style.css, which is copied into the install location and can be overridden by the user.
7. Activation and daemon boundary
- findex-daemon is a separate process whose role is to make the launcher triggerable externally, especially in environments where global hotkeys are limited.
- The README shows a toggle_file-based control path under ~/.config/findex/, so the daemon acts as a bridge between external events and the GUI launcher.
- On X11 the app can bind keys directly; on Wayland the daemon/file-trigger path becomes the workaround.
8. Plugin architecture
- findex-plugin defines the stable plugin interface and result types used across dynamic library boundaries.
- It uses an ABI-stability layer (abi_stable) so plugins can be compiled separately and loaded as .so files.
- The plugin contract is simple: initialize with config, then handle a query and return a list of results.
9. Plugin ecosystem
- The plugins/ directory contains example plugins such as cmd, github-repo, math, and urlopen.
- These are separate crates, built as shared libraries, and illustrate how the launcher is extended without changing the main binary.
- Plugins can be invoked by prefix and optionally by custom keyboard shortcut, which inserts the prefix into the search box.
10. Packaging and deployment
- installer.sh, service/findex-daemon.service, and the README’s installation notes show that deployment is part of the repo’s architecture.
- The daemon is intended to run as a user service or autostart process.
- Logs are written to ${XDG_CACHE_HOME}/findex-logs, which is the main operational boundary for debugging.
11. Net effect
- The architecture is: GTK launcher UI at the center, local app search as the default corpus, plugins as extensible result providers, and a small daemon as the external trigger path.
- Styling and behavior are both user-configurable through files, while the plugin interface is isolated behind a dedicated ABI crate.
Main entry points: result_list.rs Result list · lib.rs Plugin API · main.rs Launcher · mod.rs GUI core
Components 18
Core runtime
Launcher app, UI, configuration, and built-in app discovery.
- Launcher · Main desktop launcher executable entry point.
crates/findex/src/main.rs - GUI core · Top-level UI module wiring the launcher shell.
crates/findex/src/gui/mod.rs - Search box · User query entry and prefix insertion.
crates/findex/src/gui/searchbox.rs - Result list · Scrollable list that renders and updates matches.
crates/findex/src/gui/result_list.rs - Result row · Single selectable result item for the list.
crates/findex/src/gui/result_list_row.rs - Dialog chrome · Launcher window/dialog behavior and key handling.
crates/findex/src/gui/dialog.rs - Styling · GTK styling integration for bundled and user CSS.
crates/findex/src/gui/css.rs - Config · Runtime settings loaded from user configuration.
crates/findex/src/config.rs - App catalog · Built-in catalog of installed desktop applications.
crates/findex/src/app_list.rs
Plugins
Stable plugin ABI plus example dynamic plugins.
- Plugin API · Stable plugin interface and shared result types.
crates/findex-plugin/src/lib.rs - ABI internals · Internal ABI-stable definitions shared across plugin boundaries.
crates/findex-plugin/src/findex_internal.rs - Cmd plugin · Example plugin for command execution.
plugins/cmd/src/lib.rs - GitHub plugin · Example plugin for repository search actions.
plugins/github-repo/src/lib.rs - Math plugin · Example plugin for calculator-style queries.
plugins/math/src/lib.rs - URL open · Example plugin for opening URLs.
plugins/urlopen/src/lib.rs
Packaging
Daemon, service unit, installer, and repo glue.
- Daemon · External trigger bridge for showing or hiding the launcher.
crates/findex-daemon/src/main.rs - Installer · Packaging and installation helper script.
installer.sh - Service unit · User-service definition for the daemon.
service/findex-daemon.service
Connections 22
- Launcher → GUI core: boots UI · Main binary initializes the launcher UI stack.
- Launcher → Config: loads · Reads runtime behavior settings at startup.
- Launcher → App catalog: indexes apps · Builds the default search corpus from installed applications.
- Launcher → Plugin API: loads plugins · Uses the plugin ABI to discover and invoke extensions.
- GUI core → Search box: composes · Wires the query entry into the launcher shell.
- GUI core → Result list: composes · Includes the scrolling results surface.
- GUI core → Dialog chrome: composes · Owns the launcher window/dialog behavior.
- Result list → Result row: renders · Displays each match as an individual selectable row.
- Search box → Result list: drives · Query changes update the results shown to the user.
- App catalog → Result list: feeds · Built-in app entries become searchable results.
- Plugin API → ABI internals: defines ABI · Stable boundary types are encoded through ABI-safe internals.
- Plugin API → Cmd plugin: implements · Example plugin built against the shared interface.
- Plugin API → GitHub plugin: implements · Example plugin built against the shared interface.
- Plugin API → Math plugin: implements · Example plugin built against the shared interface.
- Plugin API → URL open: implements · Example plugin built against the shared interface.
- Cmd plugin → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- GitHub plugin → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- Math plugin → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- URL open → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- Daemon → Dialog chrome: triggers · External events toggle or raise the launcher window.
- Installer → Service unit: installs · Deployment script includes daemon service setup.
- Installer → Daemon: deploys · Installer provisions the helper process.