ubuntu Setforeground 前台应用切换
场景分析
有这样一个系统,一个服务主进程用于接收指令,其它服务是独立的gui 程序,服务进程根据命令将对应的gui 程序切换到前台。
windows 平台有Setforeground 这个api,可以根据进程ID,将某个应用的窗口切换到前台。ubuntu 并没有类似的api, 这里借助xdotool 这个第三方库,实现类似的功能。
xdotool git clone 后,直接make,生成动态库libxdo 和执行程序程序 xdotool。
需求
SetForeGround 大概就是根据进程ID,并激活该窗口为前台窗口。用xdotool 命令实现如下
xdotool search --pid 进程ID
#返回窗口id
xdotool windowactivate 窗口ID
search 返回的ID 如果有多个,是因为一个进程有多个窗口,需要根据窗口标题再筛选
实际应用中,一般直接调用库,代码实现如下:
bool SetForeground(uint32_t pid, const char* window_name)
{
Window *list = NULL;
unsigned int nwindows;
xdo_search_t search;
xdo_t *context = xdo_new(NULL);
memset(&search, 0, sizeof(xdo_search_t));
search.max_depth = -1;
search.require = xdo_search::SEARCH_ANY;
search.pid = pid;
search.searchmask = SEARCH_PID;
do
{
if(list != NULL)
{
free(list);
}
xdo_search_windows(context, &search, &list, &nwindows);
if(nwindows > 0)
{
for(int i = 0;i < nwindows;i++)
{
unsigned char *name;
int name_len;
int name_type;
xdo_get_window_name(context, list[i], &name, &name_len, &name_type);
QString window_name((char*)name);
if(window_name == window_name)
{
xdo_activate_window(context, list[i]);
}
}
}
usleep(500000);
}while(nwindows == 0);
if(list != NULL)
{
free(list);
}
xdo_free(context);
return true;
}
//调用:
SetForeground(QCoreApplication::applicationPid(), this->windowTitle().toStdString().c_str());
注:这个只适用于x11 图形平台,wayland 可能存在问题。