summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvaxerski <43317083+vaxerski@users.noreply.github.com>2022-07-16 15:57:31 +0200
committervaxerski <43317083+vaxerski@users.noreply.github.com>2022-07-16 15:57:31 +0200
commit5c836e6460ae5e8c290cfff61ec0d2d0e99dfa15 (patch)
treebb38dedd586738f0a1fe37b9a4234b754f54541d /src
parent48e5bd96bc71f94f774eb92b00ef560b2f911c73 (diff)
added master layout
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp6
-rw-r--r--src/config/ConfigManager.cpp8
-rw-r--r--src/layout/DwindleLayout.cpp15
-rw-r--r--src/layout/DwindleLayout.hpp3
-rw-r--r--src/layout/IHyprLayout.hpp2
-rw-r--r--src/layout/MasterLayout.cpp421
-rw-r--r--src/layout/MasterLayout.hpp54
-rw-r--r--src/managers/AnimationManager.cpp1
-rw-r--r--src/managers/LayoutManager.cpp20
-rw-r--r--src/managers/LayoutManager.hpp5
10 files changed, 530 insertions, 5 deletions
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<CAnimationManager>();
+ Debug::log(LOG, "Creating the LayoutManager!");
+ g_pLayoutManager = std::make_unique<CLayoutManager>();
+
Debug::log(LOG, "Creating the ConfigManager!");
g_pConfigManager = std::make_unique<CConfigManager>();
@@ -245,9 +248,6 @@ void CCompositor::startCompositor() {
Debug::log(LOG, "Creating the XWaylandManager!");
g_pXWaylandManager = std::make_unique<CHyprXWaylandManager>();
- Debug::log(LOG, "Creating the LayoutManager!");
- g_pLayoutManager = std::make_unique<CLayoutManager>();
-
Debug::log(LOG, "Creating the EventManager!");
g_pEventManager = std::make_unique<CEventManager>();
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<SDwindleNodeData> 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 <list>
+#include <deque>
+
+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<SMasterNodeData> 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<CLayoutManager> g_pLayoutManager; \ No newline at end of file