mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 00:09:49 +01:00
added master layout
This commit is contained in:
parent
48e5bd96bc
commit
5c836e6460
10 changed files with 530 additions and 5 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
421
src/layout/MasterLayout.cpp
Normal file
421
src/layout/MasterLayout.cpp
Normal file
|
@ -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();
|
||||
}
|
54
src/layout/MasterLayout.hpp
Normal file
54
src/layout/MasterLayout.hpp
Normal file
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
Loading…
Reference in a new issue