GNOME Bugzilla – Bug 503071
Application direction changes to right to left even if theres no translation
Last modified: 2008-08-13 00:41:04 UTC
on an RTL Desktop, the application direction changes to right to left even if theres no translation (no Hebrew translation in my case). if theres no translation the direction should not be changed. in the way its working now it hurts the usability of some applications. i'll try to add some screenshots to make it more clear.
Created attachment 100770 [details] bluefish editor on a Hebrew Dektop
the default text direction is determined based on the locale, not based on the content of individual strings. If your app is missing hebrew translations, that is the bug to be fixed. Short of that, you can just run it in a different locale: LANG=en_US untranslated-application
If the app is missing hebrew translations, thats not the bug. its impossible to translate every possible application, and there are some applications that dont need to be translated. for example, developers tools: in my case, most Hebrew speakers are more familiar with the English terms then the Hebrew terms. and im not planing to run my application with "LANG=en_US untranslated-application" ill keep using an english Desktop or go Back to KDE/qt, there it works the way it should work.
Created attachment 100777 [details] Editing preferences in bluefish on a hebrew desktop another example on how an application with no translation looks.
Comment on attachment 100777 [details] Editing preferences in bluefish on a hebrew desktop another example on how an application with no translation looks
Comment on attachment 100777 [details] Editing preferences in bluefish on a hebrew desktop another example on how an application with no translation looks, the direction should be LTR.
(In reply to comment #3) > and im not planing to run my application with "LANG=en_US > untranslated-application" > ill keep using an english Desktop or go Back to KDE/qt, there it works the way > it should work. Considering Mark's rude behavior I was tempted to close this bug with the words "Goodbye, Mark". Well, actually it seems possible to figure out, if the current application is translated: $ gettext -d gtk20 ""Project-Id-Version: GTK+ HEAD Report-Msgid-Bugs-To: POT-Creation-Date: 2007-09-13 19:20-0400 PO-Revision-Date: 2007-06-13 19:02+0000 Last-Translator: Hendrik Richter <hendrikr@gnome.org> Language-Team: German <gnome-de@gnome.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n != 1; X-Launchpad-Export-Date: 2007-10-11 21:06+0000 X-Generator: Launchpad (build Unknown) $ LC_ALL=fr_FR gettext -d gtk20 "" $ Behdad? As you are our RTL expert: Any opinion regarding this?
Well, the bug is valid. Except that even if we base the decision about UI direction on whether the default app domain has RTL translations, one would still get RTL (Hebrew, Arabic..) messages for the messages coming from Gtk+ (dialogs, etc). So it's not simple. On the other hand, if one fixes the Gtk+ dialog messages issue, the default widget direction will be corrected automatically. The behavior the reporter asks for essentially is, and can be implemented as a LD_PRELOAD or GTK module quite easily, override the textdomain() function and if the set text domain doesn't have a translation for the current domain, set LC_MESSAGES to some default value, preferably the first language from $LANGUAGE. I think this needs to be filed as a gettext issue. CC'ing Bruno to get his opinion as gettext maintainer.
Yeah, I was about to bring that point up; apps show translated strings from multiple domains: app, gtk, libgnome, etc. Which domain do you base the decision on ?
Probably "current" one. That makes a whole lot sense if/when we support live locale changing. That actually sounds more reachable than I used to think it is.
Yes, the "current" one would be used for choosing the locale. Guess we have some chance to do the right thing, as GTK+ applications do not call setlocale by themself, but let gtk_init do the job. I've found this interesting code in "gtkmain.c:do_pre_parse_initialization": if (!setlocale (LC_ALL, "")) g_warning ("Locale not supported by C library.\n\tUsing the fallback 'C' locale.") Maybe the code above should be changed like this: previous_locale = setlocale (LC_ALL, ""); if (!previous_locale) g_warning ("Locale not supported by C library.\n\t" "Using the fallback 'C' locale.") the next step would be something like this: if (previous_locale && !*gettext("")) { setlocale (LC_ALL, previous_locale); previous_locale = NULL; g_warning ("Program not translated yet... blub... blub..."); } Obvious problems with that: - There __could__ be many programs that call "textdomain" and "bindtextdomain" after gtk_init. - Nobody says you have to use gettext for localizing your application. Java applications, like Eclipse for instances, use Java message bundles instead of GNU gettext - for obvious reasons. So blindly changing anything here has a hugh breakage potential. @Mark: In this case the KDE folks obviously have the advantage of taking backwards compability not that serious as we do.
sorry if my behavior seemed rude, i just wanted a little bit more attention to this issue. so is it possible to fix this?
(In reply to comment #12) > so is it possible to fix this? The problem you raised really is an interesting one, that affects not only RTL, but also LTR users: Serveral times I've heared users complaining about applications mixing English (non-localized) widgets with for instance German (localized) stock widgets. Especially when this happens in the same window it lowers perceived product quality. Well, and when this happens to RTL users, the slight anoyance which it is for LTR people, becomes a quite dramatic one - as you demonstrated. So we definitly should try to find a solution. We just have to figure out, how the solution looks like. Hooks are identified, but they have to be used in a way that doesn't break dozens of GNOME applications.
> so is it possible to fix this ? The proposed solution seems dubious to me. Checking for gettext("") might tell you if there is no translation at all (ie no .po file) for a locale, but it won't help you if there is a po file that is 80% empty. In that case, you'll still end up with mixed strings in the ui.
(In reply to comment #14) > > so is it possible to fix this ? > > The proposed solution seems dubious to me. Checking for gettext("") might > tell you if there is no translation at all (ie no .po file) for a locale, > but it won't help you if there is a po file that is 80% empty. In that case, > you'll still end up with mixed strings in the ui. > Well, but in that case we clearly are in the situation "file a bug report, Luke (and patches)".
I actually like the gettext("") suggestion. If there does exist a .po file, it's translators bug. And we have a good fix: remove the po file. If we can detect that textdomain is not called yet, we warn and fall back to old behavior. That's a fix to me.
(In reply to comment #16) > If we can detect that textdomain is not called yet, we warn and fall back to > old behavior. That's a fix to me. Indeed, this should work: if (NULL == textdomain (NULL) && assuming_progam_uses_gettext) { g_warning ("blub, blub, call textdomain() or gtk_disable_get_text() " "before calling gtk_init()"); } else if ('\0' == *gettext("")) { ... } Matthias, I'll cook a patch if you agree with that solution.
Also, cam we get rid of the: g_warning ("Locale not supported by C library.\n\t" "Using the fallback 'C' locale.") Currently to translate GNOME to your minority language you need to write a glibc locale first and get it upstream and in distros. That takes something like two years at least... But most minority language people will be happy enough to run with any UTF-8 locale, say en_US, as long as they get their messages translated. And LC_MESSAGES=whatever doesn't use much from the libc locale anyway. Maybe just dates...
(In reply to comment #18) > Also, cam we get rid of the: > > g_warning ("Locale not supported by C library.\n\t" > "Using the fallback 'C' locale.") After playing with LANGUAGE, LANG, LC_*, setlocale and friends I'd rather keep the warning, but make it more useful: "Locale not supported by C library.\n" "\tUsing the fallback 'C' locale.\n" "\tSet LANG (or LC_* if you use them) to some mainstream locale and\n" "\tLANGUAGE to your preferred locale to work arround that limitation."
Was working on the issue this morning. Seems much harder than initially thought: * there also is gtk_set_locale() * with LANGUAGE set there seems no fallback possible, expect for unsetting that environment variable, which clearly is not wanted, if you consider the effect on spawning sub-processes
Yeah, seems like some gettext support is needed. Back to giulia... http://live.gnome.org/LocaleProject
is there any progress?
(In reply to comment #22) > is there any progress? > Currently stalled due lack of ideas. If you want to help, you could try to get some gettext/i18n people to look at this topic: We need a method to override GNU gettext's non-standard LANGUAGE variable override. What irony: Overriding a override. :-/
> We need a method to override > GNU gettext's non-standard LANGUAGE variable override. > > What irony: Overriding a override. :-/ When you're trying to override programmatically an override that the user has given, chances are high that you're doing the wrong thing. I think that for people who set the LANGUAGE variable, it's perfectly natural to have a mix of locales. Whereas your feeling that the screenshot with the RTL menu structure labelled in LTR English is "wrong" probably matches the habits of people who *don't* set the LANGUAGE variable. I have LANGUAGE set, and it does not shock me if gcc or make talk to me in a mix of French, German, and English. And likewise, I found the mentioned screenshot OK. People in RTL locales are used to see short strings in LTR direction: namely, numbers and foreign words written in Latin script. So, I don't see the need to do something in gettext. People who like mixing locales are not shocked by your screenshot, and people who want a pure mono-locale GUI will not set LANGUAGE.
Just a quick note on how KDE is handling this issue. bool KLocale::isApplicationTranslatedInto( const QString & language) { . . QString sFileName = QString::fromLatin1("%1/LC_MESSAGES/%2.mo") .arg( language ) .arg( appName ); QString sAbsFileName = locate( "locale", sFileName ); return ! sAbsFileName.isEmpty(); } bool KLocale::setLanguage(const QStringList & languages) { QStringList languageList( languages ); //If you only have kdelibs.mo but nothing from appname.mo, you get a mostly //English app with layout from right to left. That was considered to be a bug //by the Hebrew translators. . . for( QStringList::Iterator it = languageList.fromLast(); it != languageList.begin(); --it ) { bool bIsTranslated = isApplicationTranslatedInto( *it ); if ( ... || !bIsTranslated) { it = languageList.remove( it ); } } . . } KDE actually doesn't use gettext() at all. They copied gettext code to their library.
I agree with Comment #24. If LANGUAGE is set than gtk should not care for missing translations. As for "gtk_set_locale()" - According to its comment this should be a rarely used function. I guess a usage survey is needed but i think it is safe to ignore this issue as it will make users happier even if we only 95% percent support RTL usage correctly (95% is still better then 80%). I would like to disagree on Mark being rude. I think he had a really good point. GNOME users should not care for the technical details, and getting a "this is your problem" sort of response creates a negative attitude. I know that developers are here on their good will, but we need to remember that a user filing a bug is also a volunteer.
glib defines _(msg) as alias for glib_gettext(), guess we could something similiar for GTK
That is not true. GLib defines _() as an alias for gettext(). glib_gettext() is an internal function.
(In reply to comment #28) > That is not true. GLib defines _() as an alias for gettext(). glib_gettext() is > an internal function. > glibintl.h disagrees: http://svn.gnome.org/viewvc/glib/trunk/glib/glibintl.h?revision=5973&view=markup
(In reply to comment #29) > (In reply to comment #28) > > That is not true. GLib defines _() as an alias for gettext(). glib_gettext() is > > an internal function. > > > > glibintl.h disagrees: > http://svn.gnome.org/viewvc/glib/trunk/glib/glibintl.h?revision=5973&view=markup Yes, and glibintl.h is an internal header. gi18n.h is the public one and has: #define _(String) gettext (String)
(In reply to comment #25) > KDE actually doesn't use gettext() at all. They copied gettext code to their > library. Yes, Qt has its own locale system and so they can do whatever they want... Please don't copy considerable amount of code from KDE/Qt here. The licenses are not necessarily compatible with glib. (thought about KDE libs it probably is)
(In reply to comment #30) > (In reply to comment #29) > > (In reply to comment #28) > > > That is not true. GLib defines _() as an alias for gettext(). glib_gettext() is > > > an internal function. > > > > > > > glibintl.h disagrees: > > http://svn.gnome.org/viewvc/glib/trunk/glib/glibintl.h?revision=5973&view=markup > > Yes, and glibintl.h is an internal header. gi18n.h is the public one and has: > > #define _(String) gettext (String) > Yes, absolutely right. My idea for disabling translations in GTK+, when the application itself is untranslated, is using _gtk_gettext for translations in GTK+, instead of GNU gettext. _gtk_gettext would check a flag, to figure out if calling gettext is appropriate.
> My idea for disabling translations in GTK+, when the application itself is > untranslated, is using _gtk_gettext for translations in GTK+, instead of GNU > gettext. _gtk_gettext would check a flag, to figure out if calling gettext is > appropriate. Need to do that in all libraries. Changing _() in gi18n-lib.h to call a function is one possibility. That's a compatible-enough change. We have done that kind of macro changes before (even this cycle about g_assert). mclasen, how does that sound?
If the app is only half translated, letting this work involves also the language coordinator withdrawing half done and old translations that are severely outdated. Or, at the coordinator's option, just leaving things as they are :-)
If a coordinator feels a translation is not good enough he should remove it from the LINGUAS file (or at some packages ALL_LINGUAS in configure.ac/in). (In replay to comment #31) I will make sure to also post the code license if pasting external code in bugzilla.
Created attachment 105041 [details] [review] add glib gettext API and only translate if a translation is available for the application using glib
Created attachment 105042 [details] [review] modify gtk to use new glib gettext api With both of the patches applied the bug is solved
Comment on attachment 105041 [details] [review] add glib gettext API and only translate if a translation is available for the application using glib >+const gchar * >+g_gettext (const gchar *msgid) >+{ >+ if (g_should_translate) >+ return gettext (msgid); >+ else >+ return msgid; >+} Not a huge fan of this one. This is equivalent to gettext(). So, no need for it. Lets just add g_dgettext() initially. It's not a bad idea to move to a gettext() wrapper, so we can "fix" other bugs in the future, but not necessary to fix this bug specifically. The Gtk+ patch needs rework because I filed bug 516083.
Mathias, Matthias, what do you think about this addition?
I would appreciate a response. Cause my fingers are itching to do "svn ci".
Created attachment 107824 [details] [review] modify gtk to use new glib gettext api: removed calls to g_gettext()
Created attachment 107825 [details] [review] add glib gettext API and only translate if a translation is available for the application using glib Add a call to setlocale(LC_ALL, "") in i18n initialization. This to be compatible with applications that do not do this them selves (gnome-panel for example).
Not quite sure I understand how this works but what happens if my application doesn't need translations? It should be possible to build an entire application using only things translated by gtk or other libraries, it just might not be the best thing to do. But, in that case, does this patch mean the application always uses english?
If an application does not set its textdomain before g_i18n_init() is called (for example, if the applications has no translatable strings) then the default English locale will be used. I don't know any such application which only relies on gtk for translations (i.e. only stock items are used w/o introducing any new user visible strings). If such a case does exist then the application would need to set its textdomain to gtk's textdomain.
I believe this is good enough to be committed on HEAD - Doesn't effect current stable release and give us enough time to handle issues that may be raised.
Created attachment 108680 [details] [review] modify gtk to use new glib gettext api updated patch for HEAD branch
Created attachment 108681 [details] [review] add glib gettext API and only translate if a translation is available for the application using glib updated patch for HEAD branch
Commited. There is enough time before the gnome 2.24 release for the few broken application (those that call bindtextdomain() after gtk_init()) to get fixed. Glib ---- 2008-05-11 Yair Hershkovitz <yairhr@gmail.com> Bug 503071 - Application direction changes to right to left even if theres no translation. * glib/gi18n.c: g_i18n_init() for initializing the glib i18n, checking if a translation is available for the calling app. wrappers for gettext, dgettext and dpgettext to check first if the application should be translated. * glib/gi18n.h: symbol declaration for gettext wrappers. * glib/gi18n-lib.h: include gi18n.h instead of libintl.h. * glib/gstrfuncs.c: moved g_dpgettext() to glib/gi18n.c. * glib/gutils.c: use g_dgettext() instead of dgettext(). * glib/glibintl.h: include gi18n.h. * glib.symbols: added gettext wrappers. * glib/Makefile.am: added gi18n.c. Gtk+ ---- 2008-05-11 Yair Hershkovitz <yairhr@gmail.com> * gtk/gtkmain.c: call g_i18n_init() in gettext_initialization(). do gettext_initialization only once. * gtk/gtkbuilderparser.c: use glib i18n api. removed dpgettext() as it duplicates g_dpgettext() and added _g_dpgettext() to wrap g_dpgettext with the extended functionality that was in the removed dpgettext(). * gtk/gtkaccellabelc: * gtk/gtkstock.c: * gtk/gtkimmulticontext.c: * gtk/gtkactiongroup.c: * gtk/gtkintl.h: use glib i18n api.
(In reply to comment #48) > Commited. Did you get permission from Matthias first? This change involves new glib API so I like to see Matthias comment on it with his maintainer hat on.
Matthias, would you like to comment?
The function g_i18n_init() doesn't adhere to the coding guidelines (it has no spaces between function names and opening parens). Yes, I am a pedant.
(In reply to comment #51) 2008-05-12 Yair Hershkovitz <yairhr@gmail.com> * gtk/gtkmain.c: g_i18n_init(); -> g_i18n_init (); Commited
I was referring to the code in g_i18n_init() itself;)
After this patch, running gtk-demo now gives the warnings: GLib-WARNING **: textdomain() must be called before glib i18n initialization GLib-WARNING **: No translation is available for the requested locale. Is this really the intent, that an application that doesn't call any libintl or gi18n API at all will get such warnings? Is the intent really that applications now *must* have i18n? If not, then these warnings are misleading and should be removed. Or can the case of calling textdomain() too late be distinguished from the case of not calling it at all?
(In reply to comment #54) If an application doesn't support intl then it shouldn't call g_i18n_init(). If your application uses Gtk then it does support intl and therefor need to call textdomain() before initializing gtk. If you are referring to a case similar to that in comment #43, where an application doesn't have translatable strings but uses gtk stock translations then we need to add API which allows to declare that this is the case. If you are referring to some console application that uses glib then it shouldn't call g_i18n_init(). g_i18n_init() is called by Gtk before initializing its own text domain so that when testing for LTR/RTL condition g_dgettext() will always return LTR if the application itself has no translation. Testing if textdomain() was called or not is only relevant for the time of calling.
> If your application uses Gtk then it does support intl It does? Get real. There are also other kinds of GTK+ application than well-known Open Source applications of general interest distributed with Linux distros. Why should an in-house application used by a small number of people, all speaking the same language, at one site, need to support i18n? Why should people who run such an application suddely need to see these weird warning messages when they have upgraded their GTK+ runtime?
(In reply to comment #53) 2008-05-12 Yair Hershkovitz <yairhr@gmail.com> * glib/gi18n.c (g_i18n_init): Coding convention fix. Space between a function name and its opening parenthesis.
(In reply to comment #56) The purpose of this fix is also to affect binaries compiled with earlier gtk+ versions. So that application that doesn't have a certain locale translation will run in the English locale, though it wasn't upgraded. Only applications of the official GNOME release are recompiled for each release. Applications from the Extras set do not often make releases. But as you mentioned some applications may get hurt by this. I would less worry on the printed warning but on the fact that if in your example the application uses a language other than english than it would get a mixed english/other language look. It is possible that if textdomain is called after i18n_init, or not called at all to only print the warning without forcing the application to use the english translation.
It also says this in C locale: (medit:27379): GLib-WARNING **: No translation is available for the requested locale. which doesn't make sense (for C locale). So, is glib a translation policeman now? It does make much sense to have this warning, but *optional*, for when you do want it. --g-fatal-warnings is still a debugging tool, and any extra warning is still a bad thing which must be fixed. And textdomain("nonexistent-because-glib-wants-me-to-do-this") is not a fix! Hey, I got an idea, let me just fix this in SVN. We still will have time to fix any problems shall they arise ;)
This change actually breaks things: here I have an application which never calls gettext (it uses dgettext) and it doesn't call textdomain(). And so gtk parts in it are untranslated now because glib decides it doesn't want to translate gtk strings.
Someone please revert the committed patches, then continue discussing here until we reach an agreement. No more commits (other than the revert) please.
Created attachment 110812 [details] [review] Don't break applications which doesn't call textdomain(). Dont warn of unavailable translation for the "C" locale. 1) Don't break applications which doesn't call textdomain(), so if an application doesn't have its own translatable strings or uses a more complex translation scheme then textdomain() and gettext() its intl state is not affected. The textdomain WARNING is still in tact. The right thing is to make sure g_i18n_init() is not called if textdomain() is intentionally isn't used. Maybe gtk_disable_gi18n()? This should be called before gtk_init() and friends similarly as gtk_disable_setlocale() is used. 2) Dont warn of unavailable translation for the "C" locale.
Tor, Yevgen, Behdad: Please review and test along with the new patch. Please also comment on the gtk_disable_gi18n() suggestion. (In reply to comment #61): I don't see the point in reverting the commit. In order to reach an agreement participants willing to test/comment/review are needed, and no one was willing to do this before I've committed. If the commit is reverted then again we will have to wait months to years until someone cares. Besides, I believe that with the last patch the code is stable enough (nothing is broken) to stay in HEAD.
Seems working here, except the warning. How about applications calling g_i18n_init(domain) explicitly? That way you don't get any magic, but then you don't get any breakage either. gtk_disable_gi18n() won't work for pygtk.
Commited attachment #110812 [details]. Also added g_disable_setlocale() API which makes g_i18n_init() to not set the locale. This was needed so that gtk_disable_setlocale() is not broken. 2008-05-17 Yair Hershkovitz <yairhr@gmail.com> * glib/glib.symbols: * glib/gi18n.h: Added g_disable_setlocale(). * glib/gi18n.c: Added g_disable_setlocale() API to disable setting the locale in g_i18n_init(). Dont disable translations if textdomain was not set before calling g_i18n_init(). Dont disable translations if the locale is "C". 2008-05-17 Yair Hershkovitz <yairhr@gmail.com> * gtk/gtkmain.c: gtk_disable_setlocale() - Added a call to g_disable_setlocale().
In reply to comment #64: I dont see why the displayed warning breaks anything. Your program functionality is not changed. For applications who use textdomain() this indicates that they have a fix to do. For those who don't then they can use 'gtk_disable_gi18n()' to eliminate the warning. Not automatically assuming i18n is used means that this bug can't be solved. I think it would be a shame if the reason for this is a g_warning(). Regarding pygtk, it is normally up to the binding library to follow gtk's api. For pygtk adding gtk_disable_gi18n() is quite easy, so it is for java-gtk. I'm not sure I'm aware of all official gtk bindings but each one of them can easily add a simple api call.
I thought I said no further commit before we reach consensus. /me removes the bug from his todo list...
In reply to comment #67: Yeah, and it's better to live it in a state where things are broken. Anyway, I thought you put RTL community needs before your ego.
(In reply to comment #66) > In reply to comment #64: > > I dont see why the displayed warning breaks anything. Your program > functionality is not changed. Yes it is. "myapp --g-fatal-warnings" aborts. > For applications who use textdomain() this indicates that they have a fix to > do. For those who don't then they can use 'gtk_disable_gi18n()' to eliminate > the warning. Thank you very much, no thank you. I can call textdomain() as well. But I prefer not to work around artificial problems; it's better not to have them in the first place. And untranslated applications must not be forced to deal with translations! > Not automatically assuming i18n is used means that this bug can't be solved. I > think it would be a shame if the reason for this is a g_warning(). It would be a shame to force code changes in non-buggy well-behaved applications. > Regarding pygtk, it is normally up to the binding library to follow gtk's api. > For pygtk adding gtk_disable_gi18n() is quite easy, ... No it's not. gtk module initialization code calls gtk_init(), after that it's too late to call gtk_disable_gi18n().
(In reply to comment #69) >(In reply to comment #66) >> In reply to comment #64: >> >> I dont see why the displayed warning breaks anything. Your program >> functionality is not changed. >Yes it is. "myapp --g-fatal-warnings" aborts. And so it aborts if you run "LANG=ii myapp --g-fatal-warnings" g_warning are not necessarily issues with your application, they can be caused from system misconfiguration. So I don't think shipping your application with a script that calls it with "--g-fatal-warnings" is a good idea. fatal-warnings are used for debug needs. >> For applications who use textdomain() this indicates that they have a fix to >> do. For those who don't then they can use 'gtk_disable_gi18n()' to eliminate >> the warning. >Thank you very much, no thank you. I can call textdomain() as well. But I >prefer not to work around artificial problems; it's better not to have them in >the first place. And untranslated applications must not be forced to deal with >translations! Thats the whole point, they should - untranslated application should be forced to deal with translations. Gtk automatically deals with translations and intl and unless you explicitly tell it to not act in its default manner, for example you use gtk_disable_setlocale if you do not want automatic selection of the locale, it assumes you want translations and intl. If you don't deal with it then your application has translations, the gtk translations. And if a user locale is different then the one which you assumes then he'll get a mixed languages look and feel. >> Not automatically assuming i18n is used means that this bug can't be solved. I >> think it would be a shame if the reason for this is a g_warning(). >It would be a shame to force code changes in non-buggy well-behaved >applications. Unless you actually shipped your application with a wrapping script that calls "--g-fatal-warnings" then you are not forced to change anything. >> Regarding pygtk, it is normally up to the binding library to follow gtk's api. >> For pygtk adding gtk_disable_gi18n() is quite easy, ... >No it's not. gtk module initialization code calls gtk_init(), after that it's >too late to call gtk_disable_gi18n(). Then can you explain how and why pygtk uses gtk_disable_setlocale()? cuz it also must be called before gtk_init().
(In reply to comment #68) > In reply to comment #67: > > Yeah, and it's better to live it in a state where things are broken. > > Anyway, I thought you put RTL community needs before your ego. Wow, now you get personal. It's not about ego. It's about chaos vs order. You committed to a module that you don't have permission to commit to. I asked you not to do that again. You failed and repeated it. A third time doing that will result in your commit access revoked. That's all.
Umm, so which one is easier: use a wrapper script to make sure an untranslated app runs with LANG=C or LANG=en_US, or add a call to gtk_disable_setlocale() and/or g_disable_setlocale() to the source code of the app (if the correct version of the source code can be found) and rebuild it (if the build environment still exists and still works). If you think it is an uncommon scenario that some application's source code has been lost, or the only person who knew how to build it and/or had a working build environment has left the company, wake up to the real world. Sure, we don't come across situations like that very often in the Open Source community where we recompile code all the time. But I can very much imagine it might be a relevant problem for some in-house GTK+ application in some small company, where the hacker who built it has left.
(In reply to comment #72) I didn't get your point. My change does not affect any in-house application, but the warning that may be displayed. It seems we argue wither a warning should be displayed or not. As far as i care the warning can be removed if it helps this change to be included in the next release.
Well, as far as I know g_warning() calls aren't supposed to be used for informational messages that can be ignored. I think the intent is that if you call g_warning(), it indicates that something is seriously wrong, there is a bug in the program, and its behaviour from that point on is basically undefined. Of course, I don't claim that all current uses of g_warning() conform to such an interpretation... But we shouldn't add more g_warning() calls in situations that actually aren't bugs, but perfectly normal and/or recoverable, should we?
It does look like glib log messages are in mess. ordered from less to more severe: DEBUG, INFO, MESSAGE, WARNING, CRITICAL, ERROR. First, shouldn't CRITICAL be more severe then ERROR? Now if the difference between ERROR and WARNING is that ERROR also means fatal then there shouldn't be a log level between them. Maybe CRITICAL was supposed to be the fatal one and not ERROR? It also looks like INFO and MESSAGE has no meaningful difference. And there is no API that uses the INFO log level.
Yair: please revert your committed patches, you do not have permission to commit in either glib or gtk+. Unreviewed patches are broken per definition.
Lots of apps suddenly have started warning when building becauseof the change to make _() return a const string. While that is theoretically correct of course, I wonder if we really can change that now? It adds a lot of build warnings to user code. Yair, why are you repeatedly ignoring the requests to stop committing/revert until this has been discussed?
About the const return, it was ment to avoid the warning when compiling gi18n.c as g_gettext() prototype is similar to the gettext() one which receives a const msgid. Obviously the intention was not to add warnings to other apps, and the return value should not have been const, especially since gettext() itself does not return a const. I'm not going to do any commits at this point but i'll fix this on my local copy.
I think the important point is that you should revert the change ASAP
Yair, thanks for the patches, but for glib and gtk+, patches need review and approval before they can go in. As for the technical side of things, i don't quite see why we need to add extra API at all here. Something close to what tbf suggested in Comment #11 or later refinements should be good enough to settle the issue.
(In reply to comment #80) My patches are implementing the ideas in Comment #11, Comment #13 and so on. If ignoring the glib API comment, then any attempt to develop the suggestion from Comment #11 will converge to the same implementation, having gtk_dgettext instead of g_dgettext and so on. Regarding Glib and the API I've added: It is not enough to check if a translation exists in gtk+. Glib itself need to to check the untranslated condition as it itself contains translations which could appear in gtk+ or in terminal (when gtk+ is not used at all). In such a case we will have a mixed languages gui. The API makes it easier to share the logic between glib and gtk. It also removes code duplication of dcgettext implemented in both gtk+ and glib.
I was referring to comment #33 and not #13
About the g_warning() calls in comment #11, isn't that very much a case where one should *not* use g_warning(), because no programming error is involved? Just a g_message(), if anything at all.
Where is `g_dgettext'? where is glib/gi18n.c? Does any of this have any bearing on this build failure? /bin/sh ../libtool --mode=link i686-pc-linux-gnu-gcc -march=prescott -O2 -ggdb -pipe -o gnome-open gnome-open.o libgnome-2.la -Wl,--export-dynamic -pthread -lgnomevfs-2 -lbonobo-2 -lbonobo-activation -lgmodule-2.0 -ldl -lORBit-2 -lgthread-2.0 -lrt -lgobject-2.0 -lgconf-2 -lglib-2.0 -lesd -laudiofile -lm -lpopt i686-pc-linux-gnu-gcc -march=prescott -O2 -ggdb -pipe -o .libs/gnome-open gnome-open.o -Wl,--export-dynamic -pthread ./.libs/libgnome-2.so -L/usr/lib /usr/lib/libgnomevfs-2.so /usr/lib/libxml2.so /usr/lib/libdbus-glib-1.so -lnsl /usr/lib/libgnutls.so -lz /usr/lib/libtasn1.so /usr/lib/libgcrypt.so /usr/lib/libgpg-error.so /usr/lib/libavahi-glib.so /usr/lib/libavahi-client.so /usr/lib/libdbus-1.so /usr/lib/libavahi-common.so -lresolv -lutil /usr/lib/libbonobo-2.so /usr/lib/libbonobo-activation.so /usr/lib/libORBitCosNaming-2.so /usr/lib/libgconf-2.so /usr/lib/libORBit-2.so /usr/lib/libgmodule-2.0.so /usr/lib/libgthread-2.0.so -lrt /usr/lib/libgobject-2.0.so /usr/lib/libglib-2.0.so /usr/lib/libesd.so /usr/lib/libasound.so -ldl -lpthread /usr/lib/libaudiofile.so -lm /usr/lib/libpopt.so /usr/lib/libgnomevfs-2.so: undefined reference to `g_dgettext' collect2: ld returned 1 exit status make[3]: *** [gnome-open] Error 1 make[3]: Leaving directory `/var/tmp/portage/gnome-base/libgnome-2.22.0/work/libgnome-2.22.0/libgnome' make[2]: *** [all] Error 2 make[2]: Leaving directory `/var/tmp/portage/gnome-base/libgnome-2.22.0/work/libgnome-2.22.0/libgnome' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/var/tmp/portage/gnome-base/libgnome-2.22.0/work/libgnome-2.22.0' make: *** [all] Error 2
You need to recompile and reinstall glib and libgnome.
Sorry, libgnomevfs and not libgnome.
Created attachment 112432 [details] [review] add glib gettext API and only translate if a translation is available for the application using glib
Created attachment 112433 [details] [review] modify gtk to use new glib gettext api
Comment on attachment 112433 [details] [review] modify gtk to use new glib gettext api >@@ -839,22 +836,10 @@ > msg_ctxt_id = g_alloca (msgctxt_len + msgid_len); > > memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); >- msg_ctxt_id[msgctxt_len - 1] = '\004'; >+ msg_ctxt_id[msgctxt_len - 1] = '|'; > memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); > >- translation = dgettext (domain, msg_ctxt_id); >- >- if (translation == msg_ctxt_id) >- { >- /* try the old way of doing message contexts, too */ >- msg_ctxt_id[msgctxt_len - 1] = '|'; >- translation = dgettext (domain, msg_ctxt_id); >- >- if (translation == msg_ctxt_id) >- return msgid; >- } >- >- return translation; >+ return g_dpgettext (domain, msg_ctxt_id, 0); > } Why use the deprecated '|' convention here while one can use the \004 one?
I'm working on a fix without any warnings or new initialization API.
Created attachment 112449 [details] [review] glib patch Attaching my take on this. Should not have any of the problems raised with previous patches. If application calls textdomain after gtk_init, the it doesn't benefit from the feature in this bug and will continue working like before (no warning, no anything).
Created attachment 112450 [details] [review] gtk patch
Three questions/issues: 1) "char *e = _("default:LTR");" - Doesn't this bypass the should_translate check? This means that you should get an all english translation but ui rtl aligned. 2) There is still a bug that even if gtk_disable_setlocale() was called prior to gtk_init(), setlocale() is called from _g_dgettext_should_translate(). 3) I still feel that it is good to have a notification message when deciding not to use partial translations: g_message ("No translation is available for the requested locale.");
(In reply to comment #93) > Three questions/issues: > > 1) "char *e = _("default:LTR");" - Doesn't this bypass the should_translate > check? This means that you should get an all english translation but ui rtl > aligned. How? The underscore expands to g_dgettext(). I tested it and it works. > 2) There is still a bug that even if gtk_disable_setlocale() was called prior > to gtk_init(), setlocale() is called from _g_dgettext_should_translate(). No. The setlocale() there does not set any locales. It only gets the current value (second argument is NULL). > 3) I still feel that it is good to have a notification message when deciding > not > to use partial translations: g_message ("No translation is available for the > requested locale."); Who is that message intended for? There are a thousand other places that a notification message can be considered as useful.
Created attachment 112488 [details] [review] gtk patch Updated gtk patch. Old one was returning pointer to a string on the stack. Oops.
Comments on the glib patch: Looks generally fine to me. Please capitalize glib as GLib in docs. "the application who initialized glib i18n" is not 100% clear to me. What does it mean to initialize glib i18n ? Need to update the Since tag to 2.18 at this point
Comments on the gtk patch: Replacing all instances of dgettext() with g_dgettext() is fine I'm not sure I grok the initialization changes. Moving setlocale to post_parse_initialization will cause --help output to come out untranslated, no ?
(In reply to comment #97) > Comments on the gtk patch: > > Replacing all instances of dgettext() with g_dgettext() is fine > > I'm not sure I grok the initialization changes. Moving setlocale to > post_parse_initialization will cause --help output to come out untranslated, no > ? It was being called in do_pre_parse_initialization(). However that meant that these translations never worked: group = g_option_group_new ("gtk", _("GTK+ Options"), _("Show GTK+ Options"), info, g_free); I've moved it to be called from gettext_initialization() which is called from all main entry points (gtk_parse_args, gtk_init_with_args, gtk_get_option_group, and do_post_parse_initialization; the last one looks redundant to me).
1: Doesn't [d]ngettext need the same treatment? 2: + * - If locale starts with "en_", we can continue using the + * translations even if the app doesn't have translations for + * this locale. That is, en_UK and en_CA for example. ... + 0 != strncmp (translate_locale, "en_", 3) && a) This assumes that any i18n'd app is using native strings in the same language as gtk+ (i.e. en_US) which I don't think is a valid assumption. b) The same relationship as between en_{GB,US,CA,...} exists between many other classes of locales, e.g. pt{,BR} and de_{DE,AT,CH,BE} and fr_{FR,CA,BE,CH,...} etc. Why give en_* special treatment? E.g. an app could be natively pt and have a pt_BR translation but no other translations. In that case the glib/gtk/... messages should fall back either to pt[_BR] for consistency or to the user locale's domain, but certainly not english, I think... 3: I'm not convincend that the whole premise of this bug is right. I can get that it's a problem to mix writing directions in the same window, but why should e.g. the print dialogue and filechooser in an app be untranslated just because the app itself is not translated to the user's locale?
(In reply to comment #99) > 1: Doesn't [d]ngettext need the same treatment? Right. Adding g_dngettext. > 2: > + * - If locale starts with "en_", we can continue using the > + * translations even if the app doesn't have translations for > + * this locale. That is, en_UK and en_CA for example. > ... > + 0 != strncmp (translate_locale, "en_", 3) && > > a) This assumes that any i18n'd app is using native strings in the same > language as gtk+ (i.e. en_US) which I don't think is a valid assumption. How is this worse that what has been happening previously? > b) The same relationship as between en_{GB,US,CA,...} exists between many other > classes of locales, e.g. pt{,BR} and de_{DE,AT,CH,BE} and fr_{FR,CA,BE,CH,...} > etc. Why give en_* special treatment? Special treatment here because not all apps even need separate en_GB/CA translations. In that case they wont have any translations for those. We want to make sure GTK+ uses the translations still. > E.g. an app could be natively pt and have a pt_BR translation but no other > translations. In that case the glib/gtk/... messages should fall back either to > pt[_BR] for consistency or to the user locale's domain, but certainly not > english, I think... gettext already does such fallback IIRC. For example if I run: LANGUAGE=fa_XX gedit it uses the translations for "fa". > 3: I'm not convincend that the whole premise of this bug is right. I can get > that it's a problem to mix writing directions in the same window, but why > should e.g. the print dialogue and filechooser in an app be untranslated just > because the app itself is not translated to the user's locale? It's an improvement over the current setup and that's what matters IMO.
Created attachment 112581 [details] [review] updated glib patch Update docs to exactly say what g_dgettext() does. Add g_dngettext().
Created attachment 112582 [details] [review] updated gtk patch Same as before. Just uses g_dngettext in one block of commented code..
(In reply to comment #100) > > a) This assumes that any i18n'd app is using native strings in the same > > language as gtk+ (i.e. en_US) which I don't think is a valid assumption. > > How is this worse that what has been happening previously? I gave an example above in comment 99: App set up for i18n (calling textdomain()), with native strings in pt (ergo there's no pt.po file), locale pt_PT. This patch will make gtk not use its existing pt translation, resulting in a mixture of pt and en in the UI. Without the patch the whole UI is in pt.
(In reply to comment #103) > (In reply to comment #100) > > > a) This assumes that any i18n'd app is using native strings in the same > > > language as gtk+ (i.e. en_US) which I don't think is a valid assumption. > > > > How is this worse that what has been happening previously? > > I gave an example above in comment 99: App set up for i18n (calling > textdomain()), with native strings in pt (ergo there's no pt.po file), locale > pt_PT. This patch will make gtk not use its existing pt translation, resulting > in a mixture of pt and en in the UI. Without the patch the whole UI is in pt. In that case the app can call textdomain() after gtk_init(). I tried to accommodate all the corner cases but this one can't be handled easily. Since this is rather rare, I'd say that's fine. Alternatively I don't mind adding an env var to force the new behavior off.
Glib patch looks fine. Following the latest discussion, you might want to mention the cornercase of native strings in a language other than English in a footnote...
GTK+ patch is ok too. Just bump the glib requirement in configure.in...
2008-06-11 Behdad Esfahbod <behdad@gnome.org> Bug 503071 – Application direction changes to right to left even if theres no translation * glib/gi18n-lib.h: * glib/glib.symbols: * glib/gstrfuncs.h: * glib/gstrfuncs.c: Add new functions g_dgettext() and g_dngettext(). * glib/gutils.c (glib_gettext): * glib/gfileutils.c (g_format_size_for_display): * glib/goption.c (dgettext_swapped): Use the new functions.
2008-06-11 Behdad Esfahbod <behdad@gnome.org> Bug 503071 – Application direction changes to right to left even if theres no translation * configure.in: Bump glib requirement. * gtk/gtkaccellabel.c (_gtk_accel_label_class_get_accelerator_label): * gtk/gtkactiongroup.c (dgettext_swapped): * gtk/gtkbuilder.c (gtk_builder_class_init): * gtk/gtkbuilderparser.c (_dpgettext), (_gtk_builder_parser_translate): * gtk/gtkfilechooserdefault.c (list_size_data_func): * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems): * gtk/gtkintl.h: * gtk/gtkmain.c (setlocale_initialization), (do_pre_parse_initialization), (gettext_initialization): * gtk/gtkstock.c (gtk_stock_lookup), (sgettext_swapped): Use g_dgettext() and g_dngettext().