diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-04-03 21:06:28 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-04-03 21:06:28 -0400 |
commit | 260595076977729bcaf9aadcfbbc8c5f269c6387 (patch) | |
tree | c102e0391d37aab306e7ac839b50906112491477 | |
parent | Merge pull request #1717 from emersion/fix-multiple-outputs (diff) | |
download | sway-260595076977729bcaf9aadcfbbc8c5f269c6387.tar.gz sway-260595076977729bcaf9aadcfbbc8c5f269c6387.tar.zst sway-260595076977729bcaf9aadcfbbc8c5f269c6387.zip |
Add hidpi support to swaybar
-rw-r--r-- | include/swaybar/bar.h | 1 | ||||
-rw-r--r-- | swaybar/bar.c | 73 | ||||
-rw-r--r-- | swaybar/render.c | 168 |
3 files changed, 173 insertions, 69 deletions
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index 74292519..503b961c 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h | |||
@@ -58,6 +58,7 @@ struct swaybar_output { | |||
58 | bool focused; | 58 | bool focused; |
59 | 59 | ||
60 | uint32_t width, height; | 60 | uint32_t width, height; |
61 | int32_t scale; | ||
61 | struct pool_buffer buffers[2]; | 62 | struct pool_buffer buffers[2]; |
62 | struct pool_buffer *current_buffer; | 63 | struct pool_buffer *current_buffer; |
63 | }; | 64 | }; |
diff --git a/swaybar/bar.c b/swaybar/bar.c index fb417095..cf812a60 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -69,11 +69,19 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, | |||
69 | break; | 69 | break; |
70 | } | 70 | } |
71 | } | 71 | } |
72 | int max_scale = 1; | ||
73 | struct swaybar_output *_output; | ||
74 | wl_list_for_each(_output, &bar->outputs, link) { | ||
75 | if (_output->scale > max_scale) { | ||
76 | max_scale = _output->scale; | ||
77 | } | ||
78 | } | ||
79 | wl_surface_set_buffer_scale(pointer->cursor_surface, max_scale); | ||
72 | wl_surface_attach(pointer->cursor_surface, | 80 | wl_surface_attach(pointer->cursor_surface, |
73 | wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); | 81 | wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); |
74 | wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, | 82 | wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, |
75 | pointer->cursor_image->hotspot_x, | 83 | pointer->cursor_image->hotspot_x / max_scale, |
76 | pointer->cursor_image->hotspot_y); | 84 | pointer->cursor_image->hotspot_y / max_scale); |
77 | wl_surface_commit(pointer->cursor_surface); | 85 | wl_surface_commit(pointer->cursor_surface); |
78 | } | 86 | } |
79 | 87 | ||
@@ -103,10 +111,12 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | |||
103 | } | 111 | } |
104 | struct swaybar_hotspot *hotspot; | 112 | struct swaybar_hotspot *hotspot; |
105 | wl_list_for_each(hotspot, &output->hotspots, link) { | 113 | wl_list_for_each(hotspot, &output->hotspots, link) { |
106 | if (pointer->x >= hotspot->x | 114 | double x = pointer->x * output->scale; |
107 | && pointer->y >= hotspot->y | 115 | double y = pointer->y * output->scale; |
108 | && pointer->x < hotspot->x + hotspot->width | 116 | if (x >= hotspot->x |
109 | && pointer->y < hotspot->y + hotspot->height) { | 117 | && y >= hotspot->y |
118 | && x < hotspot->x + hotspot->width | ||
119 | && y < hotspot->y + hotspot->height) { | ||
110 | hotspot->callback(output, pointer->x, pointer->y, | 120 | hotspot->callback(output, pointer->x, pointer->y, |
111 | button, hotspot->data); | 121 | button, hotspot->data); |
112 | } | 122 | } |
@@ -197,12 +207,43 @@ const struct wl_seat_listener seat_listener = { | |||
197 | .name = seat_handle_name, | 207 | .name = seat_handle_name, |
198 | }; | 208 | }; |
199 | 209 | ||
210 | static void output_geometry(void *data, struct wl_output *output, int32_t x, | ||
211 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, | ||
212 | const char *make, const char *model, int32_t transform) { | ||
213 | // Who cares | ||
214 | } | ||
215 | |||
216 | static void output_mode(void *data, struct wl_output *output, uint32_t flags, | ||
217 | int32_t width, int32_t height, int32_t refresh) { | ||
218 | // Who cares | ||
219 | } | ||
220 | |||
221 | static void output_done(void *data, struct wl_output *output) { | ||
222 | // Who cares | ||
223 | } | ||
224 | |||
225 | static void output_scale(void *data, struct wl_output *wl_output, | ||
226 | int32_t factor) { | ||
227 | struct swaybar_output *output = data; | ||
228 | output->scale = factor; | ||
229 | if (output->surface) { | ||
230 | render_frame(output->bar, output); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | struct wl_output_listener output_listener = { | ||
235 | .geometry = output_geometry, | ||
236 | .mode = output_mode, | ||
237 | .done = output_done, | ||
238 | .scale = output_scale, | ||
239 | }; | ||
240 | |||
200 | static void handle_global(void *data, struct wl_registry *registry, | 241 | static void handle_global(void *data, struct wl_registry *registry, |
201 | uint32_t name, const char *interface, uint32_t version) { | 242 | uint32_t name, const char *interface, uint32_t version) { |
202 | struct swaybar *bar = data; | 243 | struct swaybar *bar = data; |
203 | if (strcmp(interface, wl_compositor_interface.name) == 0) { | 244 | if (strcmp(interface, wl_compositor_interface.name) == 0) { |
204 | bar->compositor = wl_registry_bind(registry, name, | 245 | bar->compositor = wl_registry_bind(registry, name, |
205 | &wl_compositor_interface, 1); | 246 | &wl_compositor_interface, 3); |
206 | } else if (strcmp(interface, wl_seat_interface.name) == 0) { | 247 | } else if (strcmp(interface, wl_seat_interface.name) == 0) { |
207 | bar->seat = wl_registry_bind(registry, name, | 248 | bar->seat = wl_registry_bind(registry, name, |
208 | &wl_seat_interface, 1); | 249 | &wl_seat_interface, 1); |
@@ -216,7 +257,9 @@ static void handle_global(void *data, struct wl_registry *registry, | |||
216 | calloc(1, sizeof(struct swaybar_output)); | 257 | calloc(1, sizeof(struct swaybar_output)); |
217 | output->bar = bar; | 258 | output->bar = bar; |
218 | output->output = wl_registry_bind(registry, name, | 259 | output->output = wl_registry_bind(registry, name, |
219 | &wl_output_interface, 1); | 260 | &wl_output_interface, 3); |
261 | wl_output_add_listener(output->output, &output_listener, output); | ||
262 | output->scale = 1; | ||
220 | output->index = index++; | 263 | output->index = index++; |
221 | wl_list_init(&output->workspaces); | 264 | wl_list_init(&output->workspaces); |
222 | wl_list_init(&output->hotspots); | 265 | wl_list_init(&output->hotspots); |
@@ -262,9 +305,20 @@ void bar_setup(struct swaybar *bar, | |||
262 | wl_registry_add_listener(registry, ®istry_listener, bar); | 305 | wl_registry_add_listener(registry, ®istry_listener, bar); |
263 | wl_display_roundtrip(bar->display); | 306 | wl_display_roundtrip(bar->display); |
264 | assert(bar->compositor && bar->layer_shell && bar->shm); | 307 | assert(bar->compositor && bar->layer_shell && bar->shm); |
308 | wl_display_roundtrip(bar->display); | ||
309 | |||
265 | struct swaybar_pointer *pointer = &bar->pointer; | 310 | struct swaybar_pointer *pointer = &bar->pointer; |
266 | 311 | ||
267 | assert(pointer->cursor_theme = wl_cursor_theme_load(NULL, 16, bar->shm)); | 312 | int max_scale = 1; |
313 | struct swaybar_output *output; | ||
314 | wl_list_for_each(output, &bar->outputs, link) { | ||
315 | if (output->scale > max_scale) { | ||
316 | max_scale = output->scale; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | assert(pointer->cursor_theme = wl_cursor_theme_load( | ||
321 | NULL, 16 * (max_scale * 2), bar->shm)); | ||
268 | struct wl_cursor *cursor; | 322 | struct wl_cursor *cursor; |
269 | assert(cursor = wl_cursor_theme_get_cursor( | 323 | assert(cursor = wl_cursor_theme_get_cursor( |
270 | pointer->cursor_theme, "left_ptr")); | 324 | pointer->cursor_theme, "left_ptr")); |
@@ -273,7 +327,6 @@ void bar_setup(struct swaybar *bar, | |||
273 | wl_compositor_create_surface(bar->compositor)); | 327 | wl_compositor_create_surface(bar->compositor)); |
274 | 328 | ||
275 | // TODO: we might not necessarily be meant to do all of the outputs | 329 | // TODO: we might not necessarily be meant to do all of the outputs |
276 | struct swaybar_output *output; | ||
277 | wl_list_for_each(output, &bar->outputs, link) { | 330 | wl_list_for_each(output, &bar->outputs, link) { |
278 | struct config_output *coutput; | 331 | struct config_output *coutput; |
279 | wl_list_for_each(coutput, &bar->config->outputs, link) { | 332 | wl_list_for_each(coutput, &bar->config->outputs, link) { |
diff --git a/swaybar/render.c b/swaybar/render.c index 6f3b0788..bf144d5c 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -14,55 +14,73 @@ | |||
14 | #include "swaybar/status_line.h" | 14 | #include "swaybar/status_line.h" |
15 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 15 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
16 | 16 | ||
17 | static const int ws_horizontal_padding = 5; | 17 | 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, | 21 | static uint32_t render_status_line_error(cairo_t *cairo, |
22 | struct swaybar_config *config, const char *error, | 22 | struct swaybar_output *output, struct swaybar_config *config, |
23 | double *x, uint32_t width, uint32_t height) { | 23 | const char *error, double *x, uint32_t width, uint32_t height) { |
24 | if (!error) { | 24 | if (!error) { |
25 | return 0; | 25 | return 0; |
26 | } | 26 | } |
27 | |||
28 | height *= output->scale; | ||
29 | |||
27 | cairo_set_source_u32(cairo, 0xFF0000FF); | 30 | cairo_set_source_u32(cairo, 0xFF0000FF); |
28 | static const int margin = 3; | 31 | |
32 | int margin = 3 * output->scale; | ||
33 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | ||
34 | |||
29 | int text_width, text_height; | 35 | int text_width, text_height; |
30 | get_text_size(cairo, config->font, | 36 | get_text_size(cairo, config->font, |
31 | &text_width, &text_height, 1, false, "%s", error); | 37 | &text_width, &text_height, output->scale, false, "%s", error); |
38 | |||
32 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 39 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
33 | if (height < ideal_height) { | 40 | if (height < ideal_height / output->scale) { |
34 | return ideal_height; | 41 | return ideal_height / output->scale; |
35 | } | 42 | } |
36 | *x -= text_width + margin; | 43 | *x -= text_width + margin; |
44 | |||
37 | double text_y = height / 2.0 - text_height / 2.0; | 45 | double text_y = height / 2.0 - text_height / 2.0; |
38 | cairo_move_to(cairo, *x, (int)floor(text_y)); | 46 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
39 | pango_printf(cairo, config->font, 1, false, "%s", error); | 47 | pango_printf(cairo, config->font, output->scale, false, "%s", error); |
40 | *x -= margin; | 48 | *x -= margin; |
41 | return ideal_height; | 49 | return ideal_height / output->scale; |
42 | } | 50 | } |
43 | 51 | ||
44 | static uint32_t render_status_line_text(cairo_t *cairo, | 52 | static uint32_t render_status_line_text(cairo_t *cairo, |
45 | struct swaybar_config *config, const char *text, | 53 | struct swaybar_output *output, struct swaybar_config *config, |
46 | bool focused, double *x, uint32_t width, uint32_t height) { | 54 | const char *text, bool focused, double *x, |
55 | uint32_t width, uint32_t height) { | ||
47 | if (!text) { | 56 | if (!text) { |
48 | return 0; | 57 | return 0; |
49 | } | 58 | } |
59 | |||
60 | height *= output->scale; | ||
61 | |||
50 | cairo_set_source_u32(cairo, focused ? | 62 | cairo_set_source_u32(cairo, focused ? |
51 | config->colors.focused_statusline : config->colors.statusline); | 63 | config->colors.focused_statusline : config->colors.statusline); |
52 | static const int margin = 3; | 64 | |
53 | int text_width, text_height; | 65 | int text_width, text_height; |
54 | get_text_size(cairo, config->font, &text_width, &text_height, | 66 | get_text_size(cairo, config->font, &text_width, &text_height, |
55 | 1, config->pango_markup, "%s", text); | 67 | output->scale, config->pango_markup, "%s", text); |
68 | |||
69 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | ||
70 | int margin = 3 * output->scale; | ||
71 | |||
56 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 72 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
57 | if (height < ideal_height) { | 73 | if (height < ideal_height / output->scale) { |
58 | return ideal_height; | 74 | return ideal_height / output->scale; |
59 | } | 75 | } |
76 | |||
60 | *x -= text_width + margin; | 77 | *x -= text_width + margin; |
61 | double text_y = height / 2.0 - text_height / 2.0; | 78 | double text_y = height / 2.0 - text_height / 2.0; |
62 | cairo_move_to(cairo, *x, (int)floor(text_y)); | 79 | cairo_move_to(cairo, *x, (int)floor(text_y)); |
63 | pango_printf(cairo, config->font, 1, config->pango_markup, "%s", text); | 80 | pango_printf(cairo, config->font, output->scale, |
81 | config->pango_markup, "%s", text); | ||
64 | *x -= margin; | 82 | *x -= margin; |
65 | return ideal_height; | 83 | return ideal_height / output->scale; |
66 | } | 84 | } |
67 | 85 | ||
68 | static void render_sharp_line(cairo_t *cairo, uint32_t color, | 86 | static void render_sharp_line(cairo_t *cairo, uint32_t color, |
@@ -100,22 +118,28 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
100 | struct swaybar_config *config, struct swaybar_output *output, | 118 | struct swaybar_config *config, struct swaybar_output *output, |
101 | struct i3bar_block *block, double *x, | 119 | struct i3bar_block *block, double *x, |
102 | uint32_t height, bool focused, bool edge) { | 120 | uint32_t height, bool focused, bool edge) { |
103 | static const int margin = 3; | ||
104 | if (!block->full_text || !*block->full_text) { | 121 | if (!block->full_text || !*block->full_text) { |
105 | return 0; | 122 | return 0; |
106 | } | 123 | } |
107 | 124 | ||
125 | height *= output->scale; | ||
126 | |||
108 | int text_width, text_height; | 127 | int text_width, text_height; |
109 | get_text_size(cairo, config->font, &text_width, &text_height, | 128 | get_text_size(cairo, config->font, &text_width, &text_height, |
110 | 1, block->markup, "%s", block->full_text); | 129 | output->scale, block->markup, "%s", block->full_text); |
130 | |||
131 | int margin = 3 * output->scale; | ||
132 | int ws_vertical_padding = WS_VERTICAL_PADDING * 2; | ||
133 | |||
111 | int width = text_width; | 134 | int width = text_width; |
112 | if (width < block->min_width) { | 135 | if (width < block->min_width) { |
113 | width = block->min_width; | 136 | width = block->min_width; |
114 | } | 137 | } |
138 | |||
115 | double block_width = width; | 139 | double block_width = width; |
116 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | 140 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; |
117 | if (height < ideal_height) { | 141 | if (height < ideal_height / output->scale) { |
118 | return ideal_height; | 142 | return ideal_height / output->scale; |
119 | } | 143 | } |
120 | 144 | ||
121 | *x -= width; | 145 | *x -= width; |
@@ -133,10 +157,10 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
133 | if (config->sep_symbol) { | 157 | if (config->sep_symbol) { |
134 | int _height; | 158 | int _height; |
135 | get_text_size(cairo, config->font, &sep_width, &_height, | 159 | get_text_size(cairo, config->font, &sep_width, &_height, |
136 | 1, false, "%s", config->sep_symbol); | 160 | output->scale, false, "%s", config->sep_symbol); |
137 | uint32_t _ideal_height = _height + ws_vertical_padding * 2; | 161 | uint32_t _ideal_height = _height + ws_vertical_padding * 2; |
138 | if (height < _ideal_height) { | 162 | if (height < _ideal_height / output->scale) { |
139 | return _height; | 163 | return _height / output->scale; |
140 | } | 164 | } |
141 | if (sep_width > block->separator_block_width) { | 165 | if (sep_width > block->separator_block_width) { |
142 | block->separator_block_width = sep_width + margin * 2; | 166 | block->separator_block_width = sep_width + margin * 2; |
@@ -160,22 +184,26 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
160 | double pos = *x; | 184 | double pos = *x; |
161 | if (block->background) { | 185 | if (block->background) { |
162 | cairo_set_source_u32(cairo, block->background); | 186 | cairo_set_source_u32(cairo, block->background); |
163 | cairo_rectangle(cairo, pos - 0.5, 1, block_width, height); | 187 | cairo_rectangle(cairo, pos - 0.5 * output->scale, |
188 | output->scale, block_width, height); | ||
164 | cairo_fill(cairo); | 189 | cairo_fill(cairo); |
165 | } | 190 | } |
166 | 191 | ||
167 | if (block->border && block->border_top > 0) { | 192 | if (block->border && block->border_top > 0) { |
168 | render_sharp_line(cairo, block->border, | 193 | render_sharp_line(cairo, block->border, |
169 | pos - 0.5, 1, block_width, block->border_top); | 194 | pos - 0.5 * output->scale, output->scale, |
195 | block_width, block->border_top); | ||
170 | } | 196 | } |
171 | if (block->border && block->border_bottom > 0) { | 197 | if (block->border && block->border_bottom > 0) { |
172 | render_sharp_line(cairo, block->border, | 198 | render_sharp_line(cairo, block->border, |
173 | pos - 0.5, height - 1 - block->border_bottom, | 199 | pos - 0.5 * output->scale, |
200 | height - output->scale - block->border_bottom, | ||
174 | block_width, block->border_bottom); | 201 | block_width, block->border_bottom); |
175 | } | 202 | } |
176 | if (block->border != 0 && block->border_left > 0) { | 203 | if (block->border != 0 && block->border_left > 0) { |
177 | render_sharp_line(cairo, block->border, | 204 | render_sharp_line(cairo, block->border, |
178 | pos - 0.5, 1, block->border_left, height); | 205 | pos - 0.5 * output->scale, output->scale, |
206 | block->border_left, height); | ||
179 | pos += block->border_left + margin; | 207 | pos += block->border_left + margin; |
180 | } | 208 | } |
181 | 209 | ||
@@ -190,13 +218,15 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
190 | cairo_move_to(cairo, offset, height / 2.0 - text_height / 2.0); | 218 | cairo_move_to(cairo, offset, height / 2.0 - text_height / 2.0); |
191 | uint32_t color = block->color ? *block->color : config->colors.statusline; | 219 | uint32_t color = block->color ? *block->color : config->colors.statusline; |
192 | cairo_set_source_u32(cairo, color); | 220 | cairo_set_source_u32(cairo, color); |
193 | pango_printf(cairo, config->font, 1, block->markup, "%s", block->full_text); | 221 | pango_printf(cairo, config->font, output->scale, |
222 | block->markup, "%s", block->full_text); | ||
194 | pos += width; | 223 | pos += width; |
195 | 224 | ||
196 | if (block->border && block->border_right > 0) { | 225 | if (block->border && block->border_right > 0) { |
197 | pos += margin; | 226 | pos += margin; |
198 | render_sharp_line(cairo, block->border, | 227 | render_sharp_line(cairo, block->border, |
199 | pos - 0.5, 1, block->border_right, height); | 228 | pos - 0.5 * output->scale, output->scale, |
229 | block->border_right, height); | ||
200 | pos += block->border_right; | 230 | pos += block->border_right; |
201 | } | 231 | } |
202 | 232 | ||
@@ -209,7 +239,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
209 | if (config->sep_symbol) { | 239 | if (config->sep_symbol) { |
210 | offset = pos + (block->separator_block_width - sep_width) / 2; | 240 | offset = pos + (block->separator_block_width - sep_width) / 2; |
211 | cairo_move_to(cairo, offset, margin); | 241 | cairo_move_to(cairo, offset, margin); |
212 | pango_printf(cairo, config->font, 1, false, | 242 | pango_printf(cairo, config->font, output->scale, false, |
213 | "%s", config->sep_symbol); | 243 | "%s", config->sep_symbol); |
214 | } else { | 244 | } else { |
215 | cairo_set_line_width(cairo, 1); | 245 | cairo_set_line_width(cairo, 1); |
@@ -220,7 +250,7 @@ static uint32_t render_status_block(cairo_t *cairo, | |||
220 | cairo_stroke(cairo); | 250 | cairo_stroke(cairo); |
221 | } | 251 | } |
222 | } | 252 | } |
223 | return ideal_height; | 253 | return ideal_height / output->scale; |
224 | } | 254 | } |
225 | 255 | ||
226 | static uint32_t render_status_line_i3bar(cairo_t *cairo, | 256 | static uint32_t render_status_line_i3bar(cairo_t *cairo, |
@@ -246,10 +276,10 @@ static uint32_t render_status_line(cairo_t *cairo, | |||
246 | switch (status->protocol) { | 276 | switch (status->protocol) { |
247 | case PROTOCOL_ERROR: | 277 | case PROTOCOL_ERROR: |
248 | return render_status_line_error(cairo, | 278 | return render_status_line_error(cairo, |
249 | config, status->text, x, width, height); | 279 | output, config, status->text, x, width, height); |
250 | case PROTOCOL_TEXT: | 280 | case PROTOCOL_TEXT: |
251 | return render_status_line_text(cairo, | 281 | return render_status_line_text(cairo, |
252 | config, status->text, focused, x, width, height); | 282 | output, config, status->text, focused, x, width, height); |
253 | case PROTOCOL_I3BAR: | 283 | case PROTOCOL_I3BAR: |
254 | return render_status_line_i3bar(cairo, config, output, status, | 284 | return render_status_line_i3bar(cairo, config, output, status, |
255 | focused, x, width, height); | 285 | focused, x, width, height); |
@@ -260,15 +290,23 @@ static uint32_t render_status_line(cairo_t *cairo, | |||
260 | } | 290 | } |
261 | 291 | ||
262 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | 292 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, |
263 | struct swaybar_config *config, const char *mode, double x, | 293 | struct swaybar_output *output, struct swaybar_config *config, |
264 | uint32_t height) { | 294 | const char *mode, double x, uint32_t height) { |
295 | |||
296 | height *= output->scale; | ||
297 | |||
265 | int text_width, text_height; | 298 | int text_width, text_height; |
266 | get_text_size(cairo, config->font, &text_width, &text_height, | 299 | get_text_size(cairo, config->font, &text_width, &text_height, |
267 | 1, true, "%s", mode); | 300 | output->scale, true, "%s", mode); |
301 | |||
302 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | ||
303 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; | ||
304 | int border_width = BORDER_WIDTH * output->scale; | ||
305 | |||
268 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 | 306 | uint32_t ideal_height = text_height + ws_vertical_padding * 2 |
269 | + border_width * 2; | 307 | + border_width * 2; |
270 | if (height < ideal_height) { | 308 | if (height < ideal_height / output->scale) { |
271 | return ideal_height; | 309 | return ideal_height / output->scale; |
272 | } | 310 | } |
273 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; | 311 | uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; |
274 | 312 | ||
@@ -289,8 +327,8 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, | |||
289 | double text_y = height / 2.0 - text_height / 2.0; | 327 | double text_y = height / 2.0 - text_height / 2.0; |
290 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); | 328 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); |
291 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); | 329 | cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); |
292 | pango_printf(cairo, config->font, 1, true, "%s", mode); | 330 | pango_printf(cairo, config->font, output->scale, true, "%s", mode); |
293 | return ideal_height; | 331 | return ideal_height / output->scale; |
294 | } | 332 | } |
295 | 333 | ||
296 | static const char *strip_workspace_number(const char *ws_name) { | 334 | static const char *strip_workspace_number(const char *ws_name) { |
@@ -330,14 +368,22 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
330 | box_colors = config->colors.inactive_workspace; | 368 | box_colors = config->colors.inactive_workspace; |
331 | } | 369 | } |
332 | 370 | ||
371 | height *= output->scale; | ||
372 | |||
333 | int text_width, text_height; | 373 | int text_width, text_height; |
334 | get_text_size(cairo, config->font, &text_width, &text_height, | 374 | get_text_size(cairo, config->font, &text_width, &text_height, |
335 | 1, true, "%s", name); | 375 | output->scale, true, "%s", name); |
376 | |||
377 | int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; | ||
378 | int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; | ||
379 | int border_width = BORDER_WIDTH * output->scale; | ||
380 | |||
336 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height | 381 | uint32_t ideal_height = ws_vertical_padding * 2 + text_height |
337 | + border_width * 2; | 382 | + border_width * 2; |
338 | if (height < ideal_height) { | 383 | if (height < ideal_height / output->scale) { |
339 | return ideal_height; | 384 | return ideal_height / output->scale; |
340 | } | 385 | } |
386 | |||
341 | uint32_t width = ws_horizontal_padding * 2 + text_width + border_width * 2; | 387 | uint32_t width = ws_horizontal_padding * 2 + text_width + border_width * 2; |
342 | 388 | ||
343 | cairo_set_source_u32(cairo, box_colors.background); | 389 | cairo_set_source_u32(cairo, box_colors.background); |
@@ -357,7 +403,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
357 | double text_y = height / 2.0 - text_height / 2.0; | 403 | double text_y = height / 2.0 - text_height / 2.0; |
358 | cairo_set_source_u32(cairo, box_colors.text); | 404 | cairo_set_source_u32(cairo, box_colors.text); |
359 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); | 405 | cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); |
360 | pango_printf(cairo, config->font, 1, true, "%s", name); | 406 | pango_printf(cairo, config->font, output->scale, true, "%s", name); |
361 | 407 | ||
362 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | 408 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); |
363 | hotspot->x = *x; | 409 | hotspot->x = *x; |
@@ -370,7 +416,7 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
370 | wl_list_insert(&output->hotspots, &hotspot->link); | 416 | wl_list_insert(&output->hotspots, &hotspot->link); |
371 | 417 | ||
372 | *x += width; | 418 | *x += width; |
373 | return height; | 419 | return height / output->scale; |
374 | } | 420 | } |
375 | 421 | ||
376 | static uint32_t render_to_cairo(cairo_t *cairo, | 422 | static uint32_t render_to_cairo(cairo_t *cairo, |
@@ -394,7 +440,13 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
394 | * height is too tall, the render function should adapt its drawing to | 440 | * height is too tall, the render function should adapt its drawing to |
395 | * utilize the available space. | 441 | * utilize the available space. |
396 | */ | 442 | */ |
397 | double x = 0; | 443 | double x = output->width * output->scale; |
444 | if (bar->status) { | ||
445 | uint32_t h = render_status_line(cairo, config, output, bar->status, | ||
446 | output->focused, &x, output->width, output->height); | ||
447 | max_height = h > max_height ? h : max_height; | ||
448 | } | ||
449 | x = 0; | ||
398 | if (config->workspace_buttons) { | 450 | if (config->workspace_buttons) { |
399 | struct swaybar_workspace *ws; | 451 | struct swaybar_workspace *ws; |
400 | wl_list_for_each_reverse(ws, &output->workspaces, link) { | 452 | wl_list_for_each_reverse(ws, &output->workspaces, link) { |
@@ -404,14 +456,8 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
404 | } | 456 | } |
405 | } | 457 | } |
406 | if (config->binding_mode_indicator && config->mode) { | 458 | if (config->binding_mode_indicator && config->mode) { |
407 | uint32_t h = render_binding_mode_indicator( | 459 | uint32_t h = render_binding_mode_indicator(cairo, |
408 | cairo, config, config->mode, x, output->height); | 460 | output, config, config->mode, x, output->height); |
409 | max_height = h > max_height ? h : max_height; | ||
410 | } | ||
411 | x = output->width; | ||
412 | if (bar->status) { | ||
413 | uint32_t h = render_status_line(cairo, config, output, bar->status, | ||
414 | output->focused, &x, output->width, output->height); | ||
415 | max_height = h > max_height ? h : max_height; | 461 | max_height = h > max_height ? h : max_height; |
416 | } | 462 | } |
417 | 463 | ||
@@ -451,7 +497,9 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
451 | } else { | 497 | } else { |
452 | // Replay recording into shm and send it off | 498 | // Replay recording into shm and send it off |
453 | output->current_buffer = get_next_buffer(bar->shm, | 499 | output->current_buffer = get_next_buffer(bar->shm, |
454 | output->buffers, output->width, output->height); | 500 | output->buffers, |
501 | output->width * output->scale, | ||
502 | output->height * output->scale); | ||
455 | cairo_t *shm = output->current_buffer->cairo; | 503 | cairo_t *shm = output->current_buffer->cairo; |
456 | 504 | ||
457 | cairo_save(shm); | 505 | cairo_save(shm); |
@@ -462,9 +510,11 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { | |||
462 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); | 510 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); |
463 | cairo_paint(shm); | 511 | cairo_paint(shm); |
464 | 512 | ||
513 | wl_surface_set_buffer_scale(output->surface, output->scale); | ||
465 | wl_surface_attach(output->surface, | 514 | wl_surface_attach(output->surface, |
466 | output->current_buffer->buffer, 0, 0); | 515 | output->current_buffer->buffer, 0, 0); |
467 | wl_surface_damage(output->surface, 0, 0, output->width, output->height); | 516 | wl_surface_damage(output->surface, 0, 0, |
517 | output->width, output->height); | ||
468 | wl_surface_commit(output->surface); | 518 | wl_surface_commit(output->surface); |
469 | wl_display_roundtrip(bar->display); | 519 | wl_display_roundtrip(bar->display); |
470 | } | 520 | } |