How coffee7cup/app-drawer-rs works
1. What this repo is
- This is a Rust-based Wayland layer-shell launcher/dock for the Niri compositor.
- It has two primary modes in the UI: an app launcher dock and a window switcher / active-app dock.
2. Top-level runtime flow
- src/main.rs is the entrypoint and likely wires together configuration, app discovery, Niri state, and the GUI event loop.
- The program runs locally on the Wayland session; there is no backend service. Its “backend” is the compositor and the local desktop-entry filesystem.
3. GUI / presentation layer
- src/app_launcher.rs is the core presentation and interaction module.
- It likely owns the layer-shell surface, rendering, animations, hover/enter behavior, scrolling behavior, and the switch between launcher vs active-app views.
- The README indicates dynamic surface sizing and reactive padding are used to create the dock-like motion and the “pop up” effect.
4. App discovery subsystem
- src/apps.rs is the app catalog layer.
- It scans desktop entries from /usr/share/applications and ~/.local/share/applications, resolves metadata, and loads icons from sources like linicons and freedesktop_icons.
- This is the source of the launcher’s searchable app list and icon model.
5. Launching apps
- src/init_app.rs appears to encapsulate the launch action for a selected app.
- The actual spawn path goes through Niri IPC using Action::SpawnSh, so launching is delegated to the compositor rather than shelling out directly from UI code.
- This keeps launch behavior tied to the Niri session and its command execution model.
6. Active windows / switcher subsystem
- src/current_apps.rs likely queries the compositor for current windows and maps them into launcher-friendly items.
- The README says it uses niri_ipc::Request::Windows to fetch active apps, so this module is the bridge from compositor window state into the UI list.
7. Focus and workspace logic
- src/workspaces.rs probably organizes windows by workspace and/or determines which workspace should receive focus when an item is selected.
- Focus behavior is implemented via Niri IPC using Request::FocusWindow(id).
- This is the boundary where the app switches from passive browsing to compositor control.
8. Caching and ranking
- src/config.rs and the cache-related behavior described in the README suggest a local persistence layer for frequently used apps.
- The app list is not just static enumeration; it is reordered so commonly used apps stay prominent, which affects the launcher’s first-screen ranking.
- This is a local optimization path, not a networked or shared cache.
9. Error handling and startup orchestration
- src/error.rs provides a project-wide error type for failures across filesystem scanning, icon loading, IPC calls, and UI setup.
- src/init_app.rs and src/config.rs likely work together during startup to build the initial model before the GUI renders.
10. Assets and presentation resources
- assets/ contains demo media and likely icon or visual resources used by the app.
- These are not part of the runtime logic, but they support the visual identity of the launcher and documentation.
11. Main external dependencies that shape architecture
- Wayland + layer-shell: defines the app as an overlay-like surface rather than a normal window.
- guido: the GUI framework used for rendering, interaction, and dynamic list behavior.
- niri_ipc: the control plane for window queries, focus changes, and app spawning.
- freedesktop desktop entries / icon themes: the source of app metadata and visuals.
12. Overall data flow to diagram
- Desktop entries and icon metadata are read from the filesystem, normalized into app records, optionally ranked by cache/frequency, then rendered in the layer-shell UI.
- User selection flows back through Niri IPC to either spawn an app or focus an existing window.
- The active-window path is separate from the app-discovery path but reuses the same icon/app model to keep the UI consistent.
13. Useful architectural boundary to draw
- A clean diagram would show three layers: desktop data sources + Niri IPC, Rust domain modules (apps, current_apps, workspaces, config), and the GUI surface (app_launcher).
- The key integration points are the filesystem scan, the cache/ranking step, and the two compositor actions: spawn and focus.
Main entry points: app_launcher.rs App launcher · apps.rs Apps · main.rs Main · current_apps.rs Current apps
Components 14
Runtime
Entry point and user-facing Wayland layer-shell UI.
- Main · Starts the app and wires the runtime.
src/main.rs - App launcher · Layer-shell surface, interaction, and view switching.
src/app_launcher.rs
Domain
App catalog, window state, ranking, and selection logic.
- Apps · Discovers desktop apps and icons.
src/apps.rs - Current apps · Reads compositor window state into launcher items.
src/current_apps.rs - Workspaces · Groups windows and resolves workspace focus behavior.
src/workspaces.rs - Config · Stores local preferences and ranking state.
src/config.rs - Init app · Turns a selection into a compositor spawn request.
src/init_app.rs - Errors · Shared repository error type.
src/error.rs
System
Filesystem, compositor IPC, and visual assets that feed the app.
- Desktop entries · System and user application metadata.
- Icons · Freedesktop and local icon lookup sources.
- Niri IPC · Queries windows and sends spawn or focus actions.
- Layer shell · Wayland overlay surface used for dock-like presentation.
- GUI framework · Rendering and interaction framework for the surface.
- Assets · Visual assets and demo media.
assets
Connections 23
- Main → App launcher: starts · Main initializes the launcher runtime and enters the UI loop.
- Main → Apps: loads · Startup builds the initial app model from the catalog.
- Main → Current apps: loads · Startup reads current compositor windows for active-app mode.
- Main → Config: reads · Startup loads local settings and ranking state.
- Main → Errors: uses · Entry path propagates setup and runtime failures.
- App launcher → GUI framework: renders · Presentation and interaction are driven by the GUI framework.
- App launcher → Layer shell: hosts on · The UI is presented as a layer-shell surface.
- App launcher → Apps: shows · Launcher view consumes the discovered app catalog.
- App launcher → Current apps: shows · Switcher view consumes current window items.
- App launcher → Workspaces: routes focus · Selection can be routed by workspace or window grouping.
- App launcher → Init app: launches · User selection can trigger app launch actions.
- App launcher → Config: applies · Uses configuration and ranking data for behavior and ordering.
- App launcher → Assets: uses · Visual assets support presentation and documentation.
- Apps → Desktop entries: scans · Reads system and user desktop-entry files.
- Apps → Icons: resolves · Maps apps to icons from theme sources.
- Apps → Config: ranks · Uses local preference/cache data to reorder apps.
- Apps → Errors: fails with · Catalog building can surface filesystem and icon errors.
- Current apps → Niri IPC: queries · Fetches active windows from the compositor.
- Current apps → Workspaces: organizes · Window state is organized into workspace-aware items.
- Current apps → Errors: fails with · IPC or mapping errors propagate through the shared error type.
- Workspaces → Niri IPC: focuses · Workspace selection can emit focus-window requests.
- Init app → Niri IPC: spawns · Launches the selected app through compositor execution.
- Config → Errors: fails with · Settings and cache I/O errors use the shared error type.