「どんな簡単なことでも、完璧にできるとうれしいもんでしょう」
田中あすか(『響け! ユーフォニアム』5話より)
fcitx-anthyのキーバインド設定が飛ぶというバグは、柴田さんが
直してくれました。
このバグはどう頑張っても私には直せないものでした。ありがとうございます。
実はこのバグの検証中に、別なバグを見つけました。
[記号のスタイル]を変更しても、UI上は変更できたように見えても実際には反映されないというバグです。
得てしてこの手のバグは単純なものなので、自分で直すと決意しました。
ソースコードを読み込んで、src/imengine.cppの749行目以降がおかしいので間違いないという確信までは持てました。
void AnthyInstance::set_symbol_style(SymbolStyle symbol)
{
m_config.m_symbol_style = symbol;
FcitxUISetStatusString(m_owner,
"anthy-symbol-style",
_(symbol_style_status[symbol].label),
_(symbol_style_status[symbol].description));
switch (m_config.m_symbol_style)
{
case FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
case FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
case FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_MIDDLEDOT:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
case FCITX_ANTHY_SYMBOL_STYLE_JAPANESE:
default:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
break;
}
}
一瞬で気づかないとダメなレベルですよね。
そもそもこれはどういう機能かというと、鉤括弧と中黒キーを変更する機能です。
こういう機能があることは昔取った杵柄で知っていますけど、自分で使ったことはありません。
fcitx-anthyの場合は、
「」・
「」/
[]・
[]/
の4種類から選択できます。まず、この4つの定義はsrc/fcitx-anthy.descにあります。
[General/SymbolStyle]
Type=Enum
Description=Symbol style
DefaultValue=Japanese
EnumCount=4
Enum0=Japanese
Enum1=Wide bracket and wide slash
Enum2=Corner bracket and wide slash
Enum3=Wide bracket and Middle Dot
だめでしょこれ。
「」がwide bracket、[]がcorner braketだとすると、
[General/SymbolStyle]
Type=Enum
Description=Symbol style
DefaultValue=Japanese
EnumCount=4
Enum0=Japanese
Enum1=Wide bracket and wide slash
Enum2=Corner bracket and Middle Dot
Enum3=Corner bracket and wide slash
でないといけません。
(というか書いてて間違いに気づいたことは秘密な!)
ここを変更したら、src/factory.hも変更する必要があります。
typedef enum {
FCITX_ANTHY_SYMBOL_STYLE_JAPANESE,
FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_WIDESLASH,
FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_MIDDLEDOT,
FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_WIDESLASH,
FCITX_ANTHY_SYMBOL_STYLE_LAST
} SymbolStyle;
これは、
typedef enum {
FCITX_ANTHY_SYMBOL_STYLE_JAPANESE,
FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_WIDESLASH,
FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_MIDDLEDOT,
FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_WIDESLASH,
FCITX_ANTHY_SYMBOL_STYLE_LAST
} SymbolStyle;
でないといけません。
{
case FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
case FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
case FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_MIDDLEDOT:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
case FCITX_ANTHY_SYMBOL_STYLE_JAPANESE:
default:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
break;
}
これもよく見たら間違っていて、
{
case FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
case FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
case FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_MIDDLEDOT:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
case FCITX_ANTHY_SYMBOL_STYLE_JAPANESE:
default:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
break;
}
が正しいです。ほとんど間違い探しですな。diffがないとわかりにくくてしょうがないです。
で、ここまできて、あれ、これってbreakがないだけじゃね、ということに気がついて、
{
case FCITX_ANTHY_SYMBOL_STYLE_WIDEBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
break;
case FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_WIDESLASH:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_WIDE);
break;
case FCITX_ANTHY_SYMBOL_STYLE_CORNERBRACKET_MIDDLEDOT:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_WIDE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
break;
case FCITX_ANTHY_SYMBOL_STYLE_JAPANESE:
default:
m_preedit.set_bracket_style (FCITX_ANTHY_BRACKET_JAPANESE);
m_preedit.set_slash_style (FCITX_ANTHY_SLASH_JAPANESE);
break;
}
としたら意図した通りに動いてくれました。めでたしめでたし。
pull requestは
これです。
C言語の文法はわかりませんけど、switch文はシェルスクリプトと同じなので、breakが必須であることは知ってました。自分ではswitch文はあまり書かないですけど。
breakがないからdefaultまでいっちゃうので、UI上では変更したのにもかかわらずそれが反映されない、というバグの挙動とも一致します。
今回わかったことは、本来どう動くべきなのかがわかっているといろいろと話が早いということと、今回はシェルスクリプトの知識で乗り越えられたものの、やっぱりC言語の文法知らなきゃダメだよね、ということです。
ちょっとC言語の勉強してきます……。