diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 5e87c4fb..4258b4ec 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -57,27 +57,15 @@ void Events::listener_newOutput(wl_listener* listener, void* data) { return; } - if (g_pCompositor->m_bUnsafeState) { + if (g_pCompositor->m_bUnsafeState) Debug::log(WARN, "Recovering from an unsafe state. May you be lucky."); - } // add it to real std::shared_ptr* PNEWMONITORWRAP = nullptr; - for (auto& rm : g_pCompositor->m_vRealMonitors) { - if (rm->szName == OUTPUT->name) { - PNEWMONITORWRAP = &rm; - Debug::log(LOG, "Recovering a removed monitor."); - break; - } - } + PNEWMONITORWRAP = &g_pCompositor->m_vRealMonitors.emplace_back(std::make_shared()); - if (!PNEWMONITORWRAP) { - Debug::log(LOG, "Adding completely new monitor."); - PNEWMONITORWRAP = &g_pCompositor->m_vRealMonitors.emplace_back(std::make_shared()); - - (*PNEWMONITORWRAP)->ID = g_pCompositor->getNextAvailableMonitorID(OUTPUT->name); - } + (*PNEWMONITORWRAP)->ID = g_pCompositor->getNextAvailableMonitorID(OUTPUT->name); const auto PNEWMONITOR = PNEWMONITORWRAP->get(); @@ -91,6 +79,20 @@ void Events::listener_newOutput(wl_listener* listener, void* data) { // ready to process cuz we have a monitor if (PNEWMONITOR->m_bEnabled) { + + if (g_pCompositor->m_bUnsafeState) { + // recover workspaces + for (auto& ws : g_pCompositor->m_vWorkspaces) { + g_pCompositor->moveWorkspaceToMonitor(ws.get(), PNEWMONITOR); + } + + g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR; + + const auto POS = PNEWMONITOR->vecPosition + PNEWMONITOR->vecSize / 2.f; + if (g_pCompositor->m_sSeat.mouse) + wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, POS.x, POS.y); + } + g_pCompositor->m_bReadyToProcess = true; g_pCompositor->m_bUnsafeState = false; } @@ -184,12 +186,9 @@ void Events::listener_monitorDestroy(void* owner, void* data) { pMonitor->output = nullptr; pMonitor->m_bRenderingInitPassed = false; - // cleanup if not unsafe - if (!g_pCompositor->m_bUnsafeState) { - Debug::log(LOG, "Removing monitor %s from realMonitors", pMonitor->szName.c_str()); + Debug::log(LOG, "Removing monitor %s from realMonitors", pMonitor->szName.c_str()); - std::erase_if(g_pCompositor->m_vRealMonitors, [&](std::shared_ptr& el) { return el.get() == pMonitor; }); - } + std::erase_if(g_pCompositor->m_vRealMonitors, [&](std::shared_ptr& el) { return el.get() == pMonitor; }); } void Events::listener_monitorStateRequest(void* owner, void* data) { diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 5b30e351..773b0045 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -252,33 +252,31 @@ void CMonitor::onDisconnect() { if (!BACKUPMON) { Debug::log(WARN, "Unplugged last monitor, entering an unsafe state. Good luck my friend."); - - hyprListener_monitorStateRequest.removeCallback(); - hyprListener_monitorDestroy.removeCallback(); - g_pCompositor->m_bUnsafeState = true; - - std::erase_if(g_pCompositor->m_vMonitors, [&](std::shared_ptr& el) { return el.get() == this; }); - - return; } - // snap cursor - wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, - BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f); + if (BACKUPMON) { + // snap cursor + wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, + BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f); - // move workspaces - std::deque wspToMove; - for (auto& w : g_pCompositor->m_vWorkspaces) { - if (w->m_iMonitorID == ID) { - wspToMove.push_back(w.get()); + // move workspaces + std::deque wspToMove; + for (auto& w : g_pCompositor->m_vWorkspaces) { + if (w->m_iMonitorID == ID) { + wspToMove.push_back(w.get()); + } } - } - for (auto& w : wspToMove) { - w->m_szLastMonitor = szName; - g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON); - w->startAnim(true, true, true); + for (auto& w : wspToMove) { + w->m_szLastMonitor = szName; + g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON); + w->startAnim(true, true, true); + } + } else { + g_pCompositor->m_pLastFocus = nullptr; + g_pCompositor->m_pLastWindow = nullptr; + g_pCompositor->m_pLastMonitor = nullptr; } activeWorkspace = -1; @@ -289,8 +287,6 @@ void CMonitor::onDisconnect() { wlr_output_commit(output); - std::erase_if(g_pCompositor->m_vWorkspaces, [&](std::unique_ptr& el) { return el->m_iMonitorID == ID; }); - if (g_pCompositor->m_pLastMonitor == this) g_pCompositor->setActiveMonitor(BACKUPMON); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index f4e845c3..113b4851 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -3,8 +3,10 @@ #include "HookSystemManager.hpp" int wlTick(void* data) { + if (g_pAnimationManager) + g_pAnimationManager->onTicked(); - if (g_pCompositor->m_bSessionActive && g_pAnimationManager && g_pHookSystem && + if (g_pCompositor->m_bSessionActive && g_pAnimationManager && g_pHookSystem && !g_pCompositor->m_bUnsafeState && std::ranges::any_of(g_pCompositor->m_vMonitors, [](const auto& mon) { return mon->m_bEnabled && mon->output; })) { g_pAnimationManager->tick(); EMIT_HOOK_EVENT("tick", nullptr); @@ -37,10 +39,11 @@ void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, m_mBezierCurves[name].setup(&points); } -void CAnimationManager::tick() { - +void CAnimationManager::onTicked() { m_bTickScheduled = false; +} +void CAnimationManager::tick() { static std::chrono::time_point lastTick = std::chrono::high_resolution_clock::now(); m_fLastTickTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - lastTick).count() / 1000.0; lastTick = std::chrono::high_resolution_clock::now(); @@ -247,8 +250,8 @@ void CAnimationManager::tick() { const auto EXTENTS = PDECO->getWindowDecorationExtents(); wlr_box dmg = {PWINDOW->m_vRealPosition.vec().x - EXTENTS.topLeft.x, PWINDOW->m_vRealPosition.vec().y - EXTENTS.topLeft.y, - PWINDOW->m_vRealSize.vec().x + EXTENTS.topLeft.x + EXTENTS.bottomRight.x, - PWINDOW->m_vRealSize.vec().y + EXTENTS.topLeft.y + EXTENTS.bottomRight.y}; + PWINDOW->m_vRealSize.vec().x + EXTENTS.topLeft.x + EXTENTS.bottomRight.x, + PWINDOW->m_vRealSize.vec().y + EXTENTS.topLeft.y + EXTENTS.bottomRight.y}; if (!*PSHADOWIGNOREWINDOW) { // easy, damage the entire box diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index cf1f19b3..281c61f8 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -14,6 +14,7 @@ class CAnimationManager { void tick(); bool shouldTickForNext(); + void onTicked(); void scheduleTick(); void addBezierWithName(std::string, const Vector2D&, const Vector2D&); void removeAllBeziers(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 0f1cd139..ef6ee6cb 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -215,7 +215,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) { } bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) { - if (!g_pCompositor->m_bSessionActive) { + if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) { m_dPressedKeycodes.clear(); m_dPressedKeysyms.clear(); return true; @@ -1502,7 +1502,6 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) { } bool requestedWorkspaceIsAlreadyOpen = false; - bool requestedWorkspaceExists = g_pCompositor->getWorkspaceByID(workspaceID); const auto PMONITOR = *PFOLLOWMOUSE == 1 ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->m_pLastMonitor; int specialOpenOnMonitor = PMONITOR->specialWorkspaceID; diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp index c1049bb5..4a7278d4 100644 --- a/src/protocols/XDGOutput.cpp +++ b/src/protocols/XDGOutput.cpp @@ -58,16 +58,11 @@ void CXDGOutputProtocol::bindManager(wl_client* client, void* data, uint32_t ver } CXDGOutputProtocol::CXDGOutputProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { - g_pHookSystem->hookDynamic("monitorLayoutChanged", [&](void* self, std::any param) { this->updateAllOutputs(); }); - g_pHookSystem->hookDynamic("configReloaded", [&](void* self, std::any param) { this->updateAllOutputs(); }); - g_pHookSystem->hookDynamic("monitorRemoved", [&](void* self, std::any param) { + g_pHookSystem->hookDynamic("monitorLayoutChanged", [this](void* self, std::any param) { this->updateAllOutputs(); }); + g_pHookSystem->hookDynamic("configReloaded", [this](void* self, std::any param) { this->updateAllOutputs(); }); + g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, std::any param) { const auto PMONITOR = std::any_cast(param); - std::erase_if(m_vXDGOutputs, [&](const auto& other) { - const bool R = other->monitor == PMONITOR; - if (R) - other->resource->markDefunct(); - return R; - }); + std::erase_if(m_vXDGOutputs, [&](const auto& other) { return other->monitor == PMONITOR; }); }); }