mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-02 17:45:58 +01:00
window: improve swallowing functionality
cleanups, fixes, etc. ref #6095
This commit is contained in:
parent
77f44bfcab
commit
91fe58f8f2
3 changed files with 63 additions and 62 deletions
|
@ -1540,3 +1540,58 @@ void CWindow::warpCursor() {
|
||||||
else
|
else
|
||||||
g_pCompositor->warpCursorTo(middle());
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -450,6 +450,7 @@ class CWindow {
|
||||||
std::string fetchTitle();
|
std::string fetchTitle();
|
||||||
std::string fetchClass();
|
std::string fetchClass();
|
||||||
void warpCursor();
|
void warpCursor();
|
||||||
|
PHLWINDOW getSwallower();
|
||||||
|
|
||||||
// listeners
|
// listeners
|
||||||
void onAck(uint32_t serial);
|
void onAck(uint32_t serial);
|
||||||
|
|
|
@ -44,7 +44,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
|
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
|
||||||
static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
|
static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
|
||||||
static auto PSWALLOWREGEX = CConfigValue<std::string>("misc:swallow_regex");
|
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 PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:new_window_takes_over_fullscreen");
|
||||||
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
|
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
|
||||||
|
|
||||||
|
@ -527,73 +526,19 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
|
|
||||||
// verify swallowing
|
// verify swallowing
|
||||||
if (*PSWALLOW && std::string{*PSWALLOWREGEX} != STRVAL_EMPTY) {
|
if (*PSWALLOW && std::string{*PSWALLOWREGEX} != STRVAL_EMPTY) {
|
||||||
// don't swallow ourselves
|
const auto SWALLOWER = PWINDOW->getSwallower();
|
||||||
std::regex rgx(*PSWALLOWREGEX);
|
|
||||||
if (!std::regex_match(PWINDOW->m_szClass, rgx)) {
|
|
||||||
// check parent
|
|
||||||
int ppid = getPPIDof(PWINDOW->getPID());
|
|
||||||
|
|
||||||
int curppid = 0;
|
if (SWALLOWER) {
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
curppid = getPPIDof(ppid);
|
|
||||||
|
|
||||||
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
|
// swallow
|
||||||
PWINDOW->m_pSwallowed = finalFound;
|
PWINDOW->m_pSwallowed = SWALLOWER;
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(finalFound);
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(SWALLOWER);
|
||||||
|
|
||||||
finalFound->setHidden(true);
|
SWALLOWER->setHidden(true);
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWINDOW->m_iMonitorID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PWINDOW->m_bFirstMap = false;
|
PWINDOW->m_bFirstMap = false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue