Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,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;
Expand All @@ -462,6 +464,18 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
g_pEventManager->postEvent(SHyprIPCEvent{.event = "movewindow", .data = std::format("{:x},{}", rc<uintptr_t>(this), pWorkspace->m_name)});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "movewindowv2", .data = std::format("{:x},{},{}", rc<uintptr_t>(this), pWorkspace->m_id, pWorkspace->m_name)});
EMIT_HOOK_EVENT("moveWindow", (std::vector<std::any>{m_self.lock(), pWorkspace}));

if (!OLDWORKSPACE->hasWindow()) {
g_pEventManager->postEvent(SHyprIPCEvent{.event = "depopulateworkspace", .data = OLDWORKSPACE->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "depopulateworkspacev2", .data = std::format("{},{}", OLDWORKSPACE->m_id, OLDWORKSPACE->m_name)});
EMIT_HOOK_EVENT("depopulateWorkspace", OLDWORKSPACE);
}

if (previouslyEmpty) {
g_pEventManager->postEvent(SHyprIPCEvent{.event = "populateworkspace", .data = pWorkspace->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{.event = "populateworkspacev2", .data = std::format("{},{}", pWorkspace->m_id, pWorkspace->m_name)});
EMIT_HOOK_EVENT("populateWorkspace", pWorkspace);
}
}

if (const auto SWALLOWED = m_swallowed.lock()) {
Expand All @@ -471,7 +485,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
}
}

if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_id) && OLDWORKSPACE->getWindows() == 0 && *PCLOSEONLASTSPECIAL) {
if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_id) && !OLDWORKSPACE->hasWindow() && *PCLOSEONLASTSPECIAL) {
if (const auto PMONITOR = OLDWORKSPACE->m_monitor.lock(); PMONITOR)
PMONITOR->setSpecialWorkspace(nullptr);
}
Expand Down Expand Up @@ -526,10 +540,10 @@ void CWindow::onUnmap() {
// if the special workspace now has 0 windows, it will be closed, and this
// window will no longer pass render checks, cuz the workspace will be nuked.
// throw it into the main one for the fadeout.
if (m_workspace->m_isSpecialWorkspace && m_workspace->getWindows() == 0)
if (m_workspace->m_isSpecialWorkspace && !m_workspace->hasWindow())
m_lastWorkspace = m_monitor->activeWorkspaceID();

if (*PCLOSEONLASTSPECIAL && m_workspace && m_workspace->getWindows() == 0 && onSpecialWorkspace()) {
if (*PCLOSEONLASTSPECIAL && m_workspace && !m_workspace->hasWindow() && onSpecialWorkspace()) {
const auto PMONITOR = m_monitor.lock();
if (PMONITOR && PMONITOR->m_activeSpecialWorkspace && PMONITOR->m_activeSpecialWorkspace == m_workspace)
PMONITOR->setSpecialWorkspace(nullptr);
Expand Down
4 changes: 4 additions & 0 deletions src/desktop/Workspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,3 +561,7 @@ void CWorkspace::setPersistent(bool persistent) {
bool CWorkspace::isPersistent() {
return m_persistent;
}

bool CWorkspace::hasWindow() {
return std::ranges::any_of(g_pCompositor->m_windows, [this](const auto& w) { return w->workspaceID() == m_id && w->m_isMapped; });
}
1 change: 1 addition & 0 deletions src/desktop/Workspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class CWorkspace {
void updateWindows();
void setPersistent(bool persistent);
bool isPersistent();
bool hasWindow();

struct {
CSignalT<> destroy;
Expand Down
19 changes: 17 additions & 2 deletions src/events/Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
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();

PWINDOW->m_monitor = PMONITOR;
PWINDOW->m_workspace = PWORKSPACE;
PWINDOW->m_isMapped = true;
Expand Down Expand Up @@ -370,6 +372,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
// 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},{},{},{}", PWINDOW, PWORKSPACE->m_name, PWINDOW->m_class, PWINDOW->m_title)});
EMIT_HOOK_EVENT("openWindowEarly", PWINDOW);
if (workspacePreviouslyEmpty) {
g_pEventManager->postEvent(SHyprIPCEvent{"populateworkspace", PWORKSPACE->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{"populateworkspacev2", std::format("{},{}", PWORKSPACE->m_id, PWORKSPACE->m_name)});
}

if (PWINDOW->m_isFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
Expand Down Expand Up @@ -510,6 +516,9 @@ void Events::listener_mapWindow(void* owner, void* data) {

// emit the hook event here after basic stuff has been initialized
EMIT_HOOK_EVENT("openWindow", PWINDOW);
if (workspacePreviouslyEmpty) {
EMIT_HOOK_EVENT("populateWorkspace", PWORKSPACE);
}

// apply data from default decos. Borders, shadows.
g_pDecorationPositioner->forceRecalcFor(PWINDOW);
Expand Down Expand Up @@ -627,6 +636,12 @@ void Events::listener_unmapWindow(void* owner, void* data) {
// do this after onWindowRemoved because otherwise it'll think the window is invalid
PWINDOW->m_isMapped = false;

if (!PWINDOW->m_workspace->hasWindow()) {
g_pEventManager->postEvent(SHyprIPCEvent{"depopulateworkspace", PWINDOW->m_workspace->m_name});
g_pEventManager->postEvent(SHyprIPCEvent{"depopulateworkspacev2", std::format("{},{}", PWINDOW->m_workspace->m_id, PWINDOW->m_workspace->m_name)});
EMIT_HOOK_EVENT("depopulateWorkspace", PWINDOW->m_workspace);
}

// refocus on a new window if needed
if (wasLastWindow) {
static auto FOCUSONCLOSE = CConfigValue<Hyprlang::INT>("input:focus_on_close");
Expand All @@ -644,7 +659,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE);
}

if (!PWINDOWCANDIDATE && PWINDOW->m_workspace && PWINDOW->m_workspace->getWindows() == 0)
if (!PWINDOWCANDIDATE && PWINDOW->m_workspace && !PWINDOW->m_workspace->hasWindow())
g_pInputManager->refocus();

g_pInputManager->sendMotionEventsToFocused();
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/MiscFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
WORKSPACEID id = next ? Desktop::focusState()->monitor()->activeWorkspaceID() : 0;
while (++id < LONG_MAX) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
if (!invalidWSes.contains(id) && (!PWORKSPACE || PWORKSPACE->getWindows() == 0)) {
if (!invalidWSes.contains(id) && (!PWORKSPACE || !PWORKSPACE->hasWindow())) {
result.id = id;
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2262,7 +2262,7 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) {
if (!Desktop::focusState()->window()) {
// if we have a clear focus, find the first window and get the next focusable.
const auto PWS = Desktop::focusState()->monitor()->m_activeWorkspace;
if (PWS && PWS->getWindows() > 0) {
if (PWS && PWS->hasWindow()) {
const auto PWINDOW = PWS->getFirstWindow();
switchToWindow(PWINDOW);
}
Expand Down
4 changes: 2 additions & 2 deletions src/managers/input/UnifiedWorkspaceSwipeGesture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void CUnifiedWorkspaceSwipeGesture::update(double delta) {
m_delta = std::clamp(m_delta, sc<double>(-SWIPEDISTANCE), sc<double>(SWIPEDISTANCE));

if ((m_workspaceBegin->m_id == workspaceIDLeft && *PSWIPENEW && (m_delta < 0)) ||
(m_delta > 0 && m_workspaceBegin->getWindows() == 0 && workspaceIDRight <= m_workspaceBegin->m_id) || (m_delta < 0 && m_workspaceBegin->m_id <= workspaceIDLeft)) {
(m_delta > 0 && !m_workspaceBegin->hasWindow() && workspaceIDRight <= m_workspaceBegin->m_id) || (m_delta < 0 && m_workspaceBegin->m_id <= workspaceIDLeft)) {

m_delta = 0;
g_pHyprRenderer->damageMonitor(m_monitor.lock());
Expand Down Expand Up @@ -311,4 +311,4 @@ void CUnifiedWorkspaceSwipeGesture::end() {
for (auto const& ls : Desktop::focusState()->monitor()->m_layerSurfaceLayers[2]) {
*ls->m_alpha = pSwitchedTo->m_hasFullscreenWindow && pSwitchedTo->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
}
}
}