バグ #1280
完了sub partsの領域描画が読み込みタイミングにより下部が欠ける
説明
#1274 (エラーメッセージ Gdk-CRITICAL **: IA__gdk_pixbuf_get_from_drawable: assertion 'src_x + width <= src_width && src_y + height <= src_height' failed が大量に表示される)
の修正 a8d2a043 がコミットされてエラーメッセージは出なくなりましたが、ツイートのTL描画が意図通りになっていない状態になっています。
https://mstdn.kanagu.info/@cobodo/100395115122408864
toshi_a 初音 一応知らせておくと、 #1274のパッチの影響で、sub_parts_quote、replyviewer、sub_parts_voter、subparts_imageのような(おそらくすべての)sub partsが読み込みタイミング次第では下部が欠けた状態で描画されています。mouseroverやclickなどで再描画を走らせれば直るので、別段困るほどでもない、という感じです。
「再現手順」に記載しましたが、従来エラーメッセージが出ていたタイミングで mikutter のウインドウからはみ出していた部分が描画されていない状態になっていると思います。
エラーメッセージの抑制とTL描画とを両立することが可能なのかどうかは把握できていません。
(スクロールした時点で再描画?)
上に添付しているスクロール前後画像のTL描画範囲を見ると、
微妙に元の mikutter ウインドウ領域内にあった部分より数ドット多めに描画されているので、
そもそも何かしらパラメータの値が誤っている可能性もあるかもしれません。
ファイル
再現手順
- リストの抽出タブ等で「TL表示において、ツイートURLは取得されているが、TL位置的にウインドウの外にありTL描画はされていない」というツイートが存在する状態にする
- そのタイムラインをマウスホイールで下にスクロールしていく
- 「引用」を含むツイートで、subpartの引用表示部分が mikutter のウインドウの外側にはみ出すツイートが表示される状態にする
- #1274 のエラーメッセージはこの時点で発生していた
- そのままさらにマウスホイールで下にスクロールしていく
関連するチケット
Izumi Tsutsui さんが6年以上前に更新
- 関連している バグ #1274: エラーメッセージ Gdk-CRITICAL **: IA__gdk_pixbuf_get_from_drawable: assertion 'src_x + width <= src_width && src_y + height <= src_height' failed が大量に表示される を追加
Izumi Tsutsui さんが6年以上前に更新
- ファイル mikutter-render-20180512.png mikutter-render-20180512.png を追加
- ファイル shibafu528-992647124499103744.png shibafu528-992647124499103744.png を追加
確かに a8d2a043 適用以前の 2018/5 あたりでも subpart 描画が欠ける現象は発生していました。
https://social.mikutter.hachune.net/@tsutsuii/100014648334481427
ただし、このときは「高速でマウススクロールする」といった限られた条件
(subpart対象のツイート取得前にスクロール?; 特定できず)のみで発生していたと思います。
現状は「再現手順」の記載、つまり従来警告が出ていた時の条件で発生しているようです。
あと、 subpart の描画位置がおかしいというのもありましたが、これは別の問題ですかね……。
https://social.mikutter.hachune.net/@tsutsuii/99983682173337087
Izumi Tsutsui さんが6年以上前に更新
直接関係ありませんが
TLが重いときに高速ホイールスクロールすると
表示がおかしくなる場合があるようです。
↑これは下から上へスクロールした際に発生
toshi_a 初音 さんが6年以上前に更新
- ステータス を 分類待ち から 実装待ち に変更
これはウチの環境でも再現しています。どのリビジョンからかはわかりませんが、つついさんの言うとおりっぽいですね
toshi_a 初音 さんが6年以上前に更新
- ステータス を 実装待ち から レビュー待ち に変更
- 担当者 を Izumi Tsutsui にセット
- ブランチ を topic/1280-broken-subparts-rendering にセット
対応しました。確認をお願いします。
以下、修正する過程で判明したこの問題の原因です。
まず、Pixmapは自身の寸法より大きなPixbufを要求された時の動作が未定義なため、実際のPixmapの寸法を使う #1274 の修正は正当です。
原因¶
高さの予測が外れる¶
Pixmapのサイズは事前に決定する必要があり、描画前にはMiraclePainterは考えうる最小の寸法を得ることになる、という点です。
要するにPixmapにCairoによるMessageのレンダリングが終わった後だと、heightが考えうる最小のサイズではなく実際のサイズを返します。
#1274 は、本来確保された描画領域だけがTLに表示されるようにしたため、警告の出力はなくなりましたが本件のような新たな問題を引き起こしています。
内容変化後に再描画がされない場合がある¶
予想している高さと実際の高さに食い違いが発生すると、高さの計算中や描画中に高さを再計算するリクエストを投げます。
そのさい、まだ高さの予測値が計算されていない(または計算中)の場合、リセットする対象がないので再描画はしないようになっているのですが、その再入処理の条件が以下のようにキャッシュ変数を使うようになっています。
@height and defined?(@minpart_height) and tree
ここには2つの問題があります。
問題1: 2つのキャッシュ変数¶
@height
と @minpart_height
という2つの変数が使われているのが問題で、これらはそれぞれ要求された時に計算されてセットされるものです。
内容が変わって古くなったキャッシュをクリアするなら、ここはandではなくorにすべきでした。
具体的には、初めて描画されるときには @minpart_height
がセットされていないことが多く、高さを再計算する要求が出されず本件のような表示の崩れが発生します。
問題2: キャッシュ変数を再入条件にしていること¶
そもそもこの条件式の中でやっていることは:
- 再描画を予約する(ここが実行されているということは高さの予測が外れた時なので、もはや描画されている内容は役に立たないため)
- なので、このタイミングで高さの計算結果もクリアする
- 次回の再描画の後にTreeViewに高さの再計算を要求する
の二点です。高さのキャッシュクリアは副次的な処理なので、これらの処理の前提条件として用いるのは間違っています。
解決策¶
fc6893df で、Gdkシグナルのmodifiedシグナルを受け取った時に一度だけ実行されるイベントハンドラを毎回登録していましたが、そのシグナルIDを記録しておいて、記録の有無を条件にしています。
高さの予測値(や実測値)は再描画前に何度変わってしまっても、最後の値で一度だけ描画すれば良いからです。
正確に再描画及び高さの再計算が必要なタイミングで先に列挙した諸々の処理が実行されるようになったことで、本件の問題は再現しなくなったと思います。
Izumi Tsutsui さんが6年以上前に更新
- ステータス を レビュー待ち から マージ待ち に変更
速攻修正ありがとうございます。
確認しました。2回起動して検索タブ、抽出タブ、リプライタブ、TLタブ等々で
ぐりぐりスクロールさせたり追加ロードしたりしましたが、
subparts 描画がおかしいツイート表示はありませんでした。
修正前後の頻度変化だけ見てもマージOKと思います。