Ubuntu + fcitx5 で IME モードをトップバーの色で示す GNOME 拡張を作った(作ってもらった)
Ubuntu デスクトップで日本語入力してると、いま英語モードなのか日本語モードなのかわからなくなることがよくある。トップバーの右端に「あ」とか「A」は出てるんだけど、作業中は目線が画面中央にあるので全然気づかない。
何回も Ghostty の tmux でプレフィックス打って効かないことが続くの嫌になった。心底嫌になった。
macOS だと入力モード切り替え時に画面上に色付きのバーで今のモードを表示してくれるやつがあったのに…
既製品を探した
Claude さんに相談してみて、GNOME Extensions も漁ったけど、ぴったりのものがない。
- Kimpanel(extension/261): fcitx5 と連携してトップバーにモード表示できる。でも文字表示なので見づらさは変わらない
- Input-Method Status Indicator(extension/68): IBus 向けなので fcitx5 環境では微妙
- カーソル近くに表示するやつ: Linux/GNOME には存在しなかった
そんなとき
「無ければ作ればいいじゃんw」
みたいなノリで Claude 様がおっしゃられたので
「まじっすか、それでお願いします!」
って言ったら10分もかからずにできた。すげーなおい。
俺指示したの「色の指定は外出しファイルにしてリアルタイムに反映できるようにしといて」の雑な1行だけ。
そんな雑な指示によって作られたものが以下です。
作ったもの(作ってもらったもの)
fcitx5 が提供している fcitx5-remote コマンドをポーリングして、返り値に応じてトップバーの色を切り替える GNOME Shell 拡張。
~/.local/share/gnome-shell/extensions/ime-indicator@local/
├── extension.js
├── colors.json
└── metadata.json
metadata.json
{
"name": "IME Indicator",
"description": "fcitx5 の入力モードに応じてトップバーの背景色を切り替える",
"uuid": "ime-indicator@local",
"shell-version": ["46"],
"version": 1
}
colors.json
色の設定だけを切り出したファイル。ここを編集すると即時反映される。
{
"jp": "#641414",
"en": "#000000"
}
extension.js
import { Extension } from "resource:///org/gnome/shell/extensions/extension.js";
import * as Main from "resource:///org/gnome/shell/ui/main.js";
import GLib from "gi://GLib";
import Gio from "gi://Gio";
export default class IMEIndicatorExtension extends Extension {
enable() {
this._colors = { jp: "#641414", en: "#000000" };
this._isJp = null;
this._loadColors();
this._watchColors();
this._updateState();
this._timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 400, () => {
this._updateState();
return GLib.SOURCE_CONTINUE;
});
}
disable() {
if (this._timeout) {
GLib.source_remove(this._timeout);
this._timeout = null;
}
if (this._monitor) {
this._monitor.cancel();
this._monitor = null;
}
Main.panel.set_style("");
}
_loadColors() {
try {
const [ok, contents] = GLib.file_get_contents(`${this.path}/colors.json`);
if (ok) {
this._colors = JSON.parse(new TextDecoder().decode(contents));
if (this._isJp !== null) this._applyColor(this._isJp);
}
} catch (_) {}
}
_watchColors() {
const file = Gio.File.new_for_path(`${this.path}/colors.json`);
this._monitor = file.monitor_file(Gio.FileMonitorFlags.NONE, null);
this._monitor.connect("changed", (_m, _f, _o, eventType) => {
if (eventType === Gio.FileMonitorEvent.CHANGES_DONE_HINT)
this._loadColors();
});
}
_updateState() {
try {
const [ok, stdout] = GLib.spawn_command_line_sync("fcitx5-remote");
if (!ok) return;
const state = parseInt(new TextDecoder().decode(stdout).trim());
const isJp = state === 2;
if (isJp === this._isJp) return;
this._isJp = isJp;
this._applyColor(isJp);
} catch (_) {}
}
_applyColor(isJp) {
const color = isJp ? this._colors.jp : this._colors.en;
Main.panel.set_style(`background-color: ${color};`);
}
}
ポイント
fcitx5-remote の返り値
| 値 | 意味 |
|---|---|
1 | 英語(直接入力) |
2 | 日本語(IME アクティブ) |
400ms ポーリングで十分追いつく。
色のリアルタイム反映
Gio.FileMonitor で colors.json を監視して、変更を検知したら Main.panel.set_style() で即反映。拡張の再起動不要。
色は hex(#641414)でも rgba(100, 20, 20, 0.90) でも指定できる。CSS がそのまま通る。
拡張の有効化
初回だけ GNOME Shell の再起動または disable → enable が必要。
# X11 なら Alt+F2 → r → Enter で再起動
# Wayland はログアウト→ログインが必要
gnome-extensions enable ime-indicator@local
色を変えたいときは colors.json を保存するだけでよい。
ターゲットが狭すぎる問題
「Ubuntu デスクトップ + 日本語入力 + fcitx5 + Mozc + GNOME 46 + 入力モードが視覚的にわかりにくくてミスタッチが多くイライラし過ぎてこのままじゃタヒそう」という条件が全部重なる人向けなので、需要は相当ニッチだと自分でも思うけど同じ悩みを持っている人に届けばこれ幸い。