diff options
author | 2018-04-02 15:30:58 -0400 | |
---|---|---|
committer | 2018-04-02 15:30:58 -0400 | |
commit | a4a241697ae591289d7c14eff972e1ef787216e2 (patch) | |
tree | d82d3c3eba2946670aa634a62d03feb7102f0bf8 /swaybar/render.c | |
parent | Xwayland unmanaged views aren't views anymore (diff) | |
parent | Merge pull request #1699 from acrisci/seat-fixes (diff) | |
download | sway-a4a241697ae591289d7c14eff972e1ef787216e2.tar.gz sway-a4a241697ae591289d7c14eff972e1ef787216e2.tar.zst sway-a4a241697ae591289d7c14eff972e1ef787216e2.zip |
Merge branch 'wlroots' into view-redesign
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 238 |
1 files changed, 218 insertions, 20 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index c2358724..6f3b0788 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,211 @@ 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 void block_hotspot_callback(struct swaybar_output *output, | ||
93 | int x, int y, uint32_t button, void *data) { | ||
94 | struct i3bar_block *block = data; | ||
95 | struct status_line *status = output->bar->status; | ||
96 | i3bar_block_send_click(status, block, x, y, button); | ||
97 | } | ||
98 | |||
99 | static uint32_t render_status_block(cairo_t *cairo, | ||
100 | struct swaybar_config *config, struct swaybar_output *output, | ||
101 | struct i3bar_block *block, double *x, | ||
102 | uint32_t height, bool focused, bool edge) { | ||
103 | static const int margin = 3; | ||
104 | if (!block->full_text || !*block->full_text) { | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | int text_width, text_height; | ||
109 | get_text_size(cairo, config->font, &text_width, &text_height, | ||
110 | 1, block->markup, "%s", block->full_text); | ||
111 | int width = text_width; | ||
112 | if (width < block->min_width) { | ||
113 | width = block->min_width; | ||
114 | } | ||
115 | double block_width = width; | ||
116 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
117 | if (height < ideal_height) { | ||
118 | return ideal_height; | ||
119 | } | ||
120 | |||
121 | *x -= width; | ||
122 | if (block->border && block->border_left > 0) { | ||
123 | *x -= (block->border_left + margin); | ||
124 | block_width += block->border_left + margin; | ||
125 | } | ||
126 | if (block->border && block->border_right > 0) { | ||
127 | *x -= (block->border_right + margin); | ||
128 | block_width += block->border_right + margin; | ||
129 | } | ||
130 | |||
131 | int sep_width; | ||
132 | if (!edge) { | ||
133 | if (config->sep_symbol) { | ||
134 | int _height; | ||
135 | get_text_size(cairo, config->font, &sep_width, &_height, | ||
136 | 1, false, "%s", config->sep_symbol); | ||
137 | uint32_t _ideal_height = _height + ws_vertical_padding * 2; | ||
138 | if (height < _ideal_height) { | ||
139 | return _height; | ||
140 | } | ||
141 | if (sep_width > block->separator_block_width) { | ||
142 | block->separator_block_width = sep_width + margin * 2; | ||
143 | } | ||
144 | } | ||
145 | *x -= block->separator_block_width; | ||
146 | } else { | ||
147 | *x -= margin; | ||
148 | } | ||
149 | |||
150 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | ||
151 | hotspot->x = *x; | ||
152 | hotspot->y = 0; | ||
153 | hotspot->width = width; | ||
154 | hotspot->height = height; | ||
155 | hotspot->callback = block_hotspot_callback; | ||
156 | hotspot->destroy = NULL; | ||
157 | hotspot->data = block; | ||
158 | wl_list_insert(&output->hotspots, &hotspot->link); | ||
159 | |||
160 | double pos = *x; | ||
161 | if (block->background) { | ||
162 | cairo_set_source_u32(cairo, block->background); | ||
163 | cairo_rectangle(cairo, pos - 0.5, 1, block_width, height); | ||
164 | cairo_fill(cairo); | ||
165 | } | ||
166 | |||
167 | if (block->border && block->border_top > 0) { | ||
168 | render_sharp_line(cairo, block->border, | ||
169 | pos - 0.5, 1, block_width, block->border_top); | ||
170 | } | ||
171 | if (block->border && block->border_bottom > 0) { | ||
172 | render_sharp_line(cairo, block->border, | ||
173 | pos - 0.5, height - 1 - block->border_bottom, | ||
174 | block_width, block->border_bottom); | ||
175 | } | ||
176 | if (block->border != 0 && block->border_left > 0) { | ||
177 | render_sharp_line(cairo, block->border, | ||
178 | pos - 0.5, 1, block->border_left, height); | ||
179 | pos += block->border_left + margin; | ||
180 | } | ||
181 | |||
182 | double offset = 0; | ||
183 | if (strncmp(block->align, "left", 5) == 0) { | ||
184 | offset = pos; | ||
185 | } else if (strncmp(block->align, "right", 5) == 0) { | ||
186 | offset = pos + width - text_width; | ||
187 | } else if (strncmp(block->align, "center", 6) == 0) { | ||
188 | offset = pos + (width - text_width) / 2; | ||
189 | } | ||
190 | cairo_move_to(cairo, offset, height / 2.0 - text_height / 2.0); | ||
191 | uint32_t color = block->color ? *block->color : config->colors.statusline; | ||
192 | cairo_set_source_u32(cairo, color); | ||
193 | pango_printf(cairo, config->font, 1, block->markup, "%s", block->full_text); | ||
194 | pos += width; | ||
195 | |||
196 | if (block->border && block->border_right > 0) { | ||
197 | pos += margin; | ||
198 | render_sharp_line(cairo, block->border, | ||
199 | pos - 0.5, 1, block->border_right, height); | ||
200 | pos += block->border_right; | ||
201 | } | ||
202 | |||
203 | if (!edge && block->separator) { | ||
204 | if (focused) { | ||
205 | cairo_set_source_u32(cairo, config->colors.focused_separator); | ||
206 | } else { | ||
207 | cairo_set_source_u32(cairo, config->colors.separator); | ||
208 | } | ||
209 | if (config->sep_symbol) { | ||
210 | offset = pos + (block->separator_block_width - sep_width) / 2; | ||
211 | cairo_move_to(cairo, offset, margin); | ||
212 | pango_printf(cairo, config->font, 1, false, | ||
213 | "%s", config->sep_symbol); | ||
214 | } else { | ||
215 | cairo_set_line_width(cairo, 1); | ||
216 | cairo_move_to(cairo, | ||
217 | pos + block->separator_block_width / 2, margin); | ||
218 | cairo_line_to(cairo, | ||
219 | pos + block->separator_block_width / 2, height - margin); | ||
220 | cairo_stroke(cairo); | ||
221 | } | ||
222 | } | ||
41 | return ideal_height; | 223 | return ideal_height; |
42 | } | 224 | } |
43 | 225 | ||
44 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 226 | static uint32_t render_status_line_i3bar(cairo_t *cairo, |
45 | struct swaybar_config *config, struct status_line *status, | 227 | struct swaybar_config *config, struct swaybar_output *output, |
46 | bool focused, uint32_t width, uint32_t height) { | 228 | struct status_line *status, bool focused, |
47 | // TODO | 229 | double *x, uint32_t width, uint32_t height) { |
48 | return 0; | 230 | uint32_t max_height = 0; |
231 | bool edge = true; | ||
232 | struct i3bar_block *block; | ||
233 | wl_list_for_each(block, &status->blocks, link) { | ||
234 | uint32_t h = render_status_block(cairo, config, output, | ||
235 | block, x, height, focused, edge); | ||
236 | max_height = h > max_height ? h : max_height; | ||
237 | edge = false; | ||
238 | } | ||
239 | return max_height; | ||
49 | } | 240 | } |
50 | 241 | ||
51 | static uint32_t render_status_line(cairo_t *cairo, | 242 | static uint32_t render_status_line(cairo_t *cairo, |
52 | struct swaybar_config *config, struct status_line *status, | 243 | struct swaybar_config *config, struct swaybar_output *output, |
53 | bool focused, uint32_t width, uint32_t height) { | 244 | struct status_line *status, bool focused, |
245 | double *x, uint32_t width, uint32_t height) { | ||
54 | switch (status->protocol) { | 246 | switch (status->protocol) { |
247 | case PROTOCOL_ERROR: | ||
248 | return render_status_line_error(cairo, | ||
249 | config, status->text, x, width, height); | ||
55 | case PROTOCOL_TEXT: | 250 | case PROTOCOL_TEXT: |
56 | return render_status_line_text(cairo, | 251 | return render_status_line_text(cairo, |
57 | config, status, focused, width, height); | 252 | config, status->text, focused, x, width, height); |
58 | case PROTOCOL_I3BAR: | 253 | case PROTOCOL_I3BAR: |
59 | return render_status_line_i3bar(cairo, | 254 | return render_status_line_i3bar(cairo, config, output, status, |
60 | config, status, focused, width, height); | 255 | focused, x, width, height); |
61 | default: | 256 | case PROTOCOL_UNDEF: |
62 | return 0; | 257 | return 0; |
63 | } | 258 | } |
259 | return 0; | ||
64 | } | 260 | } |
65 | 261 | ||
66 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 262 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, |
@@ -166,8 +362,8 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
166 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | 362 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); |
167 | hotspot->x = *x; | 363 | hotspot->x = *x; |
168 | hotspot->y = 0; | 364 | hotspot->y = 0; |
169 | hotspot->height = height; | ||
170 | hotspot->width = width; | 365 | hotspot->width = width; |
366 | hotspot->height = height; | ||
171 | hotspot->callback = workspace_hotspot_callback; | 367 | hotspot->callback = workspace_hotspot_callback; |
172 | hotspot->destroy = free; | 368 | hotspot->destroy = free; |
173 | hotspot->data = strdup(name); | 369 | hotspot->data = strdup(name); |
@@ -180,6 +376,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
180 | static uint32_t render_to_cairo(cairo_t *cairo, | 376 | static uint32_t render_to_cairo(cairo_t *cairo, |
181 | struct swaybar *bar, struct swaybar_output *output) { | 377 | struct swaybar *bar, struct swaybar_output *output) { |
182 | struct swaybar_config *config = bar->config; | 378 | struct swaybar_config *config = bar->config; |
379 | wlr_log(L_DEBUG, "output %p", output); | ||
183 | 380 | ||
184 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 381 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
185 | if (output->focused) { | 382 | if (output->focused) { |
@@ -211,9 +408,10 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
211 | cairo, config, config->mode, x, output->height); | 408 | cairo, config, config->mode, x, output->height); |
212 | max_height = h > max_height ? h : max_height; | 409 | max_height = h > max_height ? h : max_height; |
213 | } | 410 | } |
411 | x = output->width; | ||
214 | if (bar->status) { | 412 | if (bar->status) { |
215 | uint32_t h = render_status_line(cairo, config, bar->status, | 413 | uint32_t h = render_status_line(cairo, config, output, bar->status, |
216 | output->focused, output->width, output->height); | 414 | output->focused, &x, output->width, output->height); |
217 | max_height = h > max_height ? h : max_height; | 415 | max_height = h > max_height ? h : max_height; |
218 | } | 416 | } |
219 | 417 | ||