Skip to content

Add Farsi localization, RTL flow-direction sync, and fix language-pack save bug - #110

Open
codesbygom wants to merge 14 commits into
hbashton:mainfrom
codesbygom:main
Open

codesbygom wants to merge 14 commits into
hbashton:mainfrom
codesbygom:main

Conversation

@codesbygom

Copy link
Copy Markdown

Summary

  • Port Farsi (fa) translation (Strings.fa.resx) from the codesbygom DS4Windows fork.
  • Port the content-only RTL flow-direction sync (App.xaml / App.xaml.cs, LanguagePackControl, UpdaterWindow, WelcomeDialog) from the same fork, so RTL languages mirror window content without mirroring native window chrome, images, or English-only text blocks.
  • Fix a bug in LanguagePackViewModel.ChangeLanguagePack(): Global.Save() was commented out, so a new language-pack selection only ever lived in memory. The "restart required" prompt fired, but the saved config still had the old UseLang, so the app came back up in the previous language every time — selecting a non-English language pack never actually stuck across a restart.

Test plan

  • Build the WPF app and confirm switching Language Pack to a non-English language (e.g. Farsi or Arabic) persists after restart.
  • Confirm RTL languages mirror window content correctly while window chrome/images/English captions stay LTR.

arash added 3 commits September 16, 2026 13:21
Port Strings.fa.resx and the content-only FlowDirection sync
(App.xaml/App.xaml.cs, LanguagePackControl, UpdaterWindow,
WelcomeDialog) from the codesbygom DS4Windows fork.
Global.Save() was commented out in ChangeLanguagePack(), so a new
language selection only lived in memory: the "restart required"
prompt fired, but the saved config still had the old UseLang, so
the app came back up in the previous language every time.
Twelve panels (About, ControllerOverview, AudioHaptics, ViiperSetupPrompt/
Progress, MappingLiveInput, TriggerLab, SwipeProfilesEditor,
Switch2StickCalibration, LogMessageDisplay, StickCalibration,
TouchButtonUserControl) had zero WPFLocalizeExtension bindings, so their
text stayed English regardless of the selected language pack. Wired all of
them to {lex:Loc}/Properties.Resources, keeping license text, proper nouns,
usernames, URLs, and unit suffixes (ms, Hz) untranslated as appropriate.

Also:
- Added the 4 keys missing from Strings.fa.resx and translated 2 tooltips
  that were copied verbatim from English.
- Created Properties/Resources.fa.resx (the legacy resx family used by
  ~200 Properties.Resources.* call sites) and uncommented
  DS4WinWPF.Properties.Resources.Culture = ci; in SetUICulture, which was
  never actually switching that resource family's culture.
- Registered Strings.fa.resx and Resources.fa.resx in the csproj
  (DependentUpon metadata) to match the other language entries.
- Fixed a latent bug in TriggerLabControl's MakeMeter: the slider's
  internal property key ("Start"/"Wall"/"Force") was reused as the
  display label, so localizing the label would have silently broken
  meter updates. Split them into separate parameters.

Net: 170 new Strings.resx/Strings.fa.resx keys, 156 new
Properties/Resources.resx/Resources.fa.resx keys, all translated.
arash added 11 commits September 17, 2026 12:10
Resources.resx was edited directly (not through Visual Studio's
designer), so the PublicResXFileCodeGenerator custom tool never ran
and Resources.Designer.cs still only exposed the pre-existing string
properties. Every Properties.Resources.* call site added for the
localization work failed with CS0117 as a result. Added the missing
156 properties by hand, matching the generator's existing pattern.
Replaces all 644 hardcoded Text/Content/Header/ToolTip attributes in
ProfileEditor.xaml with {lex:Loc} bindings, adding 406 new resx keys
(reusing 30 existing ones for identical text) to Strings.resx and
translating each into Farsi, Arabic, and Hebrew.

Renamed the auto-generated "Deadzone" key to "AimDeadzone" after the
build revealed it case-insensitively collided with the pre-existing
"DeadZone" resource, which MSBuild silently drops on conflict.
Manually reconciled with the ProfileEditor.xaml localization pass instead
of a plain merge: both passes independently added same-named keys for
shared controller terms (Cross/Circle/Square/Triangle, SideL/SideR, Mute,
etc). Kept the ProfileEditor pass's values for those (it established the
convention of leaving symbol names like Cross/Circle/Square/Triangle
untranslated) and added BindingWindow's 74 genuinely new keys on top.

Also fixed a case-mismatch bug from the BindingWindow pass: it referenced
{lex:Loc Multitouch} while the resx key is MultiTouch. WPFLocalizeExtension
resource lookups are case-sensitive, so this would have silently failed to
resolve at runtime; corrected to MultiTouch.
Manually reconciled with the resx state left by the ProfileEditor.xaml
and BindingWindow.xaml passes (union-merged the added keys rather than
a plain git merge, since the branch was created before those landed
on main and a straight merge produced conflicting hunks).
….ar/he.resx from PR hbashton#113

Strings.ar.resx's NoControllersConnected had two opening parens and no
closing paren ("(لا توجد أيادي تحكم متصلة (الأقصى {0}") from a prior
manual attempt to "fix" RTL rendering by hand-reversing bracket
characters — Unicode bidi already mirrors ASCII parens automatically in
RTL runs, so the fix is to write them in normal logical order.

Also cherry-picked Resources.ar.resx and Resources.he.resx from
feature/arabic-hebrew-localization (PR hbashton#113): those satellite resource
files only existed on that branch, so dialogs reading from
Properties.Resources (VIIPER setup prompts, etc.) fell back to English
even when the app's UI culture was set to Arabic or Hebrew. Confirmed
both files only provide translated values for keys already present in
the base Resources.resx (no new keys), so no Resources.Designer.cs
changes were needed.
…nslations

Strings.ar.resx and Strings.he.resx were missing 510 keys each versus
the English base (and versus Strings.fa.resx, which had full coverage) —
every key that PR hbashton#110 wired into panels' {lex:Loc} bindings but that
predated PR hbashton#113's Arabic/Hebrew work landing on a separate branch.
Since that fell back to English at runtime, most of the app still
displayed English text even with the UI culture set to Arabic or
Hebrew, despite those languages otherwise being "supported".

Union-merged feature/arabic-hebrew-localization's translations for
those 510 keys into both files. Only one collision (both branches
independently had the same broken-parenthesis NoControllersConnected
string, already fixed on main) — every other key was additive.
These two nav/tab titles were deliberately left as literal English by
an earlier pass, treating them like brand names (DualSense, Xbox).
Translated instead, using terminology already established elsewhere
in each resx file for consistency: "Trigger" = ماشه (fa) / الضغط (ar) /
טריגר (ar loanword, ar... actually he) already used in Trigger-prefixed
keys, and "Haptics" matches the existing האפ../הפטיקה (he) and
هپتیک (fa) wording used in nearby AudioHaptics.* strings.
Localizes the modern shell (BridgeShellStyles), controller readings panel,
special action editor, controller registration options, auto-profiles rules
panel, plugin output device picker, about dialog, live mapping preview,
welcome dialog, record box, and preset picker. Reuses existing resx keys
where the exact English text already had one (e.g. product/controller
names, Yes/No, Axis Config, Trigger Lab), adds new keys only for text with
no existing match, and backfills two orphaned keys (Finished,
PresetOptWin.WinTitle) that already existed in Strings.fa.resx but were
missing from the English/Arabic/Hebrew files. Every new key gets real
Persian, Arabic, and Hebrew translations alongside English in the same
commit. Controller/trigger button codes (L2, R2) and other established
non-translated abbreviations are left as-is to match existing convention
elsewhere in the codebase.

Also fixes MappingLiveInputControl.xaml.cs, which was overwriting the
newly-localized axis placeholder text with a hardcoded English literal at
runtime.
…ow.xaml

Pre-existing bug (not introduced by this session's localization pass) that
silently blanked the preset-selection dialog's intro text in every language,
since WPFLocalizeExtension resource lookups are case-sensitive.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant