From a2ae37396fd92482534579a5344c0a0594026a33 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 24 Jan 2023 19:05:34 +0000 Subject: [PATCH] add hyprctl setprop --- hyprctl/main.cpp | 84 +++++++------- src/Compositor.cpp | 17 +-- src/Window.cpp | 2 +- src/Window.hpp | 109 +++++++++++++++--- src/debug/HyprCtl.cpp | 69 +++++++++++ src/render/Renderer.cpp | 2 +- .../decorations/CHyprDropShadowDecoration.cpp | 5 +- 7 files changed, 218 insertions(+), 70 deletions(-) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index 299a5007..37534329 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -39,6 +39,8 @@ commands: getoption cursorpos switchxkblayout + seterror + setprop flags: -j -> output in JSON @@ -46,73 +48,73 @@ flags: )#"; void request(std::string arg, int minArgs = 0) { - const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0); + const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0); - const auto ARGS = std::count(arg.begin(), arg.end(), ' '); + const auto ARGS = std::count(arg.begin(), arg.end(), ' '); - if (ARGS < minArgs) { - std::cout << "Not enough arguments, expected at least " << minArgs; - return; + if (ARGS < minArgs) { + std::cout << "Not enough arguments, expected at least " << minArgs; + return; } - if (SERVERSOCKET < 0) { - std::cout << "Couldn't open a socket (1)"; - return; + if (SERVERSOCKET < 0) { + std::cout << "Couldn't open a socket (1)"; + return; } - // get the instance signature - auto instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE"); + // get the instance signature + auto instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE"); - if (!instanceSig) { - std::cout << "HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)"; - return; + if (!instanceSig) { + std::cout << "HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)"; + return; } - std::string instanceSigStr = std::string(instanceSig); + std::string instanceSigStr = std::string(instanceSig); - sockaddr_un serverAddress = {0}; - serverAddress.sun_family = AF_UNIX; + sockaddr_un serverAddress = {0}; + serverAddress.sun_family = AF_UNIX; - std::string socketPath = "/tmp/hypr/" + instanceSigStr + "/.socket.sock"; + std::string socketPath = "/tmp/hypr/" + instanceSigStr + "/.socket.sock"; - strcpy(serverAddress.sun_path, socketPath.c_str()); + strcpy(serverAddress.sun_path, socketPath.c_str()); - if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) { - std::cout << "Couldn't connect to " << socketPath << ". (3)"; - return; + if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) { + std::cout << "Couldn't connect to " << socketPath << ". (3)"; + return; } - auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length()); + auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length()); - if (sizeWritten < 0) { - std::cout << "Couldn't write (4)"; - return; + if (sizeWritten < 0) { + std::cout << "Couldn't write (4)"; + return; } - std::string reply = ""; - char buffer[8192] = {0}; + std::string reply = ""; + char buffer[8192] = {0}; - sizeWritten = read(SERVERSOCKET, buffer, 8192); + sizeWritten = read(SERVERSOCKET, buffer, 8192); - if (sizeWritten < 0) { - std::cout << "Couldn't read (5)"; - return; + if (sizeWritten < 0) { + std::cout << "Couldn't read (5)"; + return; } - reply += std::string(buffer, sizeWritten); + reply += std::string(buffer, sizeWritten); - while (sizeWritten == 8192) { - sizeWritten = read(SERVERSOCKET, buffer, 8192); - if (sizeWritten < 0) { - std::cout << "Couldn't read (5)"; - return; + while (sizeWritten == 8192) { + sizeWritten = read(SERVERSOCKET, buffer, 8192); + if (sizeWritten < 0) { + std::cout << "Couldn't read (5)"; + return; } - reply += std::string(buffer, sizeWritten); + reply += std::string(buffer, sizeWritten); } - close(SERVERSOCKET); + close(SERVERSOCKET); - std::cout << reply; + std::cout << reply; } void requestHyprpaper(std::string arg) { @@ -343,6 +345,8 @@ int main(int argc, char** argv) { request(fullRequest, 2); else if (fullRequest.contains("/seterror")) request(fullRequest, 1); + else if (fullRequest.contains("/setprop")) + request(fullRequest, 3); else if (fullRequest.contains("/output")) exitStatus = outputRequest(argc, argv); else if (fullRequest.contains("/setcursor")) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index d9f45309..c1cb9bc6 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1559,9 +1559,12 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) { if (RENDERDATA.isBorderGradient) setBorderColor(*RENDERDATA.borderGradient); else - setBorderColor(pWindow == m_pLastWindow ? - (pWindow->m_sSpecialRenderData.activeBorderColor >= 0 ? CGradientValueData(CColor(pWindow->m_sSpecialRenderData.activeBorderColor)) : *ACTIVECOL) : - (pWindow->m_sSpecialRenderData.inactiveBorderColor >= 0 ? CGradientValueData(CColor(pWindow->m_sSpecialRenderData.inactiveBorderColor)) : *INACTIVECOL)); + setBorderColor(pWindow == m_pLastWindow ? (pWindow->m_sSpecialRenderData.activeBorderColor.toUnderlying() >= 0 ? + CGradientValueData(CColor(pWindow->m_sSpecialRenderData.activeBorderColor.toUnderlying())) : + *ACTIVECOL) : + (pWindow->m_sSpecialRenderData.inactiveBorderColor.toUnderlying() >= 0 ? + CGradientValueData(CColor(pWindow->m_sSpecialRenderData.inactiveBorderColor.toUnderlying())) : + *INACTIVECOL)); // opacity const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); @@ -1570,11 +1573,11 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) { } else { if (pWindow == m_pLastWindow) pWindow->m_fActiveInactiveAlpha = - pWindow->m_sSpecialRenderData.alphaOverride ? pWindow->m_sSpecialRenderData.alpha : pWindow->m_sSpecialRenderData.alpha * *PACTIVEALPHA; + pWindow->m_sSpecialRenderData.alphaOverride.toUnderlying() ? pWindow->m_sSpecialRenderData.alpha.toUnderlying() : pWindow->m_sSpecialRenderData.alpha.toUnderlying() * *PACTIVEALPHA; else - pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? - (pWindow->m_sSpecialRenderData.alphaInactiveOverride ? pWindow->m_sSpecialRenderData.alphaInactive : - pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA) : + pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() != -1 ? + (pWindow->m_sSpecialRenderData.alphaInactiveOverride.toUnderlying() ? pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() : + pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() * *PINACTIVEALPHA) : *PINACTIVEALPHA; } diff --git a/src/Window.cpp b/src/Window.cpp index e64835be..c2f75868 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -379,7 +379,7 @@ void CWindow::updateDynamicRules() { if (!m_sAdditionalConfigData.forceOpaqueOverriden) m_sAdditionalConfigData.forceOpaque = false; m_sAdditionalConfigData.forceNoAnims = false; - m_sAdditionalConfigData.animationStyle = ""; + m_sAdditionalConfigData.animationStyle = std::string(""); m_sAdditionalConfigData.rounding = -1; m_sAdditionalConfigData.dimAround = false; diff --git a/src/Window.hpp b/src/Window.hpp index d729df2a..64cde495 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -15,14 +15,85 @@ enum eIdleInhibitMode { IDLEINHIBIT_FOCUS }; -struct SWindowSpecialRenderData { - bool alphaOverride = false; - float alpha = 1.f; - bool alphaInactiveOverride = false; - float alphaInactive = -1.f; // -1 means unset +template +class CWindowOverridableVar { + public: + CWindowOverridableVar(T val) { + value = val; + } - int64_t activeBorderColor = -1; // -1 means unset - int64_t inactiveBorderColor = -1; // -1 means unset + cCWindowOverridableVar operator=(CWindowOverridableVar other) { + if (locked) + return *this; + + locked = other.locked; + value = other.value; + + return *this; + } + + T operator=(T& other) { + if (locked) + return value; + value = other; + return other; + } + + void forceSetIgnoreLocked(T val, bool lock = false) { + value = val; + locked = lock; + } + + T operator*(T& other) { + return value * other; + } + + T operator+(T& other) { + return value + other; + } + + bool operator==(T& other) { + return other == value; + } + + bool operator>=(T& other) { + return value >= other; + } + + bool operator<=(T& other) { + return value <= other; + } + + bool operator>(T& other) { + return value > other; + } + + bool operator<(T& other) { + return value < other; + } + + explicit operator bool() { + return static_cast(value); + } + + T toUnderlying() { + return value; + } + + bool locked = false; + + private: + T value; +}; + +struct SWindowSpecialRenderData { + CWindowOverridableVar alphaOverride = false; + CWindowOverridableVar alpha = 1.f; + CWindowOverridableVar alphaInactiveOverride = false; + CWindowOverridableVar alphaInactive = -1.f; // -1 means unset + + CWindowOverridableVar activeBorderColor = -1; // -1 means unset + CWindowOverridableVar inactiveBorderColor = -1; // -1 means unset // set by the layout bool rounding = true; @@ -31,18 +102,18 @@ struct SWindowSpecialRenderData { }; struct SWindowAdditionalConfigData { - std::string animationStyle = ""; - int rounding = -1; // -1 means no - bool forceNoBlur = false; - bool forceOpaque = false; - bool forceOpaqueOverriden = false; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher. - bool forceAllowsInput = false; - bool forceNoAnims = false; - bool forceNoBorder = false; - bool forceNoShadow = false; - bool windowDanceCompat = false; - bool noMaxSize = false; - bool dimAround = false; + std::string animationStyle = std::string(""); + CWindowOverridableVar rounding = -1; // -1 means no + CWindowOverridableVar forceNoBlur = false; + CWindowOverridableVar forceOpaque = false; + CWindowOverridableVar forceOpaqueOverriden = false; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher. + CWindowOverridableVar forceAllowsInput = false; + CWindowOverridableVar forceNoAnims = false; + CWindowOverridableVar forceNoBorder = false; + CWindowOverridableVar forceNoShadow = false; + CWindowOverridableVar windowDanceCompat = false; + CWindowOverridableVar noMaxSize = false; + CWindowOverridableVar dimAround = false; }; struct SWindowRule { diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index e2c265bf..934bd3de 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -836,6 +836,73 @@ std::string dispatchSeterror(std::string request) { return "ok"; } +std::string dispatchSetProp(std::string request) { + CVarList vars(request, 0, ' '); + + if (vars.size() < 4) + return "not enough args"; + + const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); + + if (!PWINDOW) + return "window not found"; + + const auto PROP = vars[2]; + const auto VAL = vars[3]; + + bool lock = false; + + if (vars.size() > 4) { + if (vars[4].find("lock") == 0) { + lock = true; + } + } + + try { + if (PROP == "animationstyle") { + PWINDOW->m_sAdditionalConfigData.animationStyle = VAL; + } else if (PROP == "rounding") { + PWINDOW->m_sAdditionalConfigData.rounding.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forcenoblur") { + PWINDOW->m_sAdditionalConfigData.forceNoBlur.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forceopaque") { + PWINDOW->m_sAdditionalConfigData.forceOpaque.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forceopaqueoverriden") { + PWINDOW->m_sAdditionalConfigData.forceOpaqueOverriden.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forceallowsinput") { + PWINDOW->m_sAdditionalConfigData.forceAllowsInput.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forcenoanims") { + PWINDOW->m_sAdditionalConfigData.forceNoAnims.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forcenoborder") { + PWINDOW->m_sAdditionalConfigData.forceNoBorder.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "forcenoshadow") { + PWINDOW->m_sAdditionalConfigData.forceNoShadow.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "windowdancecompat") { + PWINDOW->m_sAdditionalConfigData.windowDanceCompat.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "nomaxsize") { + PWINDOW->m_sAdditionalConfigData.noMaxSize.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "dimaround") { + PWINDOW->m_sAdditionalConfigData.dimAround.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "alphaoverride") { + PWINDOW->m_sSpecialRenderData.alphaOverride.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "alpha") { + PWINDOW->m_sSpecialRenderData.alpha.forceSetIgnoreLocked(std::stof(VAL), lock); + } else if (PROP == "alphainactiveoverride") { + PWINDOW->m_sSpecialRenderData.alphaInactiveOverride.forceSetIgnoreLocked(std::stoi(VAL), lock); + } else if (PROP == "alphainactive") { + PWINDOW->m_sSpecialRenderData.alphaInactive.forceSetIgnoreLocked(std::stof(VAL), lock); + } else if (PROP == "activebordercolor") { + PWINDOW->m_sSpecialRenderData.activeBorderColor.forceSetIgnoreLocked(std::stoll(VAL), lock); + } else if (PROP == "inactivebordercolor") { + PWINDOW->m_sSpecialRenderData.inactiveBorderColor.forceSetIgnoreLocked(std::stoll(VAL), lock); + } else { + return "prop not found"; + } + } catch (std::exception& e) { return "error in parsing prop value: " + std::string(e.what()); } + + return "ok"; +} + std::string dispatchGetOption(std::string request, HyprCtl::eHyprCtlOutputFormat format) { std::string curitem = ""; @@ -1004,6 +1071,8 @@ std::string getReply(std::string request) { return cursorPosRequest(format); else if (request == "binds") return bindsRequest(format); + else if (request.find("setprop") == 0) + return dispatchSetProp(request); else if (request.find("seterror") == 0) return dispatchSeterror(request); else if (request.find("switchxkblayout") == 0) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 765864c1..68a90b4b 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -247,7 +247,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl(); renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL); - renderdata.rounding = ignoreAllGeometry ? 0 : pWindow->m_sAdditionalConfigData.rounding; + renderdata.rounding = ignoreAllGeometry ? 0 : pWindow->m_sAdditionalConfigData.rounding.toUnderlying(); renderdata.blur = !ignoreAllGeometry; // if it shouldn't, it will be ignored later renderdata.pWindow = pWindow; diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index a46ae290..f7bb23d2 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -73,8 +73,9 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D if (*PSHADOWS != 1) return; // disabled - const auto ROUNDING = - !m_pWindow->m_sSpecialRenderData.rounding ? 0 : (m_pWindow->m_sAdditionalConfigData.rounding == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding); + const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ? + 0 : + (m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying()); // draw the shadow wlr_box fullBox = {m_vLastWindowPos.x - *PSHADOWSIZE, m_vLastWindowPos.y - *PSHADOWSIZE, m_vLastWindowSize.x + 2.0 * *PSHADOWSIZE, m_vLastWindowSize.y + 2.0 * *PSHADOWSIZE};