diff --git a/src/desktop/view/Window.cpp b/src/desktop/view/Window.cpp index b84505d3d..e1b2ab7b9 100644 --- a/src/desktop/view/Window.cpp +++ b/src/desktop/view/Window.cpp @@ -470,6 +470,8 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { const auto OLDWORKSPACE = m_workspace; + bool previouslyEmpty = !pWorkspace->hasWindow(); + if (OLDWORKSPACE->isVisible()) { m_movingToWorkspaceAlpha->setValueAndWarp(1.F); *m_movingToWorkspaceAlpha = 0.F; @@ -495,6 +497,16 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { g_pEventManager->postEvent(SHyprIPCEvent{.event = "movewindow", .data = std::format("{:x},{}", rc(this), pWorkspace->m_name)}); g_pEventManager->postEvent(SHyprIPCEvent{.event = "movewindowv2", .data = std::format("{:x},{},{}", rc(this), pWorkspace->m_id, pWorkspace->m_name)}); EMIT_HOOK_EVENT("moveWindow", (std::vector{m_self.lock(), pWorkspace})); + + if (!OLDWORKSPACE->hasWindow()) { + g_pEventManager->postEvent(SHyprIPCEvent{.event = "depopulateworkspace", .data = std::format("{},{}", OLDWORKSPACE->m_id, OLDWORKSPACE->m_name)}); + EMIT_HOOK_EVENT("depopulateWorkspace", OLDWORKSPACE); + } + + if (previouslyEmpty) { + g_pEventManager->postEvent(SHyprIPCEvent{.event = "populateworkspace", .data = std::format("{},{}", pWorkspace->m_id, pWorkspace->m_name)}); + EMIT_HOOK_EVENT("populateWorkspace", pWorkspace); + } } if (const auto SWALLOWED = m_swallowed.lock()) { @@ -1936,7 +1948,9 @@ void CWindow::mapWindow() { Desktop::focusState()->rawMonitorFocus(g_pCompositor->getMonitorFromVector({})); PMONITOR = Desktop::focusState()->monitor(); } - auto PWORKSPACE = PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace; + auto PWORKSPACE = PMONITOR->m_activeSpecialWorkspace ? PMONITOR->m_activeSpecialWorkspace : PMONITOR->m_activeWorkspace; + bool workspacePreviouslyEmpty = !PWORKSPACE->hasWindow(); + m_monitor = PMONITOR; m_workspace = PWORKSPACE; m_isMapped = true; @@ -2233,6 +2247,9 @@ void CWindow::mapWindow() { // 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)}); EMIT_HOOK_EVENT("openWindowEarly", m_self.lock()); + if (workspacePreviouslyEmpty) { + g_pEventManager->postEvent(SHyprIPCEvent{"populateworkspace", std::format("{},{}", PWORKSPACE->m_id, PWORKSPACE->m_name)}); + } if (m_isFloating) { g_pLayoutManager->getCurrentLayout()->onWindowCreated(m_self.lock()); @@ -2373,6 +2390,10 @@ void CWindow::mapWindow() { // emit the hook event here after basic stuff has been initialized EMIT_HOOK_EVENT("openWindow", m_self.lock()); + if (workspacePreviouslyEmpty) { + EMIT_HOOK_EVENT("populateWorkspace", m_self.lock()); + } + // apply data from default decos. Borders, shadows. g_pDecorationPositioner->forceRecalcFor(m_self.lock()); @@ -2485,6 +2506,11 @@ void CWindow::unmapWindow() { // do this after onWindowRemoved because otherwise it'll think the window is invalid m_isMapped = false; + if (!m_workspace->hasWindow()) { + g_pEventManager->postEvent(SHyprIPCEvent{"depopulateworkspace", std::format("{},{}", m_workspace->m_id, m_workspace->m_name)}); + EMIT_HOOK_EVENT("depopulateWorkspace", m_workspace); + } + // refocus on a new window if needed if (wasLastWindow) { static auto FOCUSONCLOSE = CConfigValue("input:focus_on_close");