Switch to using process names for process condition and executable tab (#337)

Previously the process condition and executable tab were just reusing
the window title functionality.
This commit is contained in:
WarmUpTill 2021-10-31 06:05:54 -07:00 committed by GitHub
parent 0490c97ad9
commit 95537f39e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 17 deletions

View File

@ -43,7 +43,7 @@ jobs:
# devscripts and libobs-dev are needed but they were already installed
# from check_libobs_revision and install_frontend_header sections.
sudo apt update
sudo apt install cmake debhelper libcurl4-openssl-dev libxss-dev libxtst-dev qtbase5-dev libopencv-dev
sudo apt install cmake debhelper libcurl4-openssl-dev libxss-dev libxtst-dev qtbase5-dev libopencv-dev libprocps-dev
- name: build
run: |
debuild --no-lintian --no-sign

View File

@ -179,7 +179,8 @@ jobs:
libxss-dev \
libx11-xcb-dev \
libxcb-xfixes0-dev \
libopencv-dev
libopencv-dev \
libprocps-dev
- name: 'Configure'
shell: bash
run: |

View File

@ -137,9 +137,20 @@ endif()
if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED COMPONENTS Xtst Xss)
link_libraries(${X11_LIBRARIES})
find_path(PROCPS_INCLUDE_DIR NAMES proc/procps.h)
if(NOT PROCPS_INCLUDE_DIR)
message(
FATAL_ERROR "procps include dir not found - please set PROCPS_INCLUDE_DIR"
)
endif()
find_library(PROCPS_LIBRARY NAMES procps)
if(NOT PROCPS_LIBRARY)
message(FATAL_ERROR "procps lib not found - please set PROCPS_LIBRARY")
endif()
message (STATUS "WHAT THE FUCK IS GOING ON ${PROCPS_LIBRARY}")
link_libraries(${X11_LIBRARIES} ${procps_LIBRARIES})
include_directories("${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}"
"${X11_Xss_INCLUDE_PATH}")
"${X11_Xss_INCLUDE_PATH}" "${PROCPS_INCLUDE_DIR}")
endif()
if(WIN32)
@ -154,7 +165,7 @@ elseif(APPLE)
else()
set(advanced-scene-switcher_PLATFORM_SOURCES
src/linux/advanced-scene-switcher-nix.cpp)
set(advanced-scene-switcher_PLATFORM_LIBS Xss)
set(advanced-scene-switcher_PLATFORM_LIBS Xss ${PROCPS_LIBRARY})
endif()
# asio and websocketpp
@ -401,11 +412,7 @@ if(BUILD_OUT_OF_TREE)
else()
# In tree build
target_link_libraries(
advanced-scene-switcher
${advanced-scene-switcher_PLATFORM_LIBS}
${OpenCV_LIBRARIES}
obs-frontend-api
Qt5::Widgets
libobs)
advanced-scene-switcher ${advanced-scene-switcher_PLATFORM_LIBS}
${OpenCV_LIBRARIES} obs-frontend-api Qt5::Widgets libobs)
install_obs_plugin_with_data(advanced-scene-switcher data)
endif()

View File

@ -24,6 +24,9 @@
#include <QStringList>
#include <QRegularExpression>
#include <QLibrary>
#include <proc/readproc.h>
#include <fstream>
#include <sstream>
static Display *xdisplay = 0;
@ -363,17 +366,78 @@ bool isFullscreen(const std::string &title)
void GetProcessList(QStringList &processes)
{
processes.clear();
for (size_t i = 0; i < getTopLevelWindows().size(); ++i) {
std::string s = GetWindowTitle(i);
if (s != "")
processes << QString::fromStdString(s);
PROCTAB *proc = openproc(PROC_FILLSTAT);
proc_t proc_info;
memset(&proc_info, 0, sizeof(proc_info));
while (readproc(proc, &proc_info) != NULL) {
QString procName(proc_info.cmd);
if (!procName.isEmpty() && !processes.contains(proc_info.cmd)) {
processes << QString(proc_info.cmd);
}
}
closeproc(proc);
}
int getForegroundProcessPid()
{
if (!ewmhIsSupported()) {
return -1;
}
auto dpy = disp();
Atom active = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", true);
Atom actualType;
int format;
unsigned long num, bytes;
Window *window = 0;
int pid = -1;
Window rootWin = RootWindow(dpy, 0);
int xstatus = XGetWindowProperty(dpy, rootWin, active, 0L, ~0L, false,
AnyPropertyType, &actualType, &format,
&num, &bytes, (uint8_t **)&window);
if (xstatus == 0 && window == nullptr) {
return -1;
}
Atom atom, actual_type;
int actual_format;
unsigned long nitems;
unsigned long bytes_after;
unsigned char *prop;
atom = XInternAtom(dpy, "_NET_WM_PID", True);
auto status = XGetWindowProperty(dpy, *window, atom, 0, 1024, False,
AnyPropertyType, &actual_type,
&actual_format, &nitems, &bytes_after,
&prop);
if (status != 0) {
return -2;
}
if (!prop) {
return -3;
}
pid = prop[1] * 256;
pid += prop[0];
return pid;
}
std::string getProcNameFromPid(int pid)
{
std::string path = "/proc/" + std::to_string(pid) + "/comm";
std::ifstream t(path);
std::stringstream buffer;
buffer << t.rdbuf();
return buffer.str();
}
bool isInFocus(const QString &executable)
{
std::string current;
GetCurrentWindowTitle(current);
auto pid = getForegroundProcessPid();
std::string current = getProcNameFromPid(pid);
// True if executable switch equals current window
bool equals = (executable.toStdString() == current);