diff options
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 517 |
1 files changed, 200 insertions, 317 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index 6fc09078..3d9ef66b 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -1,228 +1,120 @@ | |||
1 | #include <limits.h> | ||
1 | #include <stdlib.h> | 2 | #include <stdlib.h> |
2 | #include <stdint.h> | 3 | #include <stdint.h> |
3 | #include <string.h> | 4 | #include <string.h> |
4 | 5 | #include <wlr/util/log.h> | |
5 | #include "client/cairo.h" | 6 | #include "cairo.h" |
6 | #include "client/pango.h" | 7 | #include "pango.h" |
7 | #include "client/window.h" | 8 | #include "pool-buffer.h" |
9 | #include "swaybar/bar.h" | ||
8 | #include "swaybar/config.h" | 10 | #include "swaybar/config.h" |
9 | #include "swaybar/status_line.h" | ||
10 | #include "swaybar/render.h" | 11 | #include "swaybar/render.h" |
11 | #ifdef ENABLE_TRAY | 12 | #include "swaybar/status_line.h" |
12 | #include "swaybar/tray/tray.h" | 13 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
13 | #include "swaybar/tray/sni.h" | ||
14 | #endif | ||
15 | #include "log.h" | ||
16 | |||
17 | |||
18 | /* internal spacing */ | ||
19 | static int margin = 3; | ||
20 | static int ws_horizontal_padding = 5; | ||
21 | static double ws_vertical_padding = 1.5; | ||
22 | static int ws_spacing = 1; | ||
23 | |||
24 | /** | ||
25 | * Renders a sharp line of any width and height. | ||
26 | * | ||
27 | * The line is drawn from (x,y) to (x+width,y+height) where width/height is 0 | ||
28 | * if the line has a width/height of one pixel, respectively. | ||
29 | */ | ||
30 | static void render_sharp_line(cairo_t *cairo, uint32_t color, double x, double y, double width, double height) { | ||
31 | cairo_set_source_u32(cairo, color); | ||
32 | |||
33 | if (width > 1 && height > 1) { | ||
34 | cairo_rectangle(cairo, x, y, width, height); | ||
35 | cairo_fill(cairo); | ||
36 | } else { | ||
37 | if (width == 1) { | ||
38 | x += 0.5; | ||
39 | height += y; | ||
40 | width = x; | ||
41 | } | ||
42 | 14 | ||
43 | if (height == 1) { | 15 | static const int ws_horizontal_padding = 5; |
44 | y += 0.5; | 16 | static const double ws_vertical_padding = 1.5; |
45 | width += x; | 17 | static const double border_width = 1; |
46 | height = y; | ||
47 | } | ||
48 | 18 | ||
49 | cairo_move_to(cairo, x, y); | 19 | static uint32_t render_status_line_text(cairo_t *cairo, |
50 | cairo_set_line_width(cairo, 1.0); | 20 | struct swaybar_config *config, struct status_line *status, |
51 | cairo_line_to(cairo, width, height); | 21 | bool focused, uint32_t width, uint32_t height) { |
52 | cairo_stroke(cairo); | 22 | if (!status->text) { |
23 | return 0; | ||
53 | } | 24 | } |
25 | cairo_set_source_u32(cairo, focused ? | ||
26 | config->colors.focused_statusline : config->colors.statusline); | ||
27 | static const int margin = 3; | ||
28 | int text_width, text_height; | ||
29 | get_text_size(cairo, config->font, &text_width, &text_height, | ||
30 | 1, config->pango_markup, "%s", status->text); | ||
31 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
32 | if (height < ideal_height) { | ||
33 | return ideal_height; | ||
34 | } | ||
35 | double text_y = height / 2.0 - text_height / 2.0; | ||
36 | cairo_move_to(cairo, width - text_width - margin, (int)floor(text_y)); | ||
37 | pango_printf(cairo, config->font, 1, config->pango_markup, | ||
38 | "%s", status->text); | ||
39 | return ideal_height; | ||
54 | } | 40 | } |
55 | 41 | ||
56 | static void render_block(struct window *window, struct config *config, struct status_block *block, double *x, bool edge, bool is_focused) { | 42 | static uint32_t render_status_line_i3bar(cairo_t *cairo, |
57 | int width, height, sep_width; | 43 | struct swaybar_config *config, struct status_line *status, |
58 | get_text_size(window->cairo, window->font, &width, &height, | 44 | bool focused, uint32_t width, uint32_t height) { |
59 | window->scale, block->markup, "%s", block->full_text); | 45 | // TODO |
60 | 46 | return 0; | |
61 | int textwidth = width; | 47 | } |
62 | double block_width = width; | ||
63 | |||
64 | if (width < block->min_width) { | ||
65 | width = block->min_width; | ||
66 | } | ||
67 | |||
68 | *x -= width; | ||
69 | |||
70 | if (block->border != 0 && block->border_left > 0) { | ||
71 | *x -= (block->border_left + margin); | ||
72 | block_width += block->border_left + margin; | ||
73 | } | ||
74 | |||
75 | if (block->border != 0 && block->border_right > 0) { | ||
76 | *x -= (block->border_right + margin); | ||
77 | block_width += block->border_right + margin; | ||
78 | } | ||
79 | |||
80 | // Add separator | ||
81 | if (!edge) { | ||
82 | if (config->sep_symbol) { | ||
83 | get_text_size(window->cairo, window->font, &sep_width, &height, | ||
84 | window->scale, false, "%s", config->sep_symbol); | ||
85 | if (sep_width > block->separator_block_width) { | ||
86 | block->separator_block_width = sep_width + margin * 2; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | *x -= block->separator_block_width; | ||
91 | } else { | ||
92 | *x -= margin; | ||
93 | } | ||
94 | |||
95 | double pos = *x; | ||
96 | |||
97 | block->x = (int)pos; | ||
98 | block->width = (int)block_width; | ||
99 | |||
100 | // render background | ||
101 | if (block->background != 0x0) { | ||
102 | cairo_set_source_u32(window->cairo, block->background); | ||
103 | cairo_rectangle(window->cairo, pos - 0.5, 1, block_width, (window->height * window->scale) - 2); | ||
104 | cairo_fill(window->cairo); | ||
105 | } | ||
106 | |||
107 | // render top border | ||
108 | if (block->border != 0 && block->border_top > 0) { | ||
109 | render_sharp_line(window->cairo, block->border, | ||
110 | pos - 0.5, | ||
111 | 1, | ||
112 | block_width, | ||
113 | block->border_top); | ||
114 | } | ||
115 | |||
116 | // render bottom border | ||
117 | if (block->border != 0 && block->border_bottom > 0) { | ||
118 | render_sharp_line(window->cairo, block->border, | ||
119 | pos - 0.5, | ||
120 | (window->height * window->scale) - 1 - block->border_bottom, | ||
121 | block_width, | ||
122 | block->border_bottom); | ||
123 | } | ||
124 | |||
125 | // render left border | ||
126 | if (block->border != 0 && block->border_left > 0) { | ||
127 | render_sharp_line(window->cairo, block->border, | ||
128 | pos - 0.5, | ||
129 | 1, | ||
130 | block->border_left, | ||
131 | (window->height * window->scale) - 2); | ||
132 | |||
133 | pos += block->border_left + margin; | ||
134 | } | ||
135 | |||
136 | // render text | ||
137 | double offset = 0; | ||
138 | |||
139 | if (strncmp(block->align, "left", 5) == 0) { | ||
140 | offset = pos; | ||
141 | } else if (strncmp(block->align, "right", 5) == 0) { | ||
142 | offset = pos + width - textwidth; | ||
143 | } else if (strncmp(block->align, "center", 6) == 0) { | ||
144 | offset = pos + (width - textwidth) / 2; | ||
145 | } | ||
146 | |||
147 | cairo_move_to(window->cairo, offset, margin); | ||
148 | cairo_set_source_u32(window->cairo, block->color); | ||
149 | pango_printf(window->cairo, window->font, window->scale, | ||
150 | block->markup, "%s", block->full_text); | ||
151 | |||
152 | pos += width; | ||
153 | |||
154 | // render right border | ||
155 | if (block->border != 0 && block->border_right > 0) { | ||
156 | pos += margin; | ||
157 | |||
158 | render_sharp_line(window->cairo, block->border, | ||
159 | pos - 0.5, | ||
160 | 1, | ||
161 | block->border_right, | ||
162 | (window->height * window->scale) - 2); | ||
163 | |||
164 | pos += block->border_right; | ||
165 | } | ||
166 | 48 | ||
167 | // render separator | 49 | static uint32_t render_status_line(cairo_t *cairo, |
168 | if (!edge && block->separator) { | 50 | struct swaybar_config *config, struct status_line *status, |
169 | if (is_focused) { | 51 | bool focused, uint32_t width, uint32_t height) { |
170 | cairo_set_source_u32(window->cairo, config->colors.focused_separator); | 52 | switch (status->protocol) { |
171 | } else { | 53 | case PROTOCOL_TEXT: |
172 | cairo_set_source_u32(window->cairo, config->colors.separator); | 54 | return render_status_line_text(cairo, |
173 | } | 55 | config, status, focused, width, height); |
174 | if (config->sep_symbol) { | 56 | case PROTOCOL_I3BAR: |
175 | offset = pos + (block->separator_block_width - sep_width) / 2; | 57 | return render_status_line_i3bar(cairo, |
176 | cairo_move_to(window->cairo, offset, margin); | 58 | config, status, focused, width, height); |
177 | pango_printf(window->cairo, window->font, window->scale, | 59 | default: |
178 | false, "%s", config->sep_symbol); | 60 | return 0; |
179 | } else { | ||
180 | cairo_set_line_width(window->cairo, 1); | ||
181 | cairo_move_to(window->cairo, pos + block->separator_block_width/2, | ||
182 | margin); | ||
183 | cairo_line_to(window->cairo, pos + block->separator_block_width/2, | ||
184 | (window->height * window->scale) - margin); | ||
185 | cairo_stroke(window->cairo); | ||
186 | } | ||
187 | } | 61 | } |
188 | |||
189 | } | 62 | } |
190 | 63 | ||
191 | static const char *strip_workspace_name(bool strip_num, const char *ws_name) { | 64 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, |
192 | bool strip = false; | 65 | struct swaybar_config *config, const char *mode, double x, |
193 | int i; | 66 | uint32_t height) { |
67 | int text_width, text_height; | ||
68 | get_text_size(cairo, config->font, &text_width, &text_height, | ||
69 | 1, true, "%s", mode); | ||
70 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 | ||
71 | + border_width * 2; | ||
72 | if (height < ideal_height) { | ||
73 | return ideal_height; | ||
74 | } | ||
75 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | ||
76 | |||
77 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); | ||
78 | cairo_rectangle(cairo, x, 0, width, height); | ||
79 | cairo_fill(cairo); | ||
80 | |||
81 | cairo_set_source_u32(cairo, config->colors.binding_mode.border); | ||
82 | cairo_rectangle(cairo, x, 0, width, border_width); | ||
83 | cairo_fill(cairo); | ||
84 | cairo_rectangle(cairo, x, 0, border_width, height); | ||
85 | cairo_fill(cairo); | ||
86 | cairo_rectangle(cairo, x + width - border_width, 0, border_width, height); | ||
87 | cairo_fill(cairo); | ||
88 | cairo_rectangle(cairo, x, height - border_width, width, border_width); | ||
89 | cairo_fill(cairo); | ||
90 | |||
91 | double text_y = height / 2.0 - text_height / 2.0; | ||
92 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); | ||
93 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); | ||
94 | pango_printf(cairo, config->font, 1, true, "%s", mode); | ||
95 | return ideal_height; | ||
96 | } | ||
194 | 97 | ||
195 | if (strip_num) { | 98 | static const char *strip_workspace_number(const char *ws_name) { |
196 | int len = strlen(ws_name); | 99 | size_t len = strlen(ws_name); |
197 | for (i = 0; i < len; ++i) { | 100 | for (size_t i = 0; i < len; ++i) { |
198 | if (!('0' <= ws_name[i] && ws_name[i] <= '9')) { | 101 | if (ws_name[i] < '0' || ws_name[i] > '9') { |
199 | if (':' == ws_name[i] && i < len-1 && i > 0) { | 102 | if (':' == ws_name[i] && i < len - 1 && i > 0) { |
200 | strip = true; | 103 | return ws_name + i + 1; |
201 | ++i; | ||
202 | } | ||
203 | break; | ||
204 | } | 104 | } |
105 | return ws_name; | ||
205 | } | 106 | } |
206 | } | 107 | } |
207 | |||
208 | if (strip) { | ||
209 | return ws_name + i; | ||
210 | } | ||
211 | |||
212 | return ws_name; | 108 | return ws_name; |
213 | } | 109 | } |
214 | 110 | ||
215 | void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height) { | 111 | static uint32_t render_workspace_button(cairo_t *cairo, |
216 | const char *stripped_name = strip_workspace_name(swaybar.config->strip_workspace_numbers, workspace_name); | 112 | struct swaybar_config *config, struct swaybar_workspace *ws, |
217 | 113 | double *x, uint32_t height) { | |
218 | get_text_size(window->cairo, window->font, width, height, | 114 | const char *name = ws->name; |
219 | window->scale, true, "%s", stripped_name); | 115 | if (config->strip_workspace_numbers) { |
220 | *width += 2 * ws_horizontal_padding; | 116 | name = strip_workspace_number(ws->name); |
221 | *height += 2 * ws_vertical_padding; | 117 | } |
222 | } | ||
223 | |||
224 | static void render_workspace_button(struct window *window, struct config *config, struct workspace *ws, double *x) { | ||
225 | const char *stripped_name = strip_workspace_name(config->strip_workspace_numbers, ws->name); | ||
226 | 118 | ||
227 | struct box_colors box_colors; | 119 | struct box_colors box_colors; |
228 | if (ws->urgent) { | 120 | if (ws->urgent) { |
@@ -235,133 +127,124 @@ static void render_workspace_button(struct window *window, struct config *config | |||
235 | box_colors = config->colors.inactive_workspace; | 127 | box_colors = config->colors.inactive_workspace; |
236 | } | 128 | } |
237 | 129 | ||
238 | int width, height; | 130 | int text_width, text_height; |
239 | workspace_button_size(window, stripped_name, &width, &height); | 131 | get_text_size(cairo, config->font, &text_width, &text_height, |
240 | 132 | 1, true, "%s", name); | |
241 | // background | 133 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height |
242 | cairo_set_source_u32(window->cairo, box_colors.background); | 134 | + border_width * 2; |
243 | cairo_rectangle(window->cairo, *x, 1.5, width - 1, height); | 135 | if (height < ideal_height) { |
244 | cairo_fill(window->cairo); | 136 | return ideal_height; |
245 | 137 | } | |
246 | // border | 138 | uint32_t width = ws_horizontal_padding * 2 + text_width + border_width * 2; |
247 | cairo_set_source_u32(window->cairo, box_colors.border); | 139 | |
248 | cairo_rectangle(window->cairo, *x, 1.5, width - 1, height); | 140 | cairo_set_source_u32(cairo, box_colors.background); |
249 | cairo_stroke(window->cairo); | 141 | cairo_rectangle(cairo, *x, 0, width, height); |
250 | 142 | cairo_fill(cairo); | |
251 | // text | 143 | |
252 | cairo_set_source_u32(window->cairo, box_colors.text); | 144 | cairo_set_source_u32(cairo, box_colors.border); |
253 | cairo_move_to(window->cairo, (int)*x + ws_horizontal_padding, margin); | 145 | cairo_rectangle(cairo, *x, 0, width, border_width); |
254 | pango_printf(window->cairo, window->font, window->scale, | 146 | cairo_fill(cairo); |
255 | true, "%s", stripped_name); | 147 | cairo_rectangle(cairo, *x, 0, border_width, height); |
256 | 148 | cairo_fill(cairo); | |
257 | *x += width + ws_spacing; | 149 | cairo_rectangle(cairo, *x + width - border_width, 0, border_width, height); |
258 | } | 150 | cairo_fill(cairo); |
259 | 151 | cairo_rectangle(cairo, *x, height - border_width, width, border_width); | |
260 | static void render_binding_mode_indicator(struct window *window, struct config *config, double pos) { | 152 | cairo_fill(cairo); |
261 | int width, height; | 153 | |
262 | get_text_size(window->cairo, window->font, &width, &height, | 154 | double text_y = height / 2.0 - text_height / 2.0; |
263 | window->scale, false, "%s", config->mode); | 155 | cairo_set_source_u32(cairo, box_colors.text); |
264 | 156 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); | |
265 | // background | 157 | pango_printf(cairo, config->font, 1, true, "%s", name); |
266 | cairo_set_source_u32(window->cairo, config->colors.binding_mode.background); | 158 | |
267 | cairo_rectangle(window->cairo, pos, 1.5, width + ws_horizontal_padding * 2 - 1, | 159 | *x += width; |
268 | height + ws_vertical_padding * 2); | 160 | return ideal_height; |
269 | cairo_fill(window->cairo); | ||
270 | |||
271 | // border | ||
272 | cairo_set_source_u32(window->cairo, config->colors.binding_mode.border); | ||
273 | cairo_rectangle(window->cairo, pos, 1.5, width + ws_horizontal_padding * 2 - 1, | ||
274 | height + ws_vertical_padding * 2); | ||
275 | cairo_stroke(window->cairo); | ||
276 | |||
277 | // text | ||
278 | cairo_set_source_u32(window->cairo, config->colors.binding_mode.text); | ||
279 | cairo_move_to(window->cairo, (int)pos + ws_horizontal_padding, margin); | ||
280 | pango_printf(window->cairo, window->font, window->scale, | ||
281 | false, "%s", config->mode); | ||
282 | } | 161 | } |
283 | 162 | ||
284 | void render(struct output *output, struct config *config, struct status_line *line) { | 163 | static uint32_t render_to_cairo(cairo_t *cairo, |
285 | int i; | 164 | struct swaybar *bar, struct swaybar_output *output) { |
286 | 165 | struct swaybar_config *config = bar->config; | |
287 | struct window *window = output->window; | ||
288 | cairo_t *cairo = window->cairo; | ||
289 | bool is_focused = output->focused; | ||
290 | |||
291 | // Clear | ||
292 | cairo_save(cairo); | ||
293 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); | ||
294 | cairo_paint(cairo); | ||
295 | cairo_restore(cairo); | ||
296 | 166 | ||
297 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 167 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
298 | 168 | if (output->focused) { | |
299 | // Background | ||
300 | if (is_focused) { | ||
301 | cairo_set_source_u32(cairo, config->colors.focused_background); | 169 | cairo_set_source_u32(cairo, config->colors.focused_background); |
302 | } else { | 170 | } else { |
303 | cairo_set_source_u32(cairo, config->colors.background); | 171 | cairo_set_source_u32(cairo, config->colors.background); |
304 | } | 172 | } |
305 | cairo_paint(cairo); | 173 | cairo_paint(cairo); |
306 | 174 | ||
307 | #ifdef ENABLE_TRAY | 175 | uint32_t max_height = 0; |
308 | uint32_t tray_width = tray_render(output, config); | 176 | /* |
309 | #else | 177 | * Each render_* function takes the actual height of the bar, and returns |
310 | const uint32_t tray_width = window->width * window->scale; | 178 | * the ideal height. If the actual height is too short, the render function |
311 | #endif | 179 | * can do whatever it wants - the buffer won't be committed. If the actual |
312 | 180 | * height is too tall, the render function should adapt its drawing to | |
313 | // Command output | 181 | * utilize the available space. |
314 | if (is_focused) { | 182 | */ |
315 | cairo_set_source_u32(cairo, config->colors.focused_statusline); | 183 | double x = 0; |
316 | } else { | ||
317 | cairo_set_source_u32(cairo, config->colors.statusline); | ||
318 | } | ||
319 | |||
320 | int width, height; | ||
321 | |||
322 | if (line->protocol == TEXT) { | ||
323 | get_text_size(window->cairo, window->font, &width, &height, | ||
324 | window->scale, config->pango_markup, "%s", line->text_line); | ||
325 | cairo_move_to(cairo, tray_width - margin - width, margin); | ||
326 | pango_printf(window->cairo, window->font, window->scale, | ||
327 | config->pango_markup, "%s", line->text_line); | ||
328 | } else if (line->protocol == I3BAR && line->block_line) { | ||
329 | double pos = tray_width - 0.5; | ||
330 | bool edge = true; | ||
331 | for (i = line->block_line->length - 1; i >= 0; --i) { | ||
332 | struct status_block *block = line->block_line->items[i]; | ||
333 | if (block->full_text && block->full_text[0]) { | ||
334 | render_block(window, config, block, &pos, edge, is_focused); | ||
335 | edge = false; | ||
336 | } | ||
337 | } | ||
338 | } | ||
339 | |||
340 | cairo_set_line_width(cairo, 1.0); | ||
341 | double x = 0.5; | ||
342 | |||
343 | // Workspaces | ||
344 | if (config->workspace_buttons) { | 184 | if (config->workspace_buttons) { |
345 | for (i = 0; i < output->workspaces->length; ++i) { | 185 | struct swaybar_workspace *ws; |
346 | struct workspace *ws = output->workspaces->items[i]; | 186 | wl_list_for_each_reverse(ws, &output->workspaces, link) { |
347 | render_workspace_button(window, config, ws, &x); | 187 | uint32_t h = render_workspace_button( |
188 | cairo, config, ws, &x, output->height); | ||
189 | max_height = h > max_height ? h : max_height; | ||
348 | } | 190 | } |
349 | } | 191 | } |
350 | 192 | if (config->binding_mode_indicator && config->mode) { | |
351 | // binding mode indicator | 193 | uint32_t h = render_binding_mode_indicator( |
352 | if (config->mode && config->binding_mode_indicator) { | 194 | cairo, config, config->mode, x, output->height); |
353 | render_binding_mode_indicator(window, config, x); | 195 | max_height = h > max_height ? h : max_height; |
196 | } | ||
197 | if (bar->status) { | ||
198 | uint32_t h = render_status_line(cairo, config, bar->status, | ||
199 | output->focused, output->width, output->height); | ||
200 | max_height = h > max_height ? h : max_height; | ||
354 | } | 201 | } |
202 | |||
203 | return max_height > output->height ? max_height : output->height; | ||
355 | } | 204 | } |
356 | 205 | ||
357 | void set_window_height(struct window *window, int height) { | 206 | void render_frame(struct swaybar *bar, |
358 | int text_width, text_height; | 207 | struct swaybar_output *output) { |
359 | get_text_size(window->cairo, window->font, | 208 | cairo_surface_t *recorder = cairo_recording_surface_create( |
360 | &text_width, &text_height, window->scale, false, | 209 | CAIRO_CONTENT_COLOR_ALPHA, NULL); |
361 | "Test string for measuring purposes"); | 210 | cairo_t *cairo = cairo_create(recorder); |
362 | if (height > 0) { | 211 | cairo_save(cairo); |
363 | margin = (height - text_height) / 2; | 212 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); |
364 | ws_vertical_padding = margin - 1.5; | 213 | cairo_paint(cairo); |
365 | } | 214 | cairo_restore(cairo); |
366 | window->height = (text_height + margin * 2) / window->scale; | 215 | uint32_t height = render_to_cairo(cairo, bar, output); |
216 | if (bar->config->height >= 0 && height < (uint32_t)bar->config->height) { | ||
217 | height = bar->config->height; | ||
218 | } | ||
219 | if (height != output->height) { | ||
220 | // Reconfigure surface | ||
221 | zwlr_layer_surface_v1_set_size( | ||
222 | output->layer_surface, 0, height); | ||
223 | zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, height); | ||
224 | // TODO: this could infinite loop if the compositor assigns us a | ||
225 | // different height than what we asked for | ||
226 | wl_surface_commit(output->surface); | ||
227 | wl_display_roundtrip(bar->display); | ||
228 | } else { | ||
229 | // Replay recording into shm and send it off | ||
230 | output->current_buffer = get_next_buffer(bar->shm, | ||
231 | output->buffers, output->width, output->height); | ||
232 | cairo_t *shm = output->current_buffer->cairo; | ||
233 | |||
234 | cairo_save(shm); | ||
235 | cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR); | ||
236 | cairo_paint(shm); | ||
237 | cairo_restore(shm); | ||
238 | |||
239 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); | ||
240 | cairo_paint(shm); | ||
241 | |||
242 | wl_surface_attach(output->surface, | ||
243 | output->current_buffer->buffer, 0, 0); | ||
244 | wl_surface_damage(output->surface, 0, 0, output->width, output->height); | ||
245 | wl_surface_commit(output->surface); | ||
246 | wl_display_roundtrip(bar->display); | ||
247 | } | ||
248 | cairo_surface_destroy(recorder); | ||
249 | cairo_destroy(cairo); | ||
367 | } | 250 | } |