場景分析
有這樣一個系統,一個服務主進程用于接收指令,其它服務是獨立的gui 程序,服務進程根據命令將對應的gui 程序切換到前臺。
windows 平臺有Setforeground 這個api,可以根據進程ID,將某個應用的窗口切換到前臺。ubuntu 并沒有類似的api,?這里借助xdotool 這個第三方庫,實現類似的功能。
xdotool?git clone 后,直接make,生成動態庫libxdo 和執行程序程序 xdotool。
需求
SetForeGround 大概就是根據進程ID,并激活該窗口為前臺窗口。用xdotool 命令實現如下
xdotool search --pid 進程ID
#返回窗口idxdotool 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 可能存在問題。