Download
(require 'dbus)
(defvar my-rcirc-dbus-notification-ids '()
"List with the dbus notification IDs from rcirc")
(defun fsm-x-active-window ()
"Return the window ID of the current active window in X, as
given by the _NET_ACTIVE_WINDOW of the root window set by the
window-manager, or nil if not able to"
(if (eq (window-system) 'x)
(let ((x-active-window (x-window-property "_NET_ACTIVE_WINDOW" nil "WINDOW" 0 nil t)))
(string-to-number (format "%x00%x" (car x-active-window) (cdr x-active-window))
16))
nil))
(defun fsm-frame-outer-window-id (frame)
"Return the frame outer-window-id property, or nil if FRAME not of the correct type"
(if (framep frame)
(string-to-number
(frame-parameter frame 'outer-window-id))
nil))
(defun fsm-frame-x-active-window-p (frame)
"Check if FRAME is is the X active windows
Returns t if frame has focus or nil if"
(if (framep frame)
(progn
(if (eq (fsm-frame-outer-window-id frame)
(fsm-x-active-window))
t
nil))
nil))
(defun my-rcirc-dbus-notification (proc sender response target text)
(when (and (string-match (rcirc-nick proc) text)
(not (string= (rcirc-nick proc) sender))
(not (string= (rcirc-server-name proc) sender))
(not (fsm-frame-x-active-window-p (selected-frame))))
(push
(list
(dbus-call-method
:session
"org.freedesktop.Notifications"
"/org/freedesktop/Notifications"
"org.freedesktop.Notifications"
"Notify"
"GNU Emacs"
0
"/usr/share/icons/hicolor/48x48/apps/emacs.png"
(format "%s: IRC activity" target)
(format "%s" text)
'(:array)
'(:array :signature "{sv}")
':int32 -1)
proc
target)
my-rcirc-dbus-notification-ids)))
(defun my-dbus-signal-handler-action-invoked (id action-key)
"Signal handler for when an action is invoked"
(let ((rcirc-data (assq id my-rcirc-dbus-notification-ids))
(rcirc-buffer)
(rcirc-window)
(rcirc-frame))
(setq rcirc-buffer (rcirc-get-buffer (nth 1 rcirc-data) (nth 2 rcirc-data)))
(switch-to-buffer rcirc-buffer)
(setq rcirc-window (get-buffer-window rcirc-buffer))
(setq rcirc-frame (window-frame rcirc-window))
(when (window-system)
(raise-frame rcirc-frame)
(x-focus-frame rcirc-frame))
(setq my-rcirc-dbus-notification-ids (assq-delete-all id my-rcirc-dbus-notification-ids))))
(defun my-dbus-signal-handler-notification-closed (id &optional reason)
"Signal handler for when a notification is closed. REASON is
&optional since in some configurations dbus ommits it, and we
do not need it anyway given that we're only cleaning up the notification list"
(setq my-rcirc-dbus-notification-ids (assq-delete-all id my-rcirc-dbus-notification-ids)))
(dbus-register-signal
:session
"org.freedesktop.Notifications"
"/org/freedesktop/Notifications"
"org.freedesktop.Notifications"
"ActionInvoked"
'my-dbus-signal-handler-action-invoked)
(dbus-register-signal
:session
"org.freedesktop.Notifications"
"/org/freedesktop/Notifications"
"org.freedesktop.Notifications"
"NotificationClosed"
'my-dbus-signal-handler-notification-closed)
(add-hook 'rcirc-print-hooks 'my-rcirc-dbus-notification)