summaryrefslogtreecommitdiff
path: root/README.md
blob: 683bde656dbb6bcaf9324b42fe22eb91518134a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# mktrayicon

`mktrayicon` is a simple proxy program that lets you create and modify system
tray icons without having to deal with a graphical toolkit like GTK.

`mktrayicon` expects to be given a name pipe (FIFO) file path when it is
started, and you control your status icon by writing to this named pipe. *Note
that the pipe should already be created before you call `mktrayicon`*.

Every line written to the pipe should contain a single letter specifying what
operation to perform, optionally followed by a space and a parameter to the
command. Each command should be terminated by a newline. The following commands
are supported:

  - `q`: Terminate `mktrayicon` and remove the tray icon
  - `i <icon>`: Set the graphic to use for the tray icon (see `/usr/share/icons`)
  - `t <text>`: Set the text to display in the icon tooltip
  - `t`: Remove the icon tooltip
  - `c <cmnd>`: Set the command to be execute when the user clicks the icon (`cmnd` is passed to `/bin/sh -c`)
  - `c`: Remove the click handler
  - `h`: Hide the tray icon
  - `s`: Show the tray icon

By default, the `none` tooltip icon is used. To change this, pass `-i
<icon_name>` when running `mktrayicon`.

Note that any script communicating with `mktrayicon` **must**, for the time
being, send `q` when they are done. Just removing the FIFO file will **not**
cause the tray icon to be removed.

## Why?

Because I wanted to be able to create tray icons from bash without all the
hassle of interacting with GTK. Now I can create scripts for measuring stuff and
instantly make tray icons out of them (3G signal strength for example).

## Example run

This example is also in `example.sh` so you can try running it.

```bash
#!/bin/bash

# Set up tray icon
mkfifo /tmp/$$.icon
./mktrayicon /tmp/$$.icon &

# Manipulate tray icon

# Click handling
echo "c xterm -e /bin/sh -c 'iwconfig; read'" > /tmp/$$.icon

# Change the icon and tooltip
for i in none weak ok good excellent; do
  echo "i network-wireless-signal-$i-symbolic" > /tmp/$$.icon
  echo "t Signal strength: $i" > /tmp/$$.icon
  sleep 2
done

# Remove tooltip and click handler
echo "c" > /tmp/$$.icon
echo "t" > /tmp/$$.icon

# Toggle the visibility of the icon for a bit
for i in {1..3}; do
  for j in h s; do
    echo $j > /tmp/$$.icon
    sleep 1
  done
done

# Remove tray icon
echo "q" > /tmp/$$.icon
rm /tmp/$$.icon
```

## Known bugs

This is my first time using the GTK+ C library, and I've got to say it is less
than pleasant to work with. My biggest issue has been trying to do blocking IO
without blocking the GUI thread, as GTK seems to not like that. They've
deprecated most of the threading stuff, and only left this
`g_main_context_invoke` mess, which doesn't even seem to work all of the time.

So, every now and again, the program will just die completely with one of the
following messages:

```
Xlib: sequence lost (0x100c1 > 0xc3) in reply type 0x1c!
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.

[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
mktrayicon: xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.

Xlib: sequence lost (0x100c1 > 0xc3) in reply type 0x1c!
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
mktrayicon: xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
```

If someone has a genious way to fix this, patches are welcome.

Also, it would be nice if removing the FIFO file would cause `mktrayicon` to
exit automatically as if "q" was sent. Unfortunately, this is not entirely
trivial to implement. Have a look
[here](http://stackoverflow.com/questions/18643486/detect-deletion-of-fifo-file-with-blocking-open)
and send a patch my way if you know how to do it.
bgstack15