aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/swaybar/bar.h5
-rw-r--r--include/swaybar/i3bar.h34
-rw-r--r--include/swaybar/ipc.h2
-rw-r--r--include/swaybar/status_line.h26
-rw-r--r--sway/commands/bar/binding_mode_indicator.c6
-rw-r--r--swaybar/bar.c14
-rw-r--r--swaybar/i3bar.c2
-rw-r--r--swaybar/ipc.c19
-rw-r--r--swaybar/main.c5
-rw-r--r--swaybar/render.c110
-rw-r--r--swaybar/status_line.c2
11 files changed, 124 insertions, 101 deletions
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h
index 29e96159..20992014 100644
--- a/include/swaybar/bar.h
+++ b/include/swaybar/bar.h
@@ -54,7 +54,6 @@ struct swaybar {
54 struct wl_seat *seat; 54 struct wl_seat *seat;
55 55
56 struct swaybar_config *config; 56 struct swaybar_config *config;
57 struct swaybar_output *focused_output;
58 struct swaybar_pointer pointer; 57 struct swaybar_pointer pointer;
59 struct status_line *status; 58 struct status_line *status;
60 59
@@ -95,9 +94,7 @@ struct swaybar_workspace {
95 bool urgent; 94 bool urgent;
96}; 95};
97 96
98void bar_setup(struct swaybar *bar, 97bool bar_setup(struct swaybar *bar, const char *socket_path, const char *bar_id);
99 const char *socket_path,
100 const char *bar_id);
101void bar_run(struct swaybar *bar); 98void bar_run(struct swaybar *bar);
102void bar_teardown(struct swaybar *bar); 99void bar_teardown(struct swaybar *bar);
103 100
diff --git a/include/swaybar/i3bar.h b/include/swaybar/i3bar.h
new file mode 100644
index 00000000..12d9b317
--- /dev/null
+++ b/include/swaybar/i3bar.h
@@ -0,0 +1,34 @@
1#ifndef _SWAYBAR_I3BAR_H
2#define _SWAYBAR_I3BAR_H
3
4#include "bar.h"
5#include "status_line.h"
6
7struct i3bar_block {
8 struct wl_list link;
9 int ref_count;
10 char *full_text, *short_text, *align;
11 bool urgent;
12 uint32_t *color;
13 int min_width;
14 char *name, *instance;
15 bool separator;
16 int separator_block_width;
17 bool markup;
18 // Airblader features
19 uint32_t background;
20 uint32_t border;
21 int border_top;
22 int border_bottom;
23 int border_left;
24 int border_right;
25};
26
27void i3bar_block_unref(struct i3bar_block *block);
28bool i3bar_handle_readable(struct status_line *status);
29enum hotspot_event_handling i3bar_block_send_click(struct status_line *status,
30 struct i3bar_block *block, int x, int y, enum x11_button button);
31enum x11_button wl_button_to_x11_button(uint32_t button);
32enum x11_button wl_axis_to_x11_button(uint32_t axis, wl_fixed_t value);
33
34#endif
diff --git a/include/swaybar/ipc.h b/include/swaybar/ipc.h
index a1696bcf..81e48a6b 100644
--- a/include/swaybar/ipc.h
+++ b/include/swaybar/ipc.h
@@ -3,7 +3,7 @@
3#include <stdbool.h> 3#include <stdbool.h>
4#include "swaybar/bar.h" 4#include "swaybar/bar.h"
5 5
6void ipc_initialize(struct swaybar *bar, const char *bar_id); 6bool ipc_initialize(struct swaybar *bar, const char *bar_id);
7bool handle_ipc_readable(struct swaybar *bar); 7bool handle_ipc_readable(struct swaybar *bar);
8void ipc_get_workspaces(struct swaybar *bar); 8void ipc_get_workspaces(struct swaybar *bar);
9void ipc_send_workspace_command(struct swaybar *bar, const char *ws); 9void ipc_send_workspace_command(struct swaybar *bar, const char *ws);
diff --git a/include/swaybar/status_line.h b/include/swaybar/status_line.h
index d3eabdf6..e6c7dac2 100644
--- a/include/swaybar/status_line.h
+++ b/include/swaybar/status_line.h
@@ -13,26 +13,6 @@ enum status_protocol {
13 PROTOCOL_I3BAR, 13 PROTOCOL_I3BAR,
14}; 14};
15 15
16struct i3bar_block {
17 struct wl_list link;
18 int ref_count;
19 char *full_text, *short_text, *align;
20 bool urgent;
21 uint32_t *color;
22 int min_width;
23 char *name, *instance;
24 bool separator;
25 int separator_block_width;
26 bool markup;
27 // Airblader features
28 uint32_t background;
29 uint32_t border;
30 int border_top;
31 int border_bottom;
32 int border_left;
33 int border_right;
34};
35
36struct status_line { 16struct status_line {
37 pid_t pid; 17 pid_t pid;
38 int read_fd, write_fd; 18 int read_fd, write_fd;
@@ -55,11 +35,5 @@ struct status_line *status_line_init(char *cmd);
55void status_error(struct status_line *status, const char *text); 35void status_error(struct status_line *status, const char *text);
56bool status_handle_readable(struct status_line *status); 36bool status_handle_readable(struct status_line *status);
57void status_line_free(struct status_line *status); 37void status_line_free(struct status_line *status);
58bool i3bar_handle_readable(struct status_line *status);
59enum hotspot_event_handling i3bar_block_send_click(struct status_line *status,
60 struct i3bar_block *block, int x, int y, enum x11_button button);
61void i3bar_block_unref(struct i3bar_block *block);
62enum x11_button wl_button_to_x11_button(uint32_t button);
63enum x11_button wl_axis_to_x11_button(uint32_t axis, wl_fixed_t value);
64 38
65#endif 39#endif
diff --git a/sway/commands/bar/binding_mode_indicator.c b/sway/commands/bar/binding_mode_indicator.c
index 0c48bee9..f18b8d7c 100644
--- a/sway/commands/bar/binding_mode_indicator.c
+++ b/sway/commands/bar/binding_mode_indicator.c
@@ -21,7 +21,9 @@ struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) {
21 config->current_bar->binding_mode_indicator = false; 21 config->current_bar->binding_mode_indicator = false;
22 wlr_log(WLR_DEBUG, "Disabling binding mode indicator on bar: %s", 22 wlr_log(WLR_DEBUG, "Disabling binding mode indicator on bar: %s",
23 config->current_bar->id); 23 config->current_bar->id);
24 } else {
25 return cmd_results_new(CMD_INVALID, "binding_mode_indicator",
26 "Invalid value %s", argv[0]);
24 } 27 }
25 return cmd_results_new(CMD_INVALID, "binding_mode_indicator", 28 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
26 "Invalid value %s", argv[0]);
27} 29}
diff --git a/swaybar/bar.c b/swaybar/bar.c
index ab307fd4..15e81976 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -16,12 +16,13 @@
16#else 16#else
17#include <linux/input-event-codes.h> 17#include <linux/input-event-codes.h>
18#endif 18#endif
19#include "swaybar/render.h" 19#include "swaybar/bar.h"
20#include "swaybar/config.h" 20#include "swaybar/config.h"
21#include "swaybar/event_loop.h" 21#include "swaybar/event_loop.h"
22#include "swaybar/status_line.h" 22#include "swaybar/i3bar.h"
23#include "swaybar/bar.h"
24#include "swaybar/ipc.h" 23#include "swaybar/ipc.h"
24#include "swaybar/status_line.h"
25#include "swaybar/render.h"
25#include "ipc-client.h" 26#include "ipc-client.h"
26#include "list.h" 27#include "list.h"
27#include "log.h" 28#include "log.h"
@@ -478,14 +479,16 @@ static void render_all_frames(struct swaybar *bar) {
478 } 479 }
479} 480}
480 481
481void bar_setup(struct swaybar *bar, 482bool bar_setup(struct swaybar *bar,
482 const char *socket_path, const char *bar_id) { 483 const char *socket_path, const char *bar_id) {
483 bar_init(bar); 484 bar_init(bar);
484 init_event_loop(); 485 init_event_loop();
485 486
486 bar->ipc_socketfd = ipc_open_socket(socket_path); 487 bar->ipc_socketfd = ipc_open_socket(socket_path);
487 bar->ipc_event_socketfd = ipc_open_socket(socket_path); 488 bar->ipc_event_socketfd = ipc_open_socket(socket_path);
488 ipc_initialize(bar, bar_id); 489 if (!ipc_initialize(bar, bar_id)) {
490 return false;
491 }
489 if (bar->config->status_command) { 492 if (bar->config->status_command) {
490 bar->status = status_line_init(bar->config->status_command); 493 bar->status = status_line_init(bar->config->status_command);
491 } 494 }
@@ -526,6 +529,7 @@ void bar_setup(struct swaybar *bar,
526 529
527 ipc_get_workspaces(bar); 530 ipc_get_workspaces(bar);
528 render_all_frames(bar); 531 render_all_frames(bar);
532 return true;
529} 533}
530 534
531static void display_in(int fd, short mask, void *data) { 535static void display_in(int fd, short mask, void *data) {
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c
index 325aa61a..8e9b038b 100644
--- a/swaybar/i3bar.c
+++ b/swaybar/i3bar.c
@@ -6,7 +6,9 @@
6#include <string.h> 6#include <string.h>
7#include <unistd.h> 7#include <unistd.h>
8#include <wlr/util/log.h> 8#include <wlr/util/log.h>
9#include "swaybar/bar.h"
9#include "swaybar/config.h" 10#include "swaybar/config.h"
11#include "swaybar/i3bar.h"
10#include "swaybar/status_line.h" 12#include "swaybar/status_line.h"
11 13
12void i3bar_block_unref(struct i3bar_block *block) { 14void i3bar_block_unref(struct i3bar_block *block) {
diff --git a/swaybar/ipc.c b/swaybar/ipc.c
index 0e60c10c..7c53a44f 100644
--- a/swaybar/ipc.c
+++ b/swaybar/ipc.c
@@ -141,9 +141,16 @@ static void ipc_parse_colors(
141 } 141 }
142} 142}
143 143
144static void ipc_parse_config( 144static bool ipc_parse_config(
145 struct swaybar_config *config, const char *payload) { 145 struct swaybar_config *config, const char *payload) {
146 json_object *bar_config = json_tokener_parse(payload); 146 json_object *bar_config = json_tokener_parse(payload);
147 json_object *success;
148 if (json_object_object_get_ex(bar_config, "success", &success)
149 && !json_object_get_boolean(success)) {
150 wlr_log(WLR_ERROR, "No bar with that ID. Use 'swaymsg -t get_bar_config to get the available bar configs.");
151 json_object_put(bar_config);
152 return false;
153 }
147 json_object *markup, *mode, *hidden_bar, *position, *status_command; 154 json_object *markup, *mode, *hidden_bar, *position, *status_command;
148 json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; 155 json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers;
149 json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; 156 json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs;
@@ -226,10 +233,10 @@ static void ipc_parse_config(
226 } 233 }
227 234
228 json_object_put(bar_config); 235 json_object_put(bar_config);
236 return true;
229} 237}
230 238
231void ipc_get_workspaces(struct swaybar *bar) { 239void ipc_get_workspaces(struct swaybar *bar) {
232 bar->focused_output = NULL;
233 struct swaybar_output *output; 240 struct swaybar_output *output;
234 wl_list_for_each(output, &bar->outputs, link) { 241 wl_list_for_each(output, &bar->outputs, link) {
235 free_workspaces(&output->workspaces); 242 free_workspaces(&output->workspaces);
@@ -312,11 +319,14 @@ static void ipc_get_outputs(struct swaybar *bar) {
312 free(res); 319 free(res);
313} 320}
314 321
315void ipc_initialize(struct swaybar *bar, const char *bar_id) { 322bool ipc_initialize(struct swaybar *bar, const char *bar_id) {
316 uint32_t len = strlen(bar_id); 323 uint32_t len = strlen(bar_id);
317 char *res = ipc_single_command(bar->ipc_socketfd, 324 char *res = ipc_single_command(bar->ipc_socketfd,
318 IPC_GET_BAR_CONFIG, bar_id, &len); 325 IPC_GET_BAR_CONFIG, bar_id, &len);
319 ipc_parse_config(bar->config, res); 326 if (!ipc_parse_config(bar->config, res)) {
327 free(res);
328 return false;
329 }
320 free(res); 330 free(res);
321 ipc_get_outputs(bar); 331 ipc_get_outputs(bar);
322 332
@@ -324,6 +334,7 @@ void ipc_initialize(struct swaybar *bar, const char *bar_id) {
324 len = strlen(subscribe); 334 len = strlen(subscribe);
325 free(ipc_single_command(bar->ipc_event_socketfd, 335 free(ipc_single_command(bar->ipc_event_socketfd,
326 IPC_SUBSCRIBE, subscribe, &len)); 336 IPC_SUBSCRIBE, subscribe, &len));
337 return true;
327} 338}
328 339
329bool handle_ipc_readable(struct swaybar *bar) { 340bool handle_ipc_readable(struct swaybar *bar) {
diff --git a/swaybar/main.c b/swaybar/main.c
index 60e4b37c..d2c579db 100644
--- a/swaybar/main.c
+++ b/swaybar/main.c
@@ -96,7 +96,10 @@ int main(int argc, char **argv) {
96 96
97 signal(SIGTERM, sig_handler); 97 signal(SIGTERM, sig_handler);
98 98
99 bar_setup(&swaybar, socket_path, bar_id); 99 if (!bar_setup(&swaybar, socket_path, bar_id)) {
100 free(socket_path);
101 return 1;
102 }
100 103
101 free(socket_path); 104 free(socket_path);
102 free(bar_id); 105 free(bar_id);
diff --git a/swaybar/render.c b/swaybar/render.c
index 9413dc57..90e5bac7 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -10,6 +10,7 @@
10#include "pool-buffer.h" 10#include "pool-buffer.h"
11#include "swaybar/bar.h" 11#include "swaybar/bar.h"
12#include "swaybar/config.h" 12#include "swaybar/config.h"
13#include "swaybar/i3bar.h"
13#include "swaybar/ipc.h" 14#include "swaybar/ipc.h"
14#include "swaybar/render.h" 15#include "swaybar/render.h"
15#include "swaybar/status_line.h" 16#include "swaybar/status_line.h"
@@ -20,47 +21,47 @@ static const double WS_VERTICAL_PADDING = 1.5;
20static const double BORDER_WIDTH = 1; 21static const double BORDER_WIDTH = 1;
21 22
22static uint32_t render_status_line_error(cairo_t *cairo, 23static uint32_t render_status_line_error(cairo_t *cairo,
23 struct swaybar_output *output, struct swaybar_config *config, 24 struct swaybar_output *output, double *x) {
24 const char *error, double *x, uint32_t surface_height) { 25 const char *error = output->bar->status->text;
25 if (!error) { 26 if (!error) {
26 return 0; 27 return 0;
27 } 28 }
28 29
29 uint32_t height = surface_height * output->scale; 30 uint32_t height = output->height * output->scale;
30 31
31 cairo_set_source_u32(cairo, 0xFF0000FF); 32 cairo_set_source_u32(cairo, 0xFF0000FF);
32 33
33 int margin = 3 * output->scale; 34 int margin = 3 * output->scale;
34 int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; 35 int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
35 36
37 char *font = output->bar->config->font;
36 int text_width, text_height; 38 int text_width, text_height;
37 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 39 get_text_size(cairo, font, &text_width, &text_height, NULL,
38 output->scale, false, "%s", error); 40 output->scale, false, "%s", error);
39 41
40 uint32_t ideal_height = text_height + ws_vertical_padding * 2; 42 uint32_t ideal_height = text_height + ws_vertical_padding * 2;
41 uint32_t ideal_surface_height = ideal_height / output->scale; 43 uint32_t ideal_surface_height = ideal_height / output->scale;
42 if (surface_height < ideal_surface_height) { 44 if (output->height < ideal_surface_height) {
43 return ideal_surface_height; 45 return ideal_surface_height;
44 } 46 }
45 *x -= text_width + margin; 47 *x -= text_width + margin;
46 48
47 double text_y = height / 2.0 - text_height / 2.0; 49 double text_y = height / 2.0 - text_height / 2.0;
48 cairo_move_to(cairo, *x, (int)floor(text_y)); 50 cairo_move_to(cairo, *x, (int)floor(text_y));
49 pango_printf(cairo, config->font, output->scale, false, "%s", error); 51 pango_printf(cairo, font, output->scale, false, "%s", error);
50 *x -= margin; 52 *x -= margin;
51 return surface_height; 53 return output->height;
52} 54}
53 55
54static uint32_t render_status_line_text(cairo_t *cairo, 56static uint32_t render_status_line_text(cairo_t *cairo,
55 struct swaybar_output *output, struct swaybar_config *config, 57 struct swaybar_output *output, double *x) {
56 const char *text, bool focused, double *x, uint32_t surface_height) { 58 const char *text = output->bar->status->text;
57 if (!text) { 59 if (!text) {
58 return 0; 60 return 0;
59 } 61 }
60 62
61 uint32_t height = surface_height * output->scale; 63 struct swaybar_config *config = output->bar->config;
62 64 cairo_set_source_u32(cairo, output->focused ?
63 cairo_set_source_u32(cairo, focused ?
64 config->colors.focused_statusline : config->colors.statusline); 65 config->colors.focused_statusline : config->colors.statusline);
65 66
66 int text_width, text_height; 67 int text_width, text_height;
@@ -72,17 +73,18 @@ static uint32_t render_status_line_text(cairo_t *cairo,
72 73
73 uint32_t ideal_height = text_height + ws_vertical_padding * 2; 74 uint32_t ideal_height = text_height + ws_vertical_padding * 2;
74 uint32_t ideal_surface_height = ideal_height / output->scale; 75 uint32_t ideal_surface_height = ideal_height / output->scale;
75 if (surface_height < ideal_surface_height) { 76 if (output->height < ideal_surface_height) {
76 return ideal_surface_height; 77 return ideal_surface_height;
77 } 78 }
78 79
79 *x -= text_width + margin; 80 *x -= text_width + margin;
81 uint32_t height = output->height * output->scale;
80 double text_y = height / 2.0 - text_height / 2.0; 82 double text_y = height / 2.0 - text_height / 2.0;
81 cairo_move_to(cairo, *x, (int)floor(text_y)); 83 cairo_move_to(cairo, *x, (int)floor(text_y));
82 pango_printf(cairo, config->font, output->scale, 84 pango_printf(cairo, config->font, output->scale,
83 config->pango_markup, "%s", text); 85 config->pango_markup, "%s", text);
84 *x -= margin; 86 *x -= margin;
85 return surface_height; 87 return output->height;
86} 88}
87 89
88static void render_sharp_line(cairo_t *cairo, uint32_t color, 90static void render_sharp_line(cairo_t *cairo, uint32_t color,
@@ -122,12 +124,11 @@ static void i3bar_block_unref_callback(void *data) {
122 124
123static uint32_t render_status_block(cairo_t *cairo, 125static uint32_t render_status_block(cairo_t *cairo,
124 struct swaybar_output *output, struct i3bar_block *block, double *x, 126 struct swaybar_output *output, struct i3bar_block *block, double *x,
125 uint32_t surface_height, bool focused, bool edge) { 127 bool edge) {
126 if (!block->full_text || !*block->full_text) { 128 if (!block->full_text || !*block->full_text) {
127 return 0; 129 return 0;
128 } 130 }
129 131
130 uint32_t height = surface_height * output->scale;
131 struct swaybar_config *config = output->bar->config; 132 struct swaybar_config *config = output->bar->config;
132 133
133 int text_width, text_height; 134 int text_width, text_height;
@@ -145,7 +146,7 @@ static uint32_t render_status_block(cairo_t *cairo,
145 double block_width = width; 146 double block_width = width;
146 uint32_t ideal_height = text_height + ws_vertical_padding * 2; 147 uint32_t ideal_height = text_height + ws_vertical_padding * 2;
147 uint32_t ideal_surface_height = ideal_height / output->scale; 148 uint32_t ideal_surface_height = ideal_height / output->scale;
148 if (surface_height < ideal_surface_height) { 149 if (output->height < ideal_surface_height) {
149 return ideal_surface_height; 150 return ideal_surface_height;
150 } 151 }
151 152
@@ -166,7 +167,7 @@ static uint32_t render_status_block(cairo_t *cairo,
166 output->scale, false, "%s", config->sep_symbol); 167 output->scale, false, "%s", config->sep_symbol);
167 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; 168 uint32_t _ideal_height = sep_height + ws_vertical_padding * 2;
168 uint32_t _ideal_surface_height = _ideal_height / output->scale; 169 uint32_t _ideal_surface_height = _ideal_height / output->scale;
169 if (surface_height < _ideal_surface_height) { 170 if (output->height < _ideal_surface_height) {
170 return _ideal_surface_height; 171 return _ideal_surface_height;
171 } 172 }
172 if (sep_width > block->separator_block_width) { 173 if (sep_width > block->separator_block_width) {
@@ -178,6 +179,7 @@ static uint32_t render_status_block(cairo_t *cairo,
178 *x -= margin; 179 *x -= margin;
179 } 180 }
180 181
182 uint32_t height = output->height * output->scale;
181 if (output->bar->status->click_events) { 183 if (output->bar->status->click_events) {
182 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); 184 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
183 hotspot->x = *x; 185 hotspot->x = *x;
@@ -241,7 +243,7 @@ static uint32_t render_status_block(cairo_t *cairo,
241 } 243 }
242 244
243 if (!edge && block->separator) { 245 if (!edge && block->separator) {
244 if (focused) { 246 if (output->focused) {
245 cairo_set_source_u32(cairo, config->colors.focused_separator); 247 cairo_set_source_u32(cairo, config->colors.focused_separator);
246 } else { 248 } else {
247 cairo_set_source_u32(cairo, config->colors.separator); 249 cairo_set_source_u32(cairo, config->colors.separator);
@@ -260,19 +262,16 @@ static uint32_t render_status_block(cairo_t *cairo,
260 cairo_stroke(cairo); 262 cairo_stroke(cairo);
261 } 263 }
262 } 264 }
263 return surface_height; 265 return output->height;
264} 266}
265 267
266static uint32_t render_status_line_i3bar(cairo_t *cairo, 268static uint32_t render_status_line_i3bar(cairo_t *cairo,
267 struct swaybar_config *config, struct swaybar_output *output, 269 struct swaybar_output *output, double *x) {
268 struct status_line *status, bool focused,
269 double *x, uint32_t surface_height) {
270 uint32_t max_height = 0; 270 uint32_t max_height = 0;
271 bool edge = true; 271 bool edge = true;
272 struct i3bar_block *block; 272 struct i3bar_block *block;
273 wl_list_for_each(block, &status->blocks, link) { 273 wl_list_for_each(block, &output->bar->status->blocks, link) {
274 uint32_t h = render_status_block(cairo, output, 274 uint32_t h = render_status_block(cairo, output, block, x, edge);
275 block, x, surface_height, focused, edge);
276 max_height = h > max_height ? h : max_height; 275 max_height = h > max_height ? h : max_height;
277 edge = false; 276 edge = false;
278 } 277 }
@@ -280,19 +279,15 @@ static uint32_t render_status_line_i3bar(cairo_t *cairo,
280} 279}
281 280
282static uint32_t render_status_line(cairo_t *cairo, 281static uint32_t render_status_line(cairo_t *cairo,
283 struct swaybar_config *config, struct swaybar_output *output, 282 struct swaybar_output *output, double *x) {
284 struct status_line *status, bool focused, 283 struct status_line *status = output->bar->status;
285 double *x, uint32_t surface_height) {
286 switch (status->protocol) { 284 switch (status->protocol) {
287 case PROTOCOL_ERROR: 285 case PROTOCOL_ERROR:
288 return render_status_line_error(cairo, output, config, 286 return render_status_line_error(cairo, output, x);
289 status->text, x, surface_height);
290 case PROTOCOL_TEXT: 287 case PROTOCOL_TEXT:
291 return render_status_line_text(cairo, output, config, 288 return render_status_line_text(cairo, output, x);
292 status->text, focused, x, surface_height);
293 case PROTOCOL_I3BAR: 289 case PROTOCOL_I3BAR:
294 return render_status_line_i3bar(cairo, config, output, 290 return render_status_line_i3bar(cairo, output, x);
295 status, focused, x, surface_height);
296 case PROTOCOL_UNDEF: 291 case PROTOCOL_UNDEF:
297 return 0; 292 return 0;
298 } 293 }
@@ -300,10 +295,9 @@ static uint32_t render_status_line(cairo_t *cairo,
300} 295}
301 296
302static uint32_t render_binding_mode_indicator(cairo_t *cairo, 297static uint32_t render_binding_mode_indicator(cairo_t *cairo,
303 struct swaybar_output *output, struct swaybar_config *config, 298 struct swaybar_output *output, double x) {
304 const char *mode, double x, uint32_t surface_height) { 299 struct swaybar_config *config = output->bar->config;
305 uint32_t height = surface_height * output->scale; 300 const char *mode = config->mode;
306
307 int text_width, text_height; 301 int text_width, text_height;
308 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 302 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
309 output->scale, config->mode_pango_markup, 303 output->scale, config->mode_pango_markup,
@@ -316,11 +310,12 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo,
316 uint32_t ideal_height = text_height + ws_vertical_padding * 2 310 uint32_t ideal_height = text_height + ws_vertical_padding * 2
317 + border_width * 2; 311 + border_width * 2;
318 uint32_t ideal_surface_height = ideal_height / output->scale; 312 uint32_t ideal_surface_height = ideal_height / output->scale;
319 if (surface_height < ideal_surface_height) { 313 if (output->height < ideal_surface_height) {
320 return ideal_surface_height; 314 return ideal_surface_height;
321 } 315 }
322 uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; 316 uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2;
323 317
318 uint32_t height = output->height * output->scale;
324 cairo_set_source_u32(cairo, config->colors.binding_mode.background); 319 cairo_set_source_u32(cairo, config->colors.binding_mode.background);
325 cairo_rectangle(cairo, x, 0, width, height); 320 cairo_rectangle(cairo, x, 0, width, height);
326 cairo_fill(cairo); 321 cairo_fill(cairo);
@@ -340,7 +335,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo,
340 cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); 335 cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y));
341 pango_printf(cairo, config->font, output->scale, config->mode_pango_markup, 336 pango_printf(cairo, config->font, output->scale, config->mode_pango_markup,
342 "%s", mode); 337 "%s", mode);
343 return surface_height; 338 return output->height;
344} 339}
345 340
346static const char *strip_workspace_number(const char *ws_name) { 341static const char *strip_workspace_number(const char *ws_name) {
@@ -366,8 +361,9 @@ static enum hotspot_event_handling workspace_hotspot_callback(struct swaybar_out
366} 361}
367 362
368static uint32_t render_workspace_button(cairo_t *cairo, 363static uint32_t render_workspace_button(cairo_t *cairo,
369 struct swaybar_output *output, struct swaybar_config *config, 364 struct swaybar_output *output,
370 struct swaybar_workspace *ws, double *x, uint32_t surface_height) { 365 struct swaybar_workspace *ws, double *x) {
366 struct swaybar_config *config = output->bar->config;
371 const char *name = ws->name; 367 const char *name = ws->name;
372 if (config->strip_workspace_numbers) { 368 if (config->strip_workspace_numbers) {
373 name = strip_workspace_number(ws->name); 369 name = strip_workspace_number(ws->name);
@@ -384,7 +380,7 @@ static uint32_t render_workspace_button(cairo_t *cairo,
384 box_colors = config->colors.inactive_workspace; 380 box_colors = config->colors.inactive_workspace;
385 } 381 }
386 382
387 uint32_t height = surface_height * output->scale; 383 uint32_t height = output->height * output->scale;
388 384
389 int text_width, text_height; 385 int text_width, text_height;
390 get_text_size(cairo, config->font, &text_width, &text_height, NULL, 386 get_text_size(cairo, config->font, &text_width, &text_height, NULL,
@@ -397,7 +393,7 @@ static uint32_t render_workspace_button(cairo_t *cairo,
397 uint32_t ideal_height = ws_vertical_padding * 2 + text_height 393 uint32_t ideal_height = ws_vertical_padding * 2 + text_height
398 + border_width * 2; 394 + border_width * 2;
399 uint32_t ideal_surface_height = ideal_height / output->scale; 395 uint32_t ideal_surface_height = ideal_height / output->scale;
400 if (surface_height < ideal_surface_height) { 396 if (output->height < ideal_surface_height) {
401 return ideal_surface_height; 397 return ideal_surface_height;
402 } 398 }
403 399
@@ -434,11 +430,11 @@ static uint32_t render_workspace_button(cairo_t *cairo,
434 wl_list_insert(&output->hotspots, &hotspot->link); 430 wl_list_insert(&output->hotspots, &hotspot->link);
435 431
436 *x += width; 432 *x += width;
437 return surface_height; 433 return output->height;
438} 434}
439 435
440static uint32_t render_to_cairo(cairo_t *cairo, 436static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) {
441 struct swaybar *bar, struct swaybar_output *output) { 437 struct swaybar *bar = output->bar;
442 struct swaybar_config *config = bar->config; 438 struct swaybar_config *config = bar->config;
443 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); 439 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
444 if (output->focused) { 440 if (output->focused) {
@@ -458,22 +454,19 @@ static uint32_t render_to_cairo(cairo_t *cairo,
458 */ 454 */
459 double x = output->width * output->scale; 455 double x = output->width * output->scale;
460 if (bar->status) { 456 if (bar->status) {
461 uint32_t h = render_status_line(cairo, config, output, 457 uint32_t h = render_status_line(cairo, output, &x);
462 bar->status, output->focused, &x, output->height);
463 max_height = h > max_height ? h : max_height; 458 max_height = h > max_height ? h : max_height;
464 } 459 }
465 x = 0; 460 x = 0;
466 if (config->workspace_buttons) { 461 if (config->workspace_buttons) {
467 struct swaybar_workspace *ws; 462 struct swaybar_workspace *ws;
468 wl_list_for_each_reverse(ws, &output->workspaces, link) { 463 wl_list_for_each_reverse(ws, &output->workspaces, link) {
469 uint32_t h = render_workspace_button(cairo, 464 uint32_t h = render_workspace_button(cairo, output, ws, &x);
470 output, config, ws, &x, output->height);
471 max_height = h > max_height ? h : max_height; 465 max_height = h > max_height ? h : max_height;
472 } 466 }
473 } 467 }
474 if (config->binding_mode_indicator && config->mode) { 468 if (config->binding_mode_indicator && config->mode) {
475 uint32_t h = render_binding_mode_indicator(cairo, 469 uint32_t h = render_binding_mode_indicator(cairo, output, x);
476 output, config, config->mode, x, output->height);
477 max_height = h > max_height ? h : max_height; 470 max_height = h > max_height ? h : max_height;
478 } 471 }
479 472
@@ -506,9 +499,10 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) {
506 cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); 499 cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
507 cairo_paint(cairo); 500 cairo_paint(cairo);
508 cairo_restore(cairo); 501 cairo_restore(cairo);
509 uint32_t height = render_to_cairo(cairo, bar, output); 502 uint32_t height = render_to_cairo(cairo, output);
510 if (bar->config->height >= 0 && height < (uint32_t)bar->config->height) { 503 int config_height = output->bar->config->height;
511 height = bar->config->height; 504 if (config_height >= 0 && height < (uint32_t)config_height) {
505 height = config_height;
512 } 506 }
513 if (height != output->height) { 507 if (height != output->height) {
514 // Reconfigure surface 508 // Reconfigure surface
@@ -519,7 +513,7 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) {
519 wl_surface_commit(output->surface); 513 wl_surface_commit(output->surface);
520 } else if (height > 0) { 514 } else if (height > 0) {
521 // Replay recording into shm and send it off 515 // Replay recording into shm and send it off
522 output->current_buffer = get_next_buffer(bar->shm, 516 output->current_buffer = get_next_buffer(output->bar->shm,
523 output->buffers, 517 output->buffers,
524 output->width * output->scale, 518 output->width * output->scale,
525 output->height * output->scale); 519 output->height * output->scale);
diff --git a/swaybar/status_line.c b/swaybar/status_line.c
index 1442e1a0..ed6dc7c8 100644
--- a/swaybar/status_line.c
+++ b/swaybar/status_line.c
@@ -7,7 +7,9 @@
7#include <stdio.h> 7#include <stdio.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <wlr/util/log.h> 9#include <wlr/util/log.h>
10#include "swaybar/bar.h"
10#include "swaybar/config.h" 11#include "swaybar/config.h"
12#include "swaybar/i3bar.h"
11#include "swaybar/event_loop.h" 13#include "swaybar/event_loop.h"
12#include "swaybar/status_line.h" 14#include "swaybar/status_line.h"
13#include "readline.h" 15#include "readline.h"