minad / corfu

:desert_island: corfu.el - COmpletion in Region FUnction
GNU General Public License v3.0
1.15k stars 43 forks source link

Lag when completing or exiting completion on Emacs 29 #307

Closed yoav-za closed 1 year ago

yoav-za commented 1 year ago

I started experiencing a noticeable lag when using corfu-auto after upgrading my Emacs to version 29 from version 28. Specifically, the lag occurs when completing a word and when exiting completion by either hitting the space key or by deleting the last character in a word. It looks very similar to the behavior described in https://github.com/minad/corfu/issues/48 before you issued the fix. I reverted back to Emacs 28 and I did not experience the lag anymore.

I created a minimal Emacs configuration that includes just the corfu package and I can confirm that I'm experiencing the issue only on Emacs 29:

(use-package corfu
  :demand t
  :init
  (setq corfu-auto t)
  :config
  (setq corfu-auto-delay 0) ;; Happens also without this, but makes it easier to notice the issue
  (setq corfu-auto-prefix 0) ;; Happens also without this, but makes it easier to notice the issue
  (setq corfu-quit-no-match t) ;; Happens also without this, but makes it easier to notice the issue
  (global-corfu-mode))

I use Emacs 29 that I built from the emacs-29 branch (078cf512). I run it on Linux. My build configuration is: ./configure --with-dbus --with-gif --with-jpeg --with-png --with-rsvg --with-tiff --with-xft --with-xpm --with-x-toolkit=gtk3 --with-gpm=no --with-modules --with-harfbuzz --with-cairo --with-json --with-native-compilation --with-pgtk --with-tree-sitter

minad commented 1 year ago

I cannot observe the issue myself with the Lucid toolkit on Emacs 29. Maybe don't use pgtk which is not recommended? There have been many changes in Emacs 29 related to the GUI, which could cause such a regression. In order to narrow down the issue one could bisect the Emacs source between 28 and 29, but this is a lot of work.

Besides that you could try debugging this in more detail as pushqrdx did in #48 and provide me with as much information as possible. You could add messages with timings in the Corfu source to figure out the place causing the latency increase. In #48 a bunch of issues were fixed and all fixes should still be intact:

This means that your observation is unrelated. The issue must be in the GUI code of Emacs itself and we may or may not have to adapt Corfu accordingly.

minad commented 1 year ago

One more thing you should check - did you recompile Corfu on Emacs 29? I observed some issues with child frames on Emacs 29 and added a workaround:

https://github.com/minad/corfu/blob/44df3d98b7ef5b2e745124ea46c761fca9760140/corfu.el#L441-L443

But this code will only be enabled if Corfu is reinstalled/recompiled on Emacs 29. If you use Corfu compiled on Emacs 28 in Emacs 29 it probably won't work too well.

yoav-za commented 1 year ago

Thank you for your response, minad.

I confirmed that when building Emacs without pgtk and using the lucid toolkit instead, this issue does not occur anymore. I was not aware that pgtk is not recommended (and couldn't find any reference to this).

It is important to note that when I tested the issue on the pgtk build, I switched to company-mode and did not notice any lag. It is the combination of pgtk and corfu that leads to this problem. Unfortunately I am not proficient enough in debugging elisp scripts, but I believe that I provided enough information for a skillful elisp developer to consistently reproduce and further debug this issue.

minad commented 1 year ago

I was not aware that pgtk is not recommended (and couldn't finvd any reference to this).

You can search the mailing list. Afaik pgtk even prints a warning when started on X. It should only be used on Wayland due to the lack of better alternatives.

It is important to note that when I tested the issue on the pgtk build, I switched to company-mode and did not notice any lag. It is the combination of pgtk and corfu that lead to this problem.

Yes, Corfu and Company are quite different. Corfu uses child frames and it seems that these are inefficiently implemented for pgtk.

Unfortunately I am not proficient enough in debugging elisp scripts, but I believe that I provided enough information for a skillful elisp developer to consistently reproduce and further debug this issue.

Sure. If I would have this issue myself or at least if I could reproduce it directly without building pgtk, I would dig into it. Given that it only occurs for pgtk I don't consider the issue very relevant. It should probably be fixed in the pgtk display engine itself anyway, since ideally all display engines should behave in the same way.

yoav-za commented 1 year ago

Thank you. I am aware that one should not use pgtk on X, and I do use wayland instead. This is why I built Emacs with pgtk to begin with. For now I will refrain from using it.

minad commented 1 year ago

Yes, the situation is a bit unfortunate. I had also some hopes about pgtk, since I had used the GTK build before for many years. Then it turned out that the pgtk build didn't really hold up to its promises. As a consequence I switched to the lucid build and I am perfectly happy with it - lightweight, fast, no serious issues and the retro style also fits to Emacs in case one uses the menu bar or context menus. ;)

pushqrdx commented 1 year ago

Adding (setq-default pgtk-wait-for-event-timeout 0) somewhere in early-init.el alleviates ~80% of the input lag experienced with pgtk, especially with anything that uses childframes such as corfu.