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
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->aliveAndVisible(); });
}
1 change: 1 addition & 0 deletions src/desktop/Workspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class CWorkspace {
void updateWindows();
void setPersistent(bool persistent);
bool isPersistent();
bool hasWindow();

struct {
CSignalT<> destroy;
Expand Down
36 changes: 31 additions & 5 deletions src/desktop/view/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -495,6 +497,16 @@ 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 = 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()) {
Expand All @@ -504,7 +516,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 @@ -559,10 +571,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 Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no {}

g_pEventManager->postEvent(SHyprIPCEvent{"populateworkspace", std::format("{},{}", PWORKSPACE->m_id, PWORKSPACE->m_name)});
}

if (m_isFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(m_self.lock());
Expand Down Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no {}

EMIT_HOOK_EVENT("populateWorkspace", m_self.lock());
}


// apply data from default decos. Borders, shadows.
g_pDecorationPositioner->forceRecalcFor(m_self.lock());
Expand Down Expand Up @@ -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<Hyprlang::INT>("input:focus_on_close");
Expand All @@ -2503,7 +2529,7 @@ void CWindow::unmapWindow() {
g_pCompositor->setWindowFullscreenInternal(PWINDOWCANDIDATE, CURRENTFSMODE);
}

if (!PWINDOWCANDIDATE && m_workspace && m_workspace->getWindows() == 0)
if (!PWINDOWCANDIDATE && m_workspace && !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 @@ -2259,7 +2259,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
2 changes: 1 addition & 1 deletion 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
Loading