Added center orientation to master layout (#1642)

* Added center orientation to master layout to improve experience on ultra widescreen monitors.

* Added support for orientationcenter layout message for master layout

* Added ability to optionally always center master window when in centered master mode.
This commit is contained in:
Marcus Kellerman 2023-02-26 15:12:14 -08:00 committed by GitHub
parent 2e21ad875b
commit 492f36f7df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 98 additions and 14 deletions

View file

@ -114,6 +114,7 @@ void CConfigManager::setDefaultVars() {
configValues["master:special_scale_factor"].floatValue = 0.8f; configValues["master:special_scale_factor"].floatValue = 0.8f;
configValues["master:new_is_master"].intValue = 1; configValues["master:new_is_master"].intValue = 1;
configValues["master:always_center_master"].intValue = 0;
configValues["master:new_on_top"].intValue = 0; configValues["master:new_on_top"].intValue = 0;
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";

View file

@ -46,8 +46,10 @@ SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) {
PWORKSPACEDATA->orientation = ORIENTATION_RIGHT; PWORKSPACEDATA->orientation = ORIENTATION_RIGHT;
} else if (*orientation == "bottom") { } else if (*orientation == "bottom") {
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM; PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
} else { } else if (*orientation == "left"){
PWORKSPACEDATA->orientation = ORIENTATION_LEFT; PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
} else {
PWORKSPACEDATA->orientation = ORIENTATION_CENTER;
} }
return PWORKSPACEDATA; return PWORKSPACEDATA;
} }
@ -56,6 +58,7 @@ std::string CHyprMasterLayout::getLayoutName() {
return "Master"; return "Master";
} }
SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const int& ws) { SMasterNodeData* CHyprMasterLayout::getMasterNodeOnWorkspace(const int& ws) {
for (auto& n : m_lMasterNodesData) { for (auto& n : m_lMasterNodesData) {
if (n.isMaster && n.workspaceID == ws) if (n.isMaster && n.workspaceID == ws)
@ -236,16 +239,27 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (!PMASTERNODE) if (!PMASTERNODE)
return; return;
eOrientation orientation = PWORKSPACEDATA->orientation;
bool centerMasterWindow = false;
static auto* const ALWAYSCENTER = &g_pConfigManager->getConfigValuePtr("master:always_center_master")->intValue;
if (orientation == ORIENTATION_CENTER) {
if (getNodesOnWorkspace(PWORKSPACE->m_iID) > 2 || (*ALWAYSCENTER==1)) {
centerMasterWindow = true;
} else {
orientation = ORIENTATION_LEFT;
}
}
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID); const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
//compute placement of master window(s) //compute placement of master window(s)
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) { if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 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 (PWORKSPACEDATA->orientation == ORIENTATION_LEFT || PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) { } else if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT) {
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;
@ -253,7 +267,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
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) {
if (PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) { if (orientation == ORIENTATION_RIGHT) {
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition +
Vector2D(PMONITOR->vecSize.x - WIDTH - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x, nextY); Vector2D(PMONITOR->vecSize.x - WIDTH - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x, nextY);
} else { } else {
@ -271,7 +285,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
applyNodeDataToWindow(&n); applyNodeDataToWindow(&n);
} }
} }
} else if (PWORKSPACEDATA->orientation == ORIENTATION_TOP || PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) { } else if (orientation == ORIENTATION_TOP || orientation == ORIENTATION_BOTTOM) {
float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x; float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x;
int nodesLeft = MASTERS; int nodesLeft = MASTERS;
float nextX = 0; float nextX = 0;
@ -279,7 +293,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
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) {
if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) { if (orientation == ORIENTATION_BOTTOM) {
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition +
Vector2D(nextX, PMONITOR->vecSize.y - HEIGHT - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); Vector2D(nextX, PMONITOR->vecSize.y - HEIGHT - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
} else { } else {
@ -294,6 +308,28 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
widthLeft -= WIDTH; widthLeft -= WIDTH;
nextX += WIDTH; nextX += WIDTH;
applyNodeDataToWindow(&n);
}
}
} else if (orientation == ORIENTATION_CENTER) {
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
int nodesLeft = MASTERS;
float nextY = 0;
const float WIDTH = (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster;
for (auto& n : m_lMasterNodesData) {
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
float CENTER_OFFSET = (PMONITOR->vecSize.x - WIDTH) / 2;
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(CENTER_OFFSET, nextY);
float HEIGHT = nodesLeft > 1 ? heightLeft / nodesLeft * n.percSize : heightLeft;
if (HEIGHT > heightLeft * 0.9f && nodesLeft > 1)
HEIGHT = heightLeft * 0.9f;
n.size = Vector2D(WIDTH, HEIGHT);
nodesLeft--;
heightLeft -= HEIGHT;
nextY += HEIGHT;
applyNodeDataToWindow(&n); applyNodeDataToWindow(&n);
} }
} }
@ -301,7 +337,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 (PWORKSPACEDATA->orientation == ORIENTATION_LEFT || PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) { if (orientation == ORIENTATION_LEFT || orientation == ORIENTATION_RIGHT) {
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;
@ -310,7 +346,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 (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) { if (orientation == ORIENTATION_LEFT) {
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 {
@ -327,7 +363,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
applyNodeDataToWindow(&nd); applyNodeDataToWindow(&nd);
} }
} else if (PWORKSPACEDATA->orientation == ORIENTATION_TOP || PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) { } else if (orientation == ORIENTATION_TOP || orientation == ORIENTATION_BOTTOM) {
float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x; float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x;
float nextX = 0; float nextX = 0;
const float HEIGHT = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y - PMASTERNODE->size.y; const float HEIGHT = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y - PMASTERNODE->size.y;
@ -335,7 +371,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
continue; continue;
if (PWORKSPACEDATA->orientation == ORIENTATION_TOP) { if (orientation == ORIENTATION_TOP) {
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition +
Vector2D(nextX, PMASTERNODE->percMaster * (PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y)); Vector2D(nextX, PMASTERNODE->percMaster * (PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y));
} else { } else {
@ -352,6 +388,49 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
applyNodeDataToWindow(&nd); applyNodeDataToWindow(&nd);
} }
} else if (orientation == ORIENTATION_CENTER) {
float heightLeftL = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
float heightLeftR = heightLeftL;
float heightLeft = 0;
float nextYL = 0;
float nextYR = 0;
const float WIDTH = (PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x) / 2.0;
bool on_left = true;
int slavesLeftL = 1 + (slavesLeft - 1) / 2;
int slavesLeftR = slavesLeft - slavesLeftL;
for (auto& nd : m_lMasterNodesData) {
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
continue;
if (on_left) {
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextYL);
heightLeft = heightLeftL;
slavesLeft = slavesLeftL;
} else {
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(WIDTH+PMASTERNODE->size.x, nextYR);
heightLeft = heightLeftR;
slavesLeft = slavesLeftR;
}
float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft;
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
HEIGHT = heightLeft * 0.9f;
nd.size = Vector2D(WIDTH, HEIGHT);
if (on_left) {
heightLeftL -= HEIGHT;
nextYL += HEIGHT;
slavesLeftL--;
} else {
heightLeftR -= HEIGHT;
nextYR += HEIGHT;
slavesLeftR--;
}
applyNodeDataToWindow(&nd);
on_left = !on_left;
}
} }
} }
@ -486,6 +565,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* p
case ORIENTATION_RIGHT: delta = -pixResize.x / PMONITOR->vecSize.x; break; case ORIENTATION_RIGHT: delta = -pixResize.x / PMONITOR->vecSize.x; break;
case ORIENTATION_BOTTOM: delta = -pixResize.y / PMONITOR->vecSize.y; break; case ORIENTATION_BOTTOM: delta = -pixResize.y / PMONITOR->vecSize.y; break;
case ORIENTATION_TOP: delta = pixResize.y / PMONITOR->vecSize.y; break; case ORIENTATION_TOP: delta = pixResize.y / PMONITOR->vecSize.y; break;
case ORIENTATION_CENTER: delta = pixResize.x / PMONITOR->vecSize.x; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
@ -965,7 +1045,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
} }
recalculateMonitor(header.pWindow->m_iMonitorID); recalculateMonitor(header.pWindow->m_iMonitorID);
} else if (command == "orientationleft" || command == "orientationright" || command == "orientationtop" || command == "orientationbottom") { } else if (command == "orientationleft" || command == "orientationright" || command == "orientationtop" || command == "orientationbottom" || command == "orientationcenter") {
const auto PWINDOW = header.pWindow; const auto PWINDOW = header.pWindow;
if (!PWINDOW) if (!PWINDOW)
@ -983,6 +1063,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
PWORKSPACEDATA->orientation = ORIENTATION_TOP; PWORKSPACEDATA->orientation = ORIENTATION_TOP;
else if (command == "orientationbottom") else if (command == "orientationbottom")
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM; PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
else if (command == "orientationcenter")
PWORKSPACEDATA->orientation = ORIENTATION_CENTER;
recalculateMonitor(header.pWindow->m_iMonitorID); recalculateMonitor(header.pWindow->m_iMonitorID);
@ -996,7 +1078,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) { if (PWORKSPACEDATA->orientation == ORIENTATION_CENTER) {
PWORKSPACEDATA->orientation = ORIENTATION_LEFT; PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
} else { } else {
PWORKSPACEDATA->orientation = (eOrientation)(PWORKSPACEDATA->orientation + 1); PWORKSPACEDATA->orientation = (eOrientation)(PWORKSPACEDATA->orientation + 1);
@ -1014,7 +1096,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) { if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) {
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM; PWORKSPACEDATA->orientation = ORIENTATION_CENTER;
} else { } else {
PWORKSPACEDATA->orientation = (eOrientation)(PWORKSPACEDATA->orientation - 1); PWORKSPACEDATA->orientation = (eOrientation)(PWORKSPACEDATA->orientation - 1);
} }

View file

@ -14,7 +14,8 @@ enum eOrientation : uint8_t
ORIENTATION_LEFT = 0, ORIENTATION_LEFT = 0,
ORIENTATION_TOP, ORIENTATION_TOP,
ORIENTATION_RIGHT, ORIENTATION_RIGHT,
ORIENTATION_BOTTOM ORIENTATION_BOTTOM,
ORIENTATION_CENTER
}; };
struct SMasterNodeData { struct SMasterNodeData {