Имитация динамических обоев из macOS штатными средствами Linux-систем

Принцип их работы весьма прост. Основан он на способности оконных менеджеров (WM) многих популярных окружений рабочего стола (DE) отслеживать изменения выбранного файла обоев.


В качестве обоев устанавливается только один файл картинки. Используемый файл обоев является символической ссылкой на другую картинку. Ступенчатая "динамичность" обоев обеспечивается заменой картинки-ссылки на новую в нужные моменты времени. В эти же моменты WM замечает изменение файла обоев и обновляет картинку.


Таким образом, WM постоянно работает с одним и тем же файлом-картинкой, а вся логика работы обеспечивается обычным сценарием командной строки и простыми файловыми операциями.


Предыстория создания


Концепцию динамических обоев подглядел ещё в macOS Mojave. Сразу захотел себе такие же.


Что требовалось от обоев:


  • смена соответственно времени дня,
  • возможность точного задания времени смены обоев,
  • минимум внешних зависимостей,
  • автономная работа,
  • нечувствительность к перезагрузкам и системным сбоям,
  • минимальная нагрузка на систему,
  • простота обслуживания и гибкость настройки.

В ходе поисков найдены несколько путей достижения цели:


  • Установка сторонних программ. Мало где поддерживается точное задание времени, тянутся внешние зависимости, и что-то постоянно будет висеть в фоне.
  • Видеообои или gif. Сложно и ресурсоёмко.
  • XML-слайдшоу для GNOME. Основан на периодичном отсчёте интервалов в секундах от 11.02.2014. Способ немного топорный и заточен под среду GNOME и её fork'и. Для другого набора обоев придётся заново пересчитывать секунды.
  • Взять за основу готовый набор обоев, а логику работы воплощать самому. Вызов принят :)

Статью пишу как памятку для себя и дань благодарности сообществу Хабра, благодаря которому вырос как специалист в своей сфере.


А у меня заработает?


Ваш WM должен уметь следить за используемым файлом обоев. Это можно легко проверить так:


  1. Скопируйте какую-нибудь картинку в корень своего домашнего каталога.
  2. Измените имя картинки на какое-нибудь простое. Например "pic1".
  3. Назначьте картинку обоями рабочего стола.
  4. Удалите картинку.
  5. Скопируйте другую картинку в корень своего домашнего каталога.
  6. Дайте ей имя удалённой ранее картинки.
  7. Посмотрите на обои рабочего стола. Если они соответствуют новой картинке, то у вас всё заработает.
  8. Верните прежние обои.

В ролях


Динамические обои будут использовать 5 штатных утилит Linux-систем:


  • date — получение текущего времени;
  • rm — удаление файлов;
  • ls — создание ссылок на файлы;
  • сron — выполнение команд по расписанию;
  • bash — исполнение стартового сценария обоев.

Ничего дополнительно устанавливать не нужно.


Предостережения для опытных


Нижеследующие инструкции по установке и удалению обоев предполагают, что вы ещё не работали с Crontab в своей системе. Если же вы уже работали c Cron и у вас есть настроенная под себя таблица Cron, то вместо установки или восстановления таблицы просто открывайте её через crontab -e и добавляйте или убирайте дополнительные строки из приведённого crontab.txt в своей crontab в любом удобном текстовом редакторе.


Для сохранности вашей системы и данных других её пользователей все приведённые ниже команды выполняйте только от имени своего пользователя. Привилегии суперпользователя не требуются.


Установка


1) Создайте папку для обоев:


mkdir $HOME/.mojave_dynamic

2) Загрузите набор обоев и извлеките из полученного архива 16 файлов формата .jpeg в папку .mojave_dynamic. Для Вашего удобства папка обоев скрыта. Поэтому, если её не видно, включите отображение скрытых файлов (обычно, это Ctrl+h).
Пакет обоев любезно предоставлен всем желающим пользователем Reddit randybruder.


3) Создайте картинку-ссылку в папке .mojave_dynamic:


ln -s $HOME/.mojave_dynamic/mojave_dynamic_1.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg

4) Создайте в той же папке обычный текстовый файл:


touch $HOME/.mojave_dynamic/crontab.txt

Скопируйте в него текст из-под спойлера, оставьте после него пустую строку и сохраните:


crontab.txt
# Динамические обои
# Установка обоев после запуска системы
@reboot bash $HOME/.mojave_dynamic/mojave_dynamic_init.sh
# Смена обоев по расписанию
# Справка по формату файла: https://www.opennet.ru/man.shtml?topic=crontab&category=8&russian=0
# 6:00 №1
0 6 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_1.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 6:30 №2
30 6 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_2.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 7:00 №3
0 7 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_3.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 7:30 №4
30 7 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_4.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 8:00 №5
0 8 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_5.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 10:30 №6
30 10 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_6.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 13:00 №7
0 13 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_7.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 15:30 №8
30 15 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_8.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 18:00 №9
0 18 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_9.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 18:30 №10
30 18 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_10.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 19:00 №11
0 19 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_11.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 19:30 №12
30 19 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_12.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 20:00 №13
0 20 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_13.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 22:30 №14
30 22 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_14.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 01:00 №15
0 1 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_15.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg
# 03:30 №16
30 3 * * * rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg ; ln -s $HOME/.mojave_dynamic/mojave_dynamic_16.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg

Пустая строка в конце файла должна быть обязательно. Иначе на следующем шаге Crontab напомнит вам об этом.


Сразу после старта системы Сron запускает сценарий Bash для начальной установки обоев с их каталогом в качестве рабочего. Без стартового сценария нам пришлось бы ждать смены обоев на подходящие до начала следующего промежутка в расписании (от 30 минут до 2,5 часов).


В остальное время Cron в нужные моменты заменяет текущую картинку-ссылку подходящей для следующего промежутка времени. Моменты смены обоев взяты с официальной презентационной страницы macOS Mojave. Для этого достаточно поиграться с ползунком, поглядывая на часы MacBook'а.


5) Установите из crontab.txt управляющую таблицу Сron для своей учётной записи:


crontab -u $USER ~/.mojave_dynamic/crontab.txt

6) Создайте файл стартового сценария обоев:


touch $HOME/.mojave_dynamic/mojave_dynamic_init.sh

Скопируйте в него текст из-под спойлера и сохраните:


mojave_dynamic_init.sh
#!/bin/bash

# Получить текущее время в формате "ЧЧММ"
currentTime=$(date +%H%M)

# Расписание обоев
# Номера обоев:
#              1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16
# Моменты времени смены обоев:
wallpaperTime=(0600 0630 0700 0730 0800 1030 1300 1530 1800 1830 1900 1930 2000 2230 0100 0330)
# Элементы массива моментов времени:
#              0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15

# Выбор номера обоев для текущего промежутка времени
# Правило:     С (>=) [времяНачала]                           по (<) [времяОкончания]           показывать обои No
[ "$currentTime" -ge "${wallpaperTime[0]}" ] && [ "$currentTime" -lt "${wallpaperTime[1]}" ] && wallpaperNumber=1
[ "$currentTime" -ge "${wallpaperTime[1]}" ] && [ "$currentTime" -lt "${wallpaperTime[2]}" ] && wallpaperNumber=2
[ "$currentTime" -ge "${wallpaperTime[2]}" ] && [ "$currentTime" -lt "${wallpaperTime[3]}" ] && wallpaperNumber=3
[ "$currentTime" -ge "${wallpaperTime[3]}" ] && [ "$currentTime" -lt "${wallpaperTime[4]}" ] && wallpaperNumber=4
[ "$currentTime" -ge "${wallpaperTime[4]}" ] && [ "$currentTime" -lt "${wallpaperTime[5]}" ] && wallpaperNumber=5
[ "$currentTime" -ge "${wallpaperTime[5]}" ] && [ "$currentTime" -lt "${wallpaperTime[6]}" ] && wallpaperNumber=6
[ "$currentTime" -ge "${wallpaperTime[6]}" ] && [ "$currentTime" -lt "${wallpaperTime[7]}" ] && wallpaperNumber=7
[ "$currentTime" -ge "${wallpaperTime[7]}" ] && [ "$currentTime" -lt "${wallpaperTime[8]}" ] && wallpaperNumber=8
[ "$currentTime" -ge "${wallpaperTime[8]}" ] && [ "$currentTime" -lt "${wallpaperTime[9]}" ] && wallpaperNumber=9
[ "$currentTime" -ge "${wallpaperTime[9]}" ] && [ "$currentTime" -lt "${wallpaperTime[10]}" ] && wallpaperNumber=10
[ "$currentTime" -ge "${wallpaperTime[10]}" ] && [ "$currentTime" -lt "${wallpaperTime[11]}" ] && wallpaperNumber=11
[ "$currentTime" -ge "${wallpaperTime[11]}" ] && [ "$currentTime" -lt "${wallpaperTime[12]}" ] && wallpaperNumber=12
[ "$currentTime" -ge "${wallpaperTime[12]}" ] && [ "$currentTime" -lt "${wallpaperTime[13]}" ] && wallpaperNumber=13
[ "$currentTime" -ge "${wallpaperTime[13]}" ] || [ "$currentTime" -lt "${wallpaperTime[14]}" ] && wallpaperNumber=14 # || -- Смена дня
[ "$currentTime" -ge "${wallpaperTime[14]}" ] && [ "$currentTime" -lt "${wallpaperTime[15]}" ] && wallpaperNumber=15
[ "$currentTime" -ge "${wallpaperTime[15]}" ] && [ "$currentTime" -lt "${wallpaperTime[0]}" ] && wallpaperNumber=16 # 15-0 -- Закольцовывание времени

# Назначить выбранные обои
rm $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg #удалить символическую ссылку на текущие обои
#     источник ссылки                                            назначение ссылки
ln -s $HOME/.mojave_dynamic/mojave_dynamic_$wallpaperNumber.jpeg $HOME/.mojave_dynamic/mojave_dynamic_x.jpeg #создать символическую ссылку на новые обои

# Убрать использованные переменные
unset currentTime
unset wallpaperNumber
unset wallpaperTime

exit 0

Сначала сценарий получает текущее время в удобном для дальнейшей обработки формате. Расписание смены обоев разворачивается в массив. Далее сценарий определяет среди всех промежутков времени текущий, сравнивая текущее время с их границами. Файл обоев заменяется ссылкой на картинку обоев, которая по номеру соответствует текущему промежутку времени. В конце работы стартовый сценарий "прибирается" за собой.


В блоке выбора времени две строки отличаются от других для обеспечения совместимости с предоставленным пакетом обоев и реальным течением времени.


7) Назначьте файл mojave_dynamic_x.jpeg фоновым изображением рабочего стола обычным для вашего DE способом. Например, для XFCE4 это ПКМ -> Сделать фоновым изображением. Динамические обои установлены и запущены.


Результат


Пример момента смены обоев

Смена обоев в 18:30


В ходе испытаний на слабом Atom'ном нетбуке обои сменялись с задержкой в 4 секунды.


В целом, представленный способ может быть адаптирован для любого другого набора обоев и расписания их переключения. Расписание смены динамических обоев можно настраивать, согласованно редактируя и таблицу Cron (через crontab -e), и файл стартового сценария mojave_dynamic_init.sh.


О своих действиях crontab отчитывается в syslog, а значит проверить "самочувствие" наших динамических обоев можно так:


cat /var/log/syslog | grep crontab | tail

Удаление


1) Восстановите исходную таблицу Cron:


crontab -r

2) Поменяйте обои на новые


3) Удалите папку динамических обоев:


rm -rf  $HOME/.mojave_dynamic

Заключение


Работоспособность описанного метода успешно испытана на Debian 10 и Ubuntu 18.04 в окружениях XFCE4, GNOME3 и KDE5. Буду признателен если кто-нибудь подтвердит это для других дистрибутивов и DE. Метод может заработать и на BSD, так как его работоспособность зависит от используемого WM и поддержки символических ссылок файловой системой.

Tags:
обои, linux, bash, скрипты, diy

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.