如何在X Windows上将进程窗口带到前台? (C )

发布时间:2020-03-27 发布网站:大佬教程
大佬教程收集整理的这篇文章主要介绍了如何在X Windows上将进程窗口带到前台? (C )大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有PID的进程(和名称),我想把它带到前面的 linux(ubuntu)上.在Mac上,我将简单地做SetFrontProcess(pid),在 Windows上我将枚举窗口,选出我想要的一个,并调用SetWindowPos(hwnd,HWND_TOPMOST,SWP_NOMOVE | SWP_NOSIZE);但是我在linux上怎么做了.我已经看过X Lib了,但是大多数/所有这些功能似乎在你的进程中的Windows上运行.

编辑:使用bdk的答案我将这些帮助器添加到我的代码以获取窗口

bool searchHelper(Display* display,Window w,Atom& atomPID,unsigned long pid,Window& result)
{
    bool ret = false;

    Atom atomType;
    int format;
    unsigned long nItems;
    unsigned long bytesAfter;
    unsigned char* propPID = 0;
    if (Success == XGetWindowProperty(display,w,atomPID,1,False,XA_CARDINAL,&atomType,&format,&nItems,&bytesAfter,&propPID))
    {
        if (propPID != 0)
        {
            if (pid == *((unsigned long *)propPID))
            {
                result = w;
                ret = true;
            }
            XFree(propPID);
        }
    }

    if (ret)
        return ret; //we found we can stop

    //check the children of the window
    Window wRoot;
    Window wParent;
    Window *wChild=NULL;
    unsigned nChildren=0;
    if (XQueryTree(display,&wRoot,&wParent,&wChild,&nChildren) != 0 )
    {
        for (unsigned i=0; i<nChildren; ++i)
        {
            ret = searchHelper(display,wChild[i],pid,result);
            if (ret)
                break;
        }
    }
    return ret;
}

bool getWindowFromPid(unsigned long pid,Display* display,Window& result)
{
    Window window = XDefaultRootWindow(display);
    Atom atomPID = XInternAtom(display,"_NET_WM_PID",true);
    if (atomPID == None)
    {
        qDebug("XInternAtom failure");
        return false;
    }
    return searchHelper(display,window,result);
}

现在我成功地获得了窗口,但是当我执行以下操作

if (getWindowFromPid(pid,display,window))
{
    qDebug("Found window ID:%d",window);
    int result = XRaiseWindow(display,window);
    qDebug("XRaiseWindow returned:%d",result);
}

XRaiseWindow返回1(BadRequest). XRaiseWindow的文档没有提到BadRequest的返回码是可能的结果.我不知道有什么问题.我不允许在不同的过程中将其称为Windows?这个焦点是防止钢铁阻碍我吗?有什么想法吗?

编辑编辑:

所以看看xwininfo.c在使用-frame调用它时会做什么,我根据bdk的建议改变了我的代码如下.

if (getWindowFromPid(pid,window))
    {
        qDebug("Found window ID:%d",window);

        //Need the windowmanger frame (or parent) id not window id
        Window root,parent;
        Window *childlist;
        unsigned int ujunk;
        int status = XQueryTree(display,&root,&parent,&childlist,&ujunk);
        if (status && parent && parent != root)
        {
            qDebug("Found frame window ID:%d",parent);
            window = parent;
        }

        XSetWindowAttributes xswa;
        xswa.override_redirect=True;
        int result = XChangeWindowAttributes (display,CWOverrideRedirect,&xswa);
        qDebug("XChangeWindowAttributes returned:%d",result);
        result = XRaiseWindow(display,window);
        qDebug("XRaiseWindow returned:%d",result);
    }
    else
        qDebug("unable to find the window for the pid");

在这一点上,我找到窗口框架ID,但是我从XChangeWindowAttributes和XRaiseWindow得到一个返回代码“1”.我只是不允许修改另一个进程的窗口?

解决方法

我没有尝试过这个,但把这两个方法放在一起可能会起作用:

如果您知道Window ID,Xlib中的XRaiseWindow API调用可以让您将窗口提升到正面.

http://www.unix.com/man-page/Linux/3/XRaiseWindow/

这个stackoverflow答案解释了如何从PID获取窗口ID:

How to get an X11 Window from a Process ID?

编辑:

我在XRaiseWindow中取得了有限的成功.以下程序在twm窗口管理器下工作,但不是通常使用的离子.窗口管理器必须具有防止应用程序“弹出”的方法.为了使这个工作,我还必须传递窗口管理器窗口的Window ID,而不是窗口本身.运行xwininfo -frame,然后单击窗口,并取得框架ID,使用gcc test.c -lX编译该程序,并在命令行上传递该程序,并将该窗口提升.

#include <stdio.h>
 #include <stdlib.h>
 #include <X11/Xlib.h>

 int main(int argc,char **argv)
 {
   Display *dsp = XOpenDisplay(NULL);
   long id = strtol(argv[1],NULL,16);
   XSetWindowAttributes xswa;
   xswa.override_redirect=True;
   XChangeWindowAttributes (dsp,id,&xswa);
   XRaiseWindow ( dsp,id );
   XCloseDisplay ( dsp );
 }

大佬总结

以上是大佬教程为你收集整理的如何在X Windows上将进程窗口带到前台? (C )全部内容,希望文章能够帮你解决如何在X Windows上将进程窗口带到前台? (C )所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ群:277859234,请注明来意。