Вопрос или проблема
Я написал скрипт для изменения обоев с помощью Rofi, но у меня возникла проблема. Пока я навожу курсор на названия обоев в меню rofi, обои не меняются динамически для временного предпросмотра (как я ожидал). Между тем, я хочу, чтобы обои менялись только после того, как я выберу нужные, а не во время просмотра.
Вот скрипт, который я использую:
#!/bin/bash
WALLPAPER_DIR="$HOME/Pictures/Wallpapers"
# Функция форматирования названий обоев для отображения
format_name() {
basename "$1" | sed -E 's/[0-9]+[kK]?[- ]?[0-9]*[a-z]*//g; s/-/ /g; s/\.(jpg|png|jpeg)$//I; s/\b([a-z])/\u\1/g; s/\s+/ /g; s/^\s+|\s+$//g'
}
# Получить список обоев и отформатировать их
mapfile -t wallpapers < <(find "$WALLPAPER_DIR" -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \))
formatted_names=()
для wp в "${wallpapers[@]}"; do
formatted_names+=("$(format_name "$wp")")
done
# Сохранить текущие обои
current_wallpaper=$(grep 'feh --bg-scale' ~/.fehbg | cut -d "'" -f2)
# Пусть rofi покажет и захватит выбор в реальном времени
selection=$(printf "%s\n" "${formatted_names[@]}" | rofi -dmenu -i -p "Select Wallpaper" -format "s" -monitor-changes | while read -r selected_name; do
for wp in "${wallpapers[@]}"; do
if [ "$(format_name "$wp")" == "$selected_name" ]; then
# Временно менять обои, пока пользователь просматривает
feh --bg-scale "$wp"
break
fi
done
done)
# Вернуть предыдущие обои, если окончательный выбор не сделан
if [ -z "$selection" ]; then
[ -n "$current_wallpaper" ] && feh --bg-scale "$current_wallpaper"
fi
Я пробовал некоторые решения, но не знаю, в чем моя ошибка. Есть ли простой способ избежать временного изменения обоев до окончательного выбора? Любая помощь будет признательна... О, и я использую Arch (кстати). :v
Ответ или решение
Похоже, у вас возникла проблема с динамической сменой обоев при использовании меню Rofi. Хотя вы хотите, чтобы обои менялись только после окончательного выбора, ваш текущий скрипт заставляет их меняться временно, как только вы наводите курсор на имя обоев. Давайте разберёмся, что именно происходит и как это можно исправить.
Теория
Прежде всего, полезно понять, как работает ваш текущий скрипт и почему он ведет себя так, как вы описали. Rofi — это инструмент запуска меню и приложений, который выводит список опций и позволяет пользователю выбрать одну из них. Ваш скрипт использует его для отображения списка обоев, используя rofi -dmenu
для создания меню с опциями. За каждой опцией скрывается команда смены обоев при наведении, которая реализована с помощью feh --bg-scale
. В данном случае, feh
назначает выбранные обои как фон рабочего стола.
Основная проблема в вашем коде кроется в том факте, что вы используете механизм "онлайн"-изменения обоев при каждой итерации while read -r selected_name; do ... done
. Как только rofi
замечает изменения, ваш цикл запускает feh
для каждой строки прочитанного ввода, изменяя фон рабочего стола временно.
Пример
Рассмотрим следующий кусок кода:
selection=$(printf "%s\n" "${formatted_names[@]}" | rofi -dmenu -i -p "Select Wallpaper" -format "s" -monitor-changes | while read -r selected_name; do
for wp in "${wallpapers[@]}"; do
if [ "$(format_name "$wp")" == "$selected_name" ]; then
feh --bg-scale "$wp"
break
fi
done
done)
Этот блок кода вызывает feh --bg-scale "$wp"
каждый раз, когда вы наводите курсор на новый элемент в меню Rofi. Это поведение реализовано через цикл while
, ожидающий ввода от rofi
и тут же меняющий фон обоев.
Применение
Чтобы добиться вашего желаемого поведения, необходимо изменить подход к использованию Rofi. Вместо динамической смены обоев на каждом "ховере", реализуйте смену обоев только после окончательной фиксации выбора.
Шаги решения
-
Измените управление потоком ввода: Вместо использования
while
цикла, просто получите один окончательный выбор из Rofi и обработайте его. -
Смещение логики предварительного отображения: Логика "предварительного" изменения обоев должна быть вообще убрана. Необходимо сохранять фокус только на финальной установке обоев.
-
Использование вспомогательной функции: Вспомогательная функция может помочь управлять установкой выбранных обоев только при выполнении окончательного подтверждения.
Ниже представлено примерное решение:
#!/bin/bash
WALLPAPER_DIR="$HOME/Pictures/Wallpapers"
format_name() {
basename "$1" | sed -E 's/[0-9]+[kK]?[- ]?[0-9]*[a-z]*//g; s/-/ /g; s/\.(jpg|png|jpeg)$//I; s/\b([a-z])/\u\1/g; s/\s+/ /g; s/^\s+|\s+$//g'
}
mapfile -t wallpapers < <(find "$WALLPAPER_DIR" -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \))
formatted_names=()
for wp in "${wallpapers[@]}"; do
formatted_names+=("$(format_name "$wp")")
done
current_wallpaper=$(grep 'feh --bg-scale' ~/.fehbg | cut -d "'" -f2)
# Let rofi show and capture the final selection
selected_name=$(printf "%s\n" "${formatted_names[@]}" | rofi -dmenu -i -p "Select Wallpaper")
if [[ -n "$selected_name" ]]; then
for wp in "${wallpapers[@]}"; do
if [ "$(format_name "$wp")" == "$selected_name" ]; then
# Change wallpaper permanently
feh --bg-scale "$wp"
break
fi
done
else
# Revert to previous wallpaper if no selection
[ -n "$current_wallpaper" ] && feh --bg-scale "$current_wallpaper"
fi
Заключение
Этот скрипт решает вашу проблему путем удаления логики динамической смены обоев. Теперь фоновое изображение экрана будет изменяться только после того, как будет сделан окончательный выбор. Таким образом, ваше рабочее окружение будет вести себя предсказуемо, и вам не придется возвращаться к предыдущим настройкам каждый раз, когда вы не делаете выбор. Удачи с управлением вашим рабочим пространством на Arch Linux!