summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémie Courrèges-Anglas <jca@wxcvbn.org>2013-02-06 19:50:53 +0100
committerJérémie Courrèges-Anglas <jca@wxcvbn.org>2013-02-06 21:17:52 +0100
commit20c5d11a3be2843c808ba84f971ed3fed011e144 (patch)
treea384626ed4d274bef782a762efabc775734b716a
parent3725c23fddd8e936a91296f74e3fd6342270d6bb (diff)
downloadratpoison-20c5d11a3be2843c808ba84f971ed3fed011e144.zip
use utf8-handling Xft functions if we are in an UTF-8 locale
* (manage.c) in get_wmname(), try to get the (UTF-8 encoded) _NET_WM_NAME property. Fallback to GetWMName() if unavailable. Add some debugging bits to see which TEXT encoding clients use for WM_NAME. * (globals.c) use Xft*Utf8 functions to compute text width and draw strings. No regressions with or without Xft, UTF-8 locale or not. * assume we can use Xft*Utf8 functions whenever we have Xft, to reduce the #ifdef dance Original patch from Bernhard R. Link
-rw-r--r--src/globals.c45
-rw-r--r--src/manage.c88
2 files changed, 111 insertions, 22 deletions
diff --git a/src/globals.c b/src/globals.c
index 8824484..fda69bf 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -280,7 +280,8 @@ init_globals (void)
/* Wrapper font functions to support Xft */
void
-rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y, char *string, int length)
+rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y,
+ char *string, int length)
{
if (length < 0)
length = strlen (string);
@@ -291,22 +292,37 @@ rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y, char *string,
XftDraw *draw;
draw = XftDrawCreate (dpy, d, DefaultVisual (dpy, s->screen_num),
DefaultColormap (dpy, s->screen_num));
- if (draw)
- {
- XftDrawString8 (draw, style == STYLE_NORMAL ? &s->xft_fg_color:&s->xft_bg_color, s->xft_font, x, y, (FcChar8*) string, length);
- XftDrawDestroy (draw);
- }
+ if (!draw)
+ {
+ PRINT_ERROR (("Failed to allocate XftDraw object\n"));
+ return;
+ }
+
+ if (defaults.utf8_locale)
+ {
+ XftDrawStringUtf8 (draw, style == STYLE_NORMAL ? &s->xft_fg_color :
+ &s->xft_bg_color, s->xft_font, x, y,
+ (FcChar8*) string, length);
+ }
else
- PRINT_ERROR(("Failed to allocate XftDraw object\n"));
+ {
+ XftDrawString8 (draw, style == STYLE_NORMAL ? &s->xft_fg_color :
+ &s->xft_bg_color, s->xft_font, x, y,
+ (FcChar8*) string, length);
+ }
+ XftDrawDestroy (draw);
}
else
+ PRINT_ERROR (("No Xft font available.\n"));
+#else
+ XmbDrawString (dpy, d, defaults.font, style == STYLE_NORMAL ? s->normal_gc :
+ s->inverse_gc, x, y, string, length);
#endif
- XmbDrawString (dpy, d, defaults.font, style == STYLE_NORMAL ? s->normal_gc:s->inverse_gc, x, y, string, length);
}
int
#ifdef USE_XFT_FONT
-rp_text_width (rp_screen *s, XFontSet font, char *string, int count)
+rp_text_width (rp_screen *s, XFontSet font UNUSED, char *string, int count)
#else
rp_text_width (rp_screen *s UNUSED, XFontSet font, char *string, int count)
#endif
@@ -318,11 +334,16 @@ rp_text_width (rp_screen *s UNUSED, XFontSet font, char *string, int count)
if (s->xft_font)
{
XGlyphInfo extents;
- XftTextExtents8 (dpy, s->xft_font, (FcChar8*) string, count, &extents);
+ if (defaults.utf8_locale)
+ XftTextExtentsUtf8 (dpy, s->xft_font, (FcChar8*) string, count, &extents);
+ else
+ XftTextExtents8 (dpy, s->xft_font, (FcChar8*) string, count, &extents);
return extents.xOff;
}
- else
+ PRINT_ERROR (("No Xft font available.\n"));
+ return 0;
+#else
+ return XmbTextEscapement (font, string, count);
#endif
- return XmbTextEscapement (font, string, count);
}
diff --git a/src/manage.c b/src/manage.c
index f822c53..49e7b75 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -200,24 +200,92 @@ get_wmname (Window w)
{
char *name = NULL;
XTextProperty text_prop;
- int status, n;
+ int ret = None, n;
char** cl;
- if (XGetWMName(dpy, w, &text_prop) != 0) {
- status = XmbTextPropertyToTextList(dpy, &text_prop, &cl, &n);
- if (status == Success && cl && n > 0) {
- name = xstrdup(cl[0]);
- XFreeStringList(cl);
- } else if (text_prop.encoding == XA_STRING) {
- name = xstrdup((char*)text_prop.value);
+ /* If current encoding is UTF-8, try to use the window's _NET_WM_NAME ewmh
+ property */
+ if (defaults.utf8_locale)
+ {
+ Atom type = None;
+ unsigned long nitems, bytes_after;
+ int format;
+ char *val = NULL;
+
+ ret = XGetWindowProperty (dpy, w, _net_wm_name, 0, 40, False,
+ xa_utf8_string, &type, &format, &nitems,
+ &bytes_after, (unsigned char **) &val);
+ /* We have a valid UTF-8 string */
+ if (ret == Success && type == xa_utf8_string
+ && format == 8 && nitems > 0)
+ {
+ name = xstrdup (val);
+ XFree (val);
+ PRINT_DEBUG (("Fetching window name using _NET_WM_NAME succeeded\n"));
+ PRINT_DEBUG (("WM_NAME: %s\n", name));
+ return name;
+ }
+ /* Something went wrong for whatever reason */
+ if (ret == Success && val)
+ XFree (val);
+ PRINT_DEBUG (("Could not fetch window name using _NET_WM_NAME\n"));
}
- XFree (text_prop.value);
- }
+
+ if (XGetWMName (dpy, w, &text_prop) == 0)
+ {
+ PRINT_ERROR (("XGetWMName failed\n"));
+ return NULL;
+ }
+
+ PRINT_DEBUG (("WM_NAME encoding: "));
+ if (text_prop.encoding == xa_string)
+ PRINT_DEBUG (("STRING\n"));
+ else if (text_prop.encoding == xa_compound_text)
+ PRINT_DEBUG (("COMPOUND_TEXT\n"));
+ else if (text_prop.encoding == xa_utf8_string)
+ PRINT_DEBUG (("UTF8_STRING\n"));
+ else
+ PRINT_DEBUG (("unknown (%d)\n", (int) text_prop.encoding));
+
+#ifdef X_HAVE_UTF8_STRING
+ /* It seems that most applications supporting UTF8_STRING and
+ _NET_WM_NAME don't bother making their WM_NAME available as
+ UTF8_STRING (but only as either STRING or COMPOUND_TEXT).
+ Let's try anyway. */
+ if (defaults.utf8_locale && text_prop.encoding == xa_utf8_string)
+ {
+ ret = Xutf8TextPropertyToTextList (dpy, &text_prop, &cl, &n);
+ PRINT_DEBUG (("Xutf8TextPropertyToTextList: %s\n",
+ ret == Success ? "success" : "error"));
+ }
+ else
+#endif
+ {
+ /* XmbTextPropertyToTextList should be fine for all cases,
+ even UTF8_STRING encoded WM_NAME */
+ ret = XmbTextPropertyToTextList (dpy, &text_prop, &cl, &n);
+ PRINT_DEBUG (("XmbTextPropertyToTextList: %s\n",
+ ret == Success ? "success" : "error"));
+ }
+
+ if (ret == Success && cl && n > 0)
+ {
+ name = xstrdup (cl[0]);
+ XFreeStringList (cl);
+ }
+ else if (text_prop.value)
+ {
+ /* Convertion failed, try to get the raw string */
+ name = xstrdup (text_prop.value);
+ XFree (text_prop.value);
+ }
+
if (name == NULL) {
PRINT_DEBUG (("I can't get the WMName.\n"));
} else {
PRINT_DEBUG (("WM_NAME: '%s'\n", name));
}
+
return name;
}