You are not logged in.
Some desktop setups do not provide a way to choose your user language environment (locale) on login. Of course you can manually edit ~/.xsessionrc for example to add
export LANG=ja_JP.UTF-8
export LANGUAGE=ja_JP:ja
or whatever, but sometimes a user wants to switch between different languages, when manual editing gets annoying.
It's fine if the login interface provides a language-chooser (don't forget to generate the locales you want to have available with sudo dpkg-reconfigure locales) but slick-greeter, for example, does not. I guess s-g expects everyone to use the Ubuntu package gnome-language-selector but that's not available in Debian. This script attempts to provide an alternative: it lists the enabled locales, let's you choose one and writes the result to ~/.dmrc and also sends it to accountsservice, if that is installed. The user does have to log out and back in to see the change, though.
It's still a work in progress. It should work OK on BunsenLabs systems because we already have a fix in place for LightDM's shortcomings with language setting, but it would be nice if eg MATE (no language chooser I can find) users could use it too. atm I'm still not sure of the best way to set LANGUAGE...
Anyway:
#!/bin/bash
# setlocale.sh
# A script to allow users to set their locale from those which have been enabled,
# writing to ~/.dmrc, also to accountsservice, if available.
# TODO
# Sometimes LANGUAGE is not updated to match LANG.
# BunsenLabs ships a fix for this when LightDM is being used,
# but something more generic would be nice.
dm_file="$HOME/.dmrc"
[[ -e "$dm_file" ]] || touch "$dm_file"
yad_info(){
yad --window-icon=distributor-logo-bunsenlabs --center --borders=20 --undecorated --fixed --on-top --button=OK:0 --text "$*"
}
error_exit() {
yad_info "$0 error:"$'\n'"$*"
exit 1
}
parse_dmrc() {
current_lang=$(sed -nr 's/^Language=([^[:blank:]]+).*$/\1/p' "$dm_file")
}
# pass locale (LANG) to be written
write_dmrc() {
sed -i '/[Ll]anguage=/d' "$dm_file"
echo "Language=$1" >> "$dm_file"
}
# pass same locale as for write_dmrc
write_accountsservice() {
pgrep -x 'accounts-daemon' >/dev/null || {
echo "${0}: accounts-daemon is not running, accountsservice language will not be updated." >&2
return 1
}
local lang=${1/utf8/UTF-8}
# put returned path in array to strip leading & trailing spaces
local user_path=($(dbus-send --print-reply=literal --system --dest=org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts.FindUserByName string:"$USER")) || error_exit "error finding ${USER}'s accountsservice path"
dbus-send --system --dest=org.freedesktop.Accounts "${user_path[0]}" org.freedesktop.Accounts.User.SetLanguage string:"$lang" || error_exit "error setting ${USER}'s language in accountsservice"
}
parse_dmrc
locale_prompt="Your current locale is <b>${current_lang:-not set}</b>
These are the locales you have enabled;
to add more: <i>sudo dpkg-reconfigure locales</i>
Please choose:"
#### parse locale ####
list=()
locale_regex="^[[:blank:]]*locale:[[:blank:]]*([^[:blank:]]+)"
name_regex="^[[:blank:]]*language \| (.*)$"
parsing=true
while read -r line
do
[[ $line =~ $locale_regex ]] && {
parsing=true
loc=${BASH_REMATCH[1]}
[[ $loc = C.* ]] && {
parsing=false
continue
}
list+=("${loc}")
}
[[ $parsing = true ]] || continue
[[ $line =~ $name_regex ]] && {
name=${BASH_REMATCH[1]}
list+=("${name}")
parsing=false
}
done < <(locale -av)
########
choice=$( yad --title 'Choose language' --window-icon=distributor-logo-bunsenlabs --center --borders=20 --geometry 350x350 --fixed --button=OK:0 --button=Cancel:1 --text "$locale_prompt" --no-headers --separator='' --list --print-column=1 --column="locale":TEXT --column="name":TEXT "${list[@]}" )
case $? in
0)
extra_info=
write_dmrc "$choice"
write_accountsservice "$choice" && extra_info=' and accountsservice'
parse_dmrc
[[ "$current_lang" = "$choice" ]] || {
yad_info "Error setting language. Please check ~/dmrc"
exit 1
}
yad_info "Your locale has been set to <b>${choice}</b> in ~/.dmrc${extra_info:-}. \nThe change will be seen after your next login."
;;
1)
notify-send "Choose language" "Change cancelled"
;;
*)
yad_info "$0 returned an error..."
exit 1
;;
esac
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
@johnraff - nice script. I think that will complement slick-greeter nicely.
It looks nicer on my screen without the --fixed.
With --fixed, I only see two locales and have to scroll for the rest.
I've run without a display manager for a while and found that setting $LANG is enough.
I don't know much about it, but wonder if $LANGUAGE is really needed?
Offline
@malm thanks for the feedback.
Sizing of yad windows with various content is a long-standing problem.
2016 post: https://forums.bunsenlabs.org/viewtopic … 043#p15043
and: https://forums.bunsenlabs.org/viewtopic … 428#p14428
I hope with recent upgrades things might be improving. --fixed was a hack needed to avoid very tall windows with long text, but even then with lists things seemed to be better off without it, so let's take --fixed out.
I'd really prefer to leave out the --geometry setting too, and let yad size the window to fit the length of the list, taking into account the font size. But it doesn't.
If anyone knows a way to make yad display the whole of any reasonably short list, with no need to scroll, please share!
Locale environment variables: you're right that LANGUAGE is not needed (although it has its uses). The problem is that if it has already been set (eg by /etc/default/locale) then it needs to be brought in harmony with the new locale set in LANG, or just unset.
Locales topic here: https://forums.bunsenlabs.org/viewtopic … 485#p84485
EDIT Added a bit more: https://forums.bunsenlabs.org/viewtopic … 632#p84632
Last edited by johnraff (2019-03-27 08:16:52)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline