summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-06-15 18:20:09 +0200
committerVaxry <vaxry@vaxry.net>2024-06-15 18:20:41 +0200
commit91fe58f8f278d126852877eadc87c50ca7b9b78d (patch)
treee8fddf5d2659a432b36d1272548a07b2a482a8ff /src
parent77f44bfcab6c3e553d26a776c011613efbfe6cfd (diff)
window: improve swallowing functionality
cleanups, fixes, etc. ref #6095
Diffstat (limited to 'src')
-rw-r--r--src/desktop/Window.cpp55
-rw-r--r--src/desktop/Window.hpp1
-rw-r--r--src/events/Windows.cpp69
3 files changed, 63 insertions, 62 deletions
diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp
index b02a53e0..d153b344 100644
--- a/src/desktop/Window.cpp
+++ b/src/desktop/Window.cpp
@@ -1540,3 +1540,58 @@ void CWindow::warpCursor() {
else
g_pCompositor->warpCursorTo(middle());
}
+
+PHLWINDOW CWindow::getSwallower() {
+ static auto PSWALLOWREGEX = CConfigValue<std::string>("misc:swallow_regex");
+ static auto PSWALLOWEXREGEX = CConfigValue<std::string>("misc:swallow_exception_regex");
+ static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
+
+ if (!*PSWALLOW || (*PSWALLOWREGEX).empty())
+ return nullptr;
+
+ // check parent
+ std::vector<PHLWINDOW> candidates;
+ pid_t currentPid = getPID();
+ // walk up the tree until we find someone, 25 iterations max.
+ for (size_t i = 0; i < 25; ++i) {
+ currentPid = getPPIDof(currentPid);
+
+ if (!currentPid)
+ break;
+
+ for (auto& w : g_pCompositor->m_vWindows) {
+ if (!w->m_bIsMapped || w->isHidden())
+ continue;
+
+ if (w->getPID() == currentPid)
+ candidates.push_back(w);
+ }
+ }
+
+ if (!(*PSWALLOWREGEX).empty())
+ std::erase_if(candidates, [&](const auto& other) { return !std::regex_match(other->m_szClass, std::regex(*PSWALLOWREGEX)); });
+
+ if (candidates.size() <= 0)
+ return nullptr;
+
+ if (!(*PSWALLOWEXREGEX).empty())
+ std::erase_if(candidates, [&](const auto& other) { return std::regex_match(other->m_szTitle, std::regex(*PSWALLOWEXREGEX)); });
+
+ if (candidates.size() <= 0)
+ return nullptr;
+
+ if (candidates.size() == 1)
+ return candidates.at(0);
+
+ // walk up the focus history and find the last focused
+ for (auto& w : g_pCompositor->m_vWindowFocusHistory) {
+ if (!w)
+ continue;
+
+ if (std::find(candidates.begin(), candidates.end(), w.lock()) != candidates.end())
+ return w.lock();
+ }
+
+ // if none are found (??) then just return the first one
+ return candidates.at(0);
+}
diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp
index 85c74622..16bf297c 100644
--- a/src/desktop/Window.hpp
+++ b/src/desktop/Window.hpp
@@ -450,6 +450,7 @@ class CWindow {
std::string fetchTitle();
std::string fetchClass();
void warpCursor();
+ PHLWINDOW getSwallower();
// listeners
void onAck(uint32_t serial);
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index becff152..d37ba12b 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -44,7 +44,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
static auto PSWALLOWREGEX = CConfigValue<std::string>("misc:swallow_regex");
- static auto PSWALLOWEXREGEX = CConfigValue<std::string>("misc:swallow_exception_regex");
static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:new_window_takes_over_fullscreen");
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
@@ -527,71 +526,17 @@ void Events::listener_mapWindow(void* owner, void* data) {
// verify swallowing
if (*PSWALLOW && std::string{*PSWALLOWREGEX} != STRVAL_EMPTY) {
- // don't swallow ourselves
- std::regex rgx(*PSWALLOWREGEX);
- if (!std::regex_match(PWINDOW->m_szClass, rgx)) {
- // check parent
- int ppid = getPPIDof(PWINDOW->getPID());
+ const auto SWALLOWER = PWINDOW->getSwallower();
- int curppid = 0;
+ if (SWALLOWER) {
+ // swallow
+ PWINDOW->m_pSwallowed = SWALLOWER;
- for (int i = 0; i < 5; ++i) {
- curppid = getPPIDof(ppid);
+ g_pLayoutManager->getCurrentLayout()->onWindowRemoved(SWALLOWER);
- if (curppid < 10) {
- break;
- }
-
- ppid = curppid;
- }
-
- if (ppid) {
- // get window by pid
- std::vector<PHLWINDOW> found;
- PHLWINDOW finalFound;
- for (auto& w : g_pCompositor->m_vWindows) {
- if (!w->m_bIsMapped || w->isHidden())
- continue;
-
- if (w->getPID() == ppid) {
- found.push_back(w);
- }
- }
-
- if (found.size() > 1) {
- for (auto& w : found) {
- // try get the focus, otherwise we'll ignore to avoid swallowing incorrect windows
- if (w == PFOCUSEDWINDOWPREV) {
- finalFound = w;
- break;
- }
- }
- } else if (found.size() == 1) {
- finalFound = found[0];
- }
-
- if (finalFound) {
- bool valid = std::regex_match(PWINDOW->m_szClass, rgx);
-
- if (std::string{*PSWALLOWEXREGEX} != STRVAL_EMPTY) {
- std::regex exc(*PSWALLOWEXREGEX);
-
- valid = valid && !std::regex_match(PWINDOW->m_szTitle, exc);
- }
-
- // check if it's the window we want & not exempt from getting swallowed
- if (valid) {
- // swallow
- PWINDOW->m_pSwallowed = finalFound;
+ SWALLOWER->setHidden(true);
- g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound);
-
- finalFound->setHidden(true);
-
- g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
- }
- }
- }
+ g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
}
}