diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-03-29 10:59:33 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-03-29 22:11:08 -0400 |
commit | 37b61eff2df3c8b47b1304650d1fb204a62658db (patch) | |
tree | 784910c008067185ce3f41a139fc95242e6e7458 /swaybar/render.c | |
parent | Re-render bar on IPC updates (diff) | |
download | sway-37b61eff2df3c8b47b1304650d1fb204a62658db.tar.gz sway-37b61eff2df3c8b47b1304650d1fb204a62658db.tar.zst sway-37b61eff2df3c8b47b1304650d1fb204a62658db.zip |
Add binding mode indicator
Diffstat (limited to 'swaybar/render.c')
-rw-r--r-- | swaybar/render.c | 77 |
1 files changed, 54 insertions, 23 deletions
diff --git a/swaybar/render.c b/swaybar/render.c index 226e4ce3..beb4de40 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -1,3 +1,4 @@ | |||
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> |
@@ -10,6 +11,38 @@ | |||
10 | #include "swaybar/render.h" | 11 | #include "swaybar/render.h" |
11 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 12 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
12 | 13 | ||
14 | static const int ws_horizontal_padding = 5; | ||
15 | static const double ws_vertical_padding = 1.5; | ||
16 | static const int ws_spacing = 1; | ||
17 | |||
18 | static uint32_t render_binding_mode_indicator(cairo_t *cairo, | ||
19 | struct swaybar_config *config, const char *mode, double x, | ||
20 | uint32_t height) { | ||
21 | int text_width, text_height; | ||
22 | get_text_size(cairo, config->font, &text_width, &text_height, | ||
23 | 1, true, "⚡ %s", mode); | ||
24 | uint32_t ideal_height = text_height + ws_vertical_padding * 2; | ||
25 | if (height < ideal_height) { | ||
26 | height = ideal_height; | ||
27 | } | ||
28 | |||
29 | cairo_set_source_u32(cairo, config->colors.binding_mode.background); | ||
30 | cairo_rectangle(cairo, x, 0, text_width + ws_horizontal_padding * 2 - 1, | ||
31 | height + ws_vertical_padding * 2); | ||
32 | cairo_fill(cairo); | ||
33 | |||
34 | cairo_set_source_u32(cairo, config->colors.binding_mode.border); | ||
35 | cairo_rectangle(cairo, x, 0, text_width + ws_horizontal_padding * 2 - 1, | ||
36 | height + ws_vertical_padding * 2); | ||
37 | cairo_stroke(cairo); | ||
38 | |||
39 | double text_y = height / 2.0 - text_height / 2.0; | ||
40 | cairo_set_source_u32(cairo, config->colors.binding_mode.text); | ||
41 | cairo_move_to(cairo, (int)x + ws_horizontal_padding, (int)floor(text_y)); | ||
42 | pango_printf(cairo, config->font, 1, true, "⚡ %s", mode); | ||
43 | return ideal_height; | ||
44 | } | ||
45 | |||
13 | static const char *strip_workspace_number(const char *ws_name) { | 46 | static const char *strip_workspace_number(const char *ws_name) { |
14 | size_t len = strlen(ws_name); | 47 | size_t len = strlen(ws_name); |
15 | for (size_t i = 0; i < len; ++i) { | 48 | for (size_t i = 0; i < len; ++i) { |
@@ -26,10 +59,6 @@ static const char *strip_workspace_number(const char *ws_name) { | |||
26 | static uint32_t render_workspace_button(cairo_t *cairo, | 59 | static uint32_t render_workspace_button(cairo_t *cairo, |
27 | struct swaybar_config *config, struct swaybar_workspace *ws, | 60 | struct swaybar_config *config, struct swaybar_workspace *ws, |
28 | double *x, uint32_t height) { | 61 | double *x, uint32_t height) { |
29 | static const int ws_horizontal_padding = 5; | ||
30 | static const double ws_vertical_padding = 1.5; | ||
31 | static const int ws_spacing = 1; | ||
32 | |||
33 | const char *name = ws->name; | 62 | const char *name = ws->name; |
34 | if (config->strip_workspace_numbers) { | 63 | if (config->strip_workspace_numbers) { |
35 | name = strip_workspace_number(ws->name); | 64 | name = strip_workspace_number(ws->name); |
@@ -72,24 +101,10 @@ static uint32_t render_workspace_button(cairo_t *cairo, | |||
72 | return ideal_height; | 101 | return ideal_height; |
73 | } | 102 | } |
74 | 103 | ||
75 | static void update_heights(uint32_t height, uint32_t *min, uint32_t *max) { | ||
76 | if (*min < height) { | ||
77 | *min = height; | ||
78 | } | ||
79 | if (height > *max) { | ||
80 | *max = height; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static uint32_t render_to_cairo(cairo_t *cairo, | 104 | static uint32_t render_to_cairo(cairo_t *cairo, |
85 | struct swaybar *bar, struct swaybar_output *output) { | 105 | struct swaybar *bar, struct swaybar_output *output) { |
86 | struct swaybar_config *config = bar->config; | 106 | struct swaybar_config *config = bar->config; |
87 | 107 | ||
88 | cairo_save(cairo); | ||
89 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); | ||
90 | cairo_paint(cairo); | ||
91 | cairo_restore(cairo); | ||
92 | |||
93 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); | 108 | cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); |
94 | if (output->focused) { | 109 | if (output->focused) { |
95 | cairo_set_source_u32(cairo, config->colors.focused_background); | 110 | cairo_set_source_u32(cairo, config->colors.focused_background); |
@@ -98,20 +113,30 @@ static uint32_t render_to_cairo(cairo_t *cairo, | |||
98 | } | 113 | } |
99 | cairo_paint(cairo); | 114 | cairo_paint(cairo); |
100 | 115 | ||
101 | uint32_t min_height = output->height, max_height = output->height; | 116 | uint32_t max_height = 0; |
102 | 117 | /* | |
118 | * Each render_* function takes the actual height of the bar, and returns | ||
119 | * the ideal height. If the actual height is too short, the render function | ||
120 | * can do whatever it wants - the buffer won't be committed. If the actual | ||
121 | * height is too tall, the render function should adapt its drawing to | ||
122 | * utilize the available space. | ||
123 | */ | ||
103 | double x = 0; | 124 | double x = 0; |
104 | if (config->workspace_buttons) { | 125 | if (config->workspace_buttons) { |
105 | struct swaybar_workspace *ws; | 126 | struct swaybar_workspace *ws; |
106 | wl_list_for_each(ws, &output->workspaces, link) { | 127 | wl_list_for_each(ws, &output->workspaces, link) { |
107 | uint32_t h = render_workspace_button( | 128 | uint32_t h = render_workspace_button( |
108 | cairo, config, ws, &x, output->height); | 129 | cairo, config, ws, &x, output->height); |
109 | update_heights(h, &min_height, &max_height); | 130 | max_height = h > max_height ? h : max_height; |
110 | } | 131 | } |
111 | } | 132 | } |
133 | if (config->binding_mode_indicator && config->mode) { | ||
134 | uint32_t h = render_binding_mode_indicator( | ||
135 | cairo, config, config->mode, x, output->height); | ||
136 | max_height = h > max_height ? h : max_height; | ||
137 | } | ||
112 | 138 | ||
113 | // TODO: Shrink via min_height if sane | 139 | return max_height > output->height ? max_height : output->height; |
114 | return max_height; | ||
115 | } | 140 | } |
116 | 141 | ||
117 | void render_frame(struct swaybar *bar, | 142 | void render_frame(struct swaybar *bar, |
@@ -134,6 +159,12 @@ void render_frame(struct swaybar *bar, | |||
134 | output->current_buffer = get_next_buffer(bar->shm, | 159 | output->current_buffer = get_next_buffer(bar->shm, |
135 | output->buffers, output->width, output->height); | 160 | output->buffers, output->width, output->height); |
136 | cairo_t *shm = output->current_buffer->cairo; | 161 | cairo_t *shm = output->current_buffer->cairo; |
162 | |||
163 | cairo_save(shm); | ||
164 | cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR); | ||
165 | cairo_paint(shm); | ||
166 | cairo_restore(shm); | ||
167 | |||
137 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); | 168 | cairo_set_source_surface(shm, recorder, 0.0, 0.0); |
138 | cairo_paint(shm); | 169 | cairo_paint(shm); |
139 | wl_surface_attach(output->surface, | 170 | wl_surface_attach(output->surface, |