把函数 posframe-hide-all 重写成直接 error ,然后看异常栈
debug-on-entry posframe-hide 的时候会出现,但是并不是每次 posframe 消失就出现。 这个像是我打空格,或者回车时候正常的 posframe-hide。
Debugger entered--entering a function:
* posframe-hide(" *rime-posframe*")
(if (string-blank-p content) (posframe-hide rime-posframe-buffer) (apply #'posframe-show rime-posframe-buffer :string content rime-posframe-properties))
(if (and (featurep 'posframe) (display-graphic-p)) (if (string-blank-p content) (posframe-hide rime-posframe-buffer) (apply #'posframe-show rime-posframe-buffer :string content rime-posframe-properties)) (rime--popup-display-content content))
rime--posframe-display-content("")
(cond ((eql rime-show-candidate 'minibuffer) (rime--minibuffer-display-content content)) ((eql rime-show-candidate 'message) (message content)) ((eql rime-show-candidate 'popup) (rime--popup-display-content content)) ((eql rime-show-candidate 'posframe) (rime--posframe-display-content content)) (t (progn)))
(if (minibufferp) (rime--minibuffer-message content) (cond ((eql rime-show-candidate 'minibuffer) (rime--minibuffer-display-content content)) ((eql rime-show-candidate 'message) (message content)) ((eql rime-show-candidate 'popup) (rime--popup-display-content content)) ((eql rime-show-candidate 'posframe) (rime--posframe-display-content content)) (t (progn))))
rime--show-content("")
rime--show-candidate()
rime--redisplay()
(cond ((not handled) (list key)) (commit (rime--clear-overlay) (mapcar 'identity commit)) (t (if (and (rime--should-inline-ascii-p) commit-text-preview (not (rime--ascii-mode-p))) (progn (rime--inline-ascii))) (rime--redisplay)))
(unwind-protect (cond ((not handled) (list key)) (commit (rime--clear-overlay) (mapcar 'identity commit)) (t (if (and (rime--should-inline-ascii-p) commit-text-preview (not (rime--ascii-mode-p))) (progn (rime--inline-ascii))) (rime--redisplay))) (rime--refresh-mode-state))
(let* ((context (rime-lib-get-context)) (commit-text-preview (alist-get 'commit-text-preview context)) (preedit (alist-get 'preedit (alist-get 'composition context))) (commit (rime-lib-get-commit))) (unwind-protect (cond ((not handled) (list key)) (commit (rime--clear-overlay) (mapcar 'identity commit)) (t (if (and (rime--should-inline-ascii-p) commit-text-preview (not (rime--ascii-mode-p))) (progn (rime--inline-ascii))) (rime--redisplay))) (rime--refresh-mode-state)))
(progn (let* ((context (rime-lib-get-context)) (commit-text-preview (alist-get 'commit-text-preview context)) (preedit (alist-get 'preedit (alist-get 'composition context))) (commit (rime-lib-get-commit))) (unwind-protect (cond ((not handled) (list key)) (commit (rime--clear-overlay) (mapcar 'identity commit)) (t (if (and (rime--should-inline-ascii-p) commit-text-preview (not ...)) (progn (rime--inline-ascii))) (rime--redisplay))) (rime--refresh-mode-state))))
(unwind-protect (progn (let* ((context (rime-lib-get-context)) (commit-text-preview (alist-get 'commit-text-preview context)) (preedit (alist-get 'preedit (alist-get 'composition context))) (commit (rime-lib-get-commit))) (unwind-protect (cond ((not handled) (list key)) (commit (rime--clear-overlay) (mapcar 'identity commit)) (t (if (and ... commit-text-preview ...) (progn ...)) (rime--redisplay))) (rime--refresh-mode-state)))) (if modified nil (restore-buffer-modified-p nil)))
(let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (let* ((context (rime-lib-get-context)) (commit-text-preview (alist-get 'commit-text-preview context)) (preedit (alist-get 'preedit (alist-get ... context))) (commit (rime-lib-get-commit))) (unwind-protect (cond ((not handled) (list key)) (commit (rime--clear-overlay) (mapcar ... commit)) (t (if ... ...) (rime--redisplay))) (rime--refresh-mode-state)))) (if modified nil (restore-buffer-modified-p nil))))
(let ((handled (rime-lib-process-key key 0))) (let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (let* ((context (rime-lib-get-context)) (commit-text-preview (alist-get ... context)) (preedit (alist-get ... ...)) (commit (rime-lib-get-commit))) (unwind-protect (cond (... ...) (commit ... ...) (t ... ...)) (rime--refresh-mode-state)))) (if modified nil (restore-buffer-modified-p nil)))))
(if (and (not (rime--should-enable-p)) (not (rime--has-composition (rime-lib-get-context)))) (list key) (let ((handled (rime-lib-process-key key 0))) (let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (let* ((context ...) (commit-text-preview ...) (preedit ...) (commit ...)) (unwind-protect (cond ... ... ...) (rime--refresh-mode-state)))) (if modified nil (restore-buffer-modified-p nil))))))
(progn (if (and (not (rime--should-enable-p)) (not (rime--has-composition (rime-lib-get-context)))) (list key) (let ((handled (rime-lib-process-key key 0))) (let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (let* (... ... ... ...) (unwind-protect ... ...))) (if modified nil (restore-buffer-modified-p nil)))))))
(if (rime--rime-lib-module-ready-p) (progn (if (and (not (rime--should-enable-p)) (not (rime--has-composition (rime-lib-get-context)))) (list key) (let ((handled (rime-lib-process-key key 0))) (let* ((modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) (inhibit-modification-hooks t)) (unwind-protect (progn (let* ... ...)) (if modified nil (restore-buffer-modified-p nil))))))))
rime-input-method(105)
是的,不同的buffer都是这样的情况。
不用 posframe
就没有这个问题, popup
和 minibuffer
都正常。
我是输入 s
的时候异常,而且输入后 posframe 反应很慢。
你是说posframe出来以后反应就很慢吗?如果 posframe 始终很慢的话,应该和 emacs 没有用 gtk 有关系。至于 hide 的话,就不太清楚了。
这个是什么意思?难道GUI Emacs不是用的GTK么?
我用二分法找到问题了。。。 但是还不知道该怎么改,要呼叫一下 @seagle0128 一起来研究下。
开了 doom-modeline 就不正常,关掉 doom-modeline 就正常了。@stardiviner 看你是不是也是这个问题。试试 doom-mode-line-mode 把那个 modeline 关掉看看是不是好了。
child frame中禁用modeline了吗?
我这边确认了,确实关掉 doom-modeline 就好了。
没看到关于 child-frame 特别的设置,有没有示例的代码,我可以测试下是不是 child-frame 打开 modeline 的影响。
就是在child-frame的buffer里面设置 (setq-local mode-line-format nil)
我加上了代码
(with-current-buffer rime-posframe-buffer
(setq-local mode-line-format nil))
没什么改变。我去那个rime 的隐藏 buffer 里面去看,确认了 mode-line-format 的值已经是 nil 了。
是不是 doom-modeline 对焦点有特殊处理?这个可能影响 posframe
posframe 有一个hook 设置
(add-hook 'focus-in-hook #'posframe--redirect-posframe-focus)
pyim 的 posframe 使用就没有问题,就是这个 emacs-rime 使用 posframe 配合 doom-modeline 有问题。
doom-modeline 里面确实有关于焦点处理的 hook.
(with-no-warnings
(if (boundp 'after-focus-change-function)
(progn
(defun doom-modeline-refresh-frame ()
(setq doom-modeline-current-window nil)
(cl-loop for frame in (frame-list)
if (eq (frame-focus-state frame) t)
return (setq doom-modeline-current-window
(doom-modeline--get-current-window frame)))
(force-mode-line-update))
(add-function :after after-focus-change-function #'doom-modeline-refresh-frame))
(progn
(add-hook 'focus-in-hook #'doom-modeline-set-selected-window)
(add-hook 'focus-out-hook #'doom-modeline-unset-selected-window))))
以及
(with-no-warnings
(if (boundp 'after-focus-change-function)
(progn
(defun doom-modeline-focus-change (&rest _)
(if (frame-focus-state)
(doom-modeline-focus)
(doom-modeline-unfocus)))
(advice-add #'handle-switch-frame :after #'doom-modeline-focus-change)
(add-function :after after-focus-change-function #'doom-modeline-focus-change))
(progn
(add-hook 'focus-in-hook #'doom-modeline-focus)
(add-hook 'focus-out-hook #'doom-modeline-unfocus))))
我把这个去掉了,还是一样的表现。
我准备去对比下 pyim 和 emacs-rime 中关于 posframe 的部分。
rime.el 里面, rime–posframe-display-content 函数,其中对 posframe-show 的调用是使用的一个 apply 方式,
(apply #'posframe-show rime-posframe-buffer
:string content
rime-posframe-properties)
rime-posframe-properties 是一个 plist 形式定义的参数。我给改成
(posframe-show rime-posframe-buffer :string content)
就好了。有点神奇。
直接调用和 apply 感觉不应该有这样的差异。。。 另外我想知道,直接 posframe-show 有没有办法将这些相当于 face 定义的外观作为变量传进去。
已放弃doom了,
我也在逐渐把 doom 的一些默认配置关掉,改成自己的了。不过就这个问题来说,不是 doom 的问题。我也只是找到了互相有冲突的包,没找到根本问题。
你以做个 profiling,看看到底是哪个调用占用 CPU。
是不是posframe的某个属性有影响