Some little fixes for bapt’s patch, use predict_text_width, support UTF8, pre-render workspace names
This commit is contained in:
parent
ddcb11baba
commit
e6198ad6c8
|
@ -165,9 +165,12 @@ struct Workspace {
|
||||||
/** Number of this workspace, starting from 0 */
|
/** Number of this workspace, starting from 0 */
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
/** Name of the workspave */
|
/** Name of the workspace (in UCS-2) */
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
/** Length of the workspace’s name (in glyphs) */
|
||||||
|
int name_len;
|
||||||
|
|
||||||
/** x, y, width, height */
|
/** x, y, width, height */
|
||||||
Rect rect;
|
Rect rect;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:expandtab
|
||||||
|
*
|
||||||
|
* i3 - an improved dynamic tiling window manager
|
||||||
|
*
|
||||||
|
* © 2009 Michael Stapelberg and contributors
|
||||||
|
*
|
||||||
|
* See file LICENSE for license information.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
|
#ifndef _WORKSPACE_H
|
||||||
|
#define _WORKSPACE_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name (or just its number) for the given workspace. This has to
|
||||||
|
* be called for every workspace as the rendering function
|
||||||
|
* (render_internal_bar) relies on workspace->name and workspace->name_len
|
||||||
|
* being ready-to-use.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void workspace_set_name(Workspace *ws, const char *name);
|
||||||
|
|
||||||
|
#endif
|
|
@ -157,7 +157,7 @@ void cached_pixmap_prepare(xcb_connection_t *conn, struct Cached_Pixmap *pixmap)
|
||||||
* real length (amount of glyphs) using the given font.
|
* real length (amount of glyphs) using the given font.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int predict_text_width(xcb_connection_t *conn, char *font_pattern, char *text,
|
int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *text,
|
||||||
int length);
|
int length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
32
src/config.c
32
src/config.c
|
@ -19,6 +19,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "xcb.h"
|
#include "xcb.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
#include "workspace.h"
|
||||||
|
|
||||||
Config config;
|
Config config;
|
||||||
|
|
||||||
|
@ -302,28 +303,29 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||||
char *ws_str = sstrdup(value);
|
char *ws_str = sstrdup(value);
|
||||||
char *end = strchr(ws_str, ' ');
|
char *end = strchr(ws_str, ' ');
|
||||||
if (end == NULL)
|
if (end == NULL)
|
||||||
die("Malformed name, couln't find terminating space\n");
|
die("Malformed name, couln't find terminating space\n");
|
||||||
*end='\0';
|
*end = '\0';
|
||||||
|
|
||||||
/* Strip trailing whitespace */
|
/* Strip trailing whitespace */
|
||||||
while (strlen(value) > 0 && value[strlen(value)-1] == ' ')
|
while (strlen(value) > 0 && value[strlen(value)-1] == ' ')
|
||||||
value[strlen(value)-1] = '\0';
|
value[strlen(value)-1] = '\0';
|
||||||
|
|
||||||
int ws_num=atoi(ws_str);
|
int ws_num = atoi(ws_str);
|
||||||
|
|
||||||
if ( ws_num < 1 || ws_num > 10 )
|
if (ws_num < 1 || ws_num > 10)
|
||||||
die("Malformed name, invalid workspace Number\n");
|
die("Malformed name, invalid workspace number\n");
|
||||||
|
|
||||||
/* find the name */
|
/* find the name */
|
||||||
char *name= value;
|
char *name = value;
|
||||||
name += strlen(ws_str) + 1;
|
name += strlen(ws_str) + 1;
|
||||||
|
|
||||||
/* if no name reinitialize the name to NULL for reload */
|
|
||||||
if (name == '\0') {
|
if (name == '\0') {
|
||||||
workspaces[ws_num - 1].name=NULL;
|
free(ws_str);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
workspaces[ws_num - 1].name=sstrdup(name);
|
|
||||||
|
workspace_set_name(&(workspaces[ws_num - 1]), name);
|
||||||
|
free(ws_str);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,5 +426,13 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||||
free(v);
|
free(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set an empty name for every workspace which got no name */
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
if (workspaces[i].name != NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
workspace_set_name(&(workspaces[i]), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
48
src/layout.c
48
src/layout.c
|
@ -434,45 +434,31 @@ static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int wid
|
||||||
|
|
||||||
struct Colortriple *color = (screen->current_workspace == c ? &(config.bar.focused) :
|
struct Colortriple *color = (screen->current_workspace == c ? &(config.bar.focused) :
|
||||||
&(config.bar.unfocused));
|
&(config.bar.unfocused));
|
||||||
|
Workspace *ws = &workspaces[c];
|
||||||
|
|
||||||
char *label=NULL;
|
|
||||||
if ( workspaces[c].name != NULL )
|
|
||||||
asprintf(&label, "%d: %s",c+1, workspaces[c].name);
|
|
||||||
else
|
|
||||||
asprintf(&label, "%d", c+1);
|
|
||||||
/* Calculate the length of a string in a given font */
|
/* Calculate the length of a string in a given font */
|
||||||
|
int text_width = predict_text_width(conn, config.font, ws->name, ws->name_len);
|
||||||
|
|
||||||
xcb_query_text_extents_cookie_t extents_cookie;
|
/* Draw the outer rect */
|
||||||
xcb_query_text_extents_reply_t *extents_reply;
|
|
||||||
xcb_char2b_t *chars;
|
|
||||||
int str_width;
|
|
||||||
int i;
|
|
||||||
chars = malloc(strlen(label) * sizeof(xcb_char2b_t));
|
|
||||||
for (i=0; i<strlen(label); i++) {
|
|
||||||
chars[i].byte1 = '\0';
|
|
||||||
chars[i].byte2 = label[i];
|
|
||||||
}
|
|
||||||
extents_cookie = xcb_query_text_extents_unchecked(conn,
|
|
||||||
font->id,
|
|
||||||
strlen(label),
|
|
||||||
chars);
|
|
||||||
extents_reply = xcb_query_text_extents_reply(conn,
|
|
||||||
extents_cookie,
|
|
||||||
NULL);
|
|
||||||
free(chars);
|
|
||||||
str_width = extents_reply->overall_width;
|
|
||||||
free(extents_reply);
|
|
||||||
xcb_draw_rect(conn, screen->bar, screen->bargc, color->border,
|
xcb_draw_rect(conn, screen->bar, screen->bargc, color->border,
|
||||||
drawn, 1, str_width + 8, height - 2);
|
drawn, /* x */
|
||||||
|
1, /* y */
|
||||||
|
text_width + 5 + 5, /* width = text width + 5 px left + 5px right */
|
||||||
|
height - 2 /* height = max. height - 1 px upper and 1 px bottom border */);
|
||||||
|
|
||||||
|
/* Draw the background of this rect */
|
||||||
xcb_draw_rect(conn, screen->bar, screen->bargc, color->background,
|
xcb_draw_rect(conn, screen->bar, screen->bargc, color->background,
|
||||||
drawn + 1, 2, str_width + 6, height - 4);
|
drawn + 1,
|
||||||
|
2,
|
||||||
|
text_width + 4 + 4,
|
||||||
|
height - 4);
|
||||||
|
|
||||||
xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, color->text);
|
xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, color->text);
|
||||||
xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, color->background);
|
xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, color->background);
|
||||||
xcb_image_text_8(conn, strlen(label), screen->bar, screen->bargc, drawn + 5 /* X */,
|
xcb_image_text_16(conn, ws->name_len, screen->bar, screen->bargc, drawn + 5 /* X */,
|
||||||
font->height + 1 /* Y = baseline of font */, label);
|
font->height + 1 /* Y = baseline of font */,
|
||||||
drawn+=str_width+8;
|
(xcb_char2b_t*)ws->name);
|
||||||
free(label);
|
drawn += text_width + 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("done rendering internal\n");
|
LOG("done rendering internal\n");
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:expandtab
|
||||||
|
*
|
||||||
|
* i3 - an improved dynamic tiling window manager
|
||||||
|
*
|
||||||
|
* © 2009 Michael Stapelberg and contributors
|
||||||
|
*
|
||||||
|
* See file LICENSE for license information.
|
||||||
|
*
|
||||||
|
* workspace.c: Functions for modifying workspaces
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <err.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the name (or just its number) for the given workspace. This has to
|
||||||
|
* be called for every workspace as the rendering function
|
||||||
|
* (render_internal_bar) relies on workspace->name and workspace->name_len
|
||||||
|
* being ready-to-use.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void workspace_set_name(Workspace *ws, const char *name) {
|
||||||
|
char *label;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
ret = asprintf(&label, "%d: %s", ws->num + 1, name);
|
||||||
|
else ret = asprintf(&label, "%d", ws->num + 1);
|
||||||
|
|
||||||
|
if (ret == -1)
|
||||||
|
errx(1, "asprintf() failed");
|
||||||
|
|
||||||
|
FREE(ws->name);
|
||||||
|
|
||||||
|
ws->name = convert_utf8_to_ucs2(label, &(ws->name_len));
|
||||||
|
|
||||||
|
free(label);
|
||||||
|
}
|
|
@ -341,10 +341,10 @@ static xcb_charinfo_t *get_charinfo(int col, int row, xcb_query_font_reply_t *fo
|
||||||
* real length (amount of glyphs) using the given font.
|
* real length (amount of glyphs) using the given font.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int predict_text_width(xcb_connection_t *conn, char *font_pattern, char *text, int length) {
|
int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *text, int length) {
|
||||||
xcb_query_font_reply_t *font_info;
|
xcb_query_font_reply_t *font_info;
|
||||||
xcb_charinfo_t *table;
|
xcb_charinfo_t *table;
|
||||||
int i, width;
|
int i, width = 0;
|
||||||
i3Font *font = load_font(conn, font_pattern);
|
i3Font *font = load_font(conn, font_pattern);
|
||||||
|
|
||||||
font_info = xcb_query_font_reply(conn, xcb_query_font_unchecked(conn, font->id), NULL);
|
font_info = xcb_query_font_reply(conn, xcb_query_font_unchecked(conn, font->id), NULL);
|
||||||
|
|
Loading…
Reference in New Issue