Как стать автором
Обновить

Имитация динамических обоев из 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 и поддержки символических ссылок файловой системой.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.