From a97621b1cb203b0e3a7dd07d88c5422b798cbfd8 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 1 Oct 2022 19:19:15 +0100 Subject: [PATCH] Added window swallowing --- src/Window.hpp | 3 +++ src/config/ConfigManager.cpp | 2 ++ src/events/Windows.cpp | 49 +++++++++++++++++++++++++++++++++++ src/helpers/MiscFunctions.cpp | 35 +++++++++++++++++++++++++ src/helpers/MiscFunctions.hpp | 1 + 5 files changed, 90 insertions(+) diff --git a/src/Window.hpp b/src/Window.hpp index b2457967..d75c89f4 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -146,6 +146,9 @@ public: // animated tint CAnimatedVariable m_fDimPercent; + // swallowing + CWindow* m_pSwallowed = nullptr; + // for toplevel monitor events uint64_t m_iLastToplevelMonitorID = -1; uint64_t m_iLastSurfaceMonitorID = -1; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 6c2d782a..7065d300 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -58,6 +58,8 @@ void CConfigManager::setDefaultVars() { configValues["misc:layers_hog_keyboard_focus"].intValue = 1; configValues["misc:animate_manual_resizes"].intValue = 0; configValues["misc:disable_autoreload"].intValue = 0; + configValues["misc:enable_swallow"].intValue = 0; + configValues["misc:swallow_regex"].strValue = STRVAL_EMPTY; configValues["debug:int"].intValue = 0; configValues["debug:log_damage"].intValue = 0; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index b64cc35c..ce927dca 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -49,6 +49,8 @@ void Events::listener_mapWindow(void* owner, void* data) { static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue; static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue; static auto *const PDIMSTRENGTH = &g_pConfigManager->getConfigValuePtr("decoration:dim_strength")->floatValue; + static auto *const PSWALLOW = &g_pConfigManager->getConfigValuePtr("misc:enable_swallow")->intValue; + static auto *const PSWALLOWREGEX = &g_pConfigManager->getConfigValuePtr("misc:swallow_regex")->strValue; const auto PMONITOR = g_pCompositor->m_pLastMonitor; const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); @@ -376,6 +378,46 @@ void Events::listener_mapWindow(void* owner, void* data) { g_pCompositor->focusWindow(nullptr); } + // verify swallowing + if (*PSWALLOW) { + // check parent + int ppid = getPPIDof(PWINDOW->getPID()); + + const auto PPPID = getPPIDof(ppid); + + // why? no clue. Blame terminals. + if (PPPID > 2) { + ppid = PPPID; + } + + if (ppid) { + // get window by pid + CWindow* found = nullptr; + for (auto& w : g_pCompositor->m_vWindows) { + if (!w->m_bIsMapped || w->m_bHidden) + continue; + + if (w->getPID() == ppid) { + found = w.get(); + break; + } + } + + if (found) { + // check if it's the window we want + std::regex rgx(*PSWALLOWREGEX); + if (std::regex_match(g_pXWaylandManager->getAppIDClass(found), rgx)) { + // swallow + PWINDOW->m_pSwallowed = found; + + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(found); + + found->m_bHidden = true; + } + } + } + } + Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y); auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName; @@ -415,6 +457,13 @@ void Events::listener_unmapWindow(void* owner, void* data) { // Allow the renderer to catch the last frame. g_pHyprOpenGL->makeWindowSnapshot(PWINDOW); + // swallowing + if (PWINDOW->m_pSwallowed && g_pCompositor->windowExists(PWINDOW->m_pSwallowed)) { + PWINDOW->m_pSwallowed->m_bHidden = false; + g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed); + PWINDOW->m_pSwallowed = nullptr; + } + bool wasLastWindow = false; if (PWINDOW == g_pCompositor->m_pLastWindow) { diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 22afd4a0..e933d496 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -354,3 +354,38 @@ void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) { // Identity mat[8] = 1.0f; } + +int64_t getPPIDof(int64_t pid) { + std::string dir = "/proc/" + std::to_string(pid) + "/status"; + FILE* infile; + + infile = fopen(dir.c_str(), "r"); + if (!infile) + return 0; + + char* line = nullptr; + size_t len = 0; + ssize_t len2 = 0; + + std::string pidstr; + + while ((len2 = getline(&line, &len, infile)) != -1) { + if (strstr(line, "PPid:")) { + pidstr = std::string(line, len2); + const auto tabpos = pidstr.find_last_of('\t'); + if (tabpos != std::string::npos) + pidstr = pidstr.substr(tabpos); + break; + } + } + + fclose(infile); + if (line) + free(line); + + try { + return std::stoll(pidstr); + } catch (std::exception& e) { + return 0; + } +} \ No newline at end of file diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index bbfb8ca2..55d51f07 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -14,6 +14,7 @@ int getWorkspaceIDFromString(const std::string&, std::string&); float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2); void logSystemInfo(); std::string execAndGet(const char*); +int64_t getPPIDof(int64_t pid); float getPlusMinusKeywordResult(std::string in, float relative);