Re: Solution for UTF-8 chars in the title bar?
- From: Timo Korvola <Timo Korvola iki fi>
- To: sawfish-list gnome org
- Subject: Re: Solution for UTF-8 chars in the title bar?
- Date: Tue, 22 Jan 2008 21:10:42 +0200
Janek Kozicki <janek_listy wp pl> writes:
> thanks, but I was unable to test your patch. I tried it against
> 1.3, 1.3.1 and svn-HEAD - I was unable to resolve conflicts by hand.
Yes, it was a patch against a previous patch. Things get complicated
without version control. Attached is a diff against 1.3.2. The patch
series is available at http://www.iki.fi/tkorvola/sawfish.git, branch
utf-8-names-fix. I may post it to the wiki if I find the time.
To illustrate the difference, run Sawfish in a non-UTF-8 locale but
with a title font capable of displaying Unicode (I use Freemono),
start a uxterm and gucharmap, then try xterm -T 'funny characters' and
konsole -T 'funny characters', where the funny characters are not
representable in the locale of Sawfish. With the Net_wm_names patch,
only konsole gets its title rendered correctly but xterm does not.
With the attached patch, both windows get correct titles.
The issues raised here remain unaddressed though:
<URL:http://mail.gnome.org/archives/sawfish-list/2007-October/msg00018.html>.
--
Timo Korvola <URL:http://www.iki.fi/tkorvola>
diff --git a/src/events.c b/src/events.c
index 4b58c7c..364be1c 100644
--- a/src/events.c
+++ b/src/events.c
@@ -479,106 +479,110 @@ motion_notify (XEvent *ev)
static bool
update_window_name(Lisp_Window * w, XPropertyEvent xproperty) {
- u_char *prop;
- Atom actual;
- int format;
- long nitems, bytes_after;
- char **text_list;
- XTextProperty tprop;
- int count;
- repv str = Qnil;
- int convert_status;
-
- if (xproperty.state != PropertyNewValue
- || XGetWindowProperty (dpy, w->id, xproperty.atom,
- 0, 200, False, AnyPropertyType, &actual,
- &format, &nitems,
- &bytes_after, &prop) != Success
- || actual == None)
- return FALSE;
-
- if (format != 8 || WINDOW_IS_GONE_P (w))
- return FALSE;
-
- tprop.value = prop;
- tprop.encoding = actual;
- tprop.format = format;
- tprop.nitems = strlen (prop);
-
- if (actual == xa_compound_text || actual == XA_STRING)
+ u_char *prop;
+ Atom actual;
+ int format;
+ long nitems, bytes_after;
+ char **text_list;
+ XTextProperty tprop;
+ int count;
+ repv str = Qnil;
+ int convert_status;
+
+ if (xproperty.state != PropertyNewValue
+ || XGetWindowProperty (dpy, w->id, xproperty.atom,
+ 0, 200, False, AnyPropertyType, &actual,
+ &format, &nitems,
+ &bytes_after, &prop) != Success
+ || actual == None)
+ return FALSE;
+
+ if (format != 8 || WINDOW_IS_GONE_P (w))
{
- convert_status = XmbTextPropertyToTextList (dpy, &tprop, &text_list, &count);
- if (convert_status >= Success && count > 0)
- {
- char * utf8str = g_locale_to_utf8(text_list[0], -1, NULL, NULL, NULL);
- if (utf8str)
- str = rep_string_dup (utf8str);
- }
- XFreeStringList(text_list);
+ XFree (prop);
+ return FALSE;
}
+ tprop.value = prop;
+ tprop.encoding = actual;
+ tprop.format = format;
+ tprop.nitems = strlen (prop);
+
#ifdef X_HAVE_UTF8_STRING
- if (actual == xa_utf8_string)
+ if (actual == xa_compound_text || actual == XA_STRING
+ || actual == xa_utf8_string)
+ {
+ convert_status = Xutf8TextPropertyToTextList (dpy, &tprop, &text_list,
+ &count);
+ if (convert_status >= Success && count > 0)
+ str = rep_string_dup (text_list[0]);
+ XFreeStringList(text_list);
+ }
+#else
+ if (actual == xa_compound_text || actual == XA_STRING)
{
- convert_status = Xutf8TextPropertyToTextList (dpy, &tprop, &text_list, &count);
- if (convert_status >= Success && count > 0)
- str = rep_string_dup (text_list[0]);
- XFreeStringList(text_list);
+ convert_status = XmbTextPropertyToTextList (dpy, &tprop, &text_list,
+ &count);
+ if (convert_status >= Success)
+ {
+ if (count > 0)
+ {
+ char * utf8str = g_locale_to_utf8(text_list[0], -1,
+ NULL, NULL, NULL);
+ if (utf8str)
+ {
+ str = rep_string_dup (utf8str);
+ g_free (utf8str);
+ }
+ }
+ XFreeStringList(text_list);
+ }
}
#endif
- XFree (prop);
+ XFree (prop);
- if (str == Qnil)
- return FALSE;
+ if (str == Qnil)
+ return FALSE;
- if (xproperty.atom == xa_wm_net_name)
+ if (xproperty.atom == xa_wm_net_name
+ && str != Qnil && Fequal (w->net_name, str) == Qnil)
{
- if ( str != Qnil && Fequal (w->net_name, str) == Qnil)
- {
- w->net_name = str;
- return TRUE;
- }
+ w->net_name = str;
+ return TRUE;
}
- if (xproperty.atom == xa_wm_net_icon_name)
+ if (xproperty.atom == xa_wm_net_icon_name
+ && str != Qnil && Fequal (w->net_icon_name, str) == Qnil)
{
- if ( str != Qnil && Fequal (w->net_icon_name, str) == Qnil)
- {
- w->net_icon_name = str;
- return TRUE;
- }
+ w->net_icon_name = str;
+ return TRUE;
}
- /* No point in updating the rest if we have the _NET ones. They won't
- be used anyways. */
- if (w->net_name != Qnil)
- return FALSE;
-
- if (xproperty.atom == XA_WM_NAME)
+ if (w->net_name == Qnil && xproperty.atom == XA_WM_NAME)
{
- if (str == Qnil)
- str = rep_null_string ();
- if (Fequal (w->name, str) == Qnil
- || Fequal (w->full_name, str) == Qnil)
- {
- w->full_name = w->name = str;
- return TRUE;
- }
+ if (str == Qnil)
+ str = rep_null_string ();
+ if (Fequal (w->name, str) == Qnil
+ || Fequal (w->full_name, str) == Qnil)
+ {
+ w->full_name = w->name = str;
+ return TRUE;
+ }
}
- if (xproperty.atom == XA_WM_ICON_NAME)
+ if (w->net_icon_name == Qnil && xproperty.atom == XA_WM_ICON_NAME)
{
- if (str == Qnil)
- str = rep_null_string ();
- if (Fequal (w->icon_name, str) == Qnil)
- {
- w->icon_name = str;
- return TRUE;
- }
- }
+ if (str == Qnil)
+ str = rep_null_string ();
+ if (Fequal (w->icon_name, str) == Qnil)
+ {
+ w->icon_name = str;
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
static void
@@ -614,16 +618,15 @@ property_notify (XEvent *ev)
break;
default:
-
- if (ev->xproperty.atom == XA_WM_NAME ||
- ev->xproperty.atom == XA_WM_ICON_NAME ||
- ev->xproperty.atom == xa_wm_net_name ||
- ev->xproperty.atom == xa_wm_net_icon_name )
- {
- need_refresh = changed =
- update_window_name(w, ev->xproperty);
- }
- else if (ev->xproperty.atom == xa_wm_colormap_windows)
+ if (ev->xproperty.atom == XA_WM_NAME ||
+ ev->xproperty.atom == XA_WM_ICON_NAME ||
+ ev->xproperty.atom == xa_wm_net_name ||
+ ev->xproperty.atom == xa_wm_net_icon_name )
+ {
+ need_refresh = changed =
+ update_window_name(w, ev->xproperty);
+ }
+ else if (ev->xproperty.atom == xa_wm_colormap_windows)
{
if (w->n_cmap_windows > 0)
XFree (w->cmap_windows);
diff --git a/src/windows.c b/src/windows.c
index 734032c..b7e2da6 100644
--- a/src/windows.c
+++ b/src/windows.c
@@ -356,85 +356,73 @@ remove_window_frame (Lisp_Window *w)
}
}
+
+static repv
+text_prop_to_utf8 (XTextProperty *prop)
+{
+ repv rval = Qnil;
+ if (prop->value && prop->nitems > 0)
+ {
+ char **list;
+ int count;
+ prop->nitems = strlen(prop->value);
+#ifdef X_HAVE_UTF8_STRING
+ if (Xutf8TextPropertyToTextList (dpy, prop, &list, &count) >= Success)
+ {
+ if (count > 0)
+ rval = rep_string_dup (list[0]);
+ XFreeStringList (list);
+ }
+#else
+ if (XmbTextPropertyToTextList (dpy, prop, &list, &count) >= Success)
+ {
+ if (count > 0) {
+ gchar *ustr = g_locale_to_utf8(list[0], -1, NULL, NULL, NULL);
+ if (ustr)
+ {
+ rval = rep_string_dup (ustr);
+ g_free (ustr);
+ }
+ }
+ XFreeStringList (list);
+ }
+#endif
+ }
+ return rval;
+}
+
+
/* Queries X properties to get the window {icon,}name */
static void
-get_window_name(Lisp_Window * w)
+get_window_name(Lisp_Window *w)
{
- char *tem;
- XTextProperty prop;
+ XTextProperty prop;
- /* We only try to use the utf8 properties if our xlib supports them */
+ /* We only try to use the utf8 properties if our xlib supports them.
+ Otherwise conversion would have to go via the current locale, which
+ might lose some characters. */
#ifdef X_HAVE_UTF8_STRING
- if (XGetTextProperty (dpy, w->id, &prop, xa_wm_net_name) && prop.value) {
- if (prop.nitems > 0)
- {
- char **list;
- int count;
- prop.nitems = strlen(prop.value);
- if (Xutf8TextPropertyToTextList (dpy, &prop, &list, &count)
- >= Success)
- {
- if (count > 0)
- w->net_name = rep_string_dup (list[0]);
- XFreeStringList (list);
- }
- }
- }
-
- if (XGetTextProperty (dpy, w->id, &prop, xa_wm_net_icon_name) && prop.value) {
- if (prop.nitems > 0)
- {
- char **list;
- int count;
- prop.nitems = strlen(prop.value);
- if (Xutf8TextPropertyToTextList (dpy, &prop, &list, &count)
- >= Success)
- {
- if (count > 0)
- w->net_icon_name = rep_string_dup (list[0]);
- XFreeStringList (list);
- }
- }
- }
-
- /* If we got the _NET names, there's no point in querying the others,
- as they won't be used anyways. */
- if (w->net_name != Qnil)
- return;
-
+ if (XGetTextProperty (dpy, w->id, &prop, xa_wm_net_name))
+ w->net_name = text_prop_to_utf8 (&prop);
+ if (XGetTextProperty (dpy, w->id, &prop, xa_wm_net_icon_name))
+ w->net_icon_name = text_prop_to_utf8 (&prop);
#endif
- if (XGetWMName (dpy, w->id, &prop) && prop.value)
+ if (w->net_name == Qnil && XGetWMName (dpy, w->id, &prop))
{
- if (prop.nitems > 0)
- {
- char **list;
- int count;
- prop.nitems = strlen(prop.value);
- if (XmbTextPropertyToTextList (dpy, &prop, &list, &count)
- >= Success)
- {
- if (count > 0)
- w->name = rep_string_dup (g_locale_to_utf8(list[0],
- -1, NULL, NULL, NULL));
- XFreeStringList (list);
- }
- }
- XFree (prop.value);
+ repv name = text_prop_to_utf8 (&prop);
+ if (name != Qnil)
+ w->name = name;
}
- w->full_name = w->name;
+ w->full_name = w->name;
- if (XGetIconName (dpy, w->id, &tem))
- {
- w->icon_name = rep_string_dup (g_locale_to_utf8(tem,
- -1, NULL, NULL, NULL));
- XFree (tem);
- }
- else
- w->icon_name = w->name;
-
+ if (w->net_icon_name == Qnil && XGetWMIconName (dpy, w->id, &prop))
+ w->icon_name = text_prop_to_utf8 (&prop);
+ if (w->icon_name == Qnil)
+ w->icon_name = w->name;
}
+
/* Add the top-level window ID to the manager's data structures */
Lisp_Window *
add_window (Window id)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]