Проблема с изменением обоев при наведении на имена в Rofi — в чём моя ошибка?

Вопрос или проблема

Я написал скрипт для изменения обоев с помощью 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. Вместо динамической смены обоев на каждом "ховере", реализуйте смену обоев только после окончательной фиксации выбора.

Шаги решения

  1. Измените управление потоком ввода: Вместо использования while цикла, просто получите один окончательный выбор из Rofi и обработайте его.

  2. Смещение логики предварительного отображения: Логика "предварительного" изменения обоев должна быть вообще убрана. Необходимо сохранять фокус только на финальной установке обоев.

  3. Использование вспомогательной функции: Вспомогательная функция может помочь управлять установкой выбранных обоев только при выполнении окончательного подтверждения.

Ниже представлено примерное решение:

#!/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!

Оцените материал
Добавить комментарий

Капча загружается...