Files
pikl/docs/use-cases/app-launcher.md

3.9 KiB

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

# 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.

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:

# Hypothetical helper that emits JSON items
desktop-entries --json \
  | pikl --mode gui \
    --format '{icon} {label} <dim>{sublabel}</dim>'

Input would look like:

{"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:

# 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?