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   作者:方杰