OSDN Git Service

[fix] : Fixed command check
[alterlinux/dmc.git] / dmc
diff --git a/dmc b/dmc
index 3b1ee67..6e5872c 100755 (executable)
--- a/dmc
+++ b/dmc
@@ -2,11 +2,15 @@
 #
 # Yamada Hayao
 # Twitter: @Hayao0819
+# GitHub : @Hayao0819
 # Email  : hayao@fascode.net
 #
 # (c) 2019-2021 Fascode Network.
 #
-# dmc
+# dmc - display manager config tool
+#
+# Tool to change display manager settings
+# It supports various display managers.
 #
 # LICENSE: THE SUSHI-WARE LICENSE
 # https://github.com/MakeNowJust/sushi-ware
 # https://qiita.com/laikuaut/items/4bc07eabce56ee30812d
 # https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51
 
+SCRIPT_PATH="$( cd -P "$( dirname "$(readlink -f "${0}")" )" && pwd )"
+
 script_usage(){
     echo "usage: dmc [options] [command]"
     echo
-    echo "A simple tool for switching LightDM Greeters"
+    echo "Tool to change display manager settings"
+    echo
+    echo " Example:"
+    echo "    dmc lightdm greeter-list"
+    echo "    dmc gdm root-login true"
+    echo
+    echo " General command:"
+    echo "    dm [display manager]              Set display manager"
+    echo "    [mode] [command]                  You can specify the mode as a command"
+    echo "    gtk-list                          Show a list of GTK theme"
+    echo "    help                              Show this help document"
     echo
     echo " LightDM command:"
     echo "    autologin [username] [session]    Set up automatic login (with blank username to disable)"
@@ -37,23 +53,35 @@ script_usage(){
     echo "    cursor                            Run cursor selection wizard"
     echo "    cursor-change [cursor]            Specify the cursor theme"
     echo "    cursor-list                       Show a list of cursor theme"
+    echo "    edit                              Edit config file"
     echo "    sound [true or false]             Toggle the sound when an event occurs"
     echo "    logo [image]                      Specify the logo of the login screen"
     echo "    tap [true or false]               Toggle whether to recognize the tap as a click"
     echo "    accessibility [true or false]     Toggle whether to show accessibility menu"
     echo "    root-login [true or false]        Toggle whether to enable root login"
+    echo "    remove                            Removes all settings"
     echo
-    echo " Webkit2 command:"
+    echo " GTKG command: (lightdm-gtk-greeter)"
+    echo "    gtk                               Run gtk theme selection wizard"
+    echo "    gtk-change [theme]                Specify gtk theme"
+    echo "    icon                              Run icon theme selection wizard"
+    echo "    icon-change [icon]                Specify the icon theme"
+    echo
+    echo " Webkit2 command: (lightdm-webkit2-greeter)"
     echo "    theme                             Run theme selection wizard"
     echo "    theme-change [theme]              Specify the theme"
+    echo "    remove                            Removes all settings"
+    echo "    debug [true or false]             Toggle debug mode"
     echo
-    echo " Qtquick command:"
+    echo " Qtquick command: (lightdm-qtquick-greeter)"
     echo "    back                              Specify the background image"
+    echo "    remove                            Removes all settings"
     echo
-    echo " Slick command:"
+    echo " Slick command: (lightdm-slick-greeter)"
     echo "    back [image]                      Specify the background image"
     echo "    grid [true or false]              Toggle whether to show grid"
     echo "    icon                              Run icon theme selection wizard"
+    echo "    icon-change [icon]                Specify the icon theme"
     echo "    gtk                               Run gtk theme selection wizard"
     echo "    gtk-change [theme]                Specify gtk theme"
     echo
@@ -77,6 +105,7 @@ script_usage(){
     echo "    gtk-change [theme]                Specify gtk theme"
     echo
     echo " General option:"
+    echo "    -G | --lightdm-greeter            Automatically get the current greeter and set as mode (Only LightDM)"
     echo "    -m | --mode [mode name]           Specifiy the target you want to set"
     echo "    -e | --editer [editor path]       Specifiy the editor to use for editing"
     echo "    -h | --help                       This help message and exit"
@@ -84,12 +113,13 @@ script_usage(){
     echo "    --no-check-target                 No check the target for the selected mode"
     echo "    --noroot                          No check root permission"
     echo "    --write-all-files                 Allows rewriting of all configuration files"
+    echo "    --remove                          Remove the file instead of renaming it with the remove command"
     echo
     echo " Supported modes:"
     echo "    Display managers: lightdm, gdm, sddm, lxdm"
-    echo "    LightDM greeters: webkit2, qtquick, slick"
+    echo "    LightDM greeters: webkit2, qtquick, slick, gtkg"
     echo
-    echo " Default mode: ${DISPLAY_MANAGER}"
+    echo " Default mode: ${MODE}"
     echo
     echo " This tool is incomplete and still under development."
     echo " If you find a bug, please report it on GitHub."
@@ -119,13 +149,9 @@ check_root(){
 
 # 数値チェック
 check_int(){
-    set +e
-    #if (( "$(expr "${1}" + 1 >/dev/null 2>&1; printf "${?}")" < 2 )); then
     if printf "%s" "${1}" | grep -E "^[0-9]+$" 1>/dev/null 2>&1; then
-        set -e
         return 0
     else
-        set -e
         return 1
     fi
 }
@@ -138,41 +164,31 @@ check_bool(){
     fi
 }
 
-# コマンドラッパー
-wrapper(){
-    local _command="${1}"
-    shift 1
-    if which "${_command}" >/dev/null 2>&1; then
-        $(which "${_command}") "${@}"
-    else
-        msg_error "${_command} was not found"
-        exit 1
-    fi
-}
-
-# crudini ラッパー
-crudini(){
-    wrapper crudini "${@}"
+# インストールされていないコマンドを確認
+check_tools(){
+    local _command
+    for _command in "${@}"; do
+        if ! which "${_command}" >/dev/null 2>&1; then
+            msg_error "${_command} was not found"
+            exit 1
+        fi
+    done
 }
 
-# jq ラッパー
-jq(){
-    wrapper jq "${@}"
-}
 
 # 指定されたコマンドが現在のモードで実行可能かどうかを判定する
 check_command_dm(){
-    if ! printf "%s\n" "${@}" | grep -xE "${DISPLAY_MANAGER}" >/dev/null 2>&1; then
-        msg_error "This command (${COMMAND}) is not available in the current mode (${DISPLAY_MANAGER})."
+    if ! printf "%s\n" "${@}" | grep -xE "${MODE}" >/dev/null 2>&1; then
+        msg_error "This command (${COMMAND}) is not available in the current mode (${MODE})."
         exit 1
     fi
 }
 
 # 現在のモードのメインバイナリが存在しているかどうか確認する
 check_main_binary(){
-    if [[ -z "${MAIN_BINARY["${DISPLAY_MANAGER}"]+SET}" ]]; then
+    if [[ -z "${MAIN_BINARY["${MODE}"]+SET}" ]]; then
         msg_warn "The main binary for the selected mode is not set."
-    elif [[ ! -f "${MAIN_BINARY["${DISPLAY_MANAGER}"]}" ]]; then
+    elif [[ ! -f "${MAIN_BINARY["${MODE}"]}" ]]; then
         msg_error "The target for the selected mode is not installed."
         exit 1
     fi
@@ -189,7 +205,7 @@ get_cursor_theme(){
         if [[ -d "${_dir}" ]]; then
             while read -r line; do
                 _cursor_theme_dir_list+=("${line}")
-            done < <(find "${_dir}" -type d -name "cursors" -print0 | xargs -0 -i dirname {} | sort)
+            done < <(find "${_dir}" -type d -name "cursors" -print0 | xargs -0 -I{} dirname {} | sort)
         fi
     done
     unset _dir _find_cursor_dir_list
@@ -213,7 +229,7 @@ get_gtk_theme(){
         if [[ -d "${_dir}" ]]; then
             while read -r line; do
                 _gtk_theme_dir_list+=("${line}")
-            done < <(find "${_dir}" -type d -name "gtk-*" -print0 | xargs -0 -i dirname {} | tr " " "\n" | sort | uniq)
+            done < <(find "${_dir}" -type d -name "gtk-*" -print0 | xargs -0 -I{} dirname {} | tr " " "\n" | sort | uniq)
         fi
     done
 
@@ -237,7 +253,7 @@ get_icon_theme(){
         if [[ -d "${_dir}" ]]; then
             while read -r line; do
                 _icon_theme_dir_list+=("${line}")
-            done < <(find "${_dir}" -type f -name "index.theme" -print0 | xargs -0 -i dirname {} | tr " " "\n" | sort | uniq)
+            done < <(find "${_dir}" -type f -name "index.theme" -print0 | xargs -0 -I{} dirname {} | tr " " "\n" | sort | uniq)
         fi
     done
 
@@ -254,20 +270,16 @@ get_icon_theme(){
     printf "%s\n" "${_gtk_theme_name_list[@]}" | sort | uniq
 }
 
-get_xorg_session(){
-    find "/usr/share/xsessions" -type f -print0 -name "*.desktop" | xargs -0 -I{} bash -c 'basename {} | sed "s|.desktop||g"'
+get_session(){
+    find "/usr/share/xsessions" "/usr/share/wayland-sessions" -type f -print0 -name "*.desktop" | xargs -0 -I{} bash -c 'basename {} | sed "s|.desktop||g"'
 }
 
-get_wayland_session(){
-    find "/usr/share/wayland-sessions" -type f  -print0 -name "*.desktop" | xargs -0 -I{} bash -c 'basename {} | sed "s|.desktop||g"'
-}
 
 # 質問を行う関数
 # Returns only the selected result to standard output
 # ask_question -d <デフォルト値> -p <質問文> <選択肢1> <選択肢2> ...
 ask_question(){
-    local arg OPTARG OPTIND
-    local _default="" _choice_list _count _choice _question
+    local arg OPTARG OPTIND _default="" _choice_list _count _choice _question
     while getopts "d:p:" arg; do
         case "${arg}" in
             d) _default="${OPTARG}" ;;
@@ -275,8 +287,9 @@ ask_question(){
             *) exit 1 ;;
         esac
     done
-    shift $((OPTIND - 1))
+    shift "$((OPTIND - 1))"
     _choice_list=("${@}")
+    _digit="${##}"
 
     # 選択肢に関するエラー
     if (( ${#_choice_list[@]} < 0 )); then
@@ -297,9 +310,9 @@ ask_question(){
     for (( _count=1; _count<=${#_choice_list[@]}; _count++)); do
         _choice="${_choice_list[$(( _count - 1 ))]}"
         if [[ ! "${_default}" = "" ]] && [[ "${_choice}" = "${_default}" ]]; then
-            echo " * ${_count}: ${_choice}" >&2
+            printf " * %${_digit}d: ${_choice}\n" "${_count}" >&2
         else
-            echo "   ${_count}: ${_choice}" >&2
+            printf "   %${_digit}d: ${_choice}\n" "${_count}" >&2
         fi
         unset _choice
     done
@@ -329,8 +342,8 @@ ask_question(){
 # デスクトップセッションを聞く
 ask_session(){
     local _session
-    if (( $(get_xorg_session | wc -l) <= 1 )); then
-        _session="$(get_xorg_session)"
+    if (( $(get_session | wc -l) <= 1 )); then
+        _session="$(get_session)"
     elif [[ "${NON_INTERACTIVE}" = true ]]; then
         # 非対話モード
         # ~/.dmrcの値を設定します
@@ -341,16 +354,8 @@ ask_session(){
             exit 1
         fi
     else
-        while read -r line; do
-            _session_list+=("${line}")
-        done < <(get_xorg_session)
-        if ! session="$(ask_question -p "Select the desktop session to autologin" "${_session_list[@]}")"; then
-            msg_error "Please enter the correct session name."
-            exit 1
-        fi
-        if [[ -f "/usr/share/xsessions/${session}.desktop" ]]; then
-            _session="${session}"
-        else
+        readarray -t _session_list < <(get_session)
+        if ! _session="$(ask_question -p "Select the desktop session to autologin" "${_session_list[@]}")"; then
             msg_error "Please enter the correct session name."
             exit 1
         fi
@@ -361,7 +366,7 @@ ask_session(){
 # GTKテーマを聞く
 ask_gtk_theme(){
     local gtk_themes _theme
-    while read -r line; do gtk_themes+=("${line}"); done < <(get_gtk_theme)
+    readarray -t gtk_themes < <(get_gtk_theme)
 
     # 質問する
     if ! _theme="$(ask_question -p "Please select the theme to use" "${gtk_themes[@]}")"; then
@@ -374,18 +379,32 @@ ask_gtk_theme(){
 # セッションが利用可能かどうか確認する
 # check_session <session>
 check_session(){
-    if [[ ! -f "/usr/share/xsessions/${1}.desktop" ]]; then
-        # 存在しないセッションが指定された場合
-        msg_error "This is a session (${1}) that does not exist."
-        exit 1
-    fi
+    for _file in "/usr/share/wayland-sessions/${1}.desktop" "/usr/share/xsessions/${1}.desktop"; do
+        if [[ -f "${_file}" ]]; then
+            return 0
+        fi
+    done
+    # 存在しないセッションが指定された場合
+    msg_error "This is a session (${1}) that does not exist."
+    return 1
+}
+
+# セッションのフルパスを返す
+get_session_path(){
+    check_session "${1}"
+    for _file in "/usr/share/wayland-sessions/${1}.desktop" "/usr/share/xsessions/${1}.desktop"; do
+        if [[ -f "${_file}" ]]; then
+            echo "${_file}"
+            return 0
+        fi
+    done
 }
 
 # セッションのバイナリを取得する
 # get_session <session name>
-get_session(){
+get_session_exec(){
     check_session "${1}"
-    local session_exec="$(crudini --get "/usr/share/xsessions/${1}.desktop" "Desktop Entry" "Exec")"
+    local session_exec="$(crudini --get "$(get_session_path "${1}")" "Desktop Entry" "Exec")"
     if [[ ! -f "${session_exec}" ]]; then
         session_exec="$(type -p "${session_exec}")"
     fi
@@ -435,6 +454,98 @@ check_filetype(){
     return 1
 }
 
+# systemdのunitが存在しているか確認
+check_systemd_unit(){
+    if [[ ! -v 1 ]]; then
+        return 1
+    elif systemctl cat "${1}" 1> /dev/null 2>&1; then
+        return 0
+    fi
+    return 1
+}
+
+# removeコマンドの共通処理
+# 引数に削除したいファイルへのパス
+common_remove_command(){
+    local _file _yes_or_no
+    for _file in "${@}"; do
+        if [[ -f "${_file}" ]]; then
+            if [[ "${NON_INTERACTIVE}" = true ]]; then
+                _yes_or_no="y"
+            else
+                echo -e "Remove ${_file} ? It is irreversible"
+                echo -ne "(y or n) > "
+                read -r -n 1 _yes_or_no
+                echo
+            fi
+            if [[ "${_yes_or_no}" = "y" ]]; then
+                if [[ "${REMOVE_FILES}" = true ]]; then
+                    echo "Removed ${_file}"
+                    rm -rf "${_file}"
+                else
+                    echo "Moved ${_file} ${_file}.disabled"
+                    mv "${_file}" "${_file}.disabled"
+                fi
+            fi
+        else
+            continue
+        fi
+    done
+}
+
+#== すべてのモード用コマンド ==#
+command_general_dm(){
+    if [[ -z "${1}" ]] || [[ "${1}" = "" ]]; then
+        msg_error "Please specify display manager"
+        exit 1
+    fi
+
+    # 現在のディスプレイマネージャを無効化
+    if [[ -n "${CURRENT_DM+SET}" ]]; then
+        systemctl disable "${CURRENT_DM}.service"
+    fi
+
+    # 指定されたディスプレイマネージャを有効化
+    if check_systemd_unit "${1}"; then
+        systemctl enable "${1}.service"
+    else
+        msg_error "Wrong display manager name"
+    fi
+}
+
+# モードをコマンドとして扱い自身を再実行する
+# command_mode <mode> <command> <args>
+command_mode(){
+    if [[ -z "${2+SET}" ]] || [[ "${2}" = "" ]]; then
+        msg_error "Please specify command"
+        exit 1
+    fi
+
+    local _mode="${1}" _command="${2}"
+    local _dmc_args=("-e" "${USE_EDITOR}" "-m" "${_mode}")
+    shift 2
+
+    # 基本的な変数を設定
+    local _command_args=("${@}")
+
+    # オプション設定
+    if [[ "${NON_INTERACTIVE}" = true ]]; then
+        _dmc_args+=("--non-interactive")
+    fi
+    if [[ "${NOROOT}" = true ]]; then
+        _dmc_args+=("--noroot")
+    fi
+    if [[ "${NO_CHECK_TARGET}" = true ]]; then
+        _dmc_args+=("--no-check-target")
+    fi
+    if [[ "${WRITE_ALL_FILES}" = true ]]; then
+        _dmc_args+=("--write-all-files")
+    fi
+
+    bash "${SCRIPT_PATH}/$(basename "${0}")" "${_dmc_args[@]}" "${_command}" "${_command_args[@]}"
+}
+
+
 
 #== LightDM用の汎用関数 ==#
 # キーが設定されている設定ファイル
@@ -452,7 +563,7 @@ lightdm_get_source_file(){
 
 # 設定ファイルの値を変更する
 lightdm_set_config(){
-    local key="${1}" value="${2}" file=${3-${DISPLAY_MANAGER_CONFIG["lightdm"]}}
+    local key="${1}" value="${2}" file=${3-${MODE_CONFIG["lightdm"]}}
     if [[ "${WRITE_ALL_FILES}" = true ]] && [[ -n "$(lightdm_get_source_file "${1}")" ]]; then
         crudini --set "$(lightdm_get_source_file "${1}")" 'Seat:*' "${key}" "${value}"
     else
@@ -468,19 +579,19 @@ lightdm_set_config(){
 # 設定ファイルのキーを削除する
 lightdm_remove_key(){
     local key="${1}" _config
-    if grep -E "^ ?${key}.+" "${DISPLAY_MANAGER_CONFIG["lightdm"]}" 1>/dev/null 2>&1; then
-        sed -i -r "s|^ ?${key} ?=.+||g" "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
-        sed -i '/^$/d' "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
+    if grep -E "^ ?${key}.+" "${MODE_CONFIG["lightdm"]}" 1>/dev/null 2>&1; then
+        sed -i -r "s|^ ?${key} ?=.+||g" "${MODE_CONFIG["lightdm"]}"
+        sed -i '/^$/d' "${MODE_CONFIG["lightdm"]}"
     fi
 }
 
 # 設定ファイルを作成
 lightdm_init_configs(){
     check_root
-    if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lightdm"]}" ]]; then
-        mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["lightdm"]}")"
-        touch "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
-        echo "[Seat:*]" > "${DISPLAY_MANAGER_CONFIG["lightdm"]}"
+    if [[ ! -f "${MODE_CONFIG["lightdm"]}" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["lightdm"]}")"
+        touch "${MODE_CONFIG["lightdm"]}"
+        echo "[Seat:*]" > "${MODE_CONFIG["lightdm"]}"
     fi
 }
 
@@ -496,6 +607,12 @@ lightdm_get_value(){
     fi
 }
 
+lightdm_greeter_list(){
+    local greeter_list
+    readarray -t greeter_list < <( (find "${LIGHTDM_GREETERS_DIR}" -print0 -type f | xargs -0 -I{} basename {} | grep -E ".desktop$" | sed "s|.desktop$||g" | grep -xv "xgreeters") 2> /dev/null )
+    printf "%s\n" "${greeter_list[@]}" | sort | uniq
+}
+
 #== LightDM用コマンド ==#
 # greeter-changeコマンド
 command_lightdm_greeter_change() {
@@ -506,7 +623,7 @@ command_lightdm_greeter_change() {
     fi
 
     # 指定されたGreeterが正しいか確認
-    if ! printf "%s\n" "${LIGHTDM_GREETERS[@]}" | grep -x "${1}" > /dev/null 2>&2; then
+    if ! lightdm_greeter_list | grep -x "${1}" > /dev/null 2>&2; then
         msg_error "The greeter (${1}) doesn't exist."
         exit 1
     else
@@ -549,7 +666,7 @@ EOF
 command_lightdm_greeter_list() {
     echo "Available Lightdm greeter list:"
     local _greeter
-    for _greeter in "${LIGHTDM_GREETERS[@]}"; do
+    for _greeter in $(lightdm_greeter_list); do
         if [[ "${_greeter}" = "${LIGHTDM_CURRENT_GREETER}" ]]; then
             echo " * ${_greeter}"
         else
@@ -559,17 +676,18 @@ command_lightdm_greeter_list() {
 }
 
 # greeterコマンド
-run_greeter_wizard(){
+command_lightdm_greeter_wizard(){
     # グリーターの数を確認
-    if (( ${#LIGHTDM_GREETERS[@]} < 1 )); then
+    if (( $(lightdm_greeter_list | wc -l) < 1 )); then
         msg_error "LightDM Greeter was not found."
         exit 1
     fi
 
     # 質問する
     local _greeter
-    if ! _greeter="$(ask_question -p "Please select the greeter to use." -d "${LIGHTDM_CURRENT_GREETER}" "${LIGHTDM_GREETERS[@]}")"; then
-        run_greeter_wizard
+    # shellcheck disable=SC2046
+    if ! _greeter="$(ask_question -p "Please select the greeter to use." -d "${LIGHTDM_CURRENT_GREETER}" $(lightdm_greeter_list))"; then
+        command_lightdm_greeter_wizard
         exit 0
     fi
 
@@ -577,7 +695,7 @@ run_greeter_wizard(){
     if [[ -n "${_greeter}" ]]; then
         command_lightdm_greeter_change "${_greeter}"
     else
-        run_greeter_wizard
+        command_lightdm_greeter_wizard
         exit 0
     fi
 
@@ -588,16 +706,7 @@ run_greeter_wizard(){
 
 # removeコマンド
 command_lightdm_remove(){
-    if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lightdm"]}" ]]; then
-        return 0
-    else
-        local _yes_or_no
-        echo -ne "Are you sure you want to delete all settings?\nThis change is irreversible.\n (y or n) > "
-        read -r -n 1 _yes_or_no
-        if [[ "${_yes_or_no}" = "y" ]]; then
-            mv "${DISPLAY_MANAGER_CONFIG["lightdm"]}" "${DISPLAY_MANAGER_CONFIG["lightdm"]}.disabled"
-        fi
-    fi
+    common_remove_command "${MODE_CONFIG["lightdm"]}"
 }
 
 # greeter-edit
@@ -607,7 +716,7 @@ command_lightdm_greeter_edit(){
         exit 1
     fi
     local _greeter="${1:-${LIGHTDM_CURRENT_GREETER}}"
-    if [[ -z "${GREETER_CONFIG["${_greeter}"]+SET}" ]]; then
+    if [[ -z "${MODE_CONFIG[${GREETER_MODE["${_greeter}"]}]+SET}" ]]; then
         msg_error "This Greeter is not currently supported."
         msg_error "Please report the problem here."
         msg_error "https://github.com/FascodeNet/lightdm-config/issues"
@@ -619,7 +728,7 @@ command_lightdm_greeter_edit(){
             read -r
         fi
         set -u
-        bash -c "${USE_EDITOR} ${GREETER_CONFIG["${_greeter}"]}"
+        bash -c "${USE_EDITOR} ${MODE_CONFIG[${GREETER_MODE["${_greeter}"]}]}"
         exit
     fi
 }
@@ -630,7 +739,9 @@ command_lightdm_edit(){
         msg_error "You cannot use this command in non-interactive mode."
         exit 1
     fi
-    for _config in "${LIGHTDM_LOADED_CONFIG[@]}"; do
+    local loaded_config_list
+    readarray -t loaded_config_list < <(printf "%s\n" "$(lightdm --show-config 2>&1 | grep -x -A "$(lightdm --show-config 2>&1 | wc -l)" "Sources:" | grep -v "Sources" | sed 's|^[A-Z]  ||g')"  | tr -d " ")
+    for _config in "${loaded_config_list[@]}"; do
         echo -ne "Edit ${_config} ? (y or n)> "
         read -r -n 1 _yes_or_no
         echo
@@ -648,7 +759,7 @@ command_lightdm_auto_login(){
         if [[ -n "${autologin_user}" ]]; then
             # autologinを無効化
             for _autologin in "autologin-guest" "autologin-user" "autologin-user-timeout" "autologin-in-background" "autologin-session"; do
-                remove_key "${_autologin}"
+                lightdm_remove_key "${_autologin}"
             done
             echo "Canceled automatic login of ${autologin_user}"
         fi
@@ -696,7 +807,7 @@ gdm_init_configs(){
     fi
 
     local _file
-    for _file in "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}"; do
+    for _file in "${MODE_CONFIG["gdm-dconf"]}" "${MODE_CONFIG["gdm-custom"]}"; do
         if [[ ! -f "${_file}" ]]; then
             mkdir -p "$(dirname "${_file}")"
             touch "${_file}"
@@ -707,29 +818,29 @@ gdm_init_configs(){
 # gdm_dconf_set_config <dconf path> <key> <value>
 gdm_dconf_set_config(){
     if check_int "${3}" || check_bool "${3}"; then
-        crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${1}" "${2}" "${3}"
+        crudini --set "${MODE_CONFIG["gdm-dconf"]}" "${1}" "${2}" "${3}"
     else
-        crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-dconf"]}" "${1}" "${2}" "\"${3}\""
+        crudini --set "${MODE_CONFIG["gdm-dconf"]}" "${1}" "${2}" "\"${3}\""
     fi
     gdm_update
 }
 
 # gdm_dconf_get_value <dconf path> <key>
 gdm_dconf_get_value(){
-    find "/etc/dconf/db/gdm.d/" -type f -print0 | xargs -0i cat {} | crudini --get - "${1}" "${2}" | sed "s|^[\"\']||g" | sed "s|[\"\']$||g"
+    find "/etc/dconf/db/gdm.d/" -type f -print0 | xargs -0 -I{} cat {} | crudini --get - "${1}" "${2}" | sed "s|^[\"\']||g" | sed "s|[\"\']$||g"
 }
 
 # gdm_custom_get_value <section> <key>
 gdm_custom_get_value(){
-    crudini --get "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}"
+    crudini --get "${MODE_CONFIG["gdm-custom"]}" "${1}" "${2}"
 }
 
 # gdm_custom_set_config <section> <key> <value>
 gdm_custom_set_config(){
     if check_int "${3}" || check_bool "${3}"; then
-        crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" "${3}"
+        crudini --set "${MODE_CONFIG["gdm-custom"]}" "${1}" "${2}" "${3}"
     else
-        crudini --set "${DISPLAY_MANAGER_CONFIG["gdm-custom"]}" "${1}" "${2}" "\"${3}\""
+        crudini --set "${MODE_CONFIG["gdm-custom"]}" "${1}" "${2}" "\"${3}\""
     fi
     gdm_update
 }
@@ -750,7 +861,7 @@ command_gdm_logo(){
         exit 1
     fi
 
-    local _backgrounf_file="/usr/share/backgrounds/gdm/background"
+    local _backgrounf_file="${BACKGROUND_DIR}/gdm/background"
     mkdir -p "$(dirname "${_backgrounf_file}")"
     cp "${1}" "${_backgrounf_file}"
     chmod 644 "${_backgrounf_file}"
@@ -761,11 +872,11 @@ command_gdm_logo(){
 command_gdm_cursor_wizard(){
     # カーソル一覧を取得
     local cursor_themes _current_theme="$(gdm_dconf_get_value "org/gnome/desktop/interface" "cursor-theme")"
-    while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
+    readarray -t cursor_themes < <(get_cursor_theme)
 
     # 一覧を生成
     if ! _cursor_theme="$(ask_question -d "${_current_theme}" -p "Please select the cursor theme to use." "${cursor_themes[@]}")"; then
-        run_greeter_wizard
+        command_gdm_cursor_wizard
         exit 0
     fi
 
@@ -787,7 +898,7 @@ command_gdm_cursor_change(){
         exit 1
     fi
     local cursor_themes
-    while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
+    readarray -t cursor_themes < <(get_cursor_theme)
     if ! printf "%s\n" "${cursor_themes[@]}" | grep -x "${1}" 1>/dev/null 2>&1; then
         msg_error "The cursor theme (${1}) was not found"
         exit 1
@@ -813,6 +924,18 @@ command_gdm_tap(){
     gdm_dconf_set_config "org/gnome/desktop/peripherals/touchpad" "tap-to-click" "${_arg}"
 }
 
+command_gdm_edit(){
+    if [[ "${NON_INTERACTIVE}" = true ]]; then
+        msg_error "You cannot use this command in non-interactive mode."
+        exit 1
+    fi
+    bash -c "${USE_EDITOR} ${MODE_CONFIG["gdm-custom"]}"
+}
+
+command_gdm_remove(){
+    common_remove_command "${MODE_CONFIG["gdm-custom"]}"
+}
+
 # autologin
 command_gdm_auto_login(){
     if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
@@ -875,33 +998,31 @@ command_gdm_root_login(){
 #== Webkit2用の汎用関数 ==#
 webkit2_init_configs(){
     check_root
-    if [[ ! -f "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" ]]; then
-        mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-webkit2-greeter"]}")"
-        touch "${GREETER_CONFIG["lightdm-webkit2-greeter"]}"
+    if [[ ! -f "${MODE_CONFIG["webkit2"]}" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["webkit2"]}")"
+        touch "${MODE_CONFIG["webkit2"]}"
     fi
 }
 
 # webkit2_get_value <section> <key>
 webkit2_get_value(){
-    crudini --get "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" "${1}" "${2}"
+    crudini --get "${MODE_CONFIG["webkit2"]}" "${1}" "${2}"
 }
 
 # webkit2_set_config <section> <key> <value>
 webkit2_set_config(){
-    crudini --set "${GREETER_CONFIG["lightdm-webkit2-greeter"]}" "${1}" "${2}" "${3}"
+    crudini --set "${MODE_CONFIG["webkit2"]}" "${1}" "${2}" "${3}"
 }
 
 #== webkit2用コマンド ==#
 command_webkit2_theme_wizard(){
     local _theme_list
-    while read -r line; do
-        _theme_list+=("${line}")
-    done < <(ls /usr/share/lightdm-webkit/themes)
+    readarray -t _theme_list < <(ls /usr/share/lightdm-webkit/themes)
 
     local _current_theme=$(webkit2_get_value greeter webkit_theme | sed "s|\"||g")
     local _theme
     if ! _theme="$(ask_question -d "${_current_theme}" -p "Please select the theme to use." "${_theme_list[@]}")"; then
-        run_greeter_wizard
+        command_webkit2_theme_wizard
         exit 0
     fi
     if [[ -n "${_theme}" ]]; then
@@ -927,13 +1048,26 @@ command_webkit2_theme_change(){
     webkit2_set_config "greeter" "webkit_theme" "${1}"
 }
 
+command_webkit2_remove(){
+    common_remove_command "${MODE_CONFIG["webkit2"]}"
+}
+
+command_webkit2_debug(){
+    local _arg="$(echo "${1-""}" | tr "[:upper:]" "[:lower:]")"
+    if ! check_bool "${_arg}"; then
+        msg_error "Please specify true or false"
+        exit 1
+    fi
+    webkit2_set_config "greeter" "debug_mode" "${_arg}"
+}
+
 #== Qtquick用の汎用関数 ==#
 qtquick_init_configs(){
     check_root
-    if [[ ! -f "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" ]] || [[ -z "$(cat "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")" ]]; then
-        mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")"
-        touch "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
-        #echo -e "{\n\n}\n" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
+    if [[ ! -f "${MODE_CONFIG["qtquick"]}" ]] || [[ -z "$(cat "${MODE_CONFIG["qtquick"]}")" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["qtquick"]}")"
+        touch "${MODE_CONFIG["qtquick"]}"
+        #echo -e "{\n\n}\n" > "${MODE_CONFIG["qtquick"]}"
         qtquick_set_config background_path "file:///hoge/fuga.png"
         qtquick_set_config theme "qrc:/Login.qml"
     fi
@@ -941,16 +1075,20 @@ qtquick_init_configs(){
 
 #qtquick_get_value <key>
 qtquick_get_value(){
-    jq ".${1}" < "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
+    jq ".${1}" < "${MODE_CONFIG["qtquick"]}"
 }
 
 # command_qtquick_back <key> <value>
 qtquick_set_config(){
-    local _tempfile="/tmp/$(basename "${GREETER_CONFIG["lightdm-qtquick-greeter"]}")-$(base64 < "/dev/urandom" | fold -w 10 | head -n 1)"
-    cp "${GREETER_CONFIG["lightdm-qtquick-greeter"]}" "${_tempfile}"
-    #cat "${_tempfile}" | jq -r ".${1}|=\"${2}\"" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
-    jq -r ".${1}|=\"${2}\"" < "${_tempfile}" > "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
-    chmod 644 "${GREETER_CONFIG["lightdm-qtquick-greeter"]}"
+    local _tempfile="/tmp/$(basename "${MODE_CONFIG["qtquick"]}")-$(base64 < "/dev/urandom" | fold -w 10 | head -n 1)"
+    cp "${MODE_CONFIG["qtquick"]}" "${_tempfile}"
+    #cat "${_tempfile}" | jq -r ".${1}|=\"${2}\"" > "${MODE_CONFIG["qtquick"]}"
+    jq -r ".${1}|=\"${2}\"" < "${_tempfile}" > "${MODE_CONFIG["qtquick"]}"
+    chmod 644 "${MODE_CONFIG["qtquick"]}"
+}
+
+qtquick_command_remove(){
+    common_remove_command "${MODE_CONFIG["qtquick"]}"
 }
 
 #== Qtquick用コマンド ==#
@@ -964,7 +1102,7 @@ command_qtquick_back(){
         exit 1
     fi
 
-    local _backgrounf_file="/usr/share/backgrounds/lightdm/qtquick-greeter"
+    local _backgrounf_file="${BACKGROUND_DIR}/lightdm/qtquick-greeter"
     mkdir -p "$(dirname "${_backgrounf_file}")"
     cp "${1}" "${_backgrounf_file}"
     chmod 644 "${_backgrounf_file}"
@@ -974,19 +1112,19 @@ command_qtquick_back(){
 
 #== slick用の汎用関数 ==#
 slick_get_value(){
-    crudini --get "${GREETER_CONFIG["lightdm-slick-greeter"]}" "Greeter" "${1}"
+    crudini --get "${MODE_CONFIG["slick"]}" "Greeter" "${1}"
 }
 
 slick_set_config(){
-    crudini --set "${GREETER_CONFIG["lightdm-slick-greeter"]}" "Greeter" "${1}" "${2}"
+    crudini --set "${MODE_CONFIG["slick"]}" "Greeter" "${1}" "${2}"
 }
 
 slick_init_configs(){
     check_root
-    if [[ ! -f "${GREETER_CONFIG["lightdm-slick-greeter"]}" ]]; then
-        mkdir -p "$(dirname "${GREETER_CONFIG["lightdm-slick-greeter"]}")"
-        touch "${GREETER_CONFIG["lightdm-slick-greeter"]}"
-        echo "[Greeter]" > "${GREETER_CONFIG["lightdm-slick-greeter"]}"
+    if [[ ! -f "${MODE_CONFIG["slick"]}" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["slick"]}")"
+        touch "${MODE_CONFIG["slick"]}"
+        echo "[Greeter]" > "${MODE_CONFIG["slick"]}"
     fi
 }
 
@@ -1010,7 +1148,7 @@ command_slick_back(){
         exit 1
     fi
 
-    local _backgrounf_file="/usr/share/backgrounds/lightdm/slick-greeter"
+    local _backgrounf_file="${BACKGROUND_DIR}/lightdm/slick-greeter"
     mkdir -p "$(dirname "${_backgrounf_file}")"
     cp "${1}" "${_backgrounf_file}"
     chmod 644 "${_backgrounf_file}"
@@ -1018,7 +1156,6 @@ command_slick_back(){
     slick_set_config "background" "${_backgrounf_file}"
 }
 
-
 command_slick_gtk_wizard(){
     local _theme="$(ask_gtk_theme)"
 
@@ -1045,7 +1182,7 @@ command_slick_gtk_change(){
 
 command_slick_icon_wizard(){
     local icons
-    while read -r line; do icons+=("${line}"); done < <(get_icon_theme)
+    readarray -t icons < <(get_icon_theme)
 
     local _icon
     echo "Please select the icon theme to use."
@@ -1063,29 +1200,45 @@ command_slick_icon_wizard(){
     echo "Changed icon theme to ${_icon}"
 }
 
+command_slick_icon_chenge(){
+    if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
+        msg_error "Please specify the icon theme to use."
+        exit 1
+    fi
+    if ! printf "%s\n" "$(get_icon_theme)" | grep -x "${1}" 1> /dev/null 2>&1; then
+        msg_error "${1} was not found."
+        exit 1
+    fi
+    slick_set_config "icon-theme-name" "${1}"
+}
+
+command_slick_remove(){
+    common_remove_command "${MODE_CONFIG["slick"]}"
+}
+
 
 #== SDDM用の汎用関数 ==#
 # sddm_get_value <section> <key> <valye>
 sddm_get_value(){
-    crudini --set "${DISPLAY_MANAGER_CONFIG["sddm"]}" "${1}" "${2}"
+    crudini --set "${MODE_CONFIG["sddm"]}" "${1}" "${2}"
 }
 
 # sddm_set_config <section> <key> <value>
 sddm_set_config(){
-    crudini --set "${DISPLAY_MANAGER_CONFIG["sddm"]}" "${1}" "${2}" "${3}"
+    crudini --set "${MODE_CONFIG["sddm"]}" "${1}" "${2}" "${3}"
 }
 
 # sddm_remove_key <section> <key>
 sddm_remove_key(){
-    crudini --del "${DISPLAY_MANAGER_CONFIG["sddm"]}" "${1}" "${2}"
+    crudini --del "${MODE_CONFIG["sddm"]}" "${1}" "${2}"
 }
 
 
 sddm_init_configs(){
     check_root
-    if [[ ! -f "${DISPLAY_MANAGER_CONFIG["sddm"]}" ]]; then
-        mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["sddm"]}")"
-        sddm --example-config > "${DISPLAY_MANAGER_CONFIG["sddm"]}"
+    if [[ ! -f "${MODE_CONFIG["sddm"]}" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["sddm"]}")"
+        sddm --example-config > "${MODE_CONFIG["sddm"]}"
     fi
 }
 
@@ -1126,7 +1279,7 @@ command_sddm_auto_login(){
 command_sddm_cursor_wizard(){
     # カーソル一覧を取得
     local cursor_themes _current_theme="$(sddm_get_value "Theme" "CursorTheme")"
-    while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
+    readarray -t cursor_themes < <(get_cursor_theme)
 
     # 一覧を生成
     if ! _cursor_theme="$(ask_question -d "${_current_theme}" -p "Please select the cursor theme to use." "${cursor_themes[@]}")"; then
@@ -1152,7 +1305,7 @@ command_sddm_cursor_change(){
         exit 1
     fi
     local cursor_themes
-    while read -r line; do cursor_themes+=("${line}"); done < <(get_cursor_theme)
+    readarray -t cursor_themes < <(get_cursor_theme)
     if ! printf "%s\n" "${cursor_themes[@]}" | grep -x "${1}" 1>/dev/null 2>&1; then
         msg_error "The cursor theme (${1}) was not found"
         exit 1
@@ -1185,9 +1338,7 @@ command_sddm_tty(){
 
 command_sddm_theme_wizard(){
     local _theme_list
-    while read -r line; do
-        _theme_list+=("${line}")
-    done < <(find "/usr/share/sddm/themes/" -maxdepth 1 -mindepth 1 -type d -print0 | xargs -0 -I{} basename {})
+    readarray -t _theme_list < <(find "/usr/share/sddm/themes/" -maxdepth 1 -mindepth 1 -type d -print0 | xargs -0 -I{} basename {})
 
     local _theme _current_theme=$(sddm_get_value "Theme" "Current")
     if ! _theme="$(ask_question -d "${_current_theme}" -p "Please select the theme to use." "${_theme_list[@]}")"; then
@@ -1220,25 +1371,25 @@ command_sddm_theme_change(){
 #== LXDM用の汎用関数 ==#
 # sddm_get_value <section> <key> <valye>
 lxdm_get_value(){
-    crudini --set "${DISPLAY_MANAGER_CONFIG["lxdm"]}" "${1}" "${2}"
+    crudini --set "${MODE_CONFIG["lxdm"]}" "${1}" "${2}"
 }
 
 # sddm_set_config <section> <key> <value>
 lxdm_set_config(){
-    crudini --set "${DISPLAY_MANAGER_CONFIG["lxdm"]}" "${1}" "${2}" "${3}"
+    crudini --set "${MODE_CONFIG["lxdm"]}" "${1}" "${2}" "${3}"
 }
 
 # sddm_remove_key <section> <key>
 lxdm_remove_key(){
-    crudini --del "${DISPLAY_MANAGER_CONFIG["lxdm"]}" "${1}" "${2}"
+    crudini --del "${MODE_CONFIG["lxdm"]}" "${1}" "${2}"
 }
 
 
 lxdm_init_configs(){
     check_root
-    if [[ ! -f "${DISPLAY_MANAGER_CONFIG["lxdm"]}" ]]; then
-        mkdir -p "$(dirname "${DISPLAY_MANAGER_CONFIG["lxdm"]}")"
-        touch "${DISPLAY_MANAGER_CONFIG["lxdm"]}"
+    if [[ ! -f "${MODE_CONFIG["lxdm"]}" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["lxdm"]}")"
+        touch "${MODE_CONFIG["lxdm"]}"
     fi
 }
 
@@ -1289,7 +1440,7 @@ command_lxdm_session_change(){
     fi
     local session="${1}"
     check_session "${session}"
-    local session_exec="$(get_session "${session}")"
+    local session_exec="$(get_session_exec "${session}")"
     lxdm_set_config "base" "session" "${session_exec}"
 }
 
@@ -1324,7 +1475,7 @@ command_lxdm_back(){
         exit 1
     fi
 
-    local _backgrounf_file="/usr/share/backgrounds/lxdm/background"
+    local _backgrounf_file="${BACKGROUND_DIR}/lxdm/background"
     mkdir -p "$(dirname "${_backgrounf_file}")"
     cp "${1}" "${_backgrounf_file}"
     chmod 644 "${_backgrounf_file}"
@@ -1356,22 +1507,101 @@ command_lxdm_gtk_change(){
     lxdm_set_config "display" "gtk_theme" "${1}"
 }
 
-#== 設定ファイルのパス ==#
-declare -A GREETER_CONFIG=(
-    ["lightdm-webkit2-greeter"]="/etc/lightdm/lightdm-webkit2-greeter.conf"
-    ["lightdm-slick-greeter"]="/etc/lightdm/slick-greeter.conf"
-    ["lightdm-gtk-greeter"]="/etc/lightdm/lightdm-gtk-greeter.conf"
-    ["io.elementary.greeter"]="/etc/lightdm/io.elementary.greeter.conf"
-    ["lightdm-mini-greeter"]="/etc/lightdm/lightdm-mini-greeter.conf"
-    ["lightdm-qtquick-greeter"]="/etc/lightdm/lightdm-qtquick-greeter.json"
-)
+#== GTk Greeter用の汎用関数 ==#
+# gtk_greeter_get_value <section> <key>
+gtk_greeter_get_value(){
+    crudini --set "${MODE_CONFIG["gtkg"]}" "${1}" "${2}"
+}
+
+# gtk_greeter_set_config <section> <key> <value>
+gtk_greeter_set_config(){
+    crudini --set "${MODE_CONFIG["gtkg"]}" "${1}" "${2}" "${3}"
+}
+
+# gtk_greeter_remove_key <section> <key>
+gtk_greeter_remove_key(){
+    crudini --del "${MODE_CONFIG["gtkg"]}" "${1}" "${2}"
+}
+
+gtk_greeter_init_configs(){
+    check_root
+    if [[ ! -f "${MODE_CONFIG["gtkg"]}" ]]; then
+        mkdir -p "$(dirname "${MODE_CONFIG["gtkg"]}")"
+        touch "${MODE_CONFIG["gtkg"]}"
+    fi
+}
+
+#== GTk Greeter用のコマンド==#
+command_gtk_greeter_gtk_wizard(){
+    local _theme="$(ask_gtk_theme)"
 
-declare -A DISPLAY_MANAGER_CONFIG=(
+    # 結果に応じて処理を実行
+    if [[ -n "${_theme}" ]]; then
+        gtk_greeter_set_config "greeter" "theme-name" "${_theme}"
+    else
+        exit 1
+    fi
+    echo "Changed theme to ${_theme}"
+}
+
+command_gtk_greeter_gtk_change(){
+    if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
+        msg_error "Please specify the theme"
+        exit 1
+    fi
+    if ! printf "%s\n" "$(get_gtk_theme)" | grep -x "${1}" 1> /dev/null 2>&1; then
+        msg_error "${1} was not found."
+        exit 1
+    fi
+    gtk_greeter_set_config "greeter" "theme-name" "${1}"
+}
+
+command_gtk_greeter_icon_wizard(){
+    local icons
+    readarray -t icons < <(get_icon_theme)
+
+    local _icon
+    echo "Please select the icon theme to use."
+    if ! _icon="$(ask_question "${icons[@]}")"; then
+        command_gtk_greeter_icon_wizard
+        exit 0
+    fi
+
+    if [[ -n "${_icon}" ]]; then
+        gtk_greeter_set_config "greeter" "icon-theme-name" "${_icon}"
+    else
+        command_gtk_greeter_icon_wizard
+        exit 0
+    fi
+    echo "Changed icon theme to ${_icon}"
+}
+
+command_gtk_greeter_icon_chenge(){
+    if [[ -z "${1+SET}" ]] || [[ "${1}" = "" ]]; then
+        msg_error "Please specify the icon theme to use."
+        exit 1
+    fi
+    if ! printf "%s\n" "$(get_icon_theme)" | grep -x "${1}" 1> /dev/null 2>&1; then
+        msg_error "${1} was not found."
+        exit 1
+    fi
+    gtk_greeter_set_config "greeter" "icon-theme-name" "${_icon}"
+}
+
+
+#== 設定ファイルのパス ==#
+declare -A MODE_CONFIG=(
     ["lightdm"]="/etc/lightdm/lightdm.conf.d/00-dmc-lightdm.conf"
     ["gdm-dconf"]="/etc/dconf/db/gdm.d/00-dmc-gdm"
     ["gdm-custom"]="/etc/gdm/custom.conf"
     ["sddm"]="/etc/sddm.conf.d/sddm.conf"
     ["lxdm"]="/etc/lxdm/lxdm.conf"
+    ["webkit2"]="/etc/lightdm/lightdm-webkit2-greeter.conf"
+    ["slick"]="/etc/lightdm/slick-greeter.conf"
+    ["gtkg"]="/etc/lightdm/lightdm-gtk-greeter.conf"
+    ["elementary"]="/etc/lightdm/io.elementary.greeter.conf"
+    ["mini"]="/etc/lightdm/lightdm-mini-greeter.conf"
+    ["qtquick"]="/etc/lightdm/lightdm-qtquick-greeter.json"
 )
 
 declare -A MAIN_BINARY=(
@@ -1380,67 +1610,71 @@ declare -A MAIN_BINARY=(
     ["sddm"]="/usr/bin/sddm"
     ["webkit2"]="/usr/bin/lightdm-webkit2-greeter"
     ["slick"]="/usr/bin/slick-greeter"
-    ["gtk"]="/usr/bin/lightdm-gtk-greeter"
+    ["gtkg"]="/usr/bin/lightdm-gtk-greeter"
     ["elementary"]="/usr/bin/io.elementary.greeter"
     ["mini"]="/usr/bin/lightdm-mini-greeter"
     ["qtquick"]="/usr/bin/lightdm-qtquick-greeter"
     ["lxdm"]="/usr/bin/lxdm"
 )
 
+declare -A GREETER_MODE=(
+    ["lightdm-webkit2-greeter"]="webkit2"
+    ["lightdm-slick-greeter"]="slick"
+    ["io.elementary.greeter"]="elementary"
+    ["lightdm-mini-greeter"]="mini"
+    ["lightdm-qtquick-greeter"]="qtquick"
+    ["lightdm-gtk-greeter"]="gtkg"
+)
+
 
 #== CONFIGS ==#
-
 # LightDM - Greeterのディレクトリ
 LIGHTDM_GREETERS_DIR="$(lightdm_get_value "greeters-directory")"
 : "${LIGHTDM_GREETERS_DIR:="/usr/share/xgreeters"}"
 
-# LightDM - Greeter一覧
-#LIGHTDM_GREETERS=( $( )
-while read -r line; do
-    LIGHTDM_GREETERS+=("${line}")
-done < <( (find "${LIGHTDM_GREETERS_DIR}" -print0 -type f | xargs -0 -i basename {} | grep -E ".desktop$" | sed "s|.desktop$||g" | grep -xv "xgreeters") 2> /dev/null )
-
 # LightDM - 現在設定されているGreeter
 LIGHTDM_CURRENT_GREETER="$(lightdm --show-config 2>&1 | grep "greeter-session" | cut -d "=" -f 2)"
 : "${LIGHTDM_CURRENT_GREETER:="lightdm-gtk-greeter"}"
 
-# LightDM - 読み込まれた設定ファイルの一覧
-while read -r line; do
-    LIGHTDM_LOADED_CONFIG+=("${line}")
-done < <(printf "%s\n" "$(lightdm --show-config 2>&1 | grep -x -A "$(lightdm --show-config 2>&1 | wc -l)" "Sources:" | grep -v "Sources" | sed 's|^[A-Z]  ||g')"  | tr -d " ")
-
 # Global - エディタ
 USE_EDITOR="${EDITOR:-vi}"
 
+# Global - 背景画像をコピーするディレクトリ
+BACKGROUND_DIR="/usr/share/backgrounds"
+
 # Global - 現在のディスプレイマネージャ名
-CURRENT_DM="$(basename "$(readlink "/etc/systemd/system/display-manager.service")" | sed "s|.service$||g")"
+if [[ -f "/etc/systemd/system/display-manager.service" ]]; then
+    CURRENT_DM="$(basename "$(readlink "/etc/systemd/system/display-manager.service")" | sed "s|.service$||g")"
+else
+    CURRENT_DM=""
+fi
 
 # モード
-DISPLAY_MANAGER="${CURRENT_DM}"
-: "${DISPLAY_MANAGER:="lightdm"}"
+MODE="${CURRENT_DM}"
+: "${MODE:="lightdm"}"
 
 # dmc config
 NON_INTERACTIVE=false
 WRITE_ALL_FILES=false
 NOROOT=false
 NO_CHECK_TARGET=false
+REMOVE_FILES=false
 
 #== 引数解析 ==#
-ARGUMENT="${*}"
-OPTS="m:e:h"
-OPTL="mode:,editor:,help,non-interactive,noroot,write-all-files,no-check-target"
-# shellcheck disable=SC2086
-if ! OPT="$(getopt -o ${OPTS} -l ${OPTL} -- ${ARGUMENT})"; then
+ARGUMENT=("${@}")
+OPTS=("m:" "e:" "h" "G")
+OPTL=("mode:" "editor:" "help" "non-interactive" "noroot" "write-all-files" "no-check-target" "lightdm-greeter" "remove")
+if ! readarray -t OPT < <(getopt -o "$(printf "%s," "${OPTS[@]}")" -l "$(printf "%s," "${OPTL[@]}")" -- "${ARGUMENT[@]}"); then
     exit 1
 fi
 
-eval set -- "${OPT}"
+eval set -- "${OPT[@]}"
 unset OPT OPTS OPTL
 
 while true; do
     case "${1}" in
         -m | --mode)
-            DISPLAY_MANAGER="${2}"
+            MODE="${2}"
             shift 2
             ;;
         -e | --editor)
@@ -1451,6 +1685,15 @@ while true; do
             script_usage
             exit 0
             ;;
+        -G | --lightdm-greeter)
+            if [[ -n "${LIGHTDM_CURRENT_GREETER+SET}" ]]; then
+                MODE="${GREETER_MODE["${LIGHTDM_CURRENT_GREETER}"]}"
+            else
+                msg_error "Failed to get the currently running Greeter."
+                exit 1
+            fi
+            shift 1
+            ;;
         --non-interactive)
             NON_INTERACTIVE=true
             shift 1
@@ -1467,6 +1710,10 @@ while true; do
             WRITE_ALL_FILES=true
             shift 1
             ;;
+        --remove)
+            REMOVE_FILES=true
+            shift 1
+            ;;
         --)
             shift 1
             break
@@ -1479,8 +1726,8 @@ COMMAND="${1:-null}"
 if (( "${#}" >= 1 )); then
     shift 1
 fi
-COMMAND_ARGS="${*}"
-: "${COMMAND_ARGS-""}" # サブコマンドの引数が何も指定されなかった場合に空文字を代入
+COMMAND_ARGS=("${@}")
+: "${COMMAND_ARGS=""}" # サブコマンドの引数が何も指定されなかった場合に空文字を代入
 
 if [[ "${COMMAND}" = "null" ]]; then
     script_usage
@@ -1492,129 +1739,259 @@ if [[ "${NO_CHECK_TARGET}" = false ]]; then
     check_main_binary
 fi
 
+# 依存コマンドの確認
+ check_tools "jq" "crudini"
+
 # コマンドとモードに応じて関数を実行する
 case "${COMMAND}" in
+    "accessibility")
+        check_command_dm "gdm"
+        gdm_init_configs
+        command_gdm_accessibility "${COMMAND_ARGS[@]}"
+        ;;
     "autologin")
         check_command_dm "lightdm" "gdm" "sddm" "lxdm"
-        case "${DISPLAY_MANAGER}" in
+        case "${MODE}" in
             "lightdm")
                 lightdm_init_configs
-                command_lightdm_auto_login "${COMMAND_ARGS}"
+                command_lightdm_auto_login "${COMMAND_ARGS[@]}"
+                ;;
+            "gdm")
+                gdm_init_configs
+                command_gdm_auto_login "${COMMAND_ARGS[@]}"
+                ;;
+            "sddm")
+                sddm_init_configs
+                command_sddm_auto_login "${COMMAND_ARGS[@]}"
+                ;;
+            "lxdm")
+                lxdm_init_configs
+                command_lxdm_auto_login "${COMMAND_ARGS[@]}"
+                ;;
+        esac
+        ;;
+    "back")
+        check_command_dm "qtquick" "slick" "lxdm"
+        case "${MODE}" in
+            "qtquick")
+                qtquick_init_configs
+                command_qtquick_back "${COMMAND_ARGS[@]}"
+                ;;
+            "slick")
+                slick_init_configs
+                command_slick_back "${COMMAND_ARGS[@]}"
+                ;;
+            "back")
+                lxdm_init_configs
+                command_lxdm_back "${COMMAND_ARGS[@]}"
                 ;;
+        esac
+        ;;
+    "cursor")
+        check_command_dm "gdm" "sddm"
+        case "${MODE}" in
             "gdm")
                 gdm_init_configs
-                command_gdm_auto_login "${COMMAND_ARGS}"
+                command_gdm_cursor_wizard
                 ;;
             "sddm")
                 sddm_init_configs
-                command_sddm_auto_login "${COMMAND_ARGS}"
+                command_sddm_cursor_wizard
+                ;;
+        esac
+        ;;
+    "cursor-change")
+        check_command_dm "gdm" "sddm"
+        case "${MODE}" in
+            "gdm")
+                gdm_init_configs
+                command_gdm_cursor_change "${COMMAND_ARGS[@]}"
+                ;;
+            "sddm")
+                sddm_init_configs
+                command_sddm_cursor_change "${COMMAND_ARGS[@]}"
+                ;;
+        esac
+        ;;
+    "debug")
+        check_comamnd_dm "webkit2"
+        command_webkit2_debug "${COMMAND_ARGS[@]}"
+        ;;
+    "dm")
+        command_general_dm "${COMMAND_ARGS[@]}"
+        ;;
+    "edit")
+        check_command_dm "lightdm" "gdm"
+        case "${MODE}" in
+            "lightdm")
+                check_root
+                command_lightdm_edit
+                ;;
+            "gdm")
+                gdm_init_configs
+                command_gdm_edit
+                ;;
+        esac
+        ;;
+    "edit-script")
+        check_command_dm "lxdm"
+        lxdm_init_configs
+        comamnd_lxdm_edit_script
+        ;;
+    "gtk")
+        check_command_dm "slick" "lxdm" "gtkg"
+        case "${MODE}" in
+            "slick")
+                slick_init_configs
+                command_slick_gtk_wizard
                 ;;
             "lxdm")
                 lxdm_init_configs
-                command_lxdm_auto_login "${COMMAND_ARGS}"
+                command_lxdm_gtk_wizard
+                ;;
+            "gtkg")
+                gtk_greeter_init_configs
+                command_gtk_greeter_gtk_wizard
                 ;;
         esac
         ;;
     "greeter")
         check_command_dm "lightdm"
         lightdm_init_configs
-        run_greeter_wizard
+        command_lightdm_greeter_wizard
         ;;
     "greeter-change")
         check_command_dm "lightdm"
         lightdm_init_configs
-        command_lightdm_greeter_change "${COMMAND_ARGS}"
+        command_lightdm_greeter_change "${COMMAND_ARGS[@]}"
         ;;
     "greeter-create")
         check_command_dm "lightdm"
         lightdm_init_configs
-        command_lightdm_greeter_create "${COMMAND_ARGS}"
-        ;;
-    "greeter-list")
-        check_command_dm "lightdm"
-        command_lightdm_greeter_list
+        command_lightdm_greeter_create "${COMMAND_ARGS[@]}"
         ;;
     "greeter-edit")
         check_command_dm "lightdm"
         check_root
-        command_lightdm_greeter_edit "${COMMAND_ARGS}"
+        command_lightdm_greeter_edit "${COMMAND_ARGS[@]}"
         ;;
-    "remove")
-        check_command_dm "lightdm"
-        check_root
-        command_lightdm_remove
-        ;;
-    "edit")
+    "greeter-list")
         check_command_dm "lightdm"
-        check_root
-        command_lightdm_edit
+        command_lightdm_greeter_list
         ;;
-    "show-config")
-        check_command_dm "lightdm"
-        command_lightdm_show_config
+
+    "grid")
+        check_command_dm "slick"
+        slick_init_configs
+        command_slick_grid "${COMMAND_ARGS[@]}"
         ;;
-    "cursor")
-        check_command_dm "gdm" "sddm"
-        case "${DISPLAY_MANAGER}" in
-            "gdm")
-                gdm_init_configs
-                command_gdm_cursor_wizard
+    "gtk-change")
+        check_command_dm "slick" "lxdm" "gtkg"
+        case "${MODE}" in
+            "slick")
+                slick_init_configs
+                command_slick_gtk_change "${COMMAND_ARGS[@]}"
                 ;;
-            "sddm")
-                sddm_init_configs
-                command_sddm_cursor_wizard
+            "lxdm")
+                command_lxdm_gtk_change "${COMMAND_ARGS[@]}"
+                ;;
+            "gtkg")
+                command_gtk_greeter_gtk_change "${COMMAND_ARGS[@]}"
                 ;;
         esac
         ;;
-    "cursor-change")
-        check_command_dm "gdm" "sddm"
-        case "${DISPLAY_MANAGER}" in
-            "gdm")
-                gdm_init_configs
-                command_gdm_cursor_change "${COMMAND_ARGS}"
+    "icon")
+        check_command_dm "slick" "gtkg"
+        case "${MODE}" in
+            "slick")
+                slick_init_configs
+                command_slick_icon_wizard
                 ;;
-            "sddm")
-                sddm_init_configs
-                command_sddm_cursor_change "${COMMAND_ARGS}"
+            "gtkg")
+                gtk_greeter_init_configs
+                command_gtk_greeter_icon_wizard
                 ;;
         esac
         ;;
-    "sound")
-        check_command_dm "gdm"
-        gdm_init_configs
-        command_gdm_sound "${COMMAND_ARGS}"
+    "icon-change")
+        check_command_dm "slick" "gtkg"
+        case "${MODE}" in
+            "slick")
+                slick_init_configs
+                command_slick_icon_chenge "${COMMAND_ARGS[@]}"
+                ;;
+            "gtkg")
+                gtk_greeter_init_configs
+                command_gtk_greeter_icon_chenge "${COMMAND_ARGS[@]}"
+                ;;
+        esac
         ;;
     "logo")
         check_command_dm "gdm" "slick"
-        case "${DISPLAY_MANAGER}" in
+        case "${MODE}" in
             "gdm")
                 gdm_init_configs
-                command_gdm_logo "${COMMAND_ARGS}"
+                command_gdm_logo "${COMMAND_ARGS[@]}"
                 ;;
             "slick")
                 slick_init_configs
-                command_slick_logo "${COMMAND_ARGS}"
+                command_slick_logo "${COMMAND_ARGS[@]}"
                 ;;
         esac
         ;;
-    "tap")
+    "numlock")
+        check_command_dm "sddm"
+        sddm_init_configs
+        command_sddm_numlock "${COMMAND_ARGS[@]}"
+        ;;
+    "other-monitor")
+        check_command_dm "slick"
+        slick_init_configs
+        command_slick_other_monitor "${COMMAND_ARGS[@]}"
+        ;;
+    "remove")
+        check_command_dm "lightdm" "gdm" "webkit2" "qtquick"
+        check_root
+        eval "command_${MODE}_remove"
+        ;;
+    "remove-last")
+        check_command_dm "lxdm"
+        lxdm_init_configs
+        command_lxdm_remove_last
+        ;;
+    "root-login")
         check_command_dm "gdm"
         gdm_init_configs
-        command_gdm_tap "${COMMAND_ARGS}"
+        command_gdm_root_login "${COMMAND_ARGS[@]}"
         ;;
-    "accessibility")
+    "session")
+        check_command_dm "lxdm"
+        lxdm_init_configs
+        command_lxdm_session_wizard
+        ;;
+    "session-change")
+        check_command_dm "lxdm"
+        lxdm_init_configs
+        command_lxdm_session_change "${COMMAND_ARGS[@]}"
+        ;;
+    "show-config")
+        check_command_dm "lightdm"
+        command_lightdm_show_config
+        ;;
+
+    "sound")
         check_command_dm "gdm"
         gdm_init_configs
-        command_gdm_accessibility "${COMMAND_ARGS}"
+        command_gdm_sound "${COMMAND_ARGS[@]}"
         ;;
-    "root-login")
+    "tap")
         check_command_dm "gdm"
         gdm_init_configs
-        command_gdm_root_login "${COMMAND_ARGS}"
+        command_gdm_tap "${COMMAND_ARGS[@]}"
         ;;
     "theme")
         check_command_dm "webkit2" "sddm"
-        case "${DISPLAY_MANAGER}" in
+        case "${MODE}" in
             "webkit2")
                 webkit2_init_configs
                 command_webkit2_theme_wizard
@@ -1627,10 +2004,10 @@ case "${COMMAND}" in
         ;;
     "theme-change")
         check_command_dm "webkit2" "sddm"
-        case "${DISPLAY_MANAGER}" in
+        case "${MODE}" in
             "webkit2")
                 webkit2_init_configs
-                command_webkit2_theme_change "${COMMAND_ARGS}"
+                command_webkit2_theme_change "${COMMAND_ARGS[@]}"
                 ;;
             "sddm")
                 sddm_init_configs
@@ -1638,92 +2015,21 @@ case "${COMMAND}" in
                 ;;
         esac
         ;;
-    "gtk")
-        check_command_dm "slick" "lxdm"
-        case "${DISPLAY_MANAGER}" in
-            "slick")
-                slick_init_configs
-                command_slick_gtk_wizard
-                ;;
-            "lxdm")
-                lxdm_init_configs
-                command_lxdm_gtk_wizard
-                ;;
-        esac
-        ;;
-    "gtk-change")
-        check_command_dm "slick" "lxdm"
-        case "${DISPLAY_MANAGER}" in
-            "slick")
-                slick_init_configs
-                command_slick_gtk_change "${COMMAND_ARGS}"
-                ;;
-            "lxdm")
-                command_lxdm_gtk_change "${COMMAND_ARGS}"
-                ;;
-        esac
-        ;;
-    "back")
-        check_command_dm "qtquick" "slick" "lxdm"
-        case "${DISPLAY_MANAGER}" in
-            "qtquick")
-                qtquick_init_configs
-                command_qtquick_back "${COMMAND_ARGS}"
-                ;;
-            "slick")
-                slick_init_configs
-                command_slick_back "${COMMAND_ARGS}"
-                ;;
-            "back")
-                lxdm_init_configs
-                command_lxdm_back "${COMMAND_ARGS}"
-                ;;
-        esac
-        ;;
-    "grid")
-        check_command_dm "slick"
-        slick_init_configs
-        command_slick_grid "${COMMAND_ARGS}"
-        ;;
-    "icon")
-        check_command_dm "slick"
-        slick_init_configs
-        command_slick_icon_wizard
-        ;;
-    "other-monitor")
-        check_command_dm "slick"
-        slick_init_configs
-        command_slick_other_monitor "${COMMAND_ARGS}"
-        ;;
-    "numlock")
-        check_command_dm "sddm"
-        sddm_init_configs
-        command_sddm_numlock "${COMMAND_ARGS}"
-        ;;
     "tty")
         check_command_dm "sddm"
         sddm_init_configs
-        command_sddm_tty "${COMMAND_ARGS}"
+        command_sddm_tty "${COMMAND_ARGS[@]}"
         ;;
-    "session")
-        check_command_dm "lxdm"
-        lxdm_init_configs
-        command_lxdm_session_wizard
-        ;;
-    "session-change")
-        check_command_dm "lxdm"
-        lxdm_init_configs
-        command_lxdm_session_change "${COMMAND_ARGS}"
+    "gtk-list")
+        get_gtk_theme
+        exit 0
         ;;
-    "remove-last")
-        check_command_dm "lxdm"
-        lxdm_init_configs
-        command_lxdm_remove_last
+    "lightdm" | "gdm" | "sddm" | "lxdm" | "webkit2" | "qtquick" | "slick" | "gtkg")
+        command_mode "${COMMAND}" "${COMMAND_ARGS[@]}"
         ;;
-    "edit-script")
-        check_command_dm "lxdm"
-        lxdm_init_configs
-        comamnd_lxdm_edit_script
+    "help")
+        script_usage
+        exit 0
         ;;
     *)
         msg_error "This command cannot be used in any mode"