QT窗口无法激活弹出问题排查记录

ops/2024/9/25 7:09:10/

问题背景

问题环境

            操作系统: 银河麒麟V10SP1qt版本  : 5.12.12

碰见了一个问题应用最小化,然后激活程序窗口无法弹出

            这里描述一下代码的逻辑,使用QLocalServer实现一个单例进程,具体的功能就是在已存在一个程序A进程时,再启动这个程序A,新的程序A进程会被杀死,然后激活已存在的进程,使窗口弹出

跟踪代码发现走到了激活函数(如下所示)

            this->raise();this->activateWindow();
问题现象如下,确实是有激活效果,图标闪烁了,但是窗口在最小化的情况不会弹


排查过程

        首先,我想写个简易的demo来复现这个问题,但是下面所示的代码并不能复现出上面提到的问题,最小化窗口可以被激活弹出,所以我还是得用原来的代码进行排查

              MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){ui->setupUi(this);//使用定时器触发执行槽函数QObject::connect(&m_timer, &QTimer::timeout, this,&MainWindow::slottimer);}MainWindow::~MainWindow(){delete ui;}//3秒钟执行一次void MainWindow::on_pushButton_clicked(){m_timer.start(3000);}//激活窗口void MainWindow::slottimer(){this->raise();this->activateWindow();}

为了排除操作系统的影响,我选择用同一份代码在不同系统上测试一下,看看效果

这里我测试了kylin、ubuntu都有这种问题,说明大概率和操作系统无关,uos因为操作系统镜像不好下载我就没测

和系统没关系,执行的时候也走了对应的函数,那么现在只能跟踪qt代码看看为什么没有弹出了,跟踪后有如下发现

            最后进入了QXcbWindow::requestActivateWindow()函数执行xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,(const char *)&event);

可以看到激活窗口实际是调用xcb模块的功能

            xcb介绍,XCB是X协议的一个C语言绑定,它提供了一种更现代、更高效的方式来与X Window System进行交互。xcb官网  https://xcb.freedesktop.org/

我分别在使用wayland和X协议的系统上进行测试,最后代码都走到了xcb_send_event方法

        接下来我就开始尝试对xcb_send_event的传参进行修改,重点是修改第二和第四个传参,其实这一步修改就是瞎改,也没有什么修改逻辑,我做的尝试如下:

            0  ->  1XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT  在此基础上增加或者减少事件掩码

        在修改测试过程中,发现偶尔能弹出来,但概率很低,然后我再把参数都恢复,发现也能偶尔弹出来,此刻我感觉和修改xcb_send_event参数没有什么关系了

        再结合前面我自己写的demo可以正常弹出的情况,我觉得代码中使用QLocalServer实现单例进程并且杀死新进程的方法可能会造成激活窗口操作失效(纯猜测,但改变了我的解决思路)

        所以还是要从应用调用代码的角度去解决


解决方案

如上所述,激活窗口一次没有没有生效,是不是多执行几次激活是不是就可以了?

       所以我修改激活窗口的方式,在原先激活窗口的位置开启定时器(定时器触发时间间隔500Ms~2s即可),在槽函数中执行激活窗口操作,当窗口激活成功就停止定时器

       在测试中发现,定时器第一次触发激活窗口的现象只是任务栏的图标闪烁,但窗口不弹出,而在第二次触发时窗口从任务栏中弹出,一般情况下第二次触发就能弹出了


后记

      为什么第一次触发激活窗口没有成功?目前还没有找到根源,我猜测可能是因为起第二进程再杀死导致了一些时序错误或者影响了堆栈,后续还要验证

      如果单纯从解决窗口不弹出的角度来说,还有一个方法就是调用命令wmctrl,但也可能存在失效的问题

            QProcess myProcess;QString program = "wmctrl";QStringList arguments;arguments << "-a" << w->windowTitle();myProcess.start(program,arguments);myProcess.waitForFinished();


http://www.ppmy.cn/ops/115673.html

相关文章

GNU链接器(LD):REGION_ALIAS函数(为存储区域取别名)用法及实例解析

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分&#xff1a; &#xff08;1&#xff09;编译器 &#xff08;2&#xff09;汇编器 &#xff08;3&#xff09;链接器 &#xff08;4&#xff09;lib库 在GNU工具链中&…

CS创世8GB SD NAND的低功耗特性

在电子设备不断追求低功耗的今天&#xff0c;CS创世半导体的8GB SD NAND芯片以其低功耗特性脱颖而出。这款芯片的读写电流仅为15mA&#xff0c;相较于同类产品&#xff0c;其功耗显著降低&#xff0c;这不仅延长了设备的使用时间&#xff0c;还减少了对电池的依赖。这种低功耗特…

oracle avg、count、max、min、sum、having、any、all、nvl的用法

组函数 having的使用 any的使用 all的使用 nvl 从执行结果来看&#xff0c;nvl(列名&#xff0c;默认值)&#xff0c;nvl的作用就是如果列名所在的这一行出现空则用默认值替换

阿里云函数计算 x NVIDIA 加速企业 AI 应用落地

作者&#xff1a;付宇轩 前言 阿里云函数计算&#xff08;Function Compute, FC&#xff09;是一种无服务器&#xff08;Serverless&#xff09;计算服务&#xff0c;允许用户在无需管理底层基础设施的情况下&#xff0c;直接运行代码。与传统的计算架构相比&#xff0c;函数…

前缀和问题

洛谷题面 这个其实可以当模板了。 代码&#xff1a; #include<bits/stdc.h> using namespace std; const int N1e510; int sum[N]; int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n,m,x;cin>>n;for(int i1;i<n;i){cin>>x;sum[i]sum[i…

Elasticsearch、ik分词器、elasticsearch-head、Kibana的认识与安装

文章目录 elasticsearch安装elasticsearchIK中文分词器elasticsearch-headkibana elasticsearch Elasticsearch是一个基于Lucene的搜索服务器&#xff0c;也是属于NoSQL阵营的数据库。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口提供给我们操…

Linux便捷查询使用手册 第一章:引言

目录 1.1 什么是Linux&#xff1f; 1.1.1 Linux内核与其他Unix-like系统内核的比较 1.1.2 Linux内核与其他操作系统内核的不同 1.1.3 Linux内核的主要功能和组件 1.2 Linux的历史与发展 1.2.1 重要里程碑事件 1.2.2 重要Linux版本发布 1.3 Linux的发行版概述 1.3.1 主…

Windows系统IP地址设置

目录 Windows系统IP地址设置一、背景二、设置步骤1、打开网络连接设置1) 在搜索栏输入“控制面板”&#xff0c;打开控制面板2) 选择“网络和Internet”&#xff0c;进入“网络和共享中心”。3) 进入网络连接设置 2、修改IP地址1) 选中你要修改的网卡&#xff0c;右键点击选择“…