From 78f5341a6817148476ac0d4274d1efdc49f6a961 Mon Sep 17 00:00:00 2001 From: Tw93 Date: Sat, 15 Nov 2025 12:28:34 +0800 Subject: [PATCH] Optimize the key usage experience --- bin/clean.sh | 28 +++++++++++++--------------- bin/optimize.sh | 1 + bin/touchid.sh | 2 ++ lib/common.sh | 9 ++++++--- lib/menu_paginated.sh | 15 --------------- lib/uninstall_batch.sh | 1 + mole | 3 ++- 7 files changed, 25 insertions(+), 34 deletions(-) diff --git a/bin/clean.sh b/bin/clean.sh index 4843157..634509b 100755 --- a/bin/clean.sh +++ b/bin/clean.sh @@ -460,25 +460,25 @@ start_cleanup() { if [[ -t 0 ]]; then echo "" - echo -ne "${PURPLE}${ICON_ARROW}${NC} System caches need sudo — ${GREEN}Enter${NC} continue, other key skip: " + echo -ne "${PURPLE}${ICON_ARROW}${NC} System caches need sudo — ${GREEN}Enter${NC} continue, ${GRAY}Space${NC} skip: " - # Use IFS= and read without -n to allow Ctrl+C to work properly - IFS= read -r -s -n 1 choice - local read_status=$? + # Use read_key to properly handle all key inputs + local choice + choice=$(read_key) - # If read was interrupted (Ctrl+C), exit cleanly - if [[ $read_status -ne 0 ]]; then - echo "" - exit 130 - fi - - if [[ "$choice" == $'\e' ]]; then + # Check for cancel (ESC or Q) + if [[ "$choice" == "QUIT" ]]; then echo -e " ${GRAY}Cancelled${NC}" exit 0 fi + # Space = skip + if [[ "$choice" == "SPACE" ]]; then + echo -e " ${GRAY}Skipped${NC}" + echo "" + SYSTEM_CLEAN=false # Enter = yes, do system cleanup - if [[ -z "$choice" ]] || [[ "$choice" == $'\n' ]]; then + elif [[ "$choice" == "ENTER" ]]; then printf "\r\033[K" # Clear the prompt line if request_sudo_access "System cleanup requires admin access"; then SYSTEM_CLEAN=true @@ -514,10 +514,8 @@ start_cleanup() { echo -e "${YELLOW}Authentication failed${NC}, continuing with user-level cleanup" fi else - # ESC or other key = no system cleanup + # Other keys (including arrow keys) = skip, no message needed SYSTEM_CLEAN=false - echo "" - echo -e "${GRAY}Skipped system cleanup, user-level only${NC}" fi else SYSTEM_CLEAN=false diff --git a/bin/optimize.sh b/bin/optimize.sh index 28bcebf..8ab1298 100755 --- a/bin/optimize.sh +++ b/bin/optimize.sh @@ -503,6 +503,7 @@ main() { echo -ne "${PURPLE}${ICON_ARROW}${NC} System optimizations need admin access — ${GREEN}Enter${NC} Touch ID/password, ${GRAY}ESC${NC} cancel: " IFS= read -r -s -n1 key || key="" + drain_pending_input # Clean up any escape sequence remnants case "$key" in $'\e' | q | Q) echo "" diff --git a/bin/touchid.sh b/bin/touchid.sh index 9fd045a..245247e 100755 --- a/bin/touchid.sh +++ b/bin/touchid.sh @@ -144,6 +144,7 @@ show_menu() { if is_touchid_configured; then echo -ne "${PURPLE}☛${NC} Press ${GREEN}Enter${NC} to disable, ${GRAY}Q${NC} to quit: " IFS= read -r -s -n1 key || key="" + drain_pending_input # Clean up any escape sequence remnants echo "" case "$key" in @@ -162,6 +163,7 @@ show_menu() { else echo -ne "${PURPLE}☛${NC} Press ${GREEN}Enter${NC} to enable, ${GRAY}Q${NC} to quit: " IFS= read -r -s -n1 key || key="" + drain_pending_input # Clean up any escape sequence remnants case "$key" in $'\e') # ESC diff --git a/lib/common.sh b/lib/common.sh index 853bfd6..fe5131e 100755 --- a/lib/common.sh +++ b/lib/common.sh @@ -289,6 +289,7 @@ read_key() { $'\n' | $'\r') echo "ENTER" ;; ' ') echo "SPACE" ;; 'q' | 'Q') echo "QUIT" ;; + 'h' | 'H') echo "HELP" ;; 'R') echo "RETRY" ;; 'o' | 'O') echo "OPEN" ;; '/') echo "FILTER" ;; # Trigger filter mode @@ -368,13 +369,13 @@ drain_pending_input() { # Mouse wheel scrolling can generate rapid sequences like B^[OB^[OB^[O... while IFS= read -r -s -n 1 -t 0.01 _ 2> /dev/null; do ((drained++)) - # Higher safety limit for mouse wheel sequences - [[ $drained -gt 1000 ]] && break + # Safety limit for mouse wheel sequences + [[ $drained -gt 200 ]] && break done # Second pass with even shorter timeout to catch any remaining input while IFS= read -r -s -n 1 -t 0.001 _ 2> /dev/null; do ((drained++)) - [[ $drained -gt 1500 ]] && break + [[ $drained -gt 500 ]] && break done } @@ -868,6 +869,7 @@ prompt_action() { echo "" echo -ne "${PURPLE}${ICON_ARROW}${NC} Press ${GREEN}Enter${NC} to ${action}, ${GRAY}ESC${NC} to ${cancel}: " IFS= read -r -s -n1 key || key="" + drain_pending_input # Clean up any escape sequence remnants case "$key" in $'\e') # ESC @@ -891,6 +893,7 @@ confirm_prompt() { local message="$1" echo -n "$message (Enter=OK / ESC q=Cancel): " IFS= read -r -s -n1 _key || _key="" + drain_pending_input # Clean up any escape sequence remnants case "$_key" in $'\e' | q | Q) echo "" diff --git a/lib/menu_paginated.sh b/lib/menu_paginated.sh index 4330aed..9414b2e 100755 --- a/lib/menu_paginated.sh +++ b/lib/menu_paginated.sh @@ -27,21 +27,6 @@ _pm_parse_csv_to_array() { done } -# Non-blocking input drain (bash 3.2) - improved for mouse wheel -drain_pending_input() { - local _k drained=0 - # Multiple passes to handle mouse wheel burst sequences - while IFS= read -r -s -n 1 -t 0.01 _k 2> /dev/null; do - ((drained++)) - [[ $drained -gt 1000 ]] && break - done - # Second pass with shorter timeout - while IFS= read -r -s -n 1 -t 0.001 _k 2> /dev/null; do - ((drained++)) - [[ $drained -gt 1500 ]] && break - done -} - # Main paginated multi-select menu function paginated_multi_select() { local title="$1" diff --git a/lib/uninstall_batch.sh b/lib/uninstall_batch.sh index f3e62e5..aa729d2 100755 --- a/lib/uninstall_batch.sh +++ b/lib/uninstall_batch.sh @@ -137,6 +137,7 @@ batch_uninstall_applications() { echo -ne "${PURPLE}${ICON_ARROW}${NC} ${removal_note}. Press ${GREEN}Enter${NC} to confirm, ${GRAY}ESC${NC} to cancel: " IFS= read -r -s -n1 key || key="" + drain_pending_input # Clean up any escape sequence remnants case "$key" in $'\e' | q | Q) echo "" diff --git a/mole b/mole index 36c8ad1..a636bde 100755 --- a/mole +++ b/mole @@ -343,6 +343,7 @@ remove_mole() { # Read single key IFS= read -r -s -n1 key || key="" + drain_pending_input # Clean up any escape sequence remnants case "$key" in $'\e') echo -e "${GRAY}Cancelled${NC}" @@ -531,7 +532,7 @@ interactive_main_menu() { 4) exec "$SCRIPT_DIR/bin/analyze.sh" ;; esac ;; - "h" | "H") + "HELP") show_cursor clear show_help