diff options
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r-- | swaybar/bar.c | 135 |
1 files changed, 101 insertions, 34 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index abde1cc9..cdaf6a37 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -7,10 +7,17 @@ | |||
7 | #include <sys/wait.h> | 7 | #include <sys/wait.h> |
8 | #include <signal.h> | 8 | #include <signal.h> |
9 | #include <poll.h> | 9 | #include <poll.h> |
10 | #ifdef ENABLE_TRAY | ||
11 | #include <dbus/dbus.h> | ||
12 | #include "swaybar/tray/sni_watcher.h" | ||
13 | #include "swaybar/tray/tray.h" | ||
14 | #include "swaybar/tray/sni.h" | ||
15 | #endif | ||
10 | #include "swaybar/ipc.h" | 16 | #include "swaybar/ipc.h" |
11 | #include "swaybar/render.h" | 17 | #include "swaybar/render.h" |
12 | #include "swaybar/config.h" | 18 | #include "swaybar/config.h" |
13 | #include "swaybar/status_line.h" | 19 | #include "swaybar/status_line.h" |
20 | #include "swaybar/event_loop.h" | ||
14 | #include "swaybar/bar.h" | 21 | #include "swaybar/bar.h" |
15 | #include "ipc-client.h" | 22 | #include "ipc-client.h" |
16 | #include "list.h" | 23 | #include "list.h" |
@@ -50,18 +57,39 @@ static void spawn_status_cmd_proc(struct bar *bar) { | |||
50 | } | 57 | } |
51 | } | 58 | } |
52 | 59 | ||
60 | #ifdef ENABLE_TRAY | ||
61 | static void spawn_xembed_sni_proxy() { | ||
62 | pid_t pid = fork(); | ||
63 | if (pid == 0) { | ||
64 | int wstatus; | ||
65 | do { | ||
66 | pid = fork(); | ||
67 | if (pid == 0) { | ||
68 | execlp("xembedsniproxy", "xembedsniproxy", NULL); | ||
69 | _exit(EXIT_FAILURE); | ||
70 | } | ||
71 | waitpid(pid, &wstatus, 0); | ||
72 | } while (!WIFEXITED(wstatus)); | ||
73 | _exit(EXIT_FAILURE); | ||
74 | } | ||
75 | } | ||
76 | #endif | ||
77 | |||
53 | struct output *new_output(const char *name) { | 78 | struct output *new_output(const char *name) { |
54 | struct output *output = malloc(sizeof(struct output)); | 79 | struct output *output = malloc(sizeof(struct output)); |
55 | output->name = strdup(name); | 80 | output->name = strdup(name); |
56 | output->window = NULL; | 81 | output->window = NULL; |
57 | output->registry = NULL; | 82 | output->registry = NULL; |
58 | output->workspaces = create_list(); | 83 | output->workspaces = create_list(); |
84 | #ifdef ENABLE_TRAY | ||
85 | output->items = create_list(); | ||
86 | #endif | ||
59 | return output; | 87 | return output; |
60 | } | 88 | } |
61 | 89 | ||
62 | static void mouse_button_notify(struct window *window, int x, int y, | 90 | static void mouse_button_notify(struct window *window, int x, int y, |
63 | uint32_t button, uint32_t state_w) { | 91 | uint32_t button, uint32_t state_w) { |
64 | sway_log(L_DEBUG, "Mouse button %d clicked at %d %d %d\n", button, x, y, state_w); | 92 | sway_log(L_DEBUG, "Mouse button %d clicked at %d %d %d", button, x, y, state_w); |
65 | if (!state_w) { | 93 | if (!state_w) { |
66 | return; | 94 | return; |
67 | } | 95 | } |
@@ -92,6 +120,30 @@ static void mouse_button_notify(struct window *window, int x, int y, | |||
92 | break; | 120 | break; |
93 | } | 121 | } |
94 | } | 122 | } |
123 | |||
124 | #ifdef ENABLE_TRAY | ||
125 | uint32_t tray_padding = swaybar.config->tray_padding; | ||
126 | int tray_width = window->width * window->scale; | ||
127 | |||
128 | for (int i = 0; i < clicked_output->items->length; ++i) { | ||
129 | struct sni_icon_ref *item = | ||
130 | clicked_output->items->items[i]; | ||
131 | int icon_width = cairo_image_surface_get_width(item->icon); | ||
132 | |||
133 | tray_width -= tray_padding; | ||
134 | if (x <= tray_width && x >= tray_width - icon_width) { | ||
135 | if (button == swaybar.config->activate_button) { | ||
136 | sni_activate(item->ref, x, y); | ||
137 | } else if (button == swaybar.config->context_button) { | ||
138 | sni_context_menu(item->ref, x, y); | ||
139 | } else if (button == swaybar.config->secondary_button) { | ||
140 | sni_secondary(item->ref, x, y); | ||
141 | } | ||
142 | break; | ||
143 | } | ||
144 | tray_width -= icon_width; | ||
145 | } | ||
146 | #endif | ||
95 | } | 147 | } |
96 | 148 | ||
97 | static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) { | 149 | static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) { |
@@ -136,6 +188,9 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | |||
136 | /* initialize bar with default values */ | 188 | /* initialize bar with default values */ |
137 | bar_init(bar); | 189 | bar_init(bar); |
138 | 190 | ||
191 | /* Initialize event loop lists */ | ||
192 | init_event_loop(); | ||
193 | |||
139 | /* connect to sway ipc */ | 194 | /* connect to sway ipc */ |
140 | bar->ipc_socketfd = ipc_open_socket(socket_path); | 195 | bar->ipc_socketfd = ipc_open_socket(socket_path); |
141 | bar->ipc_event_socketfd = ipc_open_socket(socket_path); | 196 | bar->ipc_event_socketfd = ipc_open_socket(socket_path); |
@@ -178,23 +233,54 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | |||
178 | } | 233 | } |
179 | /* spawn status command */ | 234 | /* spawn status command */ |
180 | spawn_status_cmd_proc(bar); | 235 | spawn_status_cmd_proc(bar); |
236 | |||
237 | #ifdef ENABLE_TRAY | ||
238 | // We should have at least one output to serve the tray to | ||
239 | if (!swaybar.config->tray_output || strcmp(swaybar.config->tray_output, "none") != 0) { | ||
240 | /* Connect to the D-Bus */ | ||
241 | dbus_init(); | ||
242 | |||
243 | /* Start the SNI watcher */ | ||
244 | init_sni_watcher(); | ||
245 | |||
246 | /* Start the SNI host */ | ||
247 | init_tray(); | ||
248 | |||
249 | /* Start xembedsniproxy */ | ||
250 | spawn_xembed_sni_proxy(); | ||
251 | } | ||
252 | #endif | ||
181 | } | 253 | } |
182 | 254 | ||
183 | void bar_run(struct bar *bar) { | 255 | bool dirty = true; |
184 | int pfds = bar->outputs->length + 2; | ||
185 | struct pollfd *pfd = malloc(pfds * sizeof(struct pollfd)); | ||
186 | bool dirty = true; | ||
187 | 256 | ||
188 | pfd[0].fd = bar->ipc_event_socketfd; | 257 | static void respond_ipc(int fd, short mask, void *_bar) { |
189 | pfd[0].events = POLLIN; | 258 | struct bar *bar = (struct bar *)_bar; |
190 | pfd[1].fd = bar->status_read_fd; | 259 | sway_log(L_DEBUG, "Got IPC event."); |
191 | pfd[1].events = POLLIN; | 260 | dirty = handle_ipc_event(bar); |
261 | } | ||
262 | |||
263 | static void respond_command(int fd, short mask, void *_bar) { | ||
264 | struct bar *bar = (struct bar *)_bar; | ||
265 | dirty = handle_status_line(bar); | ||
266 | } | ||
267 | |||
268 | static void respond_output(int fd, short mask, void *_output) { | ||
269 | struct output *output = (struct output *)_output; | ||
270 | if (wl_display_dispatch(output->registry->display) == -1) { | ||
271 | sway_log(L_ERROR, "failed to dispatch wl: %d", errno); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | void bar_run(struct bar *bar) { | ||
276 | add_event(bar->ipc_event_socketfd, POLLIN, respond_ipc, bar); | ||
277 | add_event(bar->status_read_fd, POLLIN, respond_command, bar); | ||
192 | 278 | ||
193 | int i; | 279 | int i; |
194 | for (i = 0; i < bar->outputs->length; ++i) { | 280 | for (i = 0; i < bar->outputs->length; ++i) { |
195 | struct output *output = bar->outputs->items[i]; | 281 | struct output *output = bar->outputs->items[i]; |
196 | pfd[i+2].fd = wl_display_get_fd(output->registry->display); | 282 | add_event(wl_display_get_fd(output->registry->display), |
197 | pfd[i+2].events = POLLIN; | 283 | POLLIN, respond_output, output); |
198 | } | 284 | } |
199 | 285 | ||
200 | while (1) { | 286 | while (1) { |
@@ -212,29 +298,10 @@ void bar_run(struct bar *bar) { | |||
212 | 298 | ||
213 | dirty = false; | 299 | dirty = false; |
214 | 300 | ||
215 | poll(pfd, pfds, -1); | 301 | event_loop_poll(); |
216 | 302 | #ifdef ENABLE_TRAY | |
217 | if (pfd[0].revents & POLLIN) { | 303 | dispatch_dbus(); |
218 | sway_log(L_DEBUG, "Got IPC event."); | 304 | #endif |
219 | dirty = handle_ipc_event(bar); | ||
220 | } | ||
221 | |||
222 | if (bar->config->status_command && pfd[1].revents & POLLIN) { | ||
223 | sway_log(L_DEBUG, "Got update from status command."); | ||
224 | dirty = handle_status_line(bar); | ||
225 | } | ||
226 | |||
227 | // dispatch wl_display events | ||
228 | for (i = 0; i < bar->outputs->length; ++i) { | ||
229 | struct output *output = bar->outputs->items[i]; | ||
230 | if (pfd[i+2].revents & POLLIN) { | ||
231 | if (wl_display_dispatch(output->registry->display) == -1) { | ||
232 | sway_log(L_ERROR, "failed to dispatch wl: %d", errno); | ||
233 | } | ||
234 | } else { | ||
235 | wl_display_dispatch_pending(output->registry->display); | ||
236 | } | ||
237 | } | ||
238 | } | 305 | } |
239 | } | 306 | } |
240 | 307 | ||