diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 5a3d59415..cc2b1792f 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -401,7 +401,7 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { escapeJSONStrings(!w->m_workspace ? "" : w->m_workspace->m_name), (sc(w->m_isFloating) == 1 ? "true" : "false"), w->monitorID(), escapeJSONStrings(w->m_class), escapeJSONStrings(w->m_title), escapeJSONStrings(w->m_initialClass), escapeJSONStrings(w->m_initialTitle), w->getPID(), (sc(w->m_isX11) == 1 ? "true" : "false"), (w->m_pinned ? "true" : "false"), sc(w->m_fullscreenState.internal), sc(w->m_fullscreenState.client), (w->m_createdOverFullscreen ? "true" : "false"), - getGroupedData(w, format), getTagsData(w, format), rc(w->m_swallowed.get()), getFocusHistoryID(w), + getGroupedData(w, format), getTagsData(w, format), rc(w->m_swallowee.get()), getFocusHistoryID(w), (g_pInputManager->isWindowInhibiting(w, false) ? "true" : "false"), escapeJSONStrings(w->xdgTag().value_or("")), escapeJSONStrings(w->xdgDescription().value_or("")), escapeJSONStrings(NContentType::toString(w->getContentType())), w->m_stableID); } else { @@ -416,7 +416,7 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { sc(w->m_realSize->goal().x), sc(w->m_realSize->goal().y), w->m_workspace ? w->workspaceID() : WORKSPACE_INVALID, (!w->m_workspace ? "" : w->m_workspace->m_name), sc(w->m_isFloating), w->monitorID(), w->m_class, w->m_title, w->m_initialClass, w->m_initialTitle, w->getPID(), sc(w->m_isX11), sc(w->m_pinned), sc(w->m_fullscreenState.internal), sc(w->m_fullscreenState.client), sc(w->m_createdOverFullscreen), - getGroupedData(w, format), getTagsData(w, format), rc(w->m_swallowed.get()), getFocusHistoryID(w), sc(g_pInputManager->isWindowInhibiting(w, false)), + getGroupedData(w, format), getTagsData(w, format), rc(w->m_swallowee.get()), getFocusHistoryID(w), sc(g_pInputManager->isWindowInhibiting(w, false)), w->xdgTag().value_or(""), w->xdgDescription().value_or(""), NContentType::toString(w->getContentType()), w->m_stableID); } } diff --git a/src/desktop/view/Window.cpp b/src/desktop/view/Window.cpp index 2f87cc0f0..94836fd52 100644 --- a/src/desktop/view/Window.cpp +++ b/src/desktop/view/Window.cpp @@ -512,10 +512,10 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { Event::bus()->m_events.window.moveToWorkspace.emit(m_self.lock(), pWorkspace); } - if (const auto SWALLOWED = m_swallowed.lock()) { - if (SWALLOWED->m_currentlySwallowed) { - SWALLOWED->moveToWorkspace(pWorkspace); - SWALLOWED->m_monitor = m_monitor; + if (const auto SWALLOWEE = m_swallowee.lock()) { + if (SWALLOWEE->m_currentlySwallowed) { + SWALLOWEE->moveToWorkspace(pWorkspace); + SWALLOWEE->m_monitor = m_monitor; } } @@ -1259,7 +1259,7 @@ void CWindow::warpCursor(bool force) { g_pCompositor->warpCursorTo(middle(), force); } -PHLWINDOW CWindow::getSwallower() { +PHLWINDOW CWindow::getSwallowee() { static auto PSWALLOWREGEX = CConfigValue("misc:swallow_regex"); static auto PSWALLOWEXREGEX = CConfigValue("misc:swallow_exception_regex"); static auto PSWALLOW = CConfigValue("misc:enable_swallow"); @@ -1938,11 +1938,14 @@ void CWindow::mapWindow() { updateWindowData(); - // Verify window swallowing. Get the swallower before calling onWindowCreated(m_self.lock()) because getSwallower() wouldn't get it after if m_self.lock() gets auto grouped. - const auto SWALLOWER = getSwallower(); - m_swallowed = SWALLOWER; - if (m_swallowed) - m_swallowed->m_currentlySwallowed = true; + // Verify window swallowing. Get the swallowee before calling onWindowCreated(m_self.lock()) because getSwallowee() wouldn't get it after if m_self.lock() gets auto grouped. + const auto SWALLOWEE = getSwallowee(); + // m_hasSwallower prevents secondary windows to swallow the parent when it's been unswallowed with `toggleswallow`. + if (SWALLOWEE && !SWALLOWEE->m_hasSwallower) { + SWALLOWEE->m_currentlySwallowed = true; + SWALLOWEE->m_hasSwallower = true; + m_swallowee = SWALLOWEE; + } // emit the IPC event before the layout might focus the window to avoid a focus event first g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", m_self.lock(), PWORKSPACE->m_name, m_class, m_title)}); @@ -2071,9 +2074,9 @@ void CWindow::mapWindow() { } // swallow - if (SWALLOWER) { - g_layoutManager->removeTarget(SWALLOWER->layoutTarget()); - SWALLOWER->setHidden(true); + if (m_swallowee) { + g_layoutManager->removeTarget(SWALLOWEE->layoutTarget()); + SWALLOWEE->setHidden(true); } m_firstMap = false; @@ -2157,19 +2160,20 @@ void CWindow::unmapWindow() { g_pHyprRenderer->makeSnapshot(m_self.lock()); // swallowing - if (valid(m_swallowed)) { - if (m_swallowed->m_currentlySwallowed) { - m_swallowed->m_currentlySwallowed = false; - m_swallowed->setHidden(false); + if (const auto SWALLOWEE = m_swallowee.lock()) { + if (SWALLOWEE->m_currentlySwallowed) { + SWALLOWEE->m_currentlySwallowed = false; + SWALLOWEE->setHidden(false); if (m_group) - m_swallowed->m_groupSwallowed = true; // flag for the swallowed window to be created into the group where it belongs when auto_group = false. + SWALLOWEE->m_groupSwallowed = true; // flag for the swallowed window to be created into the group where it belongs when auto_group = false. - g_layoutManager->newTarget(m_swallowed->layoutTarget(), m_workspace->m_space); + g_layoutManager->newTarget(SWALLOWEE->layoutTarget(), m_workspace->m_space); } - m_swallowed->m_groupSwallowed = false; - m_swallowed.reset(); + SWALLOWEE->m_groupSwallowed = false; + SWALLOWEE->m_hasSwallower = false; + m_swallowee.reset(); } bool wasLastWindow = false; diff --git a/src/desktop/view/Window.hpp b/src/desktop/view/Window.hpp index 693d0dd4a..319ac9439 100644 --- a/src/desktop/view/Window.hpp +++ b/src/desktop/view/Window.hpp @@ -233,9 +233,10 @@ namespace Desktop::View { PHLANIMVAR m_movingToWorkspaceAlpha; // swallowing - PHLWINDOWREF m_swallowed; + PHLWINDOWREF m_swallowee; bool m_currentlySwallowed = false; bool m_groupSwallowed = false; + bool m_hasSwallower = false; // for toplevel monitor events MONITORID m_lastSurfaceMonitorID = -1; @@ -326,7 +327,7 @@ namespace Desktop::View { std::string fetchTitle(); std::string fetchClass(); void warpCursor(bool force = false); - PHLWINDOW getSwallower(); + PHLWINDOW getSwallowee(); bool isX11OverrideRedirect(); bool isModal(); Vector2D realToReportSize(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e60644720..7a1a443a7 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -2195,19 +2195,19 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) { SDispatchResult CKeybindManager::toggleSwallow(std::string args) { PHLWINDOWREF pWindow = Desktop::focusState()->window(); - if (!valid(pWindow) || !valid(pWindow->m_swallowed)) + if (!valid(pWindow) || !valid(pWindow->m_swallowee)) return {}; - if (pWindow->m_swallowed->m_currentlySwallowed) { + if (pWindow->m_swallowee->m_currentlySwallowed) { // Unswallow - pWindow->m_swallowed->m_currentlySwallowed = false; - pWindow->m_swallowed->setHidden(false); - g_layoutManager->newTarget(pWindow->m_swallowed->layoutTarget(), pWindow->m_workspace->m_space); + pWindow->m_swallowee->m_currentlySwallowed = false; + pWindow->m_swallowee->setHidden(false); + g_layoutManager->newTarget(pWindow->m_swallowee->layoutTarget(), pWindow->m_workspace->m_space); } else { // Reswallow - pWindow->m_swallowed->m_currentlySwallowed = true; - pWindow->m_swallowed->setHidden(true); - g_layoutManager->removeTarget(pWindow->m_swallowed->layoutTarget()); + pWindow->m_swallowee->m_currentlySwallowed = true; + pWindow->m_swallowee->setHidden(true); + g_layoutManager->removeTarget(pWindow->m_swallowee->layoutTarget()); } return {};