Message overflow in notification bubble
I posted this a while ago on a (now) deleted Q/A. Maybe it is useful to you.
A patch to allow (very) long messages
The "patch" below will allow you to have notifications as long as it takes on your desktop:
In case of (very) long notifications, instead of this:
you will see this:
The duration of the message is automatically set to the length of the text.
What it does
Notifications, send by notify-osd
(notify-send
), are limited to appr. 120 characters.
The solution "listens" to sent messages, using dbus-monitor
. If a message exceeds the 120 characters, it takes over the messages and uses "its own" message window to display the notification, as shown above.
The scripts
-
The setup exists of two sections; de "listen-" script, which intercepts the notifications:
#!/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 {}
Copy the script into an empty file and save it as
catch_notifs.sh
-
The script that creates the replacement- notifications:
#!/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()
Copy the script above into an empty file, save it as (exactly!)
message
(no extension) and make it executable. - Store both scripts in one and the same directory.
-
Test- run the script by the command (from a terminal window):
/bin/bash /path/to/catch_notifs.sh
(keep it running)
You can test the setup by running (in another terminal):
notify-send '<long_text>'
-
If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:
/bin/bash /path/to/catch_notifs.sh
And it should work :)
As I've noted in the comments , notify-osd
is not very suitable for extensive messages and one should prefer zenity
instead.
Simple example of usage would be spawning zenity
dialog via subprocess.call([COMMAND,OPTIONS])
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)
Very simple example. With something that requires checking exit status, like questions , you might wanna use try - except - else
structure
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"
If you want something more advanced, probably consider learning one of the graphic toolkits like PyQt or Gtk.