Emacs 29 中 Xinput2 与 EAF 的兼容性问题

关于 EAF 的 PSA:

一、最近在做关于触屏支持的工作,Emacs 会对所有的 child window(包括被 reparent 的 QWindow)运行 XISelectEvents,Emacs 29 的 XInput2 用户可能发现 EAF 无法使用,如果出现这种问题,请说一声。

二、为了解决一些 GTK 带来的问题,Emacs 在未来可能会在一个 frame 的运行过程中重新创造 Window,所以不能保证 window-id 稳定,需要 EAF 端自己解决。

1 个赞

第一个问题,都知道reparent是qwindow,为啥还要管reparent window的事件?emacs管自己窗口的事件就可以,不要去动不归它管的窗口事件。

第二个问题,为啥要改window-id?frame运行啥情况需要重新创建window?window-id都不稳定要window有啥用?

能否别给开发者创造一些障碍?

Emacs 的 child frame 和各种 Xt 控件都是被 reparent 的 Window,而 Emacs 不容易判定一个 Window 是否属于其他进程。

而 frame 改变 XID 是因为改变 NET_WM_STATE 会导致 XI2 下的 Gtk 无限循环 ConfigureNotify 和 ConfigureRequest,导致切换全屏时死机。

顺便说一声管理其他 Window 不是 Emacs 的责任,其他进程向 Emacs frame 上贴 Window 并不是支持的行为,我门不会为了这些应用阻碍 Emacs 本身的发展。

每个xwindow都可以知道自己属于哪个pid,xserver肯定知道,只需要跟xserver发消息就知道pid。

NET_WM_STATE 改变导致全屏死机,很有可能是窗口焦点和输入事件焦点处理深层次原因,但是不要用新建window去绕过。

我就想表达emacs正确处理自己进程和窗口就好了,不要因为一些奇奇怪怪的理由去workaround。

BTW, 我不认为xwindow获取不了pid或者configure事件出错,需要你这样实现,更不认可reparent window这种x11标准协议哪点影响emacs本身的发展了,你要为了你自己的实现去破坏稳定window id这个API的兼容性?

1 个赞

首先,handle_one_xevent 中不能运行 XGetWindowProperty,所以不能去检查 child window 的 PID。 再说,有很多 toolkit 不遵守 _NET_WM_PID (包括 Emacs 内置的 lwlib),因此窗口的所有者不能依赖 _NET_WM_PID 判定,而 `XResQueryClientIds’ 没有受到所有 X server 的支持。

ConfigureEvent 无限循环是 GTK 3 本身的问题,如果想要彻底解决只能去发展 pgtk port,没有 pgtk 就只有这样绕过,绝对与 input focus 无关。

想要 window-id 稳定可以使用 lucid,或不使用 xinput2。

我的意思是最起码emacs知道哪些child window是emacs创建的,emacs代码就管它知道的xwindow,再不济,emacs自己xwindow设置一些特殊窗口属性都行,emacs不认识的窗口就不要去管,外部进程谁reparent谁负责事件处理,emacs就管好它自己的窗口。

第二个问题,如果是要支持触摸事件,建议针对特定图形库,按照gtk的设计,尊重gtk的事件处理就可以,需要触摸事件的用pgtk版本。不要为了触摸事件,去兼容各种图形库,甚至破坏现有API的兼容性。

以emacs现在开发模式,到处用workaround的方式去在x11上加补丁是正确的方式吗?x11处理好了,还要兼容不同桌面环境WM的事件处理喜好,这样干既破坏现有API兼容性,又无法彻底兼容各种桌面环境和图形库场景,有必要吗?

Emacs 不知道所有自己创建的窗口的 XID,特别是很多 Xaw3d 或 GTK 擅自创建的 Window。目前我们在 X11 方面的开发能力太少,没有时间做到重构,只能到处涂补丁。

window-id 稳定从来就不是 Emacs API 的一部分,Emacs 刚支持 GTK 不久,Jan Djarv(那段时间开发团队中的 X11 专家) 就表示其他程序不能依赖 outer-window-id 来判定 frame 的 XID。

回到最初的话题

有emacs自己创建的窗口不知道的情况就想办法加API让emacs知道,如果实在不知道就不要管这些不知道啥窗口的事件,为啥要对child window一棒子打死,接管我们都不知道窗口的事件?

第二个,GTK自身肯定对触摸事件处理没有无限循环的bug,bug出在emacs本身不是纯粹的gtk base应用,我相信pgtk版本会好很多。本质上是emacs自身和gtk兼容性问题。为啥要用新建window的方式绕过呢?为什么不让对触摸刚需的用户选择pgtk呢?

最后,上面两个问题本质上都可以x11 reparent都没关系,外部进程不管不就行了,为啥因为上面两个原因要对外部进程事件和外部进程依赖的稳定emacs xid动手呢?

三个风马牛不相及的问题,为啥要绕在一起呢?

触摸事件与ConfigureNotify/ConfigureRequest无限循环 bug 没有任何关系:Emacs 会吞掉所有的 XI_Touch*,GTK 没有机会处理。而这些事情与 XReparentWindow 很大:Emacs 中大部分 toolkit 子控件都是通过 child window 实现的,包括 GTK 上的 toolbar 按钮和 scrollbar,和 lucid 上的菜单栏按钮。

PGTK 的事归 PGTK,都没合并,更不可能为了 pgtk 影响 X port 的开发。

你有你做事的选择。

我个人严重鄙视两个行为:

  1. 没有道理的破坏现有API的兼容性,特别是理由还是workaround补丁

  2. emacs是社区的,维护现有API兼容性是大家都要考虑的,不是你个人的,不要把你自己观点等同于emacs

你如果真的为了这些workaround去改变API兼容性,我也会去邮件列表里写补丁改回这些没道理的补丁,最近闲的,好久没有去邮件列表扯淡了。

你可以反应,但是触摸屏支持的代码不会改变。(争论时请不要谈到 EAF 的浏览器功能,这个话题容易引起 RMS 的注意,只要他注意到 window-id 可能会被去除)

如果不想改变 EAF 的代码,编译时可以不开启 --with-xinput2。

没有啥代码是不会改变的,emacs是社区的,不是个人的。

不是你才可以改emacs代码。

2 个赞

不必,EAF早就在邮件列表中有讨论,RMS又不傻,他维护的是非自由软件代码不准进入emacs。

X11 reparent window是UNIX时代就存在的功能,自由软件和外部进程窗口合并,不存在源码级别联系,要不mplayer和vlc支持不同图形库的功能就不要做了。

我要讨论的是,为啥因为一些奇奇怪怪的理由去改现有窗口的xid?为了一些workaround去新建窗口的做法合适吗?

还是我上面观点,为了workaround新建窗口不是改变现有emacs窗口xid的理由。

xwidgets 添加 Xembed 就争吵了很久,最好别冒险。

X11 reparent window是UNIX时代就存在的功能,自由软件和外部进程窗口合并,不存在源码级别联系,要不mplayer和vlc支持不同图形库的功能就不要做了。

XReparentWindow 从古至今是用来实现控件的,与外部进程合并窗口要用 Xembed。

我要讨论的是,为啥因为一些奇奇怪怪的理由去改现有窗口的xid?为了一些workaround去新建窗口的做法合适吗?

目前没有找到更好的办法。

还是我上面观点,为了workaround新建窗口不是改变现有emacs窗口xid的理由。

请问 gtk_window_new 如何保留之前的 XID?

EAF是为了加入Emacs master分支吗?EAF用一个 window id 有啥冒险不冒险的?

那只是你个人的观点,XReparent是Linux图形桌面和窗口管理器常用技术,ffmpeg、mplayer、VLC等一系列开源软件都在用,XEmbed和XReparent爱用啥用啥。

没有找到更好的方式,就要Workaround?

Emacs的一个frame已经启动了,用的好好的,为啥要新建一个窗口? 就是为了Workaround解决你遇到的问题?

你为什么认为自己就是对的,自己要解决的任务才是重要的,别人的都是不重要的?按照Emacs的设计没有哪个API一直都是稳定API, Emacs的最佳的做事方式是,给每个人更多的选择,爱用那个用哪个。

EAF只是一个外部进程,通过X11技术粘贴到Emacs窗口上,和Emacs窗口独立进程,源码没关系,实现没关系,就是用X11的标准协议,碍你啥事了? 你要去操作非Emacs进程窗口的事件,同时还要为了Workaround去新建窗口,让EAF和任何外部程序都没办法获取稳定的XID。

你觉得你的做法本身是不是欠考虑? 还一本正经的告诉我新版会导致EAF没法用。

Emacs是属于社区的,不是你一个人的,讲点道理好不好? 不要以个人观点来代表Emacs!!!

没有找到更好的方式,就要Workaround?

workaround 总比死机好。

你为什么认为自己就是对的,自己要解决的任务才是重要的,别人的都是不重要的?按照Emacs的设计没有哪个API一直都是稳定API, Emacs的最佳的做事方式是,给每个人更多的选择,爱用那个用哪个。

首先,如果想用 reparent,你可以不开启 XInput 2,默认会处于关闭状态。 顺便举个例子:当时 Emacs 启用 double buffering 时怎么没人抱怨不能直接往 frame 的 Drawable 上绘画呢?

你这种 “自己是对的就好,破坏API到底影不影响别人,你根本就不关心” 的做法已经和Emacs这么多年让用户更多选择的基本原则相冲突了。

我不想再和你讨论,道不同。

如果你因为那些站不住脚的理由让 window-id 无法稳定使用,我们就在Emacs邮件列表上见吧,让整个Emacs社区大家一起讨论,“为啥遇到bug不去修根本问题,而是要采用新建窗口来绕过” 这种做法到底对不对吧。

我没时间修根本问题,补丁当然会很受欢迎。

全篇读下来没有看到 @oldosfan 正面回答任何一个问题,只是将自己拆东墙补西墙把功能稳定的feature拆掉作为workaround的行为跟Emacs的发展直接挂钩,并声称一个还在持续开发的自由软件新版本的代码不会改变?这是啥,只要是自己(或许会)push的代码就必须保留吗,Emacs姓Lu了?没有时间修复根本问题可以选择先放着不修也别破坏完好的功能啊??

重点是,你可以不选择使用 XInput 2,目前还是开发中的功能,默认没有开启,肯定会出现各种问题,需要各种解决方式。

请注意我还没有 push 关于改变 XID 的代码,只是说未来可能会改变,也没有说 EAF 一定会受到触摸代码的影响。

一、最近在做关于触屏支持的工作,Emacs 会对所有的 child window(包括被 reparent 的 QWindow)运行 XISelectEvents,Emacs 29 的 XInput2 用户可能发现 EAF 无法使用,如果出现这种问题,请说一声