setlocal for Ukrainian language (Issue #23210)

813 views
Skip to first unread message

Oleksandra Yushchenko

unread,
Feb 2, 2023, 11:10:35 AM2/2/23
to wx-...@googlegroups.com, Subscribed

Description

From version 3.1.6 wxWidgets calls setlocation(0, wxInfoLanguage->LocaleTag), see (prusa3d@deef116#diff-7de25e9a71c4dce61bbf76492c589623d5b93fd1bb105ceaf0662075d15f4472),
where LocaleTag is a Tag of locale in BCP 47 - like notation.
For Ukrainian Language LocaleTag is "uk".
But setlocale(0, "uk") returns "English_United Kingdom.1252" instead of "uk",
and, as a result, locales are set to English_United Kingdom

We use such workaround in PS now. After initialization of the wxLocale, for Ukrainian we call setlocal one more time with GetCanonicalWithRegion() data.

if (language_info->CanonicalName == "uk")
         setlocale(0, language_info->GetCanonicalWithRegion().data());

But I suppose, that this issue have be resolved in wxWidgets internally

Platform and version information

  • wxWidgets version you use: 3.2.0
  • wxWidgets port you use: any
  • OS and its version: any


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23210@github.com>

VZ

unread,
Feb 2, 2023, 11:25:07 AM2/2/23
to wx-...@googlegroups.com, Subscribed

It would be really great if you could please provide an example of reproducing the problem because while I understand that the issue has something to do with the confusion between the language and country codes, I have no idea how to actually trigger it.

Please show some minimal code or, again, ideally a patch to the internat sample.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23210/1414015150@github.com>

VZ

unread,
Feb 7, 2023, 4:26:42 AM2/7/23
to wx-...@googlegroups.com, Subscribed

I can't reproduce the problem in the internat sample, e.g. here is what it shows under MSW:

[Window Title]

Internat Information



[Content]

Locale "uk_UA" is available.

Identifier: uk-UA; Layout: LTR

English name: Ukrainian (Ukraine)

Localized name: українська (Україна)



[OK]

Please explain what doesn't work exactly for you and, also whether the changes of #23226 change anything for you. TIA!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23210/1420455728@github.com>

Oleksandra Yushchenko

unread,
Feb 16, 2023, 7:10:48 AM2/16/23
to wx-...@googlegroups.com, Subscribed

I'm sorry to be late with the reply.

For the repro you can just use your "calendar" sample, but make a small change

MyApp::MyApp() :
    // Locale affects on the language used in the calendar, and may affect
    // on the first day of the week.
    m_locale(wxLANGUAGE_UKRAINIAN) //m_locale(wxLANGUAGE_DEFAULT)
{
} 
  1. Start "Calendar wxWidgets sample" application
  2. Select menu "Calendar" > "Use generic version"
  3. You coudn's see any effect, calendar is in English
    image

But if I set any other language, for example wxLANGUAGE_CZECH, than everything works as expected.
image

To see where is a problem, add next code:

diff --git a/src/common/intl.cpp b/src/common/intl.cpp
--- a/src/common/intl.cpp
+++ b/src/common/intl.cpp
@@ -128,6 +128,12 @@ const char* wxLanguageInfo::TrySetLocale() const
     {
         locale = LocaleTag;
         const char* const retloc = wxSetlocale(LC_ALL, locale);
+#if 1 // output to check the issue
+        wxString msg = wxString::Format("\nUnexpected locale is set in wxLocale::Init()\n"
+            "wxSetlocale(LC_ALL, %s) returns %s\n", LocaleTag, retloc);
+        if (retloc != locale)
+            wxLogLastError(msg);
+#endif
         if ( retloc )
             return retloc;

See:
image

But if use CanonicalRef instead of LocaleTag, then issue is gone.

diff --git a/src/common/intl.cpp b/src/common/intl.cpp
--- a/src/common/intl.cpp
+++ b/src/common/intl.cpp
@@ -126,8 +126,19 @@ const char* wxLanguageInfo::TrySetLocale() const
     // CRT (check by calling setlocale()).
     if ( wxGetWinVersion() >= wxWinVersion_Vista )
     {
+#if 1 // fix for the setLocal issue
+        locale = CanonicalRef;
+#else
         locale = LocaleTag;
+#endif
+
         const char* const retloc = wxSetlocale(LC_ALL, locale);
+#if 1 // output to check the issue
+        wxString msg = wxString::Format("\nUnexpected locale is set in wxLocale::Init()\n"
+            "wxSetlocale(LC_ALL, %s) returns %s\n", LocaleTag, retloc);
+        if (retloc != locale)
+            wxLogLastError(msg);
+#endif
         if ( retloc )
             return retloc;

See
image


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23210/1432985245@github.com>

Ulrich Telle

unread,
Feb 16, 2023, 7:00:44 PM2/16/23
to wx-...@googlegroups.com, Subscribed

From version 3.1.6 wxWidgets calls setlocation(0, wxInfoLanguage->LocaleTag), where LocaleTag is a Tag of locale in BCP 47 - like notation.

Right. And usually this works as expected.

For Ukrainian Language LocaleTag is "uk".

This is correct. And in principle, it is not necessary to specify a region tag in addition to the language tag.

But setlocale(0, "uk") returns "English_United Kingdom.1252" instead of "uk", and, as a result, locales are set to English_United Kingdom

Unfortunately, this is a flaw in the function setlocale (at least under Windows - I didn't check other platforms yet). The Microsoft Visual C++ documentation describes, which languages are supported by setlocale under the heading Language strings. The first paragraph references Appendix A: Product Behavior in [MS-LCID]: Windows Language Code Identifier (LCID) Reference, where all defined languages are listed in a long table. In that table you find 2 entries for Ukrainian:

  • uk for Ukrainian
  • uk-UA for Ukrainian in Ukraine

However, the first reference Language strings also contains a second paragraph, Supported language strings. This paragraph describes in a table which language strings the Microsoft C run-time library implementation also supports. Near the end of this table you find the language string uk and the equivalent locale name en-GB.

Obviously setlocale prefers the latter mapping from language string to locale name. And that explains the misbehaviour. Actually, only Ukrainian is affected by this flaw.

Interestingly, method wxLocale::Init(int lang, int flags) uses info->GetCanonicalWithRegion() to determine the short name of the locale (for uk this corresponds to uk-UA), but the Windows implementation of method wxLanguageInfo::TrySetLocale() uses locale = LocaleTag (instead of locale = GetCanonicalWithRegion()).

BTW, the implementation of method wxLanguageInfo::TrySetLocale() for non-Windows platforms does use GetCanonicalWithRegion()).

Conclusion: The Windows implementation of method wxLanguageInfo::TrySetLocale() should be changed to use GetCanonicalWithRegion()) as well.

For the time being, you may use the language identifier wxLANGUAGE_UKRAINIAN_UKRAINE instead of wxLANGUAGE_UKRAINIAN as a workaround to get the expected results.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23210/1433903537@github.com>

VZ

unread,
Feb 20, 2023, 12:34:10 PM2/20/23
to wx-...@googlegroups.com, Subscribed

Closed #23210 as completed via a0be352.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/23210/issue_event/8563922804@github.com>

Reply all
Reply to author
Forward
0 new messages