| 588 | } |
| 589 | |
| 590 | std::tuple<std::string, std::string> GetActiveWindowName() |
| 591 | { |
| 592 | if (X11Display == nullptr) |
| 593 | { |
| 594 | static auto *libX11 = ::dlopen("libX11.so", RTLD_LAZY); |
| 595 | |
| 596 | if (libX11) |
| 597 | { |
| 598 | XOpenDisplay = reinterpret_cast<decltype(XOpenDisplay)>(::dlsym(libX11, "XOpenDisplay")); |
| 599 | XGetInputFocus = reinterpret_cast<decltype(XGetInputFocus)>(::dlsym(libX11, "XGetInputFocus")); |
| 600 | XFetchName = reinterpret_cast<decltype(XFetchName)>(::dlsym(libX11, "XFetchName")); |
| 601 | XInternAtom = reinterpret_cast<decltype(XInternAtom)>(::dlsym(libX11, "XInternAtom")); |
| 602 | XGetWindowProperty = reinterpret_cast<decltype(XGetWindowProperty)>(::dlsym(libX11, "XGetWindowProperty")); |
| 603 | XFree = reinterpret_cast<decltype(XFree)>(::dlsym(libX11, "XFree")); |
| 604 | |
| 605 | X11Display = XOpenDisplay(nullptr); |
| 606 | _NET_WM_PID = XInternAtom(X11Display, "_NET_WM_PID", true); |
| 607 | } |
| 608 | } |
| 609 | |
| 610 | std::tuple<std::string, std::string> result; |
| 611 | |
| 612 | if (X11Display != nullptr) |
| 613 | { |
| 614 | constexpr std::size_t MAX_PATH{ 256 }; |
| 615 | X11Window focusedWindow; |
| 616 | char *focusedWindowName = nullptr; |
| 617 | unsigned char *processPID = nullptr; |
| 618 | char focusedWindowExecutableName[MAX_PATH]; |
| 619 | int revert; |
| 620 | |
| 621 | focusedWindowExecutableName[0] = '\0'; |
| 622 | XGetInputFocus(X11Display, &focusedWindow, &revert); |
| 623 | if (focusedWindow > 0) |
| 624 | { |
| 625 | XFetchName(X11Display, focusedWindow, &focusedWindowName); |
| 626 | |
| 627 | X11Atom type; |
| 628 | int format; |
| 629 | unsigned long itemCount; |
| 630 | unsigned long bytesAfter; |
| 631 | |
| 632 | XGetWindowProperty(X11Display, focusedWindow, _NET_WM_PID, 0, 1, false, 0, &type, &format, &itemCount, &bytesAfter, &processPID); |
| 633 | if (processPID != nullptr) |
| 634 | { |
| 635 | const auto pid = *reinterpret_cast<unsigned long *>(processPID); |
| 636 | XFree(processPID); |
| 637 | |
| 638 | std::snprintf(focusedWindowExecutableName, MAX_PATH, "/proc/%lu/comm", pid); |
| 639 | std::unique_ptr<FILE, decltype(&std::fclose)> cmd{ std::fopen(focusedWindowExecutableName, "r"), &std::fclose }; |
| 640 | std::memset(focusedWindowExecutableName, 0, MAX_PATH); |
| 641 | if (cmd != nullptr) |
| 642 | { |
| 643 | const auto bytesRead = std::fread(focusedWindowExecutableName, sizeof(char), MAX_PATH, cmd.get()); |
| 644 | if (bytesRead > 0) |
| 645 | { |
| 646 | if (focusedWindowExecutableName[bytesRead - 1] == '\n') |
| 647 | { |