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

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

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

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

Когда мы нажимаем на уведомление, отправленное файловым менеджером Nautilus, как этот enter image description here

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

2
задан 11 October 2019 в 22:46

1 ответ

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

enter image description here

... Который был триггером для исследования ниже на предмете на экспериментальном repo UB. Результатом является всплывающее окно уведомления/сообщения, которое имеет следующие опции:

Пример уведомления с (дополнительно) функциональностью щелчка

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

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

Продолжительность жизни - как это - hardcoded, значения по умолчанию к 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 = NE, 2 = NW, 3 = SE, 4 = SW: 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

enter image description here

Код

#!/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()
1
ответ дан 2 December 2019 в 04:35

Другие вопросы по тегам:

Похожие вопросы: