diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 14726df8..e70f2e32 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -227,6 +227,9 @@ void CCompositor::startCompositor() { Debug::log(LOG, "Creating the AnimationManager!"); g_pAnimationManager = std::make_unique(); + Debug::log(LOG, "Creating the LayoutManager!"); + g_pLayoutManager = std::make_unique(); + Debug::log(LOG, "Creating the ConfigManager!"); g_pConfigManager = std::make_unique(); @@ -245,9 +248,6 @@ void CCompositor::startCompositor() { Debug::log(LOG, "Creating the XWaylandManager!"); g_pXWaylandManager = std::make_unique(); - Debug::log(LOG, "Creating the LayoutManager!"); - g_pLayoutManager = std::make_unique(); - Debug::log(LOG, "Creating the EventManager!"); g_pEventManager = std::make_unique(); g_pEventManager->startThread(); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 00550878..250ee6e5 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -43,6 +43,8 @@ void CConfigManager::setDefaultVars() { configValues["general:col.active_border"].intValue = 0xffffffff; configValues["general:col.inactive_border"].intValue = 0xff444444; configValues["general:cursor_inactive_timeout"].intValue = 0; + + configValues["general:layout"].strValue = "dwindle"; configValues["misc:disable_hyprland_logo"].intValue = 0; configValues["misc:disable_splash_rendering"].intValue = 0; @@ -80,6 +82,9 @@ void CConfigManager::setDefaultVars() { configValues["dwindle:special_scale_factor"].floatValue = 0.8f; configValues["dwindle:split_width_multiplier"].floatValue = 1.0f; + configValues["master:special_scale_factor"].floatValue = 0.8f; + configValues["master:new_is_master"].intValue = 1; + configValues["animations:enabled"].intValue = 1; configValues["animations:speed"].floatValue = 7.f; configValues["animations:curve"].strValue = "default"; @@ -923,6 +928,9 @@ void CConfigManager::loadConfigLoadVars() { // Update window border colors g_pCompositor->updateAllWindowsAnimatedDecorationValues(); + // update layout + g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue); + // Force the compositor to fully re-render all monitors for (auto& m : g_pCompositor->m_vMonitors) m->forceFullFrames = 2; diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index c356c8cc..307537d8 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -217,7 +217,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace); } else - OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace); + OPENINGON = getFirstNodeOnWorkspace(pWindow->m_iWorkspaceID); Debug::log(LOG, "OPENINGON: %x, Workspace: %i, Monitor: %i", OPENINGON, PNODE->workspaceID, PMONITOR->ID); @@ -864,3 +864,16 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) { std::string CHyprDwindleLayout::getLayoutName() { return "dwindle"; } + +void CHyprDwindleLayout::onEnable() { + for (auto& w : g_pCompositor->m_vWindows) { + if (w->m_bIsFloating || !w->m_bMappedX11 || !w->m_bIsMapped || w->m_bHidden) + continue; + + onWindowCreatedTiling(w.get()); + } +} + +void CHyprDwindleLayout::onDisable() { + m_lDwindleNodesData.clear(); +} \ No newline at end of file diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index bd73a315..b60b87e0 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -55,6 +55,9 @@ public: virtual void alterSplitRatioBy(CWindow*, float); virtual std::string getLayoutName(); + virtual void onEnable(); + virtual void onDisable(); + private: std::list m_lDwindleNodesData; diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index d214bf73..29f47405 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -16,6 +16,8 @@ enum eFullscreenMode : uint8_t; interface IHyprLayout { public: + virtual void onEnable() = 0; + virtual void onDisable() = 0; /* Called when a window is created (mapped) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp new file mode 100644 index 00000000..f88ee08f --- /dev/null +++ b/src/layout/MasterLayout.cpp @@ -0,0 +1,421 @@ +#include "MasterLayout.hpp" +#include "../Compositor.hpp" + +SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(CWindow* pWindow) { + for (auto& nd : m_lMasterNodesData) { + if (nd.pWindow == pWindow) + return &nd; + } + + return nullptr; +} + +int CHyprMasterLayout::getNodesOnWorkspace(const int& ws) { + int no = 0; + for (auto& n : m_lMasterNodesData) { + if (n.workspaceID == ws) + no++; + } + + return no; +} + +std::string CHyprMasterLayout::getLayoutName() { + return "Master"; +} + +SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const int& ws) { + for (auto& n : m_lMasterNodesData) { + if (n.isMaster && n.workspaceID == ws) + return &n; + } + + return nullptr; +} + +void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow) { + if (pWindow->m_bIsFloating) + return; + + const auto PNODE = &m_lMasterNodesData.emplace_back(); + + PNODE->workspaceID = pWindow->m_iWorkspaceID; + PNODE->pWindow = pWindow; + + static auto *const PNEWISMASTER = &g_pConfigManager->getConfigValuePtr("master:new_is_master")->intValue; + + const auto WINDOWSONWORKSPACE = getNodesOnWorkspace(PNODE->workspaceID); + float lastSplitPercent = 0.5f; + + if (*PNEWISMASTER || WINDOWSONWORKSPACE == 1) { + for (auto& nd : m_lMasterNodesData) { + if (nd.isMaster && nd.workspaceID == PNODE->workspaceID) { + nd.isMaster = false; + lastSplitPercent = nd.percMaster; + break; + } + } + + PNODE->isMaster = true; + PNODE->percMaster = lastSplitPercent; + } else { + PNODE->isMaster = false; + } + + // recalc + recalculateMonitor(pWindow->m_iMonitorID); +} + +void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) { + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE) + return; + + if (PNODE->isMaster) { + // find new one + for (auto& nd : m_lMasterNodesData) { + if (!nd.isMaster) { + nd.isMaster = true; + break; + } + } + } + + m_lMasterNodesData.remove(*PNODE); + + recalculateMonitor(pWindow->m_iMonitorID); +} + +void CHyprMasterLayout::recalculateMonitor(const int& monid) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(monid); + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + + if (!PWORKSPACE) + return; + + g_pHyprRenderer->damageMonitor(PMONITOR); + + if (PMONITOR->specialWorkspaceOpen) { + calculateWorkspace(SPECIAL_WORKSPACE_ID); + } + + if (PWORKSPACE->m_bHasFullscreenWindow) { + if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) + return; + + // massive hack from the fullscreen func + const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); + + SMasterNodeData fakeNode; + fakeNode.pWindow = PFULLWINDOW; + fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; + fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; + fakeNode.workspaceID = PWORKSPACE->m_iID; + PFULLWINDOW->m_vPosition = fakeNode.position; + PFULLWINDOW->m_vSize = fakeNode.size; + + applyNodeDataToWindow(&fakeNode); + + return; + } + + // calc the WS + calculateWorkspace(PWORKSPACE->m_iID); +} + +void CHyprMasterLayout::calculateWorkspace(const int& ws) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(ws); + + if (!PWORKSPACE) + return; + + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); + + const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID); + + if (!PMASTERNODE) + return; + + if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) { + PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition; + PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); + applyNodeDataToWindow(PMASTERNODE); + return; + } else { + PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition; + PMASTERNODE->size = Vector2D((PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); + } + + const auto SLAVESIZE = 1.f / (getNodesOnWorkspace(PWORKSPACE->m_iID) - 1) * (PMASTERNODE->size.y); + int slavesDone = 0; + + for (auto& nd : m_lMasterNodesData) { + if (nd.workspaceID != PWORKSPACE->m_iID) + continue; + + if (nd == *PMASTERNODE) { + applyNodeDataToWindow(PMASTERNODE); + continue; + } + + nd.position = Vector2D(PMASTERNODE->size.x + PMASTERNODE->position.x, slavesDone * SLAVESIZE + PMASTERNODE->position.y); + nd.size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x, SLAVESIZE); + + slavesDone++; + + applyNodeDataToWindow(&nd); + } +} + +void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { + SMonitor* PMONITOR = nullptr; + + if (pNode->workspaceID == SPECIAL_WORKSPACE_ID) { + for (auto& m : g_pCompositor->m_vMonitors) { + if (m->specialWorkspaceOpen) { + PMONITOR = m.get(); + break; + } + } + } else { + PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID); + } + + if (!PMONITOR) { + Debug::log(ERR, "Orphaned Node %x (workspace ID: %i)!!", pNode, pNode->workspaceID); + return; + } + + // for gaps outer + const bool DISPLAYLEFT = STICKS(pNode->position.x, PMONITOR->vecPosition.x + PMONITOR->vecReservedTopLeft.x); + const bool DISPLAYRIGHT = STICKS(pNode->position.x + pNode->size.x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x); + const bool DISPLAYTOP = STICKS(pNode->position.y, PMONITOR->vecPosition.y + PMONITOR->vecReservedTopLeft.y); + const bool DISPLAYBOTTOM = STICKS(pNode->position.y + pNode->size.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y); + + const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); + const auto GAPSIN = g_pConfigManager->getInt("general:gaps_in"); + const auto GAPSOUT = g_pConfigManager->getInt("general:gaps_out"); + + const auto PWINDOW = pNode->pWindow; + + if (!g_pCompositor->windowValidMapped(PWINDOW)) { + Debug::log(ERR, "Node %x holding invalid window %x!!", pNode, PWINDOW); + return; + } + + PWINDOW->m_vSize = pNode->size; + PWINDOW->m_vPosition = pNode->position; + + // TODO: special + + auto calcPos = PWINDOW->m_vPosition + Vector2D(BORDERSIZE, BORDERSIZE); + auto calcSize = PWINDOW->m_vSize - Vector2D(2 * BORDERSIZE, 2 * BORDERSIZE); + + const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? GAPSOUT : GAPSIN, + DISPLAYTOP ? GAPSOUT : GAPSIN); + + const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? GAPSOUT : GAPSIN, + DISPLAYBOTTOM ? GAPSOUT : GAPSIN); + + calcPos = calcPos + OFFSETTOPLEFT; + calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; + + if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) { + static auto *const PSCALEFACTOR = &g_pConfigManager->getConfigValuePtr("master:special_scale_factor")->floatValue; + + PWINDOW->m_vRealPosition = calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f; + PWINDOW->m_vRealSize = calcSize * *PSCALEFACTOR; + + g_pXWaylandManager->setWindowSize(PWINDOW, calcSize * *PSCALEFACTOR); + } else { + PWINDOW->m_vRealSize = calcSize; + PWINDOW->m_vRealPosition = calcPos; + + g_pXWaylandManager->setWindowSize(PWINDOW, calcSize); + } + + PWINDOW->updateWindowDecos(); +} + +bool CHyprMasterLayout::isWindowTiled(CWindow* pWindow) { + return getNodeFromWindow(pWindow) != nullptr; +} + +void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* pWindow) { + const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow; + + if (!g_pCompositor->windowValidMapped(PWINDOW)) + return; + + const auto PNODE = getNodeFromWindow(PWINDOW); + + if (!PNODE) { + PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999)); + PWINDOW->updateWindowDecos(); + return; + } + + // get master + const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID); + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); + + if (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) < 2) + return; + + float delta = pixResize.x / PMONITOR->vecSize.x; + + PMASTER->percMaster += delta; + + std::clamp(PMASTER->percMaster, 0.05f, 0.95f); + + recalculateMonitor(PMONITOR->ID); +} + +void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode fullscreenMode, bool on) { + if (!g_pCompositor->windowValidMapped(pWindow)) + return; + + if (on == pWindow->m_bIsFullscreen) + return; // ignore + + const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); + + if (PWORKSPACE->m_bHasFullscreenWindow && on) { + // if the window wants to be fullscreen but there already is one, + // ignore the request. + return; + } + + // otherwise, accept it. + pWindow->m_bIsFullscreen = on; + PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow; + + g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)on))); + + if (!pWindow->m_bIsFullscreen) { + // if it got its fullscreen disabled, set back its node if it had one + const auto PNODE = getNodeFromWindow(pWindow); + if (PNODE) + applyNodeDataToWindow(PNODE); + else { + // get back its' dimensions from position and size + pWindow->m_vRealPosition = pWindow->m_vPosition; + pWindow->m_vRealSize = pWindow->m_vSize; + } + } else { + // if it now got fullscreen, make it fullscreen + + PWORKSPACE->m_efFullscreenMode = fullscreenMode; + + // save position and size if floating + if (pWindow->m_bIsFloating) { + pWindow->m_vPosition = pWindow->m_vRealPosition.vec(); + pWindow->m_vSize = pWindow->m_vRealSize.vec(); + } + + // apply new pos and size being monitors' box + if (fullscreenMode == FULLSCREEN_FULL) { + pWindow->m_vRealPosition = PMONITOR->vecPosition; + pWindow->m_vRealSize = PMONITOR->vecSize; + } else { + // This is a massive hack. + // We make a fake "only" node and apply + // To keep consistent with the settings without C+P code + + SMasterNodeData fakeNode; + fakeNode.pWindow = pWindow; + fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; + fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight; + fakeNode.workspaceID = pWindow->m_iWorkspaceID; + pWindow->m_vPosition = fakeNode.position; + pWindow->m_vSize = fakeNode.size; + + applyNodeDataToWindow(&fakeNode); + } + } + + g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); + + g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); + + g_pCompositor->moveWindowToTop(pWindow); + + // we need to fix XWayland windows by sending them to NARNIA + // because otherwise they'd still be recieving mouse events + g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace); + + recalculateMonitor(PMONITOR->ID); +} + +void CHyprMasterLayout::recalculateWindow(CWindow* pWindow) { + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE) + return; + + recalculateMonitor(pWindow->m_iMonitorID); +} + +SWindowRenderLayoutHints CHyprMasterLayout::requestRenderHints(CWindow* pWindow) { + // window should be valid, insallah + + SWindowRenderLayoutHints hints; + + return hints; // master doesnt have any hints +} + +void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { + // windows should be valid, insallah + + const auto PNODE = getNodeFromWindow(pWindow); + const auto PNODE2 = getNodeFromWindow(pWindow2); + + if (!PNODE2 || !PNODE) + return; + + if (PNODE->workspaceID != PNODE2->workspaceID) { + Debug::log(ERR, "Master: Rejecting a swap between workspaces"); + return; + } + + // massive hack: just swap window pointers, lol + const auto PWINDOW1 = PNODE->pWindow; + PNODE->pWindow = PNODE2->pWindow; + PNODE2->pWindow = PWINDOW1; + + recalculateMonitor(PWINDOW1->m_iMonitorID); +} + +void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) { + // window should be valid, insallah + + const auto PNODE = getNodeFromWindow(pWindow); + + if (!PNODE) + return; + + const auto PMASTER = getMasterNodeOnWorkspace(pWindow->m_iWorkspaceID); + + PMASTER->percMaster = std::clamp(PMASTER->percMaster + ratio, 0.05f, 0.95f); + + recalculateMonitor(pWindow->m_iMonitorID); +} + +std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) { + return ""; +} + +void CHyprMasterLayout::onEnable() { + for (auto& w : g_pCompositor->m_vWindows) { + if (w->m_bIsFloating || !w->m_bMappedX11 || !w->m_bIsMapped || w->m_bHidden) + continue; + + onWindowCreatedTiling(w.get()); + } +} + +void CHyprMasterLayout::onDisable() { + m_lMasterNodesData.clear(); +} \ No newline at end of file diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp new file mode 100644 index 00000000..318f8940 --- /dev/null +++ b/src/layout/MasterLayout.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include "IHyprLayout.hpp" +#include +#include + +enum eFullscreenMode : uint8_t; + +struct SMasterNodeData { + bool isMaster = false; + float percMaster = 0.5f; + + CWindow* pWindow = nullptr; + + Vector2D position; + Vector2D size; + + int workspaceID = -1; + + bool operator==(const SMasterNodeData& rhs) { + return pWindow == rhs.pWindow; + } +}; + +class CHyprMasterLayout : public IHyprLayout { +public: + virtual void onWindowCreatedTiling(CWindow*); + virtual void onWindowRemovedTiling(CWindow*); + virtual bool isWindowTiled(CWindow*); + virtual void recalculateMonitor(const int&); + virtual void recalculateWindow(CWindow*); + virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr); + virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool); + virtual std::any layoutMessage(SLayoutMessageHeader, std::string); + virtual SWindowRenderLayoutHints requestRenderHints(CWindow*); + virtual void switchWindows(CWindow*, CWindow*); + virtual void alterSplitRatioBy(CWindow*, float); + virtual std::string getLayoutName(); + + virtual void onEnable(); + virtual void onDisable(); + +private: + + std::list m_lMasterNodesData; + + int getNodesOnWorkspace(const int&); + void applyNodeDataToWindow(SMasterNodeData*); + SMasterNodeData* getNodeFromWindow(CWindow*); + SMasterNodeData* getMasterNodeOnWorkspace(const int&); + void calculateWorkspace(const int&); + + friend struct SMasterNodeData; +}; \ No newline at end of file diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index a8743afd..5d3027c9 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -191,7 +191,6 @@ void CAnimationManager::tick() { } case AVARDAMAGE_SHADOW: { RASSERT(PWINDOW, "Tried to AVARDAMAGE_SHADOW a non-window AVAR!"); - static auto* const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue; static auto* const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue; const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW); diff --git a/src/managers/LayoutManager.cpp b/src/managers/LayoutManager.cpp index ec723350..8e7e397b 100644 --- a/src/managers/LayoutManager.cpp +++ b/src/managers/LayoutManager.cpp @@ -4,8 +4,28 @@ IHyprLayout* CLayoutManager::getCurrentLayout() { switch (m_iCurrentLayoutID) { case DWINDLE: return &m_cDwindleLayout; + case MASTER: + return &m_cMasterLayout; } // fallback return &m_cDwindleLayout; +} + +void CLayoutManager::switchToLayout(std::string layout) { + if (layout == "dwindle") { + if (m_iCurrentLayoutID != DWINDLE) { + getCurrentLayout()->onDisable(); + m_iCurrentLayoutID = DWINDLE; + getCurrentLayout()->onEnable(); + } + } else if (layout == "master") { + if (m_iCurrentLayoutID != MASTER) { + getCurrentLayout()->onDisable(); + m_iCurrentLayoutID = MASTER; + getCurrentLayout()->onEnable(); + } + } else { + Debug::log(ERR, "Unknown layout %s!", layout.c_str()); + } } \ No newline at end of file diff --git a/src/managers/LayoutManager.hpp b/src/managers/LayoutManager.hpp index 20f1f7f9..aa340e79 100644 --- a/src/managers/LayoutManager.hpp +++ b/src/managers/LayoutManager.hpp @@ -1,20 +1,25 @@ #pragma once #include "../layout/DwindleLayout.hpp" +#include "../layout/MasterLayout.hpp" class CLayoutManager { public: IHyprLayout* getCurrentLayout(); + void switchToLayout(std::string); + private: enum HYPRLAYOUTS { DWINDLE = 0, + MASTER }; HYPRLAYOUTS m_iCurrentLayoutID = DWINDLE; CHyprDwindleLayout m_cDwindleLayout; + CHyprMasterLayout m_cMasterLayout; }; inline std::unique_ptr g_pLayoutManager; \ No newline at end of file