diff options
-rw-r--r-- | include/swaybar/ipc.h | 2 | ||||
-rw-r--r-- | include/swaybar/status_line.h | 6 | ||||
-rw-r--r-- | swaybar/bar.c | 4 | ||||
-rw-r--r-- | swaybar/i3bar.c | 120 | ||||
-rw-r--r-- | swaybar/ipc.c | 2 | ||||
-rw-r--r-- | swaybar/render.c | 209 | ||||
-rw-r--r-- | swaybar/status_line.c | 5 |
7 files changed, 314 insertions, 34 deletions
diff --git a/include/swaybar/ipc.h b/include/swaybar/ipc.h index 6ea7c4d6..a1696bcf 100644 --- a/include/swaybar/ipc.h +++ b/include/swaybar/ipc.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "swaybar/bar.h" | 4 | #include "swaybar/bar.h" |
5 | 5 | ||
6 | void ipc_initialize(struct swaybar *bar, const char *bar_id); | 6 | void ipc_initialize(struct swaybar *bar, const char *bar_id); |
7 | bool handle_ipc_event(struct swaybar *bar); | 7 | bool handle_ipc_readable(struct swaybar *bar); |
8 | void ipc_get_workspaces(struct swaybar *bar); | 8 | void ipc_get_workspaces(struct swaybar *bar); |
9 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws); | 9 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws); |
10 | 10 | ||
diff --git a/include/swaybar/status_line.h b/include/swaybar/status_line.h index 3b93e28f..038985a3 100644 --- a/include/swaybar/status_line.h +++ b/include/swaybar/status_line.h | |||
@@ -38,7 +38,7 @@ struct i3bar_block { | |||
38 | struct wl_list link; | 38 | struct wl_list link; |
39 | char *full_text, *short_text, *align; | 39 | char *full_text, *short_text, *align; |
40 | bool urgent; | 40 | bool urgent; |
41 | uint32_t color; | 41 | uint32_t *color; |
42 | int min_width; | 42 | int min_width; |
43 | char *name, *instance; | 43 | char *name, *instance; |
44 | bool separator; | 44 | bool separator; |
@@ -68,8 +68,8 @@ struct status_line { | |||
68 | 68 | ||
69 | struct status_line *status_line_init(char *cmd); | 69 | struct status_line *status_line_init(char *cmd); |
70 | void status_line_free(struct status_line *status); | 70 | void status_line_free(struct status_line *status); |
71 | bool handle_status_readable(struct status_line *status); | 71 | bool status_handle_readable(struct status_line *status); |
72 | int i3bar_readable(struct status_line *status); | 72 | bool i3bar_handle_readable(struct status_line *status); |
73 | void status_error(struct status_line *status, const char *text); | 73 | void status_error(struct status_line *status, const char *text); |
74 | 74 | ||
75 | #endif | 75 | #endif |
diff --git a/swaybar/bar.c b/swaybar/bar.c index f743236c..fb417095 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -308,14 +308,14 @@ static void display_in(int fd, short mask, void *_bar) { | |||
308 | 308 | ||
309 | static void ipc_in(int fd, short mask, void *_bar) { | 309 | static void ipc_in(int fd, short mask, void *_bar) { |
310 | struct swaybar *bar = (struct swaybar *)_bar; | 310 | struct swaybar *bar = (struct swaybar *)_bar; |
311 | if (handle_ipc_event(bar)) { | 311 | if (handle_ipc_readable(bar)) { |
312 | render_all_frames(bar); | 312 | render_all_frames(bar); |
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | static void status_in(int fd, short mask, void *_bar) { | 316 | static void status_in(int fd, short mask, void *_bar) { |
317 | struct swaybar *bar = (struct swaybar *)_bar; | 317 | struct swaybar *bar = (struct swaybar *)_bar; |
318 | if (handle_status_readable(bar->status)) { | 318 | if (status_handle_readable(bar->status)) { |
319 | render_all_frames(bar); | 319 | render_all_frames(bar); |
320 | } | 320 | } |
321 | } | 321 | } |
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index 5be348b2..41b71164 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <json-c/json.h> | ||
1 | #include <stdlib.h> | 3 | #include <stdlib.h> |
2 | #include <string.h> | 4 | #include <string.h> |
3 | #include <unistd.h> | 5 | #include <unistd.h> |
@@ -5,11 +7,109 @@ | |||
5 | #include "swaybar/config.h" | 7 | #include "swaybar/config.h" |
6 | #include "swaybar/status_line.h" | 8 | #include "swaybar/status_line.h" |
7 | 9 | ||
8 | static void i3bar_parse_json(struct status_line *status, const char *text) { | 10 | static void i3bar_block_free(struct i3bar_block *block) { |
9 | wlr_log(L_DEBUG, "got json: %s", text); | 11 | if (!block) { |
12 | return; | ||
13 | } | ||
14 | wl_list_remove(&block->link); | ||
15 | free(block->full_text); | ||
16 | free(block->short_text); | ||
17 | free(block->align); | ||
18 | free(block->name); | ||
19 | free(block->instance); | ||
20 | free(block->color); | ||
21 | } | ||
22 | |||
23 | static bool i3bar_parse_json(struct status_line *status, const char *text) { | ||
24 | struct i3bar_block *block, *tmp; | ||
25 | wl_list_for_each_safe(block, tmp, &status->blocks, link) { | ||
26 | i3bar_block_free(block); | ||
27 | } | ||
28 | json_object *results = json_tokener_parse(text); | ||
29 | if (!results) { | ||
30 | status_error(status, "[failed to parse i3bar json]"); | ||
31 | return false; | ||
32 | } | ||
33 | if (json_object_array_length(results) < 1) { | ||
34 | return true; | ||
35 | } | ||
36 | for (size_t i = 0; i < json_object_array_length(results); ++i) { | ||
37 | json_object *full_text, *short_text, *color, *min_width, *align, *urgent; | ||
38 | json_object *name, *instance, *separator, *separator_block_width; | ||
39 | json_object *background, *border, *border_top, *border_bottom; | ||
40 | json_object *border_left, *border_right, *markup; | ||
41 | json_object *json = json_object_array_get_idx(results, i); | ||
42 | if (!json) { | ||
43 | continue; | ||
44 | } | ||
45 | json_object_object_get_ex(json, "full_text", &full_text); | ||
46 | json_object_object_get_ex(json, "short_text", &short_text); | ||
47 | json_object_object_get_ex(json, "color", &color); | ||
48 | json_object_object_get_ex(json, "min_width", &min_width); | ||
49 | json_object_object_get_ex(json, "align", &align); | ||
50 | json_object_object_get_ex(json, "urgent", &urgent); | ||
51 | json_object_object_get_ex(json, "name", &name); | ||
52 | json_object_object_get_ex(json, "instance", &instance); | ||
53 | json_object_object_get_ex(json, "markup", &markup); | ||
54 | json_object_object_get_ex(json, "separator", &separator); | ||
55 | json_object_object_get_ex(json, "separator_block_width", &separator_block_width); | ||
56 | json_object_object_get_ex(json, "background", &background); | ||
57 | json_object_object_get_ex(json, "border", &border); | ||
58 | json_object_object_get_ex(json, "border_top", &border_top); | ||
59 | json_object_object_get_ex(json, "border_bottom", &border_bottom); | ||
60 | json_object_object_get_ex(json, "border_left", &border_left); | ||
61 | json_object_object_get_ex(json, "border_right", &border_right); | ||
62 | |||
63 | struct i3bar_block *block = calloc(1, sizeof(struct i3bar_block)); | ||
64 | block->full_text = full_text ? | ||
65 | strdup(json_object_get_string(full_text)) : NULL; | ||
66 | block->short_text = short_text ? | ||
67 | strdup(json_object_get_string(short_text)) : NULL; | ||
68 | if (color) { | ||
69 | block->color = malloc(sizeof(uint32_t)); | ||
70 | *block->color = parse_color(json_object_get_string(color)); | ||
71 | } | ||
72 | if (min_width) { | ||
73 | json_type type = json_object_get_type(min_width); | ||
74 | if (type == json_type_int) { | ||
75 | block->min_width = json_object_get_int(min_width); | ||
76 | } else if (type == json_type_string) { | ||
77 | /* the width will be calculated when rendering */ | ||
78 | block->min_width = 0; | ||
79 | } | ||
80 | } | ||
81 | block->align = strdup(align ? json_object_get_string(align) : "left"); | ||
82 | block->urgent = urgent ? json_object_get_int(urgent) : false; | ||
83 | block->name = name ? strdup(json_object_get_string(name)) : NULL; | ||
84 | block->instance = instance ? | ||
85 | strdup(json_object_get_string(instance)) : NULL; | ||
86 | if (markup) { | ||
87 | block->markup = false; | ||
88 | const char *markup_str = json_object_get_string(markup); | ||
89 | if (strcmp(markup_str, "pango") == 0) { | ||
90 | block->markup = true; | ||
91 | } | ||
92 | } | ||
93 | block->separator = separator ? json_object_get_int(separator) : true; | ||
94 | block->separator_block_width = separator_block_width ? | ||
95 | json_object_get_int(separator_block_width) : 9; | ||
96 | // Airblader features | ||
97 | block->background = background ? | ||
98 | parse_color(json_object_get_string(background)) : 0; | ||
99 | block->border = border ? | ||
100 | parse_color(json_object_get_string(border)) : 0; | ||
101 | block->border_top = border_top ? json_object_get_int(border_top) : 1; | ||
102 | block->border_bottom = border_bottom ? | ||
103 | json_object_get_int(border_bottom) : 1; | ||
104 | block->border_left = border_left ? json_object_get_int(border_left) : 1; | ||
105 | block->border_right = border_right ? | ||
106 | json_object_get_int(border_right) : 1; | ||
107 | wl_list_insert(&status->blocks, &block->link); | ||
108 | } | ||
109 | return true; | ||
10 | } | 110 | } |
11 | 111 | ||
12 | int i3bar_readable(struct status_line *status) { | 112 | bool i3bar_handle_readable(struct status_line *status) { |
13 | struct i3bar_protocol_state *state = &status->i3bar_state; | 113 | struct i3bar_protocol_state *state = &status->i3bar_state; |
14 | 114 | ||
15 | char *cur = &state->buffer[state->buffer_index]; | 115 | char *cur = &state->buffer[state->buffer_index]; |
@@ -30,7 +130,7 @@ int i3bar_readable(struct status_line *status) { | |||
30 | state->buffer = new_buffer; | 130 | state->buffer = new_buffer; |
31 | } | 131 | } |
32 | 132 | ||
33 | int handled = 0; | 133 | bool redraw = false; |
34 | while (*cur) { | 134 | while (*cur) { |
35 | if (state->nodes[state->depth] == JSON_NODE_STRING) { | 135 | if (state->nodes[state->depth] == JSON_NODE_STRING) { |
36 | if (!state->escape && *cur == '"') { | 136 | if (!state->escape && *cur == '"') { |
@@ -44,7 +144,7 @@ int i3bar_readable(struct status_line *status) { | |||
44 | if (state->depth > | 144 | if (state->depth > |
45 | sizeof(state->nodes) / sizeof(state->nodes[0])) { | 145 | sizeof(state->nodes) / sizeof(state->nodes[0])) { |
46 | status_error(status, "[i3bar json too deep]"); | 146 | status_error(status, "[i3bar json too deep]"); |
47 | return -1; | 147 | return false; |
48 | } | 148 | } |
49 | state->nodes[state->depth] = JSON_NODE_ARRAY; | 149 | state->nodes[state->depth] = JSON_NODE_ARRAY; |
50 | if (state->depth == 1) { | 150 | if (state->depth == 1) { |
@@ -54,18 +154,18 @@ int i3bar_readable(struct status_line *status) { | |||
54 | case ']': | 154 | case ']': |
55 | if (state->nodes[state->depth] != JSON_NODE_ARRAY) { | 155 | if (state->nodes[state->depth] != JSON_NODE_ARRAY) { |
56 | status_error(status, "[failed to parse i3bar json]"); | 156 | status_error(status, "[failed to parse i3bar json]"); |
57 | return -1; | 157 | return false; |
58 | } | 158 | } |
59 | --state->depth; | 159 | --state->depth; |
60 | if (state->depth == 0) { | 160 | if (state->depth == 0) { |
61 | // cur[1] is valid since cur[0] != '\0' | 161 | // cur[1] is valid since cur[0] != '\0' |
62 | char p = cur[1]; | 162 | char p = cur[1]; |
63 | cur[1] = '\0'; | 163 | cur[1] = '\0'; |
64 | i3bar_parse_json(status, state->current_node); | 164 | redraw = i3bar_parse_json( |
165 | status, state->current_node) || redraw; | ||
65 | cur[1] = p; | 166 | cur[1] = p; |
66 | memmove(state->buffer, cur, | 167 | memmove(state->buffer, cur, |
67 | state->buffer_size - (cur - state->buffer)); | 168 | state->buffer_size - (cur - state->buffer)); |
68 | ++handled; | ||
69 | cur = state->buffer; | 169 | cur = state->buffer; |
70 | state->current_node = cur + 1; | 170 | state->current_node = cur + 1; |
71 | } | 171 | } |
@@ -75,7 +175,7 @@ int i3bar_readable(struct status_line *status) { | |||
75 | if (state->depth > | 175 | if (state->depth > |
76 | sizeof(state->nodes) / sizeof(state->nodes[0])) { | 176 | sizeof(state->nodes) / sizeof(state->nodes[0])) { |
77 | status_error(status, "[i3bar json too deep]"); | 177 | status_error(status, "[i3bar json too deep]"); |
78 | return -1; | 178 | return false; |
79 | } | 179 | } |
80 | state->nodes[state->depth] = JSON_NODE_STRING; | 180 | state->nodes[state->depth] = JSON_NODE_STRING; |
81 | break; | 181 | break; |
@@ -84,5 +184,5 @@ int i3bar_readable(struct status_line *status) { | |||
84 | ++cur; | 184 | ++cur; |
85 | } | 185 | } |
86 | state->buffer_index = cur - state->buffer; | 186 | state->buffer_index = cur - state->buffer; |
87 | return handled; | 187 | return redraw; |
88 | } | 188 | } |
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 64583df0..ed5d9a31 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -323,7 +323,7 @@ void ipc_initialize(struct swaybar *bar, const char *bar_id) { | |||
323 | IPC_SUBSCRIBE, subscribe, &len)); | 323 | IPC_SUBSCRIBE, subscribe, &len)); |
324 | } | 324 | } |
325 | 325 | ||
326 | bool handle_ipc_event(struct swaybar *bar) { | 326 | bool handle_ipc_readable(struct swaybar *bar) { |
327 | struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); | 327 | struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); |
328 | if (!resp) { | 328 | if (!resp) { |
329 | return false; | 329 | return false; |
diff --git a/swaybar/render.c b/swaybar/render.c index c2358724..3ad6d5d7 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -18,10 +18,33 @@ static const int ws_horizontal_padding = 5; | |||
18 | static const double ws_vertical_padding = 1.5; | 18 | static const double ws_vertical_padding = 1.5; |
19 | static const double border_width = 1; | 19 | static const double border_width = 1; |
20 | 20 | ||
21 | static uint32_t render_status_line_error(cairo_t *cairo, | ||
22 | struct swaybar_config *config, const char *error, | ||
23 | double *x, uint32_t width, uint32_t height) { | ||
24 | if (!error) { | ||
25 | return 0; | ||
26 | } | ||
27 | cairo_set_source_u32(cairo, 0xFF0000FF); | ||
28 | static const int margin = 3; | ||
29 | int text_width, text_height; | ||
30 | get_text_size(cairo, config->font, | ||
31 | &text_width, &text_height, 1, false, "%s", error); | ||
32 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
33 | if (height < ideal_height) { | ||
34 | return ideal_height; | ||
35 | } | ||
36 | *x -= text_width + margin; | ||
37 | double text_y = height / 2.0 - text_height / 2.0; | ||
38 | cairo_move_to(cairo, *x, (int)floor(text_y)); | ||
39 | pango_printf(cairo, config->font, 1, false, "%s", error); | ||
40 | *x -= margin; | ||
41 | return ideal_height; | ||
42 | } | ||
43 | |||
21 | static uint32_t render_status_line_text(cairo_t *cairo, | 44 | static uint32_t render_status_line_text(cairo_t *cairo, |
22 | struct swaybar_config *config, struct status_line *status, | 45 | struct swaybar_config *config, const char *text, |
23 | bool focused, uint32_t width, uint32_t height) { | 46 | bool focused, double *x, uint32_t width, uint32_t height) { |
24 | if (!status->text) { | 47 | if (!text) { |
25 | return 0; | 48 | return 0; |
26 | } | 49 | } |
27 | cairo_set_source_u32(cairo, focused ? | 50 | cairo_set_source_u32(cairo, focused ? |
@@ -29,38 +52,193 @@ static uint32_t render_status_line_text(cairo_t *cairo, | |||
29 | static const int margin = 3; | 52 | static const int margin = 3; |
30 | int text_width, text_height; | 53 | int text_width, text_height; |
31 | get_text_size(cairo, config->font, &text_width, &text_height, | 54 | get_text_size(cairo, config->font, &text_width, &text_height, |
32 | 1, config->pango_markup, "%s", status->text); | 55 | 1, config->pango_markup, "%s", text); |
33 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 56 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
34 | if (height < ideal_height) { | 57 | if (height < ideal_height) { |
35 | return ideal_height; | 58 | return ideal_height; |
36 | } | 59 | } |
60 | *x -= text_width + margin; | ||
37 | double text_y = height / 2.0 - text_height / 2.0; | 61 | double text_y = height / 2.0 - text_height / 2.0; |
38 | cairo_move_to(cairo, width - text_width - margin, (int)floor(text_y)); | 62 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
39 | pango_printf(cairo, config->font, 1, config->pango_markup, | 63 | pango_printf(cairo, config->font, 1, config->pango_markup, "%s", text); |
40 | "%s", status->text); | 64 | *x -= margin; |
65 | return ideal_height; | ||
66 | } | ||
67 | |||
68 | static void render_sharp_line(cairo_t *cairo, uint32_t color, | ||
69 | double x, double y, double width, double height) { | ||
70 | cairo_set_source_u32(cairo, color); | ||
71 | if (width > 1 && height > 1) { | ||
72 | cairo_rectangle(cairo, x, y, width, height); | ||
73 | cairo_fill(cairo); | ||
74 | } else { | ||
75 | if (width == 1) { | ||
76 | x += 0.5; | ||
77 | height += y; | ||
78 | width = x; | ||
79 | } | ||
80 | if (height == 1) { | ||
81 | y += 0.5; | ||
82 | width += x; | ||
83 | height = y; | ||
84 | } | ||
85 | cairo_move_to(cairo, x, y); | ||
86 | cairo_set_line_width(cairo, 1.0); | ||
87 | cairo_line_to(cairo, width, height); | ||
88 | cairo_stroke(cairo); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static uint32_t render_status_block(cairo_t *cairo, | ||
93 | struct swaybar_config *config, struct i3bar_block *block, | ||
94 | double *x, uint32_t height, bool focused, bool edge) { | ||
95 | static const int margin = 3; | ||
96 | if (!block->full_text || !*block->full_text) { | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | int text_width, text_height; | ||
101 | get_text_size(cairo, config->font, &text_width, &text_height, | ||
102 | 1, block->markup, "%s", block->full_text); | ||
103 | int width = text_width; | ||
104 | if (width < block->min_width) { | ||
105 | width = block->min_width; | ||
106 | } | ||
107 | double block_width = width; | ||
108 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
109 | if (height < ideal_height) { | ||
110 | return ideal_height; | ||
111 | } | ||
112 | |||
113 | *x -= width; | ||
114 | if (block->border && block->border_left > 0) { | ||
115 | *x -= (block->border_left + margin); | ||
116 | block_width += block->border_left + margin; | ||
117 | } | ||
118 | if (block->border && block->border_right > 0) { | ||
119 | *x -= (block->border_right + margin); | ||
120 | block_width += block->border_right + margin; | ||
121 | } | ||
122 | |||
123 | int sep_width; | ||
124 | if (!edge) { | ||
125 | if (config->sep_symbol) { | ||
126 | int _height; | ||
127 | get_text_size(cairo, config->font, &sep_width, &_height, | ||
128 | 1, false, "%s", config->sep_symbol); | ||
129 | uint32_t _ideal_height = _height + ws_vertical_padding * 2; | ||
130 | if (height < _ideal_height) { | ||
131 | return _height; | ||
132 | } | ||
133 | if (sep_width > block->separator_block_width) { | ||
134 | block->separator_block_width = sep_width + margin * 2; | ||
135 | } | ||
136 | } | ||
137 | *x -= block->separator_block_width; | ||
138 | } else { | ||
139 | *x -= margin; | ||
140 | } | ||
141 | |||
142 | // TODO: Create hotspot here | ||
143 | |||
144 | double pos = *x; | ||
145 | if (block->background) { | ||
146 | cairo_set_source_u32(cairo, block->background); | ||
147 | cairo_rectangle(cairo, pos - 0.5, 1, block_width, height); | ||
148 | cairo_fill(cairo); | ||
149 | } | ||
150 | |||
151 | if (block->border && block->border_top > 0) { | ||
152 | render_sharp_line(cairo, block->border, | ||
153 | pos - 0.5, 1, block_width, block->border_top); | ||
154 | } | ||
155 | if (block->border && block->border_bottom > 0) { | ||
156 | render_sharp_line(cairo, block->border, | ||
157 | pos - 0.5, height - 1 - block->border_bottom, | ||
158 | block_width, block->border_bottom); | ||
159 | } | ||
160 | if (block->border != 0 && block->border_left > 0) { | ||
161 | render_sharp_line(cairo, block->border, | ||
162 | pos - 0.5, 1, block->border_left, height); | ||
163 | pos += block->border_left + margin; | ||
164 | } | ||
165 | |||
166 | double offset = 0; | ||
167 | if (strncmp(block->align, "left", 5) == 0) { | ||
168 | offset = pos; | ||
169 | } else if (strncmp(block->align, "right", 5) == 0) { | ||
170 | offset = pos + width - text_width; | ||
171 | } else if (strncmp(block->align, "center", 6) == 0) { | ||
172 | offset = pos + (width - text_width) / 2; | ||
173 | } | ||
174 | cairo_move_to(cairo, offset, height / 2.0 - text_height / 2.0); | ||
175 | uint32_t color = block->color ? *block->color : config->colors.statusline; | ||
176 | cairo_set_source_u32(cairo, color); | ||
177 | pango_printf(cairo, config->font, 1, block->markup, "%s", block->full_text); | ||
178 | pos += width; | ||
179 | |||
180 | if (block->border && block->border_right > 0) { | ||
181 | pos += margin; | ||
182 | render_sharp_line(cairo, block->border, | ||
183 | pos - 0.5, 1, block->border_right, height); | ||
184 | pos += block->border_right; | ||
185 | } | ||
186 | |||
187 | if (!edge && block->separator) { | ||
188 | if (focused) { | ||
189 | cairo_set_source_u32(cairo, config->colors.focused_separator); | ||
190 | } else { | ||
191 | cairo_set_source_u32(cairo, config->colors.separator); | ||
192 | } | ||
193 | if (config->sep_symbol) { | ||
194 | offset = pos + (block->separator_block_width - sep_width) / 2; | ||
195 | cairo_move_to(cairo, offset, margin); | ||
196 | pango_printf(cairo, config->font, 1, false, | ||
197 | "%s", config->sep_symbol); | ||
198 | } else { | ||
199 | cairo_set_line_width(cairo, 1); | ||
200 | cairo_move_to(cairo, | ||
201 | pos + block->separator_block_width / 2, margin); | ||
202 | cairo_line_to(cairo, | ||
203 | pos + block->separator_block_width / 2, height - margin); | ||
204 | cairo_stroke(cairo); | ||
205 | } | ||
206 | } | ||
41 | return ideal_height; | 207 | return ideal_height; |
42 | } | 208 | } |
43 | 209 | ||
44 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 210 | static uint32_t render_status_line_i3bar(cairo_t *cairo, |
45 | struct swaybar_config *config, struct status_line *status, | 211 | struct swaybar_config *config, struct status_line *status, |
46 | bool focused, uint32_t width, uint32_t height) { | 212 | bool focused, double *x, uint32_t width, uint32_t height) { |
47 | // TODO | 213 | struct i3bar_block *block; |
48 | return 0; | 214 | uint32_t max_height = 0; |
215 | bool edge = true; | ||
216 | wl_list_for_each_reverse(block, &status->blocks, link) { | ||
217 | uint32_t h = render_status_block(cairo, config, | ||
218 | block, x, height, focused, edge); | ||
219 | max_height = h > max_height ? h : max_height; | ||
220 | edge = false; | ||
221 | } | ||
222 | return max_height; | ||
49 | } | 223 | } |
50 | 224 | ||
51 | static uint32_t render_status_line(cairo_t *cairo, | 225 | static uint32_t render_status_line(cairo_t *cairo, |
52 | struct swaybar_config *config, struct status_line *status, | 226 | struct swaybar_config *config, struct status_line *status, |
53 | bool focused, uint32_t width, uint32_t height) { | 227 | bool focused, double *x, uint32_t width, uint32_t height) { |
54 | switch (status->protocol) { | 228 | switch (status->protocol) { |
229 | case PROTOCOL_ERROR: | ||
230 | return render_status_line_error(cairo, | ||
231 | config, status->text, x, width, height); | ||
55 | case PROTOCOL_TEXT: | 232 | case PROTOCOL_TEXT: |
56 | return render_status_line_text(cairo, | 233 | return render_status_line_text(cairo, |
57 | config, status, focused, width, height); | 234 | config, status->text, focused, x, width, height); |
58 | case PROTOCOL_I3BAR: | 235 | case PROTOCOL_I3BAR: |
59 | return render_status_line_i3bar(cairo, | 236 | return render_status_line_i3bar(cairo, |
60 | config, status, focused, width, height); | 237 | config, status, focused, x, width, height); |
61 | default: | 238 | case PROTOCOL_UNDEF: |
62 | return 0; | 239 | return 0; |
63 | } | 240 | } |
241 | return 0; | ||
64 | } | 242 | } |
65 | 243 | ||
66 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 244 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, |
@@ -211,9 +389,10 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
211 | cairo, config, config->mode, x, output->height); | 389 | cairo, config, config->mode, x, output->height); |
212 | max_height = h > max_height ? h : max_height; | 390 | max_height = h > max_height ? h : max_height; |
213 | } | 391 | } |
392 | x = output->width; | ||
214 | if (bar->status) { | 393 | if (bar->status) { |
215 | uint32_t h = render_status_line(cairo, config, bar->status, | 394 | uint32_t h = render_status_line(cairo, config, bar->status, |
216 | output->focused, output->width, output->height); | 395 | output->focused, &x, output->width, output->height); |
217 | max_height = h > max_height ? h : max_height; | 396 | max_height = h > max_height ? h : max_height; |
218 | } | 397 | } |
219 | 398 | ||
diff --git a/swaybar/status_line.c b/swaybar/status_line.c index c94ac6d4..cc7e217f 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c | |||
@@ -17,13 +17,13 @@ void status_error(struct status_line *status, const char *text) { | |||
17 | status->text = text; | 17 | status->text = text; |
18 | } | 18 | } |
19 | 19 | ||
20 | bool handle_status_readable(struct status_line *status) { | 20 | bool status_handle_readable(struct status_line *status) { |
21 | char *line; | 21 | char *line; |
22 | switch (status->protocol) { | 22 | switch (status->protocol) { |
23 | case PROTOCOL_ERROR: | 23 | case PROTOCOL_ERROR: |
24 | return false; | 24 | return false; |
25 | case PROTOCOL_I3BAR: | 25 | case PROTOCOL_I3BAR: |
26 | if (i3bar_readable(status) > 0) { | 26 | if (i3bar_handle_readable(status) > 0) { |
27 | return true; | 27 | return true; |
28 | } | 28 | } |
29 | break; | 29 | break; |
@@ -66,6 +66,7 @@ bool handle_status_readable(struct status_line *status) { | |||
66 | 66 | ||
67 | status->protocol = PROTOCOL_I3BAR; | 67 | status->protocol = PROTOCOL_I3BAR; |
68 | free(status->text_state.buffer); | 68 | free(status->text_state.buffer); |
69 | wl_list_init(&status->blocks); | ||
69 | status->i3bar_state.buffer_size = 4096; | 70 | status->i3bar_state.buffer_size = 4096; |
70 | status->i3bar_state.buffer = | 71 | status->i3bar_state.buffer = |
71 | malloc(status->i3bar_state.buffer_size); | 72 | malloc(status->i3bar_state.buffer_size); |