i3bar: Port to i3String
This commit is contained in:
parent
50d52f8f9b
commit
bbd1b16043
|
@ -11,6 +11,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
#include "libi3.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
typedef struct rect_t rect;
|
typedef struct rect_t rect;
|
||||||
|
@ -29,15 +30,10 @@ struct rect_t {
|
||||||
/* This data structure represents one JSON dictionary, multiple of these make
|
/* This data structure represents one JSON dictionary, multiple of these make
|
||||||
* up one status line. */
|
* up one status line. */
|
||||||
struct status_block {
|
struct status_block {
|
||||||
char *full_text;
|
i3String *full_text;
|
||||||
|
|
||||||
char *color;
|
char *color;
|
||||||
|
|
||||||
/* full_text, but converted to UCS-2. This variable is only temporarily
|
|
||||||
* used in refresh_statusline(). */
|
|
||||||
xcb_char2b_t *ucs2_full_text;
|
|
||||||
size_t glyph_count_full_text;
|
|
||||||
|
|
||||||
/* The amount of pixels necessary to render this block. This variable is
|
/* The amount of pixels necessary to render this block. This variable is
|
||||||
* only temporarily used in refresh_statusline(). */
|
* only temporarily used in refresh_statusline(). */
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
|
|
|
@ -32,9 +32,7 @@ void free_workspaces();
|
||||||
|
|
||||||
struct i3_ws {
|
struct i3_ws {
|
||||||
int num; /* The internal number of the ws */
|
int num; /* The internal number of the ws */
|
||||||
char *name; /* The name (in utf8) of the ws */
|
i3String *name; /* The name of the ws */
|
||||||
xcb_char2b_t *ucs2_name; /* The name (in ucs2) of the ws */
|
|
||||||
int name_glyphs; /* The length (in glyphs) of the name */
|
|
||||||
int name_width; /* The rendered width of the name */
|
int name_width; /* The rendered width of the name */
|
||||||
bool visible; /* If the ws is currently visible on an output */
|
bool visible; /* If the ws is currently visible on an output */
|
||||||
bool focused; /* If the ws is currently focused */
|
bool focused; /* If the ws is currently focused */
|
||||||
|
|
|
@ -116,7 +116,7 @@ static int stdin_string(void *context, const unsigned char *val, unsigned int le
|
||||||
#endif
|
#endif
|
||||||
parser_ctx *ctx = context;
|
parser_ctx *ctx = context;
|
||||||
if (strcasecmp(ctx->last_map_key, "full_text") == 0) {
|
if (strcasecmp(ctx->last_map_key, "full_text") == 0) {
|
||||||
sasprintf(&(ctx->block.full_text), "%.*s", len, val);
|
ctx->block.full_text = i3string_from_utf8_with_length((const char *)val, len);
|
||||||
}
|
}
|
||||||
if (strcasecmp(ctx->last_map_key, "color") == 0) {
|
if (strcasecmp(ctx->last_map_key, "color") == 0) {
|
||||||
sasprintf(&(ctx->block.color), "%.*s", len, val);
|
sasprintf(&(ctx->block.color), "%.*s", len, val);
|
||||||
|
@ -131,7 +131,7 @@ static int stdin_end_map(void *context) {
|
||||||
/* Ensure we have a full_text set, so that when it is missing (or null),
|
/* Ensure we have a full_text set, so that when it is missing (or null),
|
||||||
* i3bar doesn’t crash and the user gets an annoying message. */
|
* i3bar doesn’t crash and the user gets an annoying message. */
|
||||||
if (!new_block->full_text)
|
if (!new_block->full_text)
|
||||||
new_block->full_text = sstrdup("SPEC VIOLATION (null)");
|
new_block->full_text = i3string_from_utf8("SPEC VIOLATION (null)");
|
||||||
TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks);
|
TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ static int stdin_end_array(void *context) {
|
||||||
DLOG("dumping statusline:\n");
|
DLOG("dumping statusline:\n");
|
||||||
struct status_block *current;
|
struct status_block *current;
|
||||||
TAILQ_FOREACH(current, &statusline_head, blocks) {
|
TAILQ_FOREACH(current, &statusline_head, blocks) {
|
||||||
DLOG("full_text = %s\n", current->full_text);
|
DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
|
||||||
DLOG("color = %s\n", current->color);
|
DLOG("color = %s\n", current->color);
|
||||||
}
|
}
|
||||||
DLOG("end of dump\n");
|
DLOG("end of dump\n");
|
||||||
|
@ -221,13 +221,13 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
||||||
} else {
|
} else {
|
||||||
struct status_block *first = TAILQ_FIRST(&statusline_head);
|
struct status_block *first = TAILQ_FIRST(&statusline_head);
|
||||||
/* Clear the old buffer if any. */
|
/* Clear the old buffer if any. */
|
||||||
FREE(first->full_text);
|
I3STRING_FREE(first->full_text);
|
||||||
/* Remove the trailing newline and terminate the string at the same
|
/* Remove the trailing newline and terminate the string at the same
|
||||||
* time. */
|
* time. */
|
||||||
if (buffer[rec-1] == '\n' || buffer[rec-1] == '\r')
|
if (buffer[rec-1] == '\n' || buffer[rec-1] == '\r')
|
||||||
buffer[rec-1] = '\0';
|
buffer[rec-1] = '\0';
|
||||||
else buffer[rec] = '\0';
|
else buffer[rec] = '\0';
|
||||||
first->full_text = (char*)buffer;
|
first->full_text = i3string_from_utf8((const char *)buffer);
|
||||||
}
|
}
|
||||||
draw_bars();
|
draw_bars();
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,23 +114,17 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, unsigne
|
||||||
|
|
||||||
if (!strcmp(params->cur_key, "name")) {
|
if (!strcmp(params->cur_key, "name")) {
|
||||||
/* Save the name */
|
/* Save the name */
|
||||||
params->workspaces_walk->name = smalloc(sizeof(const unsigned char) * (len + 1));
|
params->workspaces_walk->name = i3string_from_utf8_with_length((const char *)val, len);
|
||||||
strncpy(params->workspaces_walk->name, (const char*) val, len);
|
|
||||||
params->workspaces_walk->name[len] = '\0';
|
|
||||||
|
|
||||||
/* Convert the name to ucs2, save its length in glyphs and calculate its rendered width */
|
/* Convert the name to ucs2, save its length in glyphs and calculate its rendered width */
|
||||||
size_t ucs2_len;
|
|
||||||
xcb_char2b_t *ucs2_name = (xcb_char2b_t*) convert_utf8_to_ucs2(params->workspaces_walk->name, &ucs2_len);
|
|
||||||
params->workspaces_walk->ucs2_name = ucs2_name;
|
|
||||||
params->workspaces_walk->name_glyphs = ucs2_len;
|
|
||||||
params->workspaces_walk->name_width =
|
params->workspaces_walk->name_width =
|
||||||
predict_text_width((char *)params->workspaces_walk->ucs2_name,
|
predict_text_width((char *)i3string_as_ucs2(params->workspaces_walk->name),
|
||||||
params->workspaces_walk->name_glyphs, true);
|
i3string_get_num_glyphs(params->workspaces_walk->name), true);
|
||||||
|
|
||||||
DLOG("Got Workspace %s, name_width: %d, glyphs: %d\n",
|
DLOG("Got Workspace %s, name_width: %d, glyphs: %zu\n",
|
||||||
params->workspaces_walk->name,
|
i3string_as_utf8(params->workspaces_walk->name),
|
||||||
params->workspaces_walk->name_width,
|
params->workspaces_walk->name_width,
|
||||||
params->workspaces_walk->name_glyphs);
|
i3string_get_num_glyphs(params->workspaces_walk->name));
|
||||||
FREE(params->cur_key);
|
FREE(params->cur_key);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -279,8 +273,7 @@ void free_workspaces() {
|
||||||
SLIST_FOREACH(outputs_walk, outputs, slist) {
|
SLIST_FOREACH(outputs_walk, outputs, slist) {
|
||||||
if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
|
if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
|
||||||
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
||||||
FREE(ws_walk->name);
|
I3STRING_FREE(ws_walk->name);
|
||||||
FREE(ws_walk->ucs2_name);
|
|
||||||
}
|
}
|
||||||
FREE_TAILQ(outputs_walk->workspaces, i3_ws);
|
FREE_TAILQ(outputs_walk->workspaces, i3_ws);
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,14 +114,12 @@ void refresh_statusline() {
|
||||||
uint32_t old_statusline_width = statusline_width;
|
uint32_t old_statusline_width = statusline_width;
|
||||||
statusline_width = 0;
|
statusline_width = 0;
|
||||||
|
|
||||||
/* Convert all blocks from UTF-8 to UCS-2 and predict the text width (in
|
/* Predict the text width of all blocks (in pixels). */
|
||||||
* pixels). */
|
|
||||||
TAILQ_FOREACH(block, &statusline_head, blocks) {
|
TAILQ_FOREACH(block, &statusline_head, blocks) {
|
||||||
if (strlen(block->full_text) == 0)
|
if (i3string_get_num_bytes(block->full_text) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
block->ucs2_full_text = (xcb_char2b_t*)convert_utf8_to_ucs2(block->full_text, &(block->glyph_count_full_text));
|
block->width = predict_text_width((char *)i3string_as_ucs2(block->full_text), i3string_get_num_glyphs(block->full_text), true);
|
||||||
block->width = predict_text_width((char*)block->ucs2_full_text, block->glyph_count_full_text, true);
|
|
||||||
/* If this is not the last block, add some pixels for a separator. */
|
/* If this is not the last block, add some pixels for a separator. */
|
||||||
if (TAILQ_NEXT(block, blocks) != NULL)
|
if (TAILQ_NEXT(block, blocks) != NULL)
|
||||||
block->width += 9;
|
block->width += 9;
|
||||||
|
@ -141,12 +139,12 @@ void refresh_statusline() {
|
||||||
/* Draw the text of each block. */
|
/* Draw the text of each block. */
|
||||||
uint32_t x = 0;
|
uint32_t x = 0;
|
||||||
TAILQ_FOREACH(block, &statusline_head, blocks) {
|
TAILQ_FOREACH(block, &statusline_head, blocks) {
|
||||||
if (strlen(block->full_text) == 0)
|
if (i3string_get_num_bytes(block->full_text) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
|
uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
|
||||||
set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
|
set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
|
||||||
draw_text((char*)block->ucs2_full_text, block->glyph_count_full_text,
|
draw_text((char *)i3string_as_ucs2(block->full_text), i3string_get_num_glyphs(block->full_text),
|
||||||
true, statusline_pm, statusline_ctx, x, 0, block->width);
|
true, statusline_pm, statusline_ctx, x, 0, block->width);
|
||||||
x += block->width;
|
x += block->width;
|
||||||
|
|
||||||
|
@ -157,8 +155,6 @@ void refresh_statusline() {
|
||||||
statusline_ctx, 2,
|
statusline_ctx, 2,
|
||||||
(xcb_point_t[]){ { x - 5, 2 }, { x - 5, font.height - 2 } });
|
(xcb_point_t[]){ { x - 5, 2 }, { x - 5, font.height - 2 } });
|
||||||
}
|
}
|
||||||
|
|
||||||
FREE(block->ucs2_full_text);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +322,8 @@ void handle_button(xcb_button_press_event_t *event) {
|
||||||
* buffer, then we copy character by character. */
|
* buffer, then we copy character by character. */
|
||||||
int num_quotes = 0;
|
int num_quotes = 0;
|
||||||
size_t namelen = 0;
|
size_t namelen = 0;
|
||||||
for (char *walk = cur_ws->name; *walk != '\0'; walk++) {
|
const char *utf8_name = i3string_as_utf8(cur_ws->name);
|
||||||
|
for (const char *walk = utf8_name; *walk != '\0'; walk++) {
|
||||||
if (*walk == '"')
|
if (*walk == '"')
|
||||||
num_quotes++;
|
num_quotes++;
|
||||||
/* While we’re looping through the name anyway, we can save one
|
/* While we’re looping through the name anyway, we can save one
|
||||||
|
@ -341,11 +338,11 @@ void handle_button(xcb_button_press_event_t *event) {
|
||||||
for (inpos = 0, outpos = strlen("workspace \"");
|
for (inpos = 0, outpos = strlen("workspace \"");
|
||||||
inpos < namelen;
|
inpos < namelen;
|
||||||
inpos++, outpos++) {
|
inpos++, outpos++) {
|
||||||
if (cur_ws->name[inpos] == '"') {
|
if (utf8_name[inpos] == '"') {
|
||||||
buffer[outpos] = '\\';
|
buffer[outpos] = '\\';
|
||||||
outpos++;
|
outpos++;
|
||||||
}
|
}
|
||||||
buffer[outpos] = cur_ws->name[inpos];
|
buffer[outpos] = utf8_name[inpos];
|
||||||
}
|
}
|
||||||
buffer[outpos] = '"';
|
buffer[outpos] = '"';
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, buffer);
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, buffer);
|
||||||
|
@ -1468,7 +1465,7 @@ void draw_bars() {
|
||||||
bool has_urgent = false, walks_away = true;
|
bool has_urgent = false, walks_away = true;
|
||||||
|
|
||||||
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
||||||
DLOG("Drawing Button for WS %s at x = %d, len = %d\n", ws_walk->name, i, ws_walk->name_width);
|
DLOG("Drawing Button for WS %s at x = %d, len = %d\n", i3string_as_utf8(ws_walk->name), i, ws_walk->name_width);
|
||||||
uint32_t fg_color = colors.inactive_ws_fg;
|
uint32_t fg_color = colors.inactive_ws_fg;
|
||||||
uint32_t bg_color = colors.inactive_ws_bg;
|
uint32_t bg_color = colors.inactive_ws_bg;
|
||||||
uint32_t border_color = colors.inactive_ws_border;
|
uint32_t border_color = colors.inactive_ws_border;
|
||||||
|
@ -1481,19 +1478,19 @@ void draw_bars() {
|
||||||
fg_color = colors.focus_ws_fg;
|
fg_color = colors.focus_ws_fg;
|
||||||
bg_color = colors.focus_ws_bg;
|
bg_color = colors.focus_ws_bg;
|
||||||
border_color = colors.focus_ws_border;
|
border_color = colors.focus_ws_border;
|
||||||
if (last_urgent_ws && strcmp(ws_walk->name, last_urgent_ws) == 0)
|
if (last_urgent_ws && strcmp(i3string_as_utf8(ws_walk->name), last_urgent_ws) == 0)
|
||||||
walks_away = false;
|
walks_away = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ws_walk->urgent) {
|
if (ws_walk->urgent) {
|
||||||
DLOG("WS %s is urgent!\n", ws_walk->name);
|
DLOG("WS %s is urgent!\n", i3string_as_utf8(ws_walk->name));
|
||||||
fg_color = colors.urgent_ws_fg;
|
fg_color = colors.urgent_ws_fg;
|
||||||
bg_color = colors.urgent_ws_bg;
|
bg_color = colors.urgent_ws_bg;
|
||||||
border_color = colors.urgent_ws_border;
|
border_color = colors.urgent_ws_border;
|
||||||
has_urgent = true;
|
has_urgent = true;
|
||||||
if (!ws_walk->focused) {
|
if (!ws_walk->focused) {
|
||||||
FREE(last_urgent_ws);
|
FREE(last_urgent_ws);
|
||||||
last_urgent_ws = sstrdup(ws_walk->name);
|
last_urgent_ws = sstrdup(i3string_as_utf8(ws_walk->name));
|
||||||
}
|
}
|
||||||
/* The urgent-hint should get noticed, so we unhide the bars shortly */
|
/* The urgent-hint should get noticed, so we unhide the bars shortly */
|
||||||
unhide_bars();
|
unhide_bars();
|
||||||
|
@ -1522,7 +1519,7 @@ void draw_bars() {
|
||||||
1,
|
1,
|
||||||
&rect);
|
&rect);
|
||||||
set_font_colors(outputs_walk->bargc, fg_color, bg_color);
|
set_font_colors(outputs_walk->bargc, fg_color, bg_color);
|
||||||
draw_text((char*)ws_walk->ucs2_name, ws_walk->name_glyphs, true,
|
draw_text((char*)i3string_as_ucs2(ws_walk->name), i3string_get_num_glyphs(ws_walk->name), true,
|
||||||
outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width);
|
outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width);
|
||||||
i += 10 + ws_walk->name_width + 1;
|
i += 10 + ws_walk->name_width + 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue