mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 05:29:48 +01:00
feat: Add css style gaps (#4723)
This commit is contained in:
parent
13d9854897
commit
ddf022d61c
6 changed files with 132 additions and 30 deletions
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
#include "helpers/VarList.hpp"
|
||||
#include <vector>
|
||||
|
||||
enum eConfigValueDataTypes {
|
||||
CVD_TYPE_INVALID = -1,
|
||||
CVD_TYPE_GRADIENT = 0
|
||||
CVD_TYPE_INVALID = -1,
|
||||
CVD_TYPE_GRADIENT = 0,
|
||||
CVD_TYPE_CSS_VALUE = 1
|
||||
};
|
||||
|
||||
class ICustomConfigValueData {
|
||||
|
@ -50,3 +52,55 @@ class CGradientValueData : public ICustomConfigValueData {
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CCssGapData : public ICustomConfigValueData {
|
||||
public:
|
||||
CCssGapData() : top(0), right(0), bottom(0), left(0){};
|
||||
CCssGapData(int64_t global) : top(global), right(global), bottom(global), left(global){};
|
||||
CCssGapData(int64_t vertical, int64_t horizontal) : top(vertical), right(horizontal), bottom(vertical), left(horizontal){};
|
||||
CCssGapData(int64_t top, int64_t horizontal, int64_t bottom) : top(top), right(horizontal), bottom(bottom), left(horizontal){};
|
||||
CCssGapData(int64_t top, int64_t right, int64_t bottom, int64_t left) : top(top), right(right), bottom(bottom), left(left){};
|
||||
|
||||
/* Css like directions */
|
||||
int64_t top;
|
||||
int64_t right;
|
||||
int64_t bottom;
|
||||
int64_t left;
|
||||
|
||||
void parseGapData(CVarList varlist) {
|
||||
switch (varlist.size()) {
|
||||
case 1: {
|
||||
*this = CCssGapData(std::stoi(varlist[0]));
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]));
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]), std::stoi(varlist[2]));
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]), std::stoi(varlist[2]), std::stoi(varlist[3]));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Debug::log(WARN, "Too many arguments provided for gaps.");
|
||||
*this = CCssGapData(std::stoi(varlist[0]), std::stoi(varlist[1]), std::stoi(varlist[2]), std::stoi(varlist[3]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reset(int64_t global) {
|
||||
top = global;
|
||||
right = global;
|
||||
bottom = global;
|
||||
left = global;
|
||||
}
|
||||
|
||||
virtual eConfigValueDataTypes getDataType() {
|
||||
return CVD_TYPE_CSS_VALUE;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "../managers/KeybindManager.hpp"
|
||||
|
||||
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
#include "config/ConfigDataValues.hpp"
|
||||
#include "helpers/VarList.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
@ -76,6 +78,31 @@ static void configHandleGradientDestroy(void** data) {
|
|||
delete reinterpret_cast<CGradientValueData*>(*data);
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult configHandleGapSet(const char* VALUE, void** data) {
|
||||
std::string V = VALUE;
|
||||
|
||||
if (!*data)
|
||||
*data = new CCssGapData();
|
||||
|
||||
const auto DATA = reinterpret_cast<CCssGapData*>(*data);
|
||||
CVarList varlist(V);
|
||||
Hyprlang::CParseResult result;
|
||||
|
||||
try {
|
||||
DATA->parseGapData(varlist);
|
||||
} catch (...) {
|
||||
std::string parseError = "Error parsing gaps " + V;
|
||||
result.setError(parseError.c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void configHandleGapDestroy(void** data) {
|
||||
if (*data)
|
||||
delete reinterpret_cast<CCssGapData*>(*data);
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleRawExec(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
@ -279,8 +306,8 @@ CConfigManager::CConfigManager() {
|
|||
m_pConfig->addConfigValue("general:border_size", {1L});
|
||||
m_pConfig->addConfigValue("general:no_border_on_floating", {0L});
|
||||
m_pConfig->addConfigValue("general:border_part_of_window", {1L});
|
||||
m_pConfig->addConfigValue("general:gaps_in", {5L});
|
||||
m_pConfig->addConfigValue("general:gaps_out", {20L});
|
||||
m_pConfig->addConfigValue("general:gaps_in", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "5"});
|
||||
m_pConfig->addConfigValue("general:gaps_out", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "20"});
|
||||
m_pConfig->addConfigValue("general:gaps_workspaces", {0L});
|
||||
m_pConfig->addConfigValue("general:cursor_inactive_timeout", {0L});
|
||||
m_pConfig->addConfigValue("general:no_cursor_warps", {0L});
|
||||
|
@ -2116,12 +2143,22 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
|
|||
|
||||
auto assignRule = [&](std::string rule) -> std::optional<std::string> {
|
||||
size_t delim = std::string::npos;
|
||||
if ((delim = rule.find("gapsin:")) != std::string::npos)
|
||||
wsRule.gapsIn = std::stoi(rule.substr(delim + 7));
|
||||
else if ((delim = rule.find("gapsout:")) != std::string::npos)
|
||||
wsRule.gapsOut = std::stoi(rule.substr(delim + 8));
|
||||
else if ((delim = rule.find("bordersize:")) != std::string::npos)
|
||||
wsRule.borderSize = std::stoi(rule.substr(delim + 11));
|
||||
if ((delim = rule.find("gapsin:")) != std::string::npos) {
|
||||
CVarList varlist = CVarList(rule.substr(delim + 7), 0, ' ');
|
||||
wsRule.gapsIn = CCssGapData();
|
||||
try {
|
||||
wsRule.gapsIn->parseGapData(varlist);
|
||||
} catch (...) { return "Error parsing workspace rule gaps: {}", rule.substr(delim + 7); }
|
||||
} else if ((delim = rule.find("gapsout:")) != std::string::npos) {
|
||||
CVarList varlist = CVarList(rule.substr(delim + 8), 0, ' ');
|
||||
wsRule.gapsOut = CCssGapData();
|
||||
try {
|
||||
wsRule.gapsOut->parseGapData(varlist);
|
||||
} catch (...) { return "Error parsing workspace rule gaps: {}", rule.substr(delim + 8); }
|
||||
} else if ((delim = rule.find("bordersize:")) != std::string::npos)
|
||||
try {
|
||||
wsRule.borderSize = std::stoi(rule.substr(delim + 11));
|
||||
} catch (...) { return "Error parsing workspace rule bordersize: {}", rule.substr(delim + 11); }
|
||||
else if ((delim = rule.find("border:")) != std::string::npos)
|
||||
wsRule.border = configStringToInt(rule.substr(delim + 7));
|
||||
else if ((delim = rule.find("shadow:")) != std::string::npos)
|
||||
|
@ -2264,4 +2301,4 @@ std::optional<std::string> CConfigManager::handlePlugin(const std::string& comma
|
|||
m_vDeclaredPlugins.push_back(path);
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ struct SWorkspaceRule {
|
|||
int workspaceId = -1;
|
||||
bool isDefault = false;
|
||||
bool isPersistent = false;
|
||||
std::optional<int64_t> gapsIn;
|
||||
std::optional<int64_t> gapsOut;
|
||||
std::optional<CCssGapData> gapsIn;
|
||||
std::optional<CCssGapData> gapsOut;
|
||||
std::optional<int64_t> borderSize;
|
||||
std::optional<int> border;
|
||||
std::optional<int> rounding;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <sys/utsname.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
@ -250,8 +249,11 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
|
|||
const std::string monitor = r.monitor.empty() ? "" : std::format(",\n \"monitor\": \"{}\"", escapeJSONStrings(r.monitor));
|
||||
const std::string default_ = (bool)(r.isDefault) ? std::format(",\n \"default\": {}", boolToString(r.isDefault)) : "";
|
||||
const std::string persistent = (bool)(r.isPersistent) ? std::format(",\n \"persistent\": {}", boolToString(r.isPersistent)) : "";
|
||||
const std::string gapsIn = (bool)(r.gapsIn) ? std::format(",\n \"gapsIn\": {}", r.gapsIn.value()) : "";
|
||||
const std::string gapsOut = (bool)(r.gapsOut) ? std::format(",\n \"gapsOut\": {}", r.gapsOut.value()) : "";
|
||||
const std::string gapsIn =
|
||||
(bool)(r.gapsIn) ? std::format(",\n \"gapsIn\": {} {} {} {}", r.gapsIn.value().top, r.gapsIn.value().right, r.gapsIn.value().bottom, r.gapsIn.value().left) : "";
|
||||
const std::string gapsOut = (bool)(r.gapsOut) ?
|
||||
std::format(",\n \"gapsOut\": {} {} {} {}", r.gapsOut.value().top, r.gapsOut.value().right, r.gapsOut.value().bottom, r.gapsOut.value().left) :
|
||||
"";
|
||||
const std::string borderSize = (bool)(r.borderSize) ? std::format(",\n \"borderSize\": {}", r.borderSize.value()) : "";
|
||||
const std::string border = (bool)(r.border) ? std::format(",\n \"border\": {}", boolToString(r.border.value())) : "";
|
||||
const std::string rounding = (bool)(r.rounding) ? std::format(",\n \"rounding\": {}", boolToString(r.rounding.value())) : "";
|
||||
|
@ -268,8 +270,12 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
|
|||
const std::string monitor = std::format("\tmonitor: {}\n", r.monitor.empty() ? "<unset>" : escapeJSONStrings(r.monitor));
|
||||
const std::string default_ = std::format("\tdefault: {}\n", (bool)(r.isDefault) ? boolToString(r.isDefault) : "<unset>");
|
||||
const std::string persistent = std::format("\tpersistent: {}\n", (bool)(r.isPersistent) ? boolToString(r.isPersistent) : "<unset>");
|
||||
const std::string gapsIn = std::format("\tgapsIn: {}\n", (bool)(r.gapsIn) ? std::to_string(r.gapsIn.value()) : "<unset>");
|
||||
const std::string gapsOut = std::format("\tgapsOut: {}\n", (bool)(r.gapsOut) ? std::to_string(r.gapsOut.value()) : "<unset>");
|
||||
const std::string gapsIn = (bool)(r.gapsIn) ? std::format("\tgapsIn: {} {} {} {}\n", std::to_string(r.gapsIn.value().top), std::to_string(r.gapsIn.value().right),
|
||||
std::to_string(r.gapsIn.value().bottom), std::to_string(r.gapsIn.value().left)) :
|
||||
std::format("\tgapsIn: <unset>\n");
|
||||
const std::string gapsOut = (bool)(r.gapsOut) ? std::format("\tgapsOut: {} {} {} {}\n", std::to_string(r.gapsOut.value().top), std::to_string(r.gapsOut.value().right),
|
||||
std::to_string(r.gapsOut.value().bottom), std::to_string(r.gapsOut.value().left)) :
|
||||
std::format("\tgapsOut: <unset>\n");
|
||||
const std::string borderSize = std::format("\tborderSize: {}\n", (bool)(r.borderSize) ? std::to_string(r.borderSize.value()) : "<unset>");
|
||||
const std::string border = std::format("\tborder: {}\n", (bool)(r.border) ? boolToString(r.border.value()) : "<unset>");
|
||||
const std::string rounding = std::format("\trounding: {}\n", (bool)(r.rounding) ? boolToString(r.rounding.value()) : "<unset>");
|
||||
|
|
|
@ -134,12 +134,14 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
|||
|
||||
PWINDOW->updateSpecialRenderData();
|
||||
|
||||
static auto* const PGAPSIN = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_in");
|
||||
static auto* const PGAPSOUT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_out");
|
||||
static auto* const PNOGAPSWHENONLY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:no_gaps_when_only");
|
||||
static auto* const PGAPSINDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_in");
|
||||
static auto* const PGAPSOUTDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_out");
|
||||
auto* const PGAPSIN = (CCssGapData*)(*PGAPSINDATA)->getData();
|
||||
auto* const PGAPSOUT = (CCssGapData*)(*PGAPSOUTDATA)->getData();
|
||||
|
||||
auto gapsIn = WORKSPACERULE.gapsIn.value_or(**PGAPSIN);
|
||||
auto gapsOut = WORKSPACERULE.gapsOut.value_or(**PGAPSOUT);
|
||||
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
|
||||
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
|
||||
|
||||
if (!g_pCompositor->windowExists(PWINDOW) || !PWINDOW->m_bIsMapped) {
|
||||
Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW);
|
||||
|
@ -178,9 +180,9 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
|
|||
auto calcPos = PWINDOW->m_vPosition;
|
||||
auto calcSize = PWINDOW->m_vSize;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? gapsOut : gapsIn, DISPLAYTOP ? gapsOut : gapsIn);
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? gapsOut.left : gapsIn.left, DISPLAYTOP ? gapsOut.top : gapsIn.top);
|
||||
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? gapsOut : gapsIn, DISPLAYBOTTOM ? gapsOut : gapsIn);
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? gapsOut.right : gapsIn.right, DISPLAYBOTTOM ? gapsOut.bottom : gapsIn.bottom);
|
||||
|
||||
calcPos = calcPos + OFFSETTOPLEFT;
|
||||
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "MasterLayout.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
#include "config/ConfigDataValues.hpp"
|
||||
#include <ranges>
|
||||
|
||||
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(CWindow* pWindow) {
|
||||
|
@ -633,13 +634,15 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
|||
|
||||
PWINDOW->updateSpecialRenderData();
|
||||
|
||||
static auto* const PGAPSIN = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_in");
|
||||
static auto* const PGAPSOUT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_out");
|
||||
static auto* const PNOGAPSWHENONLY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:no_gaps_when_only");
|
||||
static auto* const PANIMATE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes");
|
||||
static auto* const PGAPSINDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_in");
|
||||
static auto* const PGAPSOUTDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_out");
|
||||
auto* const PGAPSIN = (CCssGapData*)(*PGAPSINDATA)->getData();
|
||||
auto* const PGAPSOUT = (CCssGapData*)(*PGAPSOUTDATA)->getData();
|
||||
|
||||
auto gapsIn = WORKSPACERULE.gapsIn.value_or(**PGAPSIN);
|
||||
auto gapsOut = WORKSPACERULE.gapsOut.value_or(**PGAPSOUT);
|
||||
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
|
||||
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW)) {
|
||||
Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW);
|
||||
|
@ -673,9 +676,9 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
|
|||
auto calcPos = PWINDOW->m_vPosition;
|
||||
auto calcSize = PWINDOW->m_vSize;
|
||||
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? gapsOut : gapsIn, DISPLAYTOP ? gapsOut : gapsIn);
|
||||
const auto OFFSETTOPLEFT = Vector2D(DISPLAYLEFT ? gapsOut.left : gapsIn.left, DISPLAYTOP ? gapsOut.top : gapsIn.top);
|
||||
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? gapsOut : gapsIn, DISPLAYBOTTOM ? gapsOut : gapsIn);
|
||||
const auto OFFSETBOTTOMRIGHT = Vector2D(DISPLAYRIGHT ? gapsOut.right : gapsIn.right, DISPLAYBOTTOM ? gapsOut.bottom : gapsIn.bottom);
|
||||
|
||||
calcPos = calcPos + OFFSETTOPLEFT;
|
||||
calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT;
|
||||
|
|
Loading…
Reference in a new issue