Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Posframe is slow if emacs is built using athena/lucid toolkit #45

Closed
junyi-hou opened this issue Sep 9, 2019 · 15 comments
Closed

Posframe is slow if emacs is built using athena/lucid toolkit #45

junyi-hou opened this issue Sep 9, 2019 · 15 comments

Comments

@junyi-hou
Copy link

Emacs stuck for ~half second every time posframe-show is called if emacs is built with athena toolkit. However, with gtk toolkit this is not such lag.

OS: gentoo, emacs is built with flag athena which, I think, is equivilant to emacs built with --with-x-toolkit=athena.

Just thought it would be nice if it is mentioned somewhere in the readme.

@tumashu
Copy link
Owner

tumashu commented Sep 10, 2019

What is athena?

@junyi-hou
Copy link
Author

I think it is a library emacs uses to draw stuffs in x. My understanding is that it is just an alternative to gtk.

@tumashu
Copy link
Owner

tumashu commented Nov 2, 2019

Added to NOTE,thanks!

@tumashu tumashu closed this as completed Nov 2, 2019
@tumashu tumashu reopened this Jan 22, 2020
@tumashu
Copy link
Owner

tumashu commented Jan 22, 2020

@tumashu tumashu changed the title Posframe is slow if emacs is built using athena toolkit Posframe is slow if emacs is built using athena/lucid toolkit Jan 22, 2020
@tumashu
Copy link
Owner

tumashu commented Jan 22, 2020

feng@debian:~/emacs/emacs$ cat configure |grep athena
                          gtk3, lucid or athena, motif, no)
	    a | at | ath | athe | athen | athena )	val=athena ;;
this option's value should be 'yes', 'no', 'lucid', 'athena', 'motif', 'gtk',
'athena' and 'lucid' are synonyms." "$LINENO" 5
    lucid | athena | motif)
/usr/athena/include
      athena | lucid ) USE_X_TOOLKIT=LUCID ;;
feng@debian:~/emacs/emacs$ 

@dgutov
Copy link
Contributor

dgutov commented Jan 22, 2020

Someone should benchmark and find which low-level operation takes all this time. Maybe using M-x profiler-start.

Personally, the Lucid build looks very fast (Ubuntu 19.04/GNOME).

@rrudakov
Copy link

I use lucid build on Linux with XMonad. Profiler reports:
Memory
CPU
Hope this will help anyhow.

@dgutov
Copy link
Contributor

dgutov commented Jan 22, 2020

My best guess here is that frame creation takes time. But it should only happen once.

You can wrap some key forms in posframe.el with benchmarking calls to track it:

@@ -511,57 +511,64 @@
       (posframe--mouse-banish parent-frame)
 
       ;; Create posframe
-      (setq posframe
-            (posframe--create-posframe
-             buffer
-             :font font
-             :parent-frame parent-frame
-             :left-fringe left-fringe
-             :right-fringe right-fringe
-             :internal-border-width internal-border-width
-             :internal-border-color internal-border-color
-             :foreground-color foreground-color
-             :background-color background-color
-             :keep-ratio keep-ratio
-             :respect-header-line respect-header-line
-             :respect-mode-line respect-mode-line
-             :override-parameters override-parameters))
+      (message "create %s"
+               (benchmark-elapse
+                 (setq posframe
+                       (posframe--create-posframe
+                        buffer
+                        :font font
+                        :parent-frame parent-frame
+                        :left-fringe left-fringe
+                        :right-fringe right-fringe
+                        :internal-border-width internal-border-width
+                        :internal-border-color internal-border-color
+                        :foreground-color foreground-color
+                        :background-color background-color
+                        :keep-ratio keep-ratio
+                        :respect-header-line respect-header-line
+                        :respect-mode-line respect-mode-line
+                        :override-parameters override-parameters))))
 
       ;; Insert string into the posframe buffer
       (posframe--insert-string string no-properties)
 
       ;; Set posframe's size
-      (posframe--set-frame-size
-       posframe height min-height width min-width)
 
-      ;; Move posframe
-      (posframe--set-frame-position
-       posframe
-       (posframe-run-poshandler
-        `(;All poshandlers will get info from this plist.
-          :position ,position
-          :position-info ,position-info
-          :poshandler ,poshandler
-          :font-height ,font-height
-          :font-width ,font-width
-          :posframe ,posframe
-          :posframe-width ,(frame-pixel-width posframe)
-          :posframe-height ,(frame-pixel-height posframe)
-          :posframe-buffer ,buffer
-          :parent-frame ,parent-frame
-          :parent-frame-width ,parent-frame-width
-          :parent-frame-height ,parent-frame-height
-          :parent-window ,parent-window
-          :parent-window-top ,parent-window-top
-          :parent-window-left ,parent-window-left
-          :parent-window-width ,parent-window-width
-          :parent-window-height ,parent-window-height
-          :mode-line-height ,mode-line-height
-          :minibuffer-height ,minibuffer-height
-          :header-line-height ,header-line-height
-          :x-pixel-offset ,x-pixel-offset
-          :y-pixel-offset ,y-pixel-offset))
-       parent-frame-width parent-frame-height)
+      (message "size %s"
+               (benchmark-elapse
+                 (posframe--set-frame-size
+                  posframe height min-height width min-width)))
+
+      (message "position %s"
+               (benchmark-elapse
+                 ;; Move posframe
+                 (posframe--set-frame-position
+                  posframe
+                  (posframe-run-poshandler
+                   `(;All poshandlers will get info from this plist.
+                     :position ,position
+                     :position-info ,position-info
+                     :poshandler ,poshandler
+                     :font-height ,font-height
+                     :font-width ,font-width
+                     :posframe ,posframe
+                     :posframe-width ,(frame-pixel-width posframe)
+                     :posframe-height ,(frame-pixel-height posframe)
+                     :posframe-buffer ,buffer
+                     :parent-frame ,parent-frame
+                     :parent-frame-width ,parent-frame-width
+                     :parent-frame-height ,parent-frame-height
+                     :parent-window ,parent-window
+                     :parent-window-top ,parent-window-top
+                     :parent-window-left ,parent-window-left
+                     :parent-window-width ,parent-window-width
+                     :parent-window-height ,parent-window-height
+                     :mode-line-height ,mode-line-height
+                     :minibuffer-height ,minibuffer-height
+                     :header-line-height ,header-line-height
+                     :x-pixel-offset ,x-pixel-offset
+                     :y-pixel-offset ,y-pixel-offset))
+                  parent-frame-width parent-frame-height)))
 
       ;; Delay hide posframe when timeout is a number.
       (posframe--run-timeout-timer posframe timeout)

@tumashu
Copy link
Owner

tumashu commented Jan 22, 2020

I think it is set-frame-position too slow

(posframe-show "test" :string "aaaaaaaa"
               :background-color "red")

(setq child-frame
      (with-current-buffer "test"
        posframe--frame))

(setq p nil)

(defun test ()
  (setq p (if (equal p '(10 10))
              '(100 100)
            '(10 10)))
  (set-frame-position child-frame (car p) (cadr p))
  (redraw-frame child-frame)
  (princ p))

(benchmark 1 '(test))

@tumashu
Copy link
Owner

tumashu commented Jan 22, 2020

(benchmark 5 '(test))

"Elapsed time: 1.576151s"

@tumashu
Copy link
Owner

tumashu commented Jan 22, 2020

If I use gtk version, the result is:

(benchmark 5 '(test))

"Elapsed time: 0.000332s"

@dgutov
Copy link
Contributor

dgutov commented Jan 22, 2020

Okay, yes, same here. So moving is indeed slow using Lucid build. Guess company-posframe doesn't do that very often, so I didn't notice.

@tumashu
Copy link
Owner

tumashu commented Jan 22, 2020

yes, posframe have position cache,

@dgutov
Copy link
Contributor

dgutov commented Mar 13, 2020

Please read this: tumashu/company-posframe#2 (comment)

Athena builds should probably benefit as much as Lucid ones.

@tumashu
Copy link
Owner

tumashu commented Apr 7, 2020

This issue should be fixed, by https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-27&id=c49d379f17bcb0ce82604def2eaa04bda00bd5ec , thanks very very much for @dgutov and Martin Rudalics's hard work :-)

@tumashu tumashu closed this as completed Apr 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants