バグ #1207
完了タイムライン上にマウスカーソルを移動するとクラッシュする
説明
現在のdevelopブランチのmikutterをUbuntuで実行したとき、タイムライン(要するにMiraclePainterが描画している領域)にカーソルを移動させると、確実にクラッシュします。
WSL上のUbuntu(私)と、MacBookAir上の実機( https://social.mikutter.hachune.net/@d_flat_aug7/99869543045799080 )での発生を確認しています。
エラーメッセージは以下の通り。
RuntimeError failed to initialize {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `initialize' {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `new' {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `set_cursor' {MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class' {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:183:in `point_moved' {MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class' {MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:184:in `block in event_hooks' {MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect' {MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `signal_emit' {MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `block in tree=' {MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect' {MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `main' {MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `mainloop' ./mikutter.rb:68:in `boot!' ./mikutter.rb:104:in `<main>'
これ以降は私の環境でのみ確認(他のUbuntu環境では未確認)
breeze-cursor-themeパッケージをインストール
$ sudo apt install breeze-cursor-theme
すると、このエラーは出なくなりますが、低確率で以下のエラーにより落ちます。
TypeError wrong argument type Gdk::DisplayX11 (expected Data) {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `initialize' {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `new' {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `set_cursor' {MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class' {MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:183:in `point_moved' {MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class' {MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:184:in `block in event_hooks' {MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect' {MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `signal_emit' {MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `block in tree=' {MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect' {MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `main' {MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `mainloop' ./mikutter.rb:68:in `boot!' ./mikutter.rb:104:in `<main>'
https://cobodo.hateblo.jp/entry/2018/04/16/143723 に貼ったプラグインでモンキーパッチして、Gdk::Cursorの旧形式コンストラクタを呼ぶように変更すると、今のところ落ちなくなるようです。
ファイル
再現手順
・developブランチのmikutterを起動
・マウスカーソルをタイムライン上に移動
toshi_a 初音 さんが6年以上前に更新
明言しているわけでわないですが、WSLやMacは環境としてかなり特殊なので、なんとも言えないですね。
とはいえ、前の方法がdeprecatedだったわけでもないようですし、新たに提案された方法はそのチケットで解決したい問題ではなかったので、動いていた環境で動かなくなったなら、その部分は修正したいです。
cob odo さんが6年以上前に更新
書き方が悪かったんですが、「MacBookAir上の実機( https://social.mikutter.hachune.net/@d_flat_aug7/99869543045799080 )」はハードウェアとしてのMacBookAirの上で動くUbuntu16.04らしいです。
Yuto Tokunaga さんが6年以上前に更新
- ファイル 1207-1.patch 1207-1.patch を追加
Ubuntu 16.04で問題を確認しました.Gdkのgdk_cursor_new_from_name
関数がGdkCursor
を返すかNULL
を返すかが環境に依ることが原因のようです.ruby-gtkのnative extensionではNULL
が返ってきた場合に適切にハンドリングできておらず,RuntimeError
が生じるようになっています.解決策として添付したパッチのような方法もあるとは思うのですが,あまりすっきりしないですね.
あと,gtk3-demoというアプリケーションのカーソルのデモでは同じAPIを使って適切にカーソルを設定できているようなのですが,なぜこちらでは上手くいくのにmikutterではできないのかもよく分かりません.
Yuto Tokunaga さんが6年以上前に更新
Ubuntu 18.04でもクラッシュを確認しました.gtk2のライブラリのバージョンに依存すると考え調べてみたのですが,Ubuntu 18.04はlibgtk2.0-0のバージョンが2.24.32なのに対し,正常に動作している手元環境(Arch linux)のgtk2のバージョンが2.24.32なので関係ないことが分かりました.
Akira Ouchi さんが6年以上前に更新
以下のチケットを適当に見た感じ、環境によってカーソルがあったりなかったりするのではないでしょうか。
https://github.com/ruby-gnome2/ruby-gnome2/issues/720
例外をスルーしたらとりあえずコケなくなりました(カーソルは変わらなくなりますが)。
(カーソルが変更できるかのチェックが出来ればそのほうが優しいとは思います)
diff --git a/core/mui/cairo_miracle_painter.rb b/core/mui/cairo_miracle_painter.rb index 8774ef4b..d507d3a6 100644 --- a/core/mui/cairo_miracle_painter.rb +++ b/core/mui/cairo_miracle_painter.rb @@ -223,10 +223,13 @@ class Gdk::MiraclePainter < Gtk::Object # ==== Args # [name] カーソルの名前(String) private def set_cursor(name) - window = @tree.get_ancestor Gtk::Window - display = window.screen.display - window.window.cursor = Gdk::Cursor.new(display, name) - self + begin + window = @tree.get_ancestor Gtk::Window + display = window.screen.display + window.window.cursor = Gdk::Cursor.new(display, name) + self + rescue => e + end end # MiraclePainterが選択解除されたことを通知する
toshi_a 初音 さんが6年以上前に更新
- 担当者 を toshi_a 初音 にセット
カーソルがない場合は他のところで既に使っている方法で取得すれば良さそうではありますが、どちらの場合も必ず従来の方法であれば正しく動いているので、そちらの方法で揃えたいと思っています。
toshi_a 初音 さんが6年以上前に更新
修正案の一つとして topic/1207-gdk-cursor をpushしました( 977f77ef )。
一度recommendedな方法にしたのを戻しているので心苦しいですが、最低限しか変えていないので万が一あとから巧いやり方がわかっても実装しやすいように配慮しています。
これでクラッシュせず、マウスカーソルがちゃんと変わっているでしょうか。
toshi_a 初音 さんが6年以上前に更新
- ステータス を 実装待ち から 終了 に変更
developにmergeしました。
topic/1207-gdk-cursor でクラッシュしなくなることは確認しましたが、リンクをmouseoverしてもカーソル形状がXTERMのままで、HAND2になりません。
これは、 topic/1207-gdk-cursor がscoreブランチmerge後のdevelopから生えていて、 Gdk::MiraclePainter#cursor_name_of がmessage.links(=entity)を参照しているためかなと思います。
これは直ってると思います