i3/window: Port window names to i3String
This commit is contained in:
parent
bc5f33878a
commit
b6c705a1a4
|
@ -19,6 +19,7 @@
|
||||||
#include <pcre.h>
|
#include <pcre.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "libi3.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -287,9 +288,8 @@ struct Window {
|
||||||
char *class_class;
|
char *class_class;
|
||||||
char *class_instance;
|
char *class_instance;
|
||||||
|
|
||||||
/** The name of the window as it will be passed to X11 (in UCS2 if the
|
/** The name of the window. */
|
||||||
* application supports _NET_WM_NAME, in COMPOUND_TEXT otherwise). */
|
i3String *name;
|
||||||
char *name_x;
|
|
||||||
|
|
||||||
/** The WM_WINDOW_ROLE of this window (for example, the pidgin buddy window
|
/** The WM_WINDOW_ROLE of this window (for example, the pidgin buddy window
|
||||||
* sets "buddy list"). Useful to match specific windows in assignments or
|
* sets "buddy list"). Useful to match specific windows in assignments or
|
||||||
|
@ -299,13 +299,6 @@ struct Window {
|
||||||
/** Flag to force re-rendering the decoration upon changes */
|
/** Flag to force re-rendering the decoration upon changes */
|
||||||
bool name_x_changed;
|
bool name_x_changed;
|
||||||
|
|
||||||
/** The name of the window as used in JSON (in UTF-8 if the application
|
|
||||||
* supports _NET_WM_NAME, in COMPOUND_TEXT otherwise) */
|
|
||||||
char *name_json;
|
|
||||||
|
|
||||||
/** The length of the name in glyphs (not bytes) */
|
|
||||||
size_t name_len;
|
|
||||||
|
|
||||||
/** Whether the application used _NET_WM_NAME */
|
/** Whether the application used _NET_WM_NAME */
|
||||||
bool uses_net_wm_name;
|
bool uses_net_wm_name;
|
||||||
|
|
||||||
|
|
|
@ -259,8 +259,8 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
|
||||||
dump_rect(gen, "geometry", con->geometry);
|
dump_rect(gen, "geometry", con->geometry);
|
||||||
|
|
||||||
ystr("name");
|
ystr("name");
|
||||||
if (con->window && con->window->name_json)
|
if (con->window && con->window->name)
|
||||||
ystr(con->window->name_json);
|
ystr(i3string_as_utf8(con->window->name));
|
||||||
else
|
else
|
||||||
ystr(con->name);
|
ystr(con->name);
|
||||||
|
|
||||||
|
|
|
@ -113,9 +113,9 @@ bool match_matches_window(Match *match, i3Window *window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match->title != NULL) {
|
if (match->title != NULL) {
|
||||||
if (window->name_json != NULL &&
|
if (window->name != NULL &&
|
||||||
regex_matches(match->title, window->name_json)) {
|
regex_matches(match->title, i3string_as_utf8(window->name))) {
|
||||||
LOG("title matches (%s)\n", window->name_json);
|
LOG("title matches (%s)\n", i3string_as_utf8(window->name));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,8 +247,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
|
||||||
}
|
}
|
||||||
FREE(con->window->class_class);
|
FREE(con->window->class_class);
|
||||||
FREE(con->window->class_instance);
|
FREE(con->window->class_instance);
|
||||||
FREE(con->window->name_x);
|
i3string_free(con->window->name);
|
||||||
FREE(con->window->name_json);
|
|
||||||
free(con->window);
|
free(con->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
src/window.c
46
src/window.c
|
@ -60,31 +60,11 @@ void window_update_name(i3Window *win, xcb_get_property_reply_t *prop, bool befo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the old pointer to make the update atomic */
|
i3string_free(win->name);
|
||||||
char *new_name;
|
win->name = i3string_from_utf8_with_length(xcb_get_property_value(prop),
|
||||||
if (asprintf(&new_name, "%.*s", xcb_get_property_value_length(prop),
|
xcb_get_property_value_length(prop));
|
||||||
(char*)xcb_get_property_value(prop)) == -1) {
|
|
||||||
perror("asprintf()");
|
|
||||||
DLOG("Could not get window name\n");
|
|
||||||
free(prop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */
|
|
||||||
size_t len;
|
|
||||||
xcb_char2b_t *ucs2_name = convert_utf8_to_ucs2(new_name, &len);
|
|
||||||
if (ucs2_name == NULL) {
|
|
||||||
LOG("Could not convert _NET_WM_NAME to UCS-2, ignoring new hint\n");
|
|
||||||
FREE(new_name);
|
|
||||||
free(prop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FREE(win->name_x);
|
|
||||||
FREE(win->name_json);
|
|
||||||
win->name_json = new_name;
|
|
||||||
win->name_x = (char*)ucs2_name;
|
|
||||||
win->name_len = len;
|
|
||||||
win->name_x_changed = true;
|
win->name_x_changed = true;
|
||||||
LOG("_NET_WM_NAME changed to \"%s\"\n", win->name_json);
|
LOG("_NET_WM_NAME changed to \"%s\"\n", i3string_as_utf8(win->name));
|
||||||
|
|
||||||
win->uses_net_wm_name = true;
|
win->uses_net_wm_name = true;
|
||||||
|
|
||||||
|
@ -118,24 +98,14 @@ void window_update_name_legacy(i3Window *win, xcb_get_property_reply_t *prop, bo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *new_name;
|
i3string_free(win->name);
|
||||||
if (asprintf(&new_name, "%.*s", xcb_get_property_value_length(prop),
|
win->name = i3string_from_utf8_with_length(xcb_get_property_value(prop),
|
||||||
(char*)xcb_get_property_value(prop)) == -1) {
|
xcb_get_property_value_length(prop));
|
||||||
perror("asprintf()");
|
|
||||||
DLOG("Could not get legacy window name\n");
|
|
||||||
free(prop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG("WM_NAME changed to \"%s\"\n", new_name);
|
LOG("WM_NAME changed to \"%s\"\n", i3string_as_utf8(win->name));
|
||||||
LOG("Using legacy window title. Note that in order to get Unicode window "
|
LOG("Using legacy window title. Note that in order to get Unicode window "
|
||||||
"titles in i3, the application has to set _NET_WM_NAME (UTF-8)\n");
|
"titles in i3, the application has to set _NET_WM_NAME (UTF-8)\n");
|
||||||
|
|
||||||
FREE(win->name_x);
|
|
||||||
FREE(win->name_json);
|
|
||||||
win->name_x = new_name;
|
|
||||||
win->name_json = sstrdup(new_name);
|
|
||||||
win->name_len = strlen(new_name);
|
|
||||||
win->name_x_changed = true;
|
win->name_x_changed = true;
|
||||||
|
|
||||||
if (before_mgmt) {
|
if (before_mgmt) {
|
||||||
|
|
4
src/x.c
4
src/x.c
|
@ -481,7 +481,7 @@ void x_draw_decoration(Con *con) {
|
||||||
int text_offset_y = (con->deco_rect.height - config.font.height) / 2;
|
int text_offset_y = (con->deco_rect.height - config.font.height) / 2;
|
||||||
|
|
||||||
struct Window *win = con->window;
|
struct Window *win = con->window;
|
||||||
if (win == NULL || win->name_x == NULL) {
|
if (win == NULL || win->name == NULL) {
|
||||||
/* this is a non-leaf container, we need to make up a good description */
|
/* this is a non-leaf container, we need to make up a good description */
|
||||||
// TODO: use a good description instead of just "another container"
|
// TODO: use a good description instead of just "another container"
|
||||||
draw_text("another container", strlen("another container"), false,
|
draw_text("another container", strlen("another container"), false,
|
||||||
|
@ -508,7 +508,7 @@ void x_draw_decoration(Con *con) {
|
||||||
//DLOG("indent_level = %d, indent_mult = %d\n", indent_level, indent_mult);
|
//DLOG("indent_level = %d, indent_mult = %d\n", indent_level, indent_mult);
|
||||||
int indent_px = (indent_level * 5) * indent_mult;
|
int indent_px = (indent_level * 5) * indent_mult;
|
||||||
|
|
||||||
draw_text(win->name_x, win->name_len, win->uses_net_wm_name,
|
draw_text((char *)i3string_as_ucs2(win->name), i3string_get_num_glyphs(win->name), true,
|
||||||
parent->pixmap, parent->pm_gc,
|
parent->pixmap, parent->pm_gc,
|
||||||
con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y,
|
con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y,
|
||||||
con->deco_rect.width - 2 - indent_px);
|
con->deco_rect.width - 2 - indent_px);
|
||||||
|
|
Loading…
Reference in New Issue