feat(i18n): add Turkish locale, plus four Linux/asset fixes - #802
Conversation
Greptile SummaryAdds Turkish localization and fixes reported issues across device assets, Linux application launching and packaging, updater behavior, gesture handling, battery diagnostics, and action icons.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the previously reported depot-variant synchronization issue is fixed by retaining separate targets for each extended model ID.
|
| Filename | Overview |
|---|---|
| crates/openlogi-desktop/src/services/assets/sync.rs | Synchronizes manifest-selected metadata and preserves separate variants by deduplicating on depot plus extended model ID. |
| crates/openlogi-desktop/src/services/assets.rs | Resolves variant metadata through depot manifests before falling back to standard metadata filenames. |
| crates/openlogi-desktop/src/platform/updater.rs | Gates update checks and automatic installation on platforms that publish supported in-app update artifacts. |
| crates/openlogi-inject/src/inject/linux.rs | Distinguishes executable application targets from resources that should remain delegated to the desktop opener. |
| crates/openlogi-ui/src/locale.rs | Registers Turkish and includes its catalog in locale parity validation. |
| packaging/linux/package.nix | Packages the standard hicolor icon-size set and verifies installed resources. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Registry[Asset registry] --> Targets[Device targets]
Targets --> Key["Deduplicate by depot + variant"]
Key --> Manifest[Resolve manifest resources]
Manifest --> Bundle[Bundled assets]
Manifest --> Cache[User asset cache]
Bundle --> Resolver[Desktop asset resolver]
Cache --> Resolver
Resolver --> UI[Device artwork and hotspots]
Reviews (3): Last reviewed commit: "fix(gui): key the sync's depot dedup on ..." | Re-trigger Greptile
Ships `locales/tr.yml` with every key `en.yml` defines, registers `tr`
("Türkçe") in `SUPPORTED` between Svenska and Ελληνικά — native-name
alphabetical within the Latin block — and adds it to the parity test's
`include_str!` table so the catalog is actually checked rather than
silently drifting.
`crowdin.yml` gains the language and its `tr -> tr` mapping so Crowdin
round-trips the new catalog like every other one.
`load_files` accepted a depot only when it carried one of the three hardcoded `METADATA_FILES` names. Depots whose variants are handed rather than coloured ship none of them: the Lift keys its hotspot metadata `core_metadata_left.json` / `core_metadata_right.json` and names the right one in the manifest's `image_metadata` resource. The name lookup missed, `resolve` returned `None` for every root, and every Lift and Lift for Business rendered the generic silhouette with a complete bundle on disk. Resolve the metadata filename through the manifest first — same model-id candidates as the image lookup, since a manifest is keyed on whichever pid Logi authored it against — then fall back to the well-known names for bundles without a manifest. Manifest-sourced names now pass through `safe_component_path` like every other asset file. The download side has to follow, or the resolver looks for a file no sync ever fetched: the desktop sync adds `image_metadata` to its manifest-mapped resource pass (and consults every model-id candidate there too), and the CLI bundle treats `core_metadata_*.json` / `metadata_*.json` as optional assets so an offline bundle carries the variant metadata. Fixes AprilNEA#782
The packages installed `openlogi.png` only under `/usr/share/icons/hicolor/1024x1024/apps`. A stock `hicolor/index.theme` stops at 512x512, so launchers that resolve icons through the theme index — KDE's kbuildsycoca, and the GTK icon cache — found nothing and showed the generic placeholder. Pre-render 512 down to 16 alongside the 1024 master and install all of them from nfpm, the Nix derivation, and `install.sh`; `uninstall.sh` and the Nix install check cover the same set. The derivation's fileset takes `design/icon` as a directory so a future size needs no second edit. Fixes AprilNEA#797 Fixes AprilNEA#766
A Linux release publishes distro packages only — `.deb`, `.rpm`, `.pkg.tar.zst` — and `xtask release latest-json` deliberately classifies none of them into the update manifest, because those installs update through the package manager. The GUI asked anyway, so every Linux user who opened Settings → Updates and clicked Check got a red "Update failed: no release asset matched the current platform (linux/x86_64)". Gate the updater on a single `IN_APP_UPDATES` const: the launch check, the auto-install observer, and the menu action skip the check where a release carries no in-place-updatable artifact, and the Updates page shows the running version plus where updates come from instead of a check button and two switches that cannot do anything. macOS and Windows are unchanged. The new string is added to all 22 catalogs at the same position. Fixes AprilNEA#769
`Action::OpenApplication` handed its target straight to `opener::open`, which on Linux is `xdg-open` — and xdg-open *opens* a file. Given `/usr/bin/nautilus` it looks for a handler claiming `application/x-executable`, finds none, and does nothing at all, so the Actions Ring slot appeared dead. On Linux, classify the target first: an executable file path or a bare command name resolved on `PATH` is spawned as a program; URLs, folders, documents, and `.desktop` entries stay with the opener — a desktop entry especially, since xdg-open reads its `Exec=` and honours `Terminal=` and `StartupNotify=`, none of which spawning the file would. macOS and Windows keep going through the opener, where `open`/`ShellExecute` already run `.app` bundles and `.exe`s. The child is waited on from a detached thread so a long-lived app does not sit as a zombie for the agent's lifetime. The decision table takes its two filesystem probes as parameters, so it is tested with fakes; one further test pins the real probes against `sh` on `PATH`. Fixes AprilNEA#775
`sync` collected one target per connected device, each carrying the HID++ `extended_model_id` its manifest-mapped resources are keyed on, then deduplicated the list on the depot alone. Two devices sharing a depot but differing in that byte — a colour pair, or the Lift's left- and right-handed variants — collapsed to one target, so `sync_depot` never saw the second and its `device_image` / `device_buttons_image` / `image_metadata` were never fetched. That device stayed on fallback artwork with no hotspot metadata. Deduplicate on `(depot, ext)` instead. The baseline files the extra pass re-requests are cache hits, so the cost is one manifest read per variant. The collection step moves into its own function so the decision is testable without the surrounding HTTP: `two_variants_of_one_depot_are_both_synced` fails on the old key, and `the_same_variant_twice_is_synced_once` pins that repeated snapshots of one device still collapse.
11bff08 to
78609e8
Compare
|
Thanks for putting this together. The individual changes look useful, but could you please split this into focused PRs before we continue the review? Suggested split:
The manifest metadata lookup and the Keeping the commits separate helps, but it does not remove the PR-level coupling: these changes span localization, device assets, packaging, the updater, and input injection, with different review and verification requirements. Several touched files also overlap active PRs such as Separate PRs would let us review, test, and merge each change independently. Please keep each |
|
Agreed — split as suggested. Closing this in favour of five independent PRs:
Each branches off current Kept together as you asked: the manifest metadata lookup and the sync dedup are One ordering note, since it is the only remaining coupling: #838 adds a string to On the Greptile finding from this PR: the depot dedup keyed on the depot alone Also dropped along the way: this branch originally carried fixes for #770, #752 |
Summary
Adds the Turkish interface locale and fixes four reported bugs, none of which
has an open PR already. Every commit is self-contained and conventional, so this
can be rebase-merged; squashing would collapse unrelated fixes into one
subject. Happy to split it per issue if you would rather review them separately.
An earlier revision of this branch also carried fixes for #770, #752 and #688.
Those were dropped once I found #790, #765 / #719 and #741 already open for them
— no point in a second implementation of work someone else is waiting on.
Changes
openlogi-uilocales/tr.ymlcarrying every keyen.ymldefines.tr("Türkçe") isregistered in
SUPPORTEDbetween Svenska and Ελληνικά — native-namealphabetical within the Latin block — and added to the parity test's
include_str!table, so the catalog is actually checked rather than silentlydrifting.
crowdin.ymlgains the language and itstr -> trmapping.openlogi-desktopimage_metadatabeforethe well-known
METADATA_FILESnames. Depots whose variants are handedrather than coloured ship none of those names — the Lift keys its metadata
core_metadata_left.json/core_metadata_right.json— so the lookup missed,resolvereturnedNonefor every root, and every Lift rendered the genericsilhouette with a complete bundle on disk. Manifest-sourced names go through
safe_component_pathlike every other asset file, and the download side addsimage_metadatato its manifest-mapped resource pass (consulting everymodel-id candidate there too, as the resolver already did).
(depot, ext)rather than the depotalone. Two devices sharing a depot but differing in
extended_model_id— acolour pair, or the Lift's left- and right-handed variants — collapsed to one
target, so the second never had its
device_image/device_buttons_image/image_metadatafetched and stayed on fallbackartwork with no hotspot metadata. That also undid the fix above for the
dropped device. The collection step moved into its own function so the
decision is testable without the surrounding HTTP. (Found by the Greptile
review on this PR.)
IN_APP_UPDATESgates the updater. A Linux release publishes distro packagesonly and
xtask release latest-jsondeliberately classifies none of them intothe manifest, but the GUI asked anyway, so Settings → Updates answered
"Update failed: no release asset matched the current platform (linux/x86_64)".
The launch check, the auto-install observer and the menu action now skip it,
and the page shows the running version plus where updates come from. macOS and
Windows are unchanged.
openlogi-cliassets syncbundlescore_metadata_*.json/metadata_*.jsonas optionalassets, or the resolver above would look for a file no sync ever fetched.
openlogi-injectexecutable path or a bare command name on
PATHis spawned; URLs, folders,documents and
.desktopentries stay with the opener.xdg-openopens afile — handed
/usr/bin/nautilusit looks for a handler claimingapplication/x-executable, finds none, and does nothing, so the ring slotlooked dead. Desktop entries deliberately stay with xdg-open, which reads
their
Exec=and honoursTerminal=/StartupNotify=. The child is waitedon from a detached thread so a long-lived app is not left a zombie. macOS and
Windows keep going through the opener, where
open/ShellExecutealreadyrun
.appbundles and.exes.packaging
1024x1024. A stockhicolor/index.themestops at 512x512, so launchers thatresolve through the theme index found nothing. 512 down to 16 are pre-rendered
beside the master and installed from nfpm, the Nix derivation and
install.sh;uninstall.shand the Nix install check cover the same set, andthe derivation's fileset takes
design/iconas a directory so a future sizeneeds no second edit.
No wire types changed, so
PROTOCOL_VERSIONis untouched.Testing
Run on the final rebased tree (Linux, x86_64, Rust 1.98.0):
All green. New regression tests:
resolves_depot_whose_metadata_is_only_named_by_the_manifest,two_variants_of_one_depot_are_both_synced,the_same_variant_twice_is_synced_once,executables_are_run_and_everything_else_goes_to_the_opener,an_executable_desktop_entry_still_goes_to_the_opener,the_real_probes_resolve_a_shell_on_path.The two sync tests were checked against the old key: the first fails on it, so
it pins the defect rather than the implementation.
Not run on this host — please treat as unverified:
shell(shellcheck / shfmt not installed). The two shell diffs were reviewedby hand and pass
bash -n; both loops are 2-space indented with everyexpansion quoted.
tests (macos),cargo-deny.covers the non-Linux side of the one
#[cfg(target_os = "linux")]statementadded to
openlogi-inject.Not runtime-tested on hardware. No Logitech device was attached, so none of
these were confirmed against a real mouse. How to check each:
the silhouette, with no
core_metadata.jsoncopy in the depot. With two Liftsof different handedness connected, both should render.
launcher (
pacman -Ql openlogi | grep -i iconshould list several sizes).manager rather than offer a check.
/usr/bin/nautilus(and barenautilus) in an Actions Ringslot; both should launch the file manager.
Fixes #782
Fixes #797
Fixes #766
Fixes #769
Fixes #775