Add binding mode indicator

This commit is contained in:
Drew DeVault 2018-03-29 10:59:33 -04:00
parent 86ba0fc15d
commit 37b61eff2d
2 changed files with 55 additions and 23 deletions

View file

@ -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);

View file

@ -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,