mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 21:45:58 +01:00
Implement orientation (placement of master area) for master layout (#1202)
* Implemented choosing placement of master area (#1059) This implement a per workspace 'orientation' that can be set to left, right, top or bottom. Reflecting placement of the master area. Left (default) and right are horizontal layouts, top and bottom produce vertical layouts. Orientation can be switched with: 'hyprctl dispatch layoutmsg orientationleft'
This commit is contained in:
parent
c3f1dc3f52
commit
6381b6474f
4 changed files with 181 additions and 20 deletions
|
@ -109,6 +109,7 @@ void CConfigManager::setDefaultVars() {
|
||||||
configValues["master:new_is_master"].intValue = 1;
|
configValues["master:new_is_master"].intValue = 1;
|
||||||
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["animations:enabled"].intValue = 1;
|
configValues["animations:enabled"].intValue = 1;
|
||||||
configValues["animations:speed"].floatValue = 7.f;
|
configValues["animations:speed"].floatValue = 7.f;
|
||||||
|
|
|
@ -30,6 +30,28 @@ int CHyprMasterLayout::getMastersOnWorkspace(const int& ws) {
|
||||||
return no;
|
return no;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) {
|
||||||
|
for (auto& n : m_lMasterWorkspacesData) {
|
||||||
|
if (n.workspaceID == ws)
|
||||||
|
return &n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create on the fly if it doesn't exist yet
|
||||||
|
const auto PWORKSPACEDATA = &m_lMasterWorkspacesData.emplace_back();
|
||||||
|
PWORKSPACEDATA->workspaceID = ws;
|
||||||
|
const auto orientation = &g_pConfigManager->getConfigValuePtr("master:orientation")->strValue;
|
||||||
|
if (*orientation == "top") {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_TOP;
|
||||||
|
} else if (*orientation == "right") {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_RIGHT;
|
||||||
|
} else if (*orientation == "bottom") {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
|
||||||
|
} else {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
|
||||||
|
}
|
||||||
|
return PWORKSPACEDATA;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CHyprMasterLayout::getLayoutName() {
|
std::string CHyprMasterLayout::getLayoutName() {
|
||||||
return "Master";
|
return "Master";
|
||||||
}
|
}
|
||||||
|
@ -187,6 +209,8 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
||||||
if (!PWORKSPACE)
|
if (!PWORKSPACE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(ws);
|
||||||
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||||
|
|
||||||
const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID);
|
const auto PMASTERNODE = getMasterNodeOnWorkspace(PWORKSPACE->m_iID);
|
||||||
|
@ -196,46 +220,85 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
||||||
|
|
||||||
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
|
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
|
||||||
|
|
||||||
|
//compute placement of master window(s)
|
||||||
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) {
|
if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) {
|
||||||
PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition;
|
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);
|
PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y);
|
||||||
applyNodeDataToWindow(PMASTERNODE);
|
applyNodeDataToWindow(PMASTERNODE);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT || PWORKSPACEDATA->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;
|
||||||
|
const float 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) {
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) {
|
||||||
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMONITOR->vecSize.x - WIDTH, nextY);
|
||||||
|
} else {
|
||||||
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
||||||
|
}
|
||||||
float HEIGHT = nodesLeft > 1 ? heightLeft / nodesLeft * n.percSize : heightLeft;
|
float HEIGHT = nodesLeft > 1 ? heightLeft / nodesLeft * n.percSize : heightLeft;
|
||||||
if (HEIGHT > heightLeft * 0.9f && nodesLeft > 1)
|
if (HEIGHT > heightLeft * 0.9f && nodesLeft > 1)
|
||||||
HEIGHT = heightLeft * 0.9f;
|
HEIGHT = heightLeft * 0.9f;
|
||||||
n.size = Vector2D((PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x) * PMASTERNODE->percMaster, HEIGHT);
|
n.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
nodesLeft--;
|
nodesLeft--;
|
||||||
heightLeft -= HEIGHT;
|
heightLeft -= HEIGHT;
|
||||||
nextY += HEIGHT;
|
nextY += HEIGHT;
|
||||||
|
|
||||||
|
applyNodeDataToWindow(&n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (PWORKSPACEDATA->orientation == ORIENTATION_TOP || PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x;
|
||||||
|
int nodesLeft = MASTERS;
|
||||||
|
float nextX = 0;
|
||||||
|
const float HEIGHT = (PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y) * PMASTERNODE->percMaster;
|
||||||
|
|
||||||
|
for (auto& n : m_lMasterNodesData) {
|
||||||
|
if (n.workspaceID == PWORKSPACE->m_iID && n.isMaster) {
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX,PMONITOR->vecSize.y - HEIGHT - PMONITOR->vecReservedBottomRight.y);
|
||||||
|
} else {
|
||||||
|
n.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX, 0);
|
||||||
|
}
|
||||||
|
float WIDTH = nodesLeft > 1 ? widthLeft / nodesLeft * n.percSize : widthLeft;
|
||||||
|
if (WIDTH > widthLeft * 0.9f && nodesLeft > 1)
|
||||||
|
WIDTH = widthLeft * 0.9f;
|
||||||
|
n.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
nodesLeft--;
|
||||||
|
widthLeft -= WIDTH;
|
||||||
|
nextX += WIDTH;
|
||||||
|
|
||||||
applyNodeDataToWindow(&n);
|
applyNodeDataToWindow(&n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float heightLeft = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y;
|
|
||||||
|
//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) {
|
||||||
|
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;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMASTERNODE->percMaster * PMONITOR->vecSize.x, nextY);
|
if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(PMASTERNODE->percMaster * (PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x), nextY);
|
||||||
|
} else {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(0, nextY);
|
||||||
|
}
|
||||||
float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft;
|
float HEIGHT = slavesLeft > 1 ? heightLeft / slavesLeft * nd.percSize : heightLeft;
|
||||||
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
|
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
|
||||||
HEIGHT = heightLeft * 0.9f;
|
HEIGHT = heightLeft * 0.9f;
|
||||||
nd.size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x - PMASTERNODE->size.x, HEIGHT);
|
nd.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
slavesLeft--;
|
slavesLeft--;
|
||||||
heightLeft -= HEIGHT;
|
heightLeft -= HEIGHT;
|
||||||
|
@ -243,6 +306,33 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
|
||||||
|
|
||||||
applyNodeDataToWindow(&nd);
|
applyNodeDataToWindow(&nd);
|
||||||
}
|
}
|
||||||
|
} else if (PWORKSPACEDATA->orientation == ORIENTATION_TOP || PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
float widthLeft = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PMONITOR->vecReservedTopLeft.x;
|
||||||
|
float nextX = 0;
|
||||||
|
const float HEIGHT = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y - PMASTERNODE->size.y;
|
||||||
|
|
||||||
|
for (auto& nd : m_lMasterNodesData) {
|
||||||
|
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
|
||||||
|
continue;
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_TOP) {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX, PMASTERNODE->percMaster * (PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y));
|
||||||
|
} else {
|
||||||
|
nd.position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition + Vector2D(nextX, 0);
|
||||||
|
}
|
||||||
|
float WIDTH = slavesLeft > 1 ? widthLeft / slavesLeft * nd.percSize : widthLeft;
|
||||||
|
if (WIDTH > widthLeft * 0.9f && slavesLeft > 1)
|
||||||
|
WIDTH = widthLeft * 0.9f;
|
||||||
|
nd.size = Vector2D(WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
slavesLeft--;
|
||||||
|
widthLeft -= WIDTH;
|
||||||
|
nextX += WIDTH;
|
||||||
|
|
||||||
|
applyNodeDataToWindow(&nd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
||||||
|
@ -752,6 +842,55 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||||
PNODE->isMaster = false;
|
PNODE->isMaster = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
|
} else if (message == "orientationleft" || message == "orientationright" || message == "orientationtop" || message == "orientationbottom") {
|
||||||
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
|
if (!PWINDOW)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (message == "orientationleft")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
|
||||||
|
else if (message == "orientationright")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_RIGHT;
|
||||||
|
else if (message == "orientationtop")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_TOP;
|
||||||
|
else if (message == "orientationbottom")
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
|
||||||
|
|
||||||
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
|
|
||||||
|
} else if (message == "orientationnext") {
|
||||||
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
|
if (!PWINDOW)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_LEFT;
|
||||||
|
} else {
|
||||||
|
PWORKSPACEDATA->orientation = (eOrientation) (PWORKSPACEDATA->orientation + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
|
} else if (message == "orientationprev") {
|
||||||
|
const auto PWINDOW = header.pWindow;
|
||||||
|
|
||||||
|
if (!PWINDOW)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) {
|
||||||
|
PWORKSPACEDATA->orientation = ORIENTATION_BOTTOM;
|
||||||
|
} else {
|
||||||
|
PWORKSPACEDATA->orientation = (eOrientation) (PWORKSPACEDATA->orientation - 1);
|
||||||
|
}
|
||||||
|
|
||||||
recalculateMonitor(header.pWindow->m_iMonitorID);
|
recalculateMonitor(header.pWindow->m_iMonitorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IHyprLayout.hpp"
|
#include "IHyprLayout.hpp"
|
||||||
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
enum eFullscreenMode : uint8_t;
|
enum eFullscreenMode : uint8_t;
|
||||||
|
|
||||||
|
//orientation determines which side of the screen the master area resides
|
||||||
|
enum eOrientation : uint8_t {
|
||||||
|
ORIENTATION_LEFT = 0,
|
||||||
|
ORIENTATION_TOP,
|
||||||
|
ORIENTATION_RIGHT,
|
||||||
|
ORIENTATION_BOTTOM
|
||||||
|
};
|
||||||
|
|
||||||
struct SMasterNodeData {
|
struct SMasterNodeData {
|
||||||
bool isMaster = false;
|
bool isMaster = false;
|
||||||
float percMaster = 0.5f;
|
float percMaster = 0.5f;
|
||||||
|
@ -24,6 +33,15 @@ struct SMasterNodeData {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SMasterWorkspaceData {
|
||||||
|
int workspaceID = -1;
|
||||||
|
eOrientation orientation = ORIENTATION_LEFT;
|
||||||
|
|
||||||
|
bool operator==(const SMasterWorkspaceData& rhs) {
|
||||||
|
return workspaceID == rhs.workspaceID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class CHyprMasterLayout : public IHyprLayout {
|
class CHyprMasterLayout : public IHyprLayout {
|
||||||
public:
|
public:
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
virtual void onWindowCreatedTiling(CWindow*);
|
||||||
|
@ -45,6 +63,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::list<SMasterNodeData> m_lMasterNodesData;
|
std::list<SMasterNodeData> m_lMasterNodesData;
|
||||||
|
std::vector<SMasterWorkspaceData> m_lMasterWorkspacesData;
|
||||||
|
|
||||||
bool m_bForceWarps = false;
|
bool m_bForceWarps = false;
|
||||||
|
|
||||||
|
@ -52,9 +71,11 @@ private:
|
||||||
void applyNodeDataToWindow(SMasterNodeData*);
|
void applyNodeDataToWindow(SMasterNodeData*);
|
||||||
SMasterNodeData* getNodeFromWindow(CWindow*);
|
SMasterNodeData* getNodeFromWindow(CWindow*);
|
||||||
SMasterNodeData* getMasterNodeOnWorkspace(const int&);
|
SMasterNodeData* getMasterNodeOnWorkspace(const int&);
|
||||||
|
SMasterWorkspaceData* getMasterWorkspaceData(const int&);
|
||||||
void calculateWorkspace(const int&);
|
void calculateWorkspace(const int&);
|
||||||
CWindow* getNextWindow(CWindow*, bool);
|
CWindow* getNextWindow(CWindow*, bool);
|
||||||
int getMastersOnWorkspace(const int&);
|
int getMastersOnWorkspace(const int&);
|
||||||
|
|
||||||
friend struct SMasterNodeData;
|
friend struct SMasterNodeData;
|
||||||
|
friend struct SMasterWorkspaceData;
|
||||||
};
|
};
|
Loading…
Reference in a new issue