IBus変換エンジンでネストしたメニューを正しく表示できるようにするには - 2018-06-27 - ククログ

ククログ

株式会社クリアコード > ククログ > IBus変換エンジンでネストしたメニューを正しく表示できるようにするには

IBus変換エンジンでネストしたメニューを正しく表示できるようにするには

はじめに

GNOME Shellには、ネストしたメニューを正しく展開できないという不具合があります。 今回はその問題への対処方法について紹介します。

問題の詳細

IBus変換エンジンのメニューは、IBusPropertyIBusPropList を組み合わせて実装します。 サンプルコードの抜粋を以下に示します。

IBusText *label = ibus_text_new_from_static_string("Menu");
IBusPropList *root = ibus_prop_list_new();
g_object_ref_sink(root);
IBusPropList *submenulist = ibus_prop_list_new();
IBusProperty *menu = ibus_property_new("InputMode",
                                       PROP_TYPE_MENU,
                                       label,
                                       NULL,
                                       NULL,
                                       TRUE,
                                       TRUE,
                                       PROP_STATE_UNCHECKED,
                                       submenulist);
g_object_ref_sink(menu);
ibus_prop_list_append(root, menu);

label = ibus_text_new_from_static_string("SubMenu");
IBusPropList *subsubmenulist = ibus_prop_list_new();
IBusProperty *submenu = ibus_property_new("SubMenuKey",
                                          PROP_TYPE_MENU,
                                          label,
                                          NULL,
                                          NULL,
                                          TRUE,
                                          TRUE,
                                          PROP_STATE_UNCHECKED,
                                          subsubmenulist);
g_object_ref_sink(submenu);
ibus_prop_list_append(submenulist, submenu);

label = ibus_text_new_from_static_string("SubSubMenu");
IBusProperty subsubmenu = ibus_property_new("SubSubMenuKey",
                                            PROP_TYPE_NORMAL,
                                            label,
                                            NULL,
                                            NULL,
                                            TRUE,
                                            TRUE,
                                            PROP_STATE_UNCHECKED,
                                            NULL);
g_object_ref_sink(subsubmenu);
ibus_prop_list_append(subsubmenulist, subsubmenu);

メニューが子のメニューを持つ場合には、該当するメニューは IBusPropList を保持する、というのが基本です。 上記の例だと menu の下に submenulist という IBusPropList を追加して、その下に IBusProperty である submenu を追加しています。 このようにすることでメニューの親子関係を表現できるというわけです。 孫にあたるメニューの追加も同様です。

では、ネストしたメニューを実装したIBus変換エンジンのメニューは実際にどのように表示されるでしょうか。

GNOME ShellとXfceそれぞれでみてみましょう。

GNOME Shellの場合

GNOME Shellの場合、SubMenu をクリックしてもその子階層に配置したはずの SubSubMenu は表示されません。 SubMenu が閉じられてしまうという挙動になります。

Xfceの場合

Xfceの場合、SubMenu をクリックしたらその子階層に配置した SubSubMenu も期待通りに表示されます。

したがって、3階層のメニューを実装した場合、GNOME Shellでは正常に機能しないということがわかります。

問題への対応について

ネストしたメニューが表示されないというこの挙動ですが、既知の問題でした。 しかし、報告から何年も経過しているものの、まだ修正されていません。 GNOME Shell自体の修正が必要なケースですが、たいていのIBus変換エンジンではそれほどネストが深いメニューを実装していないために大きな問題にはなっていないのかもしれません。

幸いにも、該当バグにパッチが投稿されていました。 最近のバージョンに合わせて多少手直しすることで、Ubuntu 18.04のGNOME Shellで問題が解決できることがわかっています。

そのため、以下のようにパッチを更新して追加のフィードバックをしておきました。

まとめ

今回は、IBusでネストしたメニューを正しく表示できないことに気づいてフィードバックしたときの知見を紹介しました。 まだアップストリームであるGNOME Shellにパッチが取り込まれていませんが、修正されればGNOME Shellでもネストしたメニューをきちんと表示できるようになるはずです。