Hello, I recall the problem:
If the locale gives a charset != ISO-8859-1 (or a subset of this charset) and if the title of an application with i18n support has non ASCII characters then the application gives a COMPOUND_TEXT WM_NAME hints (same for the icon title). So if fvwm is compiled without multibyte support the window title contains string(s) of the form ?*ISO8859-15?* as the WM_NAME is taken as a STRING. Notes: - ISO-8859-1 is now obsolete in the all Europe - It seems that it is not easy to filter a COMPOUND_TEXT string by hands Possible fix: 1) compile fvwm with --enable-multibyte. 2) apply the attached patch I do not think that 1) is acceptable in the view of the state of the I18N_MB patch (e.g., it gives memory divergence). This patch should be used only when it is really needed (for multibyte charset). So, I think that I/we should apply the attached patch (+ appropriate NEWS and ChangeLog) to 2.4.6. The patch add a new config.h variable WEAK_I18N_SUPPORT hard coded to 1 (see below). If WEAK_I18N_SUPPORT is defined then, fvwm2 call setlocale at initialization and non STRING WM_[ICON_]NAME are converted using the XmbTextPropertyToTextList function. This fix the problem (on well configured machine) and allows fvwm to be usable with any 8bits charset without --enable-multibyte. One objection (from Dan) is that the use of XmbTextPropertyToTextList causes some system to load an additional library for nothing. With the patch you should edit config.h and comment out the WEAK_I18N_SUPPORT line to prevent this. So, here what I propose: If there are no objection I will apply the patch. Dan if you think a --disable-foo option is needed for disabling the patch I can add it. If there are objection(s) I will apply the patch with WEAK_I18N_SUPPORT off by default and add a config option --enable-foo to enable the patch. My problem with the configure option is (i) find the good name for "foo" and (ii) document this option in INSTALL.fvwm. Of course any comments on the patch is welcome. It is not pretty but it is "minimal". Olivier
Index: acconfig.h =================================================================== RCS file: /home/cvs/fvwm/fvwm/acconfig.h,v retrieving revision 1.39 diff -u -r1.39 acconfig.h --- acconfig.h 2001/10/30 19:16:52 1.39 +++ acconfig.h 2002/02/03 09:52:54 @@ -80,6 +80,14 @@ /* Enables session management functionality. */ #undef SESSION +/* Enables filtering of the wm icons and windows names by using the + * XmbTextPropertyToTextList functions when needed. + * This is used only if I18N_MB is undef. This fix problems with + * windows/icons names which contain non ASCII characters if the + * locale charset is not ISO-8859-1 */ +/* NOTE: hard coded to 1 */ +#define WEAK_I18N_SUPPORT 1 + /* Enables X11 multibyte character support */ #undef I18N_MB Index: fvwm/add_window.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/add_window.c,v retrieving revision 1.236.2.3 diff -u -r1.236.2.3 add_window.c --- fvwm/add_window.c 2002/01/17 01:18:13 1.236.2.3 +++ fvwm/add_window.c 2002/02/03 09:53:03 @@ -207,21 +207,84 @@ return; } -#else +#else /* I18N_MB */ #define GET_NAME_PROPERTY(a, b, c, d) get_name_property(a, b, c) +#ifdef WEAK_I18N_SUPPORT static void get_name_property( Status (func)(Display *, Window, XTextProperty *), Window w, char **ret_name) { XTextProperty text_prop; + int num; + char **list; + /* Note: we dump the name because we cannot keep the list in memory + * without a lot of changes */ if (func(dpy, w, &text_prop) != 0) + { + if (text_prop.value) + { + if (text_prop.encoding == XA_STRING) + { + /* STRING encoding, use this as it is */ + CopyString(&*ret_name, (char *)text_prop.value); + XFree(text_prop.value); + } + else + { + /* not STRING encoding, try to convert */ + if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) == Success + && num > 0 && *list) + { + /* XXX: does not consider the conversion is REALLY succeeded */ + XFree(text_prop.value); /* return of XGetWM(Icon)Name() */ + CopyString(&*ret_name, *list); + if (list) + XFreeStringList(list); + } + else + { + if (list) + XFreeStringList(list); + XFree(text_prop.value); /* return of XGet(Icon)WMName() */ + if (func(dpy, w, &text_prop)) + { + CopyString(&*ret_name, (char *)text_prop.value); + XFree(text_prop.value); + } + else + { + *ret_name = NoName; + } + } + } + } + else + { + *ret_name = NoName; + } + } + else + { + *ret_name = NoName; + } + + return; +} +#else /* WEAK_I18N_SUPPORT */ +static void get_name_property( + Status (func)(Display *, Window, XTextProperty *), Window w, char **ret_name) +{ + XTextProperty text_prop; + + if (func(dpy, w, &text_prop) != 0) *ret_name = (char *)text_prop.value; else *ret_name = NoName; return; } -#endif +#endif /* WEAK_I18N_SUPPORT */ +#endif /* I18N_MB */ void setup_window_name(FvwmWindow *tmp_win) { @@ -1940,7 +2003,11 @@ #define FREE_TEXT_PROPERTY(a, b) free_text_property(a) static void free_text_property(char **ptext) { +#ifdef WEAK_I18N_SUPPORT + free(*ptext); +#else XFree(*ptext); +#endif *ptext = NULL; } #endif Index: fvwm/events.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/events.c,v retrieving revision 1.309.2.4 diff -u -r1.309.2.4 events.c --- fvwm/events.c 2002/01/10 11:31:35 1.309.2.4 +++ fvwm/events.c 2002/02/03 09:53:16 @@ -428,7 +428,60 @@ #if 0 fprintf(stderr, " '%s'\n", Tmp_win->name); #endif -#else +#else /* I18N_MB */ +#ifdef WEAK_I18N_SUPPORT + if (!XGetWMName (dpy, Tmp_win->w, &text_prop)) + return; + if (text_prop.value) + { + if (text_prop.encoding == XA_STRING) + { + /* STRING encoding, use this as it is */ + free_window_names (Tmp_win, True, False); + CopyString(&Tmp_win->name, (char *)text_prop.value); + XFree(text_prop.value); + } + else + { + int num; + char **list; + + fprintf(stderr,"Not a String\n"); + /* not STRING encoding, try to convert */ + if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success + && num > 0 && *list) + { + free_window_names (Tmp_win, True, False); + fprintf(stderr,"\tSuccess\n"); + /* XXX: does not consider the conversion is REALLY succeeded */ + XFree(text_prop.value); /* return of XGetWMName() */ + CopyString(&Tmp_win->name, (char *)list[0]); + if (list) + XFreeStringList(list); + } + else + { + if (list) + XFreeStringList(list); + XFree(text_prop.value); /* return of XGet(Icon)WMName() */ + if (XGetWMName(dpy, Tmp_win->w, &text_prop)) + { + free_window_names (Tmp_win, True, False); + CopyString(&Tmp_win->name, (char *)text_prop.value); + XFree(text_prop.value); + } + else + { + return; + } + } + } + } + else + { + return; + } +#else /* WEAK_I18N_SUPPORT */ if (!XGetWMName(dpy, Tmp_win->w, &text_prop)) return; free_window_names (Tmp_win, True, False); @@ -436,7 +489,8 @@ if (Tmp_win->name && strlen(Tmp_win->name) > MAX_WINDOW_NAME_LEN) /* limit to prevent hanging X server */ Tmp_win->name[MAX_WINDOW_NAME_LEN] = 0; -#endif +#endif /* WEAK_I18N_SUPPORT */ +#endif /* I18N_MB */ SET_NAME_CHANGED(Tmp_win, 1); @@ -508,8 +562,59 @@ free_window_names (Tmp_win, False, True); Tmp_win->icon_name = (char *)text_prop.value; Tmp_win->icon_name_list = NULL; + } +#else /* I18N_MB */ +#ifdef WEAK_I18N_SUPPORT + if (!XGetWMIconName (dpy, Tmp_win->w, &text_prop)) + return; + if (text_prop.value) + { + if (text_prop.encoding == XA_STRING) + { + /* STRING encoding, use this as it is */ + free_window_names (Tmp_win, False, True); + CopyString(&Tmp_win->icon_name, (char *)text_prop.value); + XFree(text_prop.value); + } + else + { + int num; + char **list; + + /* not STRING encoding, try to convert */ + if (XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success + && num > 0 && *list) + { + free_window_names (Tmp_win, False, True); + /* XXX: does not consider the conversion is REALLY succeeded */ + XFree(text_prop.value); /* return of XGetWM(Icon)Name() */ + CopyString(&Tmp_win->icon_name, (char *)list[0]); + if (list) + XFreeStringList(list); + } + else + { + if (list) + XFreeStringList(list); + XFree(text_prop.value); /* return of XGet(Icon)WMName() */ + if (XGetWMIconName(dpy, Tmp_win->w, &text_prop)) + { + free_window_names (Tmp_win, False, True); + CopyString(&Tmp_win->icon_name, (char *)text_prop.value); + XFree(text_prop.value); + } + else + { + return; + } + } + } + } + else + { + return; } -#else +#else /* WEAK_I18N_SUPPORT */ if (!XGetWMIconName (dpy, Tmp_win->w, &text_prop)) return; free_window_names (Tmp_win, False, True); @@ -518,7 +623,8 @@ MAX_ICON_NAME_LEN) /* limit to prevent hanging X server */ Tmp_win->icon_name[MAX_ICON_NAME_LEN] = 0; -#endif +#endif /* WEAK_I18N_SUPPORT */ +#endif /* I18N_MB */ SET_WAS_ICON_NAME_PROVIDED(Tmp_win, 1); if (Tmp_win->icon_name == NULL) { Index: fvwm/fvwm.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.c,v retrieving revision 1.273 diff -u -r1.273 fvwm.c --- fvwm/fvwm.c 2001/09/16 15:51:16 1.273 +++ fvwm/fvwm.c 2002/02/03 09:53:19 @@ -75,7 +75,7 @@ /* need to get prototype for XrmUniqueQuark for XUniqueContext call */ #include <X11/Xresource.h> -#ifdef I18N_MB +#if defined(I18N_MB) || defined(WEAK_I18N_SUPPORT) #include <X11/Xlocale.h> #endif @@ -202,9 +202,17 @@ setVersionInfo(); -#ifdef I18N_MB - if (setlocale(LC_CTYPE, "") == NULL) - fvwm_msg(ERR, "main", "Can't set locale. Check your $LC_CTYPE or $LANG.\n"); +#if defined(I18N_MB) || defined(WEAK_I18N_SUPPORT) + { + char *s; + + if ((s = setlocale(LC_CTYPE, "")) == NULL) + fvwm_msg(ERR, "main","Can't set locale. Check your $LC_CTYPE or $LANG.\n"); + else if (!XSupportsLocale()) + { + fvwm_msg(WARN, "main", "X does not support current locale: %s\n", s); + } + } #endif /* Put the default module directory into the environment so it can be used