# Copyright (C) 2022 Martin Matouš # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . DESCRIPTION="Manage XDG autostart applications" MAINTAINER="Martin Matouš " VERSION="1.0.0" AUTOSTART_DIR="${XDG_CONFIG_HOME%/}/autostart" get_entry_dirs() { echo "${XDG_DATA_HOME%/}/applications" local xdg_data IFS=':' read -ra xdg_data <<< "${XDG_DATA_DIRS}" for dir in "${xdg_data[@]}"; do echo "${dir%/}/applications" done } find_targets() { mapfile -t entry_dirs < <(get_entry_dirs) local dir for dir in "${entry_dirs[@]}"; do for desktop_file in "${dir%/}"/*.desktop; do [[ -f ${desktop_file} ]] && echo "${desktop_file}" done done } remove_symlink() { if [[ ! -L "${symlink}" ]]; then die -q "${symlink} does not exist or is not a symlink!" fi rm -f "${symlink}" } ### list action ### is_enabled() { local -r entry="${1}" mapfile -t autostarted_list < <(find "${AUTOSTART_DIR}" -type l) local autostarted IFS="" for autostarted in ${autostarted_list[@]}; do autostarted="$(canonicalise "${autostarted}")" [[ "${entry}" = "${autostarted}" ]] && return 0 done return 1 } describe_list() { echo "List available XDG .desktop files" } do_list() { local i mapfile -t targets < <(find_targets) if [[ ! -d ${AUTOSTART_DIR} ]]; then write_warning_msg "Autostart dir not found. Maybe you are running eselect autostart as root?" fi write_list_start "Available autostart symlink targets:" for (( i = 0; i < ${#targets[@]}; i++ )); do is_enabled "${targets[i]}" && targets[i]=$(highlight_marker "${targets[i]}") done write_numbered_list -m "(none found)" "${targets[@]}" } ### enable action ### describe_enable() { echo "Enable specified XDG .desktop file(s)" } describe_enable_parameters() { echo "" } describe_enable_options() { echo " : Target name or number (from 'list' action)" } deduce_path() { mapfile -t entry_dirs < <(get_entry_dirs) local dir local -r entry_relative_path="${1}" for dir in "${entry_dirs[@]}"; do if [[ -f ${dir%/}/${entry_relative_path} ]]; then echo "${dir%/}/${entry_relative_path}" fi done } activate_entry() { local entry=${1} shift local -r targets=("${@}") if is_number "${entry}"; then [[ ${entry} -ge 1 && ${entry} -le ${#targets[@]} ]] \ || die -q "Number out of range: ${entry}" entry=${targets[entry-1]} fi if [[ ! "${entry}" == *".desktop" ]]; then entry="${entry}.desktop" fi # if only file specified (no / in arg) if [[ ! "${entry}" == *"/"* ]]; then entry=$(deduce_path "${entry}") fi if [[ ! -f ${entry} ]]; then write_error_msg "Entry ${entry} doesn't exist!" return fi local -r symlink="${AUTOSTART_DIR}/$(basename "${entry}")" # entry with that name is already activated if [[ -L ${symlink} ]]; then local -r active=$(find "${symlink}" -printf %l) if [[ "${active}" = "${entry}" ]]; then write_warning_msg "${active} is already activated" return else remove_symlink "${symlink}" \ || die -q "Couldn't deactivate previous entry" fi return fi ln -s "${entry}" "${symlink}" || \ write_error_msg "Failed to create symlink '${symlink}' -> '${entry}'" } do_enable() { [[ -z ${1} ]] && die -q "You didn't specify any .desktop file to enable" # create directory if necessary if [[ ! -d ${AUTOSTART_DIR} ]]; then mkdir -p "${AUTOSTART_DIR}" || die -q "Failed to create ${AUTOSTART_DIR}" fi # make sure we have proper permissions if [[ ! -w ${AUTOSTART_DIR} ]]; then die -q "You don't have permission to write to ${AUTOSTART_DIR}" fi mapfile -t targets < <(find_targets) for entry in "$@"; do activate_entry "${entry}" "${targets[@]}" done } ### disable action ### describe_disable() { echo "Disable specified XDG .desktop file(s)" } describe_disable_parameters() { echo "" } describe_disable_options() { echo " : Target name or number (from 'list' action)" } do_disable() { [[ -z ${1} ]] && die -q "You didn't specify any XDG .desktop files to disable" local symlink_name symlink entry mapfile -t targets < <(find_targets) for entry in "$@"; do if is_number "${entry}"; then [[ ${entry} -ge 1 && ${entry} -le ${#targets[@]} ]] \ || die -q "Number out of range: ${entry}" entry="${targets[entry-1]}" fi if [[ ! "${entry}" == *".desktop" ]]; then entry="${entry}.desktop" fi symlink_name=$(basename "${entry}") symlink="${AUTOSTART_DIR}/${symlink_name}" remove_symlink "${symlink}" done }