web-dev-qa-db-ja.com

通知バブルのメッセージオーバーフロー

私はgtk通知を使用する方法を学んでいますが、通知バブルを介した出力表示には最大オーバーフローサイズ、おそらく10行程度があるようです。そのため、表示したいメッセージがそれ以上の場合、抑制されます。何も抑制されずにメッセージ全体を強制的に表示する方法はありますか?

ところで、notifyOSDを使用しています。

7
Razor

しばらく前に(今)削除されたQ/Aに投稿しました。たぶんそれはあなたにとって役に立つでしょう。


(非常に)長いメッセージを許可するパッチ

以下の「パッチ」を使用すると、デスクトップ上で通知を受け取ることができます。

これの代わりに(非常に)長い通知の場合:

enter image description here

これが表示されます:

enter image description here

メッセージのdurationは、テキストの長さに自動的に設定されます。

何をする

notify-osdnotify-send)によって送信される通知は、apprに制限されています。 120文字。
ソリューションは、dbus-monitorを使用して、送信されたメッセージを「リッスン」します。メッセージが120文字を超える場合、メッセージを引き継ぎ、上記のように「独自の」メッセージウィンドウを使用して通知を表示します。

スクリプト

  1. セットアップには2つのセクションがあります。通知を傍受する「listen-」スクリプト:

    #!/bin/bash
    
    currdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    
    dbus-monitor "interface='org.freedesktop.Notifications'" |\
     grep --line-buffered "string" |\
     grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v |\
     grep --line-buffered '.*(?=string)|(?<=string).*' -oPi |\
     grep --line-buffered -v '^\s*$' |\
     xargs -I '{}' $currdir/message {}
    

    スクリプトを空のファイルにコピーし、catch_notifs.shとして保存します

  2. 置換通知を作成するスクリプト:

    #!/usr/bin/env python3
    import subprocess
    import os
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import GObject, Gtk, Gdk, Pango
    from threading import Thread
    import time
    import sys
    
    text = sys.argv[1]
    length = len(text)
    showtime = length/20
    
    def get_screen():
        scr = [s.split("x") for s in subprocess.check_output([
            "xrandr"]).decode("utf-8").split() if "+0+0" in s][0]
        return int(scr[0]) -450
    
    class Splash(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="splashtitle")
            maingrid = Gtk.Grid()
            self.add(maingrid)
            maingrid.set_border_width(20)
            label = Gtk.Label(text)
            label.set_line_wrap(True)
            label.set_max_width_chars(45)
            label.modify_font(Pango.FontDescription('Ubuntu 11'))
            maingrid.attach(label, 0, 0, 1, 1)
            self.stop = Thread(target=self.close_window)
            self.stop.start()
    
        def close_window(self):
            time.sleep(showtime)
            Gtk.main_quit()
    
    def splashwindow():
        window = Splash()
        window.set_decorated(False)
        window.set_resizable(False)
        window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1))
        window.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse("white"))
        # window.set_opacity(0.8)
        window.move(get_screen(), 80)
        window.set_keep_above(True)
        window.show_all()
        window.set_default_size(200, 500)
        GObject.threads_init()
        Gtk.main()
    
    if len(text) > 120:
        subprocess.Popen(["pkill", "notify-osd"])
        splashwindow()
    

    上記のスクリプトを空のファイルにコピーし、(正確に!)message(拡張子なし)として保存し、実行可能にします

  3. 両方のスクリプトを同じディレクトリに保存します
  4. 次のコマンドでスクリプトをテスト実行します(ターミナルウィンドウから):

    /bin/bash /path/to/catch_notifs.sh
    

    (実行し続ける)

    (別の端末で)実行することにより、セットアップをテストできます。

    notify-send '<long_text>'
    
  5. すべてが正常に機能する場合は、スタートアップアプリケーションに追加します:ダッシュ>スタートアップアプリケーション>追加コマンドを追加します。

    /bin/bash /path/to/catch_notifs.sh
    

そして、それは動作するはずです:)

10
Jacob Vlijm

コメントで述べたように、notify-osdは広範なメッセージにはあまり適しておらず、代わりにzenityを好むはずです。

簡単な使用例は、subprocess.call([COMMAND,OPTIONS])を介したzenityダイアログの生成です。

import subprocess 

text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
command=['zenity', '--info', '--text="' +text + '"', '--width=250', '--height=300' ]
subprocess.call(command)

非常に簡単な例。 questionsのような終了ステータスを確認する必要があるものでは、try - except - else構造体を使用できます

import subprocess 

text='Do you want to use Zenity?'
command=['zenity', '--question', 
         '--text="' +text + '"',
         '--width=250', '--height=300' ]


try:
    stdout = subprocess.check_call(command)

except subprocess.CalledProcessError:
    pass # if return sttus is non-zero, do something here

else:
    # if exit status was 0 , we do something here
    print "Yes, I want to use Zenity too"

もっと高度なものが必要な場合は、おそらくPyQtやGtkなどのグラフィックツールキットのいずれかを学習することを検討してください。

4