diff --git a/i38.sh b/i38.sh index 87162dc..2aed90f 100755 --- a/i38.sh +++ b/i38.sh @@ -416,6 +416,7 @@ update_scripts() { existingPinHash="$screenlockPinHash" fi cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Updating scripts..." -1 -1 + write_desktop_shortcuts_template if [[ -n "$existingPinHash" ]]; then screenlockPinHash="$existingPinHash" apply_screenlock_pin @@ -423,6 +424,25 @@ update_scripts() { exit 0 } +write_desktop_shortcuts_template() { + local shortcutsFile="${i3Path}/desktop_shortcuts" + + if [[ -f "$shortcutsFile" ]]; then + return 0 + fi + + cat << 'EOF' > "$shortcutsFile" +# I38 desktop quick-launch shortcuts +# Format: Pretty Name|/path/to/application --flags-if-any|optional workspace +# The workspace field is optional. Leave it empty to launch on the current workspace. +# Lines starting with # and blank lines are ignored. +# +# Examples: +# Firefox|/usr/bin/firefox|9 +# Brave|/usr/bin/brave| +EOF +} + write_waytray_config() { # Only create config if waytray binaries are detected if ! command -v waytray-daemon &> /dev/null || ! command -v waytray &> /dev/null ; then @@ -777,6 +797,7 @@ write_waytray_config # Create the i3 configuration directory. mkdir -p "${i3Path}" +write_desktop_shortcuts_template # Move scripts into place cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Moving scripts into place and writing config..." -1 -1 apply_screenlock_pin diff --git a/scripts/desktop.sh b/scripts/desktop.sh index 7febecb..ddd3d59 100755 --- a/scripts/desktop.sh +++ b/scripts/desktop.sh @@ -10,32 +10,141 @@ # You should have received a copy of the GNU General Public License along with I38. If not, see . -# Make sure there is a desktop to search. -if [[ ! -d ~/Desktop ]]; then +trim_whitespace() { + local text="$1" + + text="${text#"${text%%[![:space:]]*}"}" + text="${text%"${text##*[![:space:]]}"}" + printf '%s' "$text" +} + +get_shortcuts_file() { + local configHome="${XDG_CONFIG_HOME:-$HOME/.config}" + local candidatePath= + + if [[ -n "${SWAYSOCK:-}" ]]; then + candidatePath="${configHome}/sway/desktop_shortcuts" + if [[ -r "$candidatePath" ]]; then + printf '%s\n' "$candidatePath" + return 0 + fi + else + candidatePath="${configHome}/i3/desktop_shortcuts" + if [[ -r "$candidatePath" ]]; then + printf '%s\n' "$candidatePath" + return 0 + fi + fi + + candidatePath="${configHome}/i3/desktop_shortcuts" + if [[ -r "$candidatePath" ]]; then + printf '%s\n' "$candidatePath" + return 0 + fi + + candidatePath="${configHome}/sway/desktop_shortcuts" + if [[ -r "$candidatePath" ]]; then + printf '%s\n' "$candidatePath" + return 0 + fi + + return 1 +} + +build_launch_command() { + local shortcutCommand="$1" + local shortcutWorkspace="$2" + local wmCommand= + local workspaceEscaped= + + if [[ -z "$shortcutWorkspace" ]]; then + printf '%s\n' "$shortcutCommand" + return 0 + fi + + if [[ -n "${SWAYSOCK:-}" ]] && command -v swaymsg &> /dev/null; then + wmCommand="swaymsg" + elif [[ -n "${I3SOCK:-}" ]] && command -v i3-msg &> /dev/null; then + wmCommand="i3-msg" + elif [[ -n "${WAYLAND_DISPLAY:-}" ]] && command -v swaymsg &> /dev/null; then + wmCommand="swaymsg" + elif command -v i3-msg &> /dev/null; then + wmCommand="i3-msg" + fi + + if [[ -z "$wmCommand" ]]; then + printf '%s\n' "$shortcutCommand" + return 0 + fi + + if [[ "$shortcutWorkspace" =~ ^[0-9]+$ ]]; then + printf '%s workspace number %s && %s\n' "$wmCommand" "$shortcutWorkspace" "$shortcutCommand" + return 0 + fi + + workspaceEscaped=$(printf '%q' "$shortcutWorkspace") + printf '%s workspace %s && %s\n' "$wmCommand" "$workspaceEscaped" "$shortcutCommand" +} + +desktopPath="${HOME}/Desktop" +if [[ ! -d "$desktopPath" ]]; then exit 0 fi -# Discover directories and files on the desktop -mapfile -t desktopDirs < <(find ~/Desktop -mindepth 1 -maxdepth 1 -type d) -mapfile -t desktopFiles < <(find ~/Desktop -mindepth 1 -maxdepth 1 -type f) +declare -a shortcutMenuList +shortcutsFile="$(get_shortcuts_file)" +if [[ -n "$shortcutsFile" ]]; then + # Optional quick-launch format: + # Pretty Name|command with args|workspace + # Firefox|/usr/bin/firefox|9 + # Brave|/usr/bin/brave| + while IFS= read -r rawLine || [[ -n "$rawLine" ]]; do + line="$(trim_whitespace "$rawLine")" + if [[ -z "$line" ]] || [[ "$line" =~ ^# ]]; then + continue + fi -# Combine directories and files into one list + IFS='|' read -r shortcutName shortcutCommand shortcutWorkspace _ <<< "$line" + shortcutName="$(trim_whitespace "$shortcutName")" + shortcutCommand="$(trim_whitespace "$shortcutCommand")" + shortcutWorkspace="$(trim_whitespace "$shortcutWorkspace")" + + if [[ -z "$shortcutName" ]] || [[ -z "$shortcutCommand" ]]; then + continue + fi + + shortcutMenuList+=("$shortcutName" "$(build_launch_command "$shortcutCommand" "$shortcutWorkspace")") + done < "$shortcutsFile" +fi + +# Discover directories and files on the desktop. +mapfile -t desktopDirs < <(find "$desktopPath" -mindepth 1 -maxdepth 1 -type d) +mapfile -t desktopFiles < <(find "$desktopPath" -mindepth 1 -maxdepth 1 -type f) desktopItems=("${desktopDirs[@]}" "${desktopFiles[@]}") # Build menu for yad. -declare -a menuList -for i in "${desktopItems[@]}" ; do - case "$i" in - *".desktop") - menuList+=("$(grep "^Name" "$i" | cut -f2- -d '=')" "gio launch \"$i\"") +declare -a desktopMenuList +for desktopItem in "${desktopItems[@]}"; do + case "$desktopItem" in + *.desktop) + desktopName="$(grep -m 1 "^Name=" "$desktopItem" | cut -f2- -d '=')" + if [[ -z "$desktopName" ]]; then + desktopName="${desktopItem##*/}" + fi + desktopMenuList+=("$desktopName" "gio launch \"$desktopItem\"") ;; *) - menuList+=("${i##*/}" "/usr/bin/env xdg-open \"$i\"") + desktopMenuList+=("${desktopItem##*/}" "/usr/bin/env xdg-open \"$desktopItem\"") ;; esac done -launch=$(yad --list \ +menuList=("${shortcutMenuList[@]}" "${desktopMenuList[@]}") +if [[ "${#menuList[@]}" -eq 0 ]]; then + exit 0 +fi + +if launch=$(yad --list \ --title="I38 Desktop" \ --column="Items" \ --column="Launch Command" \ @@ -43,8 +152,7 @@ launch=$(yad --list \ --hide-column=2 \ --search-column=1 \ --skip-taskbar \ - "${menuList[@]}") -if [[ $? -eq 0 ]]; then + "${menuList[@]}"); then launch="${launch%|}" launch="${launch##*|}" eval "$launch"