当前位置: 首页 > news >正文

OpenKylin文件管理器界面层级切换问题

开发环境

            操作系统: OpenKylinqt版本  : 5.15.10

问题描述

        在使用wayland环境下,被遮挡住的界面在右键点击新标签中打开后,界面依旧被遮挡住了

        在使用xcb环境下,现象是正常的

排查过程

        从视频的现象上看,分析可能是右边界面因为某种原因又覆盖在左侧界面上,所以优先去排查是什么原因导致右边界面自动覆盖的

        从上到下的排查顺序是 : 应用代码->Qt源码->Qt源码(qt处理 xcb或wayland 事件的逻辑)

        首先是从源码去排查,在代码中找QApplication::activeWindow(),找了几个位置的代码,注释掉之后发现没有什么变化,应该不是应用代码的问题

        其次整个问题应该是属于事件传递、处理类型的,不算是控件功能类的,所以Qt源码中的控件类代码不需要进行排查(其实这一步还是耗费了一些时间,但没有什么收获,就不展开了)

        那么最后就要去排查xcb、wayland是否传递事件有差异,或者说是qt处理事件有差异,这一部分需要用gdb调试去看,不同环境下qt处理事件的路径

====两种环境运行的堆栈====XCB环境#0  QApplicationPrivate::notifyActiveWindowChange (this=0x7f133f0, previous=0x8d26980) at kernel/qapplication.cpp:2098#1  0x00007fa83133b275 in QGuiApplicationPrivate::processActivatedEvent (e=) at kernel/qguiapplication.cpp:2515#2  0x00007fa83131209c in QWindowSystemInterface::sendWindowSystemEvents (flags=flags@entry=...) at kernel/qwindowsysteminterface.cpp:1169#3  0x00007fa827afb75a in 【xcbSourceDispatch】 (source=) at ./src/plugins/platforms/xcb/qxcbeventdispatcher.cpp:105#4  0x00007fa832ac1847 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#5  0x00007fa832b1935f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#6  0x00007fa832ac0d7c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#7  0x00007fa830d0a016 in QEventDispatcherGlib::processEvents (this=0x8055c60, flags=...) at kernel/qeventdispatcher_glib.cpp:423#8  0x00007fa830cb0f6b in QEventLoop::exec (this=this@entry=0x7ffdb5a36290, flags=..., flags@entry=...)at ../../include/QtCore/../../src/corelib/global/qflags.h:69#9  0x00007fa830cb90c6 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121#10 0x00000000004432da in main ()---#0  QApplicationPrivate::openPopup (this=0x7f133f0, popup=popup@entry=0x7ffdb5a356f0) at kernel/qapplication.cpp:3756#1  0x00007fa831ba1d90 in QWidgetPrivate::show_helper (this=this@entry=0x8e0a760) at kernel/qwidget.cpp:7848#2  0x00007fa831ba4ae3 in QWidgetPrivate::setVisible (this=0x8e0a760, visible=) at kernel/qwidget.cpp:8141#3  0x00007fa831ce892d in QMenuPrivate::popup(QPoint const&, QAction*, std::function)(this=this@entry=0x8e0a760, p=..., atAction=atAction@entry=0x0, positionFunction=...) at widgets/qmenu.cpp:2640#4  0x00007fa831ce995a in QMenuPrivate::exec(QPoint const&, QAction*, std::function)(this=0x8e0a760, p=..., action=0x0, positionFunction=...) at widgets/qmenu.cpp:2720#5  0x00007fa831ce9aaf in QMenu::exec (this=, p=, action=) at widgets/qmenu.cpp:2710#6  0x0000000000483371 in ??? ()#7  0x00007fa830ce978f in QtPrivate::QSlotObjectBase::call (a=0x7ffdb5a35840, r=0x8721fd0, this=0x876fff0)at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398#8  doActivate (sender=0x8721fd0, signal_index=6, argv=0x7ffdb5a35840) at kernel/qobject.cpp:3925#9  0x00007fa830ce2a7f in QMetaObject::activate(sender=sender@entry=0x8721fd0, m=m@entry=0x7fa83207c0a0 , local_signal_index=local_signal_index@entry=3, argv=argv@entry=0x7ffdb5a35840) at kernel/qobject.cpp:3985#10 0x00007fa831b8a435 in QWidget::customContextMenuRequested (this=this@entry=0x8721fd0, _t1=...) at .moc/moc_qwidget.cpp:653#11 0x00007fa831ba5dd3 in QWidget::event (this=this@entry=0x8721fd0, event=event@entry=0x7ffdb5a35c70) at kernel/qwidget.cpp:8856#12 0x00007fa831c5092e in QFrame::event (this=0x8721fd0, e=0x7ffdb5a35c70) at widgets/qframe.cpp:550#13 0x00007fa830cb226b in QCoreApplicationPrivate::sendThroughObjectEventFilters(receiver=receiver@entry=0x874b9f0, event=event@entry=0x7ffdb5a35c70) at kernel/qcoreapplication.cpp:1190#14 0x00007fa831b62fee in QApplicationPrivate::notify_helper(this=this@entry=0x7f133f0, receiver=receiver@entry=0x874b9f0, e=e@entry=0x7ffdb5a35c70) at kernel/qapplication.cpp:3639#15 0x00007fa831b6a600 in QApplication::notify (this=, receiver=0x874b9f0, e=) at kernel/qapplication.cpp:3251#16 0x00007fa830cb24e8 in QCoreApplication::notifyInternal2 (receiver=0x874b9f0, event=0x7ffdb5a35c70) at kernel/qcoreapplication.cpp:1064#17 0x00007fa830cb2532 in QCoreApplication::forwardEvent (receiver=, event=, originatingEvent=)at kernel/qcoreapplication.cpp:1079#18 0x00007fa831bbebc9 in QWidgetWindow::handleMouseEvent (this=this@entry=0x87caa30, event=event@entry=0x7ffdb5a35f60)at kernel/qwidgetwindow.cpp:692#19 0x00007fa831bc15f0 in QWidgetWindow::event (this=0x87caa30, event=0x7ffdb5a35f60) at kernel/qwidgetwindow.cpp:300#20 0x00007fa831b62ffe in QApplicationPrivate::notify_helper (this=, receiver=0x87caa30, e=0x7ffdb5a35f60)at kernel/qapplication.cpp:3645#21 0x00007fa830cb24e8 in QCoreApplication::notifyInternal2 (receiver=0x87caa30, event=0x7ffdb5a35f60) at kernel/qcoreapplication.cpp:1064#22 0x00007fa830cb26be in QCoreApplication::sendSpontaneousEvent (receiver=, event=)at kernel/qcoreapplication.cpp:1474#23 0x00007fa83133ef7d in QGuiApplicationPrivate::processMouseEvent (e=0x8e093a0) at kernel/qguiapplication.cpp:2282#24 0x00007fa83131209c in QWindowSystemInterface::sendWindowSystemEvents (flags=flags@entry=...) at kernel/qwindowsysteminterface.cpp:1169#25 0x00007fa827afb75a in 【xcbSourceDispatch】 (source=) at ./src/plugins/platforms/xcb/qxcbeventdispatcher.cpp:105#26 0x00007fa832ac1847 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#27 0x00007fa832b1935f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#28 0x00007fa832ac0d7c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#29 0x00007fa830d0a016 in QEventDispatcherGlib::processEvents (this=0x8055c60, flags=...) at kernel/qeventdispatcher_glib.cpp:423#30 0x00007fa830cb0f6b in QEventLoop::exec (this=this@entry=0x7ffdb5a36290, flags=..., flags@entry=...)===============================================================================================================================================WAYLAND#0  QApplicationPrivate::openPopup (this=0x48284f0, popup=popup@entry=0x7ffff9d38be0) at kernel/qapplication.cpp:3756#1  0x00007f75655a1d90 in QWidgetPrivate::show_helper (this=this@entry=0x54fc510) at kernel/qwidget.cpp:7848#2  0x00007f75655a4ae3 in QWidgetPrivate::setVisible (this=0x54fc510, visible=) at kernel/qwidget.cpp:8141#3  0x00007f75656e892d in QMenuPrivate::popup(QPoint const&, QAction*, std::function)(this=this@entry=0x54fc510, p=..., atAction=atAction@entry=0x0, positionFunction=...) at widgets/qmenu.cpp:2640#4  0x00007f75656e995a in QMenuPrivate::exec(QPoint const&, QAction*, std::function)(this=0x54fc510, p=..., action=0x0, positionFunction=...) at widgets/qmenu.cpp:2720#5  0x00007f75656e9aaf in QMenu::exec (this=, p=, action=) at widgets/qmenu.cpp:2710#6  0x0000000000483371 in ??? ()#7  0x00007f75646e978f in QtPrivate::QSlotObjectBase::call (a=0x7ffff9d38d30, r=0x4e422a0, this=0x4e7f0a0)at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398#8  doActivate (sender=0x4e422a0, signal_index=6, argv=0x7ffff9d38d30) at kernel/qobject.cpp:3925#9  0x00007f75646e2a7f in QMetaObject::activate(sender=sender@entry=0x4e422a0, m=m@entry=0x7f7565a7c0a0 , local_signal_index=local_signal_index@entry=3, argv=argv@entry=0x7ffff9d38d30) at kernel/qobject.cpp:3985#10 0x00007f756558a435 in QWidget::customContextMenuRequested (this=this@entry=0x4e422a0, _t1=...) at .moc/moc_qwidget.cpp:653#11 0x00007f75655a5dd3 in QWidget::event (this=this@entry=0x4e422a0, event=event@entry=0x7ffff9d39160) at kernel/qwidget.cpp:8856#12 0x00007f756565092e in QFrame::event (this=0x4e422a0, e=0x7ffff9d39160) at widgets/qframe.cpp:550#13 0x00007f75646b226b in QCoreApplicationPrivate::sendThroughObjectEventFilters(receiver=receiver@entry=0x4e6cf70, event=event@entry=0x7ffff9d39160) at kernel/qcoreapplication.cpp:1190#14 0x00007f7565562fee in QApplicationPrivate::notify_helper(this=this@entry=0x48284f0, receiver=receiver@entry=0x4e6cf70, e=e@entry=0x7ffff9d39160) at kernel/qapplication.cpp:3639#15 0x00007f756556a600 in QApplication::notify (this=, receiver=0x4e6cf70, e=) at kernel/qapplication.cpp:3251#16 0x00007f75646b24e8 in QCoreApplication::notifyInternal2 (receiver=0x4e6cf70, event=0x7ffff9d39160) at kernel/qcoreapplication.cpp:1064#17 0x00007f75646b2532 in QCoreApplication::forwardEvent (receiver=, event=, originatingEvent=)at kernel/qcoreapplication.cpp:1079#18 0x00007f75655bebc9 in QWidgetWindow::handleMouseEvent (this=this@entry=0x4f75e70, event=event@entry=0x7ffff9d39450)at kernel/qwidgetwindow.cpp:692#19 0x00007f75655c15f0 in QWidgetWindow::event (this=0x4f75e70, event=0x7ffff9d39450) at kernel/qwidgetwindow.cpp:300#20 0x00007f7565562ffe in QApplicationPrivate::notify_helper (this=, receiver=0x4f75e70, e=0x7ffff9d39450)at kernel/qapplication.cpp:3645#21 0x00007f75646b24e8 in QCoreApplication::notifyInternal2 (receiver=0x4f75e70, event=0x7ffff9d39450) at kernel/qcoreapplication.cpp:1064#22 0x00007f75646b26be in QCoreApplication::sendSpontaneousEvent (receiver=, event=)at kernel/qcoreapplication.cpp:1474#23 0x00007f7564d3ef7d in QGuiApplicationPrivate::processMouseEvent (e=0x525eab0) at kernel/qguiapplication.cpp:2282#24 0x00007f7564d1209c in QWindowSystemInterface::sendWindowSystemEvents (flags=...) at kernel/qwindowsysteminterface.cpp:1169#25 0x00007f755b361930 in ??? () at /lib/x86_64-linux-gnu/【libQt5WaylandClient.so.5】#26 0x00007f7565d47847 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#27 0x00007f7565d9f35f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#28 0x00007f7565d46d7c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#29 0x00007f756470a016 in QEventDispatcherGlib::processEvents (this=0x4879c20, flags=...) at kernel/qeventdispatcher_glib.cpp:423#30 0x00007f75646b0f6b in QEventLoop::exec (this=this@entry=0x7ffff9d39780, flags=..., flags@entry=...)at ../../include/QtCore/../../src/corelib/global/qflags.h:69---#0  QApplicationPrivate::notifyActiveWindowChange (this=0x48284f0, previous=0x5489c10) at kernel/qapplication.cpp:2098#1  0x00007f7564d3b275 in QGuiApplicationPrivate::processActivatedEvent (e=) at kernel/qguiapplication.cpp:2515#2  0x00007f7564d1209c in QWindowSystemInterface::sendWindowSystemEvents (flags=flags@entry=...) at kernel/qwindowsysteminterface.cpp:1169#3  0x00007f7564d12308 in QWindowSystemInterface::flushWindowSystemEvents (flags=...) at kernel/qwindowsysteminterface.cpp:1138#4  0x00007f75646de010 in QObject::event (this=0x50eb390, e=0x7f7524002310) at kernel/qobject.cpp:1347#5  0x00007f7565562ffe in QApplicationPrivate::notify_helper (this=, receiver=0x50eb390, e=0x7f7524002310)at kernel/qapplication.cpp:3645#6  0x00007f75646b24e8 in QCoreApplication::notifyInternal2 (receiver=0x50eb390, event=0x7f7524002310) at kernel/qcoreapplication.cpp:1064#7  0x00007f75646b26ae in QCoreApplication::sendEvent (receiver=, event=) at kernel/qcoreapplication.cpp:1462#8  0x00007f75646b5471 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x4834be0)at kernel/qcoreapplication.cpp:1821#9  0x00007f75646b58f8 in QCoreApplication::sendPostedEvents (receiver=, event_type=)at kernel/qcoreapplication.cpp:1680#10 0x00007f756470a933 in postEventSourceDispatch (s=0x48386e0) at kernel/qeventdispatcher_glib.cpp:277#11 0x00007f7565d47847 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#12 0x00007f7565d9f35f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#13 0x00007f7565d46d7c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#14 0x00007f756470a016 in QEventDispatcherGlib::processEvents (this=0x4879c20, flags=...) at kernel/qeventdispatcher_glib.cpp:423#15 0x00007f75646b0f6b in QEventLoop::exec (this=this@entry=0x7ffff9d389c0, flags=..., flags@entry=...)at ../../include/QtCore/../../src/corelib/global/qflags.h:69#16 0x00007f75656e998f in QMenuPrivate::exec(QPoint const&, QAction*, std::function)(this=0x54fc510, p=..., action=0x0, positionFunction=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:121#17 0x00007f75656e9aaf in QMenu::exec (this=, p=, action=) at widgets/qmenu.cpp:2710#18 0x0000000000483371 in ??? ()#19 0x00007f75646e978f in QtPrivate::QSlotObjectBase::call (a=0x7ffff9d38d30, r=0x4e422a0, this=0x4e7f0a0)at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398#20 doActivate (sender=0x4e422a0, signal_index=6, argv=0x7ffff9d38d30) at kernel/qobject.cpp:3925#21 0x00007f75646e2a7f in QMetaObject::activate(sender=sender@entry=0x4e422a0, m=m@entry=0x7f7565a7c0a0 , local_signal_index=local_signal_index@entry=3, argv=argv@entry=0x7ffff9d38d30) at kernel/qobject.cpp:3985#22 0x00007f756558a435 in QWidget::customContextMenuRequested (this=this@entry=0x4e422a0, _t1=...) at .moc/moc_qwidget.cpp:653#23 0x00007f75655a5dd3 in QWidget::event (this=this@entry=0x4e422a0, event=event@entry=0x7ffff9d39160) at kernel/qwidget.cpp:8856#24 0x00007f756565092e in QFrame::event (this=0x4e422a0, e=0x7ffff9d39160) at widgets/qframe.cpp:550#25 0x00007f75646b226b in QCoreApplicationPrivate::sendThroughObjectEventFilters(receiver=receiver@entry=0x4e6cf70, event=event@entry=0x7ffff9d39160) at kernel/qcoreapplication.cpp:1190#26 0x00007f7565562fee in QApplicationPrivate::notify_helper(this=this@entry=0x48284f0, receiver=receiver@entry=0x4e6cf70, e=e@entry=0x7ffff9d39160) at kernel/qapplication.cpp:3639#27 0x00007f756556a600 in QApplication::notify (this=, receiver=0x4e6cf70, e=) at kernel/qapplication.cpp:3251#28 0x00007f75646b24e8 in QCoreApplication::notifyInternal2 (receiver=0x4e6cf70, event=0x7ffff9d39160) at kernel/qcoreapplication.cpp:1064#29 0x00007f75646b2532 in QCoreApplication::forwardEvent (receiver=, event=, originatingEvent=)at kernel/qcoreapplication.cpp:1079#30 0x00007f75655bebc9 in QWidgetWindow::handleMouseEvent (this=this@entry=0x4f75e70, event=event@entry=0x7ffff9d39450)at kernel/qwidgetwindow.cpp:692

分析堆栈后的结论 : 

        执行openPopup接口后QWidgetList *QApplication::popupWidgets就会被赋值,不为nullptr

        QApplicationPrivate::notifyActiveWindowChange接口中判断QWidgetList *QApplication::popupWidgets,如果不为nullptr,不会执行QApplication::setActiveWindow(这个接口的调用会激活窗口)

        两个环境下QApplicationPrivate::notifyActiveWindowChange和QApplicationPrivate::openPopup的执行顺序有关系

        xcb环境中先执行的 QApplicationPrivate::notifyActiveWindowChange 后执行 QApplicationPrivate::openPopup

        wayland环境中先执行 QApplicationPrivate::openPopup 后执行 QApplicationPrivate::notifyActiveWindowChange

观察到堆栈中libQt5WaylandClient库没有符号信息,于是我下载源码进行编译,安装debug包,查看堆栈如下:

结果发现wayland环境下没有wayland库的堆栈信息了,似乎又和libglib库有关系了,之前的分析似乎又不对了

            xcb #24 0x00007fa7a0f120e5 in QWindowSystemInterface::sendWindowSystemEvents (flags=..., flags@entry=...) at kernel/qwindowsysteminterface.cpp:1173#25 0x00007fa7976a77bf in xcbSourceDispatch (source=) at ./src/plugins/platforms/xcb/qxcbeventdispatcher.cpp:106#26 0x00007fa7a1f47847 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#27 0x00007fa7a1f9f35f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#28 0x00007fa7a1f46d7c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#29 0x00007fa7a090a016 in QEventDispatcherGlib::processEvents (this=0x6866850, flags=...) at kernel/qeventdispatcher_glib.cpp:423#30 0x00007fa7a08b0f6b in QEventLoop::exec (this=this@entry=0x7ffff641f230, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69#31 0x00007fa7a08b90c6 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121#32 0x00000000004432da in main ()wayland #24 0x00007f7c7ef120e5 in QWindowSystemInterface::sendWindowSystemEvents (flags=...) at kernel/qwindowsysteminterface.cpp:1173#25 0x00007f7c77302930 in userEventSourceDispatch (source=) at ./src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp:74#26 0x00007f7c7ff47847 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#27 0x00007f7c7ff9f35f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#28 0x00007f7c7ff46d7c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0#29 0x00007f7c7e90a016 in QEventDispatcherGlib::processEvents (this=0x5ab7440, flags=...) at kernel/qeventdispatcher_glib.cpp:423#30 0x00007f7c7e8b0f6b in QEventLoop::exec (this=this@entry=0x7ffcc299e2c0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69#31 0x00007f7c7e8b90c6 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121#32 0x00000000004432da in main ()

  这里也许就和qtwayland那边没有什么关联了

修改方法

        目前看,这个问题只能是修改qtbase源码,取消一些判断的逻辑

            void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous){Q_UNUSED(previous);QWindow *wnd = QGuiApplicationPrivate::focus_window;//改成下面这段代码即可,后面我查了一下,qt6也已经这样修改了#ifndef Q_OS_MACOSif (inPopupMode()) {// some delayed focus event to ignore    return;}#endifQWidget *tlw = qt_tlw_for_window(wnd);QApplication::setActiveWindow(tlw);// QTBUG-37126, Active X controls may set the focus on native child widgets.if (wnd && tlw && wnd != tlw->windowHandle()) {if (QWidgetWindow *widgetWindow = qobject_cast(wnd))if (QWidget *widget = widgetWindow->widget())if (widget->inherits("QAxHostWidget"))widget->setFocus(Qt::ActiveWindowFocusReason);}}

相关文章:

  • kernel版本号
  • 依赖倒置原则 (Dependency Inversion Principle, DIP)
  • 实时商品数据对接实战:唯品会 API 接口调用与详情页采集教程
  • 主键与唯一键详解:概念、区别与面试要点
  • uniapp-商城-72-shop(5-商品列表,购物车实现回顾)
  • 触觉智能RK3506星闪开发板规格书 型号IDO-EVB3506-V1
  • STM32之IIC(重点)和OLED屏
  • 开源模型应用落地-模型上下文协议(MCP)-安全认证的创新与实践探索(十)
  • Win键+R键快捷命令汇总
  • Linux 资源限制(进程级,用户级,系统级)
  • [特殊字符]《计算机组成原理》第 8 章 - CPU 的结构和功能
  • ROS2学习(15)------ROS2 TF2 机器人坐标系管理器
  • 使用硬件调试器认识arm64的四大特权级
  • WPF【11_1】WPF实战-重构与美化(Entity Framework)
  • 【网络编程】十七、多路转接之 epoll
  • 想查看或修改 MinIO 桶的匿名访问权限(public/private/custom)
  • gdiplus,GDI +为什么2001年发布后几乎没有再更新了
  • 使用堡塔和XShell
  • @recogito/annotorious图像标注库
  • 哪些情况索引会失效?
  • 西瓜网络深圳网站建设 东莞网站建设/百度推广后台管理
  • 汽车租赁网站开发/站长工具综合查询2020
  • 凡科建站小程序制作/域名是什么意思
  • 萍乡土建设计网站/百度度小店申请入口
  • 做网站都需要年服务费吗/优化seo设置
  • 漳州做网站/2023年第三波新冠9月