X11 库使用
在处理electron程序置顶窗口和qt程序置顶窗口问题时,无效
#include <QWindow>
#include <X11/Xlib.h>
#include <QX11Info>
#include <X11/Xatom.h>
void forceTop(Window window) {
Display *display = QX11Info::display();
//Window window = winId();
// 设置窗口为全局置顶
XSetTransientForHint(display, window, None);
XRaiseWindow(display, window);
//XCloseDisplay(display);
}
bool isElectronScreensaver(Window win) {
// 通过窗口类名或 PID 判断(需扩展实现)
Atom actual_type;
int format;
unsigned long nItems, bytesAfter;
unsigned char *prop = nullptr;
Atom className = XInternAtom(QX11Info::display(), "WM_CLASS", False);
if (XGetWindowProperty(QX11Info::display(), win, className, 0, 1, False,
XA_STRING, &actual_type, &format, &nItems, &bytesAfter,
&prop) == Success) {
if (prop) {
QString classNameStr = QByteArray((char*)prop).split(',').first();
qDebug() << "isWindowCovered window:" << win << " class:" << classNameStr << "/" << (char*)prop;
XFree(prop);
return classNameStr == "elec"; // 根据实际类名调整
}
}
return false;
}
void ActivateWindow(Display* display, Window window) {
XEvent event = { 0 };
event.xclient.type = ClientMessage;
event.xclient.message_type = XInternAtom(display, "_NET_ACTIVE_WINDOW", False);
event.xclient.display = display;
event.xclient.window = window;
event.xclient.format = 32;
event.xclient.data.l[0] = 2;
event.xclient.data.l[1] = CurrentTime;
event.xclient.data.l[2] = 0;
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;
Window root = XDefaultRootWindow(display);
XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &event);
}
void hideWindow(Display* display, Window window) {
// 取消窗口映射(隐藏)
XUnmapWindow(display, window);
XFlush(display);
}
void showWindow(Display* display, Window window) {
// 重新映射窗口(显示)
XMapWindow(display, window);
XFlush(display);
}
bool isWindowCovered(Display *display, Window window) {
Window parent;
Window *children;
unsigned int count;
Window root = DefaultRootWindow(display);
// 查询窗口堆叠顺序
if (XQueryTree(display, root, &root, &parent, &children, &count)) {
qDebug() << "XQueryTree count:" << count << " current window:" << window;
for (unsigned int i = 0; i < count; ++i) {
// qDebug() << i << " window:" << children[i] << " parent:" << parent;
// if (children[i] != window && children[i] != parent) {
// XFree(children);
// return true; // 发现覆盖窗口
// }
if (isElectronScreensaver(children[i]))
{
//XRaiseWindow(display, window); // 提升 Qt 窗口
//XSetInputFocus(display, window, RevertToParent, CurrentTime); // 设置焦点
//ActivateWindow(display, window);
hideWindow(display, window);
}
}
XFree(children);
}
return false;
}
void MainWindow::setNetWmStateAbove() {
Display *display = QX11Info::display();
Window window = winId();
Atom aboveAtom = XInternAtom(display, "_NET_WM_STATE_ABOVE", False);
Atom wmState = XInternAtom(display, "_NET_WM_STATE", False);
XClientMessageEvent event{};
event.type = ClientMessage;
event.window = window;
event.message_type = wmState;
event.format = 32;
event.data.l[0] = 1; // _NET_WM_STATE_ADD
event.data.l[1] = aboveAtom;
event.data.l[2] = 0; // No second property
XSendEvent(display, DefaultRootWindow(display), False,
SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&event);
XFlush(display);
}
文档更新时间: 2025-03-26 15:04 作者:方杰