EAF 中浏览器点击/拖拽问题

终于有时间试用EAF啦!PDF viewer真是emacs中性能最好的,python+lisp+js的协同编程也让emacs的扩展空间大大延伸,感谢 @manateelazycat

我希望用EAF来可视化笔记,但是发现在EAF的浏览器中每次点击都会黑一下屏,拖拽元素也很不顺畅:

Interaction | React Flow

不太清楚这是因为用的是mac系统,还是eaf本身的问题。看到曾经回复说:

因为eaf会抢焦点,所以正常拖拽操作会出问题,你双击以后移动鼠标就会高亮文本

所以现在想在EAF中操作echart、G6等图表,还是会有问题么?

1 个赞

我在Linux下拖拽没有黑屏,估计Mac下窗口管理器还是有问题吧。

Mac环境下很多情况就比较怪,没有Linux下那么完美。

你Mac下最大化Emacs窗口,而不要全屏窗口再试一下呢?

不是mac原生全屏,我看到wiki提示macOS native fullscreen可能会有问题。

神奇的是,从原生全屏切换成最大化的第一次操作没有问题,但是后续操作还是会一点击一黑屏:

capture

我想尝试的一个项目是,笔记用org-mode整理编辑,但是一些复杂的问题又可以在web可视化,帮助梳理思路。emacs中的笔记和web中的操作可以双向联动。感觉EAF框架会非常适合这个场景。可是Mac现在的这种兼容情况,感觉无法实际用起来……

我先学习一下,试着开发一下,现在还只是想法没有实践😂。等到项目真的有可用性后,再想想后续的系统方案,因为平时的工作、生活依赖的应用Linux还是找不到替代品。

再次感谢!

我知道了,是因为EAF mac的开发者为了解决其他应用遮挡Emacs窗口做了一个设定,当Emacs失去焦点的时候隐藏EAF窗口,你释放鼠标的时候,Emacs获取焦点后,EAF窗口又显示导致的闪烁。

所以听上去可以做一个判断,只有失去焦点的时候释放鼠标,才重新显示EAF窗口,如果焦点在当前emacs窗口,释放鼠标不重新显示eaf。这样似乎可以避免闪烁?

你的Elisp能力可以吗? 如果可以,我可以在Python端加一个函数来判定是否鼠标是否处于按下的状态或者获取焦点的状态。

你可以拿这个函数增加一个条件判断,应该就可以解决你这种屏幕点击的问题。

lisp基本的条件判断等语法还是没有问题的!原来这个在python端加函数就行啊。感谢,请让我试一试!

好的,我研究一下,加个接口给你,然后你修改 eaf.el 里面的 eaf–mac-focus-change 函数,增加一些条件判断就可以完美解决你的问题。

修正思路如下:

  1. 现在 eaf–mac-focus-change 函数的逻辑是通过 app-frontmost --name 命令来判断系统的焦点是否是聚焦到Emacs, 如果不是Emacs就会想办法隐藏EAF窗口
  2. 你需要根据现有逻辑做一个判断,当Emacs失去焦点的同时,如果鼠标在操作EAF窗口就不隐藏

因为我没有mac电脑,需要你自己折腾一下,判断鼠标是否在EAF窗口操作的接口我稍后发帖告诉你。

我刚刚给EAF加了 (eaf-call-sync "button_press_on_eaf_window") 这个API, 这个API的作用是检测用户是否正在某个EAF窗口中按下鼠标左键。

你只需在 eaf.el 文件的 eaf--mac-focus-change 函数中适当的位置添加 (eaf-call-sync "button_press_on_eaf_window") 这个条件判断应该就可以解决你说的闪烁问题。

1 个赞

这个方向我觉得没什么问题!现在拖拽非常流畅!就是有时候点击eaf窗口,会跳转到 *eaf* 窗口回不来: capture

我再研究一下,mac上eaf的窗口机制是不是类似:

  1. 点击eaf buffer后,调用handle-focus-out → after-focus-change-function → eaf–mac-focus-change
    • 这时 eaf–mac-has-focus → (eaf–mac-focus-out) 跳到 *eaf* 窗口
  2. 跳到 *eaf* 窗口后,调用handle-focus-in → after-focus-change-function → eaf–mac-focus-change
    • 这时 not eaf–mac-has-focus → (run-with-timer 0.1 nil #'eaf–mac-focus-in) 重新展示eaf buffer

你把 webengine.py emacs-application-framework/webengine.py at dcbb87a80dba6fdfcbb7dee8b03ebeab06a91a5b · emacs-eaf/emacs-application-framework · GitHub 里面 249 ~ 252行的代码注释掉,做下面的调试工作:

  1. Emacs上下分两个窗口,上面打开浏览器页面,下面切换到 *eaf* 窗口
  2. 正常用鼠标操作,观察 *eaf* 窗口在什么事件会导致你说的 回不去 的问题
  3. 上面注释的第二个参数是Qt事件类型,Qt事件类型对照表可以从 QEvent Class | Qt Core 5.15.8 查到

只要你能稳定重现什么Qt事件导致焦点切换异常,我就可以远程告诉你怎么修复这个细节问题。

这样理解是不对的,是系统通知了Emacs焦点有变动,我们在after-focus-change-function里面再通过app-frontmost去判断是由Emacs切换到了其他应用,还是从其他应用切换回了Emacs。之前因为只处理了鼠标的点击操作,所以一旦切换到了Python就可以马上回到Emacs。处理焦点变动要小心的是after-focus-change-function触发的时候系统还不一定完成了真正的切换,这跟是由键盘还是鼠标进行的切换以及Emacs的版本都有关系,因此一定要在run-with-timer后用app-front-most判断才是安全的。

想要稳定的鼠标操作也可以试一试开了xwidget-webkit的Emacs版本,不过其他功能相比EAF少了很多。

我把每步代码逐行打印,最后发现导致出问题的,不是按键的问题,而是我的电脑调用的是python3,而不是python,所以按照原来的逻辑,点击emacs,会错误地认为app-frontmost既非 python 也非 emacs,focus out又focus in,造成闪烁:

capture

把判定条件的Python 改成 python3 貌似解决了我的问题,点击不会闪烁,drag也正常:

capture1

感谢 @manateelazycat 指出正确的方向,感谢 @lhpfvs 解释焦点的处理机制!

另外,这个需要提个PR么?

1 个赞

帮忙提交一个PR吧,我没有mac电脑无法进行验证,你这个补丁对于Mac用户非常重要,感谢你的反馈和帮助。 :wink:

你的意思,不用我上面提供那个检测鼠标的API, 只用把 python3 加入就可以了?

我的情况确实不用检测鼠标的API就能解决了。在发现检测鼠标的API加入后还有闪烁后,我研究了一下处理焦点的机制,结果发现是,由于python3没有加入,导致点击eaf窗口,会错误地认为app-frontmost既非 python 也非 emacs,触发focus out。

已经合并了,感谢补丁。

1 个赞