summaryrefslogtreecommitdiffstats
path: root/swaybar/bar.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r--swaybar/bar.c83
1 files changed, 56 insertions, 27 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 08c386a7..d36367fc 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -1,4 +1,4 @@
1#define _XOPEN_SOURCE 500 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 2#include <assert.h>
3#include <errno.h> 3#include <errno.h>
4#include <fcntl.h> 4#include <fcntl.h>
@@ -11,6 +11,7 @@
11#include <wayland-client.h> 11#include <wayland-client.h>
12#include <wayland-cursor.h> 12#include <wayland-cursor.h>
13#include <wlr/util/log.h> 13#include <wlr/util/log.h>
14#include "config.h"
14#include "swaybar/bar.h" 15#include "swaybar/bar.h"
15#include "swaybar/config.h" 16#include "swaybar/config.h"
16#include "swaybar/i3bar.h" 17#include "swaybar/i3bar.h"
@@ -18,6 +19,9 @@
18#include "swaybar/ipc.h" 19#include "swaybar/ipc.h"
19#include "swaybar/status_line.h" 20#include "swaybar/status_line.h"
20#include "swaybar/render.h" 21#include "swaybar/render.h"
22#if HAVE_TRAY
23#include "swaybar/tray/tray.h"
24#endif
21#include "ipc-client.h" 25#include "ipc-client.h"
22#include "list.h" 26#include "list.h"
23#include "log.h" 27#include "log.h"
@@ -31,6 +35,7 @@ void free_workspaces(struct wl_list *list) {
31 wl_list_for_each_safe(ws, tmp, list, link) { 35 wl_list_for_each_safe(ws, tmp, list, link) {
32 wl_list_remove(&ws->link); 36 wl_list_remove(&ws->link);
33 free(ws->name); 37 free(ws->name);
38 free(ws->label);
34 free(ws); 39 free(ws);
35 } 40 }
36} 41}
@@ -54,6 +59,7 @@ static void swaybar_output_free(struct swaybar_output *output) {
54 free_workspaces(&output->workspaces); 59 free_workspaces(&output->workspaces);
55 wl_list_remove(&output->link); 60 wl_list_remove(&output->link);
56 free(output->name); 61 free(output->name);
62 free(output->identifier);
57 free(output); 63 free(output);
58} 64}
59 65
@@ -119,7 +125,7 @@ static void destroy_layer_surface(struct swaybar_output *output) {
119 output->frame_scheduled = false; 125 output->frame_scheduled = false;
120} 126}
121 127
122static void set_bar_dirty(struct swaybar *bar) { 128void set_bar_dirty(struct swaybar *bar) {
123 struct swaybar_output *output; 129 struct swaybar_output *output;
124 wl_list_for_each(output, &bar->outputs, link) { 130 wl_list_for_each(output, &bar->outputs, link) {
125 set_output_dirty(output); 131 set_output_dirty(output);
@@ -161,13 +167,15 @@ bool determine_bar_visibility(struct swaybar *bar, bool moving_layer) {
161 return visible; 167 return visible;
162} 168}
163 169
164static bool bar_uses_output(struct swaybar *bar, const char *name) { 170static bool bar_uses_output(struct swaybar_output *output) {
165 if (bar->config->all_outputs) { 171 if (output->bar->config->all_outputs) {
166 return true; 172 return true;
167 } 173 }
174 char *identifier = output->identifier;
168 struct config_output *coutput; 175 struct config_output *coutput;
169 wl_list_for_each(coutput, &bar->config->outputs, link) { 176 wl_list_for_each(coutput, &output->bar->config->outputs, link) {
170 if (strcmp(coutput->name, name) == 0) { 177 if (strcmp(coutput->name, output->name) == 0 ||
178 (identifier && strcmp(coutput->name, identifier) == 0)) {
171 return true; 179 return true;
172 } 180 }
173 } 181 }
@@ -195,6 +203,10 @@ static void output_scale(void *data, struct wl_output *wl_output,
195 int32_t factor) { 203 int32_t factor) {
196 struct swaybar_output *output = data; 204 struct swaybar_output *output = data;
197 output->scale = factor; 205 output->scale = factor;
206 if (output == output->bar->pointer.current) {
207 update_cursor(output->bar);
208 render_frame(output);
209 }
198} 210}
199 211
200struct wl_output_listener output_listener = { 212struct wl_output_listener output_listener = {
@@ -206,12 +218,16 @@ struct wl_output_listener output_listener = {
206 218
207static void xdg_output_handle_logical_position(void *data, 219static void xdg_output_handle_logical_position(void *data,
208 struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { 220 struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) {
209 // Who cares 221 struct swaybar_output *output = data;
222 output->output_x = x;
223 output->output_y = y;
210} 224}
211 225
212static void xdg_output_handle_logical_size(void *data, 226static void xdg_output_handle_logical_size(void *data,
213 struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { 227 struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) {
214 // Who cares 228 struct swaybar_output *output = data;
229 output->output_height = height;
230 output->output_width = width;
215} 231}
216 232
217static void xdg_output_handle_done(void *data, 233static void xdg_output_handle_done(void *data,
@@ -220,7 +236,7 @@ static void xdg_output_handle_done(void *data,
220 struct swaybar *bar = output->bar; 236 struct swaybar *bar = output->bar;
221 237
222 assert(output->name != NULL); 238 assert(output->name != NULL);
223 if (!bar_uses_output(bar, output->name)) { 239 if (!bar_uses_output(output)) {
224 swaybar_output_free(output); 240 swaybar_output_free(output);
225 return; 241 return;
226 } 242 }
@@ -245,7 +261,22 @@ static void xdg_output_handle_name(void *data,
245 261
246static void xdg_output_handle_description(void *data, 262static void xdg_output_handle_description(void *data,
247 struct zxdg_output_v1 *xdg_output, const char *description) { 263 struct zxdg_output_v1 *xdg_output, const char *description) {
248 // Who cares 264 // wlroots currently sets the description to `make model serial (name)`
265 // If this changes in the future, this will need to be modified.
266 struct swaybar_output *output = data;
267 free(output->identifier);
268 output->identifier = NULL;
269 char *paren = strrchr(description, '(');
270 if (paren) {
271 size_t length = paren - description;
272 output->identifier = malloc(length);
273 if (!output->identifier) {
274 wlr_log(WLR_ERROR, "Failed to allocate output identifier");
275 return;
276 }
277 strncpy(output->identifier, description, length);
278 output->identifier[length - 1] = '\0';
279 }
249} 280}
250 281
251struct zxdg_output_v1_listener xdg_output_listener = { 282struct zxdg_output_v1_listener xdg_output_listener = {
@@ -272,7 +303,7 @@ static void handle_global(void *data, struct wl_registry *registry,
272 struct swaybar *bar = data; 303 struct swaybar *bar = data;
273 if (strcmp(interface, wl_compositor_interface.name) == 0) { 304 if (strcmp(interface, wl_compositor_interface.name) == 0) {
274 bar->compositor = wl_registry_bind(registry, name, 305 bar->compositor = wl_registry_bind(registry, name,
275 &wl_compositor_interface, 3); 306 &wl_compositor_interface, 4);
276 } else if (strcmp(interface, wl_seat_interface.name) == 0) { 307 } else if (strcmp(interface, wl_seat_interface.name) == 0) {
277 bar->seat = wl_registry_bind(registry, name, 308 bar->seat = wl_registry_bind(registry, name,
278 &wl_seat_interface, 3); 309 &wl_seat_interface, 3);
@@ -354,25 +385,15 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) {
354 wl_display_roundtrip(bar->display); 385 wl_display_roundtrip(bar->display);
355 386
356 struct swaybar_pointer *pointer = &bar->pointer; 387 struct swaybar_pointer *pointer = &bar->pointer;
357
358 int max_scale = 1;
359 struct swaybar_output *output;
360 wl_list_for_each(output, &bar->outputs, link) {
361 if (output->scale > max_scale) {
362 max_scale = output->scale;
363 }
364 }
365
366 pointer->cursor_theme =
367 wl_cursor_theme_load(NULL, 24 * max_scale, bar->shm);
368 assert(pointer->cursor_theme);
369 struct wl_cursor *cursor;
370 cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr");
371 assert(cursor);
372 pointer->cursor_image = cursor->images[0];
373 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); 388 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor);
374 assert(pointer->cursor_surface); 389 assert(pointer->cursor_surface);
375 390
391#if HAVE_TRAY
392 if (!bar->config->tray_hidden) {
393 bar->tray = create_tray(bar);
394 }
395#endif
396
376 if (bar->config->workspace_buttons) { 397 if (bar->config->workspace_buttons) {
377 ipc_get_workspaces(bar); 398 ipc_get_workspaces(bar);
378 } 399 }
@@ -414,6 +435,11 @@ void bar_run(struct swaybar *bar) {
414 loop_add_fd(bar->eventloop, bar->status->read_fd, POLLIN, 435 loop_add_fd(bar->eventloop, bar->status->read_fd, POLLIN,
415 status_in, bar); 436 status_in, bar);
416 } 437 }
438#if HAVE_TRAY
439 if (bar->tray) {
440 loop_add_fd(bar->eventloop, bar->tray->fd, POLLIN, tray_in, bar->tray->bus);
441 }
442#endif
417 while (1) { 443 while (1) {
418 errno = 0; 444 errno = 0;
419 if (wl_display_flush(bar->display) == -1 && errno != EAGAIN) { 445 if (wl_display_flush(bar->display) == -1 && errno != EAGAIN) {
@@ -431,6 +457,9 @@ static void free_outputs(struct wl_list *list) {
431} 457}
432 458
433void bar_teardown(struct swaybar *bar) { 459void bar_teardown(struct swaybar *bar) {
460#if HAVE_TRAY
461 destroy_tray(bar->tray);
462#endif
434 free_outputs(&bar->outputs); 463 free_outputs(&bar->outputs);
435 if (bar->config) { 464 if (bar->config) {
436 free_config(bar->config); 465 free_config(bar->config);