3 votes

Comment créer une notification dans gnome à partir d'une commande avec la fonctionnalité 'onClick' ?

Nous pouvons créer une notification en utilisant des commandes simples.

ex : notify-send 'SUPER IMPORTANT!' 'This is an urgent message!' -u critical

Peut-on le rendre cliquable et exécuter un script en cliquant dessus ? Comme

Lorsque nous cliquons sur une notification envoyée par le gestionnaire de fichiers Nautilus, comme celle-ci enter image description here

Il ouvre directement une nouvelle fenêtre. Mais notre notification personnalisée ne fait rien. Comment faire pour que notre notification personnalisée fasse une activité lorsque nous la cliquons.

3voto

Jacob Vlijm Points 78990

Question intéressante !

enter image description here

...Ce qui a été l'élément déclencheur de l'exploration ci-dessous sur le sujet de la Dépôt expérimental de l'UB . Le résultat est une popup de notification/message qui a les options suivantes :

Exemple de notification avec fonctionnalité de clic (facultative)

  • définir le coin à faire apparaître
  • définir une commande à exécuter lorsqu'on clique dessus
  • définir un titre (en gras)
  • définir un texte de message
  • définir une icône
  • définir une durée de vie (secondes) <- définie dans le snippet

Les quatre premières options ne s'appliquent que si vous définissez l'argument, le coin est par défaut en bas à droite (sur le primaire), sauf si vous le définissez différemment.

La durée de vie est -telle qu'elle est- codée en dur, elle est de 10 secondes par défaut, sauf si elle est définie différemment.

Notes

  • Notez que ces notifications, telles qu'elles sont, ne sont pas transmises par l'intermédiaire de l'application dbus Ils ne peuvent donc pas être "écoutés". Un développement plus poussé pourrait en faire un processus d'arrière-plan de type démon - maintenant la boucle Gtk en vie -, n'appelant la fenêtre que sur indication du bus.
  • Beaucoup de valeurs/préférences pourraient être déplacées dans gsettings.

Comment configurer

  • Copiez l'extrait dans un fichier vide, enregistrez-le en tant que alternotify.py et le rendre exécutable
  • Exécutez-le avec n'importe quelle combinaison des options suivantes, choisissez simplement ce dont vous avez besoin :

    • cliquez sur la commande : command="command_to_run"
    • titre : title="Title to show"
    • le texte du message (corps) : body="Text body of the notification message, text, text, text"
    • (à partir du nom de l'icône) : icon="icon-name"
    • le coin à faire apparaître, 1 = NE, 2 = NW, 3 = SE, 4 = SW : position=1

Une commande complète pourrait ressembler à ceci :

/path/to/alternotify.py title="Missing applet" body="To use this functionality, you need to run previews. Click this notification to switch it on." icon="budgie-hotcorners-symbolic" command="gedit /home/jacob/Bureaublad/Kap" position=4

enter image description here

Le code

#!/usr/bin/env python3
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib
import sys
import subprocess

class NotifyWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_decorated(False)
        distance = 80 # gsettings
        winwidth = 300 # gsettings
        winheight = 80 # gsettings
        self.set_default_size(winwidth, winheight)
        self.maingrid = Gtk.Grid()
        self.add(self.maingrid)  
        self.set_space()
        self.winpos = 4 # gsettings? default = SE
        self.get_args()
        self.currage = 0
        self.targetage = 10 # gsettings,life seconds
        GLib.timeout_add_seconds(1, self.limit_windowlife) 
        self.maingrid.show_all()
        self.position_popup(self.winpos, winwidth, winheight, distance)
        self.show_all()
        Gtk.main()

    def get_winpos(self, arg):
        self.winpos = int(arg)

    def limit_windowlife(self):
        if self.currage >= self.targetage:
            Gtk.main_quit()
        self.currage = self.currage + 1;
        return True        

    def position_popup(self, winpos, winwidth, winheight, distance):
        monitordata = self.get_primarymonitor()
        winsize = self.get_size()
        winwidth, winheight = winsize.width, winsize.height
        monitor_xpos = monitordata[2]
        monitor_ypos = monitordata[3]
        monitor_width = monitordata[0]
        monitor_height = monitordata[1]

        if winpos == 1:
            wintargetx = monitor_xpos + distance
            wintargety = monitor_ypos + distance
        elif winpos == 2:
            wintargetx = monitor_width + monitor_xpos - winwidth - distance
            wintargety = monitor_ypos + distance
        elif winpos == 3:
            wintargetx = monitor_xpos + distance
            wintargety = monitor_ypos + monitor_height - (
                distance + winheight
            )
        elif winpos == 4:
            wintargetx = monitor_width + monitor_xpos - winwidth - distance
            wintargety = monitor_ypos + monitor_height - (
                distance + winheight
            )
        self.move(wintargetx, wintargety)

    def get_primarymonitor(self):
        # see what is the resolution on the primary monitor
        prim = Gdk.Display.get_default().get_primary_monitor()
        geo = prim.get_geometry()
        [width, height, screen_xpos, screen_ypos] = [
            geo.width, geo.height, geo.x, geo.y
        ]
        height = geo.height
        return width, height, screen_xpos, screen_ypos

    def show_title(self, title):
        title_label = Gtk.Label(label=title)
        self.maingrid.attach(title_label, 3, 1, 1, 1)
        title_label.set_xalign(0)
        # set title bold
        self.noti_css = ".title {font-weight: bold; padding-bottom: 5px;}"
        self.provider = Gtk.CssProvider.new()
        self.provider.load_from_data(self.noti_css.encode())
        self.set_textstyle(title_label, "title")

    def set_body(self, body):
        body_label = Gtk.Label(
            label=body
        )
        self.maingrid.attach(body_label, 3, 2, 1, 1)
        body_label.set_xalign(0)
        body_label.set_size_request(250, -1)
        body_label.set_line_wrap(True)

    def set_icon(self, icon):
        self.maingrid.attach(Gtk.Label(label="\t"), 2, 0, 1, 1)
        if not "/" in icon:
            newicon = Gtk.Image.new_from_icon_name(
                icon, Gtk.IconSize.DIALOG
            )
            self.maingrid.attach(newicon, 1, 1, 1, 2)
            self.maingrid.show_all()

    def get_args(self):
        args = sys.argv[1:]
        funcs = [
            self.show_title, self.set_body, self.set_icon,
            self.connect_action, self.get_winpos,
        ]
        argnames = ["title", "body", "icon", "command", "position"]
        for arg in args:
            argdata = arg.split("=")
            argname = argdata[0]
            arg = argdata[1]
            try:
                i = argnames.index(argname)
                funcs[i](arg)
            except ValueError:
                print("invalid argument:", arg)             

    def connect_action(self, arg):
        self.connect("button_press_event", self.run_command, arg)
        pass

    def set_textstyle(self, widget, style):
        widget_cont = widget.get_style_context()
        widget_cont.add_class(style)
        Gtk.StyleContext.add_provider(
            widget_cont,
            self.provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
        )               

    def run_command(self, event, key, command):
        if key.get_button()[1] == 1:
            subprocess.Popen(["/bin/bash", "-c", command])

    def set_space(self):
        for cell in [[0, 0], [100, 0], [0, 100], [100, 100]]:
            self.maingrid.attach(
                Gtk.Label(label="\t"), cell[0], cell[1], 1, 1
            )

NotifyWindow()

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X