diff --git a/default.nix b/default.nix index e15f9174..fcee67fd 100644 --- a/default.nix +++ b/default.nix @@ -40,7 +40,7 @@ stdenv.mkDerivation rec { installPhase = '' cd ../ mkdir -p $out/share/wayland-sessions - cp ./example/hyprland.desktop $out/share/wayland-sessions/ + cp ./example/hyprland.desktop $out/share/wayland-sessions mkdir -p $out/bin cp ./build/Hyprland $out/bin cp ./hyprctl/hyprctl $out/bin @@ -50,6 +50,8 @@ stdenv.mkDerivation rec { cp ./assets/wall_8K.png $out/share/hyprland ''; + passthru.providedSessions = [ "hyprland" ]; + meta = with lib; { homepage = "https://github.com/vaxerski/Hyprland"; description = diff --git a/flake.lock b/flake.lock index de779e0b..061978e7 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "cachix": { "locked": { - "lastModified": 1651865313, - "narHash": "sha256-fLnmcBaVpJukNIzXZETxtJKLSSTf4LnBCWa/DwyGJBU=", + "lastModified": 1652530570, + "narHash": "sha256-GWRrbUv9l1GSyBkj39s9AqNLX1l3rzVOwvnuG4WYM+E=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ad667404474314806d8071eec4c8ec0db95c17e4", + "rev": "4c560cc7ee57e1fb28e6fd7bdacdf01f948f8a91", "type": "github" }, "original": { @@ -34,11 +34,11 @@ }, "flake-utils": { "locked": { - "lastModified": 1649676176, - "narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=", + "lastModified": 1652557277, + "narHash": "sha256-jSes9DaIVMdmwBB78KkFUVrlDzawmD62vrUg0GS2500=", "owner": "numtide", "repo": "flake-utils", - "rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678", + "rev": "12806d31a381e7cd169a6bac35590e7b36dc5fe5", "type": "github" }, "original": { @@ -53,11 +53,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1652011770, - "narHash": "sha256-ZX+aDa9db1lNbLI44KK0EjTV2X6gyIqpcuN9RUCy9iI=", + "lastModified": 1652616584, + "narHash": "sha256-9Uc/k/t08QsJ8rl1n/cbT8L/JrCoDuE7TmsE+F1OiS8=", "owner": "nix-community", "repo": "lib-aggregate", - "rev": "89056ca8a9c74ea4440dc53bebcd9c74fc0e1f15", + "rev": "81165c2e94b56afcb9486b82dc91d92dfb503a6b", "type": "github" }, "original": { @@ -68,11 +68,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1651927509, - "narHash": "sha256-fGVGUdEsriuAL1vkUh29FlOQmEkPRnSfRGImWYaVjos=", + "lastModified": 1652659998, + "narHash": "sha256-FqNrXC1EE6U2RACwXBlsAvg1lqQGLYpuYb6+W3DL9vA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2fdb6f2e08e7989b03a2a1aa8538d99e3eeea881", + "rev": "1d7db1b9e4cf1ee075a9f52e5c36f7b9f4207502", "type": "github" }, "original": { @@ -84,11 +84,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1651970744, - "narHash": "sha256-3X/96C8I5alTCP0FHEx01/YOIvVmjkYoUPX/1Y4Bdsw=", + "lastModified": 1652576347, + "narHash": "sha256-52Wu7hkcIRcS4UenSSrt01J2sAbbQ6YqxZIDpuEPL/c=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "da23418cffc1763e30dba3383eac541afe3e4e70", + "rev": "bdf553800c9c34ed00641785b02038f67f44d671", "type": "github" }, "original": { @@ -105,11 +105,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1652015544, - "narHash": "sha256-YFjSavZSf6NZFRt2QB5mBccPYd8wrJGKHVH9p75vZtM=", + "lastModified": 1652618007, + "narHash": "sha256-eOH21ElHKORg1kd8Z/qX9naZElAOpCt5fPq26AxMQSw=", "owner": "nix-community", "repo": "nixpkgs-wayland", - "rev": "2d9bc7f3261cc1c2a46d121f94ed483f35d194c2", + "rev": "4588213f577661d37a42c7b6bba04c138c02d78f", "type": "github" }, "original": { @@ -120,11 +120,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1651726670, - "narHash": "sha256-dSGdzB49SEvdOJvrQWfQYkAefewXraHIV08Vz6iDXWQ=", + "lastModified": 1652467128, + "narHash": "sha256-1wuQ7QgPQ3tugYcoVMJ3pUzl4wVdBzKZr9qtJAgA4VI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c777cdf5c564015d5f63b09cc93bef4178b19b01", + "rev": "fb222e008681fce4608e94f2d1dfdf3d03a364c4", "type": "github" }, "original": { @@ -138,16 +138,17 @@ "inputs": { "nixpkgs": "nixpkgs", "nixpkgs-wayland": "nixpkgs-wayland", - "utils": "utils" + "utils": "utils", + "wlroots-git": "wlroots-git" } }, "utils": { "locked": { - "lastModified": 1649676176, - "narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=", + "lastModified": 1652557277, + "narHash": "sha256-jSes9DaIVMdmwBB78KkFUVrlDzawmD62vrUg0GS2500=", "owner": "numtide", "repo": "flake-utils", - "rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678", + "rev": "12806d31a381e7cd169a6bac35590e7b36dc5fe5", "type": "github" }, "original": { @@ -155,6 +156,24 @@ "repo": "flake-utils", "type": "github" } + }, + "wlroots-git": { + "flake": false, + "locked": { + "host": "gitlab.freedesktop.org", + "lastModified": 1652629480, + "narHash": "sha256-4mouFPYB2VwgPi92trvAk8JAGjvkYm+DX72sUzljCXA=", + "owner": "wlroots", + "repo": "wlroots", + "rev": "8fe3aa29da56be16faa73aca947647bd60cd4a94", + "type": "gitlab" + }, + "original": { + "host": "gitlab.freedesktop.org", + "owner": "wlroots", + "repo": "wlroots", + "type": "gitlab" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 002bf09b..2a4d5e0a 100644 --- a/flake.nix +++ b/flake.nix @@ -3,25 +3,41 @@ description = "Hyprland is a dynamic tiling Wayland compositor that doesn't sacrifice on its looks."; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11"; utils.url = "github:numtide/flake-utils"; nixpkgs-wayland.url = "github:nix-community/nixpkgs-wayland"; + wlroots-git = { + url = "gitlab:wlroots/wlroots?host=gitlab.freedesktop.org"; + flake = false; + }; }; - outputs = { self, nixpkgs, utils, nixpkgs-wayland }: - utils.lib.eachDefaultSystem (system: + outputs = { self, nixpkgs, utils, nixpkgs-wayland, wlroots-git }: + { + overlay = final: prev: { + hyprland = prev.callPackage self { + src = self; + wlroots = (nixpkgs-wayland.overlays.default final prev).wlroots.overrideAttrs (prev: rec { + src = wlroots-git; + }); + }; + }; + overlays.default = self.overlay; + } // utils.lib.eachSystem [ "aarch64-linux" "x86_64-linux" ] (system: let pkgs = nixpkgs.legacyPackages.${system}; in rec { packages = { hyprland = pkgs.callPackage self { src = self; - inherit (nixpkgs-wayland.packages.${system}) wlroots; + wlroots = nixpkgs-wayland.packages.${system}.wlroots.overrideAttrs (prev: rec { + src = wlroots-git; + }); }; }; defaultPackage = packages.hyprland; apps.hyprland = utils.lib.mkApp { drv = packages.hyprland; }; defaultApp = apps.hyprland; apps.default = - utils.lib.mkApp { drv = self.packages."${system}".default; }; + utils.lib.mkApp { drv = self.packages.${system}.hyprland; }; }); } diff --git a/src/Compositor.cpp b/src/Compositor.cpp index bf98d079..ce807333 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -662,8 +662,8 @@ void CCompositor::cleanupFadingOut() { g_pHyprOpenGL->m_mLayerFramebuffers[ls].release(); g_pHyprOpenGL->m_mLayerFramebuffers.erase(ls); - m_lSurfacesFadingOut.remove(ls); delete ls; + m_lSurfacesFadingOut.remove(ls); Debug::log(LOG, "Cleanup: destroyed a layersurface"); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 92e7f0cf..80f2b0d4 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -42,6 +42,7 @@ void CConfigManager::setDefaultVars() { configValues["decoration:blur_passes"].intValue = 1; configValues["decoration:active_opacity"].floatValue = 1; configValues["decoration:inactive_opacity"].floatValue = 1; + configValues["decoration:fullscreen_opacity"].floatValue = 1; configValues["dwindle:pseudotile"].intValue = 0; configValues["dwindle:col.group_border"].intValue = 0x66777700; @@ -700,7 +701,7 @@ void CConfigManager::tick() { const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf"); if (!std::filesystem::exists(CONFIGPATH)) { - loadConfigLoadVars(); + Debug::log(ERR, "Config doesn't exist??"); return; } @@ -849,4 +850,4 @@ void CConfigManager::performMonitorReload() { SConfigValue* CConfigManager::getConfigValuePtr(std::string val) { return &configValues[val]; -} \ No newline at end of file +} diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index 86e2ca1a..d5ad2245 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -59,28 +59,11 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) { Debug::log(LOG, "LayerSurface %x destroyed", layersurface->layerSurface); if (!layersurface->fadingOut) { - if (layersurface->layerSurface->mapped) { - Debug::log(LOG, "LayerSurface wasn't unmapped, making a snapshot now!"); - - // make a snapshot and start fade - // layersurfaces aren't required to unmap before destroy - g_pHyprOpenGL->makeLayerSnapshot(layersurface); - layersurface->alpha = 0.f; - - layersurface->fadingOut = true; - } else { - Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); - layersurface->alpha.setValueAndWarp(0.f); - layersurface->fadingOut = true; - } + Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); + layersurface->alpha.setValueAndWarp(0.f); + layersurface->fadingOut = true; } - if (layersurface->layerSurface->mapped) - layersurface->layerSurface->mapped = false; - - if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) - g_pCompositor->m_pLastFocus = nullptr; - layersurface->hyprListener_commitLayerSurface.removeCallback(); layersurface->hyprListener_destroyLayerSurface.removeCallback(); layersurface->hyprListener_mapLayerSurface.removeCallback(); diff --git a/src/helpers/BezierCurve.cpp b/src/helpers/BezierCurve.cpp index 54a18732..bdf2c4b1 100644 --- a/src/helpers/BezierCurve.cpp +++ b/src/helpers/BezierCurve.cpp @@ -60,8 +60,8 @@ float CBezierCurve::getYForPoint(float x) { } // in the name of performance i shall make a hack - const auto LOWERPOINT = &m_aPointsBaked[(int)((float)BAKEDPOINTS * lowerT)]; - const auto UPPERPOINT = &m_aPointsBaked[(int)((float)BAKEDPOINTS * upperT)]; + const auto LOWERPOINT = &m_aPointsBaked[std::clamp((int)((float)BAKEDPOINTS * lowerT), 0, 199)]; + const auto UPPERPOINT = &m_aPointsBaked[std::clamp((int)((float)BAKEDPOINTS * upperT), 0, 199)]; const auto PERCINDELTA = (x - LOWERPOINT->x) / (UPPERPOINT->x - LOWERPOINT->x); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 61ae0c49..ebc8c213 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -1,6 +1,7 @@ #include "MiscFunctions.hpp" #include "../defines.hpp" #include +#include "../Compositor.hpp" void addWLSignal(wl_signal* pSignal, wl_listener* pListener, void* pOwner, std::string ownerString) { ASSERT(pSignal); @@ -120,4 +121,23 @@ bool isNumber(const std::string& str) { bool isDirection(const std::string& arg) { return arg == "l" || arg == "r" || arg == "u" || arg == "d" || arg == "t" || arg == "b"; +} + +int getWorkspaceIDFromString(const std::string& in, std::string& outName) { + int result = INT_MAX; + if (in.find("name:") == 0) { + const auto WORKSPACENAME = in.substr(in.find_first_of(':') + 1); + const auto WORKSPACE = g_pCompositor->getWorkspaceByName(WORKSPACENAME); + if (!WORKSPACE) { + result = g_pCompositor->getNextAvailableNamedWorkspace(); + } else { + result = WORKSPACE->m_iID; + } + outName = WORKSPACENAME; + } else { + result = std::clamp((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1, INT_MAX); + outName = std::to_string(result); + } + + return result; } \ No newline at end of file diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index e7b207de..ff7cc70a 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -9,5 +9,6 @@ void scaleBox(wlr_box*, float); std::string removeBeginEndSpacesTabs(std::string); bool isNumber(const std::string&); bool isDirection(const std::string&); +int getWorkspaceIDFromString(const std::string&, std::string&); float getPlusMinusKeywordResult(std::string in, float relative); \ No newline at end of file diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 9d1cd6df..9fd23830 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -54,6 +54,9 @@ struct SRenderData { // for alpha settings float alpha = 1.f; + + // for decorations (border) + bool decorate = false; }; struct SKeyboard { diff --git a/src/helpers/Workspace.cpp b/src/helpers/Workspace.cpp index e4065907..5341fdf7 100644 --- a/src/helpers/Workspace.cpp +++ b/src/helpers/Workspace.cpp @@ -23,6 +23,9 @@ CWorkspace::CWorkspace(int monitorID) { m_vRenderOffset.m_pWorkspace = this; m_vRenderOffset.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:workspaces_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces")->intValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE); + m_fAlpha.m_pWorkspace = this; + m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:workspaces_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces")->intValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE); + m_fAlpha.setValueAndWarp(255.f); } CWorkspace::~CWorkspace() { @@ -33,4 +36,32 @@ CWorkspace::~CWorkspace() { wlr_ext_workspace_handle_v1_destroy(m_pWlrHandle); m_pWlrHandle = nullptr; } +} + +void CWorkspace::startAnim(bool in, bool left) { + const auto ANIMSTYLE = g_pConfigManager->getString("animations:workspaces_style"); + + if (ANIMSTYLE == "fade") { + m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade. + + if (in) { + m_fAlpha.setValueAndWarp(0.f); + m_fAlpha = 255.f; + } else { + m_fAlpha.setValueAndWarp(255.f); + m_fAlpha = 0.f; + } + } else { + // fallback is slide + const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); + + m_fAlpha.setValueAndWarp(255.f); // fix a bug, if switching from fade -> slide. + + if (in) { + m_vRenderOffset.setValueAndWarp(Vector2D(left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x, 0)); + m_vRenderOffset = Vector2D(0, 0); + } else { + m_vRenderOffset = Vector2D(left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x, 0); + } + } } \ No newline at end of file diff --git a/src/helpers/Workspace.hpp b/src/helpers/Workspace.hpp index 3a9abf72..fbf32f6f 100644 --- a/src/helpers/Workspace.hpp +++ b/src/helpers/Workspace.hpp @@ -21,4 +21,7 @@ public: // for animations CAnimatedVariable m_vRenderOffset; + CAnimatedVariable m_fAlpha; + + void startAnim(bool in, bool left); }; \ No newline at end of file diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index d224e775..5c133336 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -176,7 +176,7 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); // Populate the node with our window's data - PNODE->workspaceID = PMONITOR->activeWorkspace; + PNODE->workspaceID = pWindow->m_iWorkspaceID; PNODE->pWindow = pWindow; PNODE->isNode = false; PNODE->layout = this; @@ -184,7 +184,7 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) { SDwindleNodeData* OPENINGON; const auto MONFROMCURSOR = g_pCompositor->getMonitorFromCursor(); - if (PMONITOR->ID == MONFROMCURSOR->ID) + if (PMONITOR->ID == MONFROMCURSOR->ID && PNODE->workspaceID == PMONITOR->activeWorkspace) OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())); else OPENINGON = getFirstNodeOnWorkspace(PMONITOR->activeWorkspace); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 20302da6..9117203f 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -152,17 +152,17 @@ void CAnimationManager::tick() { const auto ROUNDINGSIZE = g_pConfigManager->getInt("decoration:rounding") + 1; // damage for old box - g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, WLRBOXPREV.width, BORDERSIZE + ROUNDINGSIZE); // top - g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXPREV.height); // left - g_pHyprRenderer->damageBox(WLRBOXPREV.x + WLRBOXPREV.width - ROUNDINGSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXPREV.height); // right - g_pHyprRenderer->damageBox(WLRBOXPREV.x, WLRBOXPREV.y + WLRBOXPREV.height - ROUNDINGSIZE, WLRBOXPREV.width, BORDERSIZE + ROUNDINGSIZE); // bottom + g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top + g_pHyprRenderer->damageBox(WLRBOXPREV.x - BORDERSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXPREV.height + 2 * BORDERSIZE); // left + g_pHyprRenderer->damageBox(WLRBOXPREV.x + WLRBOXPREV.width - ROUNDINGSIZE, WLRBOXPREV.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXPREV.height + 2 * BORDERSIZE); // right + g_pHyprRenderer->damageBox(WLRBOXPREV.x, WLRBOXPREV.y + WLRBOXPREV.height - ROUNDINGSIZE, WLRBOXPREV.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // bottom // damage for new box const wlr_box WLRBOXNEW = {PWINDOW->m_vRealPosition.vec().x, PWINDOW->m_vRealPosition.vec().y, PWINDOW->m_vRealSize.vec().x, PWINDOW->m_vRealSize.vec().y}; - g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, WLRBOXNEW.width, BORDERSIZE + ROUNDINGSIZE); // top - g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height); // left - g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height); // right - g_pHyprRenderer->damageBox(WLRBOXNEW.x, WLRBOXNEW.y + WLRBOXNEW.height - ROUNDINGSIZE, WLRBOXNEW.width, BORDERSIZE + ROUNDINGSIZE); // bottom + g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top + g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // left + g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // right + g_pHyprRenderer->damageBox(WLRBOXNEW.x, WLRBOXNEW.y + WLRBOXNEW.height - ROUNDINGSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // bottom break; } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e58819d8..54258529 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -3,20 +3,21 @@ CKeybindManager::CKeybindManager() { // initialize all dispatchers - m_mDispatchers["exec"] = spawn; - m_mDispatchers["killactive"] = killActive; - m_mDispatchers["togglefloating"] = toggleActiveFloating; - m_mDispatchers["workspace"] = changeworkspace; - m_mDispatchers["fullscreen"] = fullscreenActive; - m_mDispatchers["movetoworkspace"] = moveActiveToWorkspace; - m_mDispatchers["pseudo"] = toggleActivePseudo; - m_mDispatchers["movefocus"] = moveFocusTo; - m_mDispatchers["movewindow"] = moveActiveTo; - m_mDispatchers["togglegroup"] = toggleGroup; - m_mDispatchers["changegroupactive"] = changeGroupActive; - m_mDispatchers["togglesplit"] = toggleSplit; - m_mDispatchers["splitratio"] = alterSplitRatio; - m_mDispatchers["focusmonitor"] = focusMonitor; + m_mDispatchers["exec"] = spawn; + m_mDispatchers["killactive"] = killActive; + m_mDispatchers["togglefloating"] = toggleActiveFloating; + m_mDispatchers["workspace"] = changeworkspace; + m_mDispatchers["fullscreen"] = fullscreenActive; + m_mDispatchers["movetoworkspace"] = moveActiveToWorkspace; + m_mDispatchers["movetoworkspacesilent"] = moveActiveToWorkspaceSilent; + m_mDispatchers["pseudo"] = toggleActivePseudo; + m_mDispatchers["movefocus"] = moveFocusTo; + m_mDispatchers["movewindow"] = moveActiveTo; + m_mDispatchers["togglegroup"] = toggleGroup; + m_mDispatchers["changegroupactive"] = changeGroupActive; + m_mDispatchers["togglesplit"] = toggleSplit; + m_mDispatchers["splitratio"] = alterSplitRatio; + m_mDispatchers["focusmonitor"] = focusMonitor; } void CKeybindManager::addKeybind(SKeybind kb) { @@ -167,19 +168,7 @@ void CKeybindManager::changeworkspace(std::string args) { int workspaceToChangeTo = 0; std::string workspaceName = ""; - if (args.find("name:") == 0) { - const auto WORKSPACENAME = args.substr(args.find_first_of(':') + 1); - const auto WORKSPACE = g_pCompositor->getWorkspaceByName(WORKSPACENAME); - if (!WORKSPACE) { - workspaceToChangeTo = g_pCompositor->getNextAvailableNamedWorkspace(); - } else { - workspaceToChangeTo = WORKSPACE->m_iID; - } - workspaceName = WORKSPACENAME; - } else { - workspaceToChangeTo = std::clamp((int)getPlusMinusKeywordResult(args, g_pCompositor->m_pLastMonitor->activeWorkspace), 1, INT_MAX); - workspaceName = std::to_string(workspaceToChangeTo); - } + workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName); if (workspaceToChangeTo == INT_MAX) { Debug::log(ERR, "Error in changeworkspace, invalid value"); @@ -209,11 +198,10 @@ void CKeybindManager::changeworkspace(std::string args) { const auto ANIMTOLEFT = workspaceToChangeTo > OLDWORKSPACEID; // start anim on old workspace - g_pCompositor->getWorkspaceByID(OLDWORKSPACEID)->m_vRenderOffset = Vector2D(ANIMTOLEFT ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x, 0); + g_pCompositor->getWorkspaceByID(OLDWORKSPACEID)->startAnim(false, ANIMTOLEFT); // start anim on new workspace - g_pCompositor->getWorkspaceByID(workspaceToChangeTo)->m_vRenderOffset.setValueAndWarp(Vector2D(ANIMTOLEFT ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x, 0)); - g_pCompositor->getWorkspaceByID(workspaceToChangeTo)->m_vRenderOffset = Vector2D(0, 0); + g_pCompositor->getWorkspaceByID(workspaceToChangeTo)->startAnim(true, ANIMTOLEFT); } @@ -250,14 +238,13 @@ void CKeybindManager::changeworkspace(std::string args) { const auto ANIMTOLEFT = workspaceToChangeTo > OLDWORKSPACE; // start anim on old workspace - g_pCompositor->getWorkspaceByID(OLDWORKSPACE)->m_vRenderOffset = Vector2D(ANIMTOLEFT ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x, 0); + g_pCompositor->getWorkspaceByID(OLDWORKSPACE)->startAnim(false, ANIMTOLEFT); g_pCompositor->m_lWorkspaces.emplace_back(PMONITOR->ID); const auto PWORKSPACE = &g_pCompositor->m_lWorkspaces.back(); // start anim on new workspace - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(ANIMTOLEFT ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x, 0)); - PWORKSPACE->m_vRenderOffset = Vector2D(0, 0); + PWORKSPACE->startAnim(true, ANIMTOLEFT); // We are required to set the name here immediately wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, workspaceName.c_str()); @@ -351,6 +338,58 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { } } +void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { + // hacky, but works lol + + int workspaceToMoveTo = 0; + std::string workspaceName = ""; + + workspaceToMoveTo = getWorkspaceIDFromString(args, workspaceName); + + if (workspaceToMoveTo == INT_MAX) { + Debug::log(ERR, "Error in moveActiveToWorkspaceSilent, invalid value"); + return; + } + + const auto PWINDOW = g_pCompositor->m_pLastWindow; + + if (!g_pCompositor->windowValidMapped(PWINDOW)) + return; + + const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); + + if (workspaceToMoveTo == PMONITOR->activeWorkspace) + return; + + // may be null until later! + auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo); + + const auto PMONITORNEW = PWORKSPACE ? g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID) : PMONITOR; + + const auto OLDWORKSPACEIDONMONITOR = PMONITORNEW->activeWorkspace; + const auto OLDWORKSPACEIDRETURN = PMONITOR->activeWorkspace; + + const auto POLDWORKSPACEONMON = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDONMONITOR); + const auto POLDWORKSPACEIDRETURN = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDRETURN); + + moveActiveToWorkspace(args); + + PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo); + + changeworkspace(std::to_string(OLDWORKSPACEIDONMONITOR)); + changeworkspace(std::to_string(OLDWORKSPACEIDRETURN)); + + // revert animations + PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0,0)); + PWORKSPACE->m_fAlpha.setValueAndWarp(0.f); + + POLDWORKSPACEIDRETURN->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); + POLDWORKSPACEIDRETURN->m_fAlpha.setValueAndWarp(255.f); + + POLDWORKSPACEONMON->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); + POLDWORKSPACEONMON->m_fAlpha.setValueAndWarp(255.f); +} + void CKeybindManager::moveFocusTo(std::string args) { char arg = args[0]; @@ -510,4 +549,4 @@ void CKeybindManager::focusMonitor(std::string arg) { Debug::log(ERR, "Error in focusMonitor: no such monitor"); } -} \ No newline at end of file +} diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 7f01859a..014f2cdd 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -38,6 +38,7 @@ private: static void changeworkspace(std::string); static void fullscreenActive(std::string); static void moveActiveToWorkspace(std::string); + static void moveActiveToWorkspaceSilent(std::string); static void moveFocusTo(std::string); static void moveActiveTo(std::string); static void toggleGroup(std::string); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 42f28866..d18afb6d 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -30,6 +30,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { m_shQUAD.proj = glGetUniformLocation(prog, "proj"); m_shQUAD.color = glGetUniformLocation(prog, "color"); m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos"); + m_shQUAD.texAttrib = glGetAttribLocation(prog, "texcoord"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBA); m_shRGBA.program = prog; @@ -225,13 +226,10 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h scissor(&box); } -void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { +void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) { RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); - // TODO: respect damage - scissor((wlr_box*)nullptr); - float matrix[9]; wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here @@ -241,23 +239,42 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col) { wlr_matrix_transpose(glMatrix, glMatrix); - if (col.a == 255.f) - glDisable(GL_BLEND); - else - glEnable(GL_BLEND); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(m_shQUAD.program); glUniformMatrix3fv(m_shQUAD.proj, 1, GL_FALSE, glMatrix); glUniform4f(m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f); + const auto TOPLEFT = Vector2D(round, round); + const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round); + const auto FULLSIZE = Vector2D(box->width, box->height); + + // Rounded corners + glUniform2f(glGetUniformLocation(m_shQUAD.program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y); + glUniform2f(glGetUniformLocation(m_shQUAD.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y); + glUniform2f(glGetUniformLocation(m_shQUAD.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y); + glUniform1f(glGetUniformLocation(m_shQUAD.program, "radius"), round); + glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); + glVertexAttribPointer(m_shQUAD.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); glEnableVertexAttribArray(m_shQUAD.posAttrib); + glEnableVertexAttribArray(m_shQUAD.texAttrib); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (pixman_region32_not_empty(m_RenderData.pDamage)) { + PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) { + const auto RECT = RECTSARR[i]; + scissor(&RECT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + } glDisableVertexAttribArray(m_shQUAD.posAttrib); + glDisableVertexAttribArray(m_shQUAD.texAttrib); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round) { @@ -266,15 +283,15 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha renderTexture(CTexture(tex), pBox, alpha, round); } -void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque) { +void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool border) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque); + renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, border); scissor((wlr_box*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque) { +void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); @@ -472,11 +489,11 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p return currentRenderToFB; } -void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round) { +void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round, bool border) { RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); if (g_pConfigManager->getInt("decoration:blur") == 0) { - renderTexture(tex, pBox, a, round); + renderTexture(tex, pBox, a, round, false, border); return; } @@ -530,18 +547,33 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y}; if (pixman_region32_not_empty(&damage)) { // render our great blurred FB - renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, 255.f, &damage); // 255.f because we adjusted blur strength to a + renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, a, &damage); - // render the window, but disable stencil for it - // because stencil has ignoreopaque - glDisable(GL_STENCIL_TEST); + // render the window, but clear stencil + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + + // and write to it + glStencilFunc(GL_ALWAYS, 1, -1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); renderTextureInternalWithDamage(tex, pBox, a, &damage, round); + + // then stop + glStencilFunc(GL_EQUAL, 1, -1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); } - // disable the stencil, finalize everything - glStencilMask(-1); - glStencilFunc(GL_ALWAYS, 1, 0xFF); + // disable the stencil (if no border), finalize everything + if (!border) { + glStencilMask(-1); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + } else { + auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col(); + BORDERCOL.a *= a / 255.f; + renderBorder(pBox, BORDERCOL, g_pConfigManager->getInt("general:border_size"), round); + } + glDisable(GL_STENCIL_TEST); pixman_region32_fini(&damage); scissor((wlr_box*)nullptr); @@ -554,98 +586,23 @@ void pushVert2D(float x, float y, float* arr, int& counter, wlr_box* box) { counter++; } -void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int thick, int radius) { +void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int thick, int round) { RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); - scaleBox(box, m_RenderData.pMonitor->scale); + // this method assumes a set stencil and scaled box + box->x -= thick; + box->y -= thick; + box->width += 2 * thick; + box->height += 2 * thick; - float matrix[9]; - wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here + round += thick; // cuz yeah - float glMatrix[9]; - wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); - wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix); + // only draw on non-stencild. + glStencilFunc(GL_NOTEQUAL, 1, -1); - wlr_matrix_transpose(glMatrix, glMatrix); - - if (col.a == 255.f) - glDisable(GL_BLEND); - else - glEnable(GL_BLEND); - - glUseProgram(m_shQUAD.program); - - glUniformMatrix3fv(m_shQUAD.proj, 1, GL_FALSE, glMatrix); - glUniform4f(m_shQUAD.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f); - - // Sides are ONLY for corners meaning they have to be divisible by 4. - // 32 sides shouldn't be taxing at all on the performance. - const int SIDES = 32; // sides - const int SIDES34 = 24; // 3/4th of the sides - float verts[(SIDES + 8 + 1) * 4]; // 8 for the connections and 1 because last is doubled (begin/end) - int vertNo = 0; - - // start from 0,0 tex coord space - float x = 0, y = 0, w = box->width, h = box->height; - - pushVert2D(x + radius, y + h, verts, vertNo, box); - pushVert2D(x + w - radius, y + h, verts, vertNo, box); - - float x1 = x + w - radius; - float y1 = y + h - radius; - - for (int i = 0; i <= SIDES / 4; i++) { - pushVert2D(x1 + (sin((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), y1 + (cos((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), verts, vertNo, box); - } - - // Right Line - pushVert2D(x + w, y + radius, verts, vertNo, box); - - x1 = x + w - radius; - y1 = y + radius; - - for (int i = SIDES / 4; i <= SIDES / 2; i++) { - pushVert2D(x1 + (sin((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), y1 + (cos((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), verts, vertNo, box); - } - - // Top Line - pushVert2D(x + radius, y, verts, vertNo, box); - - x1 = x + radius; - y1 = y + radius; - - for (int i = SIDES / 2; i <= SIDES34; i++) { - pushVert2D(x1 + (sin((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), y1 + (cos((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), verts, vertNo, box); - } - - // Left Line - pushVert2D(x, y + h - radius, verts, vertNo, box); - - x1 = x + radius; - y1 = y + h - radius; - - for (int i = SIDES34; i <= SIDES; i++) { - pushVert2D(x1 + (sin((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), y1 + (cos((i * (360.f / (float)SIDES) * 3.141526f / 180)) * radius), verts, vertNo, box); - } - - glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts); - - glEnableVertexAttribArray(m_shQUAD.posAttrib); - - glLineWidth(thick); - - // draw with damage - if (pixman_region32_not_empty(m_RenderData.pDamage)) { - PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) { - const auto RECT = RECTSARR[i]; - scissor(&RECT); - - glDrawArrays(GL_LINE_STRIP, 0, 41); - } - } - - glDisableVertexAttribArray(m_shQUAD.posAttrib); + // draw a rounded rect + renderRect(box, col, round); } void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index ca70c449..b3aa5968 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -53,11 +53,10 @@ public: void begin(SMonitor*, pixman_region32_t*, bool fake = false); void end(); - void renderRect(wlr_box*, const CColor&); + void renderRect(wlr_box*, const CColor&, int round = 0); void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0); - void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false); - void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0); - void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0); + void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false); + void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false); void makeWindowSnapshot(CWindow*); void makeLayerSnapshot(SLayerSurface*); @@ -77,6 +76,8 @@ public: GLint m_iCurrentOutputFb = 0; GLint m_iWLROutputFb = 0; + CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window + pixman_region32_t m_rOriginalDamageRegion; // used for storing the pre-expanded region std::unordered_map m_mWindowFramebuffers; @@ -109,9 +110,8 @@ private: // returns the out FB, can be either Mirror or MirrorSwap CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage); - void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false); - void renderTextureWithBlurInternal(const CTexture&, wlr_box*, float a, int round = 0); - + void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false); + void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0); }; inline std::unique_ptr g_pHyprOpenGL; \ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 02f7482c..89aa4f7d 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -20,10 +20,10 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { scaleBox(&windowBox, RDATA->output->scale); if (RDATA->surface && surface == RDATA->surface) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding")); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding"), RDATA->decorate); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding")); - + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, RDATA->dontRound ? 0 : g_pConfigManager->getInt("decoration:rounding"), false, RDATA->decorate); + wlr_surface_send_frame_done(surface, RDATA->when); wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output); @@ -41,7 +41,7 @@ bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); // if not, check if it maybe is active on a different monitor. vvv might be animation in progress - if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_vRenderOffset.isBeingAnimated())) + if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()))) return true; return false; @@ -96,17 +96,16 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* renderdata.w = pWindow->m_vRealSize.vec().x; renderdata.h = pWindow->m_vRealSize.vec().y; renderdata.dontRound = pWindow->m_bIsFullscreen; - renderdata.fadeAlpha = pWindow->m_fAlpha.fl(); - renderdata.alpha = pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity"); + renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f); + renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity"); + renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders; // apply window special data renderdata.alpha *= pWindow->m_sSpecialRenderData.alpha; - wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata); + g_pHyprOpenGL->m_pCurrentWindow = pWindow; - // border - if (decorate && !pWindow->m_bX11DoesntWantBorders) - drawBorderForWindow(pWindow, pMonitor, pWindow->m_fAlpha.fl() * renderdata.alpha, PWORKSPACE->m_vRenderOffset.vec()); + wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata); if (pWindow->m_bIsX11) { if (pWindow->m_uSurface.xwayland->surface) { @@ -117,7 +116,9 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* renderdata.dontRound = false; // restore dontround renderdata.pMonitor = pMonitor; wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata); - } + } + + g_pHyprOpenGL->m_pCurrentWindow = nullptr; } void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, timespec* time) { @@ -437,23 +438,6 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) { Debug::log(LOG, "Monitor %s layers arranged: reserved: %f %f %f %f", PMONITOR->szName.c_str(), PMONITOR->vecReservedTopLeft.x, PMONITOR->vecReservedTopLeft.y, PMONITOR->vecReservedBottomRight.x, PMONITOR->vecReservedBottomRight.y); } -void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor, float alpha, const Vector2D& offset) { - const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); - - if (BORDERSIZE < 1) - return; - - auto BORDERCOL = pWindow->m_cRealBorderColor.col(); - BORDERCOL.a *= (alpha / 255.f); - - Vector2D correctPos = pWindow->m_vRealPosition.vec() - pMonitor->vecPosition; - Vector2D correctSize = pWindow->m_vRealSize.vec(); - - // top - wlr_box border = {correctPos.x - BORDERSIZE / 2.f + offset.x, correctPos.y - BORDERSIZE / 2.f + offset.y, pWindow->m_vRealSize.vec().x + BORDERSIZE, pWindow->m_vRealSize.vec().y + BORDERSIZE}; - g_pHyprOpenGL->renderBorder(&border, BORDERCOL, BORDERSIZE, g_pConfigManager->getInt("decoration:rounding")); -} - void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) { if (!pSurface) return; // wut? diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index f879702b..ba7d54b3 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -34,7 +34,6 @@ public: private: void arrangeLayerArray(SMonitor*, const std::list&, bool, wlr_box*); - void drawBorderForWindow(CWindow*, SMonitor*, float a = 255.f, const Vector2D& offset = Vector2D(0,0)); void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*); void renderWindow(CWindow*, SMonitor*, timespec*, bool); void renderLayer(SLayerSurface*, SMonitor*, timespec*); diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index 49272857..4d94358e 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -7,6 +7,7 @@ struct SQuad { GLint proj; GLint color; GLint posAttrib; + GLint texAttrib; }; class CShader { diff --git a/src/render/Shaders.hpp b/src/render/Shaders.hpp index 3864d801..11d40913 100644 --- a/src/render/Shaders.hpp +++ b/src/render/Shaders.hpp @@ -21,8 +21,53 @@ precision mediump float; varying vec4 v_color; varying vec2 v_texcoord; +uniform vec2 topLeft; +uniform vec2 bottomRight; +uniform vec2 fullSize; +uniform float radius; + void main() { - gl_FragColor = v_color; + if (radius == 0.0) { + gl_FragColor = v_color; + return; + } + + vec2 pixCoord = fullSize * v_texcoord; + + if (pixCoord[0] < topLeft[0]) { + // we're close left + if (pixCoord[1] < topLeft[1]) { + // top + if (distance(topLeft, pixCoord) > radius) { + discard; + return; + } + } else if (pixCoord[1] > bottomRight[1]) { + // bottom + if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) { + discard; + return; + } + } + } + else if (pixCoord[0] > bottomRight[0]) { + // we're close right + if (pixCoord[1] < topLeft[1]) { + // top + if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) { + discard; + return; + } + } else if (pixCoord[1] > bottomRight[1]) { + // bottom + if (distance(bottomRight, pixCoord) > radius) { + discard; + return; + } + } + } + + gl_FragColor = v_color; })#"; inline const std::string TEXVERTSRC = R"#(