次回のエントリでは、この debian ruby-gtk2 パッケージのツイートを発端とした「mikutter GTK3対応の最終ステージ」について書いてみたいと思います。なんとか 12/25 の mikutter 5.0 リリースに間に合わせたい
mikutter GTK3対応(3) 〜miracle painter〜 - tsutsuiの作業記録置き場
というわけで無事にておくれてしまいましたが、まだ慌てるような時間じゃない、ということで前回の続きを書いてみたいと思います。
ruby-gnome GTK2廃止対応
前回のエントリで記載したとおり、 2021/4/22 リリースの ruby-gnome 3.4.4 で gtk2 のサポートは廃止され、当然ながら rubygems.org での gtk2 gem 更新も 3.4.3 までとなりました。
mikutter GTK3対応の前段階として、私が担当している pkgsrc の mikutter とそのための ruby gtk2 パッケージ の対応についてメモしておきたいと思います。
Farewell ruby-gtk2
Twitterその他をご覧の方はご存知と思いますが、私自身がメンテナとなっている mikutterおよび依存パッケージを含め、自分自身が必要な pkgsrc の各パッケージの検証を兼ねて NetBSD/amd64,i386 9.2 ておくれLive Image というものを NetBSD本体のリリースや pkgsrc の4半期毎リリースに合わせて更新するようにしています。
その関係で IFTTT で自分担当の各パッケージのリリース情報を見ていたため、 ruby-gnome 3.4.4 のリリースとその中の GTK2削除についてはその日のうちに気づいていました。
ただ、 mikutter本体の GTK3対応作業がしばらく止まっていたこと、 pkgsrc的に mikutter 以外で ruby-gnome を使っているのは ruby-gnomeメンテナご本人によるプレゼンツール rabbit くらいだったこと、さらに私自身が pkgsrc ruby-gnome パッケージの担当だったこともあり、「当面は現状の ruby-gnome 3.4.2 のままにするか」と、いったん様子見とすることにしました。
NetBSD 9.2 リリースにあわせて作った 20210521版の Live Image でも、「ruby-gnome をどうすべか」と思いつつ、リリースアナウンスや変更履歴では特に触れていませんでした。
NetBSD/i386 9.2 ておくれLive Image 20210521版https://t.co/7bq68ZXQ36
— Izumi Tsutsui (@tsutsuii) 2021年5月21日
NetBSD 9.2 および mikutter 4.1.5 対応 バージョンです
更新プレッシャー
2021年7月の pkgsrc-2021Q2 リリース後の Live Image更新については Firefox ビルドのための rust のビルドが NetBSD/i386 では失敗する問題のためにしばらく保留していました。
8月に入ったところでこの問題が解決して Firefoxもビルドできるようになり、 Live Image更新作業を始めたところで「そろそろ ruby-gnome 対応を真面目に考えるか」と、いったん GitHub issue でメモすることにしました。
方針としては以下のような感じです。
ruby-gnome では 3.4.3 → 3.4.4 の更新で ruby-gtk2 が削除された。
mikutter は未だ gtk2 対応のみで gtk3 対応は道半ばなので
pkgsrc として対応を考える必要がある。ruby-gtk2 削除対応 · Issue #38 · tsutsui/netbsd-teokureliveimage · GitHub
- pkgsrc/x11/ruby-gtk2 は 3.4.3 のまま残す
- pkgsrc/meta-pkgs/ruby-gnome から ruby-gtk2 を外して、 ruby-gtk2 側でバージョンや依存関係を個別定義する
- もし 3.4.4 以降から現状の 3.4.9 までに API 変更がある場合は ruby-gtk2 のソースパッチで対応できるか検証する
単純に GTK2 gem を古いままにして GLIB2 その他の gem を新しくしてしまうと以下のような懸念がありました。
ただ、悩んだところで他に手はなく、検討のために ruby-gnome 3.4.4 から 3.4.9 までの変更をざっと確認したところでは virtual functionサポート追加以外のあからさまな API/ABI変更は無さそうで、とりあえず試したところ GTK2版 mikutter は動くようでした。
このため、 ruby-gnome 3.4.9 への更新と合わせて上記の変更を pkgsrc にコミットしました。これが 2021年8月29日です。
パッケージ更新問題
という具合いに「どうしたものか」と考えた中で流れてきたのが、前回も紹介した以下のツイートです。
bullseyeがリリースされたことだしパッケージ更新作業を進めているんだけど、ruby-gnome 3.4.4でRuby/GTK2が削除されていた。https://t.co/Lh5dkX9Anl
— dai / 「Chef活用ガイド」発売中 (@dai_lxr) 2021年9月5日
mikutterをはじめとして、ruby-gtk2に依存するパッケージがいくつかあるけどどうしよう。#debian #ruby #gtk2 #mikutter
同じパッケージ管理者として debian ではどうなっていくのだろうか、ということでこれ幸いといろいろお話を聞いてみることに。
pkgsrc はむりやりで gtk2 gem だけ 3.4.3 のままにして gemspec の依存はむりやり上書き、で今のところは動いている、という状態です。https://t.co/8smuptMwtm
— Izumi Tsutsui (@tsutsuii) 2021年9月6日
gtk2 gem に依存するパッケージって他にどんなものがあるでしょうか? (rabbit は gtk3 に移行してました)
pkgsrc では ruby-gnome の各パッケージを独立した gem から生成するように変更していましたが、 debian では単一の ruby-gnome の GitHub リポジトリを親として各パッケージを生成しているそうです。このため、 ruby-gtk2 のみを古いまま新たなパッケージとして追加することは難しいのではないか、ということでした。
Debianではmikutterの他にhttps://t.co/Wype3MycS1https://t.co/rkbTs6wQ6y
— dai / 「Chef活用ガイド」発売中 (@dai_lxr) 2021年9月7日
の2つがありますが開発が止まっているようです。
今のところgtk2を丸ごと削除する計画はなさそうですがruby-gnome本体からgtk2等を切り出して3.4.3のまま置いておくことが許されるかは不明です。どうでしょうか。 @uwabami
いや、gtk2は多分可能な限りdropされると思いますよー
— henrich (@henrich) 2021年9月7日
すみません、文字数の関係で省略したらうまく伝わりませんでした。「許される」はDebian Project的に、です。
— dai / 「Chef活用ガイド」発売中 (@dai_lxr) 2021年9月8日
ruby-gnomeと別にgtk2 gemをアップロードするとバイナリは一緒でも新規ソースとなり、将来削除されるgtk2に依存する新規ソースのアップロードは許可されない可能性があるという意味でした。
Debian的には以前ruby-gnome 1ソースから生成するのではなく個別のgemをソースにしない?という話を出したのですがruby-gnome 1ソースのままで良いのではということになって今に至ってます。
— dai / 「Chef活用ガイド」発売中 (@dai_lxr) 2021年9月8日
今の状況を考えるとバラにしておいたほうがよかったのですが前述の通り手遅れの可能性が高いです。
やはりておくれる運命のmikutter
GTK3再始動
私個人としては「glib2 他の gem に非互換が発生したら自分でなんとかする」という前提です。
— Izumi Tsutsui (@tsutsuii) 2021年9月7日
そもそも gtk2 gem の drop は https://t.co/pD4pXaxPLa の対応工数をかける価値がないからだと思っていて、この PR は mikutter GTK3 対応作業が発端なので、アプリ側が頑張るのが筋かと
この私の勝手な決意表明(?)のツイートを見て立ち上がってくれたのが、人気Android Twitter/MastodonクライアントYukari の作者で mikutterのコミッタでもある shibafu528氏です。
ネクロマンシーは、死体による占い全般を指す通俗的な呼称で、未来や過去を知るために死者を呼び出し、また情報を得るために一時的な生命を与えることを含む。
ネクロマンシー - Wikipedia
2021年5月の ruby-gnome 3.4.5 で virtual function サポートが入ったものの、 mikutter GTK3作業をしていた yuntan_t氏は多忙となったため作業は止まっていた状態でした。まずはこの virtual function 対応を確認するところからだったようです。
というわけで、 9月7日 22:27の決意表明ツイートからわずか 2時間ほどで shibafu528さんがジェバンニしてくれたのでした。
ここから mikutter GTK3対応が再始動していくことになります。なんでも書いてみるものです
ruby-gnome側課題
まず ruby-gnome 3.4.5 での virtual function に問題があったようです。これは、 shibafu528氏により pull request が出され、すぐにマージされることとなりました。
このスーパークラスの virtual function の問題のほかに、 ruby-gnome 側の問題としてもう一つあったのが mikutter GTK3対応(1) のエントリでも記載した pango gem のモージュル名変更の問題です。
この問題については、12月頭の上記のブログエントリを見た shibafu528さんがサクッと mikutter側にモンキーパッチを用意してくれました。
提案 #1551: gtk3: ruby-gnome 3.4.9でも動くようにする - mikutter - やること
- https://github.com/ruby-gnome/ruby-gnome/pull/1433 をモンキーパッチで適用
- ruby-gnome 3.5.0 では PangoCairo 配下にある定数群が ruby-gnome 3.4.9以下では Pango 配下にあるので、エイリアスを張った
mikutter 5.0.0 リリースの今日 2021年12月25日まで ruby-gnome 3.5.0 のリリースは行われなかったため、現時点ではこの暫定対応がそのまま採用されている状態となっています。
mikutter GTK3 cleanup
9月10日以降、主に shibafu528氏が中心となって GTK3版の実用を目指したデバッグが始まりました。詳細は mikutter Redmine の活動ページを見ていただくとして、大枠は以下のGTK3チケットにある項目の対応です。
各チケットの件名を見ればだいたい雰囲気はわかるかと思いますが、 miracle painter というフレームワーク対応が概ね終わり、実用するための修正がメインになっていることはわかるかと思います。
9月終わりになると toshi_aさんも加わって GTK3版 miracle painter 詳細実装の修正も進んでいきます。
GTK3作業参戦
shibafu528氏と toshi_aさんが GTK3版の修正に取り掛かっていた9月後半、私自身は NetBSD/luna68k キーボードシリアルドライバの修正などというマイナー作業を2週間ほど続けていました。
10月に入り pkgsrc-2021Q3リリースに対応した Live Imageの更新版作成作業に取り掛かったところで、例の ruby-gnome 対応 GitHub issue を思い出し、「そろそろやるか」と自分でも手を出してみることにしました。
前述の PangoCairoモジュール名問題や pqueue gem 問題等々を対処しつつもちょくちょくクラッシュが発生してちょっと心を折られかけたのですが、ここでもアシストしてくれたのは shibafu528氏です。私が作っているておくれ Live Imageを使って NetBSDでの動作検証をしてくれました。
とりあえず NetBSD+pkgsrc 環境固有の問題はないということはわかったので、むりやりで ruby-gnome パッケージ関連のファイルを GitHub HEADのファイルで上書きして作業をすることにしました。その上で、各種 Twitterプラグインを持ってきて mikutter GTK3対応(1)のエントリ記載の通り適当に GTK3対処を入れると、とりあえずタイムラインは出るようになりました。
mikutter関連作業をするときは関係者が多い都合上 Mastodonメインになるのですが、とりあえず「ruby-gnome 3.5.0 出ないかなー」ということで Twitterにもそれっぽく告知したのがこのタイミング。
GTK3版 mikutter テスト中。
— Izumi Tsutsui (@tsutsuii) 2021年10月11日
ruby-gnome 3.4.9 では起動せず、 ruby-gnome の gtk3 gdk3 gio2 pango gobject-introspection のそれぞれの最新リビジョンが必要なので、 ruby-gnome 3.5.0 が早く出ませんかー、というところ pic.twitter.com/DkFNMdjMsC
Twitterプラグイン GTK3対応
Twitter プラグインのうち、ホームタイムライン表示関連のプラグインはとりあえず動いていたのですが、いくつかのプラグインはそもそもロードされない、ロードされても動きがおかしい、という状況でした。
GTK3対応の中心となっていた shibafu528氏や toshi_aさんは Twitter プラグインのサポートにあまり前向きではないというのは察せられていました。これは自分でなんとかするしかないか、と ruby の勉強も兼ねて Twitter関連プラグインの GTK3対応作業に本腰を入れてみることにしました。
個別の作業を書き出すといくらページがあっても足りないので適当に端折りますが、やはりというかなんというか ruby や miracle painter 以前に GTK2→GTK3の移行作業の勘所を掴むというところが一番苦労しました。
GTK3対応の作業としては、大きく以下に分けられるかと思います。
- GTK2→GTK3 における API変更
- GTK2 と GTK3 の同一ウィジェットのデフォルトの振る舞いの変更
- ruby-gnome の gtk2 gem と gtk3 gem の非互換性
- mikutter GTK3版本体の変更に伴うプラグイン側の変更
GTK2→GTK3 における API変更
まず、すぐに気づくのが Gtk::Hbox
, Gtk::Vbox
が deprecated という警告。
ただの警告なので無視してもよいのですが、結構大量に出るのでこれを消さないと本題のデバッグがはかどらないという問題が。まあ、これらは警告メッセージ通り Gtk::Box(:horizontal)
や gtk::Box(:vertical)
に機械的に置き換えれば済むのでまだ楽な部類です。
次に :draw
シグナルの廃止。
これは最初見様見真似で :expose_event
に置き換えたのですが、実は GTK本家のドキュメントにも記載があるとのことでした。まあ読んでも中身の本質はわからないんですけど
あと、数は少ないものの困ったのが色関係の指定。
GTK2では #FFFFFF 形式の 24ビット表記だったものが、 GTK3では各色 0.0〜1.0 の数値を指定する CSS方式に変更になっているようです。これが機械的に 1:1 で置き換える作業では対応できないようで、この問題に当たった user_detail_view プラグインでは mikutter 本体の gtk_postbox での修正内容を適当に真似る、という雑対処で済ませています。
他にも細かい修正があったような気はしますが、これらは地道に対処していく類の作業になります。
GTK2 と GTK3 の同一ウィジェットのデフォルトの振る舞いの変更
一番手を焼いたのがこれです。エラーも警告も出ずに表示だけがおかしいので、どう修正すればよいか見当がつかない、検索しようにも良いキーワードが思いつかない、できることは試行錯誤だけ、という状況に陥りがち。しかも何度も起動するには mikutterさんが重い
まず Gtk::ScrolledWindow
の幅指定。
画像投稿プラグインの mikutter-uwm-hommage で謎の表示になったのがこれ。 GTK2環境ではうまいこと(?)親のウィジェット幅に収まっていたものが、謎のデフォルト値 200pxくらいの幅になってしまうようでした。最初は width_request = 500
を指定したりしたのですが、結局 propagate_natural_width = true
を指定するとそれっぽくなるようでした。
次に、かなりの時間を費やしたのが Gtk::Box
と Gtk::Scrollbar
の組み合わせ挙動。
GTK2環境ではこの組み合わせで Box表示が表示領域より大きくなるとスクロールバーが表示されていたが、 GTK3ではスクロールバーが表示されるだけで機能しないようでした。それだけではなく、「表示領域のサイズが収まるようにアプリケーションのウインドウサイズが無限に拡大していく」という動作を引き起こし、当該操作のあるタブを表示してしまうと mikutterさんがあっという間にフルスクリーンサイズに張り付いてしまい、アプリごと落とすしか無いという状況に陥っていました。
何日かトライアンドエラーを繰り返して、「Gtk::Scrollbar
を捨てて Gtk::ScrolledWindow
を使えばよい」という結論に。
他に目についたのは以下の Gtk::ImaegMenuItem
の挙動ですが、詳細はそれぞれ Redmine チケットを参照してください。
ruby-gnome の gtk2 gem と gtk3 gem の非互換性
これはとりあえず Gtk::TreeView
の visible_range
1件だけでしたが、とにかくドキュメントがないため、試行錯誤のテストコードを書いて挙動を確認しながらの修正になりました。
visible_range
が動かないのは gtk3 の問題なのか gem の問題なのかはよくわかりませんが。添付 ruby-gtk3-TreeView.rb のテキトーテストプログラムを書いていろいろ調べたところ、
どうも GTK2 と GTK3 とでvisible_range
の返り値が異なるようです。
具体的には GTK3 では 1つ目の返り値としてbool
が返ってきています。![]()
ドキュメントがないので仕様がよくわかりませんが、とりあえずブラインドで
バグ #1514: gtk3: core/mui/gtk_userlist.rb で visible_range と :expose_event が参照されている - mikutter - やること
1つ目の返り値をvisible_range
の有効無効判定に使い
2つ目、3つ目の返り値を従来のstart_path
end_path
相当で扱うように書き換えると
一応ユーザーフォロータブの表示動作(スクロールして表示されたところだけアイコンを出す)は
mikutter_gtk3-UserList-visible_range.mp4 のとおりで実現できているようです。
GIで非voidな戻り値型かつout引数を伴う関数呼出の戻り値は、関数の本来の戻り値+out引数の配列。
バグ #1514: gtk3: core/mui/gtk_userlist.rb で visible_range と :expose_event が参照されている - mikutter - やること
今回は関係ないですが、out引数が1つの場合には配列ではなくそのout引数を単体で返すといった特殊ケースも存在するようです。
(さすがにこの辺の規約はドキュメントあってほしい)
mikutter GTK3版本体の変更に伴うプラグイン側の変更
mikutter の GTK3対応においては、 GTK APIを 1:1 で置き換えたのではなく、別のウィジェットやAPIに置き換えたケースが複数あります。よくハマったところとしては、ウィジェット配置が Gtk::Box
から Gtk::Grid
に置き換えられた部分をバンドルプラグインで参照しているようなケースです。また、置き換え作業やリファクタリングにおいて意図しない変更が入ってしまった部分もあるようでした。
これらはわかってしまえば機械的な置き換えになるのですが、前回のエントリで書いたとおり GTK3対応は yuntan_t氏が長期に渡って独力で作業していたこともあり、記録を掘り返しながらの作業になりました。
個別の内容についてはそれぞれ Redmineチケットに挙がっていますので、今後 mikutter 5.0 のバグ取りに参加しようという方はながめてみてください。
-
バグ #1519: gtk3: mastodon カスタム投稿起動時に postbox 入力済みテキストがカスタム投稿本文に反映されない
-
バグ #1522: gtk3: 一部のタイムラインの BT/RT 表示が旧来の「RT @アカウント名 本文」の表示になっている
-
バグ #1539: gtk3: Twitter プラグインでの client側設定 muted_user がタイムラインに表示されてしまう?
miracle painter とセットで実装されている timeline 関連の変更も大きく、挙動が異なる場合の差分確認が結構大変だったという印象です。ただ、これらの作業記録が将来の移行作業でも役に立つことを信じたいと思います。
その他、雑多なメモトゥートだけ貼っておきます。
mikutter GTK3対応 まとめ
長々とセルフまとめ状態を含めて書いてしまいましたが、ここで書いた以外にも様々な活動を経て、 GTK3版 mikutter は無事に mikutter 5.0.0 としてリリースされることになりました。
冒頭で引用した mikutter 5.0 リリースのエントリの中で、 toshi_aさん自身は以下のように書かれています。
Gtk3対応は、はっきりいって退屈なものでした。 だからこそ、貢献してくれた方々に心から敬意を表します。
mikutter 5.0.0 - mikutter blog
しかし、NetBSDカーネルのC言語以外のプログラミングに手を出す機会がなかなかなかった自分としては、10月から約2か月間で得られた経験値はある意味新鮮で大きなものでした。いい歳になってしまった自分ですが「古い常識に囚われた老害にならない」ためのよい勉強をさせてもらったという気持ちです。
今までも mikutter Redmine のモデレータとしてサポートメインの立場でお手伝いをさせていただいていましたが、今後は mikutter 本体コードへの貢献量も増やせればいいな、と考えています。
最後に、 mikutter というアプリを作り上げてメンテし続けてくれている toshi_aさん、そして yuntan_t氏、 shibafu528氏、その他 mikutter 開発に関わってくれた方々に感謝の言葉を贈りたいと思います。
このエントリを読んでいただいた方も、ここまでの長文駄文にお付き合いいただきどうもありがとうございました!