Emacs の表示欠けの件

先日の、新メインPC/Ubuntu 20.04 への移行の際の未解決問題の一つの「Emacs の表示欠け」問題ですが…

あらためて再現動画を貼りますが、こんなんです。

あれから調べていたのですが、以下のことがわかりました。

  • 表示欠け状態は redraw-display または redraw-frame で修復できる。redisplay ではダメ。
  • emacs -q の初期設定で表示された *GNU Emacs* バッファでも再現する。
    • なのでフォント設定とか関係なさそう。
    • 表示欠けの部分が真っ白ではなくGNUアイコンの一部が描かれる場合がある。
  • ASCII 文字だけのバッファでも発生。
    • 日本語表示が原因というわけではなさそう。
  • scroll-down, scroll-down-command, recenter-top-bottom によるスクロールで再現するが常に再現するわけではない。
  • 表示欠けはウィンドウの最下行かその近くの行で発生する。

というわけで、ウインドウがスクロールするタイミングで redraw-frame を呼び出せばいいのでは?と思って以下のような設定をしてみました。

;; スクロール時に表示が欠けるバグの回避
(defun my-auto-redraw (win start)
  (redraw-frame))

(defun my-auto-redraw-setup ()
  (if (not (member 'my-auto-redraw window-scroll-functions))
      (progn
       (add-hook 'window-scroll-functions 'my-auto-redraw nil t))))

(add-hook 'after-change-major-mode-hook 'my-auto-redraw-setup)

スクロール発生時に呼び出される hook は window-scroll-functions ですが、buffer 毎に add-hook してあげないとダメみたいで、じゃあ buffer が作られる時に呼ばれる hook は?と思ったら、どうもないみたいなんですね…

代替案として after-change-major-mode-hook と buffer-list-update-hook が候補に上がっているのですが、buffer-list-update-hook が呼び出された時の current buffer がどれになるかよくわからなくて after-change-major-mode-hook でやりました。

これでうまくいくかと思ったら、表示欠けの発生自体は防げませんでした… でも C-l なり C-v なりでスクロールしたタイミングで修復されるので、ウィンドウの下の方で編集を続けるのでない限りは気にならなくなりました。表示が重くなったりちらついたりしないかと思ったのですが、GPUが速いせいか全然気にならないレベルでした。

とりあえずこれで様子見ですかね。バグレポとかした方がいいのかなぁ。でも検索しても他に発生してる報告を見かけないので環境特有の何かっぽいんですよね。うーむ…