linux-capture: Additionally search windows via WM_CLASS

If window capture fails to find a window with a matching title, search
for a window with the same window class additionally as a backup.

Replaces the third part of the internal window string with the class
name instead of the program path due to the fact that the program path
rarely seemed to work.
This commit is contained in:
jp9000
2016-07-02 23:49:19 -07:00
parent 23430a9221
commit e389ae8a75
3 changed files with 21 additions and 8 deletions

View File

@@ -172,9 +172,9 @@ namespace XCompcap
return XScreenNumberOfScreen(attr.screen);
}
std::string getWindowName(Window win)
std::string getWindowAtom(Window win, const char *atom)
{
Atom netWmName = XInternAtom(disp(), "_NET_WM_NAME", false);
Atom netWmName = XInternAtom(disp(), atom, false);
int n;
char **list = 0;
XTextProperty tp;

View File

@@ -82,12 +82,22 @@ namespace XCompcap
std::string getWindowCommand(Window win);
int getRootWindowScreen(Window root);
std::string getWindowName(Window win);
std::string getWindowAtom(Window win, const char *atom);
int getWindowPid(Window win);
bool ewmhIsSupported();
std::list<Window> getTopLevelWindows();
std::list<Window> getAllWindows();
inline std::string getWindowName(Window win)
{
return getWindowAtom(win, "_NET_WM_NAME");
}
inline std::string getWindowClass(Window win)
{
return getWindowAtom(win, "WM_CLASS");
}
void processEvents();
bool windowWasReconfigured(Window win);
}

View File

@@ -57,11 +57,11 @@ obs_properties_t *XCompcapMain::properties()
for (Window win: XCompcap::getTopLevelWindows()) {
std::string wname = XCompcap::getWindowName(win);
std::string progpath = XCompcap::getWindowCommand(win);
std::string cls = XCompcap::getWindowClass(win);
std::string winid = std::to_string((long long)win);
std::string desc =
(winid + WIN_STRING_DIV + wname +
WIN_STRING_DIV + progpath);
WIN_STRING_DIV + cls);
obs_property_list_add_string(wins, wname.c_str(),
desc.c_str());
@@ -216,25 +216,28 @@ static Window getWindowFromString(std::string wstr)
}
size_t firstMark = wstr.find(WIN_STRING_DIV);
size_t markSize = strlen(WIN_STRING_DIV);
if (firstMark == std::string::npos)
return (Window)std::stol(wstr);
Window wid = 0;
wstr = wstr.substr(firstMark + strlen(WIN_STRING_DIV));
wstr = wstr.substr(firstMark + markSize);
size_t lastMark = wstr.rfind(WIN_STRING_DIV);
std::string wname = wstr.substr(0, lastMark);
std::string wcls = wstr.substr(lastMark + markSize);
Window matchedNameWin = wid;
for (Window cwin: XCompcap::getTopLevelWindows()) {
std::string cwinname = XCompcap::getWindowName(cwin);
std::string ccls = XCompcap::getWindowClass(cwin);
if (cwin == wid && wname == cwinname)
if (cwin == wid && wname == cwinname && wcls == ccls)
return wid;
if (wname == cwinname)
if (wname == cwinname || (!matchedNameWin && wcls == ccls))
matchedNameWin = cwin;
}