Wie erstelle ich in Gnome eine Benachrichtigung per Befehl mit der Funktion „onClick“?

Wie erstelle ich in Gnome eine Benachrichtigung per Befehl mit der Funktion „onClick“?

Wir können mit einfachen Befehlen eine Benachrichtigung erstellen.

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

Können wir es anklickbar machen und beim Klicken darauf ein Skript ausführen? Wie

Wenn wir auf eine Benachrichtigung klicken, die vom Dateimanager Nautilus gesendet wird, wie diese hier Bildbeschreibung hier eingeben

Es öffnet sich direkt ein neues Fenster. Aber unsere benutzerdefinierte Benachrichtigung tut nichts. Wie kann man dafür sorgen, dass unsere benutzerdefinierte Benachrichtigung eine Aktivität ausführt, wenn wir darauf klicken?

Antwort1

Interessante Frage!

Bildbeschreibung hier eingeben

...Was war der Auslöser für die folgende Untersuchung zu diesem Thema auf derExperimentelles UB-RepositoryDas Ergebnis ist ein Benachrichtigungs-/Nachrichten-Popup mit den folgenden Optionen:

Beispiel einer Benachrichtigung mit (optionaler) Klick-Funktionalität

  • Stellen Sie die Ecke so ein, dass sie angezeigt wird
  • Legen Sie einen Befehl fest, der beim Klicken ausgeführt wird
  • Titel festlegen (fett)
  • einen Nachrichtentext festlegen
  • setze ein Symbol
  • setze eine Lebensdauer (Sekunden) <- setze im Snippet

Die ersten vier Optionen gelten nur, wenn Sie das Argument festlegen. Die Ecke ist standardmäßig unten rechts (auf Primär), sofern nichts anderes festgelegt ist.

Die Lebensdauer ist – so wie sie ist – fest codiert und beträgt standardmäßig 10 Sekunden, sofern nicht anders festgelegt.

Anmerkungen

  • Beachten Sie, dass diese Benachrichtigungen – so wie sie sind – nicht durchgeleitet werden dbusund daher nicht „abgehört“ werden können. Eine Weiterentwicklung könnte darin bestehen, daraus einen Daemon-ähnlichen Hintergrundprozess zu machen, der die Gtk-Schleife aufrechterhält und das Fenster nur bei Dbus-Hinweis aufruft.
  • Viele der Werte/Einstellungen könnten nach gsettings verschoben werden

Wie stellt man das ein

  • Kopieren Sie das Snippet in eine leere Datei, speichern Sie es unter alternotify.py, machen Sie es ausführbar
  • Führen Sie es mit einer beliebigen Kombination der folgenden Optionen aus. Wählen Sie einfach aus, was Sie benötigen:

    • Klickbefehl:command="command_to_run"
    • Titel:title="Title to show"
    • Nachrichtentext (Body):body="Text body of the notification message, text, text, text"
    • Symbol (vom Symbolnamen):icon="icon-name"
    • die Ecke, die erscheinen soll, 1 = NO, 2 = NW, 3 = SO, 4 = SW:position=1

Ein vollständiger Befehl könnte so aussehen:

/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

Bildbeschreibung hier eingeben

Der 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()

verwandte Informationen