diff options
author | Calvin Lee <cyrus296@gmail.com> | 2017-06-07 16:45:28 -0700 |
---|---|---|
committer | Calvin Lee <cyrus296@gmail.com> | 2017-06-07 17:49:16 -0700 |
commit | 843ad38b3c427adb0bf319e9613d9813c8d9246c (patch) | |
tree | e02a5b06e2b6923371fd53724791c147c18a1fa4 /sway | |
parent | Merge pull request #1232 from johalun/master-freebsd (diff) | |
download | sway-843ad38b3c427adb0bf319e9613d9813c8d9246c.tar.gz sway-843ad38b3c427adb0bf319e9613d9813c8d9246c.tar.zst sway-843ad38b3c427adb0bf319e9613d9813c8d9246c.zip |
Implement Tray Icons
This commit implements the StatusNotifierItem protocol, and enables
swaybar to show tray icons. It also uses `xembedsniproxy` in order to
communicate with xembed applications.
The tray is completely optional, and can be disabled on compile time
with the `enable-tray` option. Or on runtime with the bar config option
`tray_output none`.
Overview of changes:
In swaybar very little is changed outside the tray subfolder except
that all events are now polled in `event_loop.c`, this creates no
functional difference.
Six bar configuration options were added, these are detailed in
sway-bar(5)
The tray subfolder is where all protocol implementation takes place and
is organised as follows:
tray/sni_watcher.c:
This file contains the StatusNotifierWatcher. It keeps track of
items and hosts and reports when they come or go.
tray/tray.c
This file contains the StatusNotifierHost. It keeps track of
sway's version of the items and represents the tray itself.
tray/sni.c
This file contains the StatusNotifierItem struct and all
communication with individual items.
tray/icon.c
This file implements the icon theme protocol. It allows for
finding icons by name, rather than by pixmap.
tray/dbus.c
This file allows for asynchronous DBus communication.
See #986 #343
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 4 | ||||
-rw-r--r-- | sway/commands/bar/activate_button.c | 26 | ||||
-rw-r--r-- | sway/commands/bar/context_button.c | 26 | ||||
-rw-r--r-- | sway/commands/bar/icon_theme.c | 25 | ||||
-rw-r--r-- | sway/commands/bar/secondary_button.c | 26 | ||||
-rw-r--r-- | sway/commands/bar/tray_output.c | 26 | ||||
-rw-r--r-- | sway/commands/bar/tray_padding.c | 34 | ||||
-rw-r--r-- | sway/config.c | 11 | ||||
-rw-r--r-- | sway/ipc-json.c | 17 | ||||
-rw-r--r-- | sway/sway-bar.5.txt | 36 |
10 files changed, 213 insertions, 18 deletions
diff --git a/sway/commands.c b/sway/commands.c index 34218491..f83b5287 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -221,18 +221,22 @@ static struct cmd_handler handlers[] = { | |||
221 | }; | 221 | }; |
222 | 222 | ||
223 | static struct cmd_handler bar_handlers[] = { | 223 | static struct cmd_handler bar_handlers[] = { |
224 | { "activate_button", bar_cmd_activate_button }, | ||
224 | { "binding_mode_indicator", bar_cmd_binding_mode_indicator }, | 225 | { "binding_mode_indicator", bar_cmd_binding_mode_indicator }, |
225 | { "bindsym", bar_cmd_bindsym }, | 226 | { "bindsym", bar_cmd_bindsym }, |
226 | { "colors", bar_cmd_colors }, | 227 | { "colors", bar_cmd_colors }, |
228 | { "context_button", bar_cmd_context_button }, | ||
227 | { "font", bar_cmd_font }, | 229 | { "font", bar_cmd_font }, |
228 | { "height", bar_cmd_height }, | 230 | { "height", bar_cmd_height }, |
229 | { "hidden_state", bar_cmd_hidden_state }, | 231 | { "hidden_state", bar_cmd_hidden_state }, |
232 | { "icon_theme", bar_cmd_icon_theme }, | ||
230 | { "id", bar_cmd_id }, | 233 | { "id", bar_cmd_id }, |
231 | { "mode", bar_cmd_mode }, | 234 | { "mode", bar_cmd_mode }, |
232 | { "modifier", bar_cmd_modifier }, | 235 | { "modifier", bar_cmd_modifier }, |
233 | { "output", bar_cmd_output }, | 236 | { "output", bar_cmd_output }, |
234 | { "pango_markup", bar_cmd_pango_markup }, | 237 | { "pango_markup", bar_cmd_pango_markup }, |
235 | { "position", bar_cmd_position }, | 238 | { "position", bar_cmd_position }, |
239 | { "secondary_button", bar_cmd_secondary_button }, | ||
236 | { "separator_symbol", bar_cmd_separator_symbol }, | 240 | { "separator_symbol", bar_cmd_separator_symbol }, |
237 | { "status_command", bar_cmd_status_command }, | 241 | { "status_command", bar_cmd_status_command }, |
238 | { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, | 242 | { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, |
diff --git a/sway/commands/bar/activate_button.c b/sway/commands/bar/activate_button.c new file mode 100644 index 00000000..32a1d3e5 --- /dev/null +++ b/sway/commands/bar/activate_button.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include "sway/commands.h" | ||
3 | #include "log.h" | ||
4 | |||
5 | struct cmd_results *bar_cmd_activate_button(int argc, char **argv) { | ||
6 | const char *cmd_name = "activate_button"; | ||
7 | #ifndef ENABLE_TRAY | ||
8 | return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command " | ||
9 | "%s called, but sway was compiled without tray support", | ||
10 | cmd_name, cmd_name); | ||
11 | #else | ||
12 | struct cmd_results *error = NULL; | ||
13 | if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) { | ||
14 | return error; | ||
15 | } | ||
16 | |||
17 | if (!config->current_bar) { | ||
18 | return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); | ||
19 | } | ||
20 | |||
21 | // User should be able to prefix with 0x or whatever they want | ||
22 | config->current_bar->secondary_button = strtoul(argv[0], NULL, 0); | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
25 | #endif | ||
26 | } | ||
diff --git a/sway/commands/bar/context_button.c b/sway/commands/bar/context_button.c new file mode 100644 index 00000000..6d7d7aec --- /dev/null +++ b/sway/commands/bar/context_button.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include "sway/commands.h" | ||
3 | #include "log.h" | ||
4 | |||
5 | struct cmd_results *bar_cmd_context_button(int argc, char **argv) { | ||
6 | const char *cmd_name = "context_button"; | ||
7 | #ifndef ENABLE_TRAY | ||
8 | return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command " | ||
9 | "%s called, but sway was compiled without tray support", | ||
10 | cmd_name, cmd_name); | ||
11 | #else | ||
12 | struct cmd_results *error = NULL; | ||
13 | if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) { | ||
14 | return error; | ||
15 | } | ||
16 | |||
17 | if (!config->current_bar) { | ||
18 | return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); | ||
19 | } | ||
20 | |||
21 | // User should be able to prefix with 0x or whatever they want | ||
22 | config->current_bar->context_button = strtoul(argv[0], NULL, 0); | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
25 | #endif | ||
26 | } | ||
diff --git a/sway/commands/bar/icon_theme.c b/sway/commands/bar/icon_theme.c new file mode 100644 index 00000000..cbfc0be5 --- /dev/null +++ b/sway/commands/bar/icon_theme.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <string.h> | ||
3 | #include "sway/commands.h" | ||
4 | |||
5 | struct cmd_results *bar_cmd_icon_theme(int argc, char **argv) { | ||
6 | const char *cmd_name = "tray_output"; | ||
7 | #ifndef ENABLE_TRAY | ||
8 | return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command " | ||
9 | "%s called, but sway was compiled without tray support", | ||
10 | cmd_name, cmd_name); | ||
11 | #else | ||
12 | struct cmd_results *error = NULL; | ||
13 | if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) { | ||
14 | return error; | ||
15 | } | ||
16 | |||
17 | if (!config->current_bar) { | ||
18 | return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); | ||
19 | } | ||
20 | |||
21 | config->current_bar->icon_theme = strdup(argv[0]); | ||
22 | |||
23 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
24 | #endif | ||
25 | } | ||
diff --git a/sway/commands/bar/secondary_button.c b/sway/commands/bar/secondary_button.c new file mode 100644 index 00000000..745045c5 --- /dev/null +++ b/sway/commands/bar/secondary_button.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include "sway/commands.h" | ||
3 | #include "log.h" | ||
4 | |||
5 | struct cmd_results *bar_cmd_secondary_button(int argc, char **argv) { | ||
6 | const char *cmd_name = "secondary_button"; | ||
7 | #ifndef ENABLE_TRAY | ||
8 | return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command " | ||
9 | "%s called, but sway was compiled without tray support", | ||
10 | cmd_name, cmd_name); | ||
11 | #else | ||
12 | struct cmd_results *error = NULL; | ||
13 | if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) { | ||
14 | return error; | ||
15 | } | ||
16 | |||
17 | if (!config->current_bar) { | ||
18 | return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); | ||
19 | } | ||
20 | |||
21 | // User should be able to prefix with 0x or whatever they want | ||
22 | config->current_bar->secondary_button = strtoul(argv[0], NULL, 0); | ||
23 | |||
24 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
25 | #endif | ||
26 | } | ||
diff --git a/sway/commands/bar/tray_output.c b/sway/commands/bar/tray_output.c index 8a1b5d35..012304a9 100644 --- a/sway/commands/bar/tray_output.c +++ b/sway/commands/bar/tray_output.c | |||
@@ -1,7 +1,29 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <string.h> | ||
1 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
2 | #include "log.h" | ||
3 | 4 | ||
4 | struct cmd_results *bar_cmd_tray_output(int argc, char **argv) { | 5 | struct cmd_results *bar_cmd_tray_output(int argc, char **argv) { |
5 | sway_log(L_ERROR, "Warning: tray_output is not supported on wayland"); | 6 | const char *cmd_name = "tray_output"; |
7 | #ifndef ENABLE_TRAY | ||
8 | return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command " | ||
9 | "%s called, but sway was compiled without tray support", | ||
10 | cmd_name, cmd_name); | ||
11 | #else | ||
12 | struct cmd_results *error = NULL; | ||
13 | if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) { | ||
14 | return error; | ||
15 | } | ||
16 | |||
17 | if (!config->current_bar) { | ||
18 | return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); | ||
19 | } | ||
20 | |||
21 | if (strcmp(argv[0], "all") == 0) { | ||
22 | // Default behaviour | ||
23 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
24 | } | ||
25 | config->current_bar->tray_output = strdup(argv[0]); | ||
26 | |||
6 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 27 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
28 | #endif | ||
7 | } | 29 | } |
diff --git a/sway/commands/bar/tray_padding.c b/sway/commands/bar/tray_padding.c index 8c559f65..ac0572ce 100644 --- a/sway/commands/bar/tray_padding.c +++ b/sway/commands/bar/tray_padding.c | |||
@@ -1,30 +1,34 @@ | |||
1 | #include <stdlib.h> | 1 | #include <stdlib.h> |
2 | #include <string.h> | ||
3 | #include <strings.h> | 2 | #include <strings.h> |
4 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
5 | #include "log.h" | 4 | #include "log.h" |
6 | 5 | ||
7 | struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { | 6 | struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { |
7 | const char *cmd_name = "tray_padding"; | ||
8 | #ifndef ENABLE_TRAY | ||
9 | return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command" | ||
10 | "%s called, but sway was compiled without tray support", | ||
11 | cmd_name, cmd_name); | ||
12 | #else | ||
8 | struct cmd_results *error = NULL; | 13 | struct cmd_results *error = NULL; |
9 | if ((error = checkarg(argc, "tray_padding", EXPECTED_AT_LEAST, 1))) { | 14 | if ((error = checkarg(argc, cmd_name, EXPECTED_AT_LEAST, 1))) { |
10 | return error; | 15 | return error; |
11 | } | 16 | } |
12 | 17 | ||
13 | if (!config->current_bar) { | 18 | if (!config->current_bar) { |
14 | return cmd_results_new(CMD_FAILURE, "tray_padding", "No bar defined."); | 19 | return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined."); |
15 | } | 20 | } |
16 | 21 | ||
17 | int padding = atoi(argv[0]); | 22 | if (argc == 1 || (argc == 2 && strcasecmp("px", argv[1]) == 0)) { |
18 | if (padding < 0) { | 23 | char *inv; |
19 | return cmd_results_new(CMD_INVALID, "tray_padding", | 24 | uint32_t padding = strtoul(argv[0], &inv, 10); |
20 | "Invalid padding value %s, minimum is 0", argv[0]); | 25 | if (*inv == '\0' || strcasecmp(inv, "px") == 0) { |
26 | config->current_bar->tray_padding = padding; | ||
27 | sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id); | ||
28 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
29 | } | ||
21 | } | 30 | } |
22 | 31 | return cmd_results_new(CMD_FAILURE, cmd_name, | |
23 | if (argc > 1 && strcasecmp("px", argv[1]) != 0) { | 32 | "Expected 'tray_padding <padding>[px]'"); |
24 | return cmd_results_new(CMD_INVALID, "tray_padding", | 33 | #endif |
25 | "Unknown unit %s", argv[1]); | ||
26 | } | ||
27 | config->current_bar->tray_padding = padding; | ||
28 | sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id); | ||
29 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
30 | } | 34 | } |
diff --git a/sway/config.c b/sway/config.c index 85823953..e0b65615 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -69,6 +69,10 @@ static void free_bar(struct bar_config *bar) { | |||
69 | } | 69 | } |
70 | free(bar->mode); | 70 | free(bar->mode); |
71 | free(bar->hidden_state); | 71 | free(bar->hidden_state); |
72 | #ifdef ENABLE_TRAY | ||
73 | free(bar->tray_output); | ||
74 | free(bar->icon_theme); | ||
75 | #endif | ||
72 | free(bar->status_command); | 76 | free(bar->status_command); |
73 | free(bar->font); | 77 | free(bar->font); |
74 | free(bar->separator_symbol); | 78 | free(bar->separator_symbol); |
@@ -1386,7 +1390,14 @@ struct bar_config *default_bar_config(void) { | |||
1386 | bar->separator_symbol = NULL; | 1390 | bar->separator_symbol = NULL; |
1387 | bar->strip_workspace_numbers = false; | 1391 | bar->strip_workspace_numbers = false; |
1388 | bar->binding_mode_indicator = true; | 1392 | bar->binding_mode_indicator = true; |
1393 | #ifdef ENABLE_TRAY | ||
1394 | bar->tray_output = NULL; | ||
1395 | bar->icon_theme = NULL; | ||
1389 | bar->tray_padding = 2; | 1396 | bar->tray_padding = 2; |
1397 | bar->activate_button = 0x110; /* BTN_LEFT */ | ||
1398 | bar->context_button = 0x111; /* BTN_RIGHT */ | ||
1399 | bar->secondary_button = 0x112; /* BTN_MIDDLE */ | ||
1400 | #endif | ||
1390 | bar->verbose = false; | 1401 | bar->verbose = false; |
1391 | bar->pid = 0; | 1402 | bar->pid = 0; |
1392 | // set default colors | 1403 | // set default colors |
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 512144a4..31de53f0 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -327,7 +327,22 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { | |||
327 | 327 | ||
328 | json_object *json = json_object_new_object(); | 328 | json_object *json = json_object_new_object(); |
329 | json_object_object_add(json, "id", json_object_new_string(bar->id)); | 329 | json_object_object_add(json, "id", json_object_new_string(bar->id)); |
330 | json_object_object_add(json, "tray_output", NULL); | 330 | #ifdef ENABLE_TRAY |
331 | if (bar->tray_output) { | ||
332 | json_object_object_add(json, "tray_output", json_object_new_string(bar->tray_output)); | ||
333 | } else { | ||
334 | json_object_object_add(json, "tray_output", NULL); | ||
335 | } | ||
336 | if (bar->icon_theme) { | ||
337 | json_object_object_add(json, "icon_theme", json_object_new_string(bar->icon_theme)); | ||
338 | } else { | ||
339 | json_object_object_add(json, "icon_theme", NULL); | ||
340 | } | ||
341 | json_object_object_add(json, "tray_padding", json_object_new_int(bar->tray_padding)); | ||
342 | json_object_object_add(json, "activate_button", json_object_new_int(bar->activate_button)); | ||
343 | json_object_object_add(json, "context_button", json_object_new_int(bar->context_button)); | ||
344 | json_object_object_add(json, "secondary_button", json_object_new_int(bar->secondary_button)); | ||
345 | #endif | ||
331 | json_object_object_add(json, "mode", json_object_new_string(bar->mode)); | 346 | json_object_object_add(json, "mode", json_object_new_string(bar->mode)); |
332 | json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); | 347 | json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); |
333 | json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier))); | 348 | json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier))); |
diff --git a/sway/sway-bar.5.txt b/sway/sway-bar.5.txt index 5a52e7db..29487662 100644 --- a/sway/sway-bar.5.txt +++ b/sway/sway-bar.5.txt | |||
@@ -65,6 +65,42 @@ Commands | |||
65 | **height** <height>:: | 65 | **height** <height>:: |
66 | Sets the height of the bar. Default height will match the font size. | 66 | Sets the height of the bar. Default height will match the font size. |
67 | 67 | ||
68 | Tray | ||
69 | ---- | ||
70 | |||
71 | Swaybar provides a system tray where programs such as NetworkManager, VLC, | ||
72 | Pidgin, etc. can place little icons. The following commands configure | ||
73 | interaction with the tray or individual icons. | ||
74 | The _button_ argument in all following commands is a Linux input event code as | ||
75 | defined in linux/input-event-codes.h. This is because wayland defines button | ||
76 | codes in this manner. | ||
77 | |||
78 | **activate_button** <button>:: | ||
79 | Sets the button to be used for the _activate_ (primary click) tray item | ||
80 | event. By default is BTN_LEFT (0x110). | ||
81 | |||
82 | **context_button** <button>:: | ||
83 | Sets the button to be used for the _context menu_ (right click) tray item | ||
84 | event. By default is BTN_RIGHT (0x111). | ||
85 | |||
86 | **secondary_button** <button>:: | ||
87 | Sets the button to be used for the _secondary_ (middle click) tray item | ||
88 | event. By default is BTN_MIDDLE (0x112). | ||
89 | |||
90 | **tray_output** none|all|<name>:: | ||
91 | Sets the output that the tray will appear on or none. Unlike i3bar, swaybar | ||
92 | should be able to show icons on any number of bars and outputs without | ||
93 | races. Because of this, the default value for this is _all_. | ||
94 | |||
95 | **tray_padding** <px> [px]:: | ||
96 | Sets the pixel padding of the system tray. This padding will surround the | ||
97 | tray on all sides and between each item. The default value for _px_ is 2. | ||
98 | |||
99 | **icon_theme** <name>:: | ||
100 | Sets the icon theme that sway will look for item icons in. This option has | ||
101 | no default value, because sway will always default to the fallback theme, | ||
102 | hicolor. | ||
103 | |||
68 | Colors | 104 | Colors |
69 | ------ | 105 | ------ |
70 | 106 | ||