Skip to content

sinic/ednc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Emacs Desktop Notification Center

The Emacs Desktop Notification Center (EDNC) is an Emacs package written in pure Lisp that implements a Desktop Notifications service according to the freedesktop.org specification. EDNC aspires to be a small, but flexible drop-in replacement of standalone daemons like Dunst. A global minor mode ednc-mode tracks active notifications, which users can access by calling the function ednc-notifications. They are also free to add their own functions to the (abnormal) hook ednc-notification-amendment-functions to amend arbitrary data and to the (abnormal) hook ednc-notification-presentation-functions to present notifications as they see fit. To be useful out of the box, default hooks record all notifications in an interactive log buffer *ednc-log*.

Basic Usage

Either install this package from MELPA, or simply execute the package-install-file command, supplying a local copy of ednc.el.

After installation, ensure that no other notification daemon is active, execute the ednc-mode command to activate the global minor mode, and watch notifications come and go in the interactive log buffer *ednc-log*. You can create example notifications from Emacs by evaluating the following expressions:

(require 'notifications)
(notifications-notify :title "1st test" :body "hello, world" :app-name "EDNC"
                      :actions '("default" "default"))

Some clients (e.g., web browsers) check for a notification server on startup and thus need to be reopened after enabling EDNC.

By default, you can use the following mouse controls and key bindings (the latter only in the log buffer):

  • TAB toggles an expanded view of the notification (ednc-toggle-expanded-view),
  • mouse-1 (left click) or RET invokes the notification’s default action (ednc-invoke-action),
  • C-down-mouse-1 shows a menu of all available actions,
  • mouse-2 (middle click) pops to the notification in the log buffer (ednc-pop-to-notification-in-log-buffer), and
  • mouse-3 (right click) or d dismisses the notification (ednc-dismiss-notification).

This is the log buffer after creating two test notifications, dismissing the first one, and expanding the second one:

./screenshot.png

Advanced Usage

You can also retrieve currently active notifications with the function ednc-notifications whenever the (abnormal) hook ednc-notification-presentation-functions runs. Functions in this hook are given access to the exact notification that was removed, added, or replaced. Read on for some suggestions.

Show Active Notifications in Mode Line

To simply display all active notifications in the mode line, first define a function that returns active notifications as a string:

(defun list-notifications ()
  (mapconcat #'ednc-format-notification (ednc-notifications) ""))

Alternatively, only include the newest notification per application:

(defun stack-notifications (&optional hide)
  (mapconcat (lambda (notification)
               (let ((app-name (ednc-notification-app-name notification)))
                 (unless (member app-name hide)
                   (push app-name hide)
                   (ednc-format-notification notification))))
             (ednc-notifications) ""))

Use the respective function’s result as part of your mode line every time a new notification appears, or an old one is removed:

(nconc global-mode-string '((:eval (list-notifications))))  ; or stack
(add-hook 'ednc-notification-presentation-functions
          (lambda (&rest _) (force-mode-line-update t)))

Pop to Buffer for Every New Notification

If you want to create a new buffer for every new notification (instead of or in addition to displaying it in the mode line) first define a function that uses the abnormal hook’s arguments:

(defun show-notification-in-buffer (old new)
  (let ((name (format "Notification %d" (ednc-notification-id (or old new)))))
    (with-current-buffer (get-buffer-create name)
      (if new (let ((inhibit-read-only t))
                (if old (erase-buffer) (ednc-view-mode))
                (insert (ednc-format-notification new t))
                (pop-to-buffer (current-buffer)))
        (kill-buffer)))))

Then ensure the function is called at the appropriate moment:

(add-hook 'ednc-notification-presentation-functions
          #'show-notification-in-buffer)

Questions and Answers

Here you find answers to some real and to some imagined questions from users.

How does EDNC differ from Alert?

These are two different classes of software: EDNC handles incoming notifications on D-Bus; Alert does not, but can be configured to emit notifications on D-Bus. It is possible, and sensible, to use both EDNC and Alert at the same time. You might configure the packages, for example, so that

  • Alert sends a notification on activity in an rcirc buffer,
  • Signal sends a notification on receiving a message, and
  • EDNC presents both of these uniformly in the mode-line.

Without EDNC, Alert could bypass D-Bus when dealing with rcirc, but the information from Signal would be inaccessible to Emacs.

How does EDNC differ from Dunst?

EDNC is native to Emacs; Dunst is not. Specifically, you can access and modify received notifications with Emacs Lisp (a big deal for some users). Other than that, there should be no fundamental difference.

Why do some icons look weird?

Emacs does not support PAM, a newer Netpbm format with optional transparency information. Until that changes, the icon’s alpha channel is simply ignored.

Why are some icons not showing up at all?

The Icon Theme Specification has not been implemented yet, so only file URIs are supported for now.


https://github.com/sinic/ednc/workflows/CI/badge.svg https://img.shields.io/badge/License-GPLv3-blue.svg https://melpa.org/packages/ednc-badge.svg

About

The Emacs Desktop Notification Center helps you manage all your desktop notifications without leaving Emacs.

Topics

Resources

License

Stars

Watchers

Forks