Add ability to split master when only 1 additional window (#2025)

* fix: enable master split less than 2 windows

added a config flag  "master:allow_small_split"
added config to minimum windows check.
TODO: check that no bug added (remove all masters?)

* IMPL:FIX: multiple master windows full width

Implemented the ability to have multiple master windows filling the full
monitor width in master mode.
this is controlled by the config option master:allow_small_split
(true/false)
this defaults to false as it was the original behaviour before this
patch

* BUGFIX: corrected issue with blanks re: addmaster

FIX 1: Treat ORIENTATION_CENTER the same as ORIENTATION_LEFT unless
there are enough STACK_WINDOWS to fill both wings.
FIX 2: enforced last window always set as master in
MasterLayout::CHyperMasterLayout::calculateWorkspace();
FIX 3: fix 2, also fixed focus issues previously noted.

* Changes requested by vaxerski

changed how we access config variables (by reference not value)
fixed a regression previously missed prior to requested changes.
I had somehow broken the very functionality i meant to add.

* added static keyword to config variables

* removed superfluous static tags

I made a mistake with making too many variables static.
this made them only evaluate once per runtime breaking things majorly.
My appologies. I haven't touched C++ in nearly 20 years.

* remove annoying comment

---------

Co-authored-by: vaxerski <43317083+vaxerski@users.noreply.github.com>
This commit is contained in:
Person1873 2023-04-14 00:20:58 +10:00 committed by GitHub
parent 4bc3f9adbe
commit 33d06fb0e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 25 deletions

View file

@ -144,6 +144,7 @@ void CConfigManager::setDefaultVars() {
configValues["master:no_gaps_when_only"].intValue = 0; configValues["master:no_gaps_when_only"].intValue = 0;
configValues["master:orientation"].strValue = "left"; configValues["master:orientation"].strValue = "left";
configValues["master:inherit_fullscreen"].intValue = 1; configValues["master:inherit_fullscreen"].intValue = 1;
configValues["master:allow_small_split"].intValue = 0;
configValues["animations:enabled"].intValue = 1; configValues["animations:enabled"].intValue = 1;

View file

@ -153,6 +153,10 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
if (!PNODE) if (!PNODE)
return; return;
const auto WORKSPACEID = PNODE->workspaceID;
const auto MASTERSLEFT = getMastersOnWorkspace(WORKSPACEID);
static const auto* SMALLSPLIT = &g_pConfigManager->getConfigValuePtr("master:allow_small_split")->intValue;
pWindow->m_sSpecialRenderData.rounding = true; pWindow->m_sSpecialRenderData.rounding = true;
pWindow->m_sSpecialRenderData.border = true; pWindow->m_sSpecialRenderData.border = true;
pWindow->m_sSpecialRenderData.decorate = true; pWindow->m_sSpecialRenderData.decorate = true;
@ -160,12 +164,10 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
if (pWindow->m_bIsFullscreen) if (pWindow->m_bIsFullscreen)
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
const auto MASTERSLEFT = getMastersOnWorkspace(PNODE->workspaceID); if (PNODE->isMaster && (MASTERSLEFT <= 1 || *SMALLSPLIT == 1)) {
// find a new master from top of the list
if (PNODE->isMaster && MASTERSLEFT < 2) {
// find new one
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
if (!nd.isMaster && nd.workspaceID == PNODE->workspaceID) { if (!nd.isMaster && nd.workspaceID == WORKSPACEID) {
nd.isMaster = true; nd.isMaster = true;
nd.percMaster = PNODE->percMaster; nd.percMaster = PNODE->percMaster;
break; break;
@ -173,8 +175,6 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
} }
} }
const auto WORKSPACEID = PNODE->workspaceID;
m_lMasterNodesData.remove(*PNODE); m_lMasterNodesData.remove(*PNODE);
if (getMastersOnWorkspace(WORKSPACEID) == getNodesOnWorkspace(WORKSPACEID) && MASTERSLEFT > 1) { if (getMastersOnWorkspace(WORKSPACEID) == getNodesOnWorkspace(WORKSPACEID) && MASTERSLEFT > 1) {
@ -185,7 +185,16 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
} }
} }
} }
// BUGFIX: correct bug where closing one master in a stack of 2 would leave
// the screen half bare, and make it difficult to select remaining window
if (getNodesOnWorkspace(WORKSPACEID) == 1) {
for (auto& nd : m_lMasterNodesData) {
if (nd.workspaceID == WORKSPACEID && nd.isMaster == false) {
nd.isMaster = true;
break;
}
}
}
recalculateMonitor(pWindow->m_iMonitorID); recalculateMonitor(pWindow->m_iMonitorID);
} }
@ -254,20 +263,26 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
} }
} }
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID); const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
const auto WINDOWS = getNodesOnWorkspace(PWORKSPACE->m_iID);
const auto STACKWINDOWS = WINDOWS - MASTERS;
//compute placement of master window(s) //compute placement of master window(s)
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2 && !centerMasterWindow) { if ((WINDOWS < 2) && !centerMasterWindow) {
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition; PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x,
PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
applyNodeDataToWindow(PMASTERNODE); applyNodeDataToWindow(PMASTERNODE);
return; return;
} else if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT) { } else if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT || (orientation == ORIENTATION_CENTER && STACKWINDOWS <= 1)) {
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y; float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
int nodesLeft = MASTERS; int nodesLeft = MASTERS;
float nextY = 0; float nextY = 0;
const float WIDTH = (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster; float WIDTH = 0;
if (STACKWINDOWS == 0 && MASTERS > 0)
WIDTH = (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x);
else
WIDTH = (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster;
for (auto& n : m_lMasterNodesData) { for (auto& n : m_lMasterNodesData) {
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) { if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
@ -315,7 +330,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
applyNodeDataToWindow(&n); applyNodeDataToWindow(&n);
} }
} }
} else if (orientation == ORIENTATION_CENTER) { } else if (orientation == ORIENTATION_CENTER && STACKWINDOWS >= 2) {
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y; float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
int nodesLeft = MASTERS; int nodesLeft = MASTERS;
float nextY = 0; float nextY = 0;
@ -341,7 +356,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
//compute placement of slave window(s) //compute placement of slave window(s)
int slavesLeft = getNodesOnWorkspace(PWORKSPACE->m_iID) - MASTERS; int slavesLeft = getNodesOnWorkspace(PWORKSPACE->m_iID) - MASTERS;
if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT) { if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT || (orientation == ORIENTATION_CENTER && STACKWINDOWS <= 1)) {
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y; float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
float nextY = 0; float nextY = 0;
const float WIDTH = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x; const float WIDTH = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x;
@ -350,7 +365,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
continue; continue;
if (orientation == ORIENTATION_LEFT) { if (orientation == ORIENTATION_LEFT || (orientation == ORIENTATION_CENTER && STACKWINDOWS <= 1)) {
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition +
Vector2D(PMASTERNODE->percMaster * (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x), nextY); Vector2D(PMASTERNODE->percMaster * (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x), nextY);
} else { } else {
@ -392,7 +407,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
applyNodeDataToWindow(&nd); applyNodeDataToWindow(&nd);
} }
} else if (orientation == ORIENTATION_CENTER) { } else if (orientation == ORIENTATION_CENTER && STACKWINDOWS >= 2) {
float heightLeftL = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y; float heightLeftL = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
float heightLeftR = heightLeftL; float heightLeftR = heightLeftL;
float heightLeft = 0; float heightLeft = 0;
@ -951,14 +966,14 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (header.pWindow->m_bIsFloating) if (header.pWindow->m_bIsFloating)
return 0; return 0;
const auto PNODE = getNodeFromWindow(header.pWindow); const auto PNODE = getNodeFromWindow(header.pWindow);
const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID); const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID);
const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID); const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID);
static const auto* SMALLSPLIT = &g_pConfigManager->getConfigValuePtr("master:allow_small_split")->intValue;
if (MASTERS + 2 > WINDOWS) if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0)
return 0; return 0;
prepareLoseFocus(header.pWindow); prepareLoseFocus(header.pWindow);
if (!PNODE || PNODE->isMaster) { if (!PNODE || PNODE->isMaster) {