How to display interactive notifications in KDE

I’m trying to find a way to display simple custom notification to user to show message like “reboot is required” from shell script. I’m able to display simple passive notifications with kdialog or notify-send, but customization of those are very limited. Is there any methods to add interactive buttons to notifications, for example “System reboot required. <click here to reboot>” ?


You would have to use DBUS directly for this.
See f.e.

You can use “qdbusviewer” to play with DBUS, and “dbus-send” or “qdbus” to call methods via DBUS from a shell script.
But I don’t think it’s possible to get the signal when the button is clicked in a shell script.
You would have to use a programming language for that I think.

Why don’t you just display a normal dialog with kdialog? Would be much easier in a shell script, as it only returns when the button is clicked.
See “kdialog --help” for all possibilities.

Maybe something like this:

kdialog --warningcontinuecancel "System reboot required." --continue-label "Reboot"

In that case kdialog would return 0 if “Reboot” is clicked, and 2 if “Cancel” is clicked.

Thanks for the tip. I managed to do this with simple Python script. It’s not perfect but seems to work in this case.

#! /usr/bin/python
import sys, dbus, gobject, gtk
from dbus.mainloop.glib import DBusGMainLoop

def message_filter(connection, message):
    if message.get_member() != "ActionInvoked":

    # ActionInvoked sent. Do something with it. 
    # TODO This does not really check that event is sent by Reboot button but works anyway.
    print("not really rebooting")

def main():

    # Display Notification popup
    knotify = dbus.SessionBus().get_object("org.kde.knotify", "/Notify")
    knotify.event("warning", "kde", ], "Reboot required", "Reboot is required", ], 'Reboot'], 0, 0, dbus_interface="org.kde.KNotify")

    bus = dbus.SessionBus()
    # Clicking reboot button sends "ActionInvoked".
    MATCH = "interface='org.freedesktop.Notifications',member='ActionInvoked'"

if __name__ == "__main__":