#!/bin/bash # Compact Flatpak TUI launcher # Get installed apps: use only application ID, then extract readable name readarray -t app_ids < <(flatpak list --app --columns=application 2>/dev/null | tail -n +1 | sort) # Check if flatpak is available if ! command -v flatpak &> /dev/null; then echo "flatpak not found. Please install flatpak." exit 1 fi # Check for installed apps if [ ${#app_ids[@]} -eq 0 ]; then echo "No Flatpak apps installed." exit 0 fi show_menu() { local input="" selection=0 max_display=8 while true; do # Clear screen printf "\033[2J\033[H" # Header echo "+----------------------------------+" echo "| Flatpak App Launcher |" echo "+----------------------------------+" # Search bar if [ -z "$input" ]; then echo "| Search: (type to filter) |" else printf "| Search: %-28s |\n" "$input" fi # Filter apps local filtered=() results_count=0 for app_id in "${app_ids[@]}"; do # Extract a readable name from the app ID (e.g. org.gimp.GIMP -> GIMP) local readable_name="${app_id##*.}" if [[ "${readable_name,,}" == *"${input,,}"* ]] || [[ "${app_id,,}" == *"${input,,}"* ]]; then filtered+=("$app_id") fi done results_count=${#filtered[@]} # Results header if [ $results_count -eq 0 ]; then echo "+----------------------------------+" echo "| No matches. Press ESC to clear. |" else echo "+----------------------------------+" printf "| %d app(s) found |\n" "$results_count" # Calculate display range local start=$selection local end=$((start + max_display)) [ $end -gt $results_count ] && end=$results_count # Show apps (compact list) for i in "${!filtered[@]}"; do if [ $i -ge $start ] && [ $i -lt $end ]; then local app_id="${filtered[i]}" # Extract readable name from app ID (last segment) local app_name="${app_id##*.}" local display_name=$(echo "$app_name" | cut -c1-30) if [ $i -eq $selection ]; then printf "| > %-30s |\n" "$display_name" else printf "| %-30s |\n" "$display_name" fi fi done # Fill empty space while [ $((end - start)) -lt $max_display ]; do echo "| |" end=$((end + 1)) done # Scroll indicator if [ $results_count -gt $max_display ]; then local percent=$((selection * 100 / (results_count - max_display + 1))) printf "| Scroll: %3d%% (%d-%d of %d) |\n" "$percent" "$((start+1))" "$end" "$results_count" fi fi # Footer echo "+----------------------------------+" echo "| Enter:Launch ESC:Quit |" echo "+----------------------------------+" # Handle input local key="" read -rn1 key 2>/dev/null || break case "$key" in "") # Enter - launch if [ $results_count -gt 0 ] && [ $selection -lt $results_count ]; then local app_id="${filtered[selection]}" printf "\033[2J\033[H" echo "Launching ${app_id##*.}..." flatpak run "$app_id" & disown break fi ;; $'\x7f') # Backspace input="${input%?}" selection=0 ;; $'\x1b') # Escape sequence local seq="" read -rn1 -t 0.1 seq 2>/dev/null || { break; } # ESC pressed if [ "$seq" = "[" ]; then read -rn1 -t 0.1 seq 2>/dev/null || continue case "$seq" in "A") # Up [ $selection -gt 0 ] && selection=$((selection-1)) ;; "B") # Down [ $selection -lt $((results_count - 1)) ] && selection=$((selection+1)) ;; esac fi ;; *) # Regular input input+="$key" selection=0 ;; esac done } show_menu