Вопрос или проблема
Я написал этот скрипт, когда кнопка увеличения громкости нажата для отображения уведомлений рабочего стола с помощью “notify-send”.
Когда кнопка нажата:
notify-send "Current volume 'pamixer --get-volume'"
Проблема в том, что уведомления накладываются друг на друга, например:
Есть ли способ предотвратить наложение уведомлений и просто отображать последнее уведомление?
Редактировать: notify-send
теперь имеет опцию -p
или --print-id
для вывода идентификатора, но я оставлю ответ ниже в качестве примера, как это сделано на Python.
API уведомлений имеет средство для указания идентификатора текущего уведомления, которое должно быть обновлено вместо создания нового всплывающего окна, но notify-send
этого не предоставляет. Если вы готовы использовать небольшое количество python, вы можете получить идентификатор уведомления, когда его создаете, а затем попытаться обновить этот идентификатор позже. Поместите следующий код на python2 в файл в директорию, которая находится в вашем PATH, скажем mynotify-send
, и выполните chmod +x mynotify-send
:
#!/usr/bin/python
import argparse, gi
#gi.require_version('Notify', '0.7')
from gi.repository import Notify
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--message', default="body")
parser.add_argument('-i', '--id', type=int)
return parser.parse_args()
def run(myid,message):
Notify.init("mynote")
obj = Notify.Notification.new("my summary", message)
obj.set_timeout(60*1000)
if myid:
obj.set_property('id', myid)
obj.show()
newid = obj.get_property('id')
print newid
else:
obj.show()
myid = obj.get_property('id')
print myid
def main():
options = parse_args()
run(options.id, options.message)
main()
Вы также должны установить python-gobject
. Когда вы выполните
mynotify-send -m 'message 1'
должно всплыть уведомление, но также будет выведен идентификатор в stdout. Часто это просто небольшое число, обозначающее количество уведомлений, например 6
. Вы можете затем изменить сообщение в существующем всплывающем окне, добавив этот идентификатор:
mynotify-send --id 6 -m 'message 2'
Вы можете делать это до тех пор, пока всплывающее окно существует. После того как всплывающее окно исчезает, следующее сообщение получит новый идентификатор, например 7
, который выведет программа, и вам нужно будет использовать его в последующих сообщениях. Так что, в основном, в shell сценарии вы бы просто запомнили вывод программы и использовали его каждый раз.
meuh упомянул механизм идентификатора notify-send и предоставил скрипт, описанный как цитируемый, который печатает последний идентификатор, и в следующий раз идентификатор должен быть включен в параметры командной строки. Я отредактировал скрипт, чтобы он запоминал идентификатор.
API уведомлений имеет средство для указания идентификатора текущего уведомления, которое должно быть обновлено вместо создания нового всплывающего окна, но
notify-send
этого не предоставляет. Если вы готовы использовать небольшое количество python, вы можете получить идентификатор уведомления, когда его создаете, а затем попытаться обновить этот идентификатор позже.
#!/usr/bin/python3
# sudo pip3 install fcache
import argparse, gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
from fcache.cache import FileCache
APPNAME = 'notify-send-nostack'
SLOT = 'id'
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('header')
parser.add_argument('body')
return parser.parse_args()
def run(header, body):
Notify.init(APPNAME)
obj = Notify.Notification.new(header, body)
obj.set_timeout(5) # кажется, это не срабатывает
# число выбрано случайно
mycache = FileCache(APPNAME)
if SLOT in mycache:
obj.set_property('id', mycache[SLOT])
obj.show()
newid = obj.get_property('id')
mycache[SLOT] = newid
mycache.close()
if __name__ == '__main__':
options = parse_args()
run(options.header, options.body)
Ответ или решение
Чтобы предотвратить накопление уведомлений при использовании notify-send
, вам нужно обновлять существующее уведомление вместо создания нового при каждом нажатии кнопки увеличения громкости. В этом случае нативный инструмент notify-send
не предоставляет функциональность для обновления уже существующего уведомления, но это можно обойти с помощью скрипта на Python.
Решение на Python
Вам потребуется создать скрипт, который будет сохранять идентификатор текущего уведомления и использовать его для обновления уведомления, вместо создания нового. Вот пример реализации на Python с использованием библиотеки gi
и кэша FileCache
:
#!/usr/bin/python3
import argparse, gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
from fcache.cache import FileCache
APPNAME = 'notify-send-nostack'
SLOT = 'id'
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('header')
parser.add_argument('body')
return parser.parse_args()
def run(header, body):
Notify.init(APPNAME)
obj = Notify.Notification.new(header, body)
obj.set_timeout(5) # Установите таймаут, если необходимо
# Используем кэш для хранения идентификатора уведомления
mycache = FileCache(APPNAME)
if SLOT in mycache:
obj.set_property('id', mycache[SLOT])
obj.show()
newid = obj.get_property('id')
mycache[SLOT] = newid
mycache.close()
if __name__ == '__main__':
options = parse_args()
run(options.header, options.body)
Инструкция по настройке:
-
Установка зависимостей: Убедитесь, что у вас установлены
python-gi
иfcache
. Вы можете установитьfcache
с помощьюpip
:sudo pip3 install fcache
-
Скрипт: Сохраните приведенный выше код в файл, например,
mynotify-send.py
, и сделайте его исполняемым:chmod +x mynotify-send.py
-
Использование: Вместо
notify-send
, используйтеmynotify-send.py
, передавая в него заголовок и тело уведомления:./mynotify-send.py "Громкость" "Текущий уровень: $(pamixer --get-volume)"
Преимущества данного подхода:
- Обновление: Вместо создания нового, уведомление обновляется. Это делает опыт пользователя более приятным, так как экран не засоряется одинаковыми сообщениями.
- Гибкость: Вы можете легко изменить текст и индикацию вашего уведомления.
- Эффективность: Уменьшает нагрузку на систему, так как используется одно уведомление с обновлениями.
Полезные советы:
- Настройте таймаут: Хотя скрипт устанавливает таймаут на 5 секунд, вы можете изменить это значение по вашему усмотрению, чтобы лучше соответствовать вашему рабочему процессу.
- Используйте кэш: Убедитесь, что кэш корректно сохраняется и обновляется, чтобы уведомления всегда обновлялись правильно.
Заключение
Данное решение позволяет вам использовать уведомления более эффективно и пользовательски ориентированно. При использовании таких средств, как Python и notify-send
, вы можете создать более интерактивную и удобную среду рабочего стола.