aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--swaybar/ipc.c1
-rw-r--r--swaybar/render.c77
2 files changed, 55 insertions, 23 deletions
diff --git a/swaybar/ipc.c b/swaybar/ipc.c
index 75f17953..3c2d6fbc 100644
--- a/swaybar/ipc.c
+++ b/swaybar/ipc.c
@@ -306,6 +306,7 @@ bool handle_ipc_event(struct swaybar *bar) {
ipc_get_workspaces(bar);
break;
case IPC_EVENT_MODE: {
+ // TODO: interpret "pango_markup" field
json_object *result = json_tokener_parse(resp->payload);
if (!result) {
free_ipc_response(resp);
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 @@
+#include <limits.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -10,6 +11,38 @@
#include "swaybar/render.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
+static const int ws_horizontal_padding = 5;
+static const double ws_vertical_padding = 1.5;
+static const int ws_spacing = 1;
+
+static uint32_t render_binding_mode_indicator(cairo_t *cairo,
+ struct swaybar_config *config, const char *mode, double x,
+ uint32_t height) {
+ int text_width, text_height;
+ get_text_size(cairo, config->font, &text_width, &text_height,
+ 1, true, "⚡ %s", mode);
+ uint32_t ideal_height = text_height + ws_vertical_padding * 2;
+ if (height < ideal_height) {
+ height = ideal_height;
+ }
+
+ cairo_set_source_u32(cairo, config->colors.binding_mode.background);
+ cairo_rectangle(cairo, x, 0, text_width + ws_horizontal_padding * 2 - 1,
+ height + ws_vertical_padding * 2);
+ cairo_fill(cairo);
+
+ cairo_set_source_u32(cairo, config->colors.binding_mode.border);
+ cairo_rectangle(cairo, x, 0, text_width + ws_horizontal_padding * 2 - 1,
+ height + ws_vertical_padding * 2);
+ cairo_stroke(cairo);
+
+ double text_y = height / 2.0 - text_height / 2.0;
+ cairo_set_source_u32(cairo, config->colors.binding_mode.text);
+ cairo_move_to(cairo, (int)x + ws_horizontal_padding, (int)floor(text_y));
+ pango_printf(cairo, config->font, 1, true, "⚡ %s", mode);
+ return ideal_height;
+}
+
static const char *strip_workspace_number(const char *ws_name) {
size_t len = strlen(ws_name);
for (size_t i = 0; i < len; ++i) {
@@ -26,10 +59,6 @@ static const char *strip_workspace_number(const char *ws_name) {
static uint32_t render_workspace_button(cairo_t *cairo,
struct swaybar_config *config, struct swaybar_workspace *ws,
double *x, uint32_t height) {
- static const int ws_horizontal_padding = 5;
- static const double ws_vertical_padding = 1.5;
- static const int ws_spacing = 1;
-
const char *name = ws->name;
if (config->strip_workspace_numbers) {
name = strip_workspace_number(ws->name);
@@ -72,24 +101,10 @@ static uint32_t render_workspace_button(cairo_t *cairo,
return ideal_height;
}
-static void update_heights(uint32_t height, uint32_t *min, uint32_t *max) {
- if (*min < height) {
- *min = height;
- }
- if (height > *max) {
- *max = height;
- }
-}
-
static uint32_t render_to_cairo(cairo_t *cairo,
struct swaybar *bar, struct swaybar_output *output) {
struct swaybar_config *config = bar->config;
- cairo_save(cairo);
- cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
- cairo_paint(cairo);
- cairo_restore(cairo);
-
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
if (output->focused) {
cairo_set_source_u32(cairo, config->colors.focused_background);
@@ -98,20 +113,30 @@ static uint32_t render_to_cairo(cairo_t *cairo,
}
cairo_paint(cairo);
- uint32_t min_height = output->height, max_height = output->height;
-
+ uint32_t max_height = 0;
+ /*
+ * Each render_* function takes the actual height of the bar, and returns
+ * the ideal height. If the actual height is too short, the render function
+ * can do whatever it wants - the buffer won't be committed. If the actual
+ * height is too tall, the render function should adapt its drawing to
+ * utilize the available space.
+ */
double x = 0;
if (config->workspace_buttons) {
struct swaybar_workspace *ws;
wl_list_for_each(ws, &output->workspaces, link) {
uint32_t h = render_workspace_button(
cairo, config, ws, &x, output->height);
- update_heights(h, &min_height, &max_height);
+ max_height = h > max_height ? h : max_height;
}
}
+ if (config->binding_mode_indicator && config->mode) {
+ uint32_t h = render_binding_mode_indicator(
+ cairo, config, config->mode, x, output->height);
+ max_height = h > max_height ? h : max_height;
+ }
- // TODO: Shrink via min_height if sane
- return max_height;
+ return max_height > output->height ? max_height : output->height;
}
void render_frame(struct swaybar *bar,
@@ -134,6 +159,12 @@ void render_frame(struct swaybar *bar,
output->current_buffer = get_next_buffer(bar->shm,
output->buffers, output->width, output->height);
cairo_t *shm = output->current_buffer->cairo;
+
+ cairo_save(shm);
+ cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR);
+ cairo_paint(shm);
+ cairo_restore(shm);
+
cairo_set_source_surface(shm, recorder, 0.0, 0.0);
cairo_paint(shm);
wl_surface_attach(output->surface,