xrdpの環境にmacOS端末でログインすると結構な確率でキーボード判定がおかしくなりませんか?
macOSでRDPするにはMicrosoft謹製のwindows.appを使うわけなのですが、どうもxrdpに送られてくるキーボードレイアウトの情報がおかしい、というか無いに等しい。
これがWindows機ならばある程度の種類を送ってきてくれるので、それに適したレイアウトで操作できるわけなのですが、Windows.appから送られてくる情報は常に0x00000000。
キーマップは0x00000411.tomlをコピーして0x00000000.tomlを作ってしまうことで誤魔化しは効くものの、どういうわけかusキー・日本語キーの判定は接続するたびに違っていたりで、少なくとも私の個人持ちのMacBookではUSキー判定されたり日本語キー判定されたり。
接続自体はスムーズなのに、いざ「@」や「¥」を入力しようとすると違うレイアウトになっていることに気づいて接続し直す羽目になるのがどうも憂鬱。
・というわけでもう作っちゃえ
というわけで、GUIで設定変更できるツールをさくさくっと。
ついでに接続してきた端末名や解像度と設定内容を記録しておいて、自動実行でも設定できるように。
[ keyboard-switcher.sh ]
#!/bin/bash
# --- 実行モード判定 ---
AUTO_MODE=false
if [[ "$1" == "--auto" ]]; then
AUTO_MODE=true
fi
# --- 設定保存先・識別情報取得 ---
CONFIG_DIR="$HOME/.config/keyboard_layouts"
AUTOSTART_DIR="$HOME/.config/autostart"
AUTOSTART_FILE="$AUTOSTART_DIR/keyboard-switcher.desktop"
mkdir -p "$CONFIG_DIR"
mkdir -p "$AUTOSTART_DIR"
resolution=$(xdpyinfo | grep dimensions | awk '{print $2}')
hostname=$(xprop -root | grep Xdpy | cut -d\" -f2 | cut -d@ -f2)
[[ -z "$resolution" ]] && resolution="unknown_resolution"
[[ -z "$hostname" ]] && hostname="unknown_host"
safe_id=$(echo "${hostname}_${resolution}" | tr -cs '[:alnum:]_-' '_')
CONFIG_FILE="$CONFIG_DIR/${safe_id}.conf"
# --- 現在のキーボードレイアウトを取得 ---
current_layout=$(setxkbmap -query | grep layout | awk '{print $2}')
# --- 自動モード: GUIなしで適用する ---
if $AUTO_MODE; then
if [[ -f "$CONFIG_FILE" ]]; then
saved_layout=$(cat "$CONFIG_FILE")
if [[ "$saved_layout" == "us" || "$saved_layout" == "jp" ]]; then
setxkbmap "$saved_layout"
echo "[INFO] 自動実行: '${saved_layout}' を適用しました (${safe_id})"
exit 0
fi
fi
echo "[INFO] 自動実行: 設定が見つからなかったため変更なし"
exit 0
fi
# --- 手動実行: GUIで選択 ---
us_selected=FALSE
jp_selected=FALSE
if [[ -f "$CONFIG_FILE" ]]; then
saved_layout=$(cat "$CONFIG_FILE")
if [[ "$saved_layout" == "us" ]]; then
us_selected=TRUE
elif [[ "$saved_layout" == "jp" ]]; then
jp_selected=TRUE
fi
else
if [[ "$current_layout" == "jp" ]]; then
jp_selected=TRUE
else
us_selected=TRUE
fi
fi
layout=$(zenity --list \
--title="キーボードレイアウトの選択" \
--text="使用するキーボードレイアウトを選んでください\n(端末: ${hostname}, 解像度: ${resolution})" \
--radiolist \
--column="選択" --column="レイアウト" \
$us_selected "us (英語)" \
$jp_selected "jp (日本語)" \
FALSE "削除(設定をリセット)")
# --- ユーザーが削除を選択した場合 ---
if [[ "$layout" == "削除(設定をリセット)" ]]; then
zenity --question --title="設定削除" --text="自動実行設定とキーボード設定を削除しますか?"
if [[ $? -eq 0 ]]; then
rm -f "$AUTOSTART_FILE"
rm -rf "$CONFIG_DIR"
zenity --info --text="削除が完了しました。"
echo "[INFO] 削除が完了しました。"
else
echo "[INFO] 削除をキャンセルしました。"
fi
exit 0
fi
# --- キーボードレイアウトの適用 ---
if [[ "$layout" == "us (英語)" ]]; then
setxkbmap us
echo "us" > "$CONFIG_FILE"
elif [[ "$layout" == "jp (日本語)" ]]; then
setxkbmap jp
echo "jp" > "$CONFIG_FILE"
else
zenity --info --text="レイアウトが選択されませんでした。"
exit 1
fi
# --- 自動起動用のデスクトップエントリーを作成 ---
cat <<EOF > "$AUTOSTART_FILE"
[Desktop Entry]
Type=Application
Exec=$HOME/path/to/keyboard-switcher.sh --auto
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
EOF
zenity --info --text="設定内容を保存し自動実行を設定しました (${AUTOSTART_FILE})"
echo "[INFO] 設定内容を保存し自動実行を設定しました (${AUTOSTART_FILE})"
と、こんな感じで。
配置はどこでも良いけれど、実行するためには chmod +x keyboard-switcher.sh を忘れずに。
・こまかいところ
仕様的には
・自動実行時+保存情報あり:保存された情報で設定して静かに終了
・自動実行時+保存情報なし:なにもせず静かに終了
・手動実行時+保存情報あり:GUIを開き保存された情報を表示
・手動実行時+保存情報なし:GUIを開く
と言う感じで、保存情報は
~/.config/keyboard_layouts/ 以下に「ホスト名_解像度.conf」の設定ファイルを作って記憶。
ただ、実際に動かしてみるとhost名が取得できなくて unknown_host_1440x900_.confみたいな形になってしまいましたが、実用上支障なしということで。
書き忘れるところだった。
自動実行時というのをどう判定するねん、という点は –auto というオプションを付けることで判断します。
・せっかく作ったならメニューへ
せっかくGUIなツールなのに起動がいちいちCLIではもったいないので、デスクトップエントリーに以下のように追加。
[ /usr/share/applications/keyboard-switcher.desktop ]
[Desktop Entry]
Name=キーボードレイアウト切替
Exec=/usr/local/bin/keyboard-switcher.sh ←ここは環境にあわせてフルpathを!
Type=Application
Terminal=false
Icon=input-keyboard
Categories=Settings;Utility;
これでちょっと楽ができるかな?
—
安心安全安価なSDカードデータ復元・HDDデータ復元は
長年の信頼と実績の『株式会社パソコントラブル救助隊』へ。
https://hqsecure.net/

株式会社パソコントラブル救助隊で公式サイトを含めたウェブマスターを兼任しています。
趣味はカメラとぶらり散歩。フォトマスターは2級。日々感じたことを忘れないうちに雑記帳に書いています。