有这样一个系统,一个服务主进程用于接收指令,其它服务是独立的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 可能存在问题。