mirror of
https://github.com/NickHu/sway
synced 2024-12-26 21:58:30 +01:00
Add binding mode indicator
This commit is contained in:
parent
86ba0fc15d
commit
37b61eff2d
2 changed files with 55 additions and 23 deletions
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue