'onClick' 機能を使用してコマンドから gnome に通知を作成する方法は?

'onClick' 機能を使用してコマンドから gnome に通知を作成する方法は?

簡単なコマンドを使用して通知を作成できます。

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

クリック可能にして、クリック時にスクリプトを実行することはできますか?

このようなNautilusファイルマネージャーから送信された通知をクリックすると ここに画像の説明を入力してください

直接新しいウィンドウが開きます。しかし、カスタム通知は何も実行しません。クリックしたときにカスタム通知がアクティビティを実行するようにする方法。

答え1

興味深い質問ですね!

ここに画像の説明を入力してください

...これが、この主題に関する以下の調査のきっかけとなった。UB 実験リポジトリ結果として、次のオプションを含む通知/メッセージのポップアップが表示されます。

クリック機能(オプション)を備えた通知の例

  • コーナーを表示するように設定する
  • クリック時に実行するコマンドを設定する
  • タイトルを設定する(太字)
  • メッセージテキストを設定する
  • アイコンを設定する
  • 有効期間(秒)を設定する <- スニペットで設定

最初の 4 つのオプションは、引数を設定した場合にのみ適用され、別の設定がない限り、コーナーはデフォルトで右下 (プライマリ) になります。

有効期間は、そのままハードコードされており、別の設定がない限り、デフォルトで 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

ここに画像の説明を入力してください

コード

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

関連情報