i3bar: implement custom workspace numbers config

Implement the configuration option within the bar config directive for
custom workspace numbers with the directive `strip_workspace_numbers
yes`.

This directive strips the workspace name of the number prefix and
delimiter. When the workspace name consists only of the number, it will
default to show the number.

For example:

* "2:5" -> "5"
* "4:$" -> "$"
* "8" -> "8"

This allows customization of i3bar for alternate ordering of workspaces
which has a legitimate use for alternate keyboard layouts such as
Dvorak.

fixes #1131
This commit is contained in:
Tony Crisci
2014-05-05 13:56:47 -04:00
committed by Michael Stapelberg
parent e2f47ef466
commit e707e0a5fa
12 changed files with 81 additions and 6 deletions

View File

@ -27,6 +27,7 @@ typedef struct config_t {
struct xcb_color_strings_t colors;
bool disable_binding_mode_indicator;
bool disable_ws;
bool strip_ws_numbers;
char *bar_id;
char *command;
char *fontname;

View File

@ -31,7 +31,8 @@ void free_workspaces(void);
struct i3_ws {
int num; /* The internal number of the ws */
i3String *name; /* The name of the ws */
char *canonical_name; /* The true name of the ws according to the ipc */
i3String *name; /* The name of the ws that is displayed on the bar */
int name_width; /* The rendered width of the name */
bool visible; /* If the ws is currently visible on an output */
bool focused; /* If the ws is currently focused */

View File

@ -193,6 +193,12 @@ static int config_boolean_cb(void *params_, int val) {
return 1;
}
if (!strcmp(cur_key, "strip_workspace_numbers")) {
DLOG("strip_workspace_numbers = %d\n", val);
config.strip_ws_numbers = val;
return 1;
}
if (!strcmp(cur_key, "verbose")) {
DLOG("verbose = %d\n", val);
config.verbose = val;

View File

@ -105,14 +105,38 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
char *output_name;
if (!strcmp(params->cur_key, "name")) {
/* Save the name */
params->workspaces_walk->name = i3string_from_utf8_with_length((const char *)val, len);
const char *ws_name = (const char*)val;
params->workspaces_walk->canonical_name = strndup(ws_name, len);
if (config.strip_ws_numbers && params->workspaces_walk->num >= 0) {
/* Special case: strip off the workspace number */
static char ws_num[10];
snprintf(ws_num, sizeof(ws_num), "%d", params->workspaces_walk->num);
/* Calculate the length of the number str in the name */
int offset = strspn(ws_name, ws_num);
/* Also strip off the conventional ws name delimiter */
if (offset && ws_name[offset] == ':')
offset += 1;
/* Offset may be equal to length, in which case display the number */
params->workspaces_walk->name = (offset < len
? i3string_from_utf8_with_length(ws_name + offset, len - offset)
: i3string_from_utf8(ws_num));
} else {
/* Default case: just save the name */
params->workspaces_walk->name = i3string_from_utf8_with_length(ws_name, len);
}
/* Save its rendered width */
params->workspaces_walk->name_width =
predict_text_width(params->workspaces_walk->name);
DLOG("Got Workspace %s, name_width: %d, glyphs: %zu\n",
DLOG("Got Workspace canonical: %s, name: '%s', name_width: %d, glyphs: %zu\n",
params->workspaces_walk->canonical_name,
i3string_as_utf8(params->workspaces_walk->name),
params->workspaces_walk->name_width,
i3string_get_num_glyphs(params->workspaces_walk->name));
@ -246,6 +270,7 @@ void free_workspaces(void) {
if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
I3STRING_FREE(ws_walk->name);
FREE(ws_walk->canonical_name);
}
FREE_TAILQ(outputs_walk->workspaces, i3_ws);
}

View File

@ -418,7 +418,7 @@ void handle_button(xcb_button_press_event_t *event) {
* buffer, then we copy character by character. */
int num_quotes = 0;
size_t namelen = 0;
const char *utf8_name = i3string_as_utf8(cur_ws->name);
const char *utf8_name = cur_ws->canonical_name;
for (const char *walk = utf8_name; *walk != '\0'; walk++) {
if (*walk == '"')
num_quotes++;