#!/bin/sh # Show regular .desktop applications plus executable files in ~/bin. # .desktop entries are launched with gtk-launch. # ~/bin entries are executed directly, so their shebang is respected. APP_DIRS="/usr/share/applications $HOME/.local/share/applications" BIN_DIR="$HOME/bin" entries=$( for dir in $APP_DIRS; do [ -d "$dir" ] || continue find "$dir" -type f -name '*.desktop' 2>/dev/null | while IFS= read -r file; do name=$(awk -F= '/^Name=/ { print $2; exit }' "$file") type=$(awk -F= '/^Type=/ { print $2; exit }' "$file") nodisplay=$(awk -F= '/^NoDisplay=/ { print $2; exit }' "$file") hidden=$(awk -F= '/^Hidden=/ { print $2; exit }' "$file") [ -n "$name" ] || continue [ -z "$type" ] || [ "$type" = "Application" ] || continue [ "$nodisplay" = "true" ] && continue [ "$hidden" = "true" ] && continue id=$(basename "$file" .desktop) printf '%s [desktop]\tdesktop\t%s\n' "$name" "$id" done done if [ -d "$BIN_DIR" ]; then find "$BIN_DIR" -maxdepth 1 -type f -perm /111 2>/dev/null | while IFS= read -r file; do name=$(basename "$file") printf '%s [bin]\tbin\t%s\n' "$name" "$file" done fi ) choice=$(printf '%s\n' "$entries" | sort -f | wmenu -l 20) [ -n "$choice" ] || exit 0 kind=$(printf '%s' "$choice" | cut -f2) target=$(printf '%s' "$choice" | cut -f3-) case "$kind" in desktop) gtk-launch "$target" >/dev/null 2>&1 & ;; bin) "$target" >/dev/null 2>&1 & ;; esac