Как создать уведомление в gnome из команды с функцией «onClick»?

Как создать уведомление в gnome из команды с функцией «onClick»?

Мы можем создать уведомление с помощью простых команд.

бывший:notify-send 'SUPER IMPORTANT!' 'This is an urgent message!' -u critical

Можно ли сделать его кликабельным и запустить скрипт при клике на него?

Когда мы нажимаем на уведомление, отправленное файловым менеджером Nautilus, например, это введите описание изображения здесь

Он напрямую открывает новое окно. Но наше пользовательское уведомление ничего не делает. Как заставить наше пользовательское уведомление выполнять действие, когда мы нажимаем на него.

решение1

Интересный вопрос!

введите описание изображения здесь

...Что послужило толчком к исследованию ниже по темеЭкспериментальный репозиторий UB. Результатом является всплывающее уведомление/сообщение со следующими параметрами:

Пример уведомления с (необязательной) функцией нажатия

  • установите угол, чтобы он появился
  • установить команду, которая будет выполняться при нажатии
  • задать заголовок (жирный)
  • установить текст сообщения
  • установить значок
  • установить продолжительность жизни (секунды) <- установить в фрагменте

Первые четыре параметра применяются только в том случае, если задан аргумент, угол по умолчанию — нижний правый (на основном), если не указано иное.

Продолжительность жизни, как и прежде, жестко запрограммирована и составляет по умолчанию 10 секунд, если не указано иное.

Примечания

  • Обратите внимание, что эти уведомления - как есть - не передаются dbus, поэтому их нельзя "прослушать". Дальнейшее развитие может заключаться в том, чтобы сделать его фоновый процесс, подобный демону - сохраняя цикл Gtk активным - вызывая окно только по подсказке dbus.
  • Многие значения/настройки можно перенести в gsettings

Как настроить

  • Скопируйте фрагмент в пустой файл, сохраните его как alternotify.py, сделайте его исполняемым.
  • Запустите его с любой комбинацией следующих опций, просто выберите то, что вам нужно:

    • нажмите команду:command="command_to_run"
    • заголовок:title="Title to show"
    • Текст сообщения (тело):body="Text body of the notification message, text, text, text"
    • значок (из названия значка):icon="icon-name"
    • угол, который должен появиться, 1 = СВ, 2 = СЗ, 3 = ЮВ, 4 = ЮЗ:position=1

Полная команда может выглядеть так:

/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

введите описание изображения здесь

Код

#!/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()

Связанный контент