Add binding mode indicator
This commit is contained in:
parent
86ba0fc15d
commit
37b61eff2d
|
@ -306,6 +306,7 @@ bool handle_ipc_event(struct swaybar *bar) {
|
||||||
ipc_get_workspaces(bar);
|
ipc_get_workspaces(bar);
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_MODE: {
|
case IPC_EVENT_MODE: {
|
||||||
|
// TODO: interpret "pango_markup" field
|
||||||
json_object *result = json_tokener_parse(resp->payload);
|
json_object *result = json_tokener_parse(resp->payload);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
free_ipc_response(resp);
|
free_ipc_response(resp);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -10,6 +11,38 @@
|
||||||
#include "swaybar/render.h"
|
#include "swaybar/render.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.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) {
|
static const char *strip_workspace_number(const char *ws_name) {
|
||||||
size_t len = strlen(ws_name);
|
size_t len = strlen(ws_name);
|
||||||
for (size_t i = 0; i < len; ++i) {
|
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,
|
static uint32_t render_workspace_button(cairo_t *cairo,
|
||||||
struct swaybar_config *config, struct swaybar_workspace *ws,
|
struct swaybar_config *config, struct swaybar_workspace *ws,
|
||||||
double *x, uint32_t height) {
|
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;
|
const char *name = ws->name;
|
||||||
if (config->strip_workspace_numbers) {
|
if (config->strip_workspace_numbers) {
|
||||||
name = strip_workspace_number(ws->name);
|
name = strip_workspace_number(ws->name);
|
||||||
|
@ -72,24 +101,10 @@ static uint32_t render_workspace_button(cairo_t *cairo,
|
||||||
return ideal_height;
|
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,
|
static uint32_t render_to_cairo(cairo_t *cairo,
|
||||||
struct swaybar *bar, struct swaybar_output *output) {
|
struct swaybar *bar, struct swaybar_output *output) {
|
||||||
struct swaybar_config *config = bar->config;
|
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);
|
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||||
if (output->focused) {
|
if (output->focused) {
|
||||||
cairo_set_source_u32(cairo, config->colors.focused_background);
|
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);
|
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;
|
double x = 0;
|
||||||
if (config->workspace_buttons) {
|
if (config->workspace_buttons) {
|
||||||
struct swaybar_workspace *ws;
|
struct swaybar_workspace *ws;
|
||||||
wl_list_for_each(ws, &output->workspaces, link) {
|
wl_list_for_each(ws, &output->workspaces, link) {
|
||||||
uint32_t h = render_workspace_button(
|
uint32_t h = render_workspace_button(
|
||||||
cairo, config, ws, &x, output->height);
|
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 > output->height ? max_height : output->height;
|
||||||
return max_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_frame(struct swaybar *bar,
|
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->current_buffer = get_next_buffer(bar->shm,
|
||||||
output->buffers, output->width, output->height);
|
output->buffers, output->width, output->height);
|
||||||
cairo_t *shm = output->current_buffer->cairo;
|
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_set_source_surface(shm, recorder, 0.0, 0.0);
|
||||||
cairo_paint(shm);
|
cairo_paint(shm);
|
||||||
wl_surface_attach(output->surface,
|
wl_surface_attach(output->surface,
|
||||||
|
|
Loading…
Reference in a new issue