4

I have wrote this script, when the increase volume button is pressed to display desktop notifications with "notify-send".

when the button is pressed:
notify-send "Current volume 'pamixer --get-volume'"

The problems is that the notifications get stacked e.g. enter image description here

Is there a way to prevent the notifications from stacking and just display the newest notification?

2
  • This depends on what is receiving and displaying the notifications. What desktop environment are you using? Commented Jul 7, 2017 at 23:27
  • Hello! I am using i3wm with Dunst.
    – Daniel
    Commented Jul 8, 2017 at 12:50

2 Answers 2

3

The notification api has a means to specify the id of a current notification that should be updated instead of creating a new popup, but notify-send does not provide for this. If you are willing to use a small amount of python, you can retrieve the id of a notification when you make it, and then try to update that id later. Put the following python2 code in a file in a directory that is in your PATH, say mynotify-send and do 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()

You must install python-gobject too. When you run

mynotify-send -m 'message 1'

it should popup the notification, but also print an id on stdout. Often this is just a small number counting the number of notifications, eg 6. You can then change the message in the existing popup by adding this id:

mynotify-send --id 6 -m 'message 2'

You can do this as long as the popup exists. After the popup goes away the next message will get a new id, eg 7, which the program prints, and you will have to use this in later messages. So basically in a shell script you would just remember the output from the program and reuse it each time.

0
0

meuh mentioned the id mechanism of notify-send and gave out a script described as quoted, which prints out last id and next time the id needs to be included in the command line options. I edited the script so that it remembers the id.

The notification API has a means to specify the id of a current notification that should be updated instead of creating a new popup, but notify-send does not provide for this. If you are willing to use a small amount of python, you can retrieve the id of a notification when you make it, and then try to update that id later.

#!/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) # seems has no effect to me
                       # number chosen at random

    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)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .