tpop-it-up.txt - monochromatic - monochromatic blog: http://blog.z3bra.org
HTML git clone git://z3bra.org/monochromatic
DIR Log
DIR Files
DIR Refs
---
tpop-it-up.txt (11141B)
---
1 # Pop it up !
2
3 30 April, 2014
4
5 So you know how to build a status bar to get informations about your computer?
6 That's **cute**. How about bringing it to the next level?
7
8 Let's go through another way to display informations from your lovely
9 computer: popup notifications !
10
11 ## What's that ?
12 Popup notifications (I'll call them "popup" from now) are a tiny window that
13 will appear on your screen with an informative text on it, and then disappear
14 after a certain amount of time, or a user interaction.
15
16 The important part is that the popups show up when an event occur, not upon user
17 request (well, if the user request a popup, it can still appear, obviously).
18
19 ## Usefulness
20 Well, most of the popup we have to deal with are annoying most of the time
21 (except those that notify me that I won an IPad by being the visitor number
22 1 000 000, it's nice to tell me!). But if you choose wisely the content and the
23 event to pop it, it can become really useful, and help you to unclutter your
24 desktop by removing useless informations.
25
26 Do you really need to know that your laptop battery is at 78% ? **NO**
27 Do you really need to know that you have 0 new mails ? **NO**
28
29 This can apply to many other informations (RAM, CPU, current workspace,..). You
30 don't need the information to be displayed all the time. You just need it when
31 it's relevant, like battery under 10%, or new mail incoming.
32
33 But if you just LIKE to have it displayed all the time (Sometime, I enjoy a nice
34 status bar with the fine infos in it), then it's okay! Remember that you can
35 have both anyway ;)
36
37 Moreover, you can use popups to notify you when a task running in the
38 background has finished, or that a torrent has finished downloading, or
39 whatever weird usage you can find!
40
41 ## Existing software
42 There are in fact, many notification systems that you can use:
43 [libnotify](http://library.gnome.org/devel/notification-spec/),
44 [notify-osd](https://launchpad.net/notify-osd),
45 [twmn](https://github.com/sboli/Twmn), etc...
46
47 These are fine. But as always, it's just funnier to build your own!
48 And in order to do so, we will need an important program:
49 [bar](https://github.com/lemonboy/bar)! (note that you can use
50 [dzen](https://github.com/robm/dzen) too)
51
52 I love this one, because it's really light and simple to use. Moreover, I
53 contributed to it to complete the geometry setting. You can now create a window
54 of any size and place it wherever you want!
55
56 ## Popup itself
57 This part is the most simple in fact. `bar` will do anything for us.
58
59 All you have to do is to create a script that will take a serie of argument and
60 put them in a resized bar on your screen.
61
62 The simplest script I can think of is:
63
64 #!/bin/sh
65
66 Create the popup and make it live for 3 seconds
67 (echo " $@"; sleep 3) | bar -g 120x20+20+20
68
69 And it's working, already!
70 After that, you can style it to make it look like you want:
71
72 #!/bin/sh
73
74 # how long should the popup remain?
75 duration=3
76
77 # define geometry
78 barx=10
79 bary=10
80 barw=120
81 barh=20
82
83 # colors
84 bar_bg='#ff333333'
85 bar_fg='#ffffffff' # white is default
86
87 # font used
88 bar_font='-*-gohufont-medium-*-*--11-*-*-*-*-*-iso10646-1'
89
90 # compute all this
91 baropt='-g ${barw}x${barh}+${barx}+${bary} -B${bar_bg} -f ${bar_font}'
92
93 Create the popup and make it live for 3 seconds
94 (echo " $@"; sleep ${duration}) | bar ${baropt}
95
96 [](http://pub.z3bra.org/monochromatic/img/2014-04-29-popup-simple.png)
97 *The simple script above, started with a random text.
98 It's my upper left hand-corner*
99
100 Obviously, that's not an informative popup at all (is it?). All you need now is
101 to write some simple script to grab the informations you will need to display in
102 your popup. I'll not develop it here, as I already wrote a not-so-tiny section
103 on a subjet in my [previous
104 post](http://blog.z3bra.org/2014/04/meeting-at-the-bar.html#grab).
105
106 You could then just pop notifications using:
107
108 popup $(~/bin/volume)
109
110
111 ## Automate the popups
112 The best thing about popups is that they spawn when it's relevent, eg: when a
113 new mail arrived, volume is changing or battery is low.
114
115 To catch those event there are many way. We will run through three of them:
116
117 * infinite loop
118 * inotify event
119 * key presses
120
121 ### infinite loop
122 This one is easy. We just check whatever we want at regular interval, and
123 depending on some conditions, we raise a notification. That's what I use for my
124 battery:
125
126 #!/bin/sh
127 #
128 # z3bra - (c) wtfpl 2014
129 # check battery level, and raise a notification if the capacity is
130 # under a defined level
131
132 LEVL=7
133 BATC=$(sed 's/%//' /sys/class/power_supply/BAT0/capacity)
134
135 test ${BATC} -le ${LEVL} && popup battery level: ${BATC}
136
137 Then run this every 2 minutes or so, and it will notify you when your battery is
138 running low. You can put it in your `.xinitrc` or as a cron job:
139
140 # .xinitrc
141 while :; do ~/bin/battery_check; sleep 120; done &
142
143 # crontab
144 */2 * * * * DISPLAY=0 ~/bin/battery_check
145
146
147 ### inotify event
148 [Inotify (inode notify) is a Linux kernel subsystem that acts to extend
149 filesystems to notice changes to the
150 filesystem](https://en.wikipedia.org/wiki/Inotify). That strange sentence means
151 that you can catch an event when a node (file, socket, fifo, directory, ...) is
152 modified. There are many events like modification, access to a node, node moved,
153 etc...
154
155 To catch those event, there are really few tools.. I wrote mine,
156 [wendy](http://blog.z3bra.org/2014/03/toolbox.html#wendy), but there are other.
157 Just take a look at this [reddit
158 thread](http://www.reddit.com/r/linux/comments/1y5iqy/wendy_watch_files_in_your_file_system_and_launch/)
159 to find out more.
160
161 So let's define the environnment. There is that directory:
162
163 $ ls ~/var/mail/INBOX
164 cur/ new/ tmp/
165
166 I use `fdm` (see [this blog
167 post](http://blog.z3bra.org/2013/11/plain-old-mails.html) to retrieve my mails
168 from my POP3 server. Each new mail creates a file in `~/var/mail/INBOX/new`, so
169 we will just need to watch file creation in that folder, and pop a notification
170 at each new mail. It's done like this in my `~/.xinitrc`
171
172 # .xinitrc
173 # note that $MAIL is set to my inbox through my ~/.profile
174 wendy -m 256 -q -f ${MAIL}/new -e popup 'new mail(s)!' &
175
176 And there we go. each time `fdm` will fetch mails to your inbox, a wild popup
177 will appear!
178
179 ### key presses
180 The last type of popup I use is those that occur when a key is pressed. The best
181 exemple for that are the volume keys. I don't know how you handle this, but
182 personnally, <s>I use `xbindkeys` for that. It's a software that let the user map
183 commands to hotkeys, which is totally useful for everything. I know some people
184 (`bspwm` users, mostly) use baskerville's `sxhkd` to do so. I have nothing against this soft, but it will just not cut it here. For further explanations, see [this comment
185 @nixers.net](http://nixers.net/showthread.php?tid=888&pid=9444#pid9444).</s>
186 ([/u/jumpwah](http://reddit.com/u/jumpwah) pointed that `sxhkd` can run
187 multiple commands using a single keybind, as shown in
188 [`examples/sxhkdrc`](https://github.com/baskerville/bspwm/blob/master/examples/sxhkdrc#L26-29)).
189
190 So, if you already use `xbindkeys` to change your volume level, probably already
191 know what to do.
192
193 I personally have a script to manage my volume level:
194
195 #!/bin/sh
196 #
197 # z3bra - (c) wtfpl 2014
198 # Manage ALSA Master channel
199
200 test "$1" = "-h" && echo "usage `basename $0` [+|-|!]" && exit 0
201
202 level() {
203 amixer get Master | sed -n 's/^.*\[\([0-9]\+%\).*$/\1/p' | uniq
204 }
205
206 state() {
207 amixer get Master | sed -n 's/^.*\[\(o[nf]\+\)]$/\1/p' | uniq
208 }
209
210 test $# -eq 0 && echo "`level` `state`" && exit 0
211
212 case $1 in
213 +) amixer set Master 5%+ >/dev/null;;
214 -) amixer set Master 5%- >/dev/null;;
215 !) amixer set Master toggle >/dev/null;;
216 state|level) $1;;
217 *) amixer set Master $1 >/dev/null;;
218 esac
219
220 It's quite simple. `volume +|-` will raise|lower volume, `volume !` will toggle
221 on/off, `volume level|state` will output the level or state, and `volume
222 whatever` will execute `whatever` through amixer (exemple: `volume on|off`).
223
224 Back to the topic. Here is my `.xbindkeysrc`
225
226 "~/bin/volume +"
227 XF86AudioRaiseVolume
228
229 "~/bin/volume -"
230 XF86AudioLowerVolume
231
232 "~/bin/volume !"
233 XF86AudioMute
234
235 "~/bin/popup volume: $(~/bin/volume level)"
236 XF86AudioRaiseVolume
237
238 "~/bin/popup volume: $(~/bin/volume level)"
239 XF86AudioLowerVolume
240
241 "~/bin/popup volume: $(~/bin/volume level)"
242 XF86AudioMute
243
244 There, simple. The popup command is bound to my volume keys, so each time I
245 press them, the notification comes up! It's quite simple.
246
247 ## Improvements
248 This system is not perfect at all, because popup overlap, the width and timing
249 is fixed, ... But it's also a bare simple system, easily hackable. You could use
250 it to build a more complex system on top of that. For example, you can easily
251 write a simple daemon that will read messages from a fifo and stack popups
252 together:
253
254
255 #!/bin/sh
256 #
257 # z3bra - (c) wtfpl 2014
258 # Popup wrapper used to stack notifications together
259
260 # fifo that we'll use to feed the popups
261 test -p /tmp/popup.fifo || mkfifo /tmp/popup.fifo
262
263 # popup definition
264 w=150
265 h=20
266 x=1930
267 y=10
268
269 # popup counter (starts at -1 so that the first popup has no offset
270 n=-1
271
272 # get messages from the fifo
273 tail -f /tmp/popup.fifo | while IFS= read -r message; do
274 # increment the counter
275 n=$((n + 1))
276
277 {
278 # display the popup under the others
279 ~/bin/popup -g ${w}x${h}+${x}+$((y + (h+y) * n)) $n ${message}
280
281 # decrement the counter
282 n=$((n - 1))
283 } &
284 done
285
286 Then, write your messages to `/tmp/popup.fifo` to see your popup stacking
287 together (`echo shblah > /tmp/popup.fifo`). It will probably require
288 improvements, but it's a good starting point!
289
290 Here are a few other ideas I had (but did not bother trying :P):
291
292 * Using [txtw](https://github.com/baskerville/txtw) to change width dynamically
293 * Make use of the clickable area of `bar` to get rid of the popup
294 * Make long notifications scroll using `skroll`
295 * shampoo / soap
296 * 4 apples
297 * <del>some fresh meat</del> <em>Ah, wrong list...</em>
298 * ...
299 * Be creative, as usual!
300
301 ## Good bye
302 I hope this will be helpful to someone. It's not meant to make you throw your
303 status bar away, or switch from libnotify and such. It's just a bare simple
304 alternative to those, as I like to have :)
305
306 [](http://pub.z3bra.org/monochromatic/img/2014-04-30-popup-showoff.png)
308 *Here is a little show case of what you can achieve. I
309 used `stlarch_font` for the icon.
310 the first popup is the volume bar. It goes red when it's muted.
311 Next is a new mail (spawned via `touch $MAIL/new/shblah`). And finally, the
312 battery level, bound to a key for the purpose of the gif. Otherwise it only
313 shows up under 15% (written in red)*
314
315 Enjoy!