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 /include | |
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 'include')
-rw-r--r-- | include/client/cairo.h | 2 | ||||
-rw-r--r-- | include/sway/commands.h | 4 | ||||
-rw-r--r-- | include/sway/config.h | 12 | ||||
-rw-r--r-- | include/swaybar/bar.h | 6 | ||||
-rw-r--r-- | include/swaybar/config.h | 11 | ||||
-rw-r--r-- | include/swaybar/event_loop.h | 26 | ||||
-rw-r--r-- | include/swaybar/tray/dbus.h | 18 | ||||
-rw-r--r-- | include/swaybar/tray/icon.h | 16 | ||||
-rw-r--r-- | include/swaybar/tray/sni.h | 81 | ||||
-rw-r--r-- | include/swaybar/tray/sni_watcher.h | 10 | ||||
-rw-r--r-- | include/swaybar/tray/tray.h | 26 |
11 files changed, 211 insertions, 1 deletions
diff --git a/include/client/cairo.h b/include/client/cairo.h index 46c53566..e7ef7c7e 100644 --- a/include/client/cairo.h +++ b/include/client/cairo.h | |||
@@ -6,6 +6,8 @@ | |||
6 | 6 | ||
7 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color); | 7 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color); |
8 | 8 | ||
9 | cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, int width, int height); | ||
10 | |||
9 | #ifdef WITH_GDK_PIXBUF | 11 | #ifdef WITH_GDK_PIXBUF |
10 | #include <gdk-pixbuf/gdk-pixbuf.h> | 12 | #include <gdk-pixbuf/gdk-pixbuf.h> |
11 | 13 | ||
diff --git a/include/sway/commands.h b/include/sway/commands.h index 078652e7..f67df10f 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -157,17 +157,21 @@ sway_cmd cmd_workspace; | |||
157 | sway_cmd cmd_ws_auto_back_and_forth; | 157 | sway_cmd cmd_ws_auto_back_and_forth; |
158 | sway_cmd cmd_workspace_layout; | 158 | sway_cmd cmd_workspace_layout; |
159 | 159 | ||
160 | sway_cmd bar_cmd_activate_button; | ||
160 | sway_cmd bar_cmd_binding_mode_indicator; | 161 | sway_cmd bar_cmd_binding_mode_indicator; |
161 | sway_cmd bar_cmd_bindsym; | 162 | sway_cmd bar_cmd_bindsym; |
162 | sway_cmd bar_cmd_colors; | 163 | sway_cmd bar_cmd_colors; |
164 | sway_cmd bar_cmd_context_button; | ||
163 | sway_cmd bar_cmd_font; | 165 | sway_cmd bar_cmd_font; |
164 | sway_cmd bar_cmd_mode; | 166 | sway_cmd bar_cmd_mode; |
165 | sway_cmd bar_cmd_modifier; | 167 | sway_cmd bar_cmd_modifier; |
166 | sway_cmd bar_cmd_output; | 168 | sway_cmd bar_cmd_output; |
167 | sway_cmd bar_cmd_height; | 169 | sway_cmd bar_cmd_height; |
168 | sway_cmd bar_cmd_hidden_state; | 170 | sway_cmd bar_cmd_hidden_state; |
171 | sway_cmd bar_cmd_icon_theme; | ||
169 | sway_cmd bar_cmd_id; | 172 | sway_cmd bar_cmd_id; |
170 | sway_cmd bar_cmd_position; | 173 | sway_cmd bar_cmd_position; |
174 | sway_cmd bar_cmd_secondary_button; | ||
171 | sway_cmd bar_cmd_separator_symbol; | 175 | sway_cmd bar_cmd_separator_symbol; |
172 | sway_cmd bar_cmd_status_command; | 176 | sway_cmd bar_cmd_status_command; |
173 | sway_cmd bar_cmd_pango_markup; | 177 | sway_cmd bar_cmd_pango_markup; |
diff --git a/include/sway/config.h b/include/sway/config.h index 35f8d5f7..999a471a 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -133,7 +133,17 @@ struct bar_config { | |||
133 | char *swaybar_command; | 133 | char *swaybar_command; |
134 | char *font; | 134 | char *font; |
135 | int height; // -1 not defined | 135 | int height; // -1 not defined |
136 | int tray_padding; | 136 | |
137 | #ifdef ENABLE_TRAY | ||
138 | // Tray | ||
139 | char *tray_output; | ||
140 | char *icon_theme; | ||
141 | uint32_t tray_padding; | ||
142 | uint32_t activate_button; | ||
143 | uint32_t context_button; | ||
144 | uint32_t secondary_button; | ||
145 | #endif | ||
146 | |||
137 | bool workspace_buttons; | 147 | bool workspace_buttons; |
138 | bool wrap_scroll; | 148 | bool wrap_scroll; |
139 | char *separator_symbol; | 149 | char *separator_symbol; |
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index 697a48c2..010e1f84 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h | |||
@@ -21,6 +21,9 @@ struct output { | |||
21 | struct window *window; | 21 | struct window *window; |
22 | struct registry *registry; | 22 | struct registry *registry; |
23 | list_t *workspaces; | 23 | list_t *workspaces; |
24 | #ifdef ENABLE_TRAY | ||
25 | list_t *items; | ||
26 | #endif | ||
24 | char *name; | 27 | char *name; |
25 | int idx; | 28 | int idx; |
26 | bool focused; | 29 | bool focused; |
@@ -37,6 +40,9 @@ struct workspace { | |||
37 | /** Global bar state */ | 40 | /** Global bar state */ |
38 | extern struct bar swaybar; | 41 | extern struct bar swaybar; |
39 | 42 | ||
43 | /** True if sway needs to render */ | ||
44 | extern bool dirty; | ||
45 | |||
40 | /** | 46 | /** |
41 | * Setup bar. | 47 | * Setup bar. |
42 | */ | 48 | */ |
diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 04b12cd4..651f0ee3 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h | |||
@@ -33,6 +33,17 @@ struct config { | |||
33 | bool all_outputs; | 33 | bool all_outputs; |
34 | list_t *outputs; | 34 | list_t *outputs; |
35 | 35 | ||
36 | #ifdef ENABLE_TRAY | ||
37 | // Tray | ||
38 | char *tray_output; | ||
39 | char *icon_theme; | ||
40 | |||
41 | uint32_t tray_padding; | ||
42 | uint32_t activate_button; | ||
43 | uint32_t context_button; | ||
44 | uint32_t secondary_button; | ||
45 | #endif | ||
46 | |||
36 | int height; | 47 | int height; |
37 | 48 | ||
38 | struct { | 49 | struct { |
diff --git a/include/swaybar/event_loop.h b/include/swaybar/event_loop.h new file mode 100644 index 00000000..a0cde07f --- /dev/null +++ b/include/swaybar/event_loop.h | |||
@@ -0,0 +1,26 @@ | |||
1 | #ifndef _SWAYBAR_EVENT_LOOP_H | ||
2 | #define _SWAYBAR_EVENT_LOOP_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | #include <time.h> | ||
6 | |||
7 | void add_event(int fd, short mask, | ||
8 | void(*cb)(int fd, short mask, void *data), | ||
9 | void *data); | ||
10 | |||
11 | // Not guaranteed to notify cb immediately | ||
12 | void add_timer(timer_t timer, | ||
13 | void(*cb)(timer_t timer, void *data), | ||
14 | void *data); | ||
15 | |||
16 | // Returns false if nothing exists, true otherwise | ||
17 | bool remove_event(int fd); | ||
18 | |||
19 | // Returns false if nothing exists, true otherwise | ||
20 | bool remove_timer(timer_t timer); | ||
21 | |||
22 | // Blocks and returns after sending callbacks | ||
23 | void event_loop_poll(); | ||
24 | |||
25 | void init_event_loop(); | ||
26 | #endif /*_SWAYBAR_EVENT_LOOP_H */ | ||
diff --git a/include/swaybar/tray/dbus.h b/include/swaybar/tray/dbus.h new file mode 100644 index 00000000..eb9cfea7 --- /dev/null +++ b/include/swaybar/tray/dbus.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _SWAYBAR_DBUS_H | ||
2 | #define _SWAYBAR_DBUS_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | #include <dbus/dbus.h> | ||
6 | extern DBusConnection *conn; | ||
7 | |||
8 | /** | ||
9 | * Should be called in main loop to dispatch events | ||
10 | */ | ||
11 | void dispatch_dbus(); | ||
12 | |||
13 | /** | ||
14 | * Initializes async dbus communication | ||
15 | */ | ||
16 | int dbus_init(); | ||
17 | |||
18 | #endif /* _SWAYBAR_DBUS_H */ | ||
diff --git a/include/swaybar/tray/icon.h b/include/swaybar/tray/icon.h new file mode 100644 index 00000000..1cc6ff9c --- /dev/null +++ b/include/swaybar/tray/icon.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _SWAYBAR_ICON_H | ||
2 | #define _SWAYBAR_ICON_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | #include <stdbool.h> | ||
6 | #include <client/cairo.h> | ||
7 | |||
8 | /** | ||
9 | * Returns the image found by `name` that is closest to `size` | ||
10 | */ | ||
11 | cairo_surface_t *find_icon(const char *name, int size); | ||
12 | |||
13 | /* Struct used internally only */ | ||
14 | struct subdir; | ||
15 | |||
16 | #endif /* _SWAYBAR_ICON_H */ | ||
diff --git a/include/swaybar/tray/sni.h b/include/swaybar/tray/sni.h new file mode 100644 index 00000000..83809b2d --- /dev/null +++ b/include/swaybar/tray/sni.h | |||
@@ -0,0 +1,81 @@ | |||
1 | #ifndef _SWAYBAR_SNI_H | ||
2 | #define _SWAYBAR_SNI_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | #include <client/cairo.h> | ||
6 | |||
7 | struct StatusNotifierItem { | ||
8 | /* Name registered to sni watcher */ | ||
9 | char *name; | ||
10 | /* Unique bus name, needed for determining signal origins */ | ||
11 | char *unique_name; | ||
12 | bool kde_special_snowflake; | ||
13 | |||
14 | cairo_surface_t *image; | ||
15 | bool dirty; | ||
16 | }; | ||
17 | |||
18 | /* Each output holds an sni_icon_ref of each item to render */ | ||
19 | struct sni_icon_ref { | ||
20 | cairo_surface_t *icon; | ||
21 | struct StatusNotifierItem *ref; | ||
22 | }; | ||
23 | |||
24 | struct sni_icon_ref *sni_icon_ref_create(struct StatusNotifierItem *item, | ||
25 | int height); | ||
26 | |||
27 | void sni_icon_ref_free(struct sni_icon_ref *sni_ref); | ||
28 | |||
29 | /** | ||
30 | * Will return a new item and get its icon. (see warning below) | ||
31 | */ | ||
32 | struct StatusNotifierItem *sni_create(const char *name); | ||
33 | |||
34 | /** | ||
35 | * `item` must be a struct StatusNotifierItem * | ||
36 | * `str` must be a NUL terminated char * | ||
37 | * | ||
38 | * Returns 0 if `item` has a name of `str` | ||
39 | */ | ||
40 | int sni_str_cmp(const void *item, const void *str); | ||
41 | |||
42 | /** | ||
43 | * Returns 0 if `item` has a unique name of `str` or if | ||
44 | * `item->unique_name == NULL` | ||
45 | */ | ||
46 | int sni_uniq_cmp(const void *item, const void *str); | ||
47 | |||
48 | /** | ||
49 | * Gets an icon for the given item if found. | ||
50 | * | ||
51 | * XXX | ||
52 | * This function keeps a reference to the item until it gets responses, make | ||
53 | * sure that the reference and item are valid during this time. | ||
54 | */ | ||
55 | void get_icon(struct StatusNotifierItem *item); | ||
56 | |||
57 | /** | ||
58 | * Calls the "activate" method on the given StatusNotifierItem | ||
59 | * | ||
60 | * x and y should be where the item was clicked | ||
61 | */ | ||
62 | void sni_activate(struct StatusNotifierItem *item, uint32_t x, uint32_t y); | ||
63 | |||
64 | /** | ||
65 | * Asks the item to draw a context menu at the given x and y coords | ||
66 | */ | ||
67 | void sni_context_menu(struct StatusNotifierItem *item, uint32_t x, uint32_t y); | ||
68 | |||
69 | /** | ||
70 | * Calls the "secondary activate" method on the given StatusNotifierItem | ||
71 | * | ||
72 | * x and y should be where the item was clicked | ||
73 | */ | ||
74 | void sni_secondary(struct StatusNotifierItem *item, uint32_t x, uint32_t y); | ||
75 | |||
76 | /** | ||
77 | * Deconstructs `item` | ||
78 | */ | ||
79 | void sni_free(struct StatusNotifierItem *item); | ||
80 | |||
81 | #endif /* _SWAYBAR_SNI_H */ | ||
diff --git a/include/swaybar/tray/sni_watcher.h b/include/swaybar/tray/sni_watcher.h new file mode 100644 index 00000000..25ddfcd2 --- /dev/null +++ b/include/swaybar/tray/sni_watcher.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef _SWAYBAR_SNI_WATCHER_H | ||
2 | #define _SWAYBAR_SNI_WATCHER_H | ||
3 | |||
4 | /** | ||
5 | * Starts the sni_watcher, the watcher is practically a black box and should | ||
6 | * only be accessed though functions described in its spec | ||
7 | */ | ||
8 | int init_sni_watcher(); | ||
9 | |||
10 | #endif /* _SWAYBAR_SNI_WATCHER_H */ | ||
diff --git a/include/swaybar/tray/tray.h b/include/swaybar/tray/tray.h new file mode 100644 index 00000000..7d371008 --- /dev/null +++ b/include/swaybar/tray/tray.h | |||
@@ -0,0 +1,26 @@ | |||
1 | #ifndef _SWAYBAR_TRAY_H | ||
2 | #define _SWAYBAR_TRAY_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | #include <stdbool.h> | ||
6 | #include "swaybar/tray/dbus.h" | ||
7 | #include "swaybar/tray/sni.h" | ||
8 | #include "list.h" | ||
9 | |||
10 | extern struct tray *tray; | ||
11 | |||
12 | struct tray { | ||
13 | list_t *items; | ||
14 | }; | ||
15 | |||
16 | /** | ||
17 | * Initializes the tray host with D-Bus | ||
18 | */ | ||
19 | int init_tray(); | ||
20 | |||
21 | /** | ||
22 | * Returns an item if `x` and `y` collide with it and NULL otherwise | ||
23 | */ | ||
24 | struct StatusNotifierItem *collides_with_sni(int x, int y); | ||
25 | |||
26 | #endif /* _SWAYBAR_TRAY_H */ | ||