# Use Case: App Launcher A global-hotkey application launcher that replaces Spotlight, Alfred, or rofi's drun mode. Bind a key combo to open pikl as a GUI overlay, fuzzy-filter binaries from PATH, hit Enter to launch. ## What It Looks Like 1. User presses a global hotkey (Super on Linux, Cmd+Space on macOS). 2. pikl opens as a centered overlay. 3. The list is pre-populated with binaries from PATH (or parsed .desktop entries). 4. User types to fuzzy-filter. Frecency sorting puts frequently launched apps at the top. 5. Enter launches the selection. Escape dismisses. This should feel instant. Sub-100ms to first paint. ## How It Works With pikl ### Basic Version ```sh # Collect PATH binaries, open pikl, run selection compgen -c | sort -u \ | pikl --mode gui \ | xargs -I{} sh -c '{} &' ``` ### With tmux Integration On select, create a new tmux session running the chosen binary, then switch to it. Keeps everything inside tmux for window management. ```sh compgen -c | sort -u \ | pikl --mode gui \ --on-select 'cmd=$(cat); tmux new-session -d -s "$cmd" "$cmd" && tmux switch-client -t "$cmd"' ``` ### With .desktop Files Parse XDG .desktop entries for proper app names and icons instead of raw binary names: ```sh # Hypothetical helper that emits JSON items desktop-entries --json \ | pikl --mode gui \ --format '{icon} {label} {sublabel}' ``` Input would look like: ```jsonl {"label": "Firefox", "sublabel": "Web Browser", "meta": {"exec": "firefox", "desktop": "firefox.desktop"}, "icon": "/usr/share/icons/.../firefox.png"} {"label": "Alacritty", "sublabel": "Terminal", "meta": {"exec": "alacritty"}, "icon": "/usr/share/icons/.../alacritty.png"} ``` ### Hyprland / Sway Keybinding ``` bind = SUPER, SPACE, exec, app-launcher.sh ``` On macOS, use skhd or a similar hotkey daemon. ### Fallback: TUI Mode Before the GUI frontend exists, this works today in a drop-down terminal: ```sh # Bind to a hotkey that opens a terminal running: compgen -c | sort -u | pikl | xargs -I{} sh -c '{} &' ``` ## What pikl Features This Exercises | Feature | Phase | How It's Used | |---|---|---| | GUI overlay | 8 | Centered layer-shell popup | | Fuzzy filtering | 2 | Filter thousands of binaries | | Frecency sorting | future | Boost frequently launched apps | | on-select hook | 3 | Spawn or exec the selection | | Structured I/O | 3 | .desktop metadata, icons | | Fast startup | 1 | Must feel instant | | Icon rendering | 8 | App icons in the list | | Groups | 9 | Categories (dev, media, etc) | ## Stretch Goals - **Frecency:** track launch counts per binary, sort by frequency so your top apps float to the top. This is the single biggest UX improvement over a plain sorted list. - **Categories:** group items by type. Dev tools, browsers, media, system. Parsed from .desktop Categories field or manually tagged. - **Recent files:** a second section below apps showing recently opened files. Needs a separate data source (zeitgeist, custom tracker, etc). - **Calculator / snippets:** if the query doesn't match any app, treat it as a math expression or snippet expansion. Scope creep, but it is what makes launchers sticky. ## Platform Notes - **Linux (Wayland):** layer-shell overlay. Global hotkey via the compositor (Hyprland bind, Sway bindsym). This is the primary target. - **Linux (X11):** override-redirect window. Global hotkey via xbindkeys or similar. - **macOS:** no layer-shell. Needs a borderless window with proper focus handling. Global hotkey via skhd or a native Swift shim. Secondary target. ## Open Questions - How to handle apps that need a terminal (e.g. htop, vim). Detect from .desktop Terminal=true and wrap in the user's preferred terminal emulator? - Should the launcher persist as a background process for faster re-open, or cold-start each time? Background process is snappier but uses memory. - PATH scanning: rescan on every open, or cache with inotify/FSEvents on PATH directories?