You are not logged in.

#1 2019-03-24 04:46:34

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 5,143
Website

Utility to choose language

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

John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
In case you forget, the rules.

Offline

#2 2019-03-25 17:40:41

malm
jgmenu developer
Registered: 2016-10-13
Posts: 320
Website

Re: Utility to choose language

@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

#3 2019-03-26 08:17:59

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 5,143
Website

Re: Utility to choose language

@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. neutral

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)


John
--------------------
( a boring Japan blog , Japan Links, idle twitterings  and GitStuff )
In case you forget, the rules.

Offline

Board footer

Powered by FluxBB