diff --git a/.gitignore b/.gitignore index c51ce806..83d399dc 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,8 @@ AGENTS.md *.log +# Compiled gettext catalogs — build artifacts, generated into OUT_DIR by rog-control-center/build.rs +/rog-control-center/translations/*/LC_MESSAGES/*.mo + # Git should not follow this IN ANY CASE Cargo.lock diff --git a/Makefile b/Makefile index 96eea57f..d1c825bd 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ LEDCFG := aura_support.ron DESTDIR_REALPATH := $(if $(DESTDIR),$(shell realpath $(DESTDIR)),) -SRC := Cargo.toml Makefile $(shell find -type f -wholename '**/src/*.rs') +SRC := Cargo.toml Makefile $(wildcard */build.rs) $(shell find -type f -wholename '**/src/*.rs') $(shell find rog-control-center/translations) STRIP_BINARIES ?= 0 @@ -96,11 +96,17 @@ install-rog_gui: target/$(TARGET)/$(BIN_ROG) install-program: install-asusd install-asus-shutdown install-asusctl install-asusd_user install-rog_gui -install-data-rog_gui: +install-data-rog_gui: target/$(TARGET)/$(BIN_ROG) $(INSTALL_DATA) "./rog-control-center/data/$(APP_ID).desktop" "$(DESTDIR)$(datarootdir)/applications/$(APP_ID).desktop" $(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png" $(INSTALL_DATA) "./rog-control-center/data/$(APP_ID).metainfo.xml" "$(DESTDIR)$(datarootdir)/metainfo/$(APP_ID).metainfo.xml" cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/rog-gui/layouts/{}" \; + set -- $$(ls -t target/$(TARGET)/build/$(BIN_ROG)-*/out/translations/*/LC_MESSAGES/$(BIN_ROG).mo 2>/dev/null); \ + if [ $$# -eq 0 ]; then \ + echo "no compiled translations found, skipping locale install" >&2; \ + else \ + cd "$${1%/*/*/*}" && find . -type f -name "$(BIN_ROG).mo" -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/locale/{}" \; ; \ + fi $(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png" $(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png" @@ -139,6 +145,7 @@ uninstall: rm -f "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop" rm -f "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png" rm -f "$(DESTDIR)$(datarootdir)/metainfo/$(APP_ID).metainfo.xml" + rm -f "$(DESTDIR)$(datarootdir)"/locale/*/LC_MESSAGES/$(BIN_ROG).mo rm -f "$(DESTDIR)$(bindir)/$(BIN_C)" rm -f "$(DESTDIR)$(bindir)/$(BIN_D)" diff --git a/distro-packaging/PKGBUILD b/distro-packaging/PKGBUILD index 266dec47..8d559333 100644 --- a/distro-packaging/PKGBUILD +++ b/distro-packaging/PKGBUILD @@ -9,7 +9,7 @@ url="https://github.com/OpenGamingCollective/asusctl" license=('MPL-2.0') depends=('libusb' 'udev') optdepends=() -makedepends=('git' 'rust' 'llvm' 'clang' 'at-spi2-core' 'cairo' 'gtk3') +makedepends=('git' 'rust' 'llvm' 'clang' 'at-spi2-core' 'cairo' 'gtk3' 'gettext') provides=() conflicts=('asusctl-git' 'tlp') @@ -51,6 +51,7 @@ _package-asusctl() { rm -rf "$pkgdir"/usr/share/icons rm -rf "$pkgdir"/usr/share/applications rm -rf "$pkgdir"/usr/share/metainfo + rm -rf "$pkgdir"/usr/share/locale } _package-rog-control-center() { diff --git a/rog-control-center/README.md b/rog-control-center/README.md index 4804c6a3..39fde654 100644 --- a/rog-control-center/README.md +++ b/rog-control-center/README.md @@ -10,6 +10,6 @@ You can help with translations by following https://slint.dev/releases/1.1.0/doc Begin by copying `rog-control-center/translations/en/rog-control-center.po` to `rog-control-center/translations//rog-control-center.po`, then edit that file. -Run `msgfmt rog-control-center/translations//rog-control-center.po -o rog-control-center/translations//LC_MESSAGES/rog-control-center.mo` to make the binary formatted translation where `` is changed to your translation locale. +The binary catalogs are compiled from the `.po` sources at build time, so rebuild to pick up your edits. This needs `msgfmt` from gettext installed. To test you local translations run `RUST_TRANSLATIONS=1 rog-control-center`. diff --git a/rog-control-center/build.rs b/rog-control-center/build.rs index 8887c316..4e283ed5 100644 --- a/rog-control-center/build.rs +++ b/rog-control-center/build.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use slint_build::CompilerConfiguration; fn main() -> Result<(), Box> { - // write_locales(); + compile_locales()?; let root = env!("CARGO_MANIFEST_DIR"); let mut main = PathBuf::from(root); main.push("ui/main_window.slint"); @@ -21,3 +21,52 @@ fn main() -> Result<(), Box> { )?; Ok(()) } + +/// Compile the .po sources into gettext catalogs under `OUT_DIR`, and export +/// that location as `ROGCC_TRANSLATIONS_DIR` for the runtime to load from. +fn compile_locales() -> Result<(), Box> { + let sources = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("translations"); + let out = PathBuf::from(std::env::var("OUT_DIR")?).join("translations"); + + println!("cargo:rustc-env=ROGCC_TRANSLATIONS_DIR={}/", out.display()); + // Catches locales being added or removed, not just edited + println!("cargo:rerun-if-changed={}", sources.display()); + + std::fs::create_dir_all(&out)?; + + let mut compiled = Vec::new(); + for entry in std::fs::read_dir(&sources)? { + let entry = entry?; + let po = entry.path().join("rog-control-center.po"); + // `en` is the extraction template and every msgstr is empty in it + if entry.file_name() == "en" || !po.exists() { + continue; + } + println!("cargo:rerun-if-changed={}", po.display()); + + let dir = out.join(entry.file_name()).join("LC_MESSAGES"); + std::fs::create_dir_all(&dir)?; + let mo = dir.join("rog-control-center.mo"); + + let status = std::process::Command::new("msgfmt") + .arg("-o") + .arg(&mo) + .arg(&po) + .status() + .map_err(|e| format!("could not run msgfmt, is gettext installed? ({e})"))?; + if !status.success() { + return Err(format!("msgfmt failed for {} ({status})", po.display()).into()); + } + compiled.push(entry.file_name()); + } + + // Cargo never clears OUT_DIR, so catalogs of removed locales would linger + // and still be picked up by the install step + for entry in std::fs::read_dir(&out)? { + let entry = entry?; + if !compiled.contains(&entry.file_name()) { + std::fs::remove_dir_all(entry.path())?; + } + } + Ok(()) +} diff --git a/rog-control-center/src/main.rs b/rog-control-center/src/main.rs index b4f11946..814b6bc1 100644 --- a/rog-control-center/src/main.rs +++ b/rog-control-center/src/main.rs @@ -187,10 +187,10 @@ async fn main() -> Result<()> { if std::env::var("RUST_TRANSLATIONS").is_ok() { // don't care about content log::debug!("---- Using local-dir translations"); - slint::init_translations!("/usr/share/locale/"); + slint::init_translations!(env!("ROGCC_TRANSLATIONS_DIR")); } else { log::debug!("Using system installed translations"); - slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/translations/")); + slint::init_translations!("/usr/share/locale/"); } // Prefetch supported Aura modes once at startup and move into the diff --git a/rog-control-center/translations/az/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/az/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index 612944aa..00000000 Binary files a/rog-control-center/translations/az/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/en/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/en/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index a24bf450..00000000 Binary files a/rog-control-center/translations/en/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/fr/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/fr/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index 31c52e22..00000000 Binary files a/rog-control-center/translations/fr/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/it/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/it/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index 3d9736ad..00000000 Binary files a/rog-control-center/translations/it/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/pt_BR/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/pt_BR/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index b16ace05..00000000 Binary files a/rog-control-center/translations/pt_BR/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/ru/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/ru/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index 34765733..00000000 Binary files a/rog-control-center/translations/ru/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/tr/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/tr/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index ad28b73a..00000000 Binary files a/rog-control-center/translations/tr/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/uk_UA/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/uk_UA/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index aae151c4..00000000 Binary files a/rog-control-center/translations/uk_UA/LC_MESSAGES/rog-control-center.mo and /dev/null differ diff --git a/rog-control-center/translations/zh_CN/LC_MESSAGES/rog-control-center.mo b/rog-control-center/translations/zh_CN/LC_MESSAGES/rog-control-center.mo deleted file mode 100644 index 4f53eae7..00000000 Binary files a/rog-control-center/translations/zh_CN/LC_MESSAGES/rog-control-center.mo and /dev/null differ