[wayland] wayland 下的父子窗口定位问题,有没有合适的解决办法?
Tofloor
poster avatar
redmibook
deepin
2023-07-25 23:06
Author

看到 deepin V23 引入了 wayland 环境,我们这些 Qt 开发者也当早做打算,但是发现一个普遍性的问题,Qt 的消息弹窗,对话框弹窗,甚至所有子窗口弹出都是据根父级窗口的位置计算的。而 wayland 不支持窗口间获取这些数据。

比如,随便写个弹窗,让它吐个坐标,在 wayland 下永远是 (0,0)

int x = this->geometry().x();
int y = this->geometry().y();
qDebug() << "Window position: (" << x << ", " << y << ")";

唯今之计,就是在启动脚本中指定一个临时变量,强指 xcb

QT_QPA_PLATFORM=xcb ./testApp

这实际是调用 x11 的接口来运行了,终不是长久之计。而 Qt 认为这是 wayland 协议的缺陷(bug),并无修复计划。

看到 deepin 博客上写过,深度截图搞定了这问题。

所以,针对这个问题,Qt框架内,有无符规范性的解决办法?

如果 Qt 放任这个问题,而 wayland 依然故我(他们一直这样),未来 deepin 怎么处理 Qt 程序这个兼容性问题?

盼复

Reply Favorite View the author
All Replies
justforlxz
deepin developers team
2023-07-25 23:24
#1

wayland 确实不允许获取窗口在全局中的坐标,我们目前还在考虑在 dwayland 扩展中增加一些自己的协议来支持这个功能。

并且 DDE 有一个 Qt 插件仓库,里面有一个 wayland shell integration 插件,是专门在 wayland 上做接口适配的,比如你调用的 geometry 方法,最终是这个插件提供的数据(也是它和 wayland composite 通信),所以只要不使用特别底层的功能,正常开发 Qt 即可。

Reply View the author
enforcee
deepin
2023-07-25 23:43
#2

https://wayland.app/protocols/xdg-shell
看看xdg-positioner。
我觉得就是Qt的开发者偷懒了。

再说点事情,窗口之间、窗口和合成器之间保持隔离是Wayland基本的安全特性和设计目标,如果这个都不要了,那就没必要上原生Wayland了,用XWayland又不是不行。又想用Wayland,又不想接受Wayland的特质,纯属建设空中楼阁。

Reply View the author
redmibook
deepin
2023-07-26 00:09
#3
enforcee

https://wayland.app/protocols/xdg-shell
看看xdg-positioner。
我觉得就是Qt的开发者偷懒了。

再说点事情,窗口之间、窗口和合成器之间保持隔离是Wayland基本的安全特性和设计目标,如果这个都不要了,那就没必要上原生Wayland了,用XWayland又不是不行。又想用Wayland,又不想接受Wayland的特质,纯属建设空中楼阁。

如果你说的「Qt开发者」是「Qt公司」,那确实,他们作为开发框架的提供者,理应解决图层渲染协议层面的数据通信问题。

这个「数据通信」是必要,不论是原生 wayland 的 api ,还是 x11,允许同一程序间的父子窗口通信都是不可或缺的,目前仅仅是 wayland 改变了 x11 下的通信方式罢了。

但是像我们这些「使用 Qt 框架」的「应用程序开发者」,确实不应接这口锅,像「消息弹窗」,「输入弹窗」这一大类父子窗口的基本组件,本该由开发框架予以提供的必要支持。如果需要重写这些基本组件,才能完成基本功能,比如上述的弹窗交互,那用 Qt 这个框架就没有什么意义了。

Reply View the author
redmibook
deepin
2023-07-26 00:28
#4
justforlxz

wayland 确实不允许获取窗口在全局中的坐标,我们目前还在考虑在 dwayland 扩展中增加一些自己的协议来支持这个功能。

并且 DDE 有一个 Qt 插件仓库,里面有一个 wayland shell integration 插件,是专门在 wayland 上做接口适配的,比如你调用的 geometry 方法,最终是这个插件提供的数据(也是它和 wayland composite 通信),所以只要不使用特别底层的功能,正常开发 Qt 即可。

是的,所有 Qt 框架使用者都不得不面对这个问题。

正常的开发流程,开发者本不该去关心这些控件底层的通信问题。

如果从一个父级窗口弹出的子窗口,都要开发者重写底层函数,这个框架也是属于要作大死了。

但是 Qt4.x 时,Qt官方发布的 qwidget 版本都不兼容 wayland 的坐标获取模式,

现在,连 Qt6.6 都出来了,依然没有任何修复这个问题的迹象。

Qt 员工在 Qt论坛里说过,这是 wayland 的问题,他们不会处理。

我看过 KDE 的处理方式,他们是重写了 sub-dialog ,但是不可能让每个 Qt 程序都重写一下,这太不现实了。

Reply View the author
enforcee
deepin
2023-07-26 00:30
#5
redmibook

如果你说的「Qt开发者」是「Qt公司」,那确实,他们作为开发框架的提供者,理应解决图层渲染协议层面的数据通信问题。

这个「数据通信」是必要,不论是原生 wayland 的 api ,还是 x11,允许同一程序间的父子窗口通信都是不可或缺的,目前仅仅是 wayland 改变了 x11 下的通信方式罢了。

但是像我们这些「使用 Qt 框架」的「应用程序开发者」,确实不应接这口锅,像「消息弹窗」,「输入弹窗」这一大类父子窗口的基本组件,本该由开发框架予以提供的必要支持。如果需要重写这些基本组件,才能完成基本功能,比如上述的弹窗交互,那用 Qt 这个框架就没有什么意义了。

不对,我刚才测试了一下Plasma,什么问题都没有
shamed
楼主用的是什么合成器?

Reply View the author
redmibook
deepin
2023-07-26 00:33
#6
enforcee

不对,我刚才测试了一下Plasma,什么问题都没有
shamed
楼主用的是什么合成器?

KDE 的处理方式,他们是重写了 sub-dialog

但是仅限系统自带程序。

第三方 Qt 应用,依然是弹窗飘移。

Reply View the author
enforcee
deepin
2023-07-26 00:55
#7
redmibook

KDE 的处理方式,他们是重写了 sub-dialog

但是仅限系统自带程序。

第三方 Qt 应用,依然是弹窗飘移。

原来是这样。不过我试了点其他Qt应用,似乎和KDE应用的表现没有不同,是新版的kwin用了另外的处理方法吗

confused

Reply View the author
redmibook
deepin
2023-07-26 01:05
#8
enforcee

原来是这样。不过我试了点其他Qt应用,似乎和KDE应用的表现没有不同,是新版的kwin用了另外的处理方法吗

confused

「其他Qt应用」,可能并不是原生 Qt 应用,以及做过 xcb 的设定。

需要写个 Demo 验证:https://github.com/cppxiaozhu/Demo

Reply View the author
babyfengfjx
Super Moderator
CQA
2023-07-26 01:14
#9

wayland后面好像要重新做,还是等出新版本后再折腾咯,目前使用还是X11相对OK一些~

Reply View the author
enforcee
deepin
2023-07-26 01:15
#10
redmibook

「其他Qt应用」,可能并不是原生 Qt 应用,以及做过 xcb 的设定。

需要写个 Demo 验证:https://github.com/cppxiaozhu/Demo

我保证没有,因为我用GNOME,确实是有这个问题

Reply View the author
redmibook
deepin
2023-07-26 01:28
#11
babyfengfjx

wayland后面好像要重新做,还是等出新版本后再折腾咯,目前使用还是X11相对OK一些~

确实,比较诧异的是,Qt公司的员工明确说过,这是 wayland 问题,他们没有修复计划。

但是 wayland 自身的发展太缓慢了,有生之年似乎看不到了。

Reply View the author
忘记、过去
deepin
2023-07-26 01:44
#12
redmibook

确实,比较诧异的是,Qt公司的员工明确说过,这是 wayland 问题,他们没有修复计划。

但是 wayland 自身的发展太缓慢了,有生之年似乎看不到了。

DDE 环境下有 dwayland 插件,好像只要子窗口设置过父对象,默认 show() 显示的初始位置就在父窗口正中间来着,也不会出现 Dialog 或者 Tool 类窗口和主窗口抢占焦点、互相遮挡的问题......

但是想移动子窗口的话就只能等待 show() 完成之后才能移动了,在此之前的 move() 操作都是无效的。坐标的话只能全部映射到全局坐标处理了......

Reply View the author
redmibook
deepin
2023-07-26 01:54
#13
忘记、过去

DDE 环境下有 dwayland 插件,好像只要子窗口设置过父对象,默认 show() 显示的初始位置就在父窗口正中间来着,也不会出现 Dialog 或者 Tool 类窗口和主窗口抢占焦点、互相遮挡的问题......

但是想移动子窗口的话就只能等待 show() 完成之后才能移动了,在此之前的 move() 操作都是无效的。坐标的话只能全部映射到全局坐标处理了......

OK,你们有在处理这个问题,那实在是太好了。

我们普通开发者,就不必关心这些了。

Reply View the author