[education/rkward] rkward/rbackend: Handle runtime backend language changes
Thomas Friedrichsmeier
null at kde.org
Thu Oct 16 20:57:56 BST 2025
Git commit 550c9b7138683efc65e011ec8797b9fa07efd702 by Thomas Friedrichsmeier.
Committed on 14/10/2025 at 16:13.
Pushed by tfry into branch 'master'.
Handle runtime backend language changes
M +27 -1 rkward/rbackend/rkrbackend.cpp
M +2 -4 rkward/rbackend/rpackages/rkward/R/base_overrides.R
https://invent.kde.org/education/rkward/-/commit/550c9b7138683efc65e011ec8797b9fa07efd702
diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index d77b19369..805d2d381 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -885,6 +885,32 @@ QString getLibLoc() {
return RKRBackendProtocolBackend::dataDir() + u"/.rkward_packages/"_s + QString::number(RKRBackend::this_pointer->r_version / 10);
}
+/* Check whether we still want to translate to the same language as last time.
+ * Calling this on every single i18n-call is silly, but not a real world performance problem
+ * (as translated strings imply user interaction). The underlying problem is that we have not
+ * good way of detecting, when R might switch the language. (Typical entry points include
+ * switchLanguage(), Sys.setenv(LANGUAGE=), Sys.setlocale("LC_MESSAGES")) */
+void checkCurrentLanguage() {
+ static QByteArray previous_locale;
+
+ // R's language always corresponds to LANGUAGE env-var, if set, but, on Unix falls back to
+ // LC_MESSAGES, if LANGUAGE is not set.
+ QByteArray current_locale = qgetenv("LANGUAGE");
+#if !defined(Q_OS_WIN)
+ if (current_locale.isEmpty()) current_locale = setlocale(LC_MESSAGES, nullptr);
+#endif
+ if (current_locale != previous_locale) {
+ previous_locale = current_locale;
+ KLocalizedString::clearLanguages();
+ auto langs = QString::fromUtf8(current_locale).split(u':');
+ for (int i = 0; i < langs.length(); ++i) {
+ langs[i] = langs[i].section(u'.', 0, 0).section(u'_', 0, 0);
+ }
+ //RFn::Rf_warning("%s->%s", qPrintable(QString::fromUtf8(lang)), qPrintable(langs.join(u',')));
+ KLocalizedString::setLanguages(langs);
+ }
+}
+
// Function to handle several simple calls from R code, that do not need any special arguments, or interaction with the frontend process.
SEXP doSimpleBackendCall(SEXP _call) {
RK_TRACE(RBACKEND);
@@ -893,6 +919,7 @@ SEXP doSimpleBackendCall(SEXP _call) {
QString call = list[0];
if (call == QStringLiteral("i18n")) {
+ checkCurrentLanguage();
auto msg = ki18n(list.value(1).toUtf8().constData());
for (int i = 2; i < list.length(); ++i) {
msg = msg.subs(list[i]);
@@ -939,7 +966,6 @@ SEXP doUpdateLocale() {
RK_TRACE(RBACKEND);
RK_DEBUG(RBACKEND, DL_WARNING, "Changing locale");
- // TODO: properly handle re-initialization of translation, too!
RKTextCodec::reinit();
return ROb(R_NilValue);
diff --git a/rkward/rbackend/rpackages/rkward/R/base_overrides.R b/rkward/rbackend/rpackages/rkward/R/base_overrides.R
index 1fa7ca47e..7dd6ba35a 100644
--- a/rkward/rbackend/rpackages/rkward/R/base_overrides.R
+++ b/rkward/rbackend/rpackages/rkward/R/base_overrides.R
@@ -87,11 +87,9 @@
#' @export
#' @rdname base_overrides
"Sys.setlocale" <- function (category = "LC_ALL", locale = "", ...) {
- if (category == "LC_ALL" || category == "LC_CTYPE" || category == "LANG") {
- .rk.call("preLocaleChange")
-
+ if (category %in% c("LC_ALL", "LC_CTYPE", "LANG")) {
+ .rk.call("preLocaleChange")
ret <- base::Sys.setlocale (category, locale, ...)
-
.Call ("rk.update.locale", PACKAGE="(embedding)")
ret
} else {
More information about the rkward-tracker
mailing list