From 4b6163aef38d19e3489f563c80828e7174e939e8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 17 Dec 2024 01:57:35 +0000 Subject: [PATCH 0001/1444] windowrules: fixup duplicate rule enum tags fixes #8746 --- src/desktop/WindowRule.cpp | 10 ---------- src/desktop/WindowRule.hpp | 5 ----- 2 files changed, 15 deletions(-) diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp index d721c4bd..4f2d949e 100644 --- a/src/desktop/WindowRule.cpp +++ b/src/desktop/WindowRule.cpp @@ -41,8 +41,6 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool ruleType = RULE_ANIMATION; else if (rule.starts_with("bordercolor")) ruleType = RULE_BORDERCOLOR; - else if (rule.starts_with("bordersize")) - ruleType = RULE_BORDERSIZE; else if (rule.starts_with("center")) ruleType = RULE_CENTER; else if (rule.starts_with("fullscreenstate")) @@ -65,12 +63,6 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool ruleType = RULE_PLUGIN; else if (rule.starts_with("pseudo")) ruleType = RULE_PSEUDO; - else if (rule.starts_with("rounding")) - ruleType = RULE_ROUNDING; - else if (rule.starts_with("scrollmouse")) - ruleType = RULE_SCROLLMOUSE; - else if (rule.starts_with("scrolltouchpad")) - ruleType = RULE_SCROLLTOUCHPAD; else if (rule.starts_with("size")) ruleType = RULE_SIZE; else if (rule.starts_with("suppressevent")) @@ -79,8 +71,6 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool ruleType = RULE_TAG; else if (rule.starts_with("workspace")) ruleType = RULE_WORKSPACE; - else if (rule.starts_with("xray")) - ruleType = RULE_XRAY; else if (rule.starts_with("prop")) ruleType = RULE_PROP; else { diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp index d1034cf6..6faf8b5a 100644 --- a/src/desktop/WindowRule.hpp +++ b/src/desktop/WindowRule.hpp @@ -19,7 +19,6 @@ class CWindowRule { RULE_RENDERUNFOCUSED, RULE_ANIMATION, RULE_BORDERCOLOR, - RULE_BORDERSIZE, RULE_CENTER, RULE_FULLSCREENSTATE, RULE_GROUP, @@ -31,14 +30,10 @@ class CWindowRule { RULE_OPACITY, RULE_PLUGIN, RULE_PSEUDO, - RULE_ROUNDING, - RULE_SCROLLMOUSE, - RULE_SCROLLTOUCHPAD, RULE_SIZE, RULE_SUPPRESSEVENT, RULE_TAG, RULE_WORKSPACE, - RULE_XRAY, RULE_PROP, }; From 7ae79205729c9648474c32bbd69f6e7e893855d3 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 16 Dec 2024 20:15:39 -0600 Subject: [PATCH 0002/1444] flake.lock: update (#8742) --- flake.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index 901f7b15..2607d1fd 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1734364797, - "narHash": "sha256-2h1c+P0v3l0Z/ypUSsAPhU/yiSRgFwjVFODWp0S3d/w=", + "lastModified": 1734384172, + "narHash": "sha256-+/d5J4xLVt3N0u01jEFVkoL6FVnXDwWDr5WFbN+jtBk=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "8e77618b403a82fde2105a8e3cd7cabe7ef00952", + "rev": "33753783549b59d7516e9afa29a4d6ddd8102606", "type": "github" }, "original": { @@ -203,11 +203,11 @@ ] }, "locked": { - "lastModified": 1733502241, - "narHash": "sha256-KAUNC4Dgq8WQjYov5auBw/usaHixhacvb7cRDd0AG/k=", + "lastModified": 1734384247, + "narHash": "sha256-bl3YyJb2CgaeVKYq/l8j27vKdbkTpDNFDsnCl0dnNlY=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "104117aed6dd68561be38b50f218190aa47f2cd8", + "rev": "e6cf45cd1845368702e03b8912f4cc44ebba3322", "type": "github" }, "original": { @@ -226,11 +226,11 @@ ] }, "locked": { - "lastModified": 1726874836, - "narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=", + "lastModified": 1734384417, + "narHash": "sha256-noYeXcNQ15g1/gIJIYT2zdO66wzY5Z06PYz6BfKUZA8=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "500c81a9e1a76760371049a8d99e008ea77aa59e", + "rev": "90e87f7fcfcce4862826d60332cbc5e2f87e1f88", "type": "github" }, "original": { @@ -281,11 +281,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1734279981, - "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", + "lastModified": 1734379367, + "narHash": "sha256-Keu8z5VgT5gnCF4pmB+g7XZFftHpfl4qOn7nqBcywdE=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", + "rev": "0bb4be58f21ff38fc3cdbd6c778eb67db97f0b99", "type": "github" }, "original": { @@ -347,11 +347,11 @@ ] }, "locked": { - "lastModified": 1734124279, - "narHash": "sha256-YNpFfiQjYt2o6LGcMN9NkjVvprC8ELrIpLHlbZbclRM=", + "lastModified": 1734384144, + "narHash": "sha256-S/Nyg63KYBO4uzpXjS87gewb5naf3l90PTp6k0VCXYs=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "0c6861f819f6d31f6195c9864709b2556f00b5cf", + "rev": "7116c9fffff106e11de4c5d0c34c9d252a46d70d", "type": "github" }, "original": { From c7d97199103fd1ca43c2a9810c085df5500169ac Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Tue, 17 Dec 2024 10:19:55 +0200 Subject: [PATCH 0003/1444] flake.lock: update --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 2607d1fd..66500c0c 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1734384172, - "narHash": "sha256-+/d5J4xLVt3N0u01jEFVkoL6FVnXDwWDr5WFbN+jtBk=", + "lastModified": 1734400729, + "narHash": "sha256-Bf+oya0BuleVXYGIWsb0eWnrK6s0aiesOsI7Mpj1pMU=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "33753783549b59d7516e9afa29a4d6ddd8102606", + "rev": "a132fa41be7ebe797ad758e84d9df068151a723b", "type": "github" }, "original": { @@ -347,11 +347,11 @@ ] }, "locked": { - "lastModified": 1734384144, - "narHash": "sha256-S/Nyg63KYBO4uzpXjS87gewb5naf3l90PTp6k0VCXYs=", + "lastModified": 1734422917, + "narHash": "sha256-0y7DRaXslhfqVKV8a/talYTYAe2NHOQhMZG7KMNRCtc=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "7116c9fffff106e11de4c5d0c34c9d252a46d70d", + "rev": "3e884d941ca819c1f2e50df8bdae0debded1ed87", "type": "github" }, "original": { From bd7092a9feb39275a9eb1426046a46671e0fe580 Mon Sep 17 00:00:00 2001 From: normaltaro <30935678+normaltaro@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:42:38 +0530 Subject: [PATCH 0004/1444] binds: cycle within group on single monitor if no window found in the argument direction. (#8714) --- src/managers/KeybindManager.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index f23f5dc7..fec608f1 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1395,17 +1395,16 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) { g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); // Prioritize focus change within groups if the window is a part of it. - if (*PGROUPCYCLE) { - if (!PLASTWINDOW->m_sGroupData.pNextWindow.expired()) { - if (arg == 'l' && PLASTWINDOW != PLASTWINDOW->getGroupHead()) { - PLASTWINDOW->setGroupCurrent(PLASTWINDOW->getGroupPrevious()); - return {}; - } + if (*PGROUPCYCLE && PLASTWINDOW->m_sGroupData.pNextWindow) { + auto isTheOnlyGroupOnWs = !PWINDOWTOCHANGETO && g_pCompositor->m_vMonitors.size() == 1; + if (arg == 'l' && (PLASTWINDOW != PLASTWINDOW->getGroupHead() || isTheOnlyGroupOnWs)) { + PLASTWINDOW->setGroupCurrent(PLASTWINDOW->getGroupPrevious()); + return {}; + } - else if (arg == 'r' && PLASTWINDOW != PLASTWINDOW->getGroupTail()) { - PLASTWINDOW->setGroupCurrent(PLASTWINDOW->m_sGroupData.pNextWindow.lock()); - return {}; - } + else if (arg == 'r' && (PLASTWINDOW != PLASTWINDOW->getGroupTail() || isTheOnlyGroupOnWs)) { + PLASTWINDOW->setGroupCurrent(PLASTWINDOW->m_sGroupData.pNextWindow.lock()); + return {}; } } From e2c78c00e50a0835c3830c8a0cd82049dc5700b8 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:31:27 -0600 Subject: [PATCH 0005/1444] internal: remove dead code (#8748) --- src/Compositor.cpp | 16 ---------------- src/Compositor.hpp | 2 -- src/config/ConfigManager.cpp | 20 -------------------- src/config/ConfigManager.hpp | 3 --- src/desktop/Window.cpp | 9 --------- src/desktop/Window.hpp | 1 - src/events/Windows.cpp | 9 --------- src/helpers/AnimatedVariable.cpp | 5 ----- src/helpers/AnimatedVariable.hpp | 2 -- src/helpers/MiscFunctions.cpp | 20 -------------------- src/helpers/MiscFunctions.hpp | 2 -- src/layout/DwindleLayout.cpp | 17 ----------------- src/layout/DwindleLayout.hpp | 1 - src/managers/input/InputMethodRelay.cpp | 4 ---- src/managers/input/InputMethodRelay.hpp | 1 - src/protocols/core/Shm.hpp | 1 - src/protocols/types/DMABuffer.cpp | 6 +----- src/protocols/types/DMABuffer.hpp | 3 +-- src/render/OpenGL.cpp | 7 ------- 19 files changed, 2 insertions(+), 127 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index ecf251f3..dea8cddf 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2234,11 +2234,6 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) { } } -void CCompositor::changeWindowFullscreenModeInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON) { - setWindowFullscreenInternal( - PWINDOW, (eFullscreenMode)(ON ? (uint8_t)PWINDOW->m_sFullscreenState.internal | (uint8_t)MODE : ((uint8_t)PWINDOW->m_sFullscreenState.internal & (uint8_t)~MODE))); -} - void CCompositor::changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON) { setWindowFullscreenClient(PWINDOW, (eFullscreenMode)(ON ? (uint8_t)PWINDOW->m_sFullscreenState.client | (uint8_t)MODE : ((uint8_t)PWINDOW->m_sFullscreenState.client & (uint8_t)~MODE))); @@ -2904,17 +2899,6 @@ void CCompositor::updateSuspendedStates() { } } -PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) { - for (auto const& w : m_vWindows) { - if (w.get() != pWindow) - continue; - - return w; - } - - return {}; -} - static void checkDefaultCursorWarp(PHLMONITOR monitor) { static auto PCURSORMONITOR = CConfigValue("cursor:default_monitor"); static bool cursorDefaultDone = false; diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 96c2c5fe..e1862829 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -140,7 +140,6 @@ class CCompositor { void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE); void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE); void setWindowFullscreenState(const PHLWINDOW PWINDOW, const SFullscreenState state); - void changeWindowFullscreenModeInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON); void changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON); void updateFullscreenFadeOnWorkspace(PHLWORKSPACE); PHLWINDOW getX11Parent(PHLWINDOW); @@ -167,7 +166,6 @@ class CCompositor { void setPreferredScaleForSurface(SP pSurface, double scale); void setPreferredTransformForSurface(SP pSurface, wl_output_transform transform); void updateSuspendedStates(); - PHLWINDOW windowForCPointer(CWindow*); void onNewMonitor(SP output); std::string explicitConfigPath; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f77a6b42..f4ba7379 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1483,22 +1483,6 @@ void CConfigManager::dispatchExecShutdown() { handleExecShutdown("", "hyprctl dispatch exit"); } -void CConfigManager::appendMonitorRule(const SMonitorRule& r) { - m_vMonitorRules.emplace_back(r); -} - -bool CConfigManager::replaceMonitorRule(const SMonitorRule& newrule) { - // Looks for an existing monitor rule (compared by name). - // If the rule exists, it is replaced with the input rule. - for (auto& r : m_vMonitorRules) { - if (r.name == newrule.name) { - r = newrule; - return true; - } - } - return false; -} - void CConfigManager::performMonitorReload() { bool overAgain = false; @@ -1718,10 +1702,6 @@ std::unordered_map CConfigManager::getAni return animationConfig; } -void onPluginLoadUnload(const std::string& name, bool load) { - // -} - void CConfigManager::addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value) { if (!name.starts_with("plugin:")) return; diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 7ce7d495..b1e7e7fd 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -163,7 +163,6 @@ class CConfigManager { void* const* getConfigValuePtr(const std::string&); Hyprlang::CConfigValue* getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat = ""); - void onPluginLoadUnload(const std::string& name, bool load); static std::string getMainConfigPath(); std::string getConfigString(); @@ -193,8 +192,6 @@ class CConfigManager { void dispatchExecShutdown(); void performMonitorReload(); - void appendMonitorRule(const SMonitorRule&); - bool replaceMonitorRule(const SMonitorRule&); void ensureMonitorStatus(); void ensureVRR(PHLMONITOR pMonitor = nullptr); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index cfced8a3..c0752224 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -473,15 +473,6 @@ PHLWINDOW CWindow::x11TransientFor() { return nullptr; } -void CWindow::removeDecorationByType(eDecorationType type) { - for (auto const& wd : m_dWindowDecorations) { - if (wd->getDecorationType() == type) - m_vDecosToRemove.push_back(wd.get()); - } - - updateWindowDecos(); -} - void unregisterVar(void* ptr) { ((CBaseAnimatedVariable*)ptr)->unregister(); } diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index c72f010e..7b2cfbdf 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -399,7 +399,6 @@ class CWindow { bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {}); pid_t getPID(); IHyprWindowDecoration* getDecorationByType(eDecorationType); - void removeDecorationByType(eDecorationType); void updateToplevel(); void updateSurfaceScaleTransformDetails(bool force = false); void moveToWorkspace(PHLWORKSPACE); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 85eae934..edc29ed3 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -872,15 +872,6 @@ void Events::listener_destroyWindow(void* owner, void* data) { PWINDOW->listeners.commit.reset(); } -void Events::listener_setTitleWindow(void* owner, void* data) { - PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock(); - - if (!validMapped(PWINDOW)) - return; - - PWINDOW->onUpdateMeta(); -} - void Events::listener_activateX11(void* owner, void* data) { PHLWINDOW PWINDOW = ((CWindow*)owner)->m_pSelf.lock(); diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp index 6deeff39..ab5643a6 100644 --- a/src/helpers/AnimatedVariable.cpp +++ b/src/helpers/AnimatedVariable.cpp @@ -55,11 +55,6 @@ void CBaseAnimatedVariable::registerVar() { m_bIsRegistered = true; } -int CBaseAnimatedVariable::getDurationLeftMs() { - return std::max( - (int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast(std::chrono::steady_clock::now() - animationBegin).count(), 0); -} - float CBaseAnimatedVariable::getPercent() { const auto DURATIONPASSED = std::chrono::duration_cast(std::chrono::steady_clock::now() - animationBegin).count(); return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f); diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index a2a06675..a1da00da 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -95,8 +95,6 @@ class CBaseAnimatedVariable { return m_pConfig; } - int getDurationLeftMs(); - /* returns the spent (completion) % */ float getPercent(); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 9b92c63d..6d365161 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -161,26 +161,6 @@ std::string absolutePath(const std::string& rawpath, const std::string& currentP return value; } -void addWLSignal(wl_signal* pSignal, wl_listener* pListener, void* pOwner, const std::string& ownerString) { - ASSERT(pSignal); - ASSERT(pListener); - - wl_signal_add(pSignal, pListener); - - Debug::log(LOG, "Registered signal for owner {:x}: {:x} -> {:x} (owner: {})", (uintptr_t)pOwner, (uintptr_t)pSignal, (uintptr_t)pListener, ownerString); -} - -void removeWLSignal(wl_listener* pListener) { - wl_list_remove(&pListener->link); - wl_list_init(&pListener->link); - - Debug::log(LOG, "Removed listener {:x}", (uintptr_t)pListener); -} - -void handleNoop(struct wl_listener* listener, void* data) { - // Do nothing -} - std::string escapeJSONStrings(const std::string& str) { std::ostringstream oss; for (auto const& c : str) { diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index 018efbed..b179b3d6 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -21,8 +21,6 @@ struct SWorkspaceIDName { }; std::string absolutePath(const std::string&, const std::string&); -void addWLSignal(wl_signal*, wl_listener*, void* pOwner, const std::string& ownerString); -void removeWLSignal(wl_listener*); std::string escapeJSONStrings(const std::string& str); bool isDirection(const std::string&); bool isDirection(const char&); diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index ec874223..dc6e37dd 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -38,14 +38,6 @@ void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverrid } } -void SDwindleNodeData::getAllChildrenRecursive(std::vector* pVec) { - if (children[0]) { - children[0]->getAllChildrenRecursive(pVec); - children[1]->getAllChildrenRecursive(pVec); - } else - pVec->push_back(this); -} - int CHyprDwindleLayout::getNodesOnWorkspace(const WORKSPACEID& id) { int no = 0; for (auto const& n : m_lDwindleNodesData) { @@ -804,15 +796,6 @@ void CHyprDwindleLayout::recalculateWindow(PHLWINDOW pWindow) { PNODE->recalcSizePosRecursive(); } -static void addToVectorRecursive(std::vector* pVec, std::vector* pParents, SDwindleNodeData* node) { - if (node->isNode) { - pParents->emplace_back(node); - addToVectorRecursive(pVec, pParents, node->children[0]); - addToVectorRecursive(pVec, pParents, node->children[1]); - } else - pVec->emplace_back(node); -} - SWindowRenderLayoutHints CHyprDwindleLayout::requestRenderHints(PHLWINDOW pWindow) { // window should be valid, insallah SWindowRenderLayoutHints hints; diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp index dffc34f7..be47e724 100644 --- a/src/layout/DwindleLayout.hpp +++ b/src/layout/DwindleLayout.hpp @@ -39,7 +39,6 @@ struct SDwindleNodeData { } void recalcSizePosRecursive(bool force = false, bool horizontalOverride = false, bool verticalOverride = false); - void getAllChildrenRecursive(std::vector*); CHyprDwindleLayout* layout = nullptr; }; diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 5ef7f331..88439924 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -68,10 +68,6 @@ void CInputMethodRelay::onNewIME(SP pIME) { } } -void CInputMethodRelay::setIMEPopupFocus(CInputPopup* pPopup, SP pSurface) { - pPopup->onCommit(); -} - void CInputMethodRelay::removePopup(CInputPopup* pPopup) { std::erase_if(m_vIMEPopups, [pPopup](const auto& other) { return other.get() == pPopup; }); } diff --git a/src/managers/input/InputMethodRelay.hpp b/src/managers/input/InputMethodRelay.hpp index 3d706563..998e1fc6 100644 --- a/src/managers/input/InputMethodRelay.hpp +++ b/src/managers/input/InputMethodRelay.hpp @@ -30,7 +30,6 @@ class CInputMethodRelay { CTextInput* getFocusedTextInput(); - void setIMEPopupFocus(CInputPopup*, SP); void removePopup(CInputPopup*); CInputPopup* popupFromCoords(const Vector2D& point); diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index fab325fe..9f4e18f9 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -43,7 +43,6 @@ class CWLSHMBuffer : public IHLBuffer { virtual void endDataPtr(); bool good(); - void updateTexture(); int32_t offset = 0, stride = 0; uint32_t fmt = 0; diff --git a/src/protocols/types/DMABuffer.cpp b/src/protocols/types/DMABuffer.cpp index 2b4c1bac..ae684424 100644 --- a/src/protocols/types/DMABuffer.cpp +++ b/src/protocols/types/DMABuffer.cpp @@ -71,10 +71,6 @@ bool CDMABuffer::good() { return success; } -void CDMABuffer::updateTexture() { - ; -} - void CDMABuffer::closeFDs() { for (int i = 0; i < attrs.planes; ++i) { if (attrs.fds[i] == -1) @@ -83,4 +79,4 @@ void CDMABuffer::closeFDs() { attrs.fds[i] = -1; } attrs.planes = 0; -} \ No newline at end of file +} diff --git a/src/protocols/types/DMABuffer.hpp b/src/protocols/types/DMABuffer.hpp index 6977df4c..40c935c5 100644 --- a/src/protocols/types/DMABuffer.hpp +++ b/src/protocols/types/DMABuffer.hpp @@ -15,7 +15,6 @@ class CDMABuffer : public IHLBuffer { virtual std::tuple beginDataPtr(uint32_t flags); virtual void endDataPtr(); bool good(); - void updateTexture(); void closeFDs(); bool success = false; @@ -26,4 +25,4 @@ class CDMABuffer : public IHLBuffer { struct { CHyprSignalListener resourceDestroy; } listeners; -}; \ No newline at end of file +}; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 307fa975..9511123c 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2142,13 +2142,6 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float scissor((CBox*)nullptr); } -void pushVert2D(float x, float y, float* arr, int& counter, CBox* box) { - // 0-1 space god damnit - arr[counter * 2 + 0] = x / box->width; - arr[counter * 2 + 1] = y / box->height; - counter++; -} - void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, int round, int borderSize, float a, int outerRound) { 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()!"); From 5f1df55fcb45a72e92258113685aa9064f6ebf3e Mon Sep 17 00:00:00 2001 From: Khalid Date: Tue, 17 Dec 2024 20:26:02 +0300 Subject: [PATCH 0006/1444] hyprctl: Fix `hyprctl` batch JSON command (#8749) --- hyprctl/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index 676c8b98..16d66223 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -284,8 +284,10 @@ int requestHyprpaper(std::string arg) { void batchRequest(std::string arg, bool json) { std::string commands = arg.substr(arg.find_first_of(' ') + 1); - if (json) + if (json) { RE2::GlobalReplace(&commands, ";\\s*", ";j/"); + commands.insert(0, "j/"); + } std::string rq = "[[BATCH]]" + commands; request(rq); From 49e5f9c42867e33d816d316507d7bc7a45ae0477 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:56:53 -0600 Subject: [PATCH 0007/1444] logging: get broader GPUINFO (#8753) --- src/debug/CrashReporter.cpp | 2 +- src/debug/HyprCtl.cpp | 2 +- src/helpers/MiscFunctions.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debug/CrashReporter.cpp b/src/debug/CrashReporter.cpp index f3478366..7072de81 100644 --- a/src/debug/CrashReporter.cpp +++ b/src/debug/CrashReporter.cpp @@ -161,7 +161,7 @@ void NCrashReporter::createAndSaveCrash(int sig) { #if defined(__DragonFly__) || defined(__FreeBSD__) finalCrashReport.writeCmdOutput("pciconf -lv | grep -F -A4 vga"); #else - finalCrashReport.writeCmdOutput("lspci -vnn | grep VGA"); + finalCrashReport.writeCmdOutput("lspci -vnn | grep -E (VGA|Display|3D)"); #endif finalCrashReport += "\n\nos-release:\n"; diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 5ce3933c..d315990f 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -976,7 +976,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request) } } catch (...) { GPUINFO = "error"; } #else - const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA"); + const std::string GPUINFO = execAndGet("lspci -vnn | grep -E (VGA|Display|3D)"); #endif result += "GPU information: \n" + GPUINFO; if (GPUINFO.contains("NVIDIA") && std::filesystem::exists("/proc/driver/nvidia/version")) { diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 6d365161..b29ad6aa 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -608,7 +608,7 @@ void logSystemInfo() { } } catch (...) { GPUINFO = "error"; } #else - const std::string GPUINFO = execAndGet("lspci -vnn | grep VGA"); + const std::string GPUINFO = execAndGet("lspci -vnn | grep -E (VGA|Display|3D)"); #endif Debug::log(LOG, "GPU information:\n{}\n", GPUINFO); From 6378c8ed65522adc432c0780eab296f7b92db183 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 18 Dec 2024 15:01:03 +0000 Subject: [PATCH 0008/1444] core: avoid activating toplevel-less surfaces ref #8609 --- src/managers/XWaylandManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 5e5c6262..ca31752d 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -47,7 +47,7 @@ void CHyprXWaylandManager::activateSurface(SP pSurface, bool } PWINDOW->m_pXWaylandSurface->activate(activate); } - } else if (PWINDOW->m_pXDGSurface) + } else if (PWINDOW->m_pXDGSurface && PWINDOW->m_pXDGSurface->toplevel) PWINDOW->m_pXDGSurface->toplevel->setActive(activate); } From 4c4471c66d89b5293ded757da76ee6f104bcb042 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 18 Dec 2024 15:14:37 +0000 Subject: [PATCH 0009/1444] xwayland: fix dnd including xwayland ref #8759 --- src/xwayland/Dnd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xwayland/Dnd.cpp b/src/xwayland/Dnd.cpp index 488ee8dd..fed1914a 100644 --- a/src/xwayland/Dnd.cpp +++ b/src/xwayland/Dnd.cpp @@ -1,7 +1,9 @@ #include "Dnd.hpp" +#ifndef NO_XWAYLAND #include "XWM.hpp" #include "XWayland.hpp" #include "Server.hpp" +#endif #include "../managers/XWaylandManager.hpp" #include "../desktop/WLSurface.hpp" From 80a4852266643c622ec68969b39c5abc3c610f30 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 18 Dec 2024 15:24:37 +0000 Subject: [PATCH 0010/1444] xwm: fixup targets in selection requests fixes #8719 --- src/xwayland/XWM.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index ec563375..44485381 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -633,7 +633,14 @@ void CXWM::handleSelectionRequest(xcb_selection_request_event_t* e) { if (e->target == HYPRATOMS["TARGETS"]) { // send mime types - auto mimes = g_pSeatManager->selection.currentSelection->mimes(); + std::vector mimes; + if (sel == &clipboard && g_pSeatManager->selection.currentSelection) + mimes = g_pSeatManager->selection.currentSelection->mimes(); + else if (sel == &dndSelection && !dndDataOffers.empty() && dndDataOffers.at(0)->source) + mimes = dndDataOffers.at(0)->source->mimes(); + + if (mimes.empty()) + Debug::log(WARN, "[xwm] WARNING: No mimes in TARGETS?"); std::vector atoms; atoms.push_back(HYPRATOMS["TIMESTAMP"]); From 0fec38fe727954e5c4cf51423a6aba03646ad5da Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 18 Dec 2024 19:09:02 +0000 Subject: [PATCH 0011/1444] xwayland: fix compile with no xwayland --- src/xwayland/Dnd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xwayland/Dnd.cpp b/src/xwayland/Dnd.cpp index fed1914a..58fc6db3 100644 --- a/src/xwayland/Dnd.cpp +++ b/src/xwayland/Dnd.cpp @@ -7,6 +7,7 @@ #include "../managers/XWaylandManager.hpp" #include "../desktop/WLSurface.hpp" +#ifndef NO_XWAYLAND static xcb_atom_t dndActionToAtom(uint32_t actions) { if (actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) return HYPRATOMS["XdndActionCopy"]; @@ -17,6 +18,7 @@ static xcb_atom_t dndActionToAtom(uint32_t actions) { return XCB_ATOM_NONE; } +#endif eDataSourceType CX11DataOffer::type() { return DATA_SOURCE_TYPE_X11; From df06cb4d71a291171c02467c384471f90832d23b Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Wed, 18 Dec 2024 19:15:44 +0000 Subject: [PATCH 0012/1444] core: Unbreak build on FreeBSD (#8762) * CrashReporter: restore explicit environ(7) after 8bbeee11734d BSD systems don't declare environ(7) in any header like POSIX suggests. src/signal-safe.cpp:12:23: error: use of undeclared identifier 'environ' 12 | for (char** var = environ; *var != nullptr; var++) { | ^ * fix --------- Co-authored-by: Vaxry --- src/signal-safe.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/signal-safe.cpp b/src/signal-safe.cpp index 2f377bf7..baee7b44 100644 --- a/src/signal-safe.cpp +++ b/src/signal-safe.cpp @@ -7,6 +7,10 @@ #include #include +// NOLINTNEXTLINE +extern "C" char** environ; + +// char const* sigGetenv(char const* name) { const size_t len = strlen(name); for (char** var = environ; *var != nullptr; var++) { From 23e7d8f6a7d4e25c2dc6be33af07249570e66940 Mon Sep 17 00:00:00 2001 From: Kamikadze <40305144+Kam1k4dze@users.noreply.github.com> Date: Thu, 19 Dec 2024 04:08:57 +0500 Subject: [PATCH 0013/1444] logging: fix Gpu info (#8764) --- src/debug/CrashReporter.cpp | 2 +- src/debug/HyprCtl.cpp | 2 +- src/helpers/MiscFunctions.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debug/CrashReporter.cpp b/src/debug/CrashReporter.cpp index 7072de81..bddc04be 100644 --- a/src/debug/CrashReporter.cpp +++ b/src/debug/CrashReporter.cpp @@ -161,7 +161,7 @@ void NCrashReporter::createAndSaveCrash(int sig) { #if defined(__DragonFly__) || defined(__FreeBSD__) finalCrashReport.writeCmdOutput("pciconf -lv | grep -F -A4 vga"); #else - finalCrashReport.writeCmdOutput("lspci -vnn | grep -E (VGA|Display|3D)"); + finalCrashReport.writeCmdOutput("lspci -vnn | grep -E '(VGA|Display|3D)'"); #endif finalCrashReport += "\n\nos-release:\n"; diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index d315990f..2d17b2ae 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -976,7 +976,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request) } } catch (...) { GPUINFO = "error"; } #else - const std::string GPUINFO = execAndGet("lspci -vnn | grep -E (VGA|Display|3D)"); + const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'"); #endif result += "GPU information: \n" + GPUINFO; if (GPUINFO.contains("NVIDIA") && std::filesystem::exists("/proc/driver/nvidia/version")) { diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index b29ad6aa..e970b781 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -608,7 +608,7 @@ void logSystemInfo() { } } catch (...) { GPUINFO = "error"; } #else - const std::string GPUINFO = execAndGet("lspci -vnn | grep -E (VGA|Display|3D)"); + const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'"); #endif Debug::log(LOG, "GPU information:\n{}\n", GPUINFO); From 7c43eed2c1e6c56ab56d1bded4a6701b5598b1c3 Mon Sep 17 00:00:00 2001 From: Aaron Blasko Date: Thu, 19 Dec 2024 01:33:57 +0100 Subject: [PATCH 0014/1444] hyprpm: fix hyrpm sometimes returning 0 despite errors occuring (#8761) * hyprpm: fix hyrpm sometimes returning 0 despite errors occuring * there u go --- hyprpm/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hyprpm/src/main.cpp b/hyprpm/src/main.cpp index 8e67af99..103132f9 100644 --- a/hyprpm/src/main.cpp +++ b/hyprpm/src/main.cpp @@ -73,7 +73,7 @@ int main(int argc, char** argv, char** envp) { if (command.empty()) { std::println(stderr, "{}", HELP); - return 0; + return 1; } g_pPluginManager = std::make_unique(); @@ -165,6 +165,7 @@ int main(int argc, char** argv, char** envp) { break; default: break; } + return 1; } else if (notify && !notifyFail) { g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins"); } From 5b714f05f87831e3e930af04649f853d5efb9902 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:56:01 -0600 Subject: [PATCH 0015/1444] internal: Make static analysis more happy (#8767) * make functions used in 1 file static * fix invalid substr param -1 * give default initializer to borderGradier * move RASSERT from printf to std::print --- src/Compositor.cpp | 8 +-- src/debug/HyprCtl.cpp | 79 ++++++++++++++------------- src/debug/HyprNotificationOverlay.cpp | 2 +- src/desktop/Window.cpp | 2 +- src/events/Windows.cpp | 2 +- src/helpers/Monitor.cpp | 2 +- src/layout/IHyprLayout.hpp | 2 +- src/macros.hpp | 3 +- src/main.cpp | 2 +- src/managers/AnimationManager.cpp | 2 +- src/managers/KeybindManager.cpp | 4 +- src/managers/ThreadManager.cpp | 2 +- src/render/OpenGL.cpp | 2 +- src/xwayland/Server.cpp | 4 +- 14 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index dea8cddf..ba723bdc 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -50,7 +50,7 @@ using namespace Hyprutils::String; using namespace Aquamarine; -int handleCritSignal(int signo, void* data) { +static int handleCritSignal(int signo, void* data) { Debug::log(LOG, "Hyprland received signal {}", signo); if (signo == SIGTERM || signo == SIGINT || signo == SIGKILL) @@ -59,7 +59,7 @@ int handleCritSignal(int signo, void* data) { return 0; } -void handleUnrecoverableSignal(int sig) { +static void handleUnrecoverableSignal(int sig) { // remove our handlers signal(SIGABRT, SIG_DFL); @@ -83,7 +83,7 @@ void handleUnrecoverableSignal(int sig) { abort(); } -void handleUserSignal(int sig) { +static void handleUserSignal(int sig) { if (sig == SIGUSR1) { // means we have to unwind a timed out event throw std::exception(); @@ -103,7 +103,7 @@ static eLogLevel aqLevelToHl(Aquamarine::eBackendLogLevel level) { return NONE; } -void aqLog(Aquamarine::eBackendLogLevel level, std::string msg) { +static void aqLog(Aquamarine::eBackendLogLevel level, std::string msg) { Debug::log(aqLevelToHl(level), "[AQ] {}", msg); } diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 2d17b2ae..da0b2e28 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -142,7 +142,7 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer return result; } -std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); auto allMonitors = false; @@ -269,7 +269,7 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { } } -std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; if (format == eHyprCtlOutputFormat::FORMAT_JSON) { result += "["; @@ -368,7 +368,8 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF return result; } } -std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) { + +static std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string request) { if (!g_pCompositor->m_pLastMonitor) return "unsafe state"; @@ -381,7 +382,7 @@ std::string activeWorkspaceRequest(eHyprCtlOutputFormat format, std::string requ return CHyprCtl::getWorkspaceData(w, format); } -std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; if (format == eHyprCtlOutputFormat::FORMAT_JSON) { @@ -402,7 +403,7 @@ std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request) return result; } -std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; if (format == eHyprCtlOutputFormat::FORMAT_JSON) { result += "["; @@ -422,7 +423,7 @@ std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string reque return result; } -std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request) { const auto PWINDOW = g_pCompositor->m_pLastWindow.lock(); if (!validMapped(PWINDOW)) @@ -436,7 +437,7 @@ std::string activeWindowRequest(eHyprCtlOutputFormat format, std::string request return result; } -std::string layersRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string layersRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; if (format == eHyprCtlOutputFormat::FORMAT_JSON) { @@ -510,7 +511,7 @@ std::string layersRequest(eHyprCtlOutputFormat format, std::string request) { return result; } -std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; if (format == eHyprCtlOutputFormat::FORMAT_JSON) { result += "["; @@ -532,7 +533,7 @@ std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) { return result; } -std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; std::string currErrors = g_pConfigManager->getErrors(); CVarList errLines(currErrors, 0, '\n'); @@ -555,7 +556,7 @@ std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request return result; } -std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; auto getModState = [](SP keyboard, const char* xkbModName) -> bool { @@ -725,7 +726,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) { return result; } -std::string animationsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string animationsRequest(eHyprCtlOutputFormat format, std::string request) { std::string ret = ""; if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) { ret += "animations:\n"; @@ -778,7 +779,7 @@ std::string animationsRequest(eHyprCtlOutputFormat format, std::string request) return ret; } -std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; if (format == eHyprCtlOutputFormat::FORMAT_JSON) { @@ -792,7 +793,7 @@ std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string request) return result; } -std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string request) { std::string ret = ""; const auto SHORTCUTS = PROTO::globalShortcuts->getAllShortcuts(); if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) { @@ -815,7 +816,7 @@ std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string requ return ret; } -std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) { std::string ret = ""; if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) { for (auto const& kb : g_pKeybindManager->m_vKeybinds) { @@ -1018,7 +1019,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request) return result; } -std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) { +static std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) { // get rid of the dispatch keyword in = in.substr(in.find_first_of(' ') + 1); @@ -1039,7 +1040,7 @@ std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) { return res.success ? "ok" : res.error; } -std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) { +static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) { // Find the first space to strip the keyword keyword auto const firstSpacePos = in.find_first_of(' '); if (firstSpacePos == std::string::npos) // Handle the case where there's no space found (invalid input) @@ -1105,7 +1106,7 @@ std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) { return retval; } -std::string reloadRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string reloadRequest(eHyprCtlOutputFormat format, std::string request) { const auto REQMODE = request.substr(request.find_last_of(' ') + 1); @@ -1120,17 +1121,17 @@ std::string reloadRequest(eHyprCtlOutputFormat format, std::string request) { return "ok"; } -std::string killRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string killRequest(eHyprCtlOutputFormat format, std::string request) { g_pInputManager->setClickMode(CLICKMODE_KILL); return "ok"; } -std::string splashRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string splashRequest(eHyprCtlOutputFormat format, std::string request) { return g_pCompositor->m_szCurrentSplash; } -std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string request) { const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal().floor(); if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) { @@ -1148,7 +1149,7 @@ std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string request) { return "error"; } -std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) { // split by ; request = request.substr(9); @@ -1182,7 +1183,7 @@ std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) { return reply.substr(0, std::max(static_cast(reply.size() - DELIMITER.size()), 0)); } -std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); const auto SIZESTR = vars[vars.size() - 1]; @@ -1206,7 +1207,7 @@ std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request) return "ok"; } -std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); const auto KB = vars[1]; @@ -1281,7 +1282,7 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ return "ok"; } -std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); std::string errorMessage = ""; @@ -1310,12 +1311,12 @@ std::string dispatchSeterror(eHyprCtlOutputFormat format, std::string request) { return "ok"; } -std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { - auto result = g_pKeybindManager->m_mDispatchers["setprop"](request.substr(request.find_first_of(' ') + 1, -1)); +static std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) { + auto result = g_pKeybindManager->m_mDispatchers["setprop"](request.substr(request.find_first_of(' ') + 1)); return "DEPRECATED: use hyprctl dispatch setprop instead" + (result.success ? "" : "\n" + result.error); } -std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) { std::string curitem = ""; auto nextItem = [&]() { @@ -1371,7 +1372,7 @@ std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request) return "invalid type (internal error)"; } -std::string decorationRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string decorationRequest(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); const auto PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); @@ -1397,7 +1398,7 @@ std::string decorationRequest(eHyprCtlOutputFormat format, std::string request) return result; } -std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); if (vars.size() < 2) @@ -1452,7 +1453,7 @@ std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) { return "ok"; } -std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); if (vars.size() < 2) @@ -1521,7 +1522,7 @@ std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) { return "ok"; } -std::string dispatchNotify(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchNotify(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); if (vars.size() < 5) @@ -1576,7 +1577,7 @@ std::string dispatchNotify(eHyprCtlOutputFormat format, std::string request) { return "ok"; } -std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::string request) { +static std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::string request) { CVarList vars(request, 0, ' '); int amount = -1; @@ -1596,7 +1597,7 @@ std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::string reque return "ok"; } -std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) { +static std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) { std::string lockedStr = g_pSessionLockManager->isSessionLocked() ? "true" : "false"; if (format == eHyprCtlOutputFormat::FORMAT_JSON) lockedStr = std::format(R"#( @@ -1608,7 +1609,7 @@ std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) { return lockedStr; } -std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) { +static std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) { std::string json = "{"; const auto& DESCS = g_pConfigManager->getAllDescriptions(); @@ -1623,7 +1624,7 @@ std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) { return json; } -std::string submapRequest(eHyprCtlOutputFormat format, std::string request) { +static std::string submapRequest(eHyprCtlOutputFormat format, std::string request) { std::string submap = g_pKeybindManager->getCurrentSubmap(); if (submap.empty()) submap = "default"; @@ -1792,7 +1793,7 @@ std::string CHyprCtl::makeDynamicCall(const std::string& input) { return getReply(input); } -bool successWrite(int fd, const std::string& data, bool needLog = true) { +static bool successWrite(int fd, const std::string& data, bool needLog = true) { if (write(fd, data.c_str(), data.length()) > 0) return true; @@ -1805,7 +1806,7 @@ bool successWrite(int fd, const std::string& data, bool needLog = true) { return false; } -void runWritingDebugLogThread(const int conn) { +static void runWritingDebugLogThread(const int conn) { using namespace std::chrono_literals; Debug::log(LOG, "In followlog thread, got connection, start writing: {}", conn); //will be finished, when reading side close connection @@ -1828,11 +1829,11 @@ void runWritingDebugLogThread(const int conn) { }).detach(); } -bool isFollowUpRollingLogRequest(const std::string& request) { +static bool isFollowUpRollingLogRequest(const std::string& request) { return request.contains("rollinglog") && request.contains("f"); } -int hyprCtlFDTick(int fd, uint32_t mask, void* data) { +static int hyprCtlFDTick(int fd, uint32_t mask, void* data) { if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP) return 0; diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index 153d2395..7bcfad82 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -4,7 +4,7 @@ #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" -inline auto iconBackendFromLayout(PangoLayout* layout) { +static inline auto iconBackendFromLayout(PangoLayout* layout) { // preference: Nerd > FontAwesome > text auto eIconBackendChecks = std::array{ICONS_BACKEND_NF, ICONS_BACKEND_FA}; for (auto iconID : eIconBackendChecks) { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index c0752224..696bfc5b 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -473,7 +473,7 @@ PHLWINDOW CWindow::x11TransientFor() { return nullptr; } -void unregisterVar(void* ptr) { +static void unregisterVar(void* ptr) { ((CBaseAnimatedVariable*)ptr)->unregister(); } diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index edc29ed3..437301b7 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -27,7 +27,7 @@ using namespace Hyprutils::String; // // // ------------------------------------------------------------ // -void setAnimToMove(void* data) { +static void setAnimToMove(void* data) { auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove"); CBaseAnimatedVariable* animvar = (CBaseAnimatedVariable*)data; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 8d1597be..33ec3abe 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -24,7 +24,7 @@ using namespace Hyprutils::String; using namespace Hyprutils::Utils; -int ratHandler(void* data) { +static int ratHandler(void* data) { g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock()); return 1; diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index c5de8339..ab188b9b 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -8,7 +8,7 @@ class CGradientValueData; struct SWindowRenderLayoutHints { bool isBorderGradient = false; - CGradientValueData* borderGradient; + CGradientValueData* borderGradient = nullptr; }; struct SLayoutMessageHeader { diff --git a/src/macros.hpp b/src/macros.hpp index 4a319569..de2fd009 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "helpers/memory/Memory.hpp" @@ -49,7 +50,7 @@ Debug::log(CRIT, "\n==========================================================================================\nASSERTION FAILED! \n\n{}\n\nat: line {} in {}", \ std::format(reason, ##__VA_ARGS__), __LINE__, \ ([]() constexpr -> std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })()); \ - printf("Assertion failed! See the log in /tmp/hypr/hyprland.log for more info."); \ + std::print("Assertion failed! See the log in /tmp/hypr/hyprland.log for more info."); \ raise(SIGABRT); \ } diff --git a/src/main.cpp b/src/main.cpp index 6b6f9063..ebae055b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ using namespace Hyprutils::String; #include #include -void help() { +static void help() { std::println("usage: Hyprland [arg [...]].\n"); std::println(R"(Arguments: --help -h - Show this message again diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index c8f7ecdf..e3309282 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -10,7 +10,7 @@ #include -int wlTick(SP self, void* data) { +static int wlTick(SP self, void* data) { if (g_pAnimationManager) g_pAnimationManager->onTicked(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index fec608f1..e1ad7d60 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -299,7 +299,7 @@ bool CKeybindManager::ensureMouseBindState() { return false; } -void updateRelativeCursorCoords() { +static void updateRelativeCursorCoords() { static auto PNOWARPS = CConfigValue("cursor:no_warps"); if (*PNOWARPS) @@ -1095,7 +1095,7 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) { return {}; } -SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE) { +static SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE) { if (!args.starts_with("previous")) { return getWorkspaceIDNameFromString(args); } diff --git a/src/managers/ThreadManager.cpp b/src/managers/ThreadManager.cpp index ce15688d..bd124c99 100644 --- a/src/managers/ThreadManager.cpp +++ b/src/managers/ThreadManager.cpp @@ -3,7 +3,7 @@ #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" -int handleTimer(void* data) { +static int handleTimer(void* data) { const auto PTM = (CThreadManager*)data; static auto PDISABLECFGRELOAD = CConfigValue("misc:disable_autoreload"); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 9511123c..4339fd40 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -21,7 +21,7 @@ const std::vector ASSET_PATHS = { "/usr/local/share", }; -inline void loadGLProc(void* pProc, const char* name) { +static inline void loadGLProc(void* pProc, const char* name) { void* proc = (void*)eglGetProcAddress(name); if (proc == nullptr) { Debug::log(CRIT, "[Tracy GPU Profiling] eglGetProcAddress({}) failed", name); diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index 9d6b3bcb..b1f02cd3 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -51,13 +51,13 @@ static bool setCloseOnExec(int fd, bool cloexec) { return true; } -void cleanUpSocket(int fd, const char* path) { +static void cleanUpSocket(int fd, const char* path) { close(fd); if (path[0]) unlink(path); } -inline void closeSocketSafely(int& fd) { +static inline void closeSocketSafely(int& fd) { if (fd >= 0) close(fd); } From bec18dc6f943587c23a3e3ec2dc397833e924001 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 19 Dec 2024 19:11:07 +0000 Subject: [PATCH 0016/1444] core: fix possible crash on null active workspace fixes #7822 --- src/Compositor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index ba723bdc..5e8c8048 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1097,7 +1097,8 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface const auto PWORKSPACE = pWindow->m_pWorkspace; // This is to fix incorrect feedback on the focus history. PWORKSPACE->m_pLastFocusedWindow = pWindow; - PWORKSPACE->rememberPrevWorkspace(m_pLastMonitor->activeWorkspace); + if (m_pLastMonitor->activeWorkspace) + PWORKSPACE->rememberPrevWorkspace(m_pLastMonitor->activeWorkspace); if (PWORKSPACE->m_bIsSpecialWorkspace) m_pLastMonitor->changeWorkspace(PWORKSPACE, false, true); // if special ws, open on current monitor else if (PMONITOR) From fd67ee9ecdc7207939fe1dcea9b81050ec7d58c4 Mon Sep 17 00:00:00 2001 From: Aqa-Ib <16420574+Aqa-Ib@users.noreply.github.com> Date: Thu, 19 Dec 2024 19:22:40 +0000 Subject: [PATCH 0017/1444] layout: apply group rules after window creation (#8779) * apply group rules after window creation * clang-format --- src/layout/IHyprLayout.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index d9c2f6a1..cbea46c5 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -20,9 +20,6 @@ void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) { pWindow->m_vPseudoSize = pWindow->m_vLastFloatingSize; - if (!g_pXWaylandManager->shouldBeFloated(pWindow)) // do not apply group rules to child windows - pWindow->applyGroupRules(); - bool autoGrouped = IHyprLayout::onWindowCreatedAutoGroup(pWindow); if (autoGrouped) return; @@ -31,6 +28,9 @@ void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) { onWindowCreatedFloating(pWindow); else onWindowCreatedTiling(pWindow, direction); + + if (!g_pXWaylandManager->shouldBeFloated(pWindow)) // do not apply group rules to child windows + pWindow->applyGroupRules(); } void IHyprLayout::onWindowRemoved(PHLWINDOW pWindow) { From 71dc9f6128b8d2e382b2a574d2d5f15e2d907f3a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 19 Dec 2024 20:23:32 +0000 Subject: [PATCH 0018/1444] pluginAPI: add register dispatcher v2 --- src/SharedDefs.hpp | 7 +++++++ src/managers/KeybindManager.hpp | 6 ------ src/plugins/PluginAPI.cpp | 13 +++++++++++++ src/plugins/PluginAPI.hpp | 11 ++++++++++- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/SharedDefs.hpp b/src/SharedDefs.hpp index 711cf562..a6271556 100644 --- a/src/SharedDefs.hpp +++ b/src/SharedDefs.hpp @@ -3,6 +3,7 @@ #include "helpers/math/Math.hpp" #include #include +#include #include enum eIcons : uint8_t { @@ -50,6 +51,12 @@ struct SHyprCtlCommand { std::function fn; }; +struct SDispatchResult { + bool passEvent = false; + bool success = true; + std::string error; +}; + typedef int64_t WINDOWID; typedef int64_t MONITORID; typedef int64_t WORKSPACEID; diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 6486ac3b..c8c6266c 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -74,12 +74,6 @@ enum eMultiKeyCase : uint8_t { MK_FULL_MATCH }; -struct SDispatchResult { - bool passEvent = false; - bool success = true; - std::string error; -}; - class CKeybindManager { public: CKeybindManager(); diff --git a/src/plugins/PluginAPI.cpp b/src/plugins/PluginAPI.cpp index 4172a856..5e1d9e58 100644 --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -202,6 +202,19 @@ APICALL bool HyprlandAPI::addDispatcher(HANDLE handle, const std::string& name, return true; } +APICALL bool HyprlandAPI::addDispatcherV2(HANDLE handle, const std::string& name, std::function handler) { + auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle); + + if (!PLUGIN) + return false; + + PLUGIN->registeredDispatchers.push_back(name); + + g_pKeybindManager->m_mDispatchers[name] = handler; + + return true; +} + APICALL bool HyprlandAPI::removeDispatcher(HANDLE handle, const std::string& name) { auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle); diff --git a/src/plugins/PluginAPI.hpp b/src/plugins/PluginAPI.hpp index 6b8c35f0..96c32bf1 100644 --- a/src/plugins/PluginAPI.hpp +++ b/src/plugins/PluginAPI.hpp @@ -236,8 +236,17 @@ namespace HyprlandAPI { Adds a keybind dispatcher. returns: true on success. False otherwise. + + DEPRECATED: use addDispatcherV2 */ - APICALL bool addDispatcher(HANDLE handle, const std::string& name, std::function handler); + APICALL [[deprecated]] bool addDispatcher(HANDLE handle, const std::string& name, std::function handler); + + /* + Adds a keybind dispatcher. + + returns: true on success. False otherwise. + */ + APICALL bool addDispatcherV2(HANDLE handle, const std::string& name, std::function handler); /* Removes a keybind dispatcher. From 52ee7a874805bbcbd8f470937c5aacd0c055f7f8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 21 Dec 2024 15:08:00 +0000 Subject: [PATCH 0019/1444] data-device: fix edge case crash on null xwm fixes #8787 --- src/protocols/core/DataDevice.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 9447f04f..b4bb8b00 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -731,14 +731,16 @@ bool CWLDataDeviceProtocol::wasDragSuccessful() { } #ifndef NO_XWAYLAND - for (auto const& o : g_pXWayland->pWM->dndDataOffers) { - if (o->dead || !o->source || !o->source->hasDnd()) - continue; + if (g_pXWayland->pWM) { + for (auto const& o : g_pXWayland->pWM->dndDataOffers) { + if (o->dead || !o->source || !o->source->hasDnd()) + continue; - if (o->source != dnd.currentSource) - continue; + if (o->source != dnd.currentSource) + continue; - return true; + return true; + } } #endif From 8e8073c42172feaf5600879f475322ab7363f017 Mon Sep 17 00:00:00 2001 From: Aqa-Ib <16420574+Aqa-Ib@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:35:47 +0000 Subject: [PATCH 0020/1444] groups: honor group lock window rule (#8782) --- src/layout/IHyprLayout.cpp | 2 ++ src/render/decorations/CHyprGroupBarDecoration.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index cbea46c5..354fc09f 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -205,6 +205,7 @@ bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) { (*USECURRPOS ? OPENINGON : OPENINGON->getGroupTail())->insertWindowToGroup(pWindow); OPENINGON->setGroupCurrent(pWindow); + pWindow->applyGroupRules(); pWindow->updateWindowDecos(); recalculateWindow(pWindow); @@ -364,6 +365,7 @@ void IHyprLayout::onEndDragWindow() { static auto USECURRPOS = CConfigValue("group:insert_after_current"); (*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW); pWindow->setGroupCurrent(DRAGGINGWINDOW); + DRAGGINGWINDOW->applyGroupRules(); DRAGGINGWINDOW->updateWindowDecos(); if (!DRAGGINGWINDOW->getDecorationByType(DECORATION_GROUPBAR)) diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 3138c326..0aee6157 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -468,6 +468,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND std::swap(pDraggedHead->m_sGroupData.head, pWindowInsertEnd->m_sGroupData.head); m_pWindow->setGroupCurrent(pDraggedWindow); + pDraggedWindow->applyGroupRules(); pDraggedWindow->updateWindowDecos(); g_pLayoutManager->getCurrentLayout()->recalculateWindow(pDraggedWindow); From 57921d7dbd1b87a9474f609cb9cd30e6174027cd Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 21 Dec 2024 19:21:45 +0000 Subject: [PATCH 0021/1444] windowrules: precompute regexes for window/layer rules --- src/config/ConfigManager.cpp | 34 +++++++++++++++++++++++----------- src/desktop/LayerRule.cpp | 1 + src/desktop/LayerRule.hpp | 14 +++++++++++--- src/desktop/WindowRule.cpp | 1 + src/desktop/WindowRule.hpp | 13 +++++++++++++ 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f4ba7379..c4078777 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1258,10 +1258,10 @@ std::vector> CConfigManager::getMatchingRules(PHLWINDOW pWindow, if (rule->szValue.starts_with("tag:") && !tags.isTagged(rule->szValue.substr(4))) continue; - if (rule->szValue.starts_with("title:") && !RE2::FullMatch(pWindow->m_szTitle, rule->szValue.substr(6))) + if (rule->szValue.starts_with("title:") && !RE2::FullMatch(pWindow->m_szTitle, *rule->rV1Regex)) continue; - if (!RE2::FullMatch(pWindow->m_szClass, rule->szValue)) + if (!RE2::FullMatch(pWindow->m_szClass, *rule->rV1Regex)) continue; } catch (...) { @@ -1351,16 +1351,16 @@ std::vector> CConfigManager::getMatchingRules(PHLWINDOW pWindow, if (!rule->szTag.empty() && !tags.isTagged(rule->szTag)) continue; - if (!rule->szClass.empty() && !RE2::FullMatch(pWindow->m_szClass, rule->szClass)) + if (!rule->szClass.empty() && !RE2::FullMatch(pWindow->m_szClass, *rule->rClass)) continue; - if (!rule->szTitle.empty() && !RE2::FullMatch(pWindow->m_szTitle, rule->szTitle)) + if (!rule->szTitle.empty() && !RE2::FullMatch(pWindow->m_szTitle, *rule->rTitle)) continue; - if (!rule->szInitialTitle.empty() && !RE2::FullMatch(pWindow->m_szInitialTitle, rule->szInitialTitle)) + if (!rule->szInitialTitle.empty() && !RE2::FullMatch(pWindow->m_szInitialTitle, *rule->rInitialTitle)) continue; - if (!rule->szInitialClass.empty() && !RE2::FullMatch(pWindow->m_szInitialClass, rule->szInitialClass)) + if (!rule->szInitialClass.empty() && !RE2::FullMatch(pWindow->m_szInitialClass, *rule->rInitialClass)) continue; } catch (std::exception& e) { @@ -1419,7 +1419,7 @@ std::vector> CConfigManager::getMatchingRules(PHLLS pLS) { if (lr->targetNamespace.starts_with("address:0x")) { if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr->targetNamespace) continue; - } else if (!RE2::FullMatch(pLS->layerSurface->layerNamespace, lr->targetNamespace)) + } else if (!RE2::FullMatch(pLS->layerSurface->layerNamespace, *lr->rTargetNamespaceRegex)) continue; // hit @@ -2281,6 +2281,8 @@ std::optional CConfigManager::handleWindowRule(const std::string& c return "Invalid rule: " + RULE; } + newRule->rV1Regex = std::make_unique(VALUE.starts_with("title:") ? VALUE.substr(6) : VALUE); + if (RULE.starts_with("size") || RULE.starts_with("maxsize") || RULE.starts_with("minsize")) m_vWindowRules.insert(m_vWindowRules.begin(), newRule); else @@ -2309,6 +2311,8 @@ std::optional CConfigManager::handleLayerRule(const std::string& co return "Invalid rule found: " + RULE; } + rule->rTargetNamespaceRegex = std::make_unique(VALUE); + m_vLayerRules.emplace_back(rule); for (auto const& m : g_pCompositor->m_vMonitors) @@ -2407,17 +2411,25 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& if (TAGPOS != std::string::npos) rule->szTag = extract(TAGPOS + 4); - if (CLASSPOS != std::string::npos) + if (CLASSPOS != std::string::npos) { rule->szClass = extract(CLASSPOS + 6); + rule->rClass = std::make_unique(rule->szClass); + } - if (TITLEPOS != std::string::npos) + if (TITLEPOS != std::string::npos) { rule->szTitle = extract(TITLEPOS + 6); + rule->rTitle = std::make_unique(rule->szTitle); + } - if (INITIALCLASSPOS != std::string::npos) + if (INITIALCLASSPOS != std::string::npos) { rule->szInitialClass = extract(INITIALCLASSPOS + 13); + rule->rInitialClass = std::make_unique(rule->szInitialClass); + } - if (INITIALTITLEPOS != std::string::npos) + if (INITIALTITLEPOS != std::string::npos) { rule->szInitialTitle = extract(INITIALTITLEPOS + 13); + rule->rInitialTitle = std::make_unique(rule->szInitialTitle); + } if (X11POS != std::string::npos) rule->bX11 = extract(X11POS + 9) == "1" ? 1 : 0; diff --git a/src/desktop/LayerRule.cpp b/src/desktop/LayerRule.cpp index d82e4d30..23371947 100644 --- a/src/desktop/LayerRule.cpp +++ b/src/desktop/LayerRule.cpp @@ -1,6 +1,7 @@ #include "LayerRule.hpp" #include #include +#include #include "../debug/Log.hpp" static const auto RULES = std::unordered_set{"noanim", "blur", "blurpopups", "dimaround"}; diff --git a/src/desktop/LayerRule.hpp b/src/desktop/LayerRule.hpp index 7dca4621..117fa6fb 100644 --- a/src/desktop/LayerRule.hpp +++ b/src/desktop/LayerRule.hpp @@ -2,6 +2,12 @@ #include #include +#include + +//NOLINTNEXTLINE +namespace re2 { + class RE2; +}; class CLayerRule { public: @@ -21,8 +27,10 @@ class CLayerRule { RULE_ZUMBA, }; - eRuleType ruleType = RULE_INVALID; + eRuleType ruleType = RULE_INVALID; - const std::string targetNamespace; - const std::string rule; + const std::string targetNamespace; + const std::string rule; + + std::unique_ptr rTargetNamespaceRegex; }; \ No newline at end of file diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp index 4f2d949e..7db6c3db 100644 --- a/src/desktop/WindowRule.cpp +++ b/src/desktop/WindowRule.cpp @@ -1,6 +1,7 @@ #include "WindowRule.hpp" #include #include +#include #include "../config/ConfigManager.hpp" static const auto RULES = std::unordered_set{ diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp index 6faf8b5a..3ce31179 100644 --- a/src/desktop/WindowRule.hpp +++ b/src/desktop/WindowRule.hpp @@ -2,6 +2,12 @@ #include #include +#include + +//NOLINTNEXTLINE +namespace re2 { + class RE2; +}; class CWindowRule { public: @@ -57,4 +63,11 @@ class CWindowRule { std::string szFullscreenState = ""; // empty means any std::string szOnWorkspace = ""; // empty means any std::string szWorkspace = ""; // empty means any + + // precompiled regexes + std::unique_ptr rTitle; + std::unique_ptr rClass; + std::unique_ptr rInitialTitle; + std::unique_ptr rInitialClass; + std::unique_ptr rV1Regex; }; \ No newline at end of file From 31422ae25dee33dd000798b64a80bd7fd08d2ece Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 21 Dec 2024 23:07:23 +0000 Subject: [PATCH 0022/1444] windowrules: add negative: prefix for negating a regex fixes #8799 --- src/config/ConfigManager.cpp | 26 +++++++++++++------------- src/desktop/LayerRule.hpp | 15 +++++---------- src/desktop/Rule.cpp | 16 ++++++++++++++++ src/desktop/Rule.hpp | 21 +++++++++++++++++++++ src/desktop/WindowRule.hpp | 17 ++++++----------- 5 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 src/desktop/Rule.cpp create mode 100644 src/desktop/Rule.hpp diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index c4078777..07421382 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1258,10 +1258,10 @@ std::vector> CConfigManager::getMatchingRules(PHLWINDOW pWindow, if (rule->szValue.starts_with("tag:") && !tags.isTagged(rule->szValue.substr(4))) continue; - if (rule->szValue.starts_with("title:") && !RE2::FullMatch(pWindow->m_szTitle, *rule->rV1Regex)) + if (rule->szValue.starts_with("title:") && !rule->rV1Regex.passes(pWindow->m_szTitle)) continue; - if (!RE2::FullMatch(pWindow->m_szClass, *rule->rV1Regex)) + if (!rule->rV1Regex.passes(pWindow->m_szClass)) continue; } catch (...) { @@ -1351,16 +1351,16 @@ std::vector> CConfigManager::getMatchingRules(PHLWINDOW pWindow, if (!rule->szTag.empty() && !tags.isTagged(rule->szTag)) continue; - if (!rule->szClass.empty() && !RE2::FullMatch(pWindow->m_szClass, *rule->rClass)) + if (!rule->szClass.empty() && !rule->rClass.passes(pWindow->m_szClass)) continue; - if (!rule->szTitle.empty() && !RE2::FullMatch(pWindow->m_szTitle, *rule->rTitle)) + if (!rule->szTitle.empty() && !rule->rTitle.passes(pWindow->m_szTitle)) continue; - if (!rule->szInitialTitle.empty() && !RE2::FullMatch(pWindow->m_szInitialTitle, *rule->rInitialTitle)) + if (!rule->szInitialTitle.empty() && !rule->rInitialTitle.passes(pWindow->m_szInitialTitle)) continue; - if (!rule->szInitialClass.empty() && !RE2::FullMatch(pWindow->m_szInitialClass, *rule->rInitialClass)) + if (!rule->szInitialClass.empty() && !rule->rInitialClass.passes(pWindow->m_szInitialClass)) continue; } catch (std::exception& e) { @@ -1419,7 +1419,7 @@ std::vector> CConfigManager::getMatchingRules(PHLLS pLS) { if (lr->targetNamespace.starts_with("address:0x")) { if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr->targetNamespace) continue; - } else if (!RE2::FullMatch(pLS->layerSurface->layerNamespace, *lr->rTargetNamespaceRegex)) + } else if (!lr->targetNamespaceRegex.passes(pLS->layerSurface->layerNamespace)) continue; // hit @@ -2281,7 +2281,7 @@ std::optional CConfigManager::handleWindowRule(const std::string& c return "Invalid rule: " + RULE; } - newRule->rV1Regex = std::make_unique(VALUE.starts_with("title:") ? VALUE.substr(6) : VALUE); + newRule->rV1Regex = {VALUE.starts_with("title:") ? VALUE.substr(6) : VALUE}; if (RULE.starts_with("size") || RULE.starts_with("maxsize") || RULE.starts_with("minsize")) m_vWindowRules.insert(m_vWindowRules.begin(), newRule); @@ -2311,7 +2311,7 @@ std::optional CConfigManager::handleLayerRule(const std::string& co return "Invalid rule found: " + RULE; } - rule->rTargetNamespaceRegex = std::make_unique(VALUE); + rule->targetNamespaceRegex = {VALUE}; m_vLayerRules.emplace_back(rule); @@ -2413,22 +2413,22 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& if (CLASSPOS != std::string::npos) { rule->szClass = extract(CLASSPOS + 6); - rule->rClass = std::make_unique(rule->szClass); + rule->rClass = {rule->szClass}; } if (TITLEPOS != std::string::npos) { rule->szTitle = extract(TITLEPOS + 6); - rule->rTitle = std::make_unique(rule->szTitle); + rule->rTitle = {rule->szTitle}; } if (INITIALCLASSPOS != std::string::npos) { rule->szInitialClass = extract(INITIALCLASSPOS + 13); - rule->rInitialClass = std::make_unique(rule->szInitialClass); + rule->rInitialClass = {rule->szInitialClass}; } if (INITIALTITLEPOS != std::string::npos) { rule->szInitialTitle = extract(INITIALTITLEPOS + 13); - rule->rInitialTitle = std::make_unique(rule->szInitialTitle); + rule->rInitialTitle = {rule->szInitialTitle}; } if (X11POS != std::string::npos) diff --git a/src/desktop/LayerRule.hpp b/src/desktop/LayerRule.hpp index 117fa6fb..8cdb332e 100644 --- a/src/desktop/LayerRule.hpp +++ b/src/desktop/LayerRule.hpp @@ -2,12 +2,7 @@ #include #include -#include - -//NOLINTNEXTLINE -namespace re2 { - class RE2; -}; +#include "Rule.hpp" class CLayerRule { public: @@ -27,10 +22,10 @@ class CLayerRule { RULE_ZUMBA, }; - eRuleType ruleType = RULE_INVALID; + eRuleType ruleType = RULE_INVALID; - const std::string targetNamespace; - const std::string rule; + const std::string targetNamespace; + const std::string rule; - std::unique_ptr rTargetNamespaceRegex; + CRuleRegexContainer targetNamespaceRegex; }; \ No newline at end of file diff --git a/src/desktop/Rule.cpp b/src/desktop/Rule.cpp new file mode 100644 index 00000000..dd1848d4 --- /dev/null +++ b/src/desktop/Rule.cpp @@ -0,0 +1,16 @@ +#include "Rule.hpp" +#include + +CRuleRegexContainer::CRuleRegexContainer(const std::string& regex_) { + const bool NEGATIVE = regex_.starts_with("negative:"); + + negative = NEGATIVE; + regex = std::make_unique(NEGATIVE ? regex_.substr(9) : regex_); +} + +bool CRuleRegexContainer::passes(const std::string& str) const { + if (!regex) + return false; + + return RE2::FullMatch(str, *regex) != negative; +} \ No newline at end of file diff --git a/src/desktop/Rule.hpp b/src/desktop/Rule.hpp new file mode 100644 index 00000000..4b178ee8 --- /dev/null +++ b/src/desktop/Rule.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +//NOLINTNEXTLINE +namespace re2 { + class RE2; +}; + +class CRuleRegexContainer { + public: + CRuleRegexContainer() = default; + + CRuleRegexContainer(const std::string& regex); + + bool passes(const std::string& str) const; + + private: + std::unique_ptr regex; + bool negative = false; +}; \ No newline at end of file diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp index 3ce31179..be9c2d9c 100644 --- a/src/desktop/WindowRule.hpp +++ b/src/desktop/WindowRule.hpp @@ -2,12 +2,7 @@ #include #include -#include - -//NOLINTNEXTLINE -namespace re2 { - class RE2; -}; +#include "Rule.hpp" class CWindowRule { public: @@ -65,9 +60,9 @@ class CWindowRule { std::string szWorkspace = ""; // empty means any // precompiled regexes - std::unique_ptr rTitle; - std::unique_ptr rClass; - std::unique_ptr rInitialTitle; - std::unique_ptr rInitialClass; - std::unique_ptr rV1Regex; + CRuleRegexContainer rTitle; + CRuleRegexContainer rClass; + CRuleRegexContainer rInitialTitle; + CRuleRegexContainer rInitialClass; + CRuleRegexContainer rV1Regex; }; \ No newline at end of file From 1cc1a46c2e154a27750b81307040d3bf7ff0f64f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 22 Dec 2024 16:04:10 +0000 Subject: [PATCH 0023/1444] core: fade in windows when they are brought from invisible workspaces --- src/Compositor.cpp | 6 ++++++ src/desktop/Window.cpp | 7 +++++++ src/desktop/Window.hpp | 1 + src/render/Renderer.cpp | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 5e8c8048..9bcbdb0f 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2649,6 +2649,7 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor const bool FULLSCREEN = pWindow->isFullscreen(); const auto FULLSCREENMODE = pWindow->m_sFullscreenState.internal; + const bool WASVISIBLE = pWindow->m_pWorkspace && pWindow->m_pWorkspace->isVisible(); if (FULLSCREEN) setWindowFullscreenInternal(pWindow, FSMODE_NONE); @@ -2716,6 +2717,11 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor if (pWindow->m_pWorkspace) pWindow->m_pWorkspace->updateWindows(); g_pCompositor->updateSuspendedStates(); + + if (!WASVISIBLE && pWindow->m_pWorkspace && pWindow->m_pWorkspace->isVisible()) { + pWindow->m_fMovingFromWorkspaceAlpha.setValueAndWarp(0.F); + pWindow->m_fMovingFromWorkspaceAlpha = 1.F; + } } PHLWINDOW CCompositor::getForceFocus() { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 696bfc5b..871e73ed 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -33,6 +33,7 @@ PHLWINDOW CWindow::create(SP surface) { pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_fMovingFromWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(std::make_unique(pWindow)); pWindow->addWindowDeco(std::make_unique(pWindow)); @@ -55,6 +56,7 @@ PHLWINDOW CWindow::create(SP resource) { pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); + pWindow->m_fMovingFromWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(std::make_unique(pWindow)); pWindow->addWindowDeco(std::make_unique(pWindow)); @@ -504,6 +506,7 @@ void CWindow::onUnmap() { m_cRealShadowColor.setCallbackOnEnd(unregisterVar); m_fDimPercent.setCallbackOnEnd(unregisterVar); m_fMovingToWorkspaceAlpha.setCallbackOnEnd(unregisterVar); + m_fMovingFromWorkspaceAlpha.setCallbackOnEnd(unregisterVar); m_vRealSize.setCallbackOnBegin(nullptr); @@ -547,6 +550,7 @@ void CWindow::onMap() { m_cRealShadowColor.resetAllCallbacks(); m_fDimPercent.resetAllCallbacks(); m_fMovingToWorkspaceAlpha.resetAllCallbacks(); + m_fMovingFromWorkspaceAlpha.resetAllCallbacks(); m_vRealPosition.registerVar(); m_vRealSize.registerVar(); @@ -557,12 +561,15 @@ void CWindow::onMap() { m_cRealShadowColor.registerVar(); m_fDimPercent.registerVar(); m_fMovingToWorkspaceAlpha.registerVar(); + m_fMovingFromWorkspaceAlpha.registerVar(); m_fBorderAngleAnimationProgress.setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false); m_fBorderAngleAnimationProgress.setValueAndWarp(0.f); m_fBorderAngleAnimationProgress = 1.f; + m_fMovingFromWorkspaceAlpha.setValueAndWarp(1.F); + g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf); m_vReportedSize = m_vPendingReportedSize; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 7b2cfbdf..6ed9a525 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -336,6 +336,7 @@ class CWindow { // for alpha CAnimatedVariable m_fActiveInactiveAlpha; + CAnimatedVariable m_fMovingFromWorkspaceAlpha; // animated shadow color CAnimatedVariable m_cRealShadowColor; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 4edd5a0c..c873842b 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -597,7 +597,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.surface = pWindow->m_pWLSurface->resource(); renderdata.dontRound = pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN) || pWindow->m_sWindowData.noRounding.valueOrDefault(); renderdata.fadeAlpha = pWindow->m_fAlpha.value() * (pWindow->m_bPinned || USE_WORKSPACE_FADE_ALPHA ? 1.f : PWORKSPACE->m_fAlpha.value()) * - (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha.value() : 1.F); + (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha.value() : 1.F) * pWindow->m_fMovingFromWorkspaceAlpha.value(); renderdata.alpha = pWindow->m_fActiveInactiveAlpha.value(); renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; From e536b02248f370971716b744968776f6880528be Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:12:09 +0100 Subject: [PATCH 0024/1444] Renderer: rewrite render scheduling (#8683) This rewrites renderer scheduling. Occlusion is now unified in a new Pass type. --- src/config/ConfigManager.cpp | 3 +- src/debug/HyprNotificationOverlay.cpp | 9 +- src/desktop/LayerSurface.cpp | 2 +- src/events/Windows.cpp | 2 +- src/helpers/WLClasses.hpp | 41 - src/hyprerror/HyprError.cpp | 8 +- src/managers/PointerManager.cpp | 11 +- src/protocols/core/Compositor.cpp | 7 +- src/protocols/core/Compositor.hpp | 2 +- src/protocols/core/DataDevice.cpp | 7 +- src/render/OpenGL.cpp | 322 ++----- src/render/OpenGL.hpp | 39 +- src/render/Renderer.cpp | 795 +++++++++--------- src/render/Renderer.hpp | 17 +- src/render/Transformer.cpp | 2 +- src/render/Transformer.hpp | 5 +- .../decorations/CHyprBorderDecoration.cpp | 24 +- .../decorations/CHyprDropShadowDecoration.cpp | 11 + .../decorations/CHyprDropShadowDecoration.hpp | 2 + .../decorations/CHyprGroupBarDecoration.cpp | 51 +- src/render/pass/BorderPassElement.cpp | 21 + src/render/pass/BorderPassElement.hpp | 30 + src/render/pass/ClearPassElement.cpp | 26 + src/render/pass/ClearPassElement.hpp | 25 + src/render/pass/FramebufferElement.cpp | 48 ++ src/render/pass/FramebufferElement.hpp | 24 + src/render/pass/Pass.cpp | 157 ++++ src/render/pass/Pass.hpp | 36 + src/render/pass/PassElement.cpp | 17 + src/render/pass/PassElement.hpp | 18 + src/render/pass/PreBlurElement.cpp | 20 + src/render/pass/PreBlurElement.hpp | 17 + src/render/pass/RectPassElement.cpp | 29 + src/render/pass/RectPassElement.hpp | 29 + src/render/pass/ShadowPassElement.cpp | 19 + src/render/pass/ShadowPassElement.hpp | 26 + src/render/pass/SurfacePassElement.cpp | 230 +++++ src/render/pass/SurfacePassElement.hpp | 82 ++ src/render/pass/TexPassElement.cpp | 44 + src/render/pass/TexPassElement.hpp | 39 + src/render/pass/TextureMatteElement.cpp | 25 + src/render/pass/TextureMatteElement.hpp | 29 + 42 files changed, 1576 insertions(+), 775 deletions(-) create mode 100644 src/render/pass/BorderPassElement.cpp create mode 100644 src/render/pass/BorderPassElement.hpp create mode 100644 src/render/pass/ClearPassElement.cpp create mode 100644 src/render/pass/ClearPassElement.hpp create mode 100644 src/render/pass/FramebufferElement.cpp create mode 100644 src/render/pass/FramebufferElement.hpp create mode 100644 src/render/pass/Pass.cpp create mode 100644 src/render/pass/Pass.hpp create mode 100644 src/render/pass/PassElement.cpp create mode 100644 src/render/pass/PassElement.hpp create mode 100644 src/render/pass/PreBlurElement.cpp create mode 100644 src/render/pass/PreBlurElement.hpp create mode 100644 src/render/pass/RectPassElement.cpp create mode 100644 src/render/pass/RectPassElement.hpp create mode 100644 src/render/pass/ShadowPassElement.cpp create mode 100644 src/render/pass/ShadowPassElement.hpp create mode 100644 src/render/pass/SurfacePassElement.cpp create mode 100644 src/render/pass/SurfacePassElement.hpp create mode 100644 src/render/pass/TexPassElement.cpp create mode 100644 src/render/pass/TexPassElement.hpp create mode 100644 src/render/pass/TextureMatteElement.cpp create mode 100644 src/render/pass/TextureMatteElement.hpp diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 07421382..9b6e29e4 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -571,7 +571,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0}); m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1}); - m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{2}); + m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{1}); // TODO: remove this. I don't think it does us any good to disable intro. m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{2}); m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0}); @@ -612,6 +612,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("render:explicit_sync_kms", Hyprlang::INT{2}); m_pConfig->addConfigValue("render:direct_scanout", Hyprlang::INT{0}); m_pConfig->addConfigValue("render:expand_undersized_textures", Hyprlang::INT{1}); + m_pConfig->addConfigValue("render:xp_mode", Hyprlang::INT{0}); m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0}); diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index 7bcfad82..504ad6c9 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -3,6 +3,7 @@ #include "HyprNotificationOverlay.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../render/pass/TexPassElement.hpp" static inline auto iconBackendFromLayout(PangoLayout* layout) { // preference: Nerd > FontAwesome > text @@ -241,8 +242,12 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA); - CBox pMonBox = {0, 0, MONSIZE.x, MONSIZE.y}; - g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f); + CTexPassElement::SRenderData data; + data.tex = m_pTexture; + data.box = {0, 0, MONSIZE.x, MONSIZE.y}; + data.a = 1.F; + + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } bool CHyprNotificationOverlay::hasAny() { diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index bfa77a68..c8134219 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -210,7 +210,7 @@ void CLayerSurface::onUnmap() { } // make a snapshot and start fade - g_pHyprOpenGL->makeLayerSnapshot(self.lock()); + g_pHyprRenderer->makeLayerSnapshot(self.lock()); startAnimation(false); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 437301b7..c17c425b 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -680,7 +680,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { g_pCompositor->setWindowFullscreenInternal(PWINDOW, FSMODE_NONE); // Allow the renderer to catch the last frame. - g_pHyprOpenGL->makeWindowSnapshot(PWINDOW); + g_pHyprRenderer->makeWindowSnapshot(PWINDOW); // swallowing if (valid(PWINDOW->m_pSwallowed)) { diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 9f2836e7..0a6ef55d 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -17,47 +17,6 @@ class CWLSurfaceResource; AQUAMARINE_FORWARD(ISwitch); -struct SRenderData { - PHLMONITORREF pMonitor; - timespec* when; - double x, y; - - // for iters - void* data = nullptr; - SP surface = nullptr; - double w, h; - - // for rounding - bool dontRound = true; - - // for fade - float fadeAlpha = 1.f; - - // for alpha settings - float alpha = 1.f; - - // for decorations (border) - bool decorate = false; - - // for custom round values - int rounding = -1; // -1 means not set - - // for blurring - bool blur = false; - bool blockBlurOptimization = false; - - // only for windows, not popups - bool squishOversized = true; - - // for calculating UV - PHLWINDOW pWindow; - - bool popup = false; - - // counts how many surfaces this pass has rendered - int surfaceCounter = 0; -}; - struct SSwipeGesture { PHLWORKSPACE pWorkspaceBegin = nullptr; diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 74a3030c..d3cd8273 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -2,6 +2,7 @@ #include "HyprError.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../render/pass/TexPassElement.hpp" #include using namespace Hyprutils::Utils; @@ -206,7 +207,12 @@ void CHyprError::draw() { m_bMonitorChanged = false; - g_pHyprOpenGL->renderTexture(m_pTexture, &monbox, m_fFadeOpacity.value(), 0); + CTexPassElement::SRenderData data; + data.tex = m_pTexture; + data.box = monbox; + data.a = m_fFadeOpacity.value(); + + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } void CHyprError::destroy() { diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 3e3ece98..bc166825 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -8,6 +8,7 @@ #include "../protocols/core/Compositor.hpp" #include "../protocols/core/Seat.hpp" #include "eventLoop/EventLoopManager.hpp" +#include "../render/pass/TexPassElement.hpp" #include "SeatManager.hpp" #include #include @@ -551,7 +552,15 @@ void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* no box.x = std::round(box.x); box.y = std::round(box.y); - g_pHyprOpenGL->renderTextureWithDamage(texture, &box, &damage, 1.F, 0, false, false, currentCursorImage.waitTimeline, currentCursorImage.waitPoint); + CTexPassElement::SRenderData data; + data.tex = texture; + data.box = box.round(); + data.syncTimeline = currentCursorImage.waitTimeline; + data.syncPoint = currentCursorImage.waitPoint; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + + currentCursorImage.waitTimeline.reset(); + currentCursorImage.waitPoint = 0; if (currentCursorImage.surface) currentCursorImage.surface->resource()->frame(now); diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 89f2a4cb..ee1e6224 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -522,11 +522,14 @@ void CWLSurfaceResource::updateCursorShm(CRegion damage) { } } -void CWLSurfaceResource::presentFeedback(timespec* when, PHLMONITOR pMonitor) { +void CWLSurfaceResource::presentFeedback(timespec* when, PHLMONITOR pMonitor, bool discarded) { frame(when); auto FEEDBACK = makeShared(self.lock()); FEEDBACK->attachMonitor(pMonitor); - FEEDBACK->presented(); + if (discarded) + FEEDBACK->discarded(); + else + FEEDBACK->presented(); PROTO::presentation->queueData(FEEDBACK); if (!pMonitor || !pMonitor->outTimeline || !syncobj) diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index c036041a..2a6f96f6 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -124,7 +124,7 @@ class CWLSurfaceResource { void breadthfirst(std::function, const Vector2D&, void*)> fn, void* data); CRegion accumulateCurrentBufferDamage(); - void presentFeedback(timespec* when, PHLMONITOR pMonitor); + void presentFeedback(timespec* when, PHLMONITOR pMonitor, bool discarded = false); void lockPendingState(); void unlockPendingState(); diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index b4bb8b00..9fc49a44 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -4,6 +4,7 @@ #include "../../managers/PointerManager.hpp" #include "../../managers/eventLoop/EventLoopManager.hpp" #include "../../Compositor.hpp" +#include "../../render/pass/TexPassElement.hpp" #include "Seat.hpp" #include "Compositor.hpp" #include "../../xwayland/XWayland.hpp" @@ -794,7 +795,11 @@ void CWLDataDeviceProtocol::renderDND(PHLMONITOR pMonitor, timespec* when) { const auto POS = g_pInputManager->getMouseCoordsInternal(); CBox box = CBox{POS, dnd.dndSurface->current.size}.translate(-pMonitor->vecPosition + g_pPointerManager->cursorSizeLogical() / 2.F).scale(pMonitor->scale); - g_pHyprOpenGL->renderTexture(dnd.dndSurface->current.texture, &box, 1.F); + + CTexPassElement::SRenderData data; + data.tex = dnd.dndSurface->current.texture; + data.box = box; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); box = CBox{POS, dnd.dndSurface->current.size}.translate(g_pPointerManager->cursorSizeLogical() / 2.F).expand(5); g_pHyprRenderer->damageBox(&box); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 4339fd40..d9f19fea 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -8,6 +8,10 @@ #include "../desktop/LayerSurface.hpp" #include "../protocols/LayerShell.hpp" #include "../protocols/core/Compositor.hpp" +#include "pass/TexPassElement.hpp" +#include "pass/RectPassElement.hpp" +#include "pass/PreBlurElement.hpp" +#include "pass/ClearPassElement.hpp" #include #include #include @@ -584,7 +588,7 @@ GLuint CHyprOpenGLImpl::createProgram(const std::string& vert, const std::string if (fragCompiled == 0) return 0; } else { - RASSERT(fragCompiled, "Compiling shader failed. FRAGMENT nullptr! Shader source:\n\n{}", frag.c_str()); + RASSERT(fragCompiled, "Compiling shader failed. FRAGMENT nullptr! Shader source:\n\n{}", frag); } auto prog = glCreateProgram(); @@ -663,7 +667,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(PHLMONITOR pMonitor) { if (*PBLUR == 0) return false; - if (m_RenderData.pCurrentMonData->blurFBShouldRender) + if (preBlurQueued()) return true; if (!pMonitor->solitaryClient.expired()) @@ -1242,7 +1246,7 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h void CHyprOpenGLImpl::renderRect(CBox* box, const CHyprColor& col, int round) { if (!m_RenderData.damage.empty()) - renderRectWithDamage(box, col, &m_RenderData.damage, round); + renderRectWithDamage(box, col, m_RenderData.damage, round); } void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int round, float blurA, bool xray) { @@ -1278,7 +1282,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r m_bEndFrame = true; // fix transformed const auto SAVEDRENDERMODIF = m_RenderData.renderModif; m_RenderData.renderModif = {}; // fix shit - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, blurA, &damage, 0, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, blurA, damage, 0, false, false, false); m_bEndFrame = false; m_RenderData.renderModif = SAVEDRENDERMODIF; @@ -1289,10 +1293,10 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r glStencilFunc(GL_ALWAYS, 1, 0xFF); scissor((CBox*)nullptr); - renderRectWithDamage(box, col, &m_RenderData.damage, round); + renderRectWithDamage(box, col, m_RenderData.damage, round); } -void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, CRegion* damage, int round) { +void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, const CRegion& damage, 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()!"); @@ -1337,7 +1341,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, CRe if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height}; - damageClip.intersect(*damage); + damageClip.intersect(damage); if (!damageClip.empty()) { for (auto const& RECT : damageClip.getRects()) { @@ -1346,7 +1350,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, CRe } } } else { - for (auto const& RECT : damage->getRects()) { + for (auto const& RECT : damage.getRects()) { scissor(&RECT); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -1360,12 +1364,12 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, CRe void CHyprOpenGLImpl::renderTexture(SP tex, CBox* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, &m_RenderData.damage, round, discardActive, false, allowCustomUV, true); + renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.damage, round, discardActive, false, allowCustomUV, true); scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, CBox* pBox, CRegion* damage, float alpha, int round, bool discardActive, bool allowCustomUV, +void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, CBox* pBox, const CRegion& damage, float alpha, int round, bool discardActive, bool allowCustomUV, SP waitTimeline, uint64_t waitPoint) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); @@ -1374,8 +1378,8 @@ void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, CBox* pBox, CReg scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pBox, float alpha, CRegion* damage, int round, bool discardActive, bool noAA, bool allowCustomUV, - bool allowDim, SP waitTimeline, uint64_t waitPoint) { +void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pBox, float alpha, const CRegion& damage, int round, bool discardActive, bool noAA, + bool allowCustomUV, bool allowDim, SP waitTimeline, uint64_t waitPoint) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex->m_iTexID > 0), "Attempted to draw nullptr texture!"); @@ -1383,7 +1387,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB alpha = std::clamp(alpha, 0.f, 1.f); - if (damage->empty()) + if (damage.empty()) return; CBox newBox = *pBox; @@ -1433,7 +1437,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB } } - if (m_pCurrentWindow.lock() && m_pCurrentWindow->m_sWindowData.RGBX.valueOrDefault()) + if (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.RGBX.valueOrDefault()) shader = &m_RenderData.pCurrentMonData->m_shRGBX; glActiveTexture(GL_TEXTURE0); @@ -1503,9 +1507,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y); glUniform1f(shader->radius, round); - if (allowDim && m_pCurrentWindow.lock()) { + if (allowDim && m_RenderData.currentWindow) { glUniform1i(shader->applyTint, 1); - const auto DIM = m_pCurrentWindow->m_fDimPercent.value(); + const auto DIM = m_RenderData.currentWindow->m_fDimPercent.value(); glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); } else { glUniform1i(shader->applyTint, 0); @@ -1532,7 +1536,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height}; - damageClip.intersect(*damage); + damageClip.intersect(damage); if (!damageClip.empty()) { for (auto const& RECT : damageClip.getRects()) { @@ -1541,7 +1545,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB } } } else { - for (auto const& RECT : damage->getRects()) { + for (auto const& RECT : damage.getRects()) { scissor(&RECT); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -1993,7 +1997,7 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() { clear(CHyprColor(0, 0, 0, 0)); m_bEndFrame = true; // fix transformed - renderTextureInternalWithDamage(POUTFB->getTexture(), &wholeMonitor, 1, &fakeDamage, 0, false, true, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &wholeMonitor, 1, fakeDamage, 0, false, true, false); m_bEndFrame = false; m_RenderData.currentFB->bind(); @@ -2009,15 +2013,14 @@ void CHyprOpenGLImpl::preWindowPass() { if (!preBlurQueued()) return; - // blur the main FB, it will be rendered onto the mirror - preBlurForCurrentMonitor(); + g_pHyprRenderer->m_sRenderPass.add(makeShared()); } bool CHyprOpenGLImpl::preBlurQueued() { static auto PBLURNEWOPTIMIZE = CConfigValue("decoration:blur:new_optimizations"); static auto PBLUR = CConfigValue("decoration:blur:enabled"); - return !(!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE || !*PBLUR || !m_RenderData.pCurrentMonData->blurFBShouldRender); + return m_RenderData.pCurrentMonData->blurFBDirty && *PBLURNEWOPTIMIZE && *PBLUR && m_RenderData.pCurrentMonData->blurFBShouldRender; } bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow) { @@ -2082,7 +2085,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float inverseOpaque.scale(m_RenderData.pMonitor->scale); // vvv TODO: layered blur fbs? - const bool USENEWOPTIMIZE = shouldUseNewBlurOptimizations(m_pCurrentLayer, m_pCurrentWindow.lock()) && !blockBlurOptimization; + const bool USENEWOPTIMIZE = shouldUseNewBlurOptimizations(m_RenderData.currentLS.lock(), m_RenderData.currentWindow.lock()) && !blockBlurOptimization; CFramebuffer* POUTFB = nullptr; if (!USENEWOPTIMIZE) { @@ -2091,9 +2094,8 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float inverseOpaque.intersect(texDamage); POUTFB = blurMainFramebufferWithDamage(a, &inverseOpaque); - } else { + } else POUTFB = &m_RenderData.pCurrentMonData->blurFB; - } m_RenderData.currentFB->bind(); @@ -2124,7 +2126,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float setMonitorTransformEnabled(true); if (!USENEWOPTIMIZE) setRenderModifEnabled(false); - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, &texDamage, 0, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, texDamage, 0, false, false, false); if (!USENEWOPTIMIZE) setRenderModifEnabled(true); setMonitorTransformEnabled(false); @@ -2135,7 +2137,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float // draw window glDisable(GL_STENCIL_TEST); - renderTextureInternalWithDamage(tex, pBox, a, &texDamage, round, false, false, true, true); + renderTextureInternalWithDamage(tex, pBox, a, texDamage, round, false, false, true, true); glStencilMask(0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF); @@ -2148,7 +2150,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in TRACY_GPU_ZONE("RenderBorder"); - if (m_RenderData.damage.empty() || (m_pCurrentWindow.lock() && m_pCurrentWindow->m_sWindowData.noBorder.valueOrDefault())) + if (m_RenderData.damage.empty() || (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.noBorder.valueOrDefault())) return; CBox newBox = *box; @@ -2241,7 +2243,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c TRACY_GPU_ZONE("RenderBorder2"); - if (m_RenderData.damage.empty() || (m_pCurrentWindow.lock() && m_pCurrentWindow->m_sWindowData.noBorder.valueOrDefault())) + if (m_RenderData.damage.empty() || (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.noBorder.valueOrDefault())) return; CBox newBox = *box; @@ -2332,225 +2334,10 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c blend(BLEND); } -void CHyprOpenGLImpl::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFramebuffer) { - // we trust the window is valid. - const auto PMONITOR = pWindow->m_pMonitor.lock(); - - if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) - return; - - // we need to "damage" the entire monitor - // so that we render the entire window - // this is temporary, doesnt mess with the actual damage - CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; - - g_pHyprRenderer->makeEGLCurrent(); - - pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); - pFramebuffer->addStencil(m_RenderData.pCurrentMonData->stencilTex); - - g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, pFramebuffer); - - clear(CHyprColor(0, 0, 0, 0)); // JIC - - timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - - // this is a hack but it works :P - // we need to disable blur or else we will get a black background, as the shader - // will try to copy the bg to apply blur. - // this isn't entirely correct, but like, oh well. - // small todo: maybe make this correct? :P - static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")); - const auto BLURVAL = **PBLUR; - **PBLUR = 0; - - // TODO: how can we make this the size of the window? setting it to window's size makes the entire screen render with the wrong res forever more. odd. - glViewport(0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); - - m_RenderData.currentFB = pFramebuffer; - - clear(CHyprColor(0, 0, 0, 0)); // JIC - - g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, false, RENDER_PASS_ALL, true); - - **PBLUR = BLURVAL; - - g_pHyprRenderer->endRender(); -} - -void CHyprOpenGLImpl::makeWindowSnapshot(PHLWINDOW pWindow) { - // we trust the window is valid. - const auto PMONITOR = pWindow->m_pMonitor.lock(); - - if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) - return; - - if (!g_pHyprRenderer->shouldRenderWindow(pWindow)) - return; // ignore, window is not being rendered - - // we need to "damage" the entire monitor - // so that we render the entire window - // this is temporary, doesnt mess with the actual damage - CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; - - PHLWINDOWREF ref{pWindow}; - - g_pHyprRenderer->makeEGLCurrent(); - - const auto PFRAMEBUFFER = &m_mWindowFramebuffers[ref]; - - PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); - - g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER); - - g_pHyprRenderer->m_bRenderingSnapshot = true; - - clear(CHyprColor(0, 0, 0, 0)); // JIC - - timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - - // this is a hack but it works :P - // we need to disable blur or else we will get a black background, as the shader - // will try to copy the bg to apply blur. - // this isn't entirely correct, but like, oh well. - // small todo: maybe make this correct? :P - static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")); - const auto BLURVAL = **PBLUR; - **PBLUR = 0; - - clear(CHyprColor(0, 0, 0, 0)); // JIC - - g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL); - - **PBLUR = BLURVAL; - - g_pHyprRenderer->endRender(); - - g_pHyprRenderer->m_bRenderingSnapshot = false; -} - -void CHyprOpenGLImpl::makeLayerSnapshot(PHLLS pLayer) { - // we trust the window is valid. - const auto PMONITOR = pLayer->monitor.lock(); - - if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) - return; - - // we need to "damage" the entire monitor - // so that we render the entire window - // this is temporary, doesnt mess with the actual damage - CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; - - g_pHyprRenderer->makeEGLCurrent(); - - const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer]; - - PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); - - g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER); - - g_pHyprRenderer->m_bRenderingSnapshot = true; - - clear(CHyprColor(0, 0, 0, 0)); // JIC - - timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - - const auto BLURLSSTATUS = pLayer->forceBlur; - pLayer->forceBlur = false; - - // draw the layer - g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now); - - pLayer->forceBlur = BLURLSSTATUS; - - g_pHyprRenderer->endRender(); - - g_pHyprRenderer->m_bRenderingSnapshot = false; -} - -void CHyprOpenGLImpl::renderSnapshot(PHLWINDOW pWindow) { - RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!"); - - static auto PDIMAROUND = CConfigValue("decoration:dim_around"); - - PHLWINDOWREF ref{pWindow}; - - if (!m_mWindowFramebuffers.contains(ref)) - return; - - const auto FBDATA = &m_mWindowFramebuffers.at(ref); - - if (!FBDATA->getTexture()) - return; - - const auto PMONITOR = pWindow->m_pMonitor.lock(); - - CBox windowBox; - // some mafs to figure out the correct box - // the originalClosedPos is relative to the monitor's pos - Vector2D scaleXY = Vector2D((PMONITOR->scale * pWindow->m_vRealSize.value().x / (pWindow->m_vOriginalClosedSize.x * PMONITOR->scale)), - (PMONITOR->scale * pWindow->m_vRealSize.value().y / (pWindow->m_vOriginalClosedSize.y * PMONITOR->scale))); - - windowBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; - windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; - windowBox.x = ((pWindow->m_vRealPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x); - windowBox.y = ((pWindow->m_vRealPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y); - - CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; - - if (*PDIMAROUND && pWindow->m_sWindowData.dimAround.valueOrDefault()) { - CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y}; - g_pHyprOpenGL->renderRect(&monbox, CHyprColor(0, 0, 0, *PDIMAROUND * pWindow->m_fAlpha.value())); - g_pHyprRenderer->damageMonitor(PMONITOR); - } - - m_bEndFrame = true; - - renderTextureInternalWithDamage(FBDATA->getTexture(), &windowBox, pWindow->m_fAlpha.value(), &fakeDamage, 0); - - m_bEndFrame = false; -} - -void CHyprOpenGLImpl::renderSnapshot(PHLLS pLayer) { - RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!"); - - if (!m_mLayerFramebuffers.contains(pLayer)) - return; - - const auto FBDATA = &m_mLayerFramebuffers.at(pLayer); - - if (!FBDATA->getTexture()) - return; - - const auto PMONITOR = pLayer->monitor.lock(); - - CBox layerBox; - // some mafs to figure out the correct box - // the originalClosedPos is relative to the monitor's pos - Vector2D scaleXY = Vector2D((PMONITOR->scale * pLayer->realSize.value().x / (pLayer->geometry.w * PMONITOR->scale)), - (PMONITOR->scale * pLayer->realSize.value().y / (pLayer->geometry.h * PMONITOR->scale))); - - layerBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; - layerBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; - layerBox.x = ((pLayer->realPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((pLayer->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x); - layerBox.y = ((pLayer->realPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((pLayer->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y); - - CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; - - m_bEndFrame = true; - - renderTextureInternalWithDamage(FBDATA->getTexture(), &layerBox, pLayer->alpha.value(), &fakeDamage, 0); - - m_bEndFrame = false; -} - void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const CHyprColor& color, float a) { RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!"); RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!"); - RASSERT(m_pCurrentWindow.lock(), "Tried to render shadow without a window!"); + RASSERT(m_RenderData.currentWindow, "Tried to render shadow without a window!"); if (m_RenderData.damage.empty()) return; @@ -2642,11 +2429,11 @@ void CHyprOpenGLImpl::saveBufferForMirror(CBox* box) { void CHyprOpenGLImpl::renderMirrored() { - auto monitor = m_RenderData.pMonitor; - auto mirrored = monitor->pMirrorOf; + auto monitor = m_RenderData.pMonitor; + auto mirrored = monitor->pMirrorOf; - double scale = std::min(monitor->vecTransformedSize.x / mirrored->vecTransformedSize.x, monitor->vecTransformedSize.y / mirrored->vecTransformedSize.y); - CBox monbox = {0, 0, mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale}; + const double scale = std::min(monitor->vecTransformedSize.x / mirrored->vecTransformedSize.x, monitor->vecTransformedSize.y / mirrored->vecTransformedSize.y); + CBox monbox = {0, 0, mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale}; // transform box as it will be drawn on a transformed projection monbox.transform(wlTransformToHyprutils(mirrored->transform), mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale); @@ -2658,20 +2445,18 @@ void CHyprOpenGLImpl::renderMirrored() { if (!PFB->isAllocated() || !PFB->getTexture()) return; - // replace monitor projection to undo the mirrored monitor's projection - m_RenderData.monitorProjection = Mat3x3::identity() - .translate(monitor->vecPixelSize / 2.0) - .transform(wlTransformToHyprutils(monitor->transform)) - .transform(wlTransformToHyprutils(invertTransform(mirrored->transform))) - .translate(-monitor->vecTransformedSize / 2.0); + g_pHyprRenderer->m_sRenderPass.add(makeShared(CClearPassElement::SClearData{CHyprColor(0, 0, 0, 0)})); - // clear stuff outside of mirrored area (e.g. when changing to mirrored) - clear(CHyprColor(0, 0, 0, 0)); + CTexPassElement::SRenderData data; + data.tex = PFB->getTexture(); + data.box = monbox; + data.replaceProjection = Mat3x3::identity() + .translate(monitor->vecPixelSize / 2.0) + .transform(wlTransformToHyprutils(monitor->transform)) + .transform(wlTransformToHyprutils(invertTransform(mirrored->transform))) + .translate(-monitor->vecTransformedSize / 2.0); - renderTexture(PFB->getTexture(), &monbox, 1.f, 0, false, false); - - // reset matrix for further drawing - m_RenderData.monitorProjection = monitor->projMatrix; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY, const Vector2D& size) { @@ -3005,11 +2790,11 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) { } CBox texbox = CBox{origin, m_pBackgroundTexture->m_vSize * scale}; - renderTextureInternalWithDamage(m_pBackgroundTexture, &texbox, 1.0, &fakeDamage); + renderTextureInternalWithDamage(m_pBackgroundTexture, &texbox, 1.0, fakeDamage); } CBox monbox = {{}, pMonitor->vecPixelSize}; - renderTextureInternalWithDamage(tex, &monbox, 1.0, &fakeDamage); + renderTextureInternalWithDamage(tex, &monbox, 1.0, fakeDamage); // bind back if (m_RenderData.currentFB) @@ -3021,8 +2806,6 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) { void CHyprOpenGLImpl::clearWithTex() { RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!"); - TRACY_GPU_ZONE("RenderClearWithTex"); - auto TEXIT = m_mMonitorBGFBs.find(m_RenderData.pMonitor); if (TEXIT == m_mMonitorBGFBs.end()) { @@ -3031,10 +2814,11 @@ void CHyprOpenGLImpl::clearWithTex() { } if (TEXIT != m_mMonitorBGFBs.end()) { - CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - m_bEndFrame = true; - renderTexture(TEXIT->second.getTexture(), &monbox, 1); - m_bEndFrame = false; + CTexPassElement::SRenderData data; + data.box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; + data.flipEndFrame = true; + data.tex = TEXIT->second.getTexture(); + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } } diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 51f38708..0b72d438 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -19,6 +19,7 @@ #include "Framebuffer.hpp" #include "Transformer.hpp" #include "Renderbuffer.hpp" +#include "pass/Pass.hpp" #include #include @@ -61,17 +62,31 @@ struct SRenderModifData { bool enabled = true; }; +enum eMonitorRenderFBs : uint8_t { + FB_MONITOR_RENDER_MAIN = 0, + FB_MONITOR_RENDER_CURRENT = 1, + FB_MONITOR_RENDER_OUT = 2, +}; + +enum eMonitorExtraRenderFBs : uint8_t { + FB_MONITOR_RENDER_EXTRA_OFFLOAD = 0, + FB_MONITOR_RENDER_EXTRA_MIRROR, + FB_MONITOR_RENDER_EXTRA_MIRROR_SWAP, + FB_MONITOR_RENDER_EXTRA_OFF_MAIN, + FB_MONITOR_RENDER_EXTRA_MONITOR_MIRROR, + FB_MONITOR_RENDER_EXTRA_BLUR, +}; + struct SMonitorRenderData { CFramebuffer offloadFB; CFramebuffer mirrorFB; // these are used for some effects, CFramebuffer mirrorSwapFB; // etc CFramebuffer offMainFB; - CFramebuffer monitorMirrorFB; // used for mirroring outputs, does not contain artifacts like offloadFB + CFramebuffer blurFB; SP stencilTex = makeShared(); - CFramebuffer blurFB; bool blurFBDirty = true; bool blurFBShouldRender = false; @@ -123,6 +138,9 @@ struct SCurrentRenderData { uint32_t discardMode = DISCARD_OPAQUE; float discardOpacity = 0.f; + + PHLLSREF currentLS; + PHLWINDOWREF currentWindow; }; class CEGLSync { @@ -155,9 +173,9 @@ class CHyprOpenGLImpl { void renderRect(CBox*, const CHyprColor&, int round = 0); void renderRectWithBlur(CBox*, const CHyprColor&, int round = 0, float blurA = 1.f, bool xray = false); - void renderRectWithDamage(CBox*, const CHyprColor&, CRegion* damage, int round = 0); + void renderRectWithDamage(CBox*, const CHyprColor&, const CRegion& damage, int round = 0); void renderTexture(SP, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); - void renderTextureWithDamage(SP, CBox*, CRegion* damage, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false, + void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false, SP waitTimeline = nullptr, uint64_t waitPoint = 0); void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f); void renderRoundedShadow(CBox*, int round, int range, const CHyprColor& color, float a = 1.0); @@ -174,11 +192,6 @@ class CHyprOpenGLImpl { void blend(bool enabled); - void makeWindowSnapshot(PHLWINDOW); - void makeRawWindowSnapshot(PHLWINDOW, CFramebuffer*); - void makeLayerSnapshot(PHLLS); - void renderSnapshot(PHLWINDOW); - void renderSnapshot(PHLLS); bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); void clear(const CHyprColor&); @@ -225,9 +238,6 @@ class CHyprOpenGLImpl { bool m_bReloadScreenShader = true; // at launch it can be set - PHLWINDOWREF m_pCurrentWindow; // hack to get the current rendered window - PHLLS m_pCurrentLayer; // hack to get the current rendered layer - std::map m_mWindowFramebuffers; std::map m_mLayerFramebuffers; std::map m_mMonitorRenderResources; @@ -300,7 +310,7 @@ class CHyprOpenGLImpl { // returns the out FB, can be either Mirror or MirrorSwap CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage); - void renderTextureInternalWithDamage(SP, CBox* pBox, float a, CRegion* damage, int round = 0, bool discardOpaque = false, bool noAA = false, + void renderTextureInternalWithDamage(SP, CBox* pBox, float a, const CRegion& damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false, bool allowDim = false, SP = nullptr, uint64_t waitPoint = 0); void renderTexturePrimitive(SP tex, CBox* pBox); void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size); @@ -310,6 +320,9 @@ class CHyprOpenGLImpl { bool passRequiresIntrospection(PHLMONITOR pMonitor); friend class CHyprRenderer; + friend class CTexPassElement; + friend class CPreBlurElement; + friend class CSurfacePassElement; }; inline std::unique_ptr g_pHyprOpenGL; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index c873842b..0f8db3bb 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -20,6 +20,10 @@ #include "../protocols/DRMSyncobj.hpp" #include "../protocols/LinuxDMABUF.hpp" #include "../helpers/sync/SyncTimeline.hpp" +#include "pass/TexPassElement.hpp" +#include "pass/ClearPassElement.hpp" +#include "pass/RectPassElement.hpp" +#include "pass/SurfacePassElement.hpp" #include "debug/Log.hpp" #include @@ -154,148 +158,6 @@ CHyprRenderer::~CHyprRenderer() { wl_event_source_remove(m_pCursorTicker); } -static void renderSurface(SP surface, int x, int y, void* data) { - if (!surface->current.texture) - return; - - const auto& TEXTURE = surface->current.texture; - - // this is bad, probably has been logged elsewhere. Means the texture failed - // uploading to the GPU. - if (!TEXTURE->m_iTexID) - return; - - // explicit sync: wait for the timeline, if any - if (surface->syncobj && surface->syncobj->current.acquireTimeline) { - if (!g_pHyprOpenGL->waitForTimelinePoint(surface->syncobj->current.acquireTimeline->timeline, surface->syncobj->current.acquirePoint)) { - Debug::log(ERR, "Renderer: failed to wait for explicit timeline"); - return; - } - } - - const auto RDATA = (SRenderData*)data; - const auto INTERACTIVERESIZEINPROGRESS = RDATA->pWindow && g_pInputManager->currentlyDraggedWindow && g_pInputManager->dragMode == MBIND_RESIZE; - TRACY_GPU_ZONE("RenderSurface"); - - double outputX = -RDATA->pMonitor->vecPosition.x, outputY = -RDATA->pMonitor->vecPosition.y; - - auto PSURFACE = CWLSurface::fromResource(surface); - - const float ALPHA = RDATA->alpha * RDATA->fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); - const bool BLUR = RDATA->blur && (!TEXTURE->m_bOpaque || ALPHA < 1.F); - - CBox windowBox; - if (RDATA->surface && surface == RDATA->surface) { - windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h}; - - // however, if surface buffer w / h < box, we need to adjust them - const auto PWINDOW = PSURFACE ? PSURFACE->getWindow() : nullptr; - - // center the surface if it's smaller than the viewport we assign it - if (PSURFACE && !PSURFACE->m_bFillIgnoreSmall && PSURFACE->small() /* guarantees PWINDOW */) { - const auto CORRECT = PSURFACE->correctSmallVec(); - const auto SIZE = PSURFACE->getViewporterCorrectedSize(); - - if (!INTERACTIVERESIZEINPROGRESS) { - windowBox.translate(CORRECT); - - windowBox.width = SIZE.x * (PWINDOW->m_vRealSize.value().x / PWINDOW->m_vReportedSize.x); - windowBox.height = SIZE.y * (PWINDOW->m_vRealSize.value().y / PWINDOW->m_vReportedSize.y); - } else { - windowBox.width = SIZE.x; - windowBox.height = SIZE.y; - } - } - - } else { // here we clamp to 2, these might be some tiny specks - windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::max((float)surface->current.size.x, 2.F), std::max((float)surface->current.size.y, 2.F)}; - if (RDATA->pWindow && RDATA->pWindow->m_vRealSize.isBeingAnimated() && RDATA->surface && RDATA->surface != surface && RDATA->squishOversized /* subsurface */) { - // adjust subsurfaces to the window - windowBox.width = (windowBox.width / RDATA->pWindow->m_vReportedSize.x) * RDATA->pWindow->m_vRealSize.value().x; - windowBox.height = (windowBox.height / RDATA->pWindow->m_vReportedSize.y) * RDATA->pWindow->m_vRealSize.value().y; - } - } - - if (RDATA->squishOversized) { - if (x + windowBox.width > RDATA->w) - windowBox.width = RDATA->w - x; - if (y + windowBox.height > RDATA->h) - windowBox.height = RDATA->h - y; - } - - const auto PROJSIZEUNSCALED = windowBox.size(); - - windowBox.scale(RDATA->pMonitor->scale); - windowBox.round(); - - if (windowBox.width <= 1 || windowBox.height <= 1) { - if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) { - Debug::log(TRACE, "presentFeedback for invisible surface"); - surface->presentFeedback(RDATA->when, RDATA->pMonitor->self.lock()); - } - - return; // invisible - } - - const bool MISALIGNEDFSV1 = std::floor(RDATA->pMonitor->scale) != RDATA->pMonitor->scale /* Fractional */ && surface->current.scale == 1 /* fs protocol */ && - windowBox.size() != surface->current.bufferSize /* misaligned */ && DELTALESSTHAN(windowBox.width, surface->current.bufferSize.x, 3) && - DELTALESSTHAN(windowBox.height, surface->current.bufferSize.y, 3) /* off by one-or-two */ && - (!RDATA->pWindow || (!RDATA->pWindow->m_vRealSize.isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */; - - g_pHyprRenderer->calculateUVForSurface(RDATA->pWindow, surface, RDATA->pMonitor->self.lock(), RDATA->surface == surface, windowBox.size(), PROJSIZEUNSCALED, MISALIGNEDFSV1); - - // check for fractional scale surfaces misaligning the buffer size - // in those cases it's better to just force nearest neighbor - // as long as the window is not animated. During those it'd look weird. - // UV will fixup it as well - const auto NEARESTNEIGHBORSET = g_pHyprOpenGL->m_RenderData.useNearestNeighbor; - if (MISALIGNEDFSV1) - g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; - - float rounding = RDATA->rounding; - - rounding -= 1; // to fix a border issue - - if (RDATA->dontRound) - rounding = 0; - - const bool WINDOWOPAQUE = RDATA->pWindow && RDATA->pWindow->m_pWLSurface->resource() == surface ? RDATA->pWindow->opaque() : false; - const bool CANDISABLEBLEND = ALPHA >= 1.f && rounding == 0 && WINDOWOPAQUE; - - if (CANDISABLEBLEND) - g_pHyprOpenGL->blend(false); - else - g_pHyprOpenGL->blend(true); - - // FIXME: This is wrong and will bug the blur out as shit if the first surface - // is a subsurface that does NOT cover the entire frame. In such cases, we probably should fall back - // to what we do for misaligned surfaces (blur the entire thing and then render shit without blur) - if (RDATA->surfaceCounter == 0 && !RDATA->popup) { - if (BLUR) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, surface, rounding, RDATA->blockBlurOptimization, RDATA->fadeAlpha); - else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA, rounding, false, true); - } else { - if (BLUR && RDATA->popup) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, surface, rounding, true, RDATA->fadeAlpha); - else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA, rounding, false, true); - } - - if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) - surface->presentFeedback(RDATA->when, RDATA->pMonitor->self.lock()); - - g_pHyprOpenGL->blend(true); - - // reset props - g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); - g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); - g_pHyprOpenGL->m_RenderData.useNearestNeighbor = NEARESTNEIGHBORSET; - - // up the counter so that we dont blur any surfaces above this one - RDATA->surfaceCounter++; -} - bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor) { if (!pWindow->visibleOnMonitor(pMonitor)) return false; @@ -495,7 +357,7 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo if (!shouldRenderWindow(w, pMonitor)) continue; - windows.push_back(w); + windows.emplace_back(w); } // Non-floating main @@ -560,7 +422,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe if (pWindow->m_bFadingOut) { if (pMonitor == pWindow->m_pMonitor) // TODO: fix this - g_pHyprOpenGL->renderSnapshot(pWindow); + renderSnapshot(pWindow); return; } @@ -569,22 +431,22 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe TRACY_GPU_ZONE("RenderWindow"); - const auto PWORKSPACE = pWindow->m_pWorkspace; - const auto REALPOS = pWindow->m_vRealPosition.value() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.value()); - static auto PDIMAROUND = CConfigValue("decoration:dim_around"); - static auto PBLUR = CConfigValue("decoration:blur:enabled"); + const auto PWORKSPACE = pWindow->m_pWorkspace; + const auto REALPOS = pWindow->m_vRealPosition.value() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.value()); + static auto PDIMAROUND = CConfigValue("decoration:dim_around"); + static auto PBLUR = CConfigValue("decoration:blur:enabled"); - SRenderData renderdata = {pMonitor, time}; - CBox textureBox = {REALPOS.x, REALPOS.y, std::max(pWindow->m_vRealSize.value().x, 5.0), std::max(pWindow->m_vRealSize.value().y, 5.0)}; + CSurfacePassElement::SRenderData renderdata = {pMonitor, time}; + CBox textureBox = {REALPOS.x, REALPOS.y, std::max(pWindow->m_vRealSize.value().x, 5.0), std::max(pWindow->m_vRealSize.value().y, 5.0)}; - renderdata.x = textureBox.x; - renderdata.y = textureBox.y; - renderdata.w = textureBox.w; - renderdata.h = textureBox.h; + renderdata.pos.x = textureBox.x; + renderdata.pos.y = textureBox.y; + renderdata.w = textureBox.w; + renderdata.h = textureBox.h; if (ignorePosition) { - renderdata.x = pMonitor->vecPosition.x; - renderdata.y = pMonitor->vecPosition.y; + renderdata.pos.x = pMonitor->vecPosition.x; + renderdata.pos.y = pMonitor->vecPosition.y; } if (ignoreAllGeometry) @@ -613,23 +475,26 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe if (pWindow->m_sWindowData.opaque.valueOrDefault()) renderdata.alpha = 1.f; - g_pHyprOpenGL->m_pCurrentWindow = pWindow; + renderdata.pWindow = pWindow; EMIT_HOOK_EVENT("render", RENDER_PRE_WINDOW); if (*PDIMAROUND && pWindow->m_sWindowData.dimAround.valueOrDefault() && !m_bRenderingSnapshot && mode != RENDER_PASS_POPUP) { - CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y}; - g_pHyprOpenGL->renderRect(&monbox, CHyprColor(0, 0, 0, *PDIMAROUND * renderdata.alpha * renderdata.fadeAlpha)); + CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y}; + CRectPassElement::SRectData data; + data.color = CHyprColor(0, 0, 0, *PDIMAROUND * renderdata.alpha * renderdata.fadeAlpha); + data.box = monbox; + m_sRenderPass.add(makeShared(data)); } - renderdata.x += pWindow->m_vFloatingOffset.x; - renderdata.y += pWindow->m_vFloatingOffset.y; + renderdata.pos.x += pWindow->m_vFloatingOffset.x; + renderdata.pos.y += pWindow->m_vFloatingOffset.y; // if window is floating and we have a slide animation, clip it to its full bb if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->isFullscreen() && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) { CRegion rg = pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value() + pWindow->m_vFloatingOffset).scale(pMonitor->scale); - g_pHyprOpenGL->m_RenderData.clipBox = rg.getExtents(); + renderdata.clipBox = rg.getExtents(); } // render window decorations first, if not fullscreen full @@ -663,19 +528,32 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe static auto PXWLUSENN = CConfigValue("xwayland:use_nearest_neighbor"); if ((pWindow->m_bIsX11 && *PXWLUSENN) || pWindow->m_sWindowData.nearestNeighbor.valueOrDefault()) - g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; + renderdata.useNearestNeighbor = true; if (!pWindow->m_sWindowData.noBlur.valueOrDefault() && pWindow->m_pWLSurface->small() && !pWindow->m_pWLSurface->m_bFillIgnoreSmall && renderdata.blur && *PBLUR) { - CBox wb = {renderdata.x - pMonitor->vecPosition.x, renderdata.y - pMonitor->vecPosition.y, renderdata.w, renderdata.h}; + CBox wb = {renderdata.pos.x - pMonitor->vecPosition.x, renderdata.pos.y - pMonitor->vecPosition.y, renderdata.w, renderdata.h}; wb.scale(pMonitor->scale).round(); - g_pHyprOpenGL->renderRectWithBlur(&wb, CHyprColor(0, 0, 0, 0), renderdata.dontRound ? 0 : renderdata.rounding - 1, renderdata.fadeAlpha, - g_pHyprOpenGL->shouldUseNewBlurOptimizations(nullptr, pWindow)); + CRectPassElement::SRectData data; + data.color = CHyprColor(0, 0, 0, 0); + data.box = wb; + data.round = renderdata.dontRound ? 0 : renderdata.rounding - 1; + data.blurA = renderdata.fadeAlpha; + data.xray = g_pHyprOpenGL->shouldUseNewBlurOptimizations(nullptr, pWindow); + m_sRenderPass.add(makeShared(data)); renderdata.blur = false; } renderdata.surfaceCounter = 0; - pWindow->m_pWLSurface->resource()->breadthfirst([](SP s, const Vector2D& offset, void* data) { renderSurface(s, offset.x, offset.y, data); }, - &renderdata); + pWindow->m_pWLSurface->resource()->breadthfirst( + [this, &renderdata, &pWindow](SP s, const Vector2D& offset, void* data) { + renderdata.localPos = offset; + renderdata.texture = s->current.texture; + renderdata.surface = s; + renderdata.mainSurface = s == pWindow->m_pWLSurface->resource(); + m_sRenderPass.add(makeShared(renderdata)); + renderdata.surfaceCounter++; + }, + nullptr); g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; @@ -689,7 +567,6 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe } if (TRANSFORMERSPRESENT) { - CFramebuffer* last = g_pHyprOpenGL->m_RenderData.currentFB; for (auto const& t : pWindow->m_vTransformers) { last = t->transform(last); @@ -706,9 +583,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe if (!pWindow->m_bIsX11) { CBox geom = pWindow->m_pXDGSurface->current.geometry; - renderdata.x -= geom.x; - renderdata.y -= geom.y; - + renderdata.pos -= geom.pos(); renderdata.dontRound = true; // don't round popups renderdata.pMonitor = pMonitor; renderdata.squishOversized = false; // don't squish popups @@ -719,41 +594,38 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.blur = *PBLURPOPUPS && *PBLUR; - const auto DM = g_pHyprOpenGL->m_RenderData.discardMode; - const auto DA = g_pHyprOpenGL->m_RenderData.discardOpacity; - if (renderdata.blur) { - g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; - g_pHyprOpenGL->m_RenderData.discardOpacity = *PBLURIGNOREA; + renderdata.discardMode |= DISCARD_ALPHA; + renderdata.discardOpacity = *PBLURIGNOREA; } if (pWindow->m_sWindowData.nearestNeighbor.valueOrDefault()) - g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; + renderdata.useNearestNeighbor = true; renderdata.surfaceCounter = 0; pWindow->m_pPopupHead->breadthfirst( - [](CPopup* popup, void* data) { + [this, &renderdata](CPopup* popup, void* data) { if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource() || !popup->m_bMapped) return; const auto pos = popup->coordsRelativeToParent(); - auto rd = (SRenderData*)data; - const Vector2D oldPos = {rd->x, rd->y}; - rd->x += pos.x; - rd->y += pos.y; + const Vector2D oldPos = renderdata.pos; + renderdata.pos += pos; - popup->m_pWLSurface->resource()->breadthfirst([](SP s, const Vector2D& offset, void* data) { renderSurface(s, offset.x, offset.y, data); }, - data); + popup->m_pWLSurface->resource()->breadthfirst( + [this, &renderdata](SP s, const Vector2D& offset, void* data) { + renderdata.localPos = offset; + renderdata.texture = s->current.texture; + renderdata.surface = s; + renderdata.mainSurface = false; + m_sRenderPass.add(makeShared(renderdata)); + renderdata.surfaceCounter++; + }, + data); - rd->x = oldPos.x; - rd->y = oldPos.y; + renderdata.pos = oldPos; }, &renderdata); - - g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; - - g_pHyprOpenGL->m_RenderData.discardMode = DM; - g_pHyprOpenGL->m_RenderData.discardOpacity = DA; } if (decorate) { @@ -767,9 +639,6 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe } EMIT_HOOK_EVENT("render", RENDER_POST_WINDOW); - - g_pHyprOpenGL->m_pCurrentWindow.reset(); - g_pHyprOpenGL->m_RenderData.clipBox = CBox(); } void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* time, bool popups) { @@ -779,13 +648,15 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim static auto PDIMAROUND = CConfigValue("decoration:dim_around"); if (*PDIMAROUND && pLayer->dimAround && !m_bRenderingSnapshot && !popups) { - CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y}; - g_pHyprOpenGL->renderRect(&monbox, CHyprColor(0, 0, 0, *PDIMAROUND * pLayer->alpha.value())); + CRectPassElement::SRectData data; + data.box = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y}; + data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pLayer->alpha.value()); + m_sRenderPass.add(makeShared(data)); } if (pLayer->fadingOut) { if (!popups) - g_pHyprOpenGL->renderSnapshot(pLayer); + renderSnapshot(pLayer); return; } @@ -793,32 +664,37 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim TRACY_GPU_ZONE("RenderLayer"); - const auto REALPOS = pLayer->realPosition.value(); - const auto REALSIZ = pLayer->realSize.value(); + const auto REALPOS = pLayer->realPosition.value(); + const auto REALSIZ = pLayer->realSize.value(); - SRenderData renderdata = {pMonitor, time, REALPOS.x, REALPOS.y}; - renderdata.fadeAlpha = pLayer->alpha.value(); - renderdata.blur = pLayer->forceBlur && *PBLUR; - renderdata.surface = pLayer->surface->resource(); - renderdata.decorate = false; - renderdata.w = REALSIZ.x; - renderdata.h = REALSIZ.y; - renderdata.blockBlurOptimization = pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM || pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; + CSurfacePassElement::SRenderData renderdata = {pMonitor, time, REALPOS}; + renderdata.fadeAlpha = pLayer->alpha.value(); + renderdata.blur = pLayer->forceBlur && *PBLUR; + renderdata.surface = pLayer->surface->resource(); + renderdata.decorate = false; + renderdata.w = REALSIZ.x; + renderdata.h = REALSIZ.y; + renderdata.pLS = pLayer; + renderdata.blockBlurOptimization = pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM || pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; - g_pHyprOpenGL->m_RenderData.clipBox = CBox{0, 0, pMonitor->vecSize.x, pMonitor->vecSize.y}.scale(pMonitor->scale); - - g_pHyprOpenGL->m_pCurrentLayer = pLayer; - - const auto DM = g_pHyprOpenGL->m_RenderData.discardMode; - const auto DA = g_pHyprOpenGL->m_RenderData.discardOpacity; + renderdata.clipBox = CBox{0, 0, pMonitor->vecSize.x, pMonitor->vecSize.y}.scale(pMonitor->scale); if (renderdata.blur && pLayer->ignoreAlpha) { - g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; - g_pHyprOpenGL->m_RenderData.discardOpacity = pLayer->ignoreAlphaValue; + renderdata.discardMode |= DISCARD_ALPHA; + renderdata.discardOpacity = pLayer->ignoreAlphaValue; } if (!popups) - pLayer->surface->resource()->breadthfirst([](SP s, const Vector2D& offset, void* data) { renderSurface(s, offset.x, offset.y, data); }, &renderdata); + pLayer->surface->resource()->breadthfirst( + [this, &renderdata, &pLayer](SP s, const Vector2D& offset, void* data) { + renderdata.localPos = offset; + renderdata.texture = s->current.texture; + renderdata.surface = s; + renderdata.mainSurface = s == pLayer->surface->resource(); + m_sRenderPass.add(makeShared(renderdata)); + renderdata.surfaceCounter++; + }, + &renderdata); renderdata.squishOversized = false; // don't squish popups renderdata.dontRound = true; @@ -827,28 +703,28 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim renderdata.surfaceCounter = 0; if (popups) { pLayer->popupHead->breadthfirst( - [](CPopup* popup, void* data) { + [this, &renderdata](CPopup* popup, void* data) { if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource() || !popup->m_bMapped) return; - Vector2D pos = popup->coordsRelativeToParent(); - renderSurface(popup->m_pWLSurface->resource(), pos.x, pos.y, data); + Vector2D pos = popup->coordsRelativeToParent(); + renderdata.localPos = pos; + renderdata.texture = popup->m_pWLSurface->resource()->current.texture; + renderdata.surface = popup->m_pWLSurface->resource(); + renderdata.mainSurface = false; + m_sRenderPass.add(makeShared(renderdata)); + renderdata.surfaceCounter++; }, &renderdata); } - - g_pHyprOpenGL->m_pCurrentLayer = nullptr; - g_pHyprOpenGL->m_RenderData.clipBox = {}; - g_pHyprOpenGL->m_RenderData.discardMode = DM; - g_pHyprOpenGL->m_RenderData.discardOpacity = DA; } void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, timespec* time) { - const auto POS = pPopup->globalBox().pos(); + const auto POS = pPopup->globalBox().pos(); - SRenderData renderdata = {pMonitor, time, POS.x, POS.y}; + CSurfacePassElement::SRenderData renderdata = {pMonitor, time, POS}; - const auto SURF = pPopup->getSurface(); + const auto SURF = pPopup->getSurface(); renderdata.surface = SURF; renderdata.decorate = false; @@ -859,24 +735,26 @@ void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, tim static auto PBLURIMES = CConfigValue("decoration:blur:input_methods"); static auto PBLURIGNOREA = CConfigValue("decoration:blur:input_methods_ignorealpha"); - // TODO: make push/pop methods for this. - const auto DM = g_pHyprOpenGL->m_RenderData.discardMode; - const auto DA = g_pHyprOpenGL->m_RenderData.discardOpacity; - renderdata.blur = *PBLURIMES && *PBLUR; if (renderdata.blur) { - g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; - g_pHyprOpenGL->m_RenderData.discardOpacity = *PBLURIGNOREA; + renderdata.discardMode |= DISCARD_ALPHA; + renderdata.discardOpacity = *PBLURIGNOREA; } - SURF->breadthfirst([](SP s, const Vector2D& offset, void* data) { renderSurface(s, offset.x, offset.y, data); }, &renderdata); - - g_pHyprOpenGL->m_RenderData.discardMode = DM; - g_pHyprOpenGL->m_RenderData.discardOpacity = DA; + SURF->breadthfirst( + [this, &renderdata, &SURF](SP s, const Vector2D& offset, void* data) { + renderdata.localPos = offset; + renderdata.texture = s->current.texture; + renderdata.surface = s; + renderdata.mainSurface = s == SURF; + m_sRenderPass.add(makeShared(renderdata)); + renderdata.surfaceCounter++; + }, + &renderdata); } void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, PHLMONITOR pMonitor, timespec* time) { - SRenderData renderdata = {pMonitor, time, pMonitor->vecPosition.x, pMonitor->vecPosition.y}; + CSurfacePassElement::SRenderData renderdata = {pMonitor, time, pMonitor->vecPosition, pMonitor->vecPosition}; renderdata.blur = false; renderdata.surface = pSurface->surface->surface(); @@ -884,7 +762,16 @@ void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, PHLM renderdata.w = pMonitor->vecSize.x; renderdata.h = pMonitor->vecSize.y; - renderdata.surface->breadthfirst([](SP s, const Vector2D& offset, void* data) { renderSurface(s, offset.x, offset.y, data); }, &renderdata); + renderdata.surface->breadthfirst( + [this, &renderdata, &pSurface](SP s, const Vector2D& offset, void* data) { + renderdata.localPos = offset; + renderdata.texture = s->current.texture; + renderdata.surface = s; + renderdata.mainSurface = s == pSurface->surface->surface(); + m_sRenderPass.add(makeShared(renderdata)); + renderdata.surfaceCounter++; + }, + &renderdata); } void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* time, const Vector2D& translate, const float& scale) { @@ -893,6 +780,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA static auto PBLUR = CConfigValue("decoration:blur:enabled"); static auto PRENDERTEX = CConfigValue("misc:disable_hyprland_logo"); static auto PBACKGROUNDCOLOR = CConfigValue("misc:background_color"); + static auto PXPMODE = CConfigValue("render:xp_mode"); SRenderModifData RENDERMODIFDATA; if (translate != Vector2D{0, 0}) @@ -916,14 +804,11 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA if (!pWorkspace) { // allow rendering without a workspace. In this case, just render layers. - g_pHyprOpenGL->blend(false); - if (!canSkipBackBufferClear(pMonitor)) { - if (*PRENDERTEX /* inverted cfg flag */) - g_pHyprOpenGL->clear(CHyprColor(*PBACKGROUNDCOLOR)); - else - g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" - } - g_pHyprOpenGL->blend(true); + + if (*PRENDERTEX /* inverted cfg flag */) + m_sRenderPass.add(makeShared(CClearPassElement::SClearData{CHyprColor(*PBACKGROUNDCOLOR)})); + else + g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { renderLayer(ls.lock(), pMonitor, time); @@ -943,27 +828,11 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA return; } - // for storing damage when we optimize for occlusion - CRegion preOccludedDamage{g_pHyprOpenGL->m_RenderData.damage}; - - // Render layer surfaces below windows for monitor - // if we have a fullscreen, opaque window that convers the screen, we can skip this. - // TODO: check better with solitary after MR for tearing. - const auto PFULLWINDOW = pWorkspace ? pWorkspace->getFullscreenWindow() : nullptr; - if (!pWorkspace->m_bHasFullscreenWindow || pWorkspace->m_efFullscreenMode != FSMODE_FULLSCREEN || !PFULLWINDOW || PFULLWINDOW->m_vRealSize.isBeingAnimated() || - !PFULLWINDOW->opaque() || pWorkspace->m_vRenderOffset.value() != Vector2D{} || g_pHyprOpenGL->preBlurQueued()) { - - if (!g_pHyprOpenGL->m_RenderData.pCurrentMonData->blurFBShouldRender) - setOccludedForBackLayers(g_pHyprOpenGL->m_RenderData.damage, pWorkspace); - - g_pHyprOpenGL->blend(false); - if (!canSkipBackBufferClear(pMonitor)) { - if (*PRENDERTEX /* inverted cfg flag */) - g_pHyprOpenGL->clear(CHyprColor(*PBACKGROUNDCOLOR)); - else - g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" - } - g_pHyprOpenGL->blend(true); + if (!*PXPMODE) { + if (*PRENDERTEX /* inverted cfg flag */) + m_sRenderPass.add(makeShared(CClearPassElement::SClearData{CHyprColor(*PBACKGROUNDCOLOR)})); + else + g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper" for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { renderLayer(ls.lock(), pMonitor, time); @@ -971,22 +840,16 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) { renderLayer(ls.lock(), pMonitor, time); } - - g_pHyprOpenGL->m_RenderData.damage = preOccludedDamage; } // pre window pass g_pHyprOpenGL->preWindowPass(); - setOccludedForMainWorkspace(g_pHyprOpenGL->m_RenderData.damage, pWorkspace); - if (pWorkspace->m_bHasFullscreenWindow) renderWorkspaceWindowsFullscreen(pMonitor, pWorkspace, time); else renderWorkspaceWindows(pMonitor, pWorkspace, time); - g_pHyprOpenGL->m_RenderData.damage = preOccludedDamage; - // and then special for (auto const& ws : g_pCompositor->m_vWorkspaces) { if (ws->m_pMonitor == pMonitor && ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) { @@ -994,13 +857,21 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA const bool ANIMOUT = !pMonitor->activeSpecialWorkspace; if (*PDIMSPECIAL != 0.f) { - CBox monbox = {translate.x, translate.y, pMonitor->vecTransformedSize.x * scale, pMonitor->vecTransformedSize.y * scale}; - g_pHyprOpenGL->renderRect(&monbox, CHyprColor(0, 0, 0, *PDIMSPECIAL * (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS))); + CRectPassElement::SRectData data; + data.box = {translate.x, translate.y, pMonitor->vecTransformedSize.x * scale, pMonitor->vecTransformedSize.y * scale}; + data.color = CHyprColor(0, 0, 0, *PDIMSPECIAL * (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS)); + + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } if (*PBLURSPECIAL && *PBLUR) { - CBox monbox = {translate.x, translate.y, pMonitor->vecTransformedSize.x * scale, pMonitor->vecTransformedSize.y * scale}; - g_pHyprOpenGL->renderRectWithBlur(&monbox, CHyprColor(0, 0, 0, 0), 0, (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS)); + CRectPassElement::SRectData data; + data.box = {translate.x, translate.y, pMonitor->vecTransformedSize.x * scale, pMonitor->vecTransformedSize.y * scale}; + data.color = CHyprColor(0, 0, 0, 0); + data.blur = true; + data.blurA = (ANIMOUT ? (1.0 - SPECIALANIMPROGRS) : SPECIALANIMPROGRS); + + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } break; @@ -1381,30 +1252,10 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { } // if we have no tracking or full tracking, invalidate the entire monitor - if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || pMonitor->forceFullFrames > 0 || damageBlinkCleanup > 0) { - damage = {0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10}; - finalDamage = damage; - } else { - static auto PBLURENABLED = CConfigValue("decoration:blur:enabled"); + if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || pMonitor->forceFullFrames > 0 || damageBlinkCleanup > 0) + damage = {0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10}; - // if we use blur we need to expand the damage for proper blurring - // if framebuffer was not offloaded we're not doing introspection aka not blurring so this is redundant and dumb - if (*PBLURENABLED == 1 && g_pHyprOpenGL->m_bOffloadedFramebuffer) { - // TODO: can this be optimized? - static auto PBLURSIZE = CConfigValue("decoration:blur:size"); - static auto PBLURPASSES = CConfigValue("decoration:blur:passes"); - const auto BLURRADIUS = - *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES); // is this 2^pass? I don't know but it works... I think. - - // now, prep the damage, get the extended damage region - damage.expand(BLURRADIUS); // expand for proper blurring - - finalDamage = damage; - - damage.expand(BLURRADIUS); // expand for proper blurring - } else - finalDamage = damage; - } + finalDamage = damage; // update damage in renderdata as we modified it g_pHyprOpenGL->setDamage(damage, finalDamage); @@ -1446,8 +1297,10 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { } if (*PDAMAGEBLINK && damageBlinkCleanup == 0) { - CBox monrect = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; - g_pHyprOpenGL->renderRect(&monrect, CHyprColor(1.0, 0.0, 1.0, 100.0 / 255.0), 0); + CRectPassElement::SRectData data; + data.box = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; + data.color = CHyprColor(1.0, 0.0, 1.0, 100.0 / 255.0); + m_sRenderPass.add(makeShared(data)); damageBlinkCleanup = 1; } else if (*PDAMAGEBLINK) { damageBlinkCleanup++; @@ -1456,7 +1309,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { } } } else - g_pHyprRenderer->renderWindow(pMonitor->solitaryClient.lock(), pMonitor, &now, false, RENDER_PASS_MAIN /* solitary = no popups */); + renderWindow(pMonitor->solitaryClient.lock(), pMonitor, &now, false, RENDER_PASS_MAIN /* solitary = no popups */); } else if (!pMonitor->isMirror()) { sendFrameEventsToWorkspace(pMonitor, pMonitor->activeWorkspace, &now); if (pMonitor->activeSpecialWorkspace) @@ -1474,6 +1327,8 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { endRender(); + finalDamage = g_pHyprOpenGL->m_RenderData.damage; + TRACY_GPU_COLLECT; if (!pMonitor->mirrors.empty()) { @@ -1488,7 +1343,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { if (*PDAMAGEBLINK) frameDamage.add(damage); - g_pHyprRenderer->damageMirrorsWith(pMonitor, frameDamage); + damageMirrorsWith(pMonitor, frameDamage); pMonitor->output->state->addDamage(frameDamage); } @@ -1517,9 +1372,8 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { if (pMonitor == g_pCompositor->m_vMonitors.front()) { const float noOverlayUs = durationUs - std::chrono::duration_cast(endRenderOverlay - renderStartOverlay).count() / 1000.f; g_pDebugOverlay->renderDataNoOverlay(pMonitor, noOverlayUs); - } else { + } else g_pDebugOverlay->renderDataNoOverlay(pMonitor, durationUs); - } } } @@ -1883,7 +1737,7 @@ void CHyprRenderer::damageWindow(PHLWINDOW pWindow, bool forceFull) { windowBox.translate(pWindow->m_vFloatingOffset); for (auto const& m : g_pCompositor->m_vMonitors) { - if (forceFull || g_pHyprRenderer->shouldRenderWindow(pWindow, m)) { // only damage if window is rendered on monitor + if (forceFull || shouldRenderWindow(pWindow, m)) { // only damage if window is rendered on monitor CBox fixedDamageBox = {windowBox.x - m->vecPosition.x, windowBox.y - m->vecPosition.y, windowBox.width, windowBox.height}; fixedDamageBox.scale(m->scale); m->addDamage(&fixedDamageBox); @@ -2443,7 +2297,7 @@ void CHyprRenderer::ensureCursorRenderingMode() { if (!g_pPointerManager->softwareLockedFor(m)) continue; - g_pHyprRenderer->damageMonitor(m); // TODO: maybe just damage the cursor area? + damageMonitor(m); // TODO: maybe just damage the cursor area? } setCursorHidden(true); @@ -2455,7 +2309,7 @@ void CHyprRenderer::ensureCursorRenderingMode() { if (!g_pPointerManager->softwareLockedFor(m)) continue; - g_pHyprRenderer->damageMonitor(m); // TODO: maybe just damage the cursor area? + damageMonitor(m); // TODO: maybe just damage the cursor area? } setCursorHidden(false); @@ -2535,94 +2389,6 @@ void CHyprRenderer::initiateManualCrash() { **PDT = 0; } -void CHyprRenderer::setOccludedForMainWorkspace(CRegion& region, PHLWORKSPACE pWorkspace) { - CRegion rg; - - const auto PMONITOR = pWorkspace->m_pMonitor.lock(); - - if (!PMONITOR->activeSpecialWorkspace) - return; - - for (auto const& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != PMONITOR->activeSpecialWorkspace) - continue; - - if (!w->opaque()) - continue; - - const auto ROUNDING = w->rounding() * PMONITOR->scale; - const Vector2D POS = w->m_vRealPosition.value() + Vector2D{ROUNDING, ROUNDING} - PMONITOR->vecPosition + (w->m_bPinned ? Vector2D{} : pWorkspace->m_vRenderOffset.value()); - const Vector2D SIZE = w->m_vRealSize.value() - Vector2D{ROUNDING * 2, ROUNDING * 2}; - - CBox box = {POS.x, POS.y, SIZE.x, SIZE.y}; - - box.scale(PMONITOR->scale); - - rg.add(box); - } - - region.subtract(rg); -} - -void CHyprRenderer::setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWorkspace) { - CRegion rg; - - const auto PMONITOR = pWorkspace->m_pMonitor.lock(); - - static auto PBLUR = CConfigValue("decoration:blur:enabled"); - static auto PBLURSIZE = CConfigValue("decoration:blur:size"); - static auto PBLURPASSES = CConfigValue("decoration:blur:passes"); - const auto BLURRADIUS = *PBLUR ? (*PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES)) : 0; - - for (auto const& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != pWorkspace) - continue; - - if (!w->opaque()) - continue; - - const auto ROUNDING = w->rounding() * PMONITOR->scale; - const Vector2D POS = w->m_vRealPosition.value() + Vector2D{ROUNDING, ROUNDING} - PMONITOR->vecPosition + (w->m_bPinned ? Vector2D{} : pWorkspace->m_vRenderOffset.value()); - const Vector2D SIZE = w->m_vRealSize.value() - Vector2D{ROUNDING * 2, ROUNDING * 2}; - - CBox box = {POS.x, POS.y, SIZE.x, SIZE.y}; - - box.scale(PMONITOR->scale).expand(-BLURRADIUS); - - g_pHyprOpenGL->m_RenderData.renderModif.applyToBox(box); - - rg.add(box); - } - - region.subtract(rg); -} - -bool CHyprRenderer::canSkipBackBufferClear(PHLMONITOR pMonitor) { - for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { - if (!ls->layerSurface) - continue; - - if (ls->alpha.value() < 1.f) - continue; - - if (ls->geometry.x != pMonitor->vecPosition.x || ls->geometry.y != pMonitor->vecPosition.y || ls->geometry.width != pMonitor->vecSize.x || - ls->geometry.height != pMonitor->vecSize.y) - continue; - - // TODO: cache maybe? - CRegion opaque = ls->layerSurface->surface->current.opaque; - CBox lsbox = {{}, ls->layerSurface->surface->current.size}; - opaque.invert(lsbox); - - if (!opaque.empty()) - continue; - - return true; - } - - return false; -} - void CHyprRenderer::recheckSolitaryForMonitor(PHLMONITOR pMonitor) { pMonitor->solitaryClient.reset(); // reset it, if we find one it will be set. @@ -2668,11 +2434,10 @@ void CHyprRenderer::recheckSolitaryForMonitor(PHLMONITOR pMonitor) { // check if it did not open any subsurfaces or shit int surfaceCount = 0; - if (PCANDIDATE->m_bIsX11) { + if (PCANDIDATE->m_bIsX11) surfaceCount = 1; - } else { + else surfaceCount = PCANDIDATE->popupsCount() + PCANDIDATE->surfacesCount(); - } if (surfaceCount > 1) return; @@ -2715,6 +2480,8 @@ bool CHyprRenderer::beginRender(PHLMONITOR pMonitor, CRegion& damage, eRenderMod makeEGLCurrent(); + m_sRenderPass.clear(); + m_eRenderMode = mode; g_pHyprOpenGL->m_RenderData.pMonitor = pMonitor; // has to be set cuz allocs @@ -2774,6 +2541,8 @@ void CHyprRenderer::endRender() { PMONITOR->commitSeq++; + g_pHyprOpenGL->m_RenderData.damage = m_sRenderPass.render(g_pHyprOpenGL->m_RenderData.damage); + auto cleanup = CScopeGuard([this]() { if (m_pCurrentRenderbuffer) m_pCurrentRenderbuffer->unbind(); @@ -2903,3 +2672,225 @@ void CHyprRenderer::addWindowToRenderUnfocused(PHLWINDOW window) { if (!m_tRenderUnfocusedTimer->armed()) m_tRenderUnfocusedTimer->updateTimeout(std::chrono::milliseconds(1000 / *PFPS)); } + +void CHyprRenderer::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFramebuffer) { + // we trust the window is valid. + const auto PMONITOR = pWindow->m_pMonitor.lock(); + + if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) + return; + + // we need to "damage" the entire monitor + // so that we render the entire window + // this is temporary, doesnt mess with the actual damage + CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; + + makeEGLCurrent(); + + pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); + pFramebuffer->addStencil(g_pHyprOpenGL->m_RenderData.pCurrentMonData->stencilTex); + + beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, pFramebuffer); + + g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC + + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + // this is a hack but it works :P + // we need to disable blur or else we will get a black background, as the shader + // will try to copy the bg to apply blur. + // this isn't entirely correct, but like, oh well. + // small todo: maybe make this correct? :P + static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")); + const auto BLURVAL = **PBLUR; + **PBLUR = 0; + + // TODO: how can we make this the size of the window? setting it to window's size makes the entire screen render with the wrong res forever more. odd. + glViewport(0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); + + g_pHyprOpenGL->m_RenderData.currentFB = pFramebuffer; + + g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC + + renderWindow(pWindow, PMONITOR, &now, false, RENDER_PASS_ALL, true); + + **PBLUR = BLURVAL; + + endRender(); +} + +void CHyprRenderer::makeWindowSnapshot(PHLWINDOW pWindow) { + // we trust the window is valid. + const auto PMONITOR = pWindow->m_pMonitor.lock(); + + if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) + return; + + if (!shouldRenderWindow(pWindow)) + return; // ignore, window is not being rendered + + // we need to "damage" the entire monitor + // so that we render the entire window + // this is temporary, doesnt mess with the actual damage + CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; + + PHLWINDOWREF ref{pWindow}; + + makeEGLCurrent(); + + const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_mWindowFramebuffers[ref]; + + PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); + + beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER); + + m_bRenderingSnapshot = true; + + g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC + + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + // this is a hack but it works :P + // we need to disable blur or else we will get a black background, as the shader + // will try to copy the bg to apply blur. + // this isn't entirely correct, but like, oh well. + // small todo: maybe make this correct? :P + static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")); + const auto BLURVAL = **PBLUR; + **PBLUR = 0; + + g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC + + renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL); + + **PBLUR = BLURVAL; + + endRender(); + + m_bRenderingSnapshot = false; +} + +void CHyprRenderer::makeLayerSnapshot(PHLLS pLayer) { + // we trust the window is valid. + const auto PMONITOR = pLayer->monitor.lock(); + + if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) + return; + + // we need to "damage" the entire monitor + // so that we render the entire window + // this is temporary, doesnt mess with the actual damage + CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; + + makeEGLCurrent(); + + const auto PFRAMEBUFFER = &g_pHyprOpenGL->m_mLayerFramebuffers[pLayer]; + + PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); + + beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER); + + m_bRenderingSnapshot = true; + + g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC + + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + const auto BLURLSSTATUS = pLayer->forceBlur; + pLayer->forceBlur = false; + + // draw the layer + renderLayer(pLayer, PMONITOR, &now); + + pLayer->forceBlur = BLURLSSTATUS; + + endRender(); + + m_bRenderingSnapshot = false; +} + +void CHyprRenderer::renderSnapshot(PHLWINDOW pWindow) { + static auto PDIMAROUND = CConfigValue("decoration:dim_around"); + + PHLWINDOWREF ref{pWindow}; + + if (!g_pHyprOpenGL->m_mWindowFramebuffers.contains(ref)) + return; + + const auto FBDATA = &g_pHyprOpenGL->m_mWindowFramebuffers.at(ref); + + if (!FBDATA->getTexture()) + return; + + const auto PMONITOR = pWindow->m_pMonitor.lock(); + + CBox windowBox; + // some mafs to figure out the correct box + // the originalClosedPos is relative to the monitor's pos + Vector2D scaleXY = Vector2D((PMONITOR->scale * pWindow->m_vRealSize.value().x / (pWindow->m_vOriginalClosedSize.x * PMONITOR->scale)), + (PMONITOR->scale * pWindow->m_vRealSize.value().y / (pWindow->m_vOriginalClosedSize.y * PMONITOR->scale))); + + windowBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; + windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; + windowBox.x = ((pWindow->m_vRealPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x); + windowBox.y = ((pWindow->m_vRealPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y); + + CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; + + if (*PDIMAROUND && pWindow->m_sWindowData.dimAround.valueOrDefault()) { + + CRectPassElement::SRectData data; + + data.box = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y}; + data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pWindow->m_fAlpha.value()); + + m_sRenderPass.add(makeShared(data)); + damageMonitor(PMONITOR); + } + + CTexPassElement::SRenderData data; + data.flipEndFrame = true; + data.tex = FBDATA->getTexture(); + data.box = windowBox; + data.a = pWindow->m_fAlpha.value(); + data.damage = fakeDamage; + + m_sRenderPass.add(makeShared(data)); +} + +void CHyprRenderer::renderSnapshot(PHLLS pLayer) { + if (!g_pHyprOpenGL->m_mLayerFramebuffers.contains(pLayer)) + return; + + const auto FBDATA = &g_pHyprOpenGL->m_mLayerFramebuffers.at(pLayer); + + if (!FBDATA->getTexture()) + return; + + const auto PMONITOR = pLayer->monitor.lock(); + + CBox layerBox; + // some mafs to figure out the correct box + // the originalClosedPos is relative to the monitor's pos + Vector2D scaleXY = Vector2D((PMONITOR->scale * pLayer->realSize.value().x / (pLayer->geometry.w * PMONITOR->scale)), + (PMONITOR->scale * pLayer->realSize.value().y / (pLayer->geometry.h * PMONITOR->scale))); + + layerBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; + layerBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; + layerBox.x = ((pLayer->realPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((pLayer->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x); + layerBox.y = ((pLayer->realPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((pLayer->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y); + + CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; + + CTexPassElement::SRenderData data; + data.flipEndFrame = true; + data.tex = FBDATA->getTexture(); + data.box = layerBox; + data.a = pLayer->alpha.value(); + data.damage = fakeDamage; + + m_sRenderPass.add(makeShared(data)); +} diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 717a3285..054f0eea 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -67,9 +67,6 @@ class CHyprRenderer { bool fixMisalignedFSV1 = false); std::tuple getRenderTimes(PHLMONITOR pMonitor); // avg max min void renderLockscreen(PHLMONITOR pMonitor, timespec* now, const CBox& geometry); - void setOccludedForBackLayers(CRegion& region, PHLWORKSPACE pWorkspace); - void setOccludedForMainWorkspace(CRegion& region, PHLWORKSPACE pWorkspace); // TODO: merge occlusion methods - bool canSkipBackBufferClear(PHLMONITOR pMonitor); void recheckSolitaryForMonitor(PHLMONITOR pMonitor); void setCursorSurface(SP surf, int hotspotX, int hotspotY, bool force = false); void setCursorFromName(const std::string& name, bool force = false); @@ -80,6 +77,11 @@ class CHyprRenderer { void unsetEGL(); SExplicitSyncSettings getExplicitSyncSettings(); void addWindowToRenderUnfocused(PHLWINDOW window); + void makeWindowSnapshot(PHLWINDOW); + void makeRawWindowSnapshot(PHLWINDOW, CFramebuffer*); + void makeLayerSnapshot(PHLLS); + void renderSnapshot(PHLWINDOW); + void renderSnapshot(PHLLS); // if RENDER_MODE_NORMAL, provided damage will be written to. // otherwise, it will be the one used. @@ -110,6 +112,8 @@ class CHyprRenderer { std::string name; } m_sLastCursorData; + CRenderPass m_sRenderPass = {}; + private: void arrangeLayerArray(PHLMONITOR, const std::vector&, bool, CBox*); void renderWorkspaceWindowsFullscreen(PHLMONITOR, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) @@ -129,10 +133,9 @@ class CHyprRenderer { bool m_bCursorHidden = false; bool m_bCursorHasSurface = false; SP m_pCurrentRenderbuffer = nullptr; - SP m_pCurrentBuffer; - eRenderMode m_eRenderMode = RENDER_MODE_NORMAL; - - bool m_bNvidia = false; + SP m_pCurrentBuffer = nullptr; + eRenderMode m_eRenderMode = RENDER_MODE_NORMAL; + bool m_bNvidia = false; struct { bool hiddenOnTouch = false; diff --git a/src/render/Transformer.cpp b/src/render/Transformer.cpp index c6989d2c..7ac4ab68 100644 --- a/src/render/Transformer.cpp +++ b/src/render/Transformer.cpp @@ -1,5 +1,5 @@ #include "Transformer.hpp" -void IWindowTransformer::preWindowRender(SRenderData* pRenderData) { +void IWindowTransformer::preWindowRender(CSurfacePassElement::SRenderData* pRenderData) { ; } \ No newline at end of file diff --git a/src/render/Transformer.hpp b/src/render/Transformer.hpp index c54da4dd..048b1898 100644 --- a/src/render/Transformer.hpp +++ b/src/render/Transformer.hpp @@ -1,8 +1,7 @@ #pragma once #include "Framebuffer.hpp" - -struct SRenderData; +#include "pass/SurfacePassElement.hpp" // A window transformer can be attached to a window. // If any is attached, Hyprland will render the window to a separate fb, then call the transform() func with it, @@ -18,5 +17,5 @@ class IWindowTransformer { virtual CFramebuffer* transform(CFramebuffer* in) = 0; // called by Hyprland before a window main pass is started. - virtual void preWindowRender(SRenderData* pRenderData); + virtual void preWindowRender(CSurfacePassElement::SRenderData* pRenderData); }; \ No newline at end of file diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 93490f31..4a793eab 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -2,6 +2,7 @@ #include "../../Compositor.hpp" #include "../../config/ConfigValue.hpp" #include "../../managers/eventLoop/EventLoopManager.hpp" +#include "../pass/BorderPassElement.hpp" CHyprBorderDecoration::CHyprBorderDecoration(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow), m_pWindow(pWindow) { ; @@ -66,13 +67,24 @@ void CHyprBorderDecoration::draw(PHLMONITOR pMonitor, float const& a) { grad.m_fAngle = normalizeAngleRad(grad.m_fAngle); } - int borderSize = m_pWindow->getRealBorderSize(); - const auto ROUNDING = m_pWindow->rounding() * pMonitor->scale; + int borderSize = m_pWindow->getRealBorderSize(); + const auto ROUNDING = m_pWindow->rounding() * pMonitor->scale; - if (ANIMATED) - g_pHyprOpenGL->renderBorder(&windowBox, m_pWindow->m_cRealBorderColorPrevious, grad, m_pWindow->m_fBorderFadeAnimationProgress.value(), ROUNDING, borderSize, a); - else - g_pHyprOpenGL->renderBorder(&windowBox, grad, ROUNDING, borderSize, a); + CBorderPassElement::SBorderData data; + data.box = windowBox; + data.grad1 = grad; + data.round = ROUNDING; + data.a = a; + data.borderSize = borderSize; + + if (ANIMATED) { + data.hasGrad2 = true; + data.grad1 = m_pWindow->m_cRealBorderColorPrevious; + data.grad2 = grad; + data.lerp = m_pWindow->m_fBorderFadeAnimationProgress.value(); + } + + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } eDecorationType CHyprBorderDecoration::getDecorationType() { diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 38ced9af..21242b57 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -2,6 +2,7 @@ #include "../../Compositor.hpp" #include "../../config/ConfigValue.hpp" +#include "../pass/ShadowPassElement.hpp" CHyprDropShadowDecoration::CHyprDropShadowDecoration(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow), m_pWindow(pWindow) { ; @@ -87,7 +88,13 @@ void CHyprDropShadowDecoration::updateWindow(PHLWINDOW pWindow) { } void CHyprDropShadowDecoration::draw(PHLMONITOR pMonitor, float const& a) { + CShadowPassElement::SShadowData data; + data.deco = this; + data.a = a; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); +} +void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { const auto PWINDOW = m_pWindow.lock(); if (!validMapped(PWINDOW)) @@ -141,6 +148,7 @@ void CHyprDropShadowDecoration::draw(PHLMONITOR pMonitor, float const& a) { return; // don't draw invisible shadows g_pHyprOpenGL->scissor((CBox*)nullptr); + g_pHyprOpenGL->m_RenderData.currentWindow = m_pWindow; // we'll take the liberty of using this as it should not be used rn CFramebuffer& alphaFB = g_pHyprOpenGL->m_RenderData.pCurrentMonData->mirrorFB; @@ -197,6 +205,7 @@ void CHyprDropShadowDecoration::draw(PHLMONITOR pMonitor, float const& a) { LASTFB->bind(); CBox monbox = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; + g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->renderTextureMatte(alphaSwapFB.getTexture(), &monbox, alphaFB); @@ -209,6 +218,8 @@ void CHyprDropShadowDecoration::draw(PHLMONITOR pMonitor, float const& a) { if (m_seExtents != m_seReportedExtents) g_pDecorationPositioner->repositionDeco(this); + + g_pHyprOpenGL->m_RenderData.currentWindow.reset(); } eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() { diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index 650f8c92..fe0f8952 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -25,6 +25,8 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { virtual std::string getDisplayName(); + void render(PHLMONITOR, float const& a); + private: SBoxExtents m_seExtents; SBoxExtents m_seReportedExtents; diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 0aee6157..f870e71b 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -4,6 +4,8 @@ #include "managers/LayoutManager.hpp" #include #include +#include "../pass/TexPassElement.hpp" +#include "../pass/RectPassElement.hpp" // shared things to conserve VRAM static SP m_tGradientActive = makeShared(); @@ -71,11 +73,11 @@ void CHyprGroupBarDecoration::updateWindow(PHLWINDOW pWindow) { m_dwGroupMembers.clear(); PHLWINDOW head = pWindow->getGroupHead(); - m_dwGroupMembers.push_back(head); + m_dwGroupMembers.emplace_back(head); PHLWINDOW curr = head->m_sGroupData.pNextWindow.lock(); while (curr != head) { - m_dwGroupMembers.push_back(curr); + m_dwGroupMembers.emplace_back(curr); curr = curr->m_sGroupData.pNextWindow.lock(); } @@ -113,10 +115,9 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { m_fBarWidth = *PSTACKED ? ASSIGNEDBOX.w : (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw; m_fBarHeight = *PSTACKED ? ((ASSIGNEDBOX.h - 2 - BAR_PADDING_OUTER_VERT) - BAR_PADDING_OUTER_VERT * (barsToDraw)) / barsToDraw : ASSIGNEDBOX.h - BAR_PADDING_OUTER_VERT; - const auto DESIREDHEIGHT = *PSTACKED ? (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT : BAR_PADDING_OUTER_VERT * 2 + ONEBARHEIGHT; - if (DESIREDHEIGHT != ASSIGNEDBOX.h) { + const auto DESIREDHEIGHT = *PSTACKED ? (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT : BAR_PADDING_OUTER_VERT * 2L + ONEBARHEIGHT; + if (DESIREDHEIGHT != ASSIGNEDBOX.h) g_pDecorationPositioner->repositionDeco(this); - } float xoff = 0; float yoff = 0; @@ -148,7 +149,10 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_pLastWindow.lock() ? PCOLACTIVE->m_vColors[0] : PCOLINACTIVE->m_vColors[0]; color.a *= a; - g_pHyprOpenGL->renderRect(&rect, color); + CRectPassElement::SRectData rectdata; + rectdata.color = color; + rectdata.box = rect; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); rect = {ASSIGNEDBOX.x + floor(xoff) - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - ONEBARHEIGHT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth, @@ -158,26 +162,33 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { if (*PGRADIENTS) { const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_pLastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) : (GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive)); - if (GRADIENTTEX->m_iTexID != 0) - g_pHyprOpenGL->renderTexture(GRADIENTTEX, &rect, 1.0); + if (GRADIENTTEX->m_iTexID) { + CTexPassElement::SRenderData data; + data.tex = GRADIENTTEX; + data.box = rect; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + } } if (*PRENDERTITLES) { CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[WINDOWINDEX]->m_szTitle); if (!pTitleTex) - pTitleTex = - m_sTitleTexs.titleTexs - .emplace_back(std::make_unique(m_dwGroupMembers[WINDOWINDEX].lock(), - Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale)) - .get(); + pTitleTex = m_sTitleTexs.titleTexs + .emplace_back(std::make_unique(m_dwGroupMembers[WINDOWINDEX].lock(), + Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2L * BAR_TEXT_PAD) * pMonitor->scale}, + pMonitor->scale)) + .get(); rect.y += (rect.height - pTitleTex->textHeight) / 2.0; rect.height = pTitleTex->textHeight; rect.width = pTitleTex->textWidth; rect.x += (m_fBarWidth * pMonitor->scale) / 2.0 - (pTitleTex->textWidth / 2.0); rect.round(); - g_pHyprOpenGL->renderTexture(pTitleTex->tex, &rect, 1.f); + CTexPassElement::SRenderData data; + data.tex = pTitleTex->tex; + data.box = rect; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } if (*PSTACKED) @@ -203,10 +214,8 @@ void CHyprGroupBarDecoration::invalidateTextures() { m_sTitleTexs.titleTexs.clear(); } -CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float monitorScale) { +CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float monitorScale) : szContent(pWindow->m_szTitle), pWindowOwner(pWindow) { tex = makeShared(); - szContent = pWindow->m_szTitle; - pWindowOwner = pWindow; const auto LAYOUTSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); const auto LAYOUTCAIRO = cairo_create(LAYOUTSURFACE); @@ -281,9 +290,7 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float cairo_surface_destroy(CAIROSURFACE); } -CTitleTex::~CTitleTex() { - tex->destroyTexture(); -} +CTitleTex::~CTitleTex() = default; void renderGradientTo(SP tex, CGradientValueData* grad) { @@ -435,7 +442,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND } while (curr != members[0]); // removes all windows - for (PHLWINDOW w : members) { + for (const PHLWINDOW& w : members) { w->m_sGroupData.pNextWindow.reset(); w->m_sGroupData.head = false; w->m_sGroupData.locked = false; @@ -521,7 +528,7 @@ bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, const IPo g_pCompositor->focusWindow(pWindow); if (pWindow->m_bIsFloating) - g_pCompositor->changeWindowZOrder(pWindow, 1); + g_pCompositor->changeWindowZOrder(pWindow, true); return true; } diff --git a/src/render/pass/BorderPassElement.cpp b/src/render/pass/BorderPassElement.cpp new file mode 100644 index 00000000..635533d0 --- /dev/null +++ b/src/render/pass/BorderPassElement.cpp @@ -0,0 +1,21 @@ +#include "BorderPassElement.hpp" +#include "../OpenGL.hpp" + +CBorderPassElement::CBorderPassElement(const CBorderPassElement::SBorderData& data_) : data(data_) { + ; +} + +void CBorderPassElement::draw(const CRegion& damage) { + if (data.hasGrad2) + g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.grad2, data.lerp, data.round, data.borderSize, data.a, data.outerRound); + else + g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.round, data.borderSize, data.a, data.outerRound); +} + +bool CBorderPassElement::needsLiveBlur() { + return false; +} + +bool CBorderPassElement::needsPrecomputeBlur() { + return false; +} \ No newline at end of file diff --git a/src/render/pass/BorderPassElement.hpp b/src/render/pass/BorderPassElement.hpp new file mode 100644 index 00000000..3a529640 --- /dev/null +++ b/src/render/pass/BorderPassElement.hpp @@ -0,0 +1,30 @@ +#pragma once +#include "PassElement.hpp" +#include "../../config/ConfigDataValues.hpp" + +class CGradientValueData; + +class CBorderPassElement : public IPassElement { + public: + struct SBorderData { + CBox box; + CGradientValueData grad1, grad2; + bool hasGrad2 = false; + float lerp = 0.F, a = 1.F; + int round = 0, borderSize = 1, outerRound = -1; + }; + + CBorderPassElement(const SBorderData& data_); + virtual ~CBorderPassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + + virtual const char* passName() { + return "CBorderPassElement"; + } + + private: + SBorderData data; +}; diff --git a/src/render/pass/ClearPassElement.cpp b/src/render/pass/ClearPassElement.cpp new file mode 100644 index 00000000..bafa73c7 --- /dev/null +++ b/src/render/pass/ClearPassElement.cpp @@ -0,0 +1,26 @@ +#include "ClearPassElement.hpp" +#include "../OpenGL.hpp" + +CClearPassElement::CClearPassElement(const CClearPassElement::SClearData& data_) : data(data_) { + ; +} + +void CClearPassElement::draw(const CRegion& damage) { + g_pHyprOpenGL->clear(data.color); +} + +bool CClearPassElement::needsLiveBlur() { + return false; +} + +bool CClearPassElement::needsPrecomputeBlur() { + return false; +} + +std::optional CClearPassElement::boundingBox() { + return CBox{{}, {INT16_MAX, INT16_MAX}}; +} + +CRegion CClearPassElement::opaqueRegion() { + return *boundingBox(); +} diff --git a/src/render/pass/ClearPassElement.hpp b/src/render/pass/ClearPassElement.hpp new file mode 100644 index 00000000..40242457 --- /dev/null +++ b/src/render/pass/ClearPassElement.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "PassElement.hpp" + +class CClearPassElement : public IPassElement { + public: + struct SClearData { + CHyprColor color; + }; + + CClearPassElement(const SClearData& data); + virtual ~CClearPassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + virtual std::optional boundingBox(); + virtual CRegion opaqueRegion(); + + virtual const char* passName() { + return "CClearPassElement"; + } + + private: + SClearData data; +}; \ No newline at end of file diff --git a/src/render/pass/FramebufferElement.cpp b/src/render/pass/FramebufferElement.cpp new file mode 100644 index 00000000..268e5589 --- /dev/null +++ b/src/render/pass/FramebufferElement.cpp @@ -0,0 +1,48 @@ +#include "FramebufferElement.hpp" +#include "../OpenGL.hpp" + +CFramebufferElement::CFramebufferElement(const CFramebufferElement::SFramebufferElementData& data_) : data(data_) { + ; +} + +void CFramebufferElement::draw(const CRegion& damage) { + CFramebuffer* fb = nullptr; + + if (data.main) { + switch (data.framebufferID) { + case FB_MONITOR_RENDER_MAIN: fb = g_pHyprOpenGL->m_RenderData.mainFB; break; + case FB_MONITOR_RENDER_CURRENT: fb = g_pHyprOpenGL->m_RenderData.currentFB; break; + case FB_MONITOR_RENDER_OUT: fb = g_pHyprOpenGL->m_RenderData.outFB; break; + } + + if (!fb) { + Debug::log(ERR, "BUG THIS: CFramebufferElement::draw: main but null"); + return; + } + + } else { + switch (data.framebufferID) { + case FB_MONITOR_RENDER_EXTRA_OFFLOAD: fb = &g_pHyprOpenGL->m_RenderData.pCurrentMonData->offloadFB; break; + case FB_MONITOR_RENDER_EXTRA_MIRROR: fb = &g_pHyprOpenGL->m_RenderData.pCurrentMonData->mirrorFB; break; + case FB_MONITOR_RENDER_EXTRA_MIRROR_SWAP: fb = &g_pHyprOpenGL->m_RenderData.pCurrentMonData->mirrorSwapFB; break; + case FB_MONITOR_RENDER_EXTRA_OFF_MAIN: fb = &g_pHyprOpenGL->m_RenderData.pCurrentMonData->offMainFB; break; + case FB_MONITOR_RENDER_EXTRA_MONITOR_MIRROR: fb = &g_pHyprOpenGL->m_RenderData.pCurrentMonData->monitorMirrorFB; break; + case FB_MONITOR_RENDER_EXTRA_BLUR: fb = &g_pHyprOpenGL->m_RenderData.pCurrentMonData->blurFB; break; + } + + if (!fb) { + Debug::log(ERR, "BUG THIS: CFramebufferElement::draw: not main but null"); + return; + } + } + + fb->bind(); +} + +bool CFramebufferElement::needsLiveBlur() { + return false; +} + +bool CFramebufferElement::needsPrecomputeBlur() { + return false; +} \ No newline at end of file diff --git a/src/render/pass/FramebufferElement.hpp b/src/render/pass/FramebufferElement.hpp new file mode 100644 index 00000000..f3d181d4 --- /dev/null +++ b/src/render/pass/FramebufferElement.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "PassElement.hpp" + +class CFramebufferElement : public IPassElement { + public: + struct SFramebufferElementData { + bool main = true; + uint8_t framebufferID = 0; + }; + + CFramebufferElement(const SFramebufferElementData& data_); + virtual ~CFramebufferElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + + virtual const char* passName() { + return "CFramebufferElement"; + } + + private: + SFramebufferElementData data; +}; \ No newline at end of file diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp new file mode 100644 index 00000000..31385acb --- /dev/null +++ b/src/render/pass/Pass.cpp @@ -0,0 +1,157 @@ +#include "Pass.hpp" +#include "../OpenGL.hpp" +#include +#include +#include "../../config/ConfigValue.hpp" + +bool CRenderPass::empty() const { + return false; +} + +bool CRenderPass::single() const { + return m_vPassElements.size() == 1; +} + +bool CRenderPass::needsIntrospection() const { + return true; +} + +void CRenderPass::add(SP el) { + m_vPassElements.emplace_back(makeShared(CRegion{}, el)); +} + +void CRenderPass::simplify() { + // TODO: use precompute blur for instances where there is nothing in between + + // if there is live blur, we need to NOT occlude any area where it will be influenced + const auto WILLBLUR = std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->needsLiveBlur(); }); + + CRegion newDamage = damage.copy().intersect(CBox{{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}); + for (auto& el : m_vPassElements | std::views::reverse) { + + if (newDamage.empty()) { + el->discard = true; + continue; + } + + el->elementDamage = newDamage; + auto bb1 = el->element->boundingBox(); + if (!bb1) + continue; + + auto bb = bb1->scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); + + // drop if empty + if (CRegion copy = newDamage.copy(); copy.intersect(bb).empty()) { + el->discard = true; + continue; + } + + auto opaque = el->element->opaqueRegion(); + + if (!opaque.empty()) { + opaque.scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); + + // if this intersects the liveBlur region, allow live blur to operate correctly. + // do not occlude a border near it. + if (WILLBLUR) { + CRegion liveBlurRegion; + for (auto& el2 : m_vPassElements) { + // if we reach self, no problem, we can break. + // if the blur is above us, we don't care, it will work fine. + if (el2 == el) + break; + + if (!el2->element->needsLiveBlur()) + continue; + + const auto BB = el2->element->boundingBox(); + RASSERT(BB, "No bounding box for an element with live blur is illegal"); + + liveBlurRegion.add(*BB); + } + + if (auto infringement = opaque.copy().intersect(liveBlurRegion); !infringement.empty()) { + // eh, this is not the correct solution, but it will do... + // TODO: is this *easily* fixable? + opaque.subtract(infringement.expand(oneBlurRadius())); + } + } + newDamage.subtract(opaque); + } + } +} + +void CRenderPass::clear() { + m_vPassElements.clear(); +} + +CRegion CRenderPass::render(const CRegion& damage_) { + const auto WILLBLUR = std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->needsLiveBlur(); }); + + damage = damage_.copy(); + + if (damage.empty()) { + g_pHyprOpenGL->m_RenderData.damage = damage; + g_pHyprOpenGL->m_RenderData.finalDamage = damage; + return damage; + } + + if (WILLBLUR) { + // combine blur regions into one that will be expanded + CRegion blurRegion; + for (auto& el : m_vPassElements) { + if (!el->element->needsLiveBlur()) + continue; + + const auto BB = el->element->boundingBox(); + RASSERT(BB, "No bounding box for an element with live blur is illegal"); + + blurRegion.add(*BB); + } + + blurRegion.intersect(damage).expand(oneBlurRadius()); + + g_pHyprOpenGL->m_RenderData.finalDamage = blurRegion.copy().add(damage); + + // FIXME: why does this break on * 1.F ? + // used to work when we expand all the damage... I think? Well, before pass. + // moving a window over blur shows the edges being wonk. + blurRegion.expand(oneBlurRadius() * 1.5F); + + damage = blurRegion.copy().add(damage); + } else + g_pHyprOpenGL->m_RenderData.finalDamage = damage; + + if (std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->disableSimplification(); })) { + for (auto& el : m_vPassElements) { + el->elementDamage = damage; + } + } else + simplify(); + + g_pHyprOpenGL->m_RenderData.pCurrentMonData->blurFBShouldRender = std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->needsPrecomputeBlur(); }); + + if (m_vPassElements.empty()) + return {}; + + for (auto& el : m_vPassElements) { + if (el->discard) { + el->element->discard(); + continue; + } + + g_pHyprOpenGL->m_RenderData.damage = el->elementDamage; + el->element->draw(el->elementDamage); + } + + g_pHyprOpenGL->m_RenderData.damage = damage; + return damage; +} + +float CRenderPass::oneBlurRadius() { + // TODO: is this exact range correct? + static auto PBLURSIZE = CConfigValue("decoration:blur:size"); + static auto PBLURPASSES = CConfigValue("decoration:blur:passes"); + return *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES); // is this 2^pass? I don't know but it works... I think. +} diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp new file mode 100644 index 00000000..7f332c19 --- /dev/null +++ b/src/render/pass/Pass.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "../../defines.hpp" +#include "PassElement.hpp" + +class CGradientValueData; + +class CRenderPass { + public: + bool empty() const; + bool single() const; + bool needsIntrospection() const; + + void add(SP elem); + void clear(); + + CRegion render(const CRegion& damage_); + + private: + CRegion damage; + + struct SPassElementData { + CRegion elementDamage; + SP element; + bool discard = false; + }; + + std::vector> m_vPassElements; + + SP currentPassInfo = nullptr; + + void simplify(); + float oneBlurRadius(); + + friend class CHyprOpenGLImpl; +}; diff --git a/src/render/pass/PassElement.cpp b/src/render/pass/PassElement.cpp new file mode 100644 index 00000000..737c6b27 --- /dev/null +++ b/src/render/pass/PassElement.cpp @@ -0,0 +1,17 @@ +#include "PassElement.hpp" + +std::optional IPassElement::boundingBox() { + return std::nullopt; +} + +CRegion IPassElement::opaqueRegion() { + return {}; +} + +bool IPassElement::disableSimplification() { + return false; +} + +void IPassElement::discard() { + ; +} diff --git a/src/render/pass/PassElement.hpp b/src/render/pass/PassElement.hpp new file mode 100644 index 00000000..025840f4 --- /dev/null +++ b/src/render/pass/PassElement.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "../../defines.hpp" +#include + +class IPassElement { + public: + virtual ~IPassElement() = default; + + virtual void draw(const CRegion& damage) = 0; + virtual bool needsLiveBlur() = 0; + virtual bool needsPrecomputeBlur() = 0; + virtual const char* passName() = 0; + virtual void discard(); + virtual std::optional boundingBox(); + virtual CRegion opaqueRegion(); + virtual bool disableSimplification(); +}; diff --git a/src/render/pass/PreBlurElement.cpp b/src/render/pass/PreBlurElement.cpp new file mode 100644 index 00000000..9fa3471d --- /dev/null +++ b/src/render/pass/PreBlurElement.cpp @@ -0,0 +1,20 @@ +#include "PreBlurElement.hpp" +#include "../OpenGL.hpp" + +CPreBlurElement::CPreBlurElement() = default; + +void CPreBlurElement::draw(const CRegion& damage) { + g_pHyprOpenGL->preBlurForCurrentMonitor(); +} + +bool CPreBlurElement::needsLiveBlur() { + return false; +} + +bool CPreBlurElement::needsPrecomputeBlur() { + return false; +} + +bool CPreBlurElement::disableSimplification() { + return true; +} diff --git a/src/render/pass/PreBlurElement.hpp b/src/render/pass/PreBlurElement.hpp new file mode 100644 index 00000000..6c52c815 --- /dev/null +++ b/src/render/pass/PreBlurElement.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "PassElement.hpp" + +class CPreBlurElement : public IPassElement { + public: + CPreBlurElement(); + virtual ~CPreBlurElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + virtual bool disableSimplification(); + + virtual const char* passName() { + return "CPreBlurElement"; + } +}; \ No newline at end of file diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp new file mode 100644 index 00000000..73727e58 --- /dev/null +++ b/src/render/pass/RectPassElement.cpp @@ -0,0 +1,29 @@ +#include "RectPassElement.hpp" +#include "../OpenGL.hpp" + +CRectPassElement::CRectPassElement(const CRectPassElement::SRectData& data_) : data(data_) { + ; +} + +void CRectPassElement::draw(const CRegion& damage) { + if (data.color.a == 1.F || !data.blur) + g_pHyprOpenGL->renderRectWithDamage(&data.box, data.color, damage, data.round); + else + g_pHyprOpenGL->renderRectWithBlur(&data.box, data.color, data.round, data.blurA, data.xray); +} + +bool CRectPassElement::needsLiveBlur() { + return data.color.a < 1.F && !data.xray && data.blur; +} + +bool CRectPassElement::needsPrecomputeBlur() { + return data.color.a < 1.F && data.xray && data.blur; +} + +std::optional CRectPassElement::boundingBox() { + return data.box.expand(-data.round); +} + +CRegion CRectPassElement::opaqueRegion() { + return data.color.a >= 1.F ? *boundingBox() : CRegion{}; +} diff --git a/src/render/pass/RectPassElement.hpp b/src/render/pass/RectPassElement.hpp new file mode 100644 index 00000000..32111a43 --- /dev/null +++ b/src/render/pass/RectPassElement.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "PassElement.hpp" + +class CRectPassElement : public IPassElement { + public: + struct SRectData { + CBox box; + CHyprColor color; + int round = 0; + bool blur = false, xray = false; + float blurA = 1.F; + }; + + CRectPassElement(const SRectData& data); + virtual ~CRectPassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + virtual std::optional boundingBox(); + virtual CRegion opaqueRegion(); + + virtual const char* passName() { + return "CRectPassElement"; + } + + private: + SRectData data; +}; \ No newline at end of file diff --git a/src/render/pass/ShadowPassElement.cpp b/src/render/pass/ShadowPassElement.cpp new file mode 100644 index 00000000..22910c96 --- /dev/null +++ b/src/render/pass/ShadowPassElement.cpp @@ -0,0 +1,19 @@ +#include "ShadowPassElement.hpp" +#include "../OpenGL.hpp" +#include "../decorations/CHyprDropShadowDecoration.hpp" + +CShadowPassElement::CShadowPassElement(const CShadowPassElement::SShadowData& data_) : data(data_) { + ; +} + +void CShadowPassElement::draw(const CRegion& damage) { + data.deco->render(g_pHyprOpenGL->m_RenderData.pMonitor.lock(), data.a); +} + +bool CShadowPassElement::needsLiveBlur() { + return false; +} + +bool CShadowPassElement::needsPrecomputeBlur() { + return false; +} \ No newline at end of file diff --git a/src/render/pass/ShadowPassElement.hpp b/src/render/pass/ShadowPassElement.hpp new file mode 100644 index 00000000..715e7bfb --- /dev/null +++ b/src/render/pass/ShadowPassElement.hpp @@ -0,0 +1,26 @@ +#pragma once +#include "PassElement.hpp" + +class CHyprDropShadowDecoration; + +class CShadowPassElement : public IPassElement { + public: + struct SShadowData { + CHyprDropShadowDecoration* deco = nullptr; + float a = 1.F; + }; + + CShadowPassElement(const SShadowData& data_); + virtual ~CShadowPassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + + virtual const char* passName() { + return "CShadowPassElement"; + } + + private: + SShadowData data; +}; \ No newline at end of file diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp new file mode 100644 index 00000000..38de5210 --- /dev/null +++ b/src/render/pass/SurfacePassElement.cpp @@ -0,0 +1,230 @@ +#include "SurfacePassElement.hpp" +#include "../OpenGL.hpp" +#include "../../desktop/WLSurface.hpp" +#include "../../protocols/core/Compositor.hpp" +#include "../../protocols/DRMSyncobj.hpp" +#include "../../managers/input/InputManager.hpp" +#include "../Renderer.hpp" + +#include +using namespace Hyprutils::Utils; + +CSurfacePassElement::CSurfacePassElement(const CSurfacePassElement::SRenderData& data_) : data(data_) { + ; +} + +void CSurfacePassElement::draw(const CRegion& damage) { + g_pHyprOpenGL->m_RenderData.currentWindow = data.pWindow; + g_pHyprOpenGL->m_RenderData.currentLS = data.pLS; + g_pHyprOpenGL->m_RenderData.clipBox = data.clipBox; + g_pHyprOpenGL->m_RenderData.discardMode = data.discardMode; + g_pHyprOpenGL->m_RenderData.discardOpacity = data.discardOpacity; + g_pHyprOpenGL->m_RenderData.useNearestNeighbor = data.useNearestNeighbor; + g_pHyprOpenGL->m_bEndFrame = data.flipEndFrame; + + CScopeGuard x = {[]() { + g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); + g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); + g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; + g_pHyprOpenGL->m_RenderData.clipBox = {}; + g_pHyprOpenGL->m_RenderData.discardMode = 0; + g_pHyprOpenGL->m_RenderData.discardOpacity = 0; + g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; + g_pHyprOpenGL->m_bEndFrame = false; + g_pHyprOpenGL->m_RenderData.currentWindow.reset(); + g_pHyprOpenGL->m_RenderData.currentLS.reset(); + }}; + + if (!data.texture) + return; + + const auto& TEXTURE = data.texture; + + // this is bad, probably has been logged elsewhere. Means the texture failed + // uploading to the GPU. + if (!TEXTURE->m_iTexID) + return; + + // explicit sync: wait for the timeline, if any + if (data.surface->syncobj && data.surface->syncobj->current.acquireTimeline) { + if (!g_pHyprOpenGL->waitForTimelinePoint(data.surface->syncobj->current.acquireTimeline->timeline, data.surface->syncobj->current.acquirePoint)) { + Debug::log(ERR, "Renderer: failed to wait for explicit timeline"); + return; + } + } + + const auto INTERACTIVERESIZEINPROGRESS = data.pWindow && g_pInputManager->currentlyDraggedWindow && g_pInputManager->dragMode == MBIND_RESIZE; + TRACY_GPU_ZONE("RenderSurface"); + + auto PSURFACE = CWLSurface::fromResource(data.surface); + + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const bool BLUR = data.blur && (!TEXTURE->m_bOpaque || ALPHA < 1.F); + + auto windowBox = getTexBox(); + + const auto PROJSIZEUNSCALED = windowBox.size(); + + windowBox.scale(data.pMonitor->scale); + windowBox.round(); + + if (windowBox.width <= 1 || windowBox.height <= 1) { + discard(); + return; + } + + const bool MISALIGNEDFSV1 = std::floor(data.pMonitor->scale) != data.pMonitor->scale /* Fractional */ && data.surface->current.scale == 1 /* fs protocol */ && + windowBox.size() != data.surface->current.bufferSize /* misaligned */ && DELTALESSTHAN(windowBox.width, data.surface->current.bufferSize.x, 3) && + DELTALESSTHAN(windowBox.height, data.surface->current.bufferSize.y, 3) /* off by one-or-two */ && + (!data.pWindow || (!data.pWindow->m_vRealSize.isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */; + + g_pHyprRenderer->calculateUVForSurface(data.pWindow, data.surface, data.pMonitor->self.lock(), data.mainSurface, windowBox.size(), PROJSIZEUNSCALED, MISALIGNEDFSV1); + + // check for fractional scale surfaces misaligning the buffer size + // in those cases it's better to just force nearest neighbor + // as long as the window is not animated. During those it'd look weird. + // UV will fixup it as well + if (MISALIGNEDFSV1) + g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; + + float rounding = data.rounding; + + rounding -= 1; // to fix a border issue + + if (data.dontRound) + rounding = 0; + + const bool WINDOWOPAQUE = data.pWindow && data.pWindow->m_pWLSurface->resource() == data.surface ? data.pWindow->opaque() : false; + const bool CANDISABLEBLEND = ALPHA >= 1.f && rounding == 0 && WINDOWOPAQUE; + + if (CANDISABLEBLEND) + g_pHyprOpenGL->blend(false); + else + g_pHyprOpenGL->blend(true); + + // FIXME: This is wrong and will bug the blur out as shit if the first surface + // is a subsurface that does NOT cover the entire frame. In such cases, we probably should fall back + // to what we do for misaligned surfaces (blur the entire thing and then render shit without blur) + if (data.surfaceCounter == 0 && !data.popup) { + if (BLUR) + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, data.blockBlurOptimization, data.fadeAlpha); + else + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA, rounding, false, true); + } else { + if (BLUR && data.popup) + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, true, data.fadeAlpha); + else + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA, rounding, false, true); + } + + if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) + data.surface->presentFeedback(data.when, data.pMonitor->self.lock()); + + g_pHyprOpenGL->blend(true); +} + +CBox CSurfacePassElement::getTexBox() { + const double outputX = -data.pMonitor->vecPosition.x, outputY = -data.pMonitor->vecPosition.y; + + const auto INTERACTIVERESIZEINPROGRESS = data.pWindow && g_pInputManager->currentlyDraggedWindow && g_pInputManager->dragMode == MBIND_RESIZE; + auto PSURFACE = CWLSurface::fromResource(data.surface); + + CBox windowBox; + if (data.surface && data.mainSurface) { + windowBox = {(int)outputX + data.pos.x + data.localPos.x, (int)outputY + data.pos.y + data.localPos.y, data.w, data.h}; + + // however, if surface buffer w / h < box, we need to adjust them + const auto PWINDOW = PSURFACE ? PSURFACE->getWindow() : nullptr; + + // center the surface if it's smaller than the viewport we assign it + if (PSURFACE && !PSURFACE->m_bFillIgnoreSmall && PSURFACE->small() /* guarantees PWINDOW */) { + const auto CORRECT = PSURFACE->correctSmallVec(); + const auto SIZE = PSURFACE->getViewporterCorrectedSize(); + + if (!INTERACTIVERESIZEINPROGRESS) { + windowBox.translate(CORRECT); + + windowBox.width = SIZE.x * (PWINDOW->m_vRealSize.value().x / PWINDOW->m_vReportedSize.x); + windowBox.height = SIZE.y * (PWINDOW->m_vRealSize.value().y / PWINDOW->m_vReportedSize.y); + } else { + windowBox.width = SIZE.x; + windowBox.height = SIZE.y; + } + } + + } else { // here we clamp to 2, these might be some tiny specks + windowBox = {(int)outputX + data.pos.x + data.localPos.x, (int)outputY + data.pos.y + data.localPos.y, std::max((float)data.surface->current.size.x, 2.F), + std::max((float)data.surface->current.size.y, 2.F)}; + if (data.pWindow && data.pWindow->m_vRealSize.isBeingAnimated() && data.surface && !data.mainSurface && data.squishOversized /* subsurface */) { + // adjust subsurfaces to the window + windowBox.width = (windowBox.width / data.pWindow->m_vReportedSize.x) * data.pWindow->m_vRealSize.value().x; + windowBox.height = (windowBox.height / data.pWindow->m_vReportedSize.y) * data.pWindow->m_vRealSize.value().y; + } + } + + if (data.squishOversized) { + if (data.localPos.x + windowBox.width > data.w) + windowBox.width = data.w - data.localPos.x; + if (data.localPos.y + windowBox.height > data.h) + windowBox.height = data.h - data.localPos.y; + } + + return windowBox; +} + +bool CSurfacePassElement::needsLiveBlur() { + auto PSURFACE = CWLSurface::fromResource(data.surface); + + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const bool BLUR = data.blur && (!data.texture || !data.texture->m_bOpaque || ALPHA < 1.F); + + if (!data.pLS && !data.pWindow) + return BLUR; + + const bool NEWOPTIM = g_pHyprOpenGL->shouldUseNewBlurOptimizations(data.pLS, data.pWindow); + + return BLUR && !NEWOPTIM; +} + +bool CSurfacePassElement::needsPrecomputeBlur() { + auto PSURFACE = CWLSurface::fromResource(data.surface); + + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const bool BLUR = data.blur && (!data.texture || !data.texture->m_bOpaque || ALPHA < 1.F); + + if (!data.pLS && !data.pWindow) + return BLUR; + + const bool NEWOPTIM = g_pHyprOpenGL->shouldUseNewBlurOptimizations(data.pLS, data.pWindow); + + return BLUR && NEWOPTIM; +} + +std::optional CSurfacePassElement::boundingBox() { + return getTexBox(); +} + +CRegion CSurfacePassElement::opaqueRegion() { + auto PSURFACE = CWLSurface::fromResource(data.surface); + + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + + if (ALPHA < 1.F) + return {}; + + if (data.surface && data.surface->current.size == Vector2D{data.w, data.h}) { + CRegion opaqueSurf = data.surface->current.opaque.copy().intersect(CBox{{}, {data.w, data.h}}); + const auto texBox = getTexBox(); + opaqueSurf.scale(texBox.size() / Vector2D{data.w, data.h}); + return opaqueSurf.translate(data.pos + data.localPos - data.pMonitor->vecPosition).expand(-data.rounding); + } + + return data.texture && data.texture->m_bOpaque ? boundingBox()->expand(-data.rounding) : CRegion{}; +} + +void CSurfacePassElement::discard() { + if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) { + Debug::log(TRACE, "discard for invisible surface"); + data.surface->presentFeedback(data.when, data.pMonitor->self.lock(), true); + } +} diff --git a/src/render/pass/SurfacePassElement.hpp b/src/render/pass/SurfacePassElement.hpp new file mode 100644 index 00000000..746c5a64 --- /dev/null +++ b/src/render/pass/SurfacePassElement.hpp @@ -0,0 +1,82 @@ +#pragma once +#include "PassElement.hpp" +#include + +class CWLSurfaceResource; +class CTexture; +class CSyncTimeline; + +class CSurfacePassElement : public IPassElement { + public: + struct SRenderData { + PHLMONITORREF pMonitor; + timespec* when = nullptr; + Vector2D pos, localPos; + + // for iters + void* data = nullptr; + SP surface = nullptr; + SP texture = nullptr; + bool mainSurface = true; + double w = 0, h = 0; + + // for rounding + bool dontRound = true; + + // for fade + float fadeAlpha = 1.f; + + // for alpha settings + float alpha = 1.f; + + // for decorations (border) + bool decorate = false; + + // for custom round values + int rounding = -1; // -1 means not set + + // for blurring + bool blur = false; + bool blockBlurOptimization = false; + + // only for windows, not popups + bool squishOversized = true; + + // for calculating UV + PHLWINDOW pWindow; + PHLLS pLS; + + bool popup = false; + + // counts how many surfaces this pass has rendered + int surfaceCounter = 0; + + CBox clipBox = {}; // scaled coordinates + + uint32_t discardMode = 0; + float discardOpacity = 0.f; + + bool useNearestNeighbor = false; + + bool flipEndFrame = false; + }; + + CSurfacePassElement(const SRenderData& data); + virtual ~CSurfacePassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + virtual std::optional boundingBox(); + virtual CRegion opaqueRegion(); + virtual void discard(); + + virtual const char* passName() { + return "CSurfacePassElement"; + } + + private: + SRenderData data; + + CBox getTexBox(); +}; \ No newline at end of file diff --git a/src/render/pass/TexPassElement.cpp b/src/render/pass/TexPassElement.cpp new file mode 100644 index 00000000..05f756dc --- /dev/null +++ b/src/render/pass/TexPassElement.cpp @@ -0,0 +1,44 @@ +#include "TexPassElement.hpp" +#include "../OpenGL.hpp" + +#include +using namespace Hyprutils::Utils; + +CTexPassElement::CTexPassElement(const CTexPassElement::SRenderData& data_) : data(data_) { + ; +} + +void CTexPassElement::draw(const CRegion& damage) { + g_pHyprOpenGL->m_bEndFrame = data.flipEndFrame; + + CScopeGuard x = {[]() { + // + g_pHyprOpenGL->m_bEndFrame = false; + }}; + + if (data.replaceProjection) + g_pHyprOpenGL->m_RenderData.monitorProjection = *data.replaceProjection; + g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, &data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.syncTimeline, data.syncPoint); + if (data.replaceProjection) + g_pHyprOpenGL->m_RenderData.monitorProjection = g_pHyprOpenGL->m_RenderData.pMonitor->projMatrix; +} + +bool CTexPassElement::needsLiveBlur() { + return false; // TODO? +} + +bool CTexPassElement::needsPrecomputeBlur() { + return false; // TODO? +} + +std::optional CTexPassElement::boundingBox() { + return data.box.copy().scale(1.F / g_pHyprOpenGL->m_RenderData.pMonitor->scale).round(); +} + +CRegion CTexPassElement::opaqueRegion() { + return {}; // TODO: +} + +void CTexPassElement::discard() { + ; +} diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp new file mode 100644 index 00000000..bf896951 --- /dev/null +++ b/src/render/pass/TexPassElement.hpp @@ -0,0 +1,39 @@ +#pragma once +#include "PassElement.hpp" +#include + +class CWLSurfaceResource; +class CTexture; +class CSyncTimeline; + +class CTexPassElement : public IPassElement { + public: + struct SRenderData { + SP tex; + CBox box; + float a = 1.F; + CRegion damage; + int round = 0; + bool flipEndFrame = false; + SP syncTimeline; + int64_t syncPoint = 0; + std::optional replaceProjection; + }; + + CTexPassElement(const SRenderData& data); + virtual ~CTexPassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + virtual std::optional boundingBox(); + virtual CRegion opaqueRegion(); + virtual void discard(); + + virtual const char* passName() { + return "CTexPassElement"; + } + + private: + SRenderData data; +}; \ No newline at end of file diff --git a/src/render/pass/TextureMatteElement.cpp b/src/render/pass/TextureMatteElement.cpp new file mode 100644 index 00000000..5aed1c9a --- /dev/null +++ b/src/render/pass/TextureMatteElement.cpp @@ -0,0 +1,25 @@ +#include "TextureMatteElement.hpp" +#include "../OpenGL.hpp" + +CTextureMatteElement::CTextureMatteElement(const CTextureMatteElement::STextureMatteData& data_) : data(data_) { + ; +} + +void CTextureMatteElement::draw(const CRegion& damage) { + if (data.disableTransformAndModify) { + g_pHyprOpenGL->setMonitorTransformEnabled(true); + g_pHyprOpenGL->setRenderModifEnabled(false); + g_pHyprOpenGL->renderTextureMatte(data.tex, &data.box, *data.fb); + g_pHyprOpenGL->setRenderModifEnabled(true); + g_pHyprOpenGL->setMonitorTransformEnabled(false); + } else + g_pHyprOpenGL->renderTextureMatte(data.tex, &data.box, *data.fb); +} + +bool CTextureMatteElement::needsLiveBlur() { + return false; +} + +bool CTextureMatteElement::needsPrecomputeBlur() { + return false; +} \ No newline at end of file diff --git a/src/render/pass/TextureMatteElement.hpp b/src/render/pass/TextureMatteElement.hpp new file mode 100644 index 00000000..bf673946 --- /dev/null +++ b/src/render/pass/TextureMatteElement.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "PassElement.hpp" +#include "../Framebuffer.hpp" + +class CTexture; + +class CTextureMatteElement : public IPassElement { + public: + struct STextureMatteData { + CBox box; + SP tex; + SP fb; + bool disableTransformAndModify = false; + }; + + CTextureMatteElement(const STextureMatteData& data_); + virtual ~CTextureMatteElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + + virtual const char* passName() { + return "CTextureMatteElement"; + } + + private: + STextureMatteData data; +}; \ No newline at end of file From 1830296df3515222bf0f03b90822e3b23e74b775 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 22 Dec 2024 17:20:33 +0000 Subject: [PATCH 0025/1444] debug: add debug:pass for debugging the render pass --- src/config/ConfigManager.cpp | 1 + src/render/pass/Pass.cpp | 30 ++++++++++++++++++++++++++++-- src/render/pass/Pass.hpp | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 9b6e29e4..f9ad54aa 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -413,6 +413,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("debug:log_damage", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:overlay", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:damage_blink", Hyprlang::INT{0}); + m_pConfig->addConfigValue("debug:pass", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:disable_logs", Hyprlang::INT{1}); m_pConfig->addConfigValue("debug:disable_time", Hyprlang::INT{1}); m_pConfig->addConfigValue("debug:enable_stdout_logs", Hyprlang::INT{0}); diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 31385acb..b6256c44 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -21,6 +21,8 @@ void CRenderPass::add(SP el) { } void CRenderPass::simplify() { + static auto PDEBUGPASS = CConfigValue("debug:pass"); + // TODO: use precompute blur for instances where there is nothing in between // if there is live blur, we need to NOT occlude any area where it will be influenced @@ -78,6 +80,20 @@ void CRenderPass::simplify() { } } newDamage.subtract(opaque); + if (*PDEBUGPASS) + occludedRegion.add(opaque); + } + } + + if (*PDEBUGPASS) { + for (auto& el2 : m_vPassElements) { + if (!el2->element->needsLiveBlur()) + continue; + + const auto BB = el2->element->boundingBox(); + RASSERT(BB, "No bounding box for an element with live blur is illegal"); + + totalLiveBlurRegion.add(*BB); } } } @@ -87,9 +103,13 @@ void CRenderPass::clear() { } CRegion CRenderPass::render(const CRegion& damage_) { - const auto WILLBLUR = std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->needsLiveBlur(); }); + static auto PDEBUGPASS = CConfigValue("debug:pass"); - damage = damage_.copy(); + const auto WILLBLUR = std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->needsLiveBlur(); }); + + damage = *PDEBUGPASS ? CRegion{CBox{{}, {INT32_MAX, INT32_MAX}}} : damage_.copy(); + occludedRegion = CRegion{}; + totalLiveBlurRegion = CRegion{}; if (damage.empty()) { g_pHyprOpenGL->m_RenderData.damage = damage; @@ -145,6 +165,12 @@ CRegion CRenderPass::render(const CRegion& damage_) { el->element->draw(el->elementDamage); } + if (*PDEBUGPASS) { + CBox monbox = {{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}; + g_pHyprOpenGL->renderRectWithDamage(&monbox, CHyprColor{1.F, 0.1F, 0.1F, 0.5F}, occludedRegion); + g_pHyprOpenGL->renderRectWithDamage(&monbox, CHyprColor{0.1F, 1.F, 0.1F, 0.5F}, totalLiveBlurRegion); + } + g_pHyprOpenGL->m_RenderData.damage = damage; return damage; } diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp index 7f332c19..6fe6938f 100644 --- a/src/render/pass/Pass.hpp +++ b/src/render/pass/Pass.hpp @@ -18,6 +18,8 @@ class CRenderPass { private: CRegion damage; + CRegion occludedRegion; + CRegion totalLiveBlurRegion; struct SPassElementData { CRegion elementDamage; From a4a4fffffb74eb40a8ab9cf4606a3edbb4e9fbd9 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 22 Dec 2024 22:07:08 +0000 Subject: [PATCH 0026/1444] renderer: allow plugins to know what window was rendered in post --- src/render/Renderer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 0f8db3bb..d8b8a847 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -555,7 +555,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe }, nullptr); - g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; + renderdata.useNearestNeighbor = false; if (renderdata.decorate) { for (auto const& wd : pWindow->m_dWindowDecorations) { @@ -638,7 +638,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe } } + // for plugins + g_pHyprOpenGL->m_RenderData.currentWindow = pWindow; + EMIT_HOOK_EVENT("render", RENDER_POST_WINDOW); + + g_pHyprOpenGL->m_RenderData.currentWindow.reset(); } void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* time, bool popups) { From 5f7ad767dbf0bac9ddd6bf6c825fb9ed7921308a Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 23 Dec 2024 00:39:17 +0200 Subject: [PATCH 0027/1444] flake.lock: update --- flake.lock | 60 +++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/flake.lock b/flake.lock index 66500c0c..6c7a09b4 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1734400729, - "narHash": "sha256-Bf+oya0BuleVXYGIWsb0eWnrK6s0aiesOsI7Mpj1pMU=", + "lastModified": 1734906446, + "narHash": "sha256-6OWluVE2A8xi+8V3jN9KA72RCgJjYdyyuLBUjxZ2q2U=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "a132fa41be7ebe797ad758e84d9df068151a723b", + "rev": "eecb74dc79bb6752a2a507e6edee3042390a6091", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1734364709, - "narHash": "sha256-+2bZJL2u5hva7rSp65OfKJBK+k03T6GB/NCvpoS1OOo=", + "lastModified": 1734906540, + "narHash": "sha256-vQ/L9hZFezC0LquLo4TWXkyniWtYBlFHAKIsDc7PYJE=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "f388aacd22be4a6e4d634fbaf6f75eb0713d239a", + "rev": "69270ba8f057d55b0e6c2dca0e165d652856e613", "type": "github" }, "original": { @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1733684019, - "narHash": "sha256-2kYREgmSmbLsmDpLEq96hxVAU3qz8aCvVhF65yCFZHY=", + "lastModified": 1734906236, + "narHash": "sha256-vH/ysV2ONGQgYZPtcJKwc8jJivzyVxru2aaOxC20ZOE=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "fb2c0268645a77403af3b8a4ce8fa7ba5917f15d", + "rev": "6dea3fba08fd704dd624b6d4b261638fb4003c9c", "type": "github" }, "original": { @@ -154,11 +154,11 @@ ] }, "locked": { - "lastModified": 1733940128, - "narHash": "sha256-hmfXWj2GA9cj1QUkPFYtAAeohhs615zL4E3APy3FnvQ=", + "lastModified": 1734906472, + "narHash": "sha256-pWPRv/GA/X/iAwoE6gMNUqn/ZeJX1IeLPRpZI0tTPK0=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "3833097e50473a152dd614d4b468886840b4ea78", + "rev": "c77109d7e1ddbcdb87cafd32ce411f76328ae152", "type": "github" }, "original": { @@ -180,11 +180,11 @@ ] }, "locked": { - "lastModified": 1734364628, - "narHash": "sha256-ii8fzJfI953n/EmIxVvq64ZAwhvwuuPHWfGd61/mJG8=", + "lastModified": 1734906259, + "narHash": "sha256-P79t/7HbACO4/PuJBroGpTptvCWJtXTv+gWsF+sM6MI=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "16e59c1eb13d9fb6de066f54e7555eb5e8a4aba5", + "rev": "0404833ea18d543df44df935ebf1b497310eb046", "type": "github" }, "original": { @@ -203,11 +203,11 @@ ] }, "locked": { - "lastModified": 1734384247, - "narHash": "sha256-bl3YyJb2CgaeVKYq/l8j27vKdbkTpDNFDsnCl0dnNlY=", + "lastModified": 1734796073, + "narHash": "sha256-TnuKsa8OHrSJEmHm3TLGOWbPNA1gRjmZLsRzKrCqOsg=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "e6cf45cd1845368702e03b8912f4cc44ebba3322", + "rev": "c3331116ebd0b71df5ae8c6efe9a7f94148b03bf", "type": "github" }, "original": { @@ -226,11 +226,11 @@ ] }, "locked": { - "lastModified": 1734384417, - "narHash": "sha256-noYeXcNQ15g1/gIJIYT2zdO66wzY5Z06PYz6BfKUZA8=", + "lastModified": 1734793513, + "narHash": "sha256-rrrHcXapXJvGFqX+L/Bb0182L25jofAZ0fm1FInvrTQ=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "90e87f7fcfcce4862826d60332cbc5e2f87e1f88", + "rev": "4d7367b6eee87397e2dbca2e78078dd0a4ef4c61", "type": "github" }, "original": { @@ -241,11 +241,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1734119587, - "narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=", + "lastModified": 1734649271, + "narHash": "sha256-4EVBRhOjMDuGtMaofAIqzJbg4Ql7Ai0PSeuVZTHjyKQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5", + "rev": "d70bd19e0a38ad4790d3913bf08fcbfc9eeca507", "type": "github" }, "original": { @@ -281,11 +281,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1734379367, - "narHash": "sha256-Keu8z5VgT5gnCF4pmB+g7XZFftHpfl4qOn7nqBcywdE=", + "lastModified": 1734797603, + "narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "0bb4be58f21ff38fc3cdbd6c778eb67db97f0b99", + "rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498", "type": "github" }, "original": { @@ -347,11 +347,11 @@ ] }, "locked": { - "lastModified": 1734422917, - "narHash": "sha256-0y7DRaXslhfqVKV8a/talYTYAe2NHOQhMZG7KMNRCtc=", + "lastModified": 1734907020, + "narHash": "sha256-p6HxwpRKVl1KIiY5xrJdjcEeK3pbmc///UOyV6QER+w=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "3e884d941ca819c1f2e50df8bdae0debded1ed87", + "rev": "d7f18dda5e511749fa1511185db3536208fb1a63", "type": "github" }, "original": { From 68a5842f06e33d381e9afbf9c9492ba5a7aa2d0f Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 23 Dec 2024 20:07:12 +0200 Subject: [PATCH 0028/1444] Nix: fix TAG substitution --- nix/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nix/default.nix b/nix/default.nix index 50f0560f..9293a35c 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -50,12 +50,12 @@ nvidiaPatches ? false, hidpiXWayland ? false, }: let - inherit (builtins) baseNameOf foldl'; + inherit (builtins) baseNameOf foldl' readFile; inherit (lib.asserts) assertMsg; inherit (lib.attrsets) mapAttrsToList; inherit (lib.lists) flatten concatLists optional optionals; inherit (lib.sources) cleanSourceWith cleanSource; - inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable; + inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable trim; adapters = flatten [ stdenvAdapters.useMoldLinker @@ -91,7 +91,7 @@ in DATE = date; DIRTY = optionalString (commit == "") "dirty"; HASH = commit; - TAG = "v${builtins.readFile "${finalAttrs.src}/VERSION"}"; + TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}"; depsBuildBuild = [ pkg-config From 2e2e2e2cad97eb017ab02f8a67b751e0abe3bb72 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 23 Dec 2024 21:14:54 +0000 Subject: [PATCH 0029/1444] monitor: bring back old description behavior this makes description match the beginning again. Fixes #8756 --- src/helpers/Monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 33ec3abe..89a833d4 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -412,7 +412,7 @@ bool CMonitor::matchesStaticSelector(const std::string& selector) const { // match by description const auto DESCRIPTIONSELECTOR = selector.substr(5); - return DESCRIPTIONSELECTOR == szShortDescription || DESCRIPTIONSELECTOR == szDescription; + return szDescription.starts_with(DESCRIPTIONSELECTOR) || szShortDescription.starts_with(DESCRIPTIONSELECTOR); } else { // match by selector return szName == selector; From 2a24a61126dcebd2e1f7862e5c21c105900110ac Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 25 Dec 2024 00:24:57 +0100 Subject: [PATCH 0030/1444] pass: improve blur region detection --- src/render/pass/Pass.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index b6256c44..69a12293 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -73,10 +73,13 @@ void CRenderPass::simplify() { liveBlurRegion.add(*BB); } + // expand the region: this area needs to be proper to blur it right. + liveBlurRegion.expand(oneBlurRadius() * 2.F); + if (auto infringement = opaque.copy().intersect(liveBlurRegion); !infringement.empty()) { // eh, this is not the correct solution, but it will do... // TODO: is this *easily* fixable? - opaque.subtract(infringement.expand(oneBlurRadius())); + opaque.subtract(infringement); } } newDamage.subtract(opaque); @@ -117,7 +120,7 @@ CRegion CRenderPass::render(const CRegion& damage_) { return damage; } - if (WILLBLUR) { + if (WILLBLUR && !*PDEBUGPASS) { // combine blur regions into one that will be expanded CRegion blurRegion; for (auto& el : m_vPassElements) { From 1a3d17da9150f255ff2144cbe8317c0200de0ee4 Mon Sep 17 00:00:00 2001 From: staz Date: Wed, 25 Dec 2024 04:32:18 +0500 Subject: [PATCH 0031/1444] debug: fix ISDEBUG checking (#8823) --- src/debug/CrashReporter.cpp | 2 +- src/debug/HyprCtl.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/debug/CrashReporter.cpp b/src/debug/CrashReporter.cpp index bddc04be..7bff7295 100644 --- a/src/debug/CrashReporter.cpp +++ b/src/debug/CrashReporter.cpp @@ -111,7 +111,7 @@ void NCrashReporter::createAndSaveCrash(int sig) { #ifdef LEGACY_RENDERER finalCrashReport += "legacyrenderer\n"; #endif -#ifndef ISDEBUG +#if ISDEBUG finalCrashReport += "debug\n"; #endif #ifdef NO_XWAYLAND diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index da0b2e28..b946da6e 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -884,14 +884,14 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) { HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS, AQUAMARINE_VERSION, HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION); -#if (!defined(LEGACY_RENDERER) && !defined(ISDEBUG) && !defined(NO_XWAYLAND)) +#if (!defined(LEGACY_RENDERER) && !ISDEBUG && !defined(NO_XWAYLAND)) result += "no flags were set\n"; #else result += "flags set:\n"; #ifdef LEGACY_RENDERER result += "legacyrenderer\n"; #endif -#ifdef ISDEBUG +#if ISDEBUG result += "debug\n"; #endif #ifdef NO_XWAYLAND @@ -922,7 +922,7 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) { #ifdef LEGACY_RENDERER result += "\"legacyrenderer\","; #endif -#ifdef ISDEBUG +#if ISDEBUG result += "\"debug\","; #endif #ifdef NO_XWAYLAND From dddb64dc353ec9ef73be22d1cc1441782fb44068 Mon Sep 17 00:00:00 2001 From: Avi Herman <45245854+avih7531@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:09:45 +0200 Subject: [PATCH 0032/1444] internal: added reference to CTimer class in KeybindManager (#8836) --- src/managers/KeybindManager.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index c8c6266c..02a39df9 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -8,6 +8,7 @@ #include #include "../devices/IPointer.hpp" #include "eventLoop/EventLoopTimer.hpp" +#include "../helpers/Timer.hpp" class CInputManager; class CConfigManager; From 2eaa4d80a0ecb56fc16c8ad4077b1b1a7d28281f Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 26 Dec 2024 00:16:42 +0100 Subject: [PATCH 0033/1444] debug: fix overlay not rendering --- src/debug/HyprDebugOverlay.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp index 0df46086..d72e2144 100644 --- a/src/debug/HyprDebugOverlay.cpp +++ b/src/debug/HyprDebugOverlay.cpp @@ -2,6 +2,8 @@ #include "HyprDebugOverlay.hpp" #include "config/ConfigValue.hpp" #include "../Compositor.hpp" +#include "../render/pass/TexPassElement.hpp" +#include "../render/Renderer.hpp" CHyprDebugOverlay::CHyprDebugOverlay() { m_pTexture = makeShared(); @@ -268,6 +270,8 @@ void CHyprDebugOverlay::draw() { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA); - CBox pMonBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y}; - g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f); + CTexPassElement::SRenderData data; + data.tex = m_pTexture; + data.box = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } From e75e2cdac79417ffdbbbe903f72668953483a4e7 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 26 Dec 2024 11:29:42 +0100 Subject: [PATCH 0034/1444] functionHooks: wait for hyprland pages before returning addr for trampo ref #8845 --- src/plugins/HookSystem.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/plugins/HookSystem.cpp b/src/plugins/HookSystem.cpp index 38657a48..3baca5b1 100644 --- a/src/plugins/HookSystem.cpp +++ b/src/plugins/HookSystem.cpp @@ -271,6 +271,8 @@ static uintptr_t seekNewPageAddr() { uint64_t lastStart = 0, lastEnd = 0; + bool anchoredToHyprland = false; + std::string line; while (std::getline(MAPS, line)) { CVarList props{line, 0, 's', true}; @@ -300,6 +302,19 @@ static uintptr_t seekNewPageAddr() { } if (start - lastEnd > PAGESIZE_VAR * 2) { + if (!line.contains("Hyprland") && !anchoredToHyprland) { + Debug::log(LOG, "seekNewPageAddr: skipping gap 0x{:x}-0x{:x}, not anchored to Hyprland code pages yet.", lastEnd, start); + lastStart = start; + lastEnd = end; + continue; + } else if (!anchoredToHyprland) { + Debug::log(LOG, "seekNewPageAddr: Anchored to hyprland at 0x{:x}", start); + anchoredToHyprland = true; + lastStart = start; + lastEnd = end; + continue; + } + Debug::log(LOG, "seekNewPageAddr: found gap: 0x{:x}-0x{:x} ({} bytes)", lastEnd, start, start - lastEnd); MAPS.close(); return lastEnd; From 43ca66779b7d267cc6c52bdea75d3ff8eb60132f Mon Sep 17 00:00:00 2001 From: Tuur Vanhoutte <4633209+zjeffer@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:40:46 +0100 Subject: [PATCH 0035/1444] hyprpm: use glaze to parse hyprctl plugin list (#8812) * Use std::filesystem::path in hyprpm DataState to avoid concatenating strings with (folder + "/" + file) * Added getPluginStates helper method in DataState * Small clang-tidy improvements --- .github/actions/setup_base/action.yml | 9 +++ hyprpm/CMakeLists.txt | 3 +- hyprpm/src/core/DataState.cpp | 107 ++++++++++++-------------- hyprpm/src/core/DataState.hpp | 22 +++--- hyprpm/src/core/PluginManager.cpp | 48 +++++------- hyprpm/src/meson.build | 1 + nix/default.nix | 4 + 7 files changed, 97 insertions(+), 97 deletions(-) diff --git a/.github/actions/setup_base/action.yml b/.github/actions/setup_base/action.yml index c510bb74..6df442b3 100644 --- a/.github/actions/setup_base/action.yml +++ b/.github/actions/setup_base/action.yml @@ -63,6 +63,15 @@ runs: librsvg \ re2 + - name: Get glaze + shell: bash + run: | + git clone https://github.com/stephenberry/glaze.git + cd glaze + cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build + cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF` + cmake --install build + - name: Get hyprwayland-scanner-git shell: bash run: | diff --git a/hyprpm/CMakeLists.txt b/hyprpm/CMakeLists.txt index 22cb8caa..8eb325fd 100644 --- a/hyprpm/CMakeLists.txt +++ b/hyprpm/CMakeLists.txt @@ -10,10 +10,11 @@ file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp") set(CMAKE_CXX_STANDARD 23) pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.2.4) +find_package(glaze REQUIRED) add_executable(hyprpm ${SRCFILES}) -target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps) +target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps glaze::glaze) # binary install(TARGETS hyprpm) diff --git a/hyprpm/src/core/DataState.cpp b/hyprpm/src/core/DataState.cpp index fb8679d6..55f148a4 100644 --- a/hyprpm/src/core/DataState.cpp +++ b/hyprpm/src/core/DataState.cpp @@ -1,11 +1,10 @@ #include "DataState.hpp" #include #include -#include #include #include "PluginManager.hpp" -std::string DataState::getDataStatePath() { +std::filesystem::path DataState::getDataStatePath() { const auto HOME = getenv("HOME"); if (!HOME) { std::println(stderr, "DataState: no $HOME"); @@ -16,12 +15,29 @@ std::string DataState::getDataStatePath() { const auto XDG_DATA_HOME = getenv("XDG_DATA_HOME"); if (XDG_DATA_HOME) - return std::string{XDG_DATA_HOME} + "/hyprpm"; - return std::string{HOME} + "/.local/share/hyprpm"; + return std::filesystem::path{XDG_DATA_HOME} / "hyprpm"; + return std::filesystem::path{HOME} / ".local/share/hyprpm"; } std::string DataState::getHeadersPath() { - return getDataStatePath() + "/headersRoot"; + return getDataStatePath() / "headersRoot"; +} + +std::vector DataState::getPluginStates() { + ensureStateStoreExists(); + + std::vector states; + for (const auto& entry : std::filesystem::directory_iterator(getDataStatePath())) { + if (!entry.is_directory() || entry.path().stem() == "headersRoot") + continue; + + const auto stateFile = entry.path() / "state.toml"; + if (!std::filesystem::exists(stateFile)) + continue; + + states.emplace_back(stateFile); + } + return states; } void DataState::ensureStateStoreExists() { @@ -37,7 +53,7 @@ void DataState::ensureStateStoreExists() { void DataState::addNewPluginRepo(const SPluginRepository& repo) { ensureStateStoreExists(); - const auto PATH = getDataStatePath() + "/" + repo.name; + const auto PATH = getDataStatePath() / repo.name; std::filesystem::create_directories(PATH); // clang-format off @@ -50,19 +66,21 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) { }} }; for (auto const& p : repo.plugins) { + const auto filename = p.name + ".so"; + // copy .so to the good place if (std::filesystem::exists(p.filename)) - std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so"); + std::filesystem::copy_file(p.filename, PATH / filename); DATA.emplace(p.name, toml::table{ - {"filename", p.name + ".so"}, + {"filename", filename}, {"enabled", p.enabled}, {"failed", p.failed} }); } // clang-format on - std::ofstream ofs(PATH + "/state.toml", std::ios::trunc); + std::ofstream ofs(PATH / "state.toml", std::ios::trunc); ofs << DATA; ofs.close(); } @@ -72,17 +90,10 @@ bool DataState::pluginRepoExists(const std::string& urlOrName) { const auto PATH = getDataStatePath(); - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); - - const auto NAME = STATE["repository"]["name"].value_or(""); - const auto URL = STATE["repository"]["url"].value_or(""); + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); + const auto NAME = STATE["repository"]["name"].value_or(""); + const auto URL = STATE["repository"]["url"].value_or(""); if (URL == urlOrName || NAME == urlOrName) return true; @@ -96,29 +107,22 @@ void DataState::removePluginRepo(const std::string& urlOrName) { const auto PATH = getDataStatePath(); - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); - - const auto NAME = STATE["repository"]["name"].value_or(""); - const auto URL = STATE["repository"]["url"].value_or(""); + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); + const auto NAME = STATE["repository"]["name"].value_or(""); + const auto URL = STATE["repository"]["url"].value_or(""); if (URL == urlOrName || NAME == urlOrName) { // unload the plugins!! - for (const auto& file : std::filesystem::directory_iterator(entry.path())) { + for (const auto& file : std::filesystem::directory_iterator(stateFile.parent_path())) { if (!file.path().string().ends_with(".so")) continue; g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false); } - std::filesystem::remove_all(entry.path()); + std::filesystem::remove_all(stateFile.parent_path()); return; } } @@ -139,7 +143,7 @@ void DataState::updateGlobalState(const SGlobalState& state) { }; // clang-format on - std::ofstream ofs(PATH + "/state.toml", std::ios::trunc); + std::ofstream ofs(PATH / "state.toml", std::ios::trunc); ofs << DATA; ofs.close(); } @@ -147,12 +151,12 @@ void DataState::updateGlobalState(const SGlobalState& state) { SGlobalState DataState::getGlobalState() { ensureStateStoreExists(); - const auto PATH = getDataStatePath(); + const auto stateFile = getDataStatePath() / "state.toml"; - if (!std::filesystem::exists(PATH + "/state.toml")) + if (!std::filesystem::exists(stateFile)) return SGlobalState{}; - auto DATA = toml::parse_file(PATH + "/state.toml"); + auto DATA = toml::parse_file(stateFile.c_str()); SGlobalState state; state.headersHashCompiled = DATA["state"]["hash"].value_or(""); @@ -167,15 +171,8 @@ std::vector DataState::getAllRepositories() { const auto PATH = getDataStatePath(); std::vector repos; - - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); const auto NAME = STATE["repository"]["name"].value_or(""); const auto URL = STATE["repository"]["url"].value_or(""); @@ -210,15 +207,8 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) { const auto PATH = getDataStatePath(); - for (const auto& entry : std::filesystem::directory_iterator(PATH)) { - if (!entry.is_directory() || entry.path().stem() == "headersRoot") - continue; - - if (!std::filesystem::exists(entry.path().string() + "/state.toml")) - continue; - - auto STATE = toml::parse_file(entry.path().string() + "/state.toml"); - + for (const auto& stateFile : getPluginStates()) { + const auto STATE = toml::parse_file(stateFile.c_str()); for (const auto& [key, val] : STATE) { if (key == "repository") continue; @@ -231,10 +221,11 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) { if (FAILED) return false; - (*STATE[key].as_table()).insert_or_assign("enabled", enabled); + auto modifiedState = STATE; + (*modifiedState[key].as_table()).insert_or_assign("enabled", enabled); - std::ofstream state(entry.path().string() + "/state.toml", std::ios::trunc); - state << STATE; + std::ofstream state(stateFile, std::ios::trunc); + state << modifiedState; state.close(); return true; diff --git a/hyprpm/src/core/DataState.hpp b/hyprpm/src/core/DataState.hpp index 70788f72..ebb550ba 100644 --- a/hyprpm/src/core/DataState.hpp +++ b/hyprpm/src/core/DataState.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include "Plugin.hpp" @@ -9,14 +10,15 @@ struct SGlobalState { }; namespace DataState { - std::string getDataStatePath(); - std::string getHeadersPath(); - void ensureStateStoreExists(); - void addNewPluginRepo(const SPluginRepository& repo); - void removePluginRepo(const std::string& urlOrName); - bool pluginRepoExists(const std::string& urlOrName); - void updateGlobalState(const SGlobalState& state); - SGlobalState getGlobalState(); - bool setPluginEnabled(const std::string& name, bool enabled); - std::vector getAllRepositories(); + std::filesystem::path getDataStatePath(); + std::string getHeadersPath(); + std::vector getPluginStates(); + void ensureStateStoreExists(); + void addNewPluginRepo(const SPluginRepository& repo); + void removePluginRepo(const std::string& urlOrName); + bool pluginRepoExists(const std::string& urlOrName); + void updateGlobalState(const SGlobalState& state); + SGlobalState getGlobalState(); + bool setPluginEnabled(const std::string& name, bool enabled); + std::vector getAllRepositories(); }; \ No newline at end of file diff --git a/hyprpm/src/core/PluginManager.cpp b/hyprpm/src/core/PluginManager.cpp index 48b108c8..a3bd5a09 100644 --- a/hyprpm/src/core/PluginManager.cpp +++ b/hyprpm/src/core/PluginManager.cpp @@ -7,10 +7,8 @@ #include #include -#include #include #include -#include #include #include #include @@ -21,6 +19,7 @@ #include #include +#include #include #include @@ -83,13 +82,13 @@ SHyprlandVersion CPluginManager::getHyprlandVersion(bool running) { hlbranch = hlbranch.substr(0, hlbranch.find(" at commit ")); std::string hldate = HLVERCALL.substr(HLVERCALL.find("Date: ") + 6); - hldate = hldate.substr(0, hldate.find("\n")); + hldate = hldate.substr(0, hldate.find('\n')); std::string hlcommits; if (HLVERCALL.contains("commits:")) { hlcommits = HLVERCALL.substr(HLVERCALL.find("commits:") + 9); - hlcommits = hlcommits.substr(0, hlcommits.find(" ")); + hlcommits = hlcommits.substr(0, hlcommits.find(' ')); } int commits = 0; @@ -378,7 +377,7 @@ eHeadersErrors CPluginManager::headersValid() { // find headers commit const std::string& cmd = std::format("PKG_CONFIG_PATH=\"{}/share/pkgconfig\" pkgconf --cflags --keep-system-cflags hyprland", DataState::getHeadersPath()); - auto headers = execAndGet(cmd.c_str()); + auto headers = execAndGet(cmd); if (!headers.contains("-I/")) return HEADERS_MISSING; @@ -790,35 +789,28 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() { const auto HOME = getenv("HOME"); const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE"); if (!HOME || !HIS) { - std::println(stderr, "PluginManager: no $HOME or HIS"); + std::println(stderr, "PluginManager: no $HOME or $HYPRLAND_INSTANCE_SIGNATURE"); return LOADSTATE_FAIL; } - const auto HYPRPMPATH = DataState::getDataStatePath() + "/"; + const auto HYPRPMPATH = DataState::getDataStatePath(); - auto pluginLines = execAndGet("hyprctl plugins list | grep Plugin"); + const auto json = glz::read_json(execAndGet("hyprctl plugins list -j")); + if (!json) { + std::println(stderr, "PluginManager: couldn't parse hyprctl output"); + return LOADSTATE_FAIL; + } std::vector loadedPlugins; + for (const auto& plugin : json.value()) { + if (!plugin.is_object() || !plugin.contains("name")) { + std::println(stderr, "PluginManager: couldn't parse plugin object"); + return LOADSTATE_FAIL; + } + loadedPlugins.emplace_back(plugin["name"].get()); + } std::println("{}", successString("Ensuring plugin load state")); - // iterate line by line - while (!pluginLines.empty()) { - auto plLine = pluginLines.substr(0, pluginLines.find('\n')); - - if (pluginLines.find('\n') != std::string::npos) - pluginLines = pluginLines.substr(pluginLines.find('\n') + 1); - else - pluginLines = ""; - - if (plLine.back() != ':') - continue; - - plLine = plLine.substr(7); - plLine = plLine.substr(0, plLine.find(" by ")); - - loadedPlugins.push_back(plLine); - } - // get state const auto REPOS = DataState::getAllRepositories(); @@ -853,7 +845,7 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() { for (auto const& p : loadedPlugins) { if (!enabled(p)) { // unload - if (!loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false)) { + if (!loadUnloadPlugin(HYPRPMPATH / repoForName(p) / (p + ".so"), false)) { std::println("{}", infoString("{} will be unloaded after restarting Hyprland", p)); hyprlandVersionMismatch = true; } else @@ -870,7 +862,7 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() { if (std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&](const auto& other) { return other == p.name; }) != loadedPlugins.end()) continue; - if (!loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true)) { + if (!loadUnloadPlugin(HYPRPMPATH / repoForName(p.name) / p.filename, true)) { std::println("{}", infoString("{} will be loaded after restarting Hyprland", p.name)); hyprlandVersionMismatch = true; } else diff --git a/hyprpm/src/meson.build b/hyprpm/src/meson.build index 2ef6c323..fd914f9d 100644 --- a/hyprpm/src/meson.build +++ b/hyprpm/src/meson.build @@ -8,6 +8,7 @@ executable( dependency('hyprutils', version: '>= 0.1.1'), dependency('threads'), dependency('tomlplusplus'), + dependency('glaze', method: 'cmake'), ], install: true, ) diff --git a/nix/default.nix b/nix/default.nix index 9293a35c..8e3af31d 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -5,12 +5,14 @@ pkg-config, pkgconf, makeWrapper, + cmake, meson, ninja, aquamarine, binutils, cairo, git, + glaze, hyprcursor, hyprgraphics, hyprland-protocols, @@ -102,6 +104,7 @@ in makeWrapper meson ninja + cmake # needed for glaze pkg-config ]; @@ -116,6 +119,7 @@ in aquamarine cairo git + glaze hyprcursor hyprgraphics hyprland-protocols From 85632e7c334f6621b7aa08f295483f3358e42c57 Mon Sep 17 00:00:00 2001 From: khushal-solves Date: Fri, 27 Dec 2024 20:50:38 +0530 Subject: [PATCH 0036/1444] internal: update window position/size after changing fullscreenstate (#8865) This effects fullscreen group of floating windows. --- src/desktop/Window.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 871e73ed..4104c737 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1026,14 +1026,14 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) { const auto WORKSPACE = PCURRENT->m_pWorkspace; const auto MODE = PCURRENT->m_sFullscreenState.internal; - const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal(); - const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal(); - const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow.lock(); if (FULLSCREEN) g_pCompositor->setWindowFullscreenInternal(PCURRENT, FSMODE_NONE); + const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal(); + const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal(); + PCURRENT->setHidden(true); pWindow->setHidden(false); // can remove m_pLastWindow From 775111b6032185c9ef164d7ba1417a875c1d0287 Mon Sep 17 00:00:00 2001 From: user111111111111111111111111111111111 Date: Fri, 27 Dec 2024 15:20:55 +0000 Subject: [PATCH 0037/1444] foreign-toplevel: update active on null window focus (#8860) * update ForeignTopLevel on null window focus * fix * clang --- src/protocols/ForeignToplevelWlr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp index 06814c88..6bbd377c 100644 --- a/src/protocols/ForeignToplevelWlr.cpp +++ b/src/protocols/ForeignToplevelWlr.cpp @@ -347,7 +347,7 @@ CForeignToplevelWlrProtocol::CForeignToplevelWlrProtocol(const wl_interface* ifa static auto P3 = g_pHookSystem->hookDynamic("activeWindow", [this](void* self, SCallbackInfo& info, std::any data) { const auto PWINDOW = std::any_cast(data); - if (!windowValidForForeign(PWINDOW)) + if (PWINDOW && !windowValidForForeign(PWINDOW)) return; for (auto const& m : m_vManagers) { From 534adad6b1940fcf0929a59be62dc78e5effaccc Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 27 Dec 2024 17:49:05 +0100 Subject: [PATCH 0038/1444] pass: scale blur regions properly --- src/render/pass/Pass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 69a12293..c5c60be6 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -74,7 +74,7 @@ void CRenderPass::simplify() { } // expand the region: this area needs to be proper to blur it right. - liveBlurRegion.expand(oneBlurRadius() * 2.F); + liveBlurRegion.scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale).expand(oneBlurRadius() * 2.F); if (auto infringement = opaque.copy().intersect(liveBlurRegion); !infringement.empty()) { // eh, this is not the correct solution, but it will do... @@ -96,7 +96,7 @@ void CRenderPass::simplify() { const auto BB = el2->element->boundingBox(); RASSERT(BB, "No bounding box for an element with live blur is illegal"); - totalLiveBlurRegion.add(*BB); + totalLiveBlurRegion.add(BB->copy().scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale)); } } } From cca0adf6a37c33fb12514b7935fa372fda27d97f Mon Sep 17 00:00:00 2001 From: Mike Will Date: Fri, 27 Dec 2024 16:49:45 -0500 Subject: [PATCH 0039/1444] snap: revert #8659, use bounds checking instead of bit mask (#8872) They seem like the same check, but a snap bit might not be turned on as expected if we grab a different corner after an edge has already been snapped. --- src/layout/IHyprLayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 354fc09f..2d6e9561 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -457,7 +457,7 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA // corner snapping const double BORDERDIFF = OTHERBORDERSIZE - DRAGGINGBORDERSIZE; - if (snaps & (SNAP_LEFT | SNAP_RIGHT)) { + if (sourceX.start == SURFBX.end || SURFBX.start == sourceX.end) { const SRange SURFY = {SURF.y - BORDERDIFF, SURF.y + SURF.h + BORDERDIFF}; if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && canSnap(sourceY.start, SURFY.start, GAPSIZE)) { SNAP(sourceY.start, sourceY.end, SURFY.start); @@ -467,7 +467,7 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA snaps |= SNAP_DOWN; } } - if (snaps & (SNAP_UP | SNAP_DOWN)) { + if (sourceY.start == SURFBY.end || SURFBY.start == sourceY.end) { const SRange SURFX = {SURF.x - BORDERDIFF, SURF.x + SURF.w + BORDERDIFF}; if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && canSnap(sourceX.start, SURFX.start, GAPSIZE)) { SNAP(sourceX.start, sourceX.end, SURFX.start); From c600e1aaff293303c8256aca7d2889fc4289e8c2 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 27 Dec 2024 21:51:12 +0000 Subject: [PATCH 0040/1444] [gha] Nix: update inputs --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 6c7a09b4..b9351586 100644 --- a/flake.lock +++ b/flake.lock @@ -203,11 +203,11 @@ ] }, "locked": { - "lastModified": 1734796073, - "narHash": "sha256-TnuKsa8OHrSJEmHm3TLGOWbPNA1gRjmZLsRzKrCqOsg=", + "lastModified": 1735316583, + "narHash": "sha256-AiiUwHWHfEdpFzXy7l1x3zInCUa1xcRMrbZ1XRSkzwU=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "c3331116ebd0b71df5ae8c6efe9a7f94148b03bf", + "rev": "8f15d45b120b33712f6db477fe5ffb18034d0ea8", "type": "github" }, "original": { @@ -241,11 +241,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1734649271, - "narHash": "sha256-4EVBRhOjMDuGtMaofAIqzJbg4Ql7Ai0PSeuVZTHjyKQ=", + "lastModified": 1735291276, + "narHash": "sha256-NYVcA06+blsLG6wpAbSPTCyLvxD/92Hy4vlY9WxFI1M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d70bd19e0a38ad4790d3913bf08fcbfc9eeca507", + "rev": "634fd46801442d760e09493a794c4f15db2d0cbb", "type": "github" }, "original": { From 8d4c18d723d18f5bf5190b62b562301860df74f7 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Sat, 28 Dec 2024 07:32:04 -0600 Subject: [PATCH 0041/1444] core: refactor/improve monitor mode selection (#8804) --- src/Compositor.cpp | 2 +- src/config/ConfigManager.cpp | 4 +- src/helpers/Monitor.cpp | 383 ++++++++++++++++++++++++++++- src/helpers/Monitor.hpp | 1 + src/managers/KeybindManager.cpp | 2 +- src/render/Renderer.cpp | 416 -------------------------------- src/render/Renderer.hpp | 1 - 7 files changed, 384 insertions(+), 425 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 9bcbdb0f..91a7705d 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -425,7 +425,7 @@ void CCompositor::initAllSignals() { for (auto const& m : m_vMonitors) { scheduleFrameForMonitor(m); - g_pHyprRenderer->applyMonitorRule(m, &m->activeMonitorRule, true); + m->applyMonitorRule(&m->activeMonitorRule, true); } g_pConfigManager->m_bWantsMonitorReload = true; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f9ad54aa..a9796bdd 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1495,7 +1495,7 @@ void CConfigManager::performMonitorReload() { auto rule = getMonitorRuleFor(m); - if (!g_pHyprRenderer->applyMonitorRule(m, &rule)) { + if (!m->applyMonitorRule(&rule)) { overAgain = true; break; } @@ -1553,7 +1553,7 @@ void CConfigManager::ensureMonitorStatus() { auto rule = getMonitorRuleFor(rm); if (rule.disabled == rm->m_bEnabled) - g_pHyprRenderer->applyMonitorRule(rm, &rule); + rm->applyMonitorRule(&rule); } } diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 89a833d4..3fb90959 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -21,6 +21,8 @@ #include "debug/Log.hpp" #include #include +#include +#include using namespace Hyprutils::String; using namespace Hyprutils::Utils; @@ -85,7 +87,7 @@ void CMonitor::onConnect(bool noRule) { return; Debug::log(LOG, "Reapplying monitor rule for {} from a state request", szName); - g_pHyprRenderer->applyMonitorRule(self.lock(), &activeMonitorRule, true); + applyMonitorRule(&activeMonitorRule, true); return; } @@ -99,7 +101,7 @@ void CMonitor::onConnect(bool noRule) { SMonitorRule rule = activeMonitorRule; rule.resolution = SIZE; - g_pHyprRenderer->applyMonitorRule(self.lock(), &rule); + applyMonitorRule(&rule); }); tearingState.canTear = output->getBackend()->type() == Aquamarine::AQ_BACKEND_DRM; @@ -172,7 +174,7 @@ void CMonitor::onConnect(bool noRule) { // set mode, also applies if (!noRule) - g_pHyprRenderer->applyMonitorRule(self.lock(), &monitorRule, true); + applyMonitorRule(&monitorRule, true); if (!state.commit()) Debug::log(WARN, "state.commit() failed in CMonitor::onCommit"); @@ -361,6 +363,379 @@ void CMonitor::onDisconnect(bool destroy) { std::erase_if(g_pCompositor->m_vMonitors, [&](PHLMONITOR& el) { return el.get() == this; }); } +bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { + + static auto PDISABLESCALECHECKS = CConfigValue("debug:disable_scale_checks"); + + Debug::log(LOG, "Applying monitor rule for {}", szName); + + activeMonitorRule = *pMonitorRule; + + if (forceSize.has_value()) + activeMonitorRule.resolution = forceSize.value(); + + const auto RULE = &activeMonitorRule; + + // if it's disabled, disable and ignore + if (RULE->disabled) { + if (m_bEnabled) + onDisconnect(); + + events.modeChanged.emit(); + + return true; + } + + // don't touch VR headsets + if (output->nonDesktop) + return true; + + if (!m_bEnabled) { + onConnect(true); // enable it. + Debug::log(LOG, "Monitor {} is disabled but is requested to be enabled", szName); + force = true; + } + + // Check if the rule isn't already applied + // TODO: clean this up lol + if (!force && DELTALESSTHAN(vecPixelSize.x, RULE->resolution.x, 1) && DELTALESSTHAN(vecPixelSize.y, RULE->resolution.y, 1) && + DELTALESSTHAN(refreshRate, RULE->refreshRate, 1) && setScale == RULE->scale && + ((DELTALESSTHAN(vecPosition.x, RULE->offset.x, 1) && DELTALESSTHAN(vecPosition.y, RULE->offset.y, 1)) || RULE->offset == Vector2D(-INT32_MAX, -INT32_MAX)) && + transform == RULE->transform && RULE->enable10bit == enabled10bit && !std::memcmp(&customDrmMode, &RULE->drmMode, sizeof(customDrmMode))) { + + Debug::log(LOG, "Not applying a new rule to {} because it's already applied!", szName); + + setMirror(RULE->mirrorOf); + + return true; + } + + bool autoScale = false; + + if (RULE->scale > 0.1) { + scale = RULE->scale; + } else { + autoScale = true; + const auto DEFAULTSCALE = getDefaultScale(); + scale = DEFAULTSCALE; + } + + setScale = scale; + transform = RULE->transform; + + // accumulate requested modes in reverse order (cause inesrting at front is inefficient) + std::vector> requestedModes; + std::string requestedStr = "preferred"; + + // use sortFunc, add best 3 to requestedModes in reverse, since we test in reverse + auto addBest3Modes = [&](auto const& sortFunc) { + auto sortedModes = output->modes; + std::ranges::sort(sortedModes, sortFunc); + if (sortedModes.size() > 3) + sortedModes.erase(sortedModes.begin() + 3, sortedModes.end()); + requestedModes.insert(requestedModes.end(), sortedModes.rbegin(), sortedModes.rend()); + }; + + // last fallback is preferred mode, btw this covers resolution == Vector2D() + if (!output->preferredMode()) + Debug::log(ERR, "Monitor {} has NO PREFERRED MODE", output->name); + else + requestedModes.push_back(output->preferredMode()); + + if (RULE->resolution == Vector2D(-1, -1)) { + requestedStr = "highrr"; + + // sort prioritizing refresh rate 1st and resolution 2nd, then add best 3 + addBest3Modes([](auto const& a, auto const& b) { + if (a->refreshRate > b->refreshRate) + return true; + else if (DELTALESSTHAN((float)a->refreshRate, (float)b->refreshRate, 1000) && a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) + return true; + return false; + }); + } else if (RULE->resolution == Vector2D(-1, -2)) { + requestedStr = "highres"; + + // sort prioritizing resultion 1st and refresh rate 2nd, then add best 3 + addBest3Modes([](auto const& a, auto const& b) { + if (a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) + return true; + else if (DELTALESSTHAN(a->pixelSize.x, b->pixelSize.x, 1) && DELTALESSTHAN(a->pixelSize.y, b->pixelSize.y, 1) && a->refreshRate > b->refreshRate) + return true; + return false; + }); + } else if (RULE->resolution != Vector2D()) { + // user requested mode + requestedStr = std::format("{:X0}@{:.2f}Hz", RULE->resolution, RULE->refreshRate); + + // sort by closeness to requested, then add best 3 + addBest3Modes([&](auto const& a, auto const& b) { + if (abs(a->pixelSize.x - RULE->resolution.x) < abs(b->pixelSize.x - RULE->resolution.x)) + return true; + if (a->pixelSize.x == b->pixelSize.x && abs(a->pixelSize.y - RULE->resolution.y) < abs(b->pixelSize.y - RULE->resolution.y)) + return true; + if (a->pixelSize == b->pixelSize && abs((a->refreshRate / 1000.f) - RULE->refreshRate) < abs((b->refreshRate / 1000.f) - RULE->refreshRate)) + return true; + return false; + }); + + // then if requested is custom, try custom mode first + if (RULE->drmMode.type == DRM_MODE_TYPE_USERDEF) { + if (output->getBackend()->type() != Aquamarine::eBackendType::AQ_BACKEND_DRM) + Debug::log(ERR, "Tried to set custom modeline on non-DRM output"); + else + requestedModes.push_back(makeShared( + Aquamarine::SOutputMode{.pixelSize = {RULE->drmMode.hdisplay, RULE->drmMode.vdisplay}, .refreshRate = RULE->drmMode.vrefresh, .modeInfo = RULE->drmMode})); + } + } + + const auto WAS10B = enabled10bit; + const auto OLDRES = vecPixelSize; + bool success = false; + + // Needed in case we are switching from a custom modeline to a standard mode + customDrmMode = {}; + currentMode = nullptr; + + output->state->setFormat(DRM_FORMAT_XRGB8888); + prevDrmFormat = drmFormat; + drmFormat = DRM_FORMAT_XRGB8888; + output->state->resetExplicitFences(); + + if (Debug::trace) { + Debug::log(TRACE, "Monitor {} requested modes:", szName); + for (auto const& mode : requestedModes | std::views::reverse) { + Debug::log(TRACE, "| {:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f); + } + } + + for (auto const& mode : requestedModes | std::views::reverse) { + std::string modeStr = std::format("{:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f); + + if (mode->modeInfo.has_value() && mode->modeInfo->type == DRM_MODE_TYPE_USERDEF) { + output->state->setCustomMode(mode); + + if (!state.test()) { + Debug::log(ERR, "Monitor {}: REJECTED custom mode {}!", szName, modeStr); + continue; + } + + customDrmMode = mode->modeInfo.value(); + } else { + output->state->setMode(mode); + + if (!state.test()) { + Debug::log(ERR, "Monitor {}: REJECTED available mode {}!", szName, modeStr); + if (mode->preferred) + Debug::log(ERR, "Monitor {}: REJECTED preferred mode!!!", szName); + continue; + } + + customDrmMode = {}; + } + + refreshRate = mode->refreshRate / 1000.f; + vecSize = mode->pixelSize; + currentMode = mode; + + success = true; + + if (mode->preferred) + Debug::log(LOG, "Monitor {}: requested {}, using preferred mode {}", szName, requestedStr, modeStr); + else if (mode->modeInfo.has_value() && mode->modeInfo->type == DRM_MODE_TYPE_USERDEF) + Debug::log(LOG, "Monitor {}: requested {}, using custom mode {}", szName, requestedStr, modeStr); + else + Debug::log(LOG, "Monitor {}: requested {}, using available mode {}", szName, requestedStr, modeStr); + + break; + } + + // try requested as custom mode jic it works + if (!success && RULE->resolution != Vector2D() && RULE->resolution != Vector2D(-1, -1) && RULE->resolution != Vector2D(-1, -2)) { + auto refreshRate = output->getBackend()->type() == Aquamarine::eBackendType::AQ_BACKEND_DRM ? RULE->refreshRate * 1000 : 0; + auto mode = makeShared(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = refreshRate}); + std::string modeStr = std::format("{:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f); + + output->state->setCustomMode(mode); + + if (state.test()) { + Debug::log(LOG, "Monitor {}: requested {}, using custom mode {}", szName, requestedStr, modeStr); + + refreshRate = mode->refreshRate / 1000.f; + vecSize = mode->pixelSize; + currentMode = mode; + customDrmMode = {}; + + success = true; + } else + Debug::log(ERR, "Monitor {}: REJECTED custom mode {}!", szName, modeStr); + } + + // try any of the modes if none of the above work + if (!success) { + for (auto const& mode : output->modes) { + output->state->setMode(mode); + + if (!state.test()) + continue; + + auto errorMessage = + std::format("Monitor {} failed to set any requested modes, falling back to mode {:X0}@{:.2f}Hz", szName, mode->pixelSize, mode->refreshRate / 1000.f); + Debug::log(WARN, errorMessage); + g_pHyprNotificationOverlay->addNotification(errorMessage, CHyprColor(0xff0000ff), 5000, ICON_WARNING); + + refreshRate = mode->refreshRate / 1000.f; + vecSize = mode->pixelSize; + currentMode = mode; + customDrmMode = {}; + + success = true; + + break; + } + } + + if (!success) { + Debug::log(ERR, "Monitor {} has NO FALLBACK MODES, and an INVALID one was requested: {:X0}@{:.2f}Hz", szName, RULE->resolution, RULE->refreshRate); + return true; + } + + vrrActive = output->state->state().adaptiveSync // disabled here, will be tested in CConfigManager::ensureVRR() + || createdByUser; // wayland backend doesn't allow for disabling adaptive_sync + + vecPixelSize = vecSize; + + // clang-format off + static const std::array>, 2> formats{ + std::vector>{ /* 10-bit */ + {"DRM_FORMAT_XRGB2101010", DRM_FORMAT_XRGB2101010}, {"DRM_FORMAT_XBGR2101010", DRM_FORMAT_XBGR2101010}, {"DRM_FORMAT_XRGB8888", DRM_FORMAT_XRGB8888}, {"DRM_FORMAT_XBGR8888", DRM_FORMAT_XBGR8888} + }, + std::vector>{ /* 8-bit */ + {"DRM_FORMAT_XRGB8888", DRM_FORMAT_XRGB8888}, {"DRM_FORMAT_XBGR8888", DRM_FORMAT_XBGR8888} + } + }; + // clang-format on + + bool set10bit = false; + + for (auto const& fmt : formats[(int)!RULE->enable10bit]) { + output->state->setFormat(fmt.second); + prevDrmFormat = drmFormat; + drmFormat = fmt.second; + + if (!state.test()) { + Debug::log(ERR, "output {} failed basic test on format {}", szName, fmt.first); + } else { + Debug::log(LOG, "output {} succeeded basic test on format {}", szName, fmt.first); + if (RULE->enable10bit && fmt.first.contains("101010")) + set10bit = true; + break; + } + } + + enabled10bit = set10bit; + + Vector2D logicalSize = vecPixelSize / scale; + if (!*PDISABLESCALECHECKS && (logicalSize.x != std::round(logicalSize.x) || logicalSize.y != std::round(logicalSize.y))) { + // invalid scale, will produce fractional pixels. + // find the nearest valid. + + float searchScale = std::round(scale * 120.0); + bool found = false; + + double scaleZero = searchScale / 120.0; + + Vector2D logicalZero = vecPixelSize / scaleZero; + if (logicalZero == logicalZero.round()) + scale = scaleZero; + else { + for (size_t i = 1; i < 90; ++i) { + double scaleUp = (searchScale + i) / 120.0; + double scaleDown = (searchScale - i) / 120.0; + + Vector2D logicalUp = vecPixelSize / scaleUp; + Vector2D logicalDown = vecPixelSize / scaleDown; + + if (logicalUp == logicalUp.round()) { + found = true; + searchScale = scaleUp; + break; + } + if (logicalDown == logicalDown.round()) { + found = true; + searchScale = scaleDown; + break; + } + } + + if (!found) { + if (autoScale) + scale = std::round(scaleZero); + else { + Debug::log(ERR, "Invalid scale passed to monitor, {} failed to find a clean divisor", scale); + g_pConfigManager->addParseError("Invalid scale passed to monitor " + szName + ", failed to find a clean divisor"); + scale = getDefaultScale(); + } + } else { + if (!autoScale) { + Debug::log(ERR, "Invalid scale passed to monitor, {} found suggestion {}", scale, searchScale); + g_pConfigManager->addParseError( + std::format("Invalid scale passed to monitor {}, failed to find a clean divisor. Suggested nearest scale: {:5f}", szName, searchScale)); + scale = getDefaultScale(); + } else + scale = searchScale; + } + } + } + + output->scheduleFrame(); + + if (!state.commit()) + Debug::log(ERR, "Couldn't commit output named {}", output->name); + + Vector2D xfmd = transform % 2 == 1 ? Vector2D{vecPixelSize.y, vecPixelSize.x} : vecPixelSize; + vecSize = (xfmd / scale).round(); + vecTransformedSize = xfmd; + + if (createdByUser) { + CBox transformedBox = {0, 0, vecTransformedSize.x, vecTransformedSize.y}; + transformedBox.transform(wlTransformToHyprutils(invertTransform(transform)), vecTransformedSize.x, vecTransformedSize.y); + + vecPixelSize = Vector2D(transformedBox.width, transformedBox.height); + } + + updateMatrix(); + + if (WAS10B != enabled10bit || OLDRES != vecPixelSize) + g_pHyprOpenGL->destroyMonitorResources(self.lock()); + + g_pCompositor->arrangeMonitors(); + + damage.setSize(vecTransformedSize); + + // Set scale for all surfaces on this monitor, needed for some clients + // but not on unsafe state to avoid crashes + if (!g_pCompositor->m_bUnsafeState) { + for (auto const& w : g_pCompositor->m_vWindows) { + w->updateSurfaceScaleTransformDetails(); + } + } + // updato us + g_pHyprRenderer->arrangeLayersForMonitor(ID); + + // reload to fix mirrors + g_pConfigManager->m_bWantsMonitorReload = true; + + Debug::log(LOG, "Monitor {} data dump: res {:X}@{:.2f}Hz, scale {:.2f}, transform {}, pos {:X}, 10b {}", szName, vecPixelSize, refreshRate, scale, (int)transform, vecPosition, + (int)enabled10bit); + + EMIT_HOOK_EVENT("monitorLayoutChanged", nullptr); + + events.modeChanged.emit(); + + return true; +} + void CMonitor::addDamage(const pixman_region32_t* rg) { static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == self) { @@ -530,7 +905,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) { setupDefaultWS(RULE); - g_pHyprRenderer->applyMonitorRule(self.lock(), (SMonitorRule*)&RULE, true); // will apply the offset and stuff + applyMonitorRule((SMonitorRule*)&RULE, true); // will apply the offset and stuff } else { PHLMONITOR BACKUPMON = nullptr; for (auto const& m : g_pCompositor->m_vMonitors) { diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 38c55572..d9f5e88c 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -163,6 +163,7 @@ class CMonitor { // methods void onConnect(bool noRule); void onDisconnect(bool destroy = false); + bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false); void addDamage(const pixman_region32_t* rg); void addDamage(const CRegion* rg); void addDamage(const CBox* box); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e1ad7d60..9e207fbe 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1992,7 +1992,7 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) { continue; auto rule = g_pConfigManager->getMonitorRuleFor(m); - if (!g_pHyprRenderer->applyMonitorRule(m, &rule, true)) { + if (!m->applyMonitorRule(&rule, true)) { overAgain = true; break; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index d8b8a847..f3030d18 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -4,7 +4,6 @@ #include "../helpers/sync/SyncReleaser.hpp" #include #include -#include #include #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" @@ -1831,421 +1830,6 @@ void CHyprRenderer::renderDragIcon(PHLMONITOR pMonitor, timespec* time) { PROTO::data->renderDND(pMonitor, time); } -bool CHyprRenderer::applyMonitorRule(PHLMONITOR pMonitor, SMonitorRule* pMonitorRule, bool force) { - - static auto PDISABLESCALECHECKS = CConfigValue("debug:disable_scale_checks"); - - Debug::log(LOG, "Applying monitor rule for {}", pMonitor->szName); - - pMonitor->activeMonitorRule = *pMonitorRule; - - if (pMonitor->forceSize.has_value()) - pMonitor->activeMonitorRule.resolution = pMonitor->forceSize.value(); - - const auto RULE = &pMonitor->activeMonitorRule; - - // if it's disabled, disable and ignore - if (RULE->disabled) { - if (pMonitor->m_bEnabled) - pMonitor->onDisconnect(); - - pMonitor->events.modeChanged.emit(); - - return true; - } - - // don't touch VR headsets - if (pMonitor->output->nonDesktop) - return true; - - if (!pMonitor->m_bEnabled) { - pMonitor->onConnect(true); // enable it. - Debug::log(LOG, "Monitor {} is disabled but is requested to be enabled", pMonitor->szName); - force = true; - } - - // Check if the rule isn't already applied - // TODO: clean this up lol - if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, RULE->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, RULE->resolution.y, 1) && - DELTALESSTHAN(pMonitor->refreshRate, RULE->refreshRate, 1) && pMonitor->setScale == RULE->scale && - ((DELTALESSTHAN(pMonitor->vecPosition.x, RULE->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, RULE->offset.y, 1)) || - RULE->offset == Vector2D(-INT32_MAX, -INT32_MAX)) && - pMonitor->transform == RULE->transform && RULE->enable10bit == pMonitor->enabled10bit && - !memcmp(&pMonitor->customDrmMode, &RULE->drmMode, sizeof(pMonitor->customDrmMode))) { - - Debug::log(LOG, "Not applying a new rule to {} because it's already applied!", pMonitor->szName); - - pMonitor->setMirror(RULE->mirrorOf); - - return true; - } - - const auto WAS10B = pMonitor->enabled10bit; - const auto OLDRES = pMonitor->vecPixelSize; - - // Needed in case we are switching from a custom modeline to a standard mode - pMonitor->customDrmMode = {}; - pMonitor->currentMode = nullptr; - - pMonitor->output->state->setFormat(DRM_FORMAT_XRGB8888); - pMonitor->prevDrmFormat = pMonitor->drmFormat; - pMonitor->drmFormat = DRM_FORMAT_XRGB8888; - pMonitor->output->state->resetExplicitFences(); - - bool autoScale = false; - - if (RULE->scale > 0.1) { - pMonitor->scale = RULE->scale; - } else { - autoScale = true; - const auto DEFAULTSCALE = pMonitor->getDefaultScale(); - pMonitor->scale = DEFAULTSCALE; - } - - pMonitor->setScale = pMonitor->scale; - pMonitor->transform = RULE->transform; - - const auto WLRREFRESHRATE = pMonitor->output->getBackend()->type() == Aquamarine::eBackendType::AQ_BACKEND_DRM ? RULE->refreshRate * 1000 : 0; - - // loop over modes and choose an appropriate one. - if (RULE->resolution != Vector2D() && RULE->resolution != Vector2D(-1, -1) && RULE->resolution != Vector2D(-1, -2)) { - if (!pMonitor->output->modes.empty() && RULE->drmMode.type != DRM_MODE_TYPE_USERDEF) { - bool found = false; - - for (auto const& mode : pMonitor->output->modes) { - // if delta of refresh rate, w and h chosen and mode is < 1 we accept it - if (DELTALESSTHAN(mode->pixelSize.x, RULE->resolution.x, 1) && DELTALESSTHAN(mode->pixelSize.y, RULE->resolution.y, 1) && - DELTALESSTHAN(mode->refreshRate / 1000.f, RULE->refreshRate, 1)) { - pMonitor->output->state->setMode(mode); - - if (!pMonitor->state.test()) { - Debug::log(LOG, "Monitor {}: REJECTED available mode: {}x{}@{:2f}!", pMonitor->output->name, mode->pixelSize.x, mode->pixelSize.y, - mode->refreshRate / 1000.f); - continue; - } - - Debug::log(LOG, "Monitor {}: requested {:X0}@{:2f}, found available mode: {}x{}@{}mHz, applying.", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate, mode->pixelSize.x, mode->pixelSize.y, mode->refreshRate); - - found = true; - - pMonitor->refreshRate = mode->refreshRate / 1000.f; - pMonitor->vecSize = mode->pixelSize; - pMonitor->currentMode = mode; - - break; - } - } - - if (!found) { - pMonitor->output->state->setCustomMode(makeShared(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = WLRREFRESHRATE})); - pMonitor->vecSize = RULE->resolution; - pMonitor->refreshRate = RULE->refreshRate; - - if (!pMonitor->state.test()) { - Debug::log(ERR, "Custom resolution FAILED, falling back to preferred"); - - const auto PREFERREDMODE = pMonitor->output->preferredMode(); - - if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->ID, RULE->resolution, - (float)RULE->refreshRate); - return true; - } - - // Preferred is valid - pMonitor->output->state->setMode(PREFERREDMODE); - - Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate, PREFERREDMODE->pixelSize.x, PREFERREDMODE->pixelSize.y, PREFERREDMODE->refreshRate / 1000.f); - - pMonitor->refreshRate = PREFERREDMODE->refreshRate / 1000.f; - pMonitor->vecSize = PREFERREDMODE->pixelSize; - pMonitor->currentMode = PREFERREDMODE; - } else { - Debug::log(LOG, "Set a custom mode {:X0}@{:2f} (mode not found in monitor modes)", RULE->resolution, (float)RULE->refreshRate); - } - } - } else { - // custom resolution - bool fail = false; - - if (RULE->drmMode.type == DRM_MODE_TYPE_USERDEF) { - if (pMonitor->output->getBackend()->type() != Aquamarine::eBackendType::AQ_BACKEND_DRM) { - Debug::log(ERR, "Tried to set custom modeline on non-DRM output"); - fail = true; - } else - pMonitor->output->state->setCustomMode(makeShared( - Aquamarine::SOutputMode{.pixelSize = {RULE->drmMode.hdisplay, RULE->drmMode.vdisplay}, .refreshRate = RULE->drmMode.vrefresh, .modeInfo = RULE->drmMode})); - } else - pMonitor->output->state->setCustomMode(makeShared(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = WLRREFRESHRATE})); - - pMonitor->vecSize = RULE->resolution; - pMonitor->refreshRate = RULE->refreshRate; - - if (fail || !pMonitor->state.test()) { - Debug::log(ERR, "Custom resolution FAILED, falling back to preferred"); - - const auto PREFERREDMODE = pMonitor->output->preferredMode(); - - if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate); - return true; - } - - // Preferred is valid - pMonitor->output->state->setMode(PREFERREDMODE); - - Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate, PREFERREDMODE->pixelSize.x, PREFERREDMODE->pixelSize.y, PREFERREDMODE->refreshRate / 1000.f); - - pMonitor->refreshRate = PREFERREDMODE->refreshRate / 1000.f; - pMonitor->vecSize = PREFERREDMODE->pixelSize; - pMonitor->customDrmMode = {}; - } else - Debug::log(LOG, "Set a custom mode {:X0}@{:2f} (mode not found in monitor modes)", RULE->resolution, (float)RULE->refreshRate); - } - } else if (RULE->resolution != Vector2D()) { - if (!pMonitor->output->modes.empty()) { - float currentWidth = 0; - float currentHeight = 0; - float currentRefresh = 0; - bool success = false; - - //(-1,-1) indicates a preference to refreshrate over resolution, (-1,-2) preference to resolution - if (RULE->resolution == Vector2D(-1, -1)) { - for (auto const& mode : pMonitor->output->modes) { - if ((mode->pixelSize.x >= currentWidth && mode->pixelSize.y >= currentHeight && mode->refreshRate >= (currentRefresh - 1000.f)) || - mode->refreshRate > (currentRefresh + 3000.f)) { - pMonitor->output->state->setMode(mode); - if (pMonitor->state.test()) { - currentWidth = mode->pixelSize.x; - currentHeight = mode->pixelSize.y; - currentRefresh = mode->refreshRate; - success = true; - } - } - } - } else { - for (auto const& mode : pMonitor->output->modes) { - if ((mode->pixelSize.x >= currentWidth && mode->pixelSize.y >= currentHeight && mode->refreshRate >= (currentRefresh - 1000.f)) || - (mode->pixelSize.x > currentWidth && mode->pixelSize.y > currentHeight)) { - pMonitor->output->state->setMode(mode); - if (pMonitor->state.test()) { - currentWidth = mode->pixelSize.x; - currentHeight = mode->pixelSize.y; - currentRefresh = mode->refreshRate; - success = true; - } - } - } - } - - if (!success) { - if (pMonitor->output->state->state().mode) - Debug::log(LOG, "Monitor {}: REJECTED mode: {:X0}@{:2f}! Falling back to preferred: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate, pMonitor->output->state->state().mode->pixelSize.x, pMonitor->output->state->state().mode->pixelSize.y, - pMonitor->output->state->state().mode->refreshRate / 1000.f); - - const auto PREFERREDMODE = pMonitor->output->preferredMode(); - - if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE, and an INVALID one was requested: {:X0}@{:2f}", pMonitor->ID, RULE->resolution, (float)RULE->refreshRate); - return true; - } - - // Preferred is valid - pMonitor->output->state->setMode(PREFERREDMODE); - - Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate, PREFERREDMODE->pixelSize.x, PREFERREDMODE->pixelSize.y, PREFERREDMODE->refreshRate / 1000.f); - - pMonitor->refreshRate = PREFERREDMODE->refreshRate / 1000.f; - pMonitor->vecSize = PREFERREDMODE->pixelSize; - pMonitor->currentMode = PREFERREDMODE; - } else { - - Debug::log(LOG, "Monitor {}: Applying highest mode {}x{}@{:2f}.", pMonitor->output->name, (int)currentWidth, (int)currentHeight, (int)currentRefresh / 1000.f); - - pMonitor->refreshRate = currentRefresh / 1000.f; - pMonitor->vecSize = Vector2D(currentWidth, currentHeight); - } - } - } else { - const auto PREFERREDMODE = pMonitor->output->preferredMode(); - - if (!PREFERREDMODE) { - Debug::log(ERR, "Monitor {} has NO PREFERRED MODE", pMonitor->output->name); - - if (!pMonitor->output->modes.empty()) { - for (auto const& mode : pMonitor->output->modes) { - pMonitor->output->state->setMode(mode); - - if (!pMonitor->state.test()) { - Debug::log(LOG, "Monitor {}: REJECTED available mode: {}x{}@{:2f}!", pMonitor->output->name, mode->pixelSize.x, mode->pixelSize.y, - mode->refreshRate / 1000.f); - continue; - } - - Debug::log(LOG, "Monitor {}: requested {:X0}@{:2f}, found available mode: {}x{}@{}mHz, applying.", pMonitor->output->name, RULE->resolution, - (float)RULE->refreshRate, mode->pixelSize.x, mode->pixelSize.y, mode->refreshRate); - - pMonitor->refreshRate = mode->refreshRate / 1000.f; - pMonitor->vecSize = mode->pixelSize; - pMonitor->currentMode = mode; - - break; - } - } - } else { - // Preferred is valid - pMonitor->output->state->setMode(PREFERREDMODE); - - pMonitor->vecSize = PREFERREDMODE->pixelSize; - pMonitor->refreshRate = PREFERREDMODE->refreshRate / 1000.f; - pMonitor->currentMode = PREFERREDMODE; - - Debug::log(LOG, "Setting preferred mode for {}", pMonitor->output->name); - } - } - - pMonitor->vrrActive = pMonitor->output->state->state().adaptiveSync // disabled here, will be tested in CConfigManager::ensureVRR() - || pMonitor->createdByUser; // wayland backend doesn't allow for disabling adaptive_sync - - pMonitor->vecPixelSize = pMonitor->vecSize; - - // clang-format off - static const std::array>, 2> formats{ - std::vector>{ /* 10-bit */ - {"DRM_FORMAT_XRGB2101010", DRM_FORMAT_XRGB2101010}, {"DRM_FORMAT_XBGR2101010", DRM_FORMAT_XBGR2101010}, {"DRM_FORMAT_XRGB8888", DRM_FORMAT_XRGB8888}, {"DRM_FORMAT_XBGR8888", DRM_FORMAT_XBGR8888}, {"DRM_FORMAT_INVALID", DRM_FORMAT_INVALID} - }, - std::vector>{ /* 8-bit */ - {"DRM_FORMAT_XRGB8888", DRM_FORMAT_XRGB8888}, {"DRM_FORMAT_XBGR8888", DRM_FORMAT_XBGR8888}, {"DRM_FORMAT_INVALID", DRM_FORMAT_INVALID} - } - }; - // clang-format on - - bool set10bit = false; - - for (auto const& fmt : formats[(int)!RULE->enable10bit]) { - pMonitor->output->state->setFormat(fmt.second); - pMonitor->prevDrmFormat = pMonitor->drmFormat; - pMonitor->drmFormat = fmt.second; - - if (!pMonitor->state.test()) { - Debug::log(ERR, "output {} failed basic test on format {}", pMonitor->szName, fmt.first); - } else { - Debug::log(LOG, "output {} succeeded basic test on format {}", pMonitor->szName, fmt.first); - if (RULE->enable10bit && fmt.first.contains("101010")) - set10bit = true; - break; - } - } - - pMonitor->enabled10bit = set10bit; - - Vector2D logicalSize = pMonitor->vecPixelSize / pMonitor->scale; - if (!*PDISABLESCALECHECKS && (logicalSize.x != std::round(logicalSize.x) || logicalSize.y != std::round(logicalSize.y))) { - // invalid scale, will produce fractional pixels. - // find the nearest valid. - - float searchScale = std::round(pMonitor->scale * 120.0); - bool found = false; - - double scaleZero = searchScale / 120.0; - - Vector2D logicalZero = pMonitor->vecPixelSize / scaleZero; - if (logicalZero == logicalZero.round()) - pMonitor->scale = scaleZero; - else { - for (size_t i = 1; i < 90; ++i) { - double scaleUp = (searchScale + i) / 120.0; - double scaleDown = (searchScale - i) / 120.0; - - Vector2D logicalUp = pMonitor->vecPixelSize / scaleUp; - Vector2D logicalDown = pMonitor->vecPixelSize / scaleDown; - - if (logicalUp == logicalUp.round()) { - found = true; - searchScale = scaleUp; - break; - } - if (logicalDown == logicalDown.round()) { - found = true; - searchScale = scaleDown; - break; - } - } - - if (!found) { - if (autoScale) - pMonitor->scale = std::round(scaleZero); - else { - Debug::log(ERR, "Invalid scale passed to monitor, {} failed to find a clean divisor", pMonitor->scale); - g_pConfigManager->addParseError("Invalid scale passed to monitor " + pMonitor->szName + ", failed to find a clean divisor"); - pMonitor->scale = pMonitor->getDefaultScale(); - } - } else { - if (!autoScale) { - Debug::log(ERR, "Invalid scale passed to monitor, {} found suggestion {}", pMonitor->scale, searchScale); - g_pConfigManager->addParseError( - std::format("Invalid scale passed to monitor {}, failed to find a clean divisor. Suggested nearest scale: {:5f}", pMonitor->szName, searchScale)); - pMonitor->scale = pMonitor->getDefaultScale(); - } else - pMonitor->scale = searchScale; - } - } - } - - pMonitor->output->scheduleFrame(); - - if (!pMonitor->state.commit()) - Debug::log(ERR, "Couldn't commit output named {}", pMonitor->output->name); - - Vector2D xfmd = pMonitor->transform % 2 == 1 ? Vector2D{pMonitor->vecPixelSize.y, pMonitor->vecPixelSize.x} : pMonitor->vecPixelSize; - pMonitor->vecSize = (xfmd / pMonitor->scale).round(); - pMonitor->vecTransformedSize = xfmd; - - if (pMonitor->createdByUser) { - CBox transformedBox = {0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}; - transformedBox.transform(wlTransformToHyprutils(invertTransform(pMonitor->transform)), pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y); - - pMonitor->vecPixelSize = Vector2D(transformedBox.width, transformedBox.height); - } - - pMonitor->updateMatrix(); - - if (WAS10B != pMonitor->enabled10bit || OLDRES != pMonitor->vecPixelSize) - g_pHyprOpenGL->destroyMonitorResources(pMonitor); - - g_pCompositor->arrangeMonitors(); - - pMonitor->damage.setSize(pMonitor->vecTransformedSize); - - // Set scale for all surfaces on this monitor, needed for some clients - // but not on unsafe state to avoid crashes - if (!g_pCompositor->m_bUnsafeState) { - for (auto const& w : g_pCompositor->m_vWindows) { - w->updateSurfaceScaleTransformDetails(); - } - } - // updato us - arrangeLayersForMonitor(pMonitor->ID); - - // reload to fix mirrors - g_pConfigManager->m_bWantsMonitorReload = true; - - Debug::log(LOG, "Monitor {} data dump: res {:X}@{:.2f}Hz, scale {:.2f}, transform {}, pos {:X}, 10b {}", pMonitor->szName, pMonitor->vecPixelSize, pMonitor->refreshRate, - pMonitor->scale, (int)pMonitor->transform, pMonitor->vecPosition, (int)pMonitor->enabled10bit); - - EMIT_HOOK_EVENT("monitorLayoutChanged", nullptr); - - pMonitor->events.modeChanged.emit(); - - return true; -} - void CHyprRenderer::setCursorSurface(SP surf, int hotspotX, int hotspotY, bool force) { m_bCursorHasSurface = surf; diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 054f0eea..6900c775 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -57,7 +57,6 @@ class CHyprRenderer { void damageRegion(const CRegion&); void damageMonitor(PHLMONITOR); void damageMirrorsWith(PHLMONITOR, const CRegion&); - bool applyMonitorRule(PHLMONITOR, SMonitorRule*, bool force = false); bool shouldRenderWindow(PHLWINDOW, PHLMONITOR); bool shouldRenderWindow(PHLWINDOW); void ensureCursorRenderingMode(); From 2b01a5bcf62956a5d641a3367edcd35e103edfcd Mon Sep 17 00:00:00 2001 From: Clayton <42688647+netadr@users.noreply.github.com> Date: Sat, 28 Dec 2024 09:07:42 -0500 Subject: [PATCH 0042/1444] xwayland: don't create an abstract unix domain socket on linux (#8874) --- src/xwayland/Server.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index b1f02cd3..c67d5830 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -148,15 +148,8 @@ static bool openSockets(std::array& sockets, int display) { sockaddr_un addr = {.sun_family = AF_UNIX}; std::string path; -#ifdef __linux__ - // cursed... - addr.sun_path[0] = 0; - path = getSocketPath(display, true); - strncpy(addr.sun_path + 1, path.c_str(), path.length() + 1); -#else path = getSocketPath(display, false); strncpy(addr.sun_path, path.c_str(), path.length() + 1); -#endif sockets[0] = createSocket(&addr, path.length()); if (sockets[0] < 0) From a364e80425b5993d8f2162963a6030fb3c3cb72e Mon Sep 17 00:00:00 2001 From: Mike Will Date: Sun, 29 Dec 2024 06:18:14 -0500 Subject: [PATCH 0043/1444] snap: give edge snapping precedence over corner snapping (#8873) --- src/layout/IHyprLayout.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 2d6e9561..e90ab0f0 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -459,20 +459,20 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA const double BORDERDIFF = OTHERBORDERSIZE - DRAGGINGBORDERSIZE; if (sourceX.start == SURFBX.end || SURFBX.start == sourceX.end) { const SRange SURFY = {SURF.y - BORDERDIFF, SURF.y + SURF.h + BORDERDIFF}; - if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && canSnap(sourceY.start, SURFY.start, GAPSIZE)) { + if (CORNER & (CORNER_TOPLEFT | CORNER_TOPRIGHT) && !(snaps & SNAP_UP) && canSnap(sourceY.start, SURFY.start, GAPSIZE)) { SNAP(sourceY.start, sourceY.end, SURFY.start); snaps |= SNAP_UP; - } else if (CORNER & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && canSnap(sourceY.end, SURFY.end, GAPSIZE)) { + } else if (CORNER & (CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) && !(snaps & SNAP_DOWN) && canSnap(sourceY.end, SURFY.end, GAPSIZE)) { SNAP(sourceY.end, sourceY.start, SURFY.end); snaps |= SNAP_DOWN; } } if (sourceY.start == SURFBY.end || SURFBY.start == sourceY.end) { const SRange SURFX = {SURF.x - BORDERDIFF, SURF.x + SURF.w + BORDERDIFF}; - if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && canSnap(sourceX.start, SURFX.start, GAPSIZE)) { + if (CORNER & (CORNER_TOPLEFT | CORNER_BOTTOMLEFT) && !(snaps & SNAP_LEFT) && canSnap(sourceX.start, SURFX.start, GAPSIZE)) { SNAP(sourceX.start, sourceX.end, SURFX.start); snaps |= SNAP_LEFT; - } else if (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && canSnap(sourceX.end, SURFX.end, GAPSIZE)) { + } else if (CORNER & (CORNER_TOPRIGHT | CORNER_BOTTOMRIGHT) && !(snaps & SNAP_RIGHT) && canSnap(sourceX.end, SURFX.end, GAPSIZE)) { SNAP(sourceX.end, sourceX.start, SURFX.end); snaps |= SNAP_RIGHT; } From 3f40d6d9361d0c5fec558b7549e58203fbe5cbd7 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 29 Dec 2024 12:56:58 +0100 Subject: [PATCH 0044/1444] pass: scale blur region in ::render --- src/render/pass/Pass.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index c5c60be6..f71bd562 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -133,6 +133,8 @@ CRegion CRenderPass::render(const CRegion& damage_) { blurRegion.add(*BB); } + blurRegion.scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); + blurRegion.intersect(damage).expand(oneBlurRadius()); g_pHyprOpenGL->m_RenderData.finalDamage = blurRegion.copy().add(damage); From deb077c34653eab251bfe71970bb5987913e7c6d Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 29 Dec 2024 19:21:20 +0100 Subject: [PATCH 0045/1444] ctm: add an internal fade animation to ctm transitions --- src/config/ConfigManager.cpp | 4 +++ src/managers/AnimationManager.cpp | 6 ++++ src/protocols/CTMControl.cpp | 50 +++++++++++++++++++++++++++++-- src/protocols/CTMControl.hpp | 10 +++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a9796bdd..65f9cb13 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -774,6 +774,8 @@ void CConfigManager::reload() { void CConfigManager::setDefaultAnimationVars() { if (isFirstLaunch) { + INITANIMCFG("__internal_fadeCTM"); + INITANIMCFG("global"); INITANIMCFG("windows"); INITANIMCFG("layers"); @@ -811,6 +813,8 @@ void CConfigManager::setDefaultAnimationVars() { // init the values animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr}; + animationConfig["__internal_fadeCTM"] = {false, "linear", "", 5.F, 1, &animationConfig["__internal_fadeCTM"], nullptr}; + CREATEANIMCFG("windows", "global"); CREATEANIMCFG("layers", "global"); CREATEANIMCFG("fade", "global"); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index e3309282..cff438b1 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -30,6 +30,9 @@ CAnimationManager::CAnimationManager() { std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; m_mBezierCurves["default"].setup(&points); + points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)}; + m_mBezierCurves["linear"].setup(&points); + m_pAnimationTimer = SP(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr)); g_pEventLoopManager->addTimer(m_pAnimationTimer); } @@ -40,6 +43,9 @@ void CAnimationManager::removeAllBeziers() { // add the default one std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; m_mBezierCurves["default"].setup(&points); + + points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)}; + m_mBezierCurves["linear"].setup(&points); } void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) { diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index cddad830..42c84e8f 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -81,6 +81,52 @@ void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* r std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; }); } -void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { - monitor->setCTM(ctm); +CHyprlandCTMControlProtocol::SCTMData::SCTMData() { + progress.create(g_pConfigManager->getAnimationPropertyConfig("__internal_fadeCTM"), AVARDAMAGE_NONE); + progress.setValueAndWarp(0.F); +} + +void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { + + std::erase_if(m_mCTMDatas, [](const auto& el) { return !el.first; }); + + if (!m_mCTMDatas.contains(monitor)) + m_mCTMDatas[monitor] = std::make_unique(); + + auto& data = m_mCTMDatas.at(monitor); + + data->ctmFrom = data->ctmTo; + data->ctmTo = ctm; + + data->progress.setValueAndWarp(0.F); + data->progress = 1.F; + + monitor->setCTM(data->ctmFrom); + + data->progress.setUpdateCallback([monitor = PHLMONITORREF{monitor}, this](void* self) { + if (!monitor || !m_mCTMDatas.contains(monitor)) + return; + auto& data = m_mCTMDatas.at(monitor); + const auto from = data->ctmFrom.getMatrix(); + const auto to = data->ctmTo.getMatrix(); + const auto PROGRESS = data->progress.getPercent(); + + static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; }; + + std::array mtx; + for (size_t i = 0; i < 9; ++i) { + mtx[i] = lerp(from[i], to[i], PROGRESS); + } + + monitor->setCTM(mtx); + }); + + data->progress.setCallbackOnEnd([monitor = PHLMONITORREF{monitor}, this](void* self) { + if (!monitor || !m_mCTMDatas.contains(monitor)) { + monitor->setCTM(Mat3x3::identity()); + return; + } + auto& data = m_mCTMDatas.at(monitor); + monitor->setCTM(data->ctmTo); + }); } diff --git a/src/protocols/CTMControl.hpp b/src/protocols/CTMControl.hpp index 70bc79bc..51820f20 100644 --- a/src/protocols/CTMControl.hpp +++ b/src/protocols/CTMControl.hpp @@ -6,6 +6,8 @@ #include "WaylandProtocol.hpp" #include "hyprland-ctm-control-v1.hpp" #include +#include +#include "../helpers/AnimatedVariable.hpp" class CMonitor; @@ -36,6 +38,14 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { // std::vector> m_vManagers; + // + struct SCTMData { + SCTMData(); + Mat3x3 ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity(); + CAnimatedVariable progress; + }; + std::map> m_mCTMDatas; + friend class CHyprlandCTMControlResource; }; From 5b37d53992f3f9bfd7f5483a85f99adf7ac104f3 Mon Sep 17 00:00:00 2001 From: Tuur Vanhoutte <4633209+zjeffer@users.noreply.github.com> Date: Mon, 30 Dec 2024 00:09:17 +0100 Subject: [PATCH 0046/1444] hyprpm: add an option to force reload all plugins (#8883) --- hyprpm/hyprpm.usage | 2 +- hyprpm/src/core/PluginManager.cpp | 8 ++++---- hyprpm/src/core/PluginManager.hpp | 2 +- hyprpm/src/main.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hyprpm/hyprpm.usage b/hyprpm/hyprpm.usage index 24e631c5..c38bdd62 100644 --- a/hyprpm/hyprpm.usage +++ b/hyprpm/hyprpm.usage @@ -14,7 +14,7 @@ hyprpm []... | (list) "List all installed plugins" | (enable ) "Load a plugin" | (disable ) "Unload a plugin" - | (reload) "Reload all plugins" + | (reload) "Reload plugins to match the enabled/disabled state. Use -f to force reload." ; ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}}; diff --git a/hyprpm/src/core/PluginManager.cpp b/hyprpm/src/core/PluginManager.cpp index a3bd5a09..80d0a402 100644 --- a/hyprpm/src/core/PluginManager.cpp +++ b/hyprpm/src/core/PluginManager.cpp @@ -780,7 +780,7 @@ bool CPluginManager::disablePlugin(const std::string& name) { return ret; } -ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() { +ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState(bool forceReload) { if (headersValid() != HEADERS_OK) { std::println(stderr, "\n{}", failureString("headers are not up-to-date, please run hyprpm update.")); return LOADSTATE_HEADERS_OUTDATED; @@ -841,9 +841,9 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() { // (and Hyprland needs to restart) bool hyprlandVersionMismatch = false; - // unload disabled plugins + // unload disabled plugins (or all if forceReload is true) for (auto const& p : loadedPlugins) { - if (!enabled(p)) { + if (forceReload || !enabled(p)) { // unload if (!loadUnloadPlugin(HYPRPMPATH / repoForName(p) / (p + ".so"), false)) { std::println("{}", infoString("{} will be unloaded after restarting Hyprland", p)); @@ -859,7 +859,7 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() { if (!p.enabled) continue; - if (std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&](const auto& other) { return other == p.name; }) != loadedPlugins.end()) + if (!forceReload && std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&](const auto& other) { return other == p.name; }) != loadedPlugins.end()) continue; if (!loadUnloadPlugin(HYPRPMPATH / repoForName(p.name) / p.filename, true)) { diff --git a/hyprpm/src/core/PluginManager.hpp b/hyprpm/src/core/PluginManager.hpp index 7502cc04..a99d8e6e 100644 --- a/hyprpm/src/core/PluginManager.hpp +++ b/hyprpm/src/core/PluginManager.hpp @@ -51,7 +51,7 @@ class CPluginManager { bool enablePlugin(const std::string& name); bool disablePlugin(const std::string& name); - ePluginLoadStateReturn ensurePluginsLoadState(); + ePluginLoadStateReturn ensurePluginsLoadState(bool forceReload = false); bool loadUnloadPlugin(const std::string& path, bool load); SHyprlandVersion getHyprlandVersion(bool running = true); diff --git a/hyprpm/src/main.cpp b/hyprpm/src/main.cpp index 103132f9..887bb436 100644 --- a/hyprpm/src/main.cpp +++ b/hyprpm/src/main.cpp @@ -154,7 +154,7 @@ int main(int argc, char** argv, char** envp) { if (ret != LOADSTATE_OK) return 1; } else if (command[0] == "reload") { - auto ret = g_pPluginManager->ensurePluginsLoadState(); + auto ret = g_pPluginManager->ensurePluginsLoadState(force); if (ret != LOADSTATE_OK && notify) { switch (ret) { From fde569db6519b613369c863d192c67dedb386910 Mon Sep 17 00:00:00 2001 From: khushal-solves Date: Mon, 30 Dec 2024 04:41:16 +0530 Subject: [PATCH 0047/1444] master: replace always_center_master with slave_count_for_center_master (#8871) - Replaced boolean config parameter `always_center_master` to an integer value `slave_count_for_center_master` for more control on when to center master window. - Also updated configuration parameter, type, description and related internal variable. New description: **when using orientation=center, make the master window centered only when at least this many slave windows are open. (Set 0 to always_center_master)** This effects center orientation of master layout. Now, user can control when the master window would be centered --- src/config/ConfigDescriptions.hpp | 8 ++++---- src/config/ConfigManager.cpp | 2 +- src/layout/MasterLayout.cpp | 28 ++++++++++++++-------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 6792a763..e1c9cb46 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1603,10 +1603,10 @@ inline static const std::vector CONFIG_OPTIONS = { .data = SConfigOptionDescription::SBoolData{true}, }, SConfigOptionDescription{ - .value = "master:always_center_master", - .description = "when using orientation=center, keep the master window centered, even when it is the only window in the workspace.", - .type = CONFIG_OPTION_BOOL, - .data = SConfigOptionDescription::SBoolData{false}, + .value = "master:slave_count_for_center_master", + .description = "when using orientation=center, make the master window centered only when at least this many slave windows are open. (Set 0 to always_center_master)", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{2, 0, 10}, //##TODO RANGE? }, SConfigOptionDescription{ .value = "master:center_ignores_reserved", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 65f9cb13..0b8e68f6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -477,7 +477,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("master:special_scale_factor", {1.f}); m_pConfig->addConfigValue("master:mfact", {0.55f}); m_pConfig->addConfigValue("master:new_status", {"slave"}); - m_pConfig->addConfigValue("master:always_center_master", Hyprlang::INT{0}); + m_pConfig->addConfigValue("master:slave_count_for_center_master", Hyprlang::INT{2}); m_pConfig->addConfigValue("master:center_ignores_reserved", Hyprlang::INT{0}); m_pConfig->addConfigValue("master:new_on_active", {"none"}); m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0}); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index f4730892..05a2a707 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -325,11 +325,11 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { if (!PMASTERNODE) return; - eOrientation orientation = getDynamicOrientation(pWorkspace); - bool centerMasterWindow = false; - static auto ALWAYSCENTER = CConfigValue("master:always_center_master"); - static auto PIGNORERESERVED = CConfigValue("master:center_ignores_reserved"); - static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); + eOrientation orientation = getDynamicOrientation(pWorkspace); + bool centerMasterWindow = false; + static auto SLAVECOUNTFORCENTER = CConfigValue("master:slave_count_for_center_master"); + static auto PIGNORERESERVED = CConfigValue("master:center_ignores_reserved"); + static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); const auto MASTERS = getMastersOnWorkspace(pWorkspace->m_iID); const auto WINDOWS = getNodesOnWorkspace(pWorkspace->m_iID); @@ -338,7 +338,7 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { const auto WSPOS = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; if (orientation == ORIENTATION_CENTER) { - if (STACKWINDOWS >= 2 || (*ALWAYSCENTER == 1)) { + if (STACKWINDOWS >= *SLAVECOUNTFORCENTER) { centerMasterWindow = true; } else { orientation = ORIENTATION_LEFT; @@ -708,13 +708,9 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne return; } - const auto PMONITOR = PWINDOW->m_pMonitor.lock(); - static auto ALWAYSCENTER = CConfigValue("master:always_center_master"); - static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); - - eOrientation orientation = getDynamicOrientation(PWINDOW->m_pWorkspace); - bool centered = orientation == ORIENTATION_CENTER && (*ALWAYSCENTER == 1); - double delta = 0; + const auto PMONITOR = PWINDOW->m_pMonitor.lock(); + static auto SLAVECOUNTFORCENTER = CConfigValue("master:slave_count_for_center_master"); + static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); const bool DISPLAYBOTTOM = STICKS(PWINDOW->m_vPosition.y + PWINDOW->m_vSize.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y); const bool DISPLAYRIGHT = STICKS(PWINDOW->m_vPosition.x + PWINDOW->m_vSize.x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x); @@ -729,6 +725,10 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne const auto WINDOWS = getNodesOnWorkspace(PNODE->workspaceID); const auto STACKWINDOWS = WINDOWS - MASTERS; + eOrientation orientation = getDynamicOrientation(PWINDOW->m_pWorkspace); + bool centered = orientation == ORIENTATION_CENTER && (STACKWINDOWS >= *SLAVECOUNTFORCENTER); + double delta = 0; + if (getNodesOnWorkspace(PWINDOW->workspaceID()) == 1 && !centered) return; @@ -741,7 +741,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne case ORIENTATION_TOP: delta = pixResize.y / PMONITOR->vecSize.y; break; case ORIENTATION_CENTER: delta = pixResize.x / PMONITOR->vecSize.x; - if (WINDOWS > 2 || *ALWAYSCENTER) { + if (STACKWINDOWS >= *SLAVECOUNTFORCENTER) { if (!NONE || !PNODE->isMaster) delta *= 2; if ((!PNODE->isMaster && DISPLAYLEFT) || (PNODE->isMaster && LEFT && *PSMARTRESIZING)) From cb211d83f68542e9fbf7567d57bdf528286cbf7e Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Sun, 29 Dec 2024 17:19:12 -0600 Subject: [PATCH 0048/1444] internal: few small monitor improvements (#8890) * remove framesToSkip, its not used anymore * only set drm format when needed after leaving direct scanout * always set drm damage --- src/Compositor.cpp | 5 ----- src/helpers/Monitor.hpp | 2 -- src/render/Renderer.cpp | 44 +++++++++++++---------------------------- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 91a7705d..4e22f398 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -434,11 +434,6 @@ void CCompositor::initAllSignals() { Debug::log(LOG, "Session got deactivated!"); m_bSessionActive = false; - - for (auto const& m : m_vMonitors) { - m->noFrameSchedule = true; - m->framesToSkip = 1; - } } }, nullptr); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index d9f5e88c..b075df81 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -90,9 +90,7 @@ class CMonitor { SP output; float refreshRate = 60; - int framesToSkip = 0; int forceFullFrames = 0; - bool noFrameSchedule = false; bool scheduledRecalc = false; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; float xwaylandScale = 1.f; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f3030d18..a66c681b 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1126,22 +1126,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { if (*PDEBUGOVERLAY == 1) g_pDebugOverlay->frameData(pMonitor); - if (pMonitor->framesToSkip > 0) { - pMonitor->framesToSkip -= 1; - - if (!pMonitor->noFrameSchedule) - g_pCompositor->scheduleFrameForMonitor(pMonitor, Aquamarine::IOutput::AQ_SCHEDULE_RENDER_MONITOR); - else - Debug::log(LOG, "NoFrameSchedule hit for {}.", pMonitor->szName); - - g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitor->ID); - - if (pMonitor->framesToSkip > 10) - pMonitor->framesToSkip = 0; + if (!g_pCompositor->m_bSessionActive) return; - } - // checks // if (pMonitor->ID == m_pMostHzMonitor->ID || *PVFR == 1) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that g_pCompositor->sanityCheckWorkspaces(); @@ -1151,7 +1138,6 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { if (g_pConfigManager->m_bWantsMonitorReload) g_pConfigManager->performMonitorReload(); } - // // if (pMonitor->scheduledRecalc) { pMonitor->scheduledRecalc = false; @@ -1194,8 +1180,10 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { Debug::log(LOG, "Left a direct scanout."); pMonitor->lastScanout.reset(); - // reset DRM format, make sure it's the one we want. - pMonitor->output->state->setFormat(pMonitor->prevDrmFormat); + // reset DRM format, but only if needed since it might modeset + if (pMonitor->output->state->state().drmFormat != pMonitor->prevDrmFormat) + pMonitor->output->state->setFormat(pMonitor->prevDrmFormat); + pMonitor->drmFormat = pMonitor->prevDrmFormat; } } @@ -1331,31 +1319,27 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { endRender(); - finalDamage = g_pHyprOpenGL->m_RenderData.damage; - TRACY_GPU_COLLECT; - if (!pMonitor->mirrors.empty()) { - CRegion frameDamage{finalDamage}; + CRegion frameDamage{g_pHyprOpenGL->m_RenderData.damage}; - const auto TRANSFORM = invertTransform(pMonitor->transform); - frameDamage.transform(wlTransformToHyprutils(TRANSFORM), pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y); + const auto TRANSFORM = invertTransform(pMonitor->transform); + frameDamage.transform(wlTransformToHyprutils(TRANSFORM), pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y); - if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR) - frameDamage.add(0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y); + if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR) + frameDamage.add(0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y); - if (*PDAMAGEBLINK) - frameDamage.add(damage); + if (*PDAMAGEBLINK) + frameDamage.add(damage); + if (!pMonitor->mirrors.empty()) damageMirrorsWith(pMonitor, frameDamage); - pMonitor->output->state->addDamage(frameDamage); - } - pMonitor->renderingActive = false; EMIT_HOOK_EVENT("render", RENDER_POST); + pMonitor->output->state->addDamage(frameDamage); pMonitor->output->state->setPresentationMode(shouldTear ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE : Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC); From 8c14c2a5f472cf3d361d3cbb90ee7d2d455aae08 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 30 Dec 2024 11:57:55 +0100 Subject: [PATCH 0049/1444] ctm: disable fade animation by default on nvidia Fixes #8891, the nvidia driver dies when we spam CTM too much. --- src/config/ConfigDescriptions.hpp | 18 ++++++++++++++++++ src/config/ConfigManager.cpp | 1 + src/protocols/CTMControl.cpp | 14 ++++++++++++++ src/protocols/CTMControl.hpp | 1 + 4 files changed, 34 insertions(+) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index e1c9cb46..17657983 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1289,6 +1289,24 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{false}, }, + SConfigOptionDescription{ + .value = "render:expand_undersized_textures", + .description = "Whether to expand textures that have not yet resized to be larger, or to just stretch them instead.", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, + SConfigOptionDescription{ + .value = "render:xp_mode", + .description = "Disable back buffer and bottom layer rendering.", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, + SConfigOptionDescription{ + .value = "render:ctm_animation", + .description = "Whether to enable a fade animation for CTM changes (hyprsunset). 2 means 'auto' (Yes on everything but Nvidia).", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{2, 0, 2}, + }, /* * cursor: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 0b8e68f6..67df5bf4 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -614,6 +614,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("render:direct_scanout", Hyprlang::INT{0}); m_pConfig->addConfigValue("render:expand_undersized_textures", Hyprlang::INT{1}); m_pConfig->addConfigValue("render:xp_mode", Hyprlang::INT{0}); + m_pConfig->addConfigValue("render:ctm_animation", Hyprlang::INT{2}); m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0}); diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index 42c84e8f..250c6326 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -1,6 +1,8 @@ #include "CTMControl.hpp" #include "../Compositor.hpp" +#include "../render/Renderer.hpp" #include "core/Output.hpp" +#include "../config/ConfigValue.hpp" CHyprlandCTMControlResource::CHyprlandCTMControlResource(SP resource_) : resource(resource_) { if (!good()) @@ -81,12 +83,24 @@ void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* r std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; }); } +bool CHyprlandCTMControlProtocol::isCTMAnimationEnabled() { + static auto PENABLEANIM = CConfigValue("render:ctm_animation"); + + if (*PENABLEANIM == 2) + return !g_pHyprRenderer->isNvidia(); + return *PENABLEANIM; +} + CHyprlandCTMControlProtocol::SCTMData::SCTMData() { progress.create(g_pConfigManager->getAnimationPropertyConfig("__internal_fadeCTM"), AVARDAMAGE_NONE); progress.setValueAndWarp(0.F); } void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { + if (!isCTMAnimationEnabled()) { + monitor->setCTM(ctm); + return; + } std::erase_if(m_mCTMDatas, [](const auto& el) { return !el.first; }); diff --git a/src/protocols/CTMControl.hpp b/src/protocols/CTMControl.hpp index 51820f20..dea2c258 100644 --- a/src/protocols/CTMControl.hpp +++ b/src/protocols/CTMControl.hpp @@ -34,6 +34,7 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { void destroyResource(CHyprlandCTMControlResource* resource); void setCTM(PHLMONITOR monitor, const Mat3x3& ctm); + bool isCTMAnimationEnabled(); // std::vector> m_vManagers; From af301312d5b9d69a39fd0a7584d2891f34d40430 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Mon, 30 Dec 2024 12:45:42 -0600 Subject: [PATCH 0050/1444] core: fix custom resolutions (#8897) --- src/helpers/Monitor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 3fb90959..01bb79ac 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -479,6 +479,12 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { return false; }); + // if the best mode isnt close to requested, then try requested as custom mode first + auto bestMode = requestedModes.back(); + if (!DELTALESSTHAN(bestMode->pixelSize.x, RULE->resolution.x, 1) || !DELTALESSTHAN(bestMode->pixelSize.y, RULE->resolution.y, 1) || + !DELTALESSTHAN(bestMode->refreshRate / 1000.f, RULE->refreshRate, 1)) + requestedModes.push_back(makeShared(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = RULE->refreshRate * 1000.f})); + // then if requested is custom, try custom mode first if (RULE->drmMode.type == DRM_MODE_TYPE_USERDEF) { if (output->getBackend()->type() != Aquamarine::eBackendType::AQ_BACKEND_DRM) From 9f933da1c502989cadf7696971aa376d65847b95 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 30 Dec 2024 20:00:34 +0100 Subject: [PATCH 0051/1444] renderer: fix oversized blur precalcs not blurring at all fixes #8839 --- src/render/Renderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index a66c681b..391492b0 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -536,6 +536,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe data.color = CHyprColor(0, 0, 0, 0); data.box = wb; data.round = renderdata.dontRound ? 0 : renderdata.rounding - 1; + data.blur = true; data.blurA = renderdata.fadeAlpha; data.xray = g_pHyprOpenGL->shouldUseNewBlurOptimizations(nullptr, pWindow); m_sRenderPass.add(makeShared(data)); From 1989b0049f7fb714a2417dfb14d6b4f3d2a079d3 Mon Sep 17 00:00:00 2001 From: davc0n Date: Mon, 30 Dec 2024 20:12:29 +0100 Subject: [PATCH 0052/1444] hyprpm: add glaze dependency FetchContent fallback (#8899) Use FetchContent to retrieve glaze dependency if not available with find_package. Allows to build hyprpm w/o installing glaze at system level (on some distros is not available in official repositories). --- hyprpm/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hyprpm/CMakeLists.txt b/hyprpm/CMakeLists.txt index 8eb325fd..d744ac16 100644 --- a/hyprpm/CMakeLists.txt +++ b/hyprpm/CMakeLists.txt @@ -10,7 +10,20 @@ file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp") set(CMAKE_CXX_STANDARD 23) pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.2.4) -find_package(glaze REQUIRED) + +find_package(glaze QUIET) +if (NOT glaze_FOUND) + set(GLAZE_VERSION v4.2.3) + message(STATUS "glaze dependency not found, retrieving ${GLAZE_VERSION} with FetchContent") + include(FetchContent) + FetchContent_Declare( + glaze + GIT_REPOSITORY https://github.com/stephenberry/glaze.git + GIT_TAG ${GLAZE_VERSION} + GIT_SHALLOW TRUE + ) + FetchContent_MakeAvailable(glaze) +endif() add_executable(hyprpm ${SRCFILES}) From aff34089c4d66b951d25a0dc1867f7fb93d61a7d Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 1 Jan 2025 13:47:16 +0100 Subject: [PATCH 0053/1444] monitor: avoid crashes on no good modes fixes #8915 --- src/helpers/Monitor.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 01bb79ac..76df00b3 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -480,10 +480,12 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { }); // if the best mode isnt close to requested, then try requested as custom mode first - auto bestMode = requestedModes.back(); - if (!DELTALESSTHAN(bestMode->pixelSize.x, RULE->resolution.x, 1) || !DELTALESSTHAN(bestMode->pixelSize.y, RULE->resolution.y, 1) || - !DELTALESSTHAN(bestMode->refreshRate / 1000.f, RULE->refreshRate, 1)) - requestedModes.push_back(makeShared(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = RULE->refreshRate * 1000.f})); + if (!requestedModes.empty()) { + auto bestMode = requestedModes.back(); + if (!DELTALESSTHAN(bestMode->pixelSize.x, RULE->resolution.x, 1) || !DELTALESSTHAN(bestMode->pixelSize.y, RULE->resolution.y, 1) || + !DELTALESSTHAN(bestMode->refreshRate / 1000.f, RULE->refreshRate, 1)) + requestedModes.push_back(makeShared(Aquamarine::SOutputMode{.pixelSize = RULE->resolution, .refreshRate = RULE->refreshRate * 1000.f})); + } // then if requested is custom, try custom mode first if (RULE->drmMode.type == DRM_MODE_TYPE_USERDEF) { @@ -510,8 +512,12 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { if (Debug::trace) { Debug::log(TRACE, "Monitor {} requested modes:", szName); - for (auto const& mode : requestedModes | std::views::reverse) { - Debug::log(TRACE, "| {:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f); + if (requestedModes.empty()) + Debug::log(TRACE, "| None"); + else { + for (auto const& mode : requestedModes | std::views::reverse) { + Debug::log(TRACE, "| {:X0}@{:.2f}Hz", mode->pixelSize, mode->refreshRate / 1000.f); + } } } From 4e93b2def5f00f944abbd63a8258ee18bd99ff54 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 1 Jan 2025 14:11:21 +0100 Subject: [PATCH 0054/1444] renderer: use a render pass for render modif in client render fixes #8918 --- src/render/OpenGL.hpp | 1 - src/render/Renderer.cpp | 38 ++++++++++---------- src/render/pass/RendererHintsPassElement.cpp | 19 ++++++++++ src/render/pass/RendererHintsPassElement.hpp | 25 +++++++++++++ 4 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 src/render/pass/RendererHintsPassElement.cpp create mode 100644 src/render/pass/RendererHintsPassElement.hpp diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 0b72d438..e73a3119 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -110,7 +110,6 @@ struct SMonitorRenderData { struct SCurrentRenderData { PHLMONITORREF pMonitor; - PHLWORKSPACE pWorkspace = nullptr; Mat3x3 projection; Mat3x3 savedProjection; Mat3x3 monitorProjection; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 391492b0..9aa794b4 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -22,6 +22,7 @@ #include "pass/TexPassElement.hpp" #include "pass/ClearPassElement.hpp" #include "pass/RectPassElement.hpp" +#include "pass/RendererHintsPassElement.hpp" #include "pass/SurfacePassElement.hpp" #include "debug/Log.hpp" @@ -780,18 +781,12 @@ void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, PHLM } void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* time, const Vector2D& translate, const float& scale) { - static auto PDIMSPECIAL = CConfigValue("decoration:dim_special"); - static auto PBLURSPECIAL = CConfigValue("decoration:blur:special"); - static auto PBLUR = CConfigValue("decoration:blur:enabled"); - static auto PRENDERTEX = CConfigValue("misc:disable_hyprland_logo"); - static auto PBACKGROUNDCOLOR = CConfigValue("misc:background_color"); - static auto PXPMODE = CConfigValue("render:xp_mode"); - - SRenderModifData RENDERMODIFDATA; - if (translate != Vector2D{0, 0}) - RENDERMODIFDATA.modifs.emplace_back(std::make_pair<>(SRenderModifData::eRenderModifType::RMOD_TYPE_TRANSLATE, translate)); - if (scale != 1.f) - RENDERMODIFDATA.modifs.emplace_back(std::make_pair<>(SRenderModifData::eRenderModifType::RMOD_TYPE_SCALE, scale)); + static auto PDIMSPECIAL = CConfigValue("decoration:dim_special"); + static auto PBLURSPECIAL = CConfigValue("decoration:blur:special"); + static auto PBLUR = CConfigValue("decoration:blur:enabled"); + static auto PRENDERTEX = CConfigValue("misc:disable_hyprland_logo"); + static auto PBACKGROUNDCOLOR = CConfigValue("misc:background_color"); + static auto PXPMODE = CConfigValue("render:xp_mode"); if (!pMonitor) return; @@ -805,7 +800,19 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA // todo: matrices are buggy atm for some reason, but probably would be preferable in the long run // g_pHyprOpenGL->saveMatrix(); // g_pHyprOpenGL->setMatrixScaleTranslate(translate, scale); - g_pHyprOpenGL->m_RenderData.renderModif = RENDERMODIFDATA; + + SRenderModifData RENDERMODIFDATA; + if (translate != Vector2D{0, 0}) + RENDERMODIFDATA.modifs.emplace_back(std::make_pair<>(SRenderModifData::eRenderModifType::RMOD_TYPE_TRANSLATE, translate)); + if (scale != 1.f) + RENDERMODIFDATA.modifs.emplace_back(std::make_pair<>(SRenderModifData::eRenderModifType::RMOD_TYPE_SCALE, scale)); + + CScopeGuard x([] {}); + + if (!RENDERMODIFDATA.modifs.empty()) { + g_pHyprRenderer->m_sRenderPass.add(makeShared(CRendererHintsPassElement::SData{RENDERMODIFDATA})); + x = CScopeGuard([] { g_pHyprRenderer->m_sRenderPass.add(makeShared(CRendererHintsPassElement::SData{SRenderModifData{}})); }); + } if (!pWorkspace) { // allow rendering without a workspace. In this case, just render layers. @@ -828,8 +835,6 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA renderLayer(ls.lock(), pMonitor, time); } - g_pHyprOpenGL->m_RenderData.renderModif = {}; - return; } @@ -933,7 +938,6 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA renderDragIcon(pMonitor, time); //g_pHyprOpenGL->restoreMatrix(); - g_pHyprOpenGL->m_RenderData.renderModif = {}; } void CHyprRenderer::renderLockscreen(PHLMONITOR pMonitor, timespec* now, const CBox& geometry) { @@ -1436,9 +1440,7 @@ void CHyprRenderer::renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace translate = Vector2D{}; } - g_pHyprOpenGL->m_RenderData.pWorkspace = pWorkspace; renderAllClientsForWorkspace(pMonitor, pWorkspace, now, translate, scale); - g_pHyprOpenGL->m_RenderData.pWorkspace = nullptr; } void CHyprRenderer::sendFrameEventsToWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now) { diff --git a/src/render/pass/RendererHintsPassElement.cpp b/src/render/pass/RendererHintsPassElement.cpp new file mode 100644 index 00000000..8ea79a27 --- /dev/null +++ b/src/render/pass/RendererHintsPassElement.cpp @@ -0,0 +1,19 @@ +#include "RendererHintsPassElement.hpp" +#include "../OpenGL.hpp" + +CRendererHintsPassElement::CRendererHintsPassElement(const CRendererHintsPassElement::SData& data_) : data(data_) { + ; +} + +void CRendererHintsPassElement::draw(const CRegion& damage) { + if (data.renderModif.has_value()) + g_pHyprOpenGL->m_RenderData.renderModif = *data.renderModif; +} + +bool CRendererHintsPassElement::needsLiveBlur() { + return false; +} + +bool CRendererHintsPassElement::needsPrecomputeBlur() { + return false; +} diff --git a/src/render/pass/RendererHintsPassElement.hpp b/src/render/pass/RendererHintsPassElement.hpp new file mode 100644 index 00000000..99ed0759 --- /dev/null +++ b/src/render/pass/RendererHintsPassElement.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "PassElement.hpp" +#include +#include "../OpenGL.hpp" + +class CRendererHintsPassElement : public IPassElement { + public: + struct SData { + std::optional renderModif; + }; + + CRendererHintsPassElement(const SData& data); + virtual ~CRendererHintsPassElement() = default; + + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + + virtual const char* passName() { + return "CRendererHintsPassElement"; + } + + private: + SData data; +}; \ No newline at end of file From d64ac472027b9bcd6eefb4c9e86f85311769f7fa Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 1 Jan 2025 17:26:05 +0100 Subject: [PATCH 0055/1444] pass: improve pass debugging --- src/helpers/Color.cpp | 4 ++ src/helpers/Color.hpp | 16 ++++++++ src/render/OpenGL.hpp | 83 ++++++++++++++++++++-------------------- src/render/pass/Pass.cpp | 67 ++++++++++++++++++++++++++++++-- src/render/pass/Pass.hpp | 7 ++++ 5 files changed, 133 insertions(+), 44 deletions(-) diff --git a/src/helpers/Color.cpp b/src/helpers/Color.cpp index 7952ef55..8dfefbbd 100644 --- a/src/helpers/Color.cpp +++ b/src/helpers/Color.cpp @@ -43,3 +43,7 @@ Hyprgraphics::CColor::SHSL CHyprColor::asHSL() const { CHyprColor CHyprColor::stripA() const { return {r, g, b, 1.F}; } + +CHyprColor CHyprColor::modifyA(float newa) const { + return {r, g, b, newa}; +} diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp index cf7f7943..0ea816f3 100644 --- a/src/helpers/Color.hpp +++ b/src/helpers/Color.hpp @@ -18,6 +18,7 @@ class CHyprColor { Hyprgraphics::CColor::SOkLab asOkLab() const; Hyprgraphics::CColor::SHSL asHSL() const; CHyprColor stripA() const; + CHyprColor modifyA(float newa) const; // bool operator==(const CHyprColor& c2) const { @@ -45,3 +46,18 @@ class CHyprColor { private: Hyprgraphics::CColor::SOkLab okLab; // cache for the OkLab representation }; + +//NOLINTNEXTLINE +namespace Colors { + static const CHyprColor WHITE = CHyprColor(1.F, 1.F, 1.F, 1.F); + static const CHyprColor GREEN = CHyprColor(0.F, 1.F, 0.F, 1.F); + static const CHyprColor BLUE = CHyprColor(0.F, 0.F, 1.F, 1.F); + static const CHyprColor RED = CHyprColor(1.F, 0.F, 0.F, 1.F); + static const CHyprColor ORANGE = CHyprColor(1.F, 0.5F, 0.F, 1.F); + static const CHyprColor YELLOW = CHyprColor(1.F, 1.F, 0.F, 1.F); + static const CHyprColor MAGENTA = CHyprColor(1.F, 0.F, 1.F, 1.F); + static const CHyprColor PURPLE = CHyprColor(0.5F, 0.F, 0.5F, 1.F); + static const CHyprColor LIME = CHyprColor(0.5F, 1.F, 0.1F, 1.F); + static const CHyprColor LIGHT_BLUE = CHyprColor(0.1F, 1.F, 1.F, 1.F); + static const CHyprColor BLACK = CHyprColor(0.F, 0.F, 0.F, 1.F); +}; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index e73a3119..4fceabc5 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -166,59 +166,62 @@ class CHyprOpenGLImpl { CHyprOpenGLImpl(); ~CHyprOpenGLImpl(); - void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); - void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); - void end(); + void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); + void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); + void end(); - void renderRect(CBox*, const CHyprColor&, int round = 0); - void renderRectWithBlur(CBox*, const CHyprColor&, int round = 0, float blurA = 1.f, bool xray = false); - void renderRectWithDamage(CBox*, const CHyprColor&, const CRegion& damage, int round = 0); - void renderTexture(SP, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); - void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false, - SP waitTimeline = nullptr, uint64_t waitPoint = 0); - void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f); - void renderRoundedShadow(CBox*, int round, int range, const CHyprColor& color, float a = 1.0); - void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); - void renderBorder(CBox*, const CGradientValueData&, const CGradientValueData&, float lerp, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); - void renderTextureMatte(SP tex, CBox* pBox, CFramebuffer& matte); + void renderRect(CBox*, const CHyprColor&, int round = 0); + void renderRectWithBlur(CBox*, const CHyprColor&, int round = 0, float blurA = 1.f, bool xray = false); + void renderRectWithDamage(CBox*, const CHyprColor&, const CRegion& damage, int round = 0); + void renderTexture(SP, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); + void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false, + SP waitTimeline = nullptr, uint64_t waitPoint = 0); + void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f); + void renderRoundedShadow(CBox*, int round, int range, const CHyprColor& color, float a = 1.0); + void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); + void renderBorder(CBox*, const CGradientValueData&, const CGradientValueData&, float lerp, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); + void renderTextureMatte(SP tex, CBox* pBox, CFramebuffer& matte); - void setMonitorTransformEnabled(bool enabled); - void setRenderModifEnabled(bool enabled); + void setMonitorTransformEnabled(bool enabled); + void setRenderModifEnabled(bool enabled); - void saveMatrix(); - void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); - void restoreMatrix(); + void saveMatrix(); + void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); + void restoreMatrix(); - void blend(bool enabled); + void blend(bool enabled); - bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); + bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); - void clear(const CHyprColor&); - void clearWithTex(); - void scissor(const CBox*, bool transform = true); - void scissor(const pixman_box32*, bool transform = true); - void scissor(const int x, const int y, const int w, const int h, bool transform = true); + void clear(const CHyprColor&); + void clearWithTex(); + void scissor(const CBox*, bool transform = true); + void scissor(const pixman_box32*, bool transform = true); + void scissor(const int x, const int y, const int w, const int h, bool transform = true); - void destroyMonitorResources(PHLMONITOR); + void destroyMonitorResources(PHLMONITOR); - void markBlurDirtyForMonitor(PHLMONITOR); + void markBlurDirtyForMonitor(PHLMONITOR); - void preWindowPass(); - bool preBlurQueued(); - void preRender(PHLMONITOR); + void preWindowPass(); + bool preBlurQueued(); + void preRender(PHLMONITOR); - void saveBufferForMirror(CBox*); - void renderMirrored(); + void saveBufferForMirror(CBox*); + void renderMirrored(); - void applyScreenShader(const std::string& path); + void applyScreenShader(const std::string& path); - void bindOffMain(); - void renderOffToMain(CFramebuffer* off); - void bindBackOnMain(); + void bindOffMain(); + void renderOffToMain(CFramebuffer* off); + void bindBackOnMain(); - void setDamage(const CRegion& damage, std::optional finalDamage = {}); + SP loadAsset(const std::string& file); + SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false); - uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); + void setDamage(const CRegion& damage, std::optional finalDamage = {}); + + uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); std::vector getDRMFormats(); EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); SP createEGLSync(int fenceFD); @@ -298,8 +301,6 @@ class CHyprOpenGLImpl { void initDRMFormats(); void initEGL(bool gbm); EGLDeviceEXT eglDeviceFromDRMFD(int drmFD); - SP loadAsset(const std::string& file); - SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false); void initAssets(); void initMissingAssetTexture(); diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index f71bd562..a2ecddaa 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -3,6 +3,10 @@ #include #include #include "../../config/ConfigValue.hpp" +#include "../../desktop/WLSurface.hpp" +#include "../../managers/SeatManager.hpp" +#include "../../managers/eventLoop/EventLoopManager.hpp" +#include "../../Compositor.hpp" bool CRenderPass::empty() const { return false; @@ -120,6 +124,15 @@ CRegion CRenderPass::render(const CRegion& damage_) { return damage; } + if (!*PDEBUGPASS && debugData.present) + debugData = {false}; + else if (*PDEBUGPASS && !debugData.present) { + debugData.present = true; + debugData.keyboardFocusText = g_pHyprOpenGL->renderText("keyboard", Colors::WHITE, 12); + debugData.pointerFocusText = g_pHyprOpenGL->renderText("pointer", Colors::WHITE, 12); + debugData.lastWindowText = g_pHyprOpenGL->renderText("lastWindow", Colors::WHITE, 12); + } + if (WILLBLUR && !*PDEBUGPASS) { // combine blur regions into one that will be expanded CRegion blurRegion; @@ -171,15 +184,63 @@ CRegion CRenderPass::render(const CRegion& damage_) { } if (*PDEBUGPASS) { - CBox monbox = {{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}; - g_pHyprOpenGL->renderRectWithDamage(&monbox, CHyprColor{1.F, 0.1F, 0.1F, 0.5F}, occludedRegion); - g_pHyprOpenGL->renderRectWithDamage(&monbox, CHyprColor{0.1F, 1.F, 0.1F, 0.5F}, totalLiveBlurRegion); + renderDebugData(); + g_pEventLoopManager->doLater([] { + for (auto& m : g_pCompositor->m_vMonitors) { + g_pHyprRenderer->damageMonitor(m); + } + }); } g_pHyprOpenGL->m_RenderData.damage = damage; return damage; } +void CRenderPass::renderDebugData() { + CBox box = {{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}; + g_pHyprOpenGL->renderRectWithDamage(&box, Colors::RED.modifyA(0.1F), occludedRegion); + g_pHyprOpenGL->renderRectWithDamage(&box, Colors::GREEN.modifyA(0.1F), totalLiveBlurRegion); + + std::unordered_map offsets; + + // render focus stuff + auto renderHLSurface = [&offsets](SP texture, SP surface, const CHyprColor& color) { + if (!surface || !texture) + return; + + auto hlSurface = CWLSurface::fromResource(surface); + if (!hlSurface) + return; + + auto bb = hlSurface->getSurfaceBoxGlobal(); + + if (!bb.has_value()) + return; + + CBox box = bb->copy().translate(-g_pHyprOpenGL->m_RenderData.pMonitor->vecPosition).scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); + + if (box.intersection(CBox{{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize}).empty()) + return; + + if (offsets.contains(surface.get())) + box.translate(Vector2D{0.F, offsets[surface.get()]}); + else + offsets[surface.get()] = 0; + + g_pHyprOpenGL->renderRectWithDamage(&box, Colors::PURPLE.modifyA(0.1F), CRegion{0, 0, INT32_MAX, INT32_MAX}); + box = {box.pos(), texture->m_vSize}; + g_pHyprOpenGL->renderRectWithDamage(&box, CHyprColor{0.F, 0.F, 0.F, 0.2F}, CRegion{0, 0, INT32_MAX, INT32_MAX}, std::min(5.0, box.size().y)); + g_pHyprOpenGL->renderTexture(texture, &box, 1.F); + + offsets[surface.get()] += texture->m_vSize.y; + }; + + renderHLSurface(debugData.keyboardFocusText, g_pSeatManager->state.keyboardFocus.lock(), Colors::PURPLE.modifyA(0.1F)); + renderHLSurface(debugData.pointerFocusText, g_pSeatManager->state.pointerFocus.lock(), Colors::ORANGE.modifyA(0.1F)); + if (g_pCompositor->m_pLastWindow) + renderHLSurface(debugData.lastWindowText, g_pCompositor->m_pLastWindow->m_pWLSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F)); +} + float CRenderPass::oneBlurRadius() { // TODO: is this exact range correct? static auto PBLURSIZE = CConfigValue("decoration:blur:size"); diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp index 6fe6938f..5d7d3bb3 100644 --- a/src/render/pass/Pass.hpp +++ b/src/render/pass/Pass.hpp @@ -4,6 +4,7 @@ #include "PassElement.hpp" class CGradientValueData; +class CTexture; class CRenderPass { public: @@ -33,6 +34,12 @@ class CRenderPass { void simplify(); float oneBlurRadius(); + void renderDebugData(); + + struct { + bool present = false; + SP keyboardFocusText, pointerFocusText, lastWindowText; + } debugData; friend class CHyprOpenGLImpl; }; From 7f177fa1cf3d8ede2841cdbbbdb7acaf27e40d57 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 1 Jan 2025 17:28:04 +0100 Subject: [PATCH 0056/1444] layershell: return focus to a valid ls on close if possible --- src/desktop/LayerSurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index c8134219..05ea4473 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -241,7 +241,7 @@ void CLayerSurface::onUnmap() { (int)layerSurface->surface->current.size.y}; g_pHyprRenderer->damageBox(&geomFixed); - g_pInputManager->sendMotionEventsToFocused(); + g_pInputManager->simulateMouseMovement(); g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); } From 9f3c9ac01a9a6ecef74429dc9a1dea250ef43c50 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 1 Jan 2025 21:35:42 +0100 Subject: [PATCH 0057/1444] pass: mark crucial elements as undiscardable --- src/render/pass/FramebufferElement.cpp | 6 +++++- src/render/pass/FramebufferElement.hpp | 1 + src/render/pass/Pass.cpp | 4 ++-- src/render/pass/PassElement.cpp | 4 ++++ src/render/pass/PassElement.hpp | 1 + src/render/pass/PreBlurElement.cpp | 4 ++++ src/render/pass/PreBlurElement.hpp | 1 + src/render/pass/RendererHintsPassElement.cpp | 4 ++++ src/render/pass/RendererHintsPassElement.hpp | 1 + 9 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/render/pass/FramebufferElement.cpp b/src/render/pass/FramebufferElement.cpp index 268e5589..8271777f 100644 --- a/src/render/pass/FramebufferElement.cpp +++ b/src/render/pass/FramebufferElement.cpp @@ -45,4 +45,8 @@ bool CFramebufferElement::needsLiveBlur() { bool CFramebufferElement::needsPrecomputeBlur() { return false; -} \ No newline at end of file +} + +bool CFramebufferElement::undiscardable() { + return true; +} diff --git a/src/render/pass/FramebufferElement.hpp b/src/render/pass/FramebufferElement.hpp index f3d181d4..ab1f1426 100644 --- a/src/render/pass/FramebufferElement.hpp +++ b/src/render/pass/FramebufferElement.hpp @@ -14,6 +14,7 @@ class CFramebufferElement : public IPassElement { virtual void draw(const CRegion& damage); virtual bool needsLiveBlur(); virtual bool needsPrecomputeBlur(); + virtual bool undiscardable(); virtual const char* passName() { return "CFramebufferElement"; diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index a2ecddaa..8fdc3049 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -35,14 +35,14 @@ void CRenderPass::simplify() { CRegion newDamage = damage.copy().intersect(CBox{{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}); for (auto& el : m_vPassElements | std::views::reverse) { - if (newDamage.empty()) { + if (newDamage.empty() && !el->element->undiscardable()) { el->discard = true; continue; } el->elementDamage = newDamage; auto bb1 = el->element->boundingBox(); - if (!bb1) + if (!bb1 || newDamage.empty()) continue; auto bb = bb1->scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); diff --git a/src/render/pass/PassElement.cpp b/src/render/pass/PassElement.cpp index 737c6b27..3ae52ef5 100644 --- a/src/render/pass/PassElement.cpp +++ b/src/render/pass/PassElement.cpp @@ -15,3 +15,7 @@ bool IPassElement::disableSimplification() { void IPassElement::discard() { ; } + +bool IPassElement::undiscardable() { + return false; +} diff --git a/src/render/pass/PassElement.hpp b/src/render/pass/PassElement.hpp index 025840f4..b45970aa 100644 --- a/src/render/pass/PassElement.hpp +++ b/src/render/pass/PassElement.hpp @@ -12,6 +12,7 @@ class IPassElement { virtual bool needsPrecomputeBlur() = 0; virtual const char* passName() = 0; virtual void discard(); + virtual bool undiscardable(); virtual std::optional boundingBox(); virtual CRegion opaqueRegion(); virtual bool disableSimplification(); diff --git a/src/render/pass/PreBlurElement.cpp b/src/render/pass/PreBlurElement.cpp index 9fa3471d..6f282232 100644 --- a/src/render/pass/PreBlurElement.cpp +++ b/src/render/pass/PreBlurElement.cpp @@ -18,3 +18,7 @@ bool CPreBlurElement::needsPrecomputeBlur() { bool CPreBlurElement::disableSimplification() { return true; } + +bool CPreBlurElement::undiscardable() { + return true; +} diff --git a/src/render/pass/PreBlurElement.hpp b/src/render/pass/PreBlurElement.hpp index 6c52c815..80474a29 100644 --- a/src/render/pass/PreBlurElement.hpp +++ b/src/render/pass/PreBlurElement.hpp @@ -10,6 +10,7 @@ class CPreBlurElement : public IPassElement { virtual bool needsLiveBlur(); virtual bool needsPrecomputeBlur(); virtual bool disableSimplification(); + virtual bool undiscardable(); virtual const char* passName() { return "CPreBlurElement"; diff --git a/src/render/pass/RendererHintsPassElement.cpp b/src/render/pass/RendererHintsPassElement.cpp index 8ea79a27..5b6d0098 100644 --- a/src/render/pass/RendererHintsPassElement.cpp +++ b/src/render/pass/RendererHintsPassElement.cpp @@ -17,3 +17,7 @@ bool CRendererHintsPassElement::needsLiveBlur() { bool CRendererHintsPassElement::needsPrecomputeBlur() { return false; } + +bool CRendererHintsPassElement::undiscardable() { + return true; +} diff --git a/src/render/pass/RendererHintsPassElement.hpp b/src/render/pass/RendererHintsPassElement.hpp index 99ed0759..a333e031 100644 --- a/src/render/pass/RendererHintsPassElement.hpp +++ b/src/render/pass/RendererHintsPassElement.hpp @@ -15,6 +15,7 @@ class CRendererHintsPassElement : public IPassElement { virtual void draw(const CRegion& damage); virtual bool needsLiveBlur(); virtual bool needsPrecomputeBlur(); + virtual bool undiscardable(); virtual const char* passName() { return "CRendererHintsPassElement"; From dde3e082c96cd6987420556bfc430cd5b8e0980c Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 1 Jan 2025 15:34:02 -0800 Subject: [PATCH 0058/1444] protocols: add hyprland_surface_v1 implementation (#8877) --- CMakeLists.txt | 1 + flake.lock | 6 +- protocols/meson.build | 1 + src/desktop/WLSurface.hpp | 5 +- src/managers/ProtocolManager.cpp | 4 + src/protocols/HyprlandSurface.cpp | 111 +++++++++++++++++++++++++ src/protocols/HyprlandSurface.hpp | 54 ++++++++++++ src/render/OpenGL.cpp | 7 +- src/render/OpenGL.hpp | 3 +- src/render/pass/SurfacePassElement.cpp | 13 +-- subprojects/hyprland-protocols | 2 +- 11 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 src/protocols/HyprlandSurface.cpp create mode 100644 src/protocols/HyprlandSurface.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3441039e..9d5c58b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,7 @@ protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true) protocolnew("protocols" "wlr-layer-shell-unstable-v1" true) protocolnew("protocols" "wayland-drm" true) protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true) +protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-surface-v1" true) protocolnew("staging/tearing-control" "tearing-control-v1" false) protocolnew("staging/fractional-scale" "fractional-scale-v1" false) diff --git a/flake.lock b/flake.lock index b9351586..76d371bc 100644 --- a/flake.lock +++ b/flake.lock @@ -128,11 +128,11 @@ ] }, "locked": { - "lastModified": 1728345020, - "narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=", + "lastModified": 1735734474, + "narHash": "sha256-9OV4lOqrEJVLdOrpNN/9msNwAhI6FQTu4N7fufilG08=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "a7c183800e74f337753de186522b9017a07a8cee", + "rev": "271df559dd30e4bc5ec6af02d017ac0aaabd63a7", "type": "github" }, "original": { diff --git a/protocols/meson.build b/protocols/meson.build index 2c0d06d1..a39602b7 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -37,6 +37,7 @@ protocols = [ hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml', + hyprland_protocol_dir / 'protocols/hyprland-surface-v1.xml', wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml', wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml', wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml', diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index a962b882..346fc935 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -86,6 +86,9 @@ class CWLSurface { // used by the alpha-modifier protocol float m_pAlphaModifier = 1.F; + // used by the hyprland-surface protocol + float m_fOverallOpacity = 1.F; + struct { CSignal destroy; } events; @@ -116,4 +119,4 @@ class CWLSurface { } listeners; friend class CPointerConstraint; -}; \ No newline at end of file +}; diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index cf517b22..0e1c21f5 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -47,6 +47,7 @@ #include "../protocols/SinglePixel.hpp" #include "../protocols/SecurityContext.hpp" #include "../protocols/CTMControl.hpp" +#include "../protocols/HyprlandSurface.hpp" #include "../protocols/core/Seat.hpp" #include "../protocols/core/DataDevice.hpp" @@ -159,6 +160,7 @@ CProtocolManager::CProtocolManager() { PROTO::singlePixel = std::make_unique(&wp_single_pixel_buffer_manager_v1_interface, 1, "SinglePixel"); PROTO::securityContext = std::make_unique(&wp_security_context_manager_v1_interface, 1, "SecurityContext"); PROTO::ctm = std::make_unique(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl"); + PROTO::hyprlandSurface = std::make_unique(&hyprland_surface_manager_v1_interface, 1, "HyprlandSurface"); for (auto const& b : g_pCompositor->m_pAqBackend->getImplementations()) { if (b->type() != Aquamarine::AQ_BACKEND_DRM) @@ -232,6 +234,7 @@ CProtocolManager::~CProtocolManager() { PROTO::singlePixel.reset(); PROTO::securityContext.reset(); PROTO::ctm.reset(); + PROTO::hyprlandSurface.reset(); PROTO::lease.reset(); PROTO::sync.reset(); @@ -282,6 +285,7 @@ bool CProtocolManager::isGlobalPrivileged(const wl_global* global) { PROTO::xdgDialog->getGlobal(), PROTO::singlePixel->getGlobal(), PROTO::primarySelection->getGlobal(), + PROTO::hyprlandSurface->getGlobal(), PROTO::sync ? PROTO::sync->getGlobal() : nullptr, PROTO::mesaDRM ? PROTO::mesaDRM->getGlobal() : nullptr, PROTO::linuxDma ? PROTO::linuxDma->getGlobal() : nullptr, diff --git a/src/protocols/HyprlandSurface.cpp b/src/protocols/HyprlandSurface.cpp new file mode 100644 index 00000000..ce6fc77a --- /dev/null +++ b/src/protocols/HyprlandSurface.cpp @@ -0,0 +1,111 @@ +#include "HyprlandSurface.hpp" +#include "../desktop/WLSurface.hpp" +#include "../render/Renderer.hpp" +#include "core/Compositor.hpp" +#include "hyprland-surface-v1.hpp" + +CHyprlandSurface::CHyprlandSurface(SP resource, SP surface) : m_pSurface(surface) { + setResource(std::move(resource)); +} + +bool CHyprlandSurface::good() const { + return m_pResource->resource(); +} + +void CHyprlandSurface::setResource(SP resource) { + m_pResource = std::move(resource); + + if (!m_pResource->resource()) + return; + + m_pResource->setDestroy([this](CHyprlandSurfaceV1* resource) { destroy(); }); + m_pResource->setOnDestroy([this](CHyprlandSurfaceV1* resource) { destroy(); }); + + m_pResource->setSetOpacity([this](CHyprlandSurfaceV1* resource, uint32_t opacity) { + if (!m_pSurface) { + m_pResource->error(HYPRLAND_SURFACE_V1_ERROR_NO_SURFACE, "set_opacity called for destroyed wl_surface"); + return; + } + + auto fOpacity = wl_fixed_to_double(opacity); + if (fOpacity < 0.0 || fOpacity > 1.0) { + m_pResource->error(HYPRLAND_SURFACE_V1_ERROR_OUT_OF_RANGE, "set_opacity called with an opacity value larger than 1.0 or smaller than 0.0."); + return; + } + + m_fOpacity = fOpacity; + }); + + listeners.surfaceCommitted = m_pSurface->events.commit.registerListener([this](std::any data) { + auto surface = CWLSurface::fromResource(m_pSurface.lock()); + + if (surface && surface->m_fOverallOpacity != m_fOpacity) { + surface->m_fOverallOpacity = m_fOpacity; + auto box = surface->getSurfaceBoxGlobal(); + + if (box.has_value()) + g_pHyprRenderer->damageBox(&*box); + + if (!m_pResource) + PROTO::hyprlandSurface->destroySurface(this); + } + }); + + listeners.surfaceDestroyed = m_pSurface->events.destroy.registerListener([this](std::any data) { + if (!m_pResource) + PROTO::hyprlandSurface->destroySurface(this); + }); +} + +void CHyprlandSurface::destroy() { + m_pResource.reset(); + m_fOpacity = 1.F; + + if (!m_pSurface) + PROTO::hyprlandSurface->destroySurface(this); +} + +CHyprlandSurfaceProtocol::CHyprlandSurfaceProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CHyprlandSurfaceProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + auto manager = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + manager->setOnDestroy([this](CHyprlandSurfaceManagerV1* manager) { destroyManager(manager); }); + + manager->setDestroy([this](CHyprlandSurfaceManagerV1* manager) { destroyManager(manager); }); + manager->setGetHyprlandSurface( + [this](CHyprlandSurfaceManagerV1* manager, uint32_t id, wl_resource* surface) { getSurface(manager, id, CWLSurfaceResource::fromResource(surface)); }); +} + +void CHyprlandSurfaceProtocol::destroyManager(CHyprlandSurfaceManagerV1* manager) { + std::erase_if(m_vManagers, [&](const auto& p) { return p.get() == manager; }); +} + +void CHyprlandSurfaceProtocol::destroySurface(CHyprlandSurface* surface) { + std::erase_if(m_mSurfaces, [&](const auto& entry) { return entry.second.get() == surface; }); +} + +void CHyprlandSurfaceProtocol::getSurface(CHyprlandSurfaceManagerV1* manager, uint32_t id, SP surface) { + CHyprlandSurface* hyprlandSurface = nullptr; + auto iter = std::find_if(m_mSurfaces.begin(), m_mSurfaces.end(), [&](const auto& entry) { return entry.second->m_pSurface == surface; }); + + if (iter != m_mSurfaces.end()) { + if (iter->second->m_pResource) { + LOGM(ERR, "HyprlandSurface already present for surface {:x}", (uintptr_t)surface.get()); + manager->error(HYPRLAND_SURFACE_MANAGER_V1_ERROR_ALREADY_CONSTRUCTED, "HyprlandSurface already present"); + return; + } else { + iter->second->setResource(makeShared(manager->client(), manager->version(), id)); + hyprlandSurface = iter->second.get(); + } + } else { + hyprlandSurface = m_mSurfaces.emplace(surface, std::make_unique(makeShared(manager->client(), manager->version(), id), surface)) + .first->second.get(); + } + + if (!hyprlandSurface->good()) { + manager->noMemory(); + m_mSurfaces.erase(surface); + } +} diff --git a/src/protocols/HyprlandSurface.hpp b/src/protocols/HyprlandSurface.hpp new file mode 100644 index 00000000..f67de115 --- /dev/null +++ b/src/protocols/HyprlandSurface.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "hyprland-surface-v1.hpp" +#include "../helpers/signal/Signal.hpp" + +class CWLSurfaceResource; +class CHyprlandSurfaceProtocol; + +class CHyprlandSurface { + public: + CHyprlandSurface(SP resource, SP surface); + + bool good() const; + void setResource(SP resource); + + private: + SP m_pResource; + WP m_pSurface; + float m_fOpacity = 1.0; + + void destroy(); + + struct { + CHyprSignalListener surfaceCommitted; + CHyprSignalListener surfaceDestroyed; + } listeners; + + friend class CHyprlandSurfaceProtocol; +}; + +class CHyprlandSurfaceProtocol : public IWaylandProtocol { + public: + CHyprlandSurfaceProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + private: + void destroyManager(CHyprlandSurfaceManagerV1* res); + void destroySurface(CHyprlandSurface* surface); + void getSurface(CHyprlandSurfaceManagerV1* manager, uint32_t id, SP surface); + + std::vector> m_vManagers; + std::unordered_map, UP> m_mSurfaces; + + friend class CHyprlandSurface; +}; + +namespace PROTO { + inline UP hyprlandSurface; +} diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index d9f19fea..93bd129a 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2045,7 +2045,8 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWin return false; } -void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float a, SP pSurface, int round, bool blockBlurOptimization, float blurA) { +void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float a, SP pSurface, int round, bool blockBlurOptimization, float blurA, + float overallA) { RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); static auto PNOBLUROVERSIZED = CConfigValue("decoration:no_blur_on_oversized"); @@ -2126,7 +2127,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float setMonitorTransformEnabled(true); if (!USENEWOPTIMIZE) setRenderModifEnabled(false); - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, texDamage, 0, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, 0, false, false, false); if (!USENEWOPTIMIZE) setRenderModifEnabled(true); setMonitorTransformEnabled(false); @@ -2137,7 +2138,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float // draw window glDisable(GL_STENCIL_TEST); - renderTextureInternalWithDamage(tex, pBox, a, texDamage, round, false, false, true, true); + renderTextureInternalWithDamage(tex, pBox, a * overallA, texDamage, round, false, false, true, true); glStencilMask(0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 4fceabc5..95ac41be 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -176,7 +176,8 @@ class CHyprOpenGLImpl { void renderTexture(SP, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false, SP waitTimeline = nullptr, uint64_t waitPoint = 0); - void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f); + void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f, + float overallA = 1.f); void renderRoundedShadow(CBox*, int round, int range, const CHyprColor& color, float a = 1.0); void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); void renderBorder(CBox*, const CGradientValueData&, const CGradientValueData&, float lerp, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index 38de5210..89d4301c 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -58,8 +58,9 @@ void CSurfacePassElement::draw(const CRegion& damage) { auto PSURFACE = CWLSurface::fromResource(data.surface); - const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); - const bool BLUR = data.blur && (!TEXTURE->m_bOpaque || ALPHA < 1.F); + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const float OVERALL_ALPHA = PSURFACE ? PSURFACE->m_fOverallOpacity : 1.F; + const bool BLUR = data.blur && (!TEXTURE->m_bOpaque || ALPHA < 1.F || OVERALL_ALPHA < 1.F); auto windowBox = getTexBox(); @@ -107,14 +108,14 @@ void CSurfacePassElement::draw(const CRegion& damage) { // to what we do for misaligned surfaces (blur the entire thing and then render shit without blur) if (data.surfaceCounter == 0 && !data.popup) { if (BLUR) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, data.blockBlurOptimization, data.fadeAlpha); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, data.blockBlurOptimization, data.fadeAlpha, OVERALL_ALPHA); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA, rounding, false, true); + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, false, true); } else { if (BLUR && data.popup) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, true, data.fadeAlpha); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, true, data.fadeAlpha, OVERALL_ALPHA); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA, rounding, false, true); + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, false, true); } if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index c7c3f4cd..271df559 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit c7c3f4cd0faed21fc90ba6bd06fe4f3e0e057ea8 +Subproject commit 271df559dd30e4bc5ec6af02d017ac0aaabd63a7 From cbd2451570d5c4d8b40035c3fcbabfb298385458 Mon Sep 17 00:00:00 2001 From: Raymond Bian Date: Thu, 2 Jan 2025 06:51:59 -0500 Subject: [PATCH 0059/1444] renderer: fix CRendererHintsPassElement reset duplication issue (#8928) --- src/render/Renderer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 9aa794b4..35150ce2 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -807,13 +807,16 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA if (scale != 1.f) RENDERMODIFDATA.modifs.emplace_back(std::make_pair<>(SRenderModifData::eRenderModifType::RMOD_TYPE_SCALE, scale)); - CScopeGuard x([] {}); - if (!RENDERMODIFDATA.modifs.empty()) { g_pHyprRenderer->m_sRenderPass.add(makeShared(CRendererHintsPassElement::SData{RENDERMODIFDATA})); - x = CScopeGuard([] { g_pHyprRenderer->m_sRenderPass.add(makeShared(CRendererHintsPassElement::SData{SRenderModifData{}})); }); } + CScopeGuard x([&RENDERMODIFDATA] { + if (!RENDERMODIFDATA.modifs.empty()) { + g_pHyprRenderer->m_sRenderPass.add(makeShared(CRendererHintsPassElement::SData{SRenderModifData{}})); + } + }); + if (!pWorkspace) { // allow rendering without a workspace. In this case, just render layers. From 42fd366046d67c52449001b6a6e9b64427aee712 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 2 Jan 2025 03:53:57 -0800 Subject: [PATCH 0060/1444] protocols: fix alpha-modifier noncompliance (#8929) Also fixes small issues with hyprland-surface opacity < 1.0 while surface alpha = 1.0. --- src/desktop/WLSurface.hpp | 2 +- src/protocols/AlphaModifier.cpp | 134 +++++++++++++------------ src/protocols/AlphaModifier.hpp | 27 ++--- src/render/pass/SurfacePassElement.cpp | 10 +- 4 files changed, 90 insertions(+), 83 deletions(-) diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 346fc935..07af13df 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -84,7 +84,7 @@ class CWLSurface { static SP fromResource(SP pSurface); // used by the alpha-modifier protocol - float m_pAlphaModifier = 1.F; + float m_fAlphaModifier = 1.F; // used by the hyprland-surface protocol float m_fOverallOpacity = 1.F; diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp index 13597fa9..d695b58f 100644 --- a/src/protocols/AlphaModifier.cpp +++ b/src/protocols/AlphaModifier.cpp @@ -1,66 +1,62 @@ #include "AlphaModifier.hpp" -#include #include "../desktop/WLSurface.hpp" #include "../render/Renderer.hpp" +#include "alpha-modifier-v1.hpp" #include "core/Compositor.hpp" -CAlphaModifier::CAlphaModifier(SP resource_, SP surface_) : resource(resource_), pSurface(surface_) { - if (!resource->resource()) - return; - - resource->setDestroy([this](CWpAlphaModifierSurfaceV1* pMgr) { - PROTO::alphaModifier->destroyModifier(this); - setSurfaceAlpha(1.F); - }); - resource->setOnDestroy([this](CWpAlphaModifierSurfaceV1* pMgr) { - PROTO::alphaModifier->destroyModifier(this); - setSurfaceAlpha(1.F); - }); - - listeners.destroySurface = pSurface->events.destroy.registerListener([this](std::any d) { onSurfaceDestroy(); }); - - resource->setSetMultiplier([this](CWpAlphaModifierSurfaceV1* mod, uint32_t alpha) { - if (!pSurface) { - LOGM(ERR, "Resource {:x} tried to setMultiplier but surface is gone", (uintptr_t)mod->resource()); - mod->error(WP_ALPHA_MODIFIER_SURFACE_V1_ERROR_NO_SURFACE, "Surface is gone"); - return; - } - - float a = alpha / (float)UINT32_MAX; - - setSurfaceAlpha(a); - }); -} - -CAlphaModifier::~CAlphaModifier() { - ; +CAlphaModifier::CAlphaModifier(SP resource, SP surface) : m_pSurface(surface) { + setResource(std::move(resource)); } bool CAlphaModifier::good() { - return resource->resource(); + return m_pResource->resource(); } -SP CAlphaModifier::getSurface() { - return pSurface.lock(); -} +void CAlphaModifier::setResource(SP resource) { + m_pResource = std::move(resource); -void CAlphaModifier::setSurfaceAlpha(float a) { - auto surf = CWLSurface::fromResource(pSurface.lock()); - - if (!surf) { - LOGM(ERR, "CAlphaModifier::setSurfaceAlpha: No CWLSurface for given surface??"); + if (!m_pResource->resource()) return; - } - surf->m_pAlphaModifier = a; + m_pResource->setDestroy([this](CWpAlphaModifierSurfaceV1* resource) { destroy(); }); + m_pResource->setOnDestroy([this](CWpAlphaModifierSurfaceV1* resource) { destroy(); }); - auto SURFBOX = surf->getSurfaceBoxGlobal(); - if (SURFBOX.has_value()) - g_pHyprRenderer->damageBox(&*SURFBOX); + m_pResource->setSetMultiplier([this](CWpAlphaModifierSurfaceV1* resource, uint32_t alpha) { + if (!m_pSurface) { + m_pResource->error(WP_ALPHA_MODIFIER_SURFACE_V1_ERROR_NO_SURFACE, "set_multiplier called for destroyed wl_surface"); + return; + } + + m_fAlpha = alpha / (float)UINT32_MAX; + }); + + listeners.surfaceCommitted = m_pSurface->events.commit.registerListener([this](std::any data) { + auto surface = CWLSurface::fromResource(m_pSurface.lock()); + + if (surface && surface->m_fAlphaModifier != m_fAlpha) { + surface->m_fAlphaModifier = m_fAlpha; + auto box = surface->getSurfaceBoxGlobal(); + + if (box.has_value()) + g_pHyprRenderer->damageBox(&*box); + + if (!m_pResource) + PROTO::alphaModifier->destroyAlphaModifier(this); + } + }); + + listeners.surfaceDestroyed = m_pSurface->events.destroy.registerListener([this](std::any data) { + if (!m_pResource) + PROTO::alphaModifier->destroyAlphaModifier(this); + }); } -void CAlphaModifier::onSurfaceDestroy() { - pSurface.reset(); +void CAlphaModifier::destroy() { + m_pResource.reset(); + m_fAlpha = 1.F; + + if (!m_pSurface) + PROTO::alphaModifier->destroyAlphaModifier(this); } CAlphaModifierProtocol::CAlphaModifierProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { @@ -69,33 +65,41 @@ CAlphaModifierProtocol::CAlphaModifierProtocol(const wl_interface* iface, const void CAlphaModifierProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); - RESOURCE->setOnDestroy([this](CWpAlphaModifierV1* p) { this->onManagerResourceDestroy(p->resource()); }); + RESOURCE->setOnDestroy([this](CWpAlphaModifierV1* manager) { destroyManager(manager); }); - RESOURCE->setDestroy([this](CWpAlphaModifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); - RESOURCE->setGetSurface([this](CWpAlphaModifierV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetSurface(pMgr, id, CWLSurfaceResource::fromResource(surface)); }); + RESOURCE->setDestroy([this](CWpAlphaModifierV1* manager) { destroyManager(manager); }); + RESOURCE->setGetSurface([this](CWpAlphaModifierV1* manager, uint32_t id, wl_resource* surface) { getSurface(manager, id, CWLSurfaceResource::fromResource(surface)); }); } -void CAlphaModifierProtocol::onManagerResourceDestroy(wl_resource* res) { - std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; }); +void CAlphaModifierProtocol::destroyManager(CWpAlphaModifierV1* manager) { + std::erase_if(m_vManagers, [&](const auto& p) { return p.get() == manager; }); } -void CAlphaModifierProtocol::destroyModifier(CAlphaModifier* modifier) { - std::erase_if(m_mAlphaModifiers, [](const auto& e) { return e.first.expired(); }); +void CAlphaModifierProtocol::destroyAlphaModifier(CAlphaModifier* modifier) { + std::erase_if(m_mAlphaModifiers, [&](const auto& entry) { return entry.second.get() == modifier; }); } -void CAlphaModifierProtocol::onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, SP surface) { - if (std::find_if(m_mAlphaModifiers.begin(), m_mAlphaModifiers.end(), [surface](const auto& e) { return e.first == surface; }) != m_mAlphaModifiers.end()) { - LOGM(ERR, "AlphaModifier already present for surface {:x}", (uintptr_t)surface.get()); - pMgr->error(WP_ALPHA_MODIFIER_V1_ERROR_ALREADY_CONSTRUCTED, "AlphaModifier already present"); - return; +void CAlphaModifierProtocol::getSurface(CWpAlphaModifierV1* manager, uint32_t id, SP surface) { + CAlphaModifier* alphaModifier = nullptr; + auto iter = std::find_if(m_mAlphaModifiers.begin(), m_mAlphaModifiers.end(), [&](const auto& entry) { return entry.second->m_pSurface == surface; }); + + if (iter != m_mAlphaModifiers.end()) { + if (iter->second->m_pResource) { + LOGM(ERR, "AlphaModifier already present for surface {:x}", (uintptr_t)surface.get()); + manager->error(WP_ALPHA_MODIFIER_V1_ERROR_ALREADY_CONSTRUCTED, "AlphaModifier already present"); + return; + } else { + iter->second->setResource(makeShared(manager->client(), manager->version(), id)); + alphaModifier = iter->second.get(); + } + } else { + alphaModifier = + m_mAlphaModifiers.emplace(surface, std::make_unique(makeShared(manager->client(), manager->version(), id), surface)) + .first->second.get(); } - const auto RESOURCE = m_mAlphaModifiers.emplace(surface, std::make_unique(makeShared(pMgr->client(), pMgr->version(), id), surface)) - .first->second.get(); - - if (!RESOURCE->good()) { - pMgr->noMemory(); + if (!alphaModifier->good()) { + manager->noMemory(); m_mAlphaModifiers.erase(surface); - return; } } diff --git a/src/protocols/AlphaModifier.hpp b/src/protocols/AlphaModifier.hpp index 1bb9cf23..43f78bef 100644 --- a/src/protocols/AlphaModifier.hpp +++ b/src/protocols/AlphaModifier.hpp @@ -8,25 +8,28 @@ #include "../helpers/signal/Signal.hpp" class CWLSurfaceResource; +class CAlphaModifierProtocol; class CAlphaModifier { public: CAlphaModifier(SP resource_, SP surface); - ~CAlphaModifier(); - bool good(); - SP getSurface(); - void onSurfaceDestroy(); + bool good(); + void setResource(SP resource); private: - SP resource; - WP pSurface; + SP m_pResource; + WP m_pSurface; + float m_fAlpha = 1.0; - void setSurfaceAlpha(float a); + void destroy(); struct { - CHyprSignalListener destroySurface; + CHyprSignalListener surfaceCommitted; + CHyprSignalListener surfaceDestroyed; } listeners; + + friend class CAlphaModifierProtocol; }; class CAlphaModifierProtocol : public IWaylandProtocol { @@ -36,13 +39,13 @@ class CAlphaModifierProtocol : public IWaylandProtocol { virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); private: - void onManagerResourceDestroy(wl_resource* res); - void destroyModifier(CAlphaModifier* decoration); - void onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, SP surface); + void destroyManager(CWpAlphaModifierV1* res); + void destroyAlphaModifier(CAlphaModifier* surface); + void getSurface(CWpAlphaModifierV1* manager, uint32_t id, SP surface); // std::vector> m_vManagers; - std::unordered_map, UP> m_mAlphaModifiers; // xdg_toplevel -> deco + std::unordered_map, UP> m_mAlphaModifiers; friend class CAlphaModifier; }; diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index 89d4301c..bdb21338 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -58,7 +58,7 @@ void CSurfacePassElement::draw(const CRegion& damage) { auto PSURFACE = CWLSurface::fromResource(data.surface); - const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_fAlphaModifier : 1.F); const float OVERALL_ALPHA = PSURFACE ? PSURFACE->m_fOverallOpacity : 1.F; const bool BLUR = data.blur && (!TEXTURE->m_bOpaque || ALPHA < 1.F || OVERALL_ALPHA < 1.F); @@ -96,7 +96,7 @@ void CSurfacePassElement::draw(const CRegion& damage) { rounding = 0; const bool WINDOWOPAQUE = data.pWindow && data.pWindow->m_pWLSurface->resource() == data.surface ? data.pWindow->opaque() : false; - const bool CANDISABLEBLEND = ALPHA >= 1.f && rounding == 0 && WINDOWOPAQUE; + const bool CANDISABLEBLEND = ALPHA >= 1.f && OVERALL_ALPHA >= 1.f && rounding == 0 && WINDOWOPAQUE; if (CANDISABLEBLEND) g_pHyprOpenGL->blend(false); @@ -176,7 +176,7 @@ CBox CSurfacePassElement::getTexBox() { bool CSurfacePassElement::needsLiveBlur() { auto PSURFACE = CWLSurface::fromResource(data.surface); - const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_fAlphaModifier * PSURFACE->m_fOverallOpacity : 1.F); const bool BLUR = data.blur && (!data.texture || !data.texture->m_bOpaque || ALPHA < 1.F); if (!data.pLS && !data.pWindow) @@ -190,7 +190,7 @@ bool CSurfacePassElement::needsLiveBlur() { bool CSurfacePassElement::needsPrecomputeBlur() { auto PSURFACE = CWLSurface::fromResource(data.surface); - const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_fAlphaModifier * PSURFACE->m_fOverallOpacity : 1.F); const bool BLUR = data.blur && (!data.texture || !data.texture->m_bOpaque || ALPHA < 1.F); if (!data.pLS && !data.pWindow) @@ -208,7 +208,7 @@ std::optional CSurfacePassElement::boundingBox() { CRegion CSurfacePassElement::opaqueRegion() { auto PSURFACE = CWLSurface::fromResource(data.surface); - const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_pAlphaModifier : 1.F); + const float ALPHA = data.alpha * data.fadeAlpha * (PSURFACE ? PSURFACE->m_fAlphaModifier * PSURFACE->m_fOverallOpacity : 1.F); if (ALPHA < 1.F) return {}; From 94381e59991824ab9a5a9cb5fe701181fbcbc81d Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 2 Jan 2025 15:58:28 +0100 Subject: [PATCH 0061/1444] dnd/seat: avoid sending button events during a dnd op fixes #8781 --- src/managers/SeatManager.cpp | 2 +- src/protocols/core/DataDevice.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp index b169faeb..3b9a4925 100644 --- a/src/managers/SeatManager.cpp +++ b/src/managers/SeatManager.cpp @@ -281,7 +281,7 @@ void CSeatManager::sendPointerMotion(uint32_t timeMs, const Vector2D& local) { } void CSeatManager::sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state_) { - if (!state.pointerFocusResource) + if (!state.pointerFocusResource || PROTO::data->dndActive()) return; for (auto const& s : seatResources) { diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 9fc49a44..6ad17d7b 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -808,5 +808,5 @@ void CWLDataDeviceProtocol::renderDND(PHLMONITOR pMonitor, timespec* when) { } bool CWLDataDeviceProtocol::dndActive() { - return dnd.currentSource && dnd.mouseButton /* test a member of the state to ensure it's also present */; + return dnd.currentSource; } From 365caa49ff4e4f87da687adfa237b8f855aee42b Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 2 Jan 2025 17:36:02 +0100 Subject: [PATCH 0062/1444] keybinds: attempt to wrap around if fallback is allowed in movefocus fixes #8909 --- src/Compositor.cpp | 61 +++++++++++++++++---------------- src/Compositor.hpp | 1 + src/managers/KeybindManager.cpp | 41 +++++++++++++++++++--- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 4e22f398..c8ed22df 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1460,7 +1460,21 @@ void CCompositor::addToFadingOutSafe(PHLWINDOW pWindow) { } PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) { + if (!isDirection(dir)) + return nullptr; + const auto PMONITOR = pWindow->m_pMonitor.lock(); + + if (!PMONITOR) + return nullptr; // ?? + + const auto WINDOWIDEALBB = pWindow->isFullscreen() ? CBox{PMONITOR->vecPosition, PMONITOR->vecSize} : pWindow->getWindowIdealBoundingBoxIgnoreReserved(); + const auto PWORKSPACE = pWindow->m_pWorkspace; + + return getWindowInDirection(WINDOWIDEALBB, PWORKSPACE, dir, pWindow, pWindow->m_bIsFloating); +} + +PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow, bool useVectorAngles) { if (!isDirection(dir)) return nullptr; @@ -1468,34 +1482,24 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) { static auto PMETHOD = CConfigValue("binds:focus_preferred_method"); static auto PMONITORFALLBACK = CConfigValue("binds:window_direction_monitor_fallback"); - const auto PMONITOR = pWindow->m_pMonitor.lock(); + const auto POSA = box.pos(); + const auto SIZEA = box.size(); - if (!PMONITOR) - return nullptr; // ?? + auto leaderValue = -1; + PHLWINDOW leaderWindow = nullptr; - const auto WINDOWIDEALBB = pWindow->isFullscreen() ? CBox{PMONITOR->vecPosition, PMONITOR->vecSize} : pWindow->getWindowIdealBoundingBoxIgnoreReserved(); - - const auto POSA = Vector2D(WINDOWIDEALBB.x, WINDOWIDEALBB.y); - const auto SIZEA = Vector2D(WINDOWIDEALBB.width, WINDOWIDEALBB.height); - - const auto PWORKSPACE = pWindow->m_pWorkspace; - auto leaderValue = -1; - PHLWINDOW leaderWindow = nullptr; - - if (!pWindow->m_bIsFloating) { - - // for tiled windows, we calc edges + if (!useVectorAngles) { for (auto const& w : m_vWindows) { - if (w == pWindow || !w->m_pWorkspace || !w->m_bIsMapped || w->isHidden() || (!w->isFullscreen() && w->m_bIsFloating) || !w->m_pWorkspace->isVisible()) + if (w == ignoreWindow || !w->m_pWorkspace || !w->m_bIsMapped || w->isHidden() || (!w->isFullscreen() && w->m_bIsFloating) || !w->m_pWorkspace->isVisible()) continue; - if (pWindow->m_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace) + if (pWorkspace->m_pMonitor == w->m_pMonitor && pWorkspace != w->m_pWorkspace) continue; - if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen) + if (pWorkspace->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen) continue; - if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor) + if (!*PMONITORFALLBACK && pWorkspace->m_pMonitor != w->m_pMonitor) continue; const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved(); @@ -1557,9 +1561,6 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) { } } } else { - // for floating windows, we calculate best distance and angle. - // if there is a window with angle better than THRESHOLD, only distance counts - if (dir == 'u') dir = 't'; if (dir == 'd') @@ -1578,20 +1579,20 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) { constexpr float THRESHOLD = 0.3 * M_PI; for (auto const& w : m_vWindows) { - if (w == pWindow || !w->m_bIsMapped || !w->m_pWorkspace || w->isHidden() || (!w->isFullscreen() && !w->m_bIsFloating) || !w->m_pWorkspace->isVisible()) + if (w == ignoreWindow || !w->m_bIsMapped || !w->m_pWorkspace || w->isHidden() || (!w->isFullscreen() && !w->m_bIsFloating) || !w->m_pWorkspace->isVisible()) continue; - if (pWindow->m_pMonitor == w->m_pMonitor && pWindow->m_pWorkspace != w->m_pWorkspace) + if (pWorkspace->m_pMonitor == w->m_pMonitor && pWorkspace != w->m_pWorkspace) continue; - if (PWORKSPACE->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen) + if (pWorkspace->m_bHasFullscreenWindow && !w->isFullscreen() && !w->m_bCreatedOverFullscreen) continue; - if (!*PMONITORFALLBACK && pWindow->m_pMonitor != w->m_pMonitor) + if (!*PMONITORFALLBACK && pWorkspace->m_pMonitor != w->m_pMonitor) continue; - const auto DIST = w->middle().distance(pWindow->middle()); - const auto ANGLE = vectorAngles(Vector2D{w->middle() - pWindow->middle()}, VECTORS.at(dir)); + const auto DIST = w->middle().distance(box.middle()); + const auto ANGLE = vectorAngles(Vector2D{w->middle() - box.middle()}, VECTORS.at(dir)); if (ANGLE > M_PI_2) continue; // if the angle is over 90 degrees, ignore. Wrong direction entirely. @@ -1603,8 +1604,8 @@ PHLWINDOW CCompositor::getWindowInDirection(PHLWINDOW pWindow, char dir) { } } - if (!leaderWindow && PWORKSPACE->m_bHasFullscreenWindow) - leaderWindow = PWORKSPACE->getFullscreenWindow(); + if (!leaderWindow && pWorkspace->m_bHasFullscreenWindow) + leaderWindow = pWorkspace->getFullscreenWindow(); } if (leaderValue != -1) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index e1862829..4c428fca 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -123,6 +123,7 @@ class CCompositor { void changeWindowZOrder(PHLWINDOW, bool); void cleanupFadingOut(const MONITORID& monid); PHLWINDOW getWindowInDirection(PHLWINDOW, char); + PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false); PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); WORKSPACEID getNextAvailableNamedWorkspace(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 9e207fbe..d368d14c 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1423,11 +1423,44 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) { if (*PNOFALLBACK) return {.success = false, .error = std::format("Nothing to focus to in direction {}", arg)}; - Debug::log(LOG, "No monitor found in direction {}, falling back to next window on current workspace", arg); + Debug::log(LOG, "No monitor found in direction {}, getting the inverse edge", arg); - const auto PWINDOWNEXT = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true); - if (PWINDOWNEXT) - switchToWindow(PWINDOWNEXT); + const auto PMONITOR = PLASTWINDOW->m_pMonitor.lock(); + + if (!PMONITOR) + return {.success = false, .error = "last window has no monitor?"}; + + if (arg == 'l' || arg == 'r') { + if (STICKS(PLASTWINDOW->m_vPosition.x, PMONITOR->vecPosition.x) && STICKS(PLASTWINDOW->m_vSize.x, PMONITOR->vecSize.x)) + return {.success = false, .error = "move does not make sense, would return back"}; + } else if (STICKS(PLASTWINDOW->m_vPosition.y, PMONITOR->vecPosition.y) && STICKS(PLASTWINDOW->m_vSize.y, PMONITOR->vecSize.y)) + return {.success = false, .error = "move does not make sense, would return back"}; + + CBox box = PMONITOR->logicalBox(); + switch (arg) { + case 'l': + box.x += box.w; + box.w = 1; + break; + case 'r': + box.x -= 1; + box.w = 1; + break; + case 'u': + case 't': + box.y += box.h; + box.h = 1; + break; + case 'd': + case 'b': + box.y -= 1; + box.h = 1; + break; + } + + const auto PWINDOWCANDIDATE = g_pCompositor->getWindowInDirection(box, PMONITOR->activeWorkspace, arg, PLASTWINDOW, PLASTWINDOW->m_bIsFloating); + if (PWINDOWCANDIDATE) + switchToWindow(PWINDOWCANDIDATE); return {}; } From 81721b8aa87b1df3c3a9c9eadafcc271178c102a Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 2 Jan 2025 17:50:55 +0100 Subject: [PATCH 0063/1444] groupbar: unify title rendering moves the text renderer to the unified opengl impl --- src/render/OpenGL.cpp | 4 +- src/render/OpenGL.hpp | 2 +- .../decorations/CHyprGroupBarDecoration.cpp | 75 ++----------------- .../decorations/CHyprGroupBarDecoration.hpp | 3 +- 4 files changed, 11 insertions(+), 73 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 93bd129a..68baf48e 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2555,12 +2555,12 @@ SP CHyprOpenGLImpl::loadAsset(const std::string& filename) { return tex; } -SP CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col, int pt, bool italic) { +SP CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col, int pt, bool italic, const std::string& fontFamily) { SP tex = makeShared(); static auto FONT = CConfigValue("misc:font_family"); - const auto FONTFAMILY = *FONT; + const auto FONTFAMILY = fontFamily.empty() ? *FONT : fontFamily; const auto FONTSIZE = pt; const auto COLOR = col; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 95ac41be..281ee09a 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -218,7 +218,7 @@ class CHyprOpenGLImpl { void bindBackOnMain(); SP loadAsset(const std::string& file); - SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false); + SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = ""); void setDamage(const CRegion& damage, std::optional finalDamage = {}); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index f870e71b..53d35a64 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -179,10 +179,10 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2L * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale)) .get(); - rect.y += (rect.height - pTitleTex->textHeight) / 2.0; - rect.height = pTitleTex->textHeight; - rect.width = pTitleTex->textWidth; - rect.x += (m_fBarWidth * pMonitor->scale) / 2.0 - (pTitleTex->textWidth / 2.0); + rect.y += std::ceil((rect.height - pTitleTex->texSize.y) / 2.0); + rect.height = pTitleTex->texSize.y; + rect.width = pTitleTex->texSize.x; + rect.x += std::round((m_fBarWidth * pMonitor->scale) / 2.0 - (pTitleTex->texSize.x / 2.0)); rect.round(); CTexPassElement::SRenderData data; @@ -215,10 +215,6 @@ void CHyprGroupBarDecoration::invalidateTextures() { } CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float monitorScale) : szContent(pWindow->m_szTitle), pWindowOwner(pWindow) { - tex = makeShared(); - const auto LAYOUTSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); - const auto LAYOUTCAIRO = cairo_create(LAYOUTSURFACE); - static auto FALLBACKFONT = CConfigValue("misc:font_family"); static auto PTITLEFONTFAMILY = CConfigValue("group:groupbar:font_family"); static auto PTITLEFONTSIZE = CConfigValue("group:groupbar:font_size"); @@ -227,67 +223,10 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float const CHyprColor COLOR = CHyprColor(*PTEXTCOLOR); const auto FONTFAMILY = *PTITLEFONTFAMILY != STRVAL_EMPTY ? *PTITLEFONTFAMILY : *FALLBACKFONT; - cairo_surface_destroy(LAYOUTSURFACE); + tex = g_pHyprOpenGL->renderText(pWindow->m_szTitle, COLOR, *PTITLEFONTSIZE, false, FONTFAMILY); - // draw title using Pango - PangoLayout* layout = pango_cairo_create_layout(LAYOUTCAIRO); - pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); - pango_layout_set_text(layout, szContent.c_str(), -1); - - PangoFontDescription* fontDesc = pango_font_description_new(); - pango_font_description_set_family_static(fontDesc, FONTFAMILY.c_str()); - pango_font_description_set_size(fontDesc, *PTITLEFONTSIZE * PANGO_SCALE * monitorScale); - pango_layout_set_font_description(layout, fontDesc); - pango_font_description_free(fontDesc); - - const int maxWidth = bufferSize.x; - - pango_layout_set_width(layout, maxWidth * PANGO_SCALE); - pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); - - int layoutWidth, layoutHeight; - PangoRectangle inkRect; - PangoRectangle logicalRect; - pango_layout_get_pixel_extents(layout, &inkRect, &logicalRect); - layoutWidth = inkRect.width; - layoutHeight = inkRect.height; - - const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, layoutWidth, layoutHeight); - const auto CAIRO = cairo_create(CAIROSURFACE); - - // clear the pixmap - cairo_save(CAIRO); - cairo_set_operator(CAIRO, CAIRO_OPERATOR_CLEAR); - cairo_paint(CAIRO); - cairo_restore(CAIRO); - cairo_move_to(CAIRO, -inkRect.x, -inkRect.y); - cairo_set_source_rgba(CAIRO, COLOR.r, COLOR.g, COLOR.b, COLOR.a); - pango_cairo_show_layout(CAIRO, layout); - - g_object_unref(layout); - - cairo_surface_flush(CAIROSURFACE); - - // copy the data to an OpenGL texture we have - const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - tex->allocate(); - glBindTexture(GL_TEXTURE_2D, tex->m_iTexID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - -#ifndef GLES2 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); -#endif - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layoutWidth, layoutHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA); - - // delete cairo - textWidth = layoutWidth; - textHeight = layoutHeight; - cairo_destroy(LAYOUTCAIRO); - cairo_destroy(CAIRO); - cairo_surface_destroy(CAIROSURFACE); + if (tex) + texSize = tex->m_vSize; } CTitleTex::~CTitleTex() = default; diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index e813d140..653cd11c 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -14,8 +14,7 @@ class CTitleTex { SP tex; std::string szContent; - int textWidth; - int textHeight; + Vector2D texSize; PHLWINDOWREF pWindowOwner; }; From 1697171fc003d26dace4a7d70e2f8038df60a196 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 2 Jan 2025 18:14:45 +0100 Subject: [PATCH 0064/1444] pass: allow removing all pass elements of a given type --- src/render/pass/Pass.cpp | 4 ++++ src/render/pass/Pass.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 8fdc3049..3e1282f0 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -247,3 +247,7 @@ float CRenderPass::oneBlurRadius() { static auto PBLURPASSES = CConfigValue("decoration:blur:passes"); return *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES); // is this 2^pass? I don't know but it works... I think. } + +void CRenderPass::removeAllOfType(const std::string& type) { + std::erase_if(m_vPassElements, [&type](const auto& e) { return e->element->passName() == type; }); +} diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp index 5d7d3bb3..5fa25fc3 100644 --- a/src/render/pass/Pass.hpp +++ b/src/render/pass/Pass.hpp @@ -14,6 +14,7 @@ class CRenderPass { void add(SP elem); void clear(); + void removeAllOfType(const std::string& type); CRegion render(const CRegion& damage_); From 4971725b69768d156047289b7606e470c6963f59 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 2 Jan 2025 18:29:10 +0100 Subject: [PATCH 0065/1444] config: avoid querying the fs every tick --- src/config/ConfigManager.cpp | 28 ++++++++++++++++------------ src/config/ConfigManager.hpp | 20 ++++++++++---------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 67df5bf4..bdce573f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -716,20 +716,24 @@ std::optional CConfigManager::generateConfig(std::string configPath } std::string CConfigManager::getMainConfigPath() { - if (!g_pCompositor->explicitConfigPath.empty()) - return g_pCompositor->explicitConfigPath; + static std::string CONFIG_PATH = [this]() -> std::string { + if (!g_pCompositor->explicitConfigPath.empty()) + return g_pCompositor->explicitConfigPath; - if (const auto CFG_ENV = getenv("HYPRLAND_CONFIG"); CFG_ENV) - return CFG_ENV; + if (const auto CFG_ENV = getenv("HYPRLAND_CONFIG"); CFG_ENV) + return CFG_ENV; - const auto PATHS = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland"); - if (PATHS.first.has_value()) { - return PATHS.first.value(); - } else if (PATHS.second.has_value()) { - const auto CONFIGPATH = Hyprutils::Path::fullConfigPath(PATHS.second.value(), ISDEBUG ? "hyprlandd" : "hyprland"); - return generateConfig(CONFIGPATH).value(); - } else - throw std::runtime_error("Neither HOME nor XDG_CONFIG_HOME are set in the environment. Could not find config in XDG_CONFIG_DIRS or /etc/xdg."); + const auto PATHS = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland"); + if (PATHS.first.has_value()) { + return PATHS.first.value(); + } else if (PATHS.second.has_value()) { + const auto CONFIGPATH = Hyprutils::Path::fullConfigPath(PATHS.second.value(), ISDEBUG ? "hyprlandd" : "hyprland"); + return generateConfig(CONFIGPATH).value(); + } else + throw std::runtime_error("Neither HOME nor XDG_CONFIG_HOME are set in the environment. Could not find config in XDG_CONFIG_DIRS or /etc/xdg."); + }(); + + return CONFIG_PATH; } std::optional CConfigManager::verifyConfigExists() { diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index b1e7e7fd..0cd0a0a4 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -163,7 +163,7 @@ class CConfigManager { void* const* getConfigValuePtr(const std::string&); Hyprlang::CConfigValue* getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat = ""); - static std::string getMainConfigPath(); + std::string getMainConfigPath(); std::string getConfigString(); SMonitorRule getMonitorRuleFor(const PHLMONITOR); @@ -300,15 +300,15 @@ class CConfigManager { std::string m_szConfigErrors = ""; // internal methods - void setAnimForChildren(SAnimationPropertyConfig* const); - void updateBlurredLS(const std::string&, const bool); - void setDefaultAnimationVars(); - std::optional resetHLConfig(); - static std::optional generateConfig(std::string configPath); - static std::optional verifyConfigExists(); - void postConfigReload(const Hyprlang::CParseResult& result); - void reload(); - SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); + void setAnimForChildren(SAnimationPropertyConfig* const); + void updateBlurredLS(const std::string&, const bool); + void setDefaultAnimationVars(); + std::optional resetHLConfig(); + std::optional generateConfig(std::string configPath); + std::optional verifyConfigExists(); + void postConfigReload(const Hyprlang::CParseResult& result); + void reload(); + SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); }; inline std::unique_ptr g_pConfigManager; From f3c49c1295126c2154ee800ceedb48b79451840c Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 2 Jan 2025 21:58:23 +0100 Subject: [PATCH 0066/1444] pass: ignore empty rectangles queued ref #8935 --- src/render/pass/RectPassElement.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index 73727e58..25a550b3 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -6,6 +6,9 @@ CRectPassElement::CRectPassElement(const CRectPassElement::SRectData& data_) : d } void CRectPassElement::draw(const CRegion& damage) { + if (data.box.w <= 0 || data.box.h <= 0) + return; + if (data.color.a == 1.F || !data.blur) g_pHyprOpenGL->renderRectWithDamage(&data.box, data.color, damage, data.round); else From b0cd9972e8158bbda2ee3933668ce727e8a9ae5c Mon Sep 17 00:00:00 2001 From: rszyma Date: Fri, 3 Jan 2025 13:47:34 +0100 Subject: [PATCH 0067/1444] github: bug issue template improvements (#8894) --- .github/ISSUE_TEMPLATE/bug.yml | 76 ++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index ce6d9d3e..5a20b890 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -5,10 +5,10 @@ body: - type: checkboxes attributes: label: Already reported ? * - description: Before opening a new bug report, please take a moment to search through the current open and closed issues to check if it already exists. + description: Before opening a new bug report, please take a moment to search through the current open issues. If the same bug is already reported, don't open new issue - instead go upvote/comment on an existing one. options: - - label: I have searched the existing open and closed issues. - required: true + - label: I have searched the existing open and closed issues. + required: true - type: dropdown id: type @@ -19,27 +19,28 @@ body: **BEFORE CONTINUING**, please check if this bug is a regression or not, and if it is, we need you to bisect with the help of the wiki: https://wiki.hyprland.org/Crashes-and-Bugs/#bisecting-an-issue multiple: true options: - - "Yes" - - "No" + - "Definitely a regression - something broke after update (requires bisect)" + - "Probably not a regression / I don't remember it happening before" + - "Not a regression - it's bug regarding new feature" + - "Not a regression - it's an old bug" + - "I don't know, I started using Hyprland only recently" validations: required: true - type: textarea id: ver attributes: - label: System Info and Version + label: System Info and Hyprland Version description: | - Paste the output of `hyprctl systeminfo -c` here. If you can't + Paste the output of `hyprctl systeminfo` here. If you can't launch Hyprland, paste the output of `Hyprland --systeminfo`. - If `Hyprland --systeminfo` errors out (added in 0.44.0), find - and paste the Hyprland version manually. value: "
System/Version info - ```sh - - + ``` + + ``` @@ -61,15 +62,56 @@ body: attributes: label: How to reproduce description: "How can someone else reproduce the issue?" + placeholder: | + 1. ... + 2. ... + 3. ... + validations: required: true + - type: markdown + attributes: + value: | + ## Additional info section + + In the section below you will be asked to upload some files. + + When including text files (such as logs or config), please **always ATTACH** them, and not paste them directly. + + This is important to avoid clutter, spam, and make the issues more readable. + Thanks for your understanding. + + # The main reason to disallow pasting directly or in a dropdown, is to not clutter + # the issue with unnecessary keywords, making the github issue search useless. + - type: checkboxes + attributes: + label: Attach not paste + options: + - label: I understand that all text files must be *attached*, and not pasted directly. If not respected, this issue will likely get closed as spam + required: true + + - type: markdown + attributes: + value: >- + Please be sure to upload the following files below if they are relevant to the issue: + + - Logs can be found in $XDG_RUNTIME_DIR/hypr (sort by date to grab the latest) + - Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland + - Hyprland config files - `hyprctl systeminfo -c > /tmp/hyprland_config_dump.txt` use this command to dump full configuration to a single file. + + - type: checkboxes + attributes: + label: Checklist of files to include below + options: + - label: Hyprland config - `hyprctl systeminfo -c` (always include) + - label: Crash report (always include in case of crash) + - label: Video (always include in case of a visual bug) + - label: Logs (might contain useful info such as errors) + - type: textarea id: logs attributes: - label: Crash reports, logs, images, videos + label: Additional info & File uploads description: | - Anything that can help. Please always ATTACH and not paste them. - Logs can be found in $XDG_RUNTIME_DIR/hypr - Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland - + Tip: You can attach files by clicking this area to highlight it and then dragging files in. From f69e72eca1a31e4780d06018fc7e09767a50969d Mon Sep 17 00:00:00 2001 From: davc0n Date: Fri, 3 Jan 2025 23:43:48 +0100 Subject: [PATCH 0068/1444] socket2: add focusedmonv2 event (#8921) * socket2: add focusedmonv2 event * socket2: remove workspace name from focusedmonv2 --- src/Compositor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index c8ed22df..aa6faa16 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2588,7 +2588,12 @@ void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) { const auto PWORKSPACE = pMonitor->activeWorkspace; - g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + (PWORKSPACE ? PWORKSPACE->m_szName : "?")}); + const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_iID) : std::to_string(WORKSPACE_INVALID); + const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_szName : "?"; + + g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + WORKSPACE_NAME}); + g_pEventManager->postEvent(SHyprIPCEvent{"focusedmonv2", pMonitor->szName + "," + WORKSPACE_ID}); + EMIT_HOOK_EVENT("focusedMon", pMonitor); m_pLastMonitor = pMonitor->self; } From 2e6e0e9278614406979f63692cdb3a015e54c248 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sat, 4 Jan 2025 00:10:10 +0100 Subject: [PATCH 0069/1444] core: guard workspace and monitor in moveWorkspaceToMonitor ref #7822 --- src/Compositor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index aa6faa16..c80f05e6 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2076,7 +2076,8 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) { void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMonitor, bool noWarpCursor) { - // We trust the monitor to be correct. + if (!pWorkspace || !pMonitor) + return; if (pWorkspace->m_pMonitor == pMonitor) return; From 60f069d54015fec66e63f1ff7e6ff26ddb349976 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sat, 4 Jan 2025 00:25:01 +0100 Subject: [PATCH 0070/1444] groupbar: fix missing ellipsize for text fixes #8938 --- src/render/OpenGL.cpp | 8 +++- src/render/OpenGL.hpp | 38 +++++++++---------- .../decorations/CHyprGroupBarDecoration.cpp | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 68baf48e..1b51acbf 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2555,7 +2555,7 @@ SP CHyprOpenGLImpl::loadAsset(const std::string& filename) { return tex; } -SP CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col, int pt, bool italic, const std::string& fontFamily) { +SP CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col, int pt, bool italic, const std::string& fontFamily, int maxWidth) { SP tex = makeShared(); static auto FONT = CConfigValue("misc:font_family"); @@ -2580,6 +2580,12 @@ SP CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col int textW = 0, textH = 0; pango_layout_set_text(layoutText, text.c_str(), -1); + + if (maxWidth > 0) { + pango_layout_set_width(layoutText, maxWidth * PANGO_SCALE); + pango_layout_set_ellipsize(layoutText, PANGO_ELLIPSIZE_END); + } + pango_layout_get_size(layoutText, &textW, &textH); textW /= PANGO_SCALE; textH /= PANGO_SCALE; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 281ee09a..713816bc 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -217,32 +217,32 @@ class CHyprOpenGLImpl { void renderOffToMain(CFramebuffer* off); void bindBackOnMain(); - SP loadAsset(const std::string& file); - SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = ""); + SP loadAsset(const std::string& file); + SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0); - void setDamage(const CRegion& damage, std::optional finalDamage = {}); + void setDamage(const CRegion& damage, std::optional finalDamage = {}); - uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); - std::vector getDRMFormats(); - EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); - SP createEGLSync(int fenceFD); - bool waitForTimelinePoint(SP timeline, uint64_t point); + uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); + std::vector getDRMFormats(); + EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); + SP createEGLSync(int fenceFD); + bool waitForTimelinePoint(SP timeline, uint64_t point); - SCurrentRenderData m_RenderData; + SCurrentRenderData m_RenderData; - GLint m_iCurrentOutputFb = 0; + GLint m_iCurrentOutputFb = 0; - int m_iGBMFD = -1; - gbm_device* m_pGbmDevice = nullptr; - EGLContext m_pEglContext = nullptr; - EGLDisplay m_pEglDisplay = nullptr; - EGLDeviceEXT m_pEglDevice = nullptr; - uint failedAssetsNo = 0; + int m_iGBMFD = -1; + gbm_device* m_pGbmDevice = nullptr; + EGLContext m_pEglContext = nullptr; + EGLDisplay m_pEglDisplay = nullptr; + EGLDeviceEXT m_pEglDevice = nullptr; + uint failedAssetsNo = 0; - bool m_bReloadScreenShader = true; // at launch it can be set + bool m_bReloadScreenShader = true; // at launch it can be set - std::map m_mWindowFramebuffers; - std::map m_mLayerFramebuffers; + std::map m_mWindowFramebuffers; + std::map m_mLayerFramebuffers; std::map m_mMonitorRenderResources; std::map m_mMonitorBGFBs; diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 53d35a64..c6dc5779 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -223,7 +223,7 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float const CHyprColor COLOR = CHyprColor(*PTEXTCOLOR); const auto FONTFAMILY = *PTITLEFONTFAMILY != STRVAL_EMPTY ? *PTITLEFONTFAMILY : *FALLBACKFONT; - tex = g_pHyprOpenGL->renderText(pWindow->m_szTitle, COLOR, *PTITLEFONTSIZE, false, FONTFAMILY); + tex = g_pHyprOpenGL->renderText(pWindow->m_szTitle, COLOR, *PTITLEFONTSIZE, false, FONTFAMILY, bufferSize.x - 2 /* some padding yk */); if (tex) texSize = tex->m_vSize; From a25d228840dfac88160b6f6c9513b5a587119f67 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sat, 4 Jan 2025 17:21:02 +0100 Subject: [PATCH 0071/1444] windows: minor initial workspace improvements ref #8942 --- src/events/Windows.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index c17c425b..a20cbcad 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -121,16 +121,6 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_bX11ShouldntFocus = PWINDOW->m_bX11ShouldntFocus || (PWINDOW->m_bIsX11 && PWINDOW->isX11OverrideRedirect() && !PWINDOW->m_pXWaylandSurface->wantsFocus()); - if (PWORKSPACE->m_bDefaultFloating) - PWINDOW->m_bIsFloating = true; - - if (PWORKSPACE->m_bDefaultPseudo) { - PWINDOW->m_bIsPseudotiled = true; - CBox desiredGeometry = {0}; - g_pXWaylandManager->getGeometryForWindow(PWINDOW, &desiredGeometry); - PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height); - } - // window rules PWINDOW->m_vMatchedRules = g_pConfigManager->getMatchingRules(PWINDOW, false); std::optional requestedInternalFSMode, requestedClientFSMode; @@ -171,6 +161,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PMONITOR = PMONITORFROMID; } PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace; + PWORKSPACE = PWINDOW->m_pWorkspace; Debug::log(LOG, "Rule monitor, applying to {:mw}", PWINDOW); } catch (std::exception& e) { Debug::log(ERR, "Rule monitor failed, rule: {} -> {} | err: {}", r->szRule, r->szValue, e.what()); } @@ -180,11 +171,10 @@ void Events::listener_mapWindow(void* owner, void* data) { // check if it isnt unset const auto WORKSPACERQ = r->szRule.substr(r->szRule.find_first_of(' ') + 1); - if (WORKSPACERQ == "unset") { + if (WORKSPACERQ == "unset") requestedWorkspace = ""; - } else { + else requestedWorkspace = WORKSPACERQ; - } const auto JUSTWORKSPACE = WORKSPACERQ.contains(' ') ? WORKSPACERQ.substr(0, WORKSPACERQ.find_first_of(' ')) : WORKSPACERQ; @@ -347,6 +337,16 @@ void Events::listener_mapWindow(void* owner, void* data) { workspaceSilent = false; } + if (PWORKSPACE->m_bDefaultFloating) + PWINDOW->m_bIsFloating = true; + + if (PWORKSPACE->m_bDefaultPseudo) { + PWINDOW->m_bIsPseudotiled = true; + CBox desiredGeometry = {0}; + g_pXWaylandManager->getGeometryForWindow(PWINDOW, &desiredGeometry); + PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height); + } + PWINDOW->updateWindowData(); // Verify window swallowing. Get the swallower before calling onWindowCreated(PWINDOW) because getSwallower() wouldn't get it after if PWINDOW gets auto grouped. From e8317ae34d635b6055c4ab3e42325a9e50b6f5a0 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sat, 4 Jan 2025 17:35:11 +0100 Subject: [PATCH 0072/1444] xwayland: don't define atoms on no_xwayland builds fixes #8661 --- src/xwayland/XWayland.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xwayland/XWayland.hpp b/src/xwayland/XWayland.hpp index 96253d19..113ca4d4 100644 --- a/src/xwayland/XWayland.hpp +++ b/src/xwayland/XWayland.hpp @@ -34,6 +34,7 @@ class CXWayland { inline std::unique_ptr g_pXWayland; inline std::unordered_map HYPRATOMS = { +#ifndef NO_XWAYLAND HYPRATOM("_NET_SUPPORTED"), HYPRATOM("_NET_SUPPORTING_WM_CHECK"), HYPRATOM("_NET_WM_NAME"), @@ -126,4 +127,5 @@ inline std::unordered_map HYPRATOMS = { HYPRATOM("DELETE"), HYPRATOM("TEXT"), HYPRATOM("INCR"), +#endif }; From b0bae15499ad57bbfeae8be958df8c022201e583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Migu=C3=A9ns?= Date: Sat, 4 Jan 2025 17:40:33 +0100 Subject: [PATCH 0073/1444] master: make loop around optional when cycling (#8926) --- src/layout/MasterLayout.cpp | 21 ++++++++++++++++----- src/layout/MasterLayout.hpp | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 05a2a707..fb7df84f 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -978,7 +978,7 @@ void CHyprMasterLayout::alterSplitRatio(PHLWINDOW pWindow, float ratio, bool exa recalculateMonitor(pWindow->monitorID()); } -PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next) { +PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next, bool loop) { if (!isWindowTiled(pWindow)) return nullptr; @@ -997,6 +997,13 @@ PHLWINDOW CHyprMasterLayout::getNextWindow(PHLWINDOW pWindow, bool next) { CANDIDATE = std::find_if(nodes.begin(), nodes.end(), [&](const auto& other) { return other != *PNODE && ISMASTER != other.isMaster && other.workspaceID == PNODE->workspaceID; }); + if (CANDIDATE != nodes.end() && !loop) { + if (CANDIDATE->isMaster && next) + return nullptr; + if (!CANDIDATE->isMaster && ISMASTER && !next) + return nullptr; + } + return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow.lock(); } @@ -1110,7 +1117,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; - const auto PNEXTWINDOW = getNextWindow(PWINDOW, true); + const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop"; + const auto PNEXTWINDOW = getNextWindow(PWINDOW, true, !NOLOOP); switchToWindow(PNEXTWINDOW); } else if (command == "cycleprev") { const auto PWINDOW = header.pWindow; @@ -1118,7 +1126,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; - const auto PPREVWINDOW = getNextWindow(PWINDOW, false); + const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop"; + const auto PPREVWINDOW = getNextWindow(PWINDOW, false, !NOLOOP); switchToWindow(PPREVWINDOW); } else if (command == "swapnext") { if (!validMapped(header.pWindow)) @@ -1129,7 +1138,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri return 0; } - const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true); + const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop"; + const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true, !NOLOOP); if (PWINDOWTOSWAPWITH) { g_pCompositor->setWindowFullscreenInternal(header.pWindow, FSMODE_NONE); @@ -1145,7 +1155,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri return 0; } - const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false); + const bool NOLOOP = vars.size() >= 2 && vars[1] == "noloop"; + const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false, !NOLOOP); if (PWINDOWTOSWAPWITH) { g_pCompositor->setWindowFullscreenClient(header.pWindow, FSMODE_NONE); diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 4841ef08..03ca3c3b 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -87,7 +87,7 @@ class CHyprMasterLayout : public IHyprLayout { SMasterNodeData* getMasterNodeOnWorkspace(const WORKSPACEID&); SMasterWorkspaceData* getMasterWorkspaceData(const WORKSPACEID&); void calculateWorkspace(PHLWORKSPACE); - PHLWINDOW getNextWindow(PHLWINDOW, bool); + PHLWINDOW getNextWindow(PHLWINDOW, bool, bool); int getMastersOnWorkspace(const WORKSPACEID&); friend struct SMasterNodeData; From a5c14370c11287cbf520c8f427179c665ac9c891 Mon Sep 17 00:00:00 2001 From: Pollux Date: Sun, 5 Jan 2025 12:38:49 -0600 Subject: [PATCH 0074/1444] renderer: Add supercircular window corners (#8943) renderer: Add supercircular shadows and borders config: Add rounding_power to default and example configs rule: add `roundingpower` window rule --- example/hyprland.conf | 1 + src/config/ConfigDescriptions.hpp | 6 + src/config/ConfigManager.cpp | 1 + src/config/ConfigManager.hpp | 1 + src/config/defaultConfig.hpp | 1 + src/desktop/Window.cpp | 23 ++-- src/desktop/Window.hpp | 2 + src/desktop/WindowRule.cpp | 6 +- src/render/OpenGL.cpp | 106 +++++++++------- src/render/OpenGL.hpp | 119 +++++++++--------- src/render/Renderer.cpp | 11 +- src/render/Shader.hpp | 1 + .../decorations/CHyprBorderDecoration.cpp | 16 +-- .../decorations/CHyprDropShadowDecoration.cpp | 14 ++- .../decorations/CHyprDropShadowDecoration.hpp | 2 +- src/render/pass/BorderPassElement.cpp | 6 +- src/render/pass/BorderPassElement.hpp | 1 + src/render/pass/RectPassElement.cpp | 4 +- src/render/pass/RectPassElement.hpp | 5 +- src/render/pass/SurfacePassElement.cpp | 17 +-- src/render/pass/SurfacePassElement.hpp | 5 +- src/render/pass/TexPassElement.cpp | 3 +- src/render/pass/TexPassElement.hpp | 7 +- src/render/shaders/Border.hpp | 7 +- src/render/shaders/Shadow.hpp | 13 +- src/render/shaders/Textures.hpp | 23 ++-- 26 files changed, 228 insertions(+), 173 deletions(-) diff --git a/example/hyprland.conf b/example/hyprland.conf index fe1a831a..c2b1a071 100644 --- a/example/hyprland.conf +++ b/example/hyprland.conf @@ -81,6 +81,7 @@ general { # https://wiki.hyprland.org/Configuring/Variables/#decoration decoration { rounding = 10 + rounding_power = 2 # Change transparency of focused and unfocused windows active_opacity = 1.0 diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 17657983..46f91a21 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -139,6 +139,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{0, 0, 20}, }, + SConfigOptionDescription{ + .value = "decoration:rounding_power", + .description = "rouding power of corners (2 is a circle)", + .type = CONFIG_OPTION_FLOAT, + .data = SConfigOptionDescription::SFloatData{2, 2, 10}, + }, SConfigOptionDescription{ .value = "decoration:active_opacity", .description = "opacity of active windows. [0.0 - 1.0]", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index bdce573f..732d12e5 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -427,6 +427,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("debug:colored_stdout_logs", Hyprlang::INT{1}); m_pConfig->addConfigValue("decoration:rounding", Hyprlang::INT{0}); + m_pConfig->addConfigValue("decoration:rounding_power", {2.F}); m_pConfig->addConfigValue("decoration:blur:enabled", Hyprlang::INT{1}); m_pConfig->addConfigValue("decoration:blur:size", Hyprlang::INT{8}); m_pConfig->addConfigValue("decoration:blur:passes", Hyprlang::INT{1}); diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 0cd0a0a4..436362ae 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -259,6 +259,7 @@ class CConfigManager { }; std::unordered_map*(PHLWINDOW)>> mfWindowProperties = { + {"roundingpower", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.roundingPower; }}, {"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }}, {"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}}; diff --git a/src/config/defaultConfig.hpp b/src/config/defaultConfig.hpp index c4eb3385..851e11f2 100644 --- a/src/config/defaultConfig.hpp +++ b/src/config/defaultConfig.hpp @@ -94,6 +94,7 @@ general { # https://wiki.hyprland.org/Configuring/Variables/#decoration decoration { rounding = 10 + rounding_power = 2 # Change transparency of focused and unfocused windows active_opacity = 1.0 diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 4104c737..60914198 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -824,7 +824,8 @@ void CWindow::updateDynamicRules() { // it is assumed that the point is within the real window box (m_vRealPosition, m_vRealSize) // otherwise behaviour is undefined bool CWindow::isInCurvedCorner(double x, double y) { - const int ROUNDING = rounding(); + const int ROUNDING = rounding(); + const int ROUNDINGPOWER = roundingPower(); if (getRealBorderSize() >= ROUNDING) return false; @@ -835,16 +836,16 @@ bool CWindow::isInCurvedCorner(double x, double y) { double y1 = m_vRealPosition.value().y + m_vRealSize.value().y - ROUNDING; if (x < x0 && y < y0) { - return Vector2D{x0, y0}.distance(Vector2D{x, y}) > (double)ROUNDING; + return std::pow(x0 - x, ROUNDINGPOWER) + std::pow(y0 - y, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER); } if (x > x1 && y < y0) { - return Vector2D{x1, y0}.distance(Vector2D{x, y}) > (double)ROUNDING; + return std::pow(x - x1, ROUNDINGPOWER) + std::pow(y0 - y, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER); } if (x < x0 && y > y1) { - return Vector2D{x0, y1}.distance(Vector2D{x, y}) > (double)ROUNDING; + return std::pow(x0 - x, ROUNDINGPOWER) + std::pow(y - y1, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER); } if (x > x1 && y > y1) { - return Vector2D{x1, y1}.distance(Vector2D{x, y}) > (double)ROUNDING; + return std::pow(x - x1, ROUNDINGPOWER) + std::pow(y - y1, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER); } return false; @@ -1164,13 +1165,21 @@ bool CWindow::opaque() { } float CWindow::rounding() { - static auto PROUNDING = CConfigValue("decoration:rounding"); + static auto PROUNDING = CConfigValue("decoration:rounding"); + static auto PROUNDINGPOWER = CConfigValue("decoration:rounding_power"); - float rounding = m_sWindowData.rounding.valueOr(*PROUNDING); + float roundingPower = m_sWindowData.roundingPower.valueOr(*PROUNDINGPOWER); + float rounding = m_sWindowData.rounding.valueOr(*PROUNDING) * (roundingPower / 2.0); /* Make perceived roundness consistent. */ return m_sWindowData.noRounding.valueOrDefault() ? 0 : rounding; } +float CWindow::roundingPower() { + static auto PROUNDINGPOWER = CConfigValue("decoration:rounding_power"); + + return m_sWindowData.roundingPower.valueOr(*PROUNDINGPOWER); +} + void CWindow::updateWindowData() { const auto PWORKSPACE = m_pWorkspace; const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{}; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 6ed9a525..3ceaf594 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -183,6 +183,7 @@ struct SWindowData { CWindowOverridableVar renderUnfocused = false; CWindowOverridableVar rounding; + CWindowOverridableVar roundingPower; CWindowOverridableVar borderSize; CWindowOverridableVar scrollMouse; @@ -414,6 +415,7 @@ class CWindow { Vector2D middle(); bool opaque(); float rounding(); + float roundingPower(); bool canBeTorn(); void setSuspended(bool suspend); bool visibleOnMonitor(PHLMONITOR pMonitor); diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp index 7db6c3db..306a25ce 100644 --- a/src/desktop/WindowRule.cpp +++ b/src/desktop/WindowRule.cpp @@ -8,8 +8,8 @@ static const auto RULES = std::unordered_set{ "float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", }; static const auto RULES_PREFIX = std::unordered_set{ - "animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor", "move", "opacity", - "plugin:", "prop", "pseudo", "rounding", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray", + "animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor", "move", "opacity", + "plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray", }; CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) { @@ -88,4 +88,4 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool ruleType = RULE_INVALID; } } -} \ No newline at end of file +} diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 1b51acbf..94b70acf 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -971,14 +971,15 @@ void CHyprOpenGLImpl::setDamage(const CRegion& damage_, std::optional f } void CHyprOpenGLImpl::initShaders() { - GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC); - m_RenderData.pCurrentMonData->m_shQUAD.program = prog; - m_RenderData.pCurrentMonData->m_shQUAD.proj = glGetUniformLocation(prog, "proj"); - m_RenderData.pCurrentMonData->m_shQUAD.color = glGetUniformLocation(prog, "color"); - m_RenderData.pCurrentMonData->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos"); - m_RenderData.pCurrentMonData->m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft"); - m_RenderData.pCurrentMonData->m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize"); - m_RenderData.pCurrentMonData->m_shQUAD.radius = glGetUniformLocation(prog, "radius"); + GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC); + m_RenderData.pCurrentMonData->m_shQUAD.program = prog; + m_RenderData.pCurrentMonData->m_shQUAD.proj = glGetUniformLocation(prog, "proj"); + m_RenderData.pCurrentMonData->m_shQUAD.color = glGetUniformLocation(prog, "color"); + m_RenderData.pCurrentMonData->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos"); + m_RenderData.pCurrentMonData->m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft"); + m_RenderData.pCurrentMonData->m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize"); + m_RenderData.pCurrentMonData->m_shQUAD.radius = glGetUniformLocation(prog, "radius"); + m_RenderData.pCurrentMonData->m_shQUAD.roundingPower = glGetUniformLocation(prog, "roundingPower"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBA); m_RenderData.pCurrentMonData->m_shRGBA.program = prog; @@ -995,6 +996,7 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius"); + m_RenderData.pCurrentMonData->m_shRGBA.roundingPower = glGetUniformLocation(prog, "roundingPower"); m_RenderData.pCurrentMonData->m_shRGBA.applyTint = glGetUniformLocation(prog, "applyTint"); m_RenderData.pCurrentMonData->m_shRGBA.tint = glGetUniformLocation(prog, "tint"); m_RenderData.pCurrentMonData->m_shRGBA.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte"); @@ -1037,6 +1039,7 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shRGBX.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius"); + m_RenderData.pCurrentMonData->m_shRGBX.roundingPower = glGetUniformLocation(prog, "roundingPower"); m_RenderData.pCurrentMonData->m_shRGBX.applyTint = glGetUniformLocation(prog, "applyTint"); m_RenderData.pCurrentMonData->m_shRGBX.tint = glGetUniformLocation(prog, "tint"); @@ -1053,6 +1056,7 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shEXT.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius"); + m_RenderData.pCurrentMonData->m_shEXT.roundingPower = glGetUniformLocation(prog, "roundingPower"); m_RenderData.pCurrentMonData->m_shEXT.applyTint = glGetUniformLocation(prog, "applyTint"); m_RenderData.pCurrentMonData->m_shEXT.tint = glGetUniformLocation(prog, "tint"); @@ -1097,18 +1101,19 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness"); m_RenderData.pCurrentMonData->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise"); - prog = createProgram(QUADVERTSRC, FRAGSHADOW); - m_RenderData.pCurrentMonData->m_shSHADOW.program = prog; - m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj"); - m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos"); - m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord"); - m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft"); - m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight"); - m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize"); - m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius"); - m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range"); - m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower"); - m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color"); + prog = createProgram(QUADVERTSRC, FRAGSHADOW); + m_RenderData.pCurrentMonData->m_shSHADOW.program = prog; + m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj"); + m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos"); + m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord"); + m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft"); + m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight"); + m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize"); + m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius"); + m_RenderData.pCurrentMonData->m_shSHADOW.roundingPower = glGetUniformLocation(prog, "roundingPower"); + m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range"); + m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower"); + m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color"); prog = createProgram(QUADVERTSRC, FRAGBORDER1); m_RenderData.pCurrentMonData->m_shBORDER1.program = prog; @@ -1122,6 +1127,7 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed = glGetUniformLocation(prog, "fullSizeUntransformed"); m_RenderData.pCurrentMonData->m_shBORDER1.radius = glGetUniformLocation(prog, "radius"); m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter = glGetUniformLocation(prog, "radiusOuter"); + m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower = glGetUniformLocation(prog, "roundingPower"); m_RenderData.pCurrentMonData->m_shBORDER1.gradient = glGetUniformLocation(prog, "gradient"); m_RenderData.pCurrentMonData->m_shBORDER1.gradient2 = glGetUniformLocation(prog, "gradient2"); m_RenderData.pCurrentMonData->m_shBORDER1.gradientLength = glGetUniformLocation(prog, "gradientLength"); @@ -1244,12 +1250,12 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h scissor(&box, transform); } -void CHyprOpenGLImpl::renderRect(CBox* box, const CHyprColor& col, int round) { +void CHyprOpenGLImpl::renderRect(CBox* box, const CHyprColor& col, int round, float roundingPower) { if (!m_RenderData.damage.empty()) - renderRectWithDamage(box, col, m_RenderData.damage, round); + renderRectWithDamage(box, col, m_RenderData.damage, round, roundingPower); } -void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int round, float blurA, bool xray) { +void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int round, float roundingPower, float blurA, bool xray) { if (m_RenderData.damage.empty()) return; @@ -1271,7 +1277,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - renderRect(box, CHyprColor(0, 0, 0, 0), round); + renderRect(box, CHyprColor(0, 0, 0, 0), round, roundingPower); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilFunc(GL_EQUAL, 1, 0xFF); @@ -1282,7 +1288,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r m_bEndFrame = true; // fix transformed const auto SAVEDRENDERMODIF = m_RenderData.renderModif; m_RenderData.renderModif = {}; // fix shit - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, blurA, damage, 0, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, blurA, damage, 0, 2.0f, false, false, false); m_bEndFrame = false; m_RenderData.renderModif = SAVEDRENDERMODIF; @@ -1293,10 +1299,10 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r glStencilFunc(GL_ALWAYS, 1, 0xFF); scissor((CBox*)nullptr); - renderRectWithDamage(box, col, m_RenderData.damage, round); + renderRectWithDamage(box, col, m_RenderData.damage, round, roundingPower); } -void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, const CRegion& damage, int round) { +void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, const CRegion& damage, int round, float roundingPower) { 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()!"); @@ -1334,6 +1340,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, con glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); glUniform1f(m_RenderData.pCurrentMonData->m_shQUAD.radius, round); + glUniform1f(m_RenderData.pCurrentMonData->m_shQUAD.roundingPower, roundingPower); glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); @@ -1361,25 +1368,25 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, con scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTexture(SP tex, CBox* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) { +void CHyprOpenGLImpl::renderTexture(SP tex, CBox* pBox, float alpha, int round, float roundingPower, bool discardActive, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.damage, round, discardActive, false, allowCustomUV, true); + renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.damage, round, roundingPower, discardActive, false, allowCustomUV, true); scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, CBox* pBox, const CRegion& damage, float alpha, int round, bool discardActive, bool allowCustomUV, - SP waitTimeline, uint64_t waitPoint) { +void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, CBox* pBox, const CRegion& damage, float alpha, int round, float roundingPower, bool discardActive, + bool allowCustomUV, SP waitTimeline, uint64_t waitPoint) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, damage, round, discardActive, false, allowCustomUV, true, waitTimeline, waitPoint); + renderTextureInternalWithDamage(tex, pBox, alpha, damage, round, roundingPower, discardActive, false, allowCustomUV, true, waitTimeline, waitPoint); scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pBox, float alpha, const CRegion& damage, int round, bool discardActive, bool noAA, - bool allowCustomUV, bool allowDim, SP waitTimeline, uint64_t waitPoint) { +void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pBox, float alpha, const CRegion& damage, int round, float roundingPower, bool discardActive, + bool noAA, bool allowCustomUV, bool allowDim, SP waitTimeline, uint64_t waitPoint) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex->m_iTexID > 0), "Attempted to draw nullptr texture!"); @@ -1506,6 +1513,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB glUniform2f(shader->topLeft, TOPLEFT.x, TOPLEFT.y); glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y); glUniform1f(shader->radius, round); + glUniform1f(shader->roundingPower, roundingPower); if (allowDim && m_RenderData.currentWindow) { glUniform1i(shader->applyTint, 1); @@ -1997,7 +2005,7 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() { clear(CHyprColor(0, 0, 0, 0)); m_bEndFrame = true; // fix transformed - renderTextureInternalWithDamage(POUTFB->getTexture(), &wholeMonitor, 1, fakeDamage, 0, false, true, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &wholeMonitor, 1, fakeDamage, 0, 2.0f, false, true, false); m_bEndFrame = false; m_RenderData.currentFB->bind(); @@ -2045,8 +2053,8 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWin return false; } -void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float a, SP pSurface, int round, bool blockBlurOptimization, float blurA, - float overallA) { +void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float a, SP pSurface, int round, float roundingPower, bool blockBlurOptimization, + float blurA, float overallA) { RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); static auto PNOBLUROVERSIZED = CConfigValue("decoration:no_blur_on_oversized"); @@ -2063,7 +2071,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float m_RenderData.renderModif.applyToRegion(texDamage); if (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) { - renderTexture(tex, pBox, a, round, false, true); + renderTexture(tex, pBox, a, round, roundingPower, false, true); return; } @@ -2076,7 +2084,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->current.size.x * pSurface->current.scale, pSurface->current.size.y * pSurface->current.scale); if (inverseOpaque.empty()) { - renderTexture(tex, pBox, a, round, false, true); + renderTexture(tex, pBox, a, round, roundingPower, false, true); return; } } else { @@ -2112,9 +2120,9 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); if (USENEWOPTIMIZE && !(m_RenderData.discardMode & DISCARD_ALPHA)) - renderRect(pBox, CHyprColor(0, 0, 0, 0), round); + renderRect(pBox, CHyprColor(0, 0, 0, 0), round, roundingPower); else - renderTexture(tex, pBox, a, round, true, true); // discard opaque + renderTexture(tex, pBox, a, round, roundingPower, true, true); // discard opaque glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilFunc(GL_EQUAL, 1, 0xFF); @@ -2127,7 +2135,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float setMonitorTransformEnabled(true); if (!USENEWOPTIMIZE) setRenderModifEnabled(false); - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, 0, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, 0, 2.0f, false, false, false); if (!USENEWOPTIMIZE) setRenderModifEnabled(true); setMonitorTransformEnabled(false); @@ -2138,14 +2146,14 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float // draw window glDisable(GL_STENCIL_TEST); - renderTextureInternalWithDamage(tex, pBox, a * overallA, texDamage, round, false, false, true, true); + renderTextureInternalWithDamage(tex, pBox, a * overallA, texDamage, round, roundingPower, false, false, true, true); glStencilMask(0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF); scissor((CBox*)nullptr); } -void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, int round, int borderSize, float a, int outerRound) { +void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, int round, float roundingPower, int borderSize, float a, int outerRound) { 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()!"); @@ -2207,6 +2215,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box->width, (float)box->height); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); + glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower, roundingPower); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, scaledBorderSize); glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); @@ -2238,7 +2247,8 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in blend(BLEND); } -void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, const CGradientValueData& grad2, float lerp, int round, int borderSize, float a, int outerRound) { +void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, const CGradientValueData& grad2, float lerp, int round, float roundingPower, int borderSize, float a, + int outerRound) { 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()!"); @@ -2304,6 +2314,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box->width, (float)box->height); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); + glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower, roundingPower); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, scaledBorderSize); glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); @@ -2335,7 +2346,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c blend(BLEND); } -void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const CHyprColor& color, float a) { +void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, float roundingPower, int range, const CHyprColor& color, float a) { RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!"); RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!"); RASSERT(m_RenderData.currentWindow, "Tried to render shadow without a window!"); @@ -2381,6 +2392,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y); glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.radius, range + round); + glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.roundingPower, roundingPower); glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.range, range); glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower, SHADOWPOWER); @@ -2421,7 +2433,7 @@ void CHyprOpenGLImpl::saveBufferForMirror(CBox* box) { blend(false); - renderTexture(m_RenderData.currentFB->getTexture(), box, 1.f, 0, false, false); + renderTexture(m_RenderData.currentFB->getTexture(), box, 1.f, 0, 2.0f, false, false); blend(true); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 713816bc..3f117a5a 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -166,83 +166,84 @@ class CHyprOpenGLImpl { CHyprOpenGLImpl(); ~CHyprOpenGLImpl(); - void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); - void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); - void end(); + void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); + void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); + void end(); - void renderRect(CBox*, const CHyprColor&, int round = 0); - void renderRectWithBlur(CBox*, const CHyprColor&, int round = 0, float blurA = 1.f, bool xray = false); - void renderRectWithDamage(CBox*, const CHyprColor&, const CRegion& damage, int round = 0); - void renderTexture(SP, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); - void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false, - SP waitTimeline = nullptr, uint64_t waitPoint = 0); - void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f, - float overallA = 1.f); - void renderRoundedShadow(CBox*, int round, int range, const CHyprColor& color, float a = 1.0); - void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); - void renderBorder(CBox*, const CGradientValueData&, const CGradientValueData&, float lerp, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); - void renderTextureMatte(SP tex, CBox* pBox, CFramebuffer& matte); + void renderRect(CBox*, const CHyprColor&, int round = 0, float roundingPower = 2.0f); + void renderRectWithBlur(CBox*, const CHyprColor&, int round = 0, float roundingPower = 2.0f, float blurA = 1.f, bool xray = false); + void renderRectWithDamage(CBox*, const CHyprColor&, const CRegion& damage, int round = 0, float roundingPower = 2.0f); + void renderTexture(SP, CBox*, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, bool allowCustomUV = false); + void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, + bool allowCustomUV = false, SP waitTimeline = nullptr, uint64_t waitPoint = 0); + void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, float roundingPower = 2.0f, bool blockBlurOptimization = false, + float blurA = 1.f, float overallA = 1.f); + void renderRoundedShadow(CBox*, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0); + void renderBorder(CBox*, const CGradientValueData&, int round, float roundingPower, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); + void renderBorder(CBox*, const CGradientValueData&, const CGradientValueData&, float lerp, int round, float roundingPower, int borderSize, float a = 1.0, + int outerRound = -1 /* use round */); + void renderTextureMatte(SP tex, CBox* pBox, CFramebuffer& matte); - void setMonitorTransformEnabled(bool enabled); - void setRenderModifEnabled(bool enabled); + void setMonitorTransformEnabled(bool enabled); + void setRenderModifEnabled(bool enabled); - void saveMatrix(); - void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); - void restoreMatrix(); + void saveMatrix(); + void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); + void restoreMatrix(); - void blend(bool enabled); + void blend(bool enabled); - bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); + bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); - void clear(const CHyprColor&); - void clearWithTex(); - void scissor(const CBox*, bool transform = true); - void scissor(const pixman_box32*, bool transform = true); - void scissor(const int x, const int y, const int w, const int h, bool transform = true); + void clear(const CHyprColor&); + void clearWithTex(); + void scissor(const CBox*, bool transform = true); + void scissor(const pixman_box32*, bool transform = true); + void scissor(const int x, const int y, const int w, const int h, bool transform = true); - void destroyMonitorResources(PHLMONITOR); + void destroyMonitorResources(PHLMONITOR); - void markBlurDirtyForMonitor(PHLMONITOR); + void markBlurDirtyForMonitor(PHLMONITOR); - void preWindowPass(); - bool preBlurQueued(); - void preRender(PHLMONITOR); + void preWindowPass(); + bool preBlurQueued(); + void preRender(PHLMONITOR); - void saveBufferForMirror(CBox*); - void renderMirrored(); + void saveBufferForMirror(CBox*); + void renderMirrored(); - void applyScreenShader(const std::string& path); + void applyScreenShader(const std::string& path); - void bindOffMain(); - void renderOffToMain(CFramebuffer* off); - void bindBackOnMain(); + void bindOffMain(); + void renderOffToMain(CFramebuffer* off); + void bindBackOnMain(); - SP loadAsset(const std::string& file); - SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0); + SP loadAsset(const std::string& file); + SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0); - void setDamage(const CRegion& damage, std::optional finalDamage = {}); + void setDamage(const CRegion& damage, std::optional finalDamage = {}); - uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); - std::vector getDRMFormats(); - EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); - SP createEGLSync(int fenceFD); - bool waitForTimelinePoint(SP timeline, uint64_t point); + uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); + std::vector getDRMFormats(); + EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); + SP createEGLSync(int fenceFD); + bool waitForTimelinePoint(SP timeline, uint64_t point); - SCurrentRenderData m_RenderData; + SCurrentRenderData m_RenderData; - GLint m_iCurrentOutputFb = 0; + GLint m_iCurrentOutputFb = 0; - int m_iGBMFD = -1; - gbm_device* m_pGbmDevice = nullptr; - EGLContext m_pEglContext = nullptr; - EGLDisplay m_pEglDisplay = nullptr; - EGLDeviceEXT m_pEglDevice = nullptr; - uint failedAssetsNo = 0; + int m_iGBMFD = -1; + gbm_device* m_pGbmDevice = nullptr; + EGLContext m_pEglContext = nullptr; + EGLDisplay m_pEglDisplay = nullptr; + EGLDeviceEXT m_pEglDevice = nullptr; + uint failedAssetsNo = 0; - bool m_bReloadScreenShader = true; // at launch it can be set + bool m_bReloadScreenShader = true; // at launch it can be set - std::map m_mWindowFramebuffers; - std::map m_mLayerFramebuffers; + std::map m_mWindowFramebuffers; + std::map m_mLayerFramebuffers; std::map m_mMonitorRenderResources; std::map m_mMonitorBGFBs; @@ -311,8 +312,8 @@ class CHyprOpenGLImpl { // returns the out FB, can be either Mirror or MirrorSwap CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage); - void renderTextureInternalWithDamage(SP, CBox* pBox, float a, const CRegion& damage, int round = 0, bool discardOpaque = false, bool noAA = false, - bool allowCustomUV = false, bool allowDim = false, SP = nullptr, uint64_t waitPoint = 0); + void renderTextureInternalWithDamage(SP, CBox* pBox, float a, const CRegion& damage, int round = 0, float roundingPower = 2.0f, bool discardOpaque = false, + bool noAA = false, bool allowCustomUV = false, bool allowDim = false, SP = nullptr, uint64_t waitPoint = 0); void renderTexturePrimitive(SP tex, CBox* pBox); void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 35150ce2..d154e64a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -460,11 +460,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.dontRound = pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN) || pWindow->m_sWindowData.noRounding.valueOrDefault(); renderdata.fadeAlpha = pWindow->m_fAlpha.value() * (pWindow->m_bPinned || USE_WORKSPACE_FADE_ALPHA ? 1.f : PWORKSPACE->m_fAlpha.value()) * (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha.value() : 1.F) * pWindow->m_fMovingFromWorkspaceAlpha.value(); - renderdata.alpha = pWindow->m_fActiveInactiveAlpha.value(); - renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); - renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; - renderdata.blur = !ignoreAllGeometry && *PBLUR && !DONT_BLUR; - renderdata.pWindow = pWindow; + renderdata.alpha = pWindow->m_fActiveInactiveAlpha.value(); + renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); + renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; + renderdata.roundingPower = ignoreAllGeometry || renderdata.dontRound ? 2.0f : pWindow->roundingPower(); + renderdata.blur = !ignoreAllGeometry && *PBLUR && !DONT_BLUR; + renderdata.pWindow = pWindow; if (ignoreAllGeometry) { renderdata.alpha = 1.f; diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index eaf9da96..666ee9d4 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -26,6 +26,7 @@ class CShader { GLint fullSizeUntransformed = -1; GLint radius = -1; GLint radiusOuter = -1; + GLfloat roundingPower = -1; GLint thick = -1; diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 4a793eab..2bc894ef 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -67,15 +67,17 @@ void CHyprBorderDecoration::draw(PHLMONITOR pMonitor, float const& a) { grad.m_fAngle = normalizeAngleRad(grad.m_fAngle); } - int borderSize = m_pWindow->getRealBorderSize(); - const auto ROUNDING = m_pWindow->rounding() * pMonitor->scale; + int borderSize = m_pWindow->getRealBorderSize(); + const auto ROUNDING = m_pWindow->rounding() * pMonitor->scale; + const auto ROUNDINGPOWER = m_pWindow->roundingPower(); CBorderPassElement::SBorderData data; - data.box = windowBox; - data.grad1 = grad; - data.round = ROUNDING; - data.a = a; - data.borderSize = borderSize; + data.box = windowBox; + data.grad1 = grad; + data.round = ROUNDING; + data.roundingPower = ROUNDINGPOWER; + data.a = a; + data.borderSize = borderSize; if (ANIMATED) { data.hasGrad2 = true; diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 21242b57..07dbb436 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -55,6 +55,7 @@ void CHyprDropShadowDecoration::damageEntire() { static auto PSHADOWIGNOREWINDOW = CConfigValue("decoration:shadow:ignore_window"); const auto ROUNDING = PWINDOW->rounding(); + const auto ROUNDINGPOWER = PWINDOW->roundingPower(); const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1; CRegion shadowRegion(shadowBox); @@ -119,6 +120,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { return; // disabled const auto ROUNDINGBASE = PWINDOW->rounding(); + const auto ROUNDINGPOWER = PWINDOW->roundingPower(); const auto ROUNDING = ROUNDINGBASE > 0 ? ROUNDINGBASE + PWINDOW->getRealBorderSize() : 0; const auto PWORKSPACE = PWINDOW->m_pWorkspace; const auto WORKSPACEOFFSET = PWORKSPACE && !PWINDOW->m_bPinned ? PWORKSPACE->m_vRenderOffset.value() : Vector2D(); @@ -192,10 +194,10 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { g_pHyprOpenGL->renderRect(&fullBox, CHyprColor(0, 0, 0, 1), 0); // render white shadow with the alpha of the shadow color (otherwise we clear with alpha later and shit it to 2 bit) - drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, CHyprColor(1, 1, 1, PWINDOW->m_cRealShadowColor.value().a), a); + drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, CHyprColor(1, 1, 1, PWINDOW->m_cRealShadowColor.value().a), a); // render black window box ("clip") - g_pHyprOpenGL->renderRect(&windowBox, CHyprColor(0, 0, 0, 1.0), (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->scale); + g_pHyprOpenGL->renderRect(&windowBox, CHyprColor(0, 0, 0, 1.0), (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->scale, ROUNDINGPOWER); alphaSwapFB.bind(); @@ -214,7 +216,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { g_pHyprOpenGL->m_RenderData.damage = saveDamage; } else - drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, PWINDOW->m_cRealShadowColor.value(), a); + drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, PWINDOW->m_cRealShadowColor.value(), a); if (m_seExtents != m_seReportedExtents) g_pDecorationPositioner->repositionDeco(this); @@ -226,7 +228,7 @@ eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() { return DECORATION_LAYER_BOTTOM; } -void CHyprDropShadowDecoration::drawShadowInternal(CBox* box, int round, int range, CHyprColor color, float a) { +void CHyprDropShadowDecoration::drawShadowInternal(CBox* box, int round, float roundingPower, int range, CHyprColor color, float a) { static auto PSHADOWSHARP = CConfigValue("decoration:shadow:sharp"); g_pHyprOpenGL->blend(true); @@ -234,7 +236,7 @@ void CHyprDropShadowDecoration::drawShadowInternal(CBox* box, int round, int ran color.a *= a; if (*PSHADOWSHARP) - g_pHyprOpenGL->renderRect(box, color, round); + g_pHyprOpenGL->renderRect(box, color, round, roundingPower); else - g_pHyprOpenGL->renderRoundedShadow(box, round, range, color, 1.F); + g_pHyprOpenGL->renderRoundedShadow(box, round, roundingPower, range, color, 1.F); } diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index fe0f8952..93fa3d1a 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -36,7 +36,7 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { Vector2D m_vLastWindowPos; Vector2D m_vLastWindowSize; - void drawShadowInternal(CBox* box, int round, int range, CHyprColor color, float a); + void drawShadowInternal(CBox* box, int round, float roundingPower, int range, CHyprColor color, float a); CBox m_bLastWindowBox = {0}; CBox m_bLastWindowBoxWithDecos = {0}; diff --git a/src/render/pass/BorderPassElement.cpp b/src/render/pass/BorderPassElement.cpp index 635533d0..ceeec6f3 100644 --- a/src/render/pass/BorderPassElement.cpp +++ b/src/render/pass/BorderPassElement.cpp @@ -7,9 +7,9 @@ CBorderPassElement::CBorderPassElement(const CBorderPassElement::SBorderData& da void CBorderPassElement::draw(const CRegion& damage) { if (data.hasGrad2) - g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.grad2, data.lerp, data.round, data.borderSize, data.a, data.outerRound); + g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.grad2, data.lerp, data.round, data.roundingPower, data.borderSize, data.a, data.outerRound); else - g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.round, data.borderSize, data.a, data.outerRound); + g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.round, data.roundingPower, data.borderSize, data.a, data.outerRound); } bool CBorderPassElement::needsLiveBlur() { @@ -18,4 +18,4 @@ bool CBorderPassElement::needsLiveBlur() { bool CBorderPassElement::needsPrecomputeBlur() { return false; -} \ No newline at end of file +} diff --git a/src/render/pass/BorderPassElement.hpp b/src/render/pass/BorderPassElement.hpp index 3a529640..785653ab 100644 --- a/src/render/pass/BorderPassElement.hpp +++ b/src/render/pass/BorderPassElement.hpp @@ -12,6 +12,7 @@ class CBorderPassElement : public IPassElement { bool hasGrad2 = false; float lerp = 0.F, a = 1.F; int round = 0, borderSize = 1, outerRound = -1; + float roundingPower = 2.F; }; CBorderPassElement(const SBorderData& data_); diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index 25a550b3..a57c959e 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -10,9 +10,9 @@ void CRectPassElement::draw(const CRegion& damage) { return; if (data.color.a == 1.F || !data.blur) - g_pHyprOpenGL->renderRectWithDamage(&data.box, data.color, damage, data.round); + g_pHyprOpenGL->renderRectWithDamage(&data.box, data.color, damage, data.round, data.roundingPower); else - g_pHyprOpenGL->renderRectWithBlur(&data.box, data.color, data.round, data.blurA, data.xray); + g_pHyprOpenGL->renderRectWithBlur(&data.box, data.color, data.round, data.roundingPower, data.blurA, data.xray); } bool CRectPassElement::needsLiveBlur() { diff --git a/src/render/pass/RectPassElement.hpp b/src/render/pass/RectPassElement.hpp index 32111a43..d27abdcc 100644 --- a/src/render/pass/RectPassElement.hpp +++ b/src/render/pass/RectPassElement.hpp @@ -6,7 +6,8 @@ class CRectPassElement : public IPassElement { struct SRectData { CBox box; CHyprColor color; - int round = 0; + int round = 0; + float roundingPower = 2.0f; bool blur = false, xray = false; float blurA = 1.F; }; @@ -26,4 +27,4 @@ class CRectPassElement : public IPassElement { private: SRectData data; -}; \ No newline at end of file +}; diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index bdb21338..13e9e741 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -88,12 +88,15 @@ void CSurfacePassElement::draw(const CRegion& damage) { if (MISALIGNEDFSV1) g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true; - float rounding = data.rounding; + float rounding = data.rounding; + float roundingPower = data.roundingPower; rounding -= 1; // to fix a border issue - if (data.dontRound) - rounding = 0; + if (data.dontRound) { + rounding = 0; + roundingPower = 2.0f; + } const bool WINDOWOPAQUE = data.pWindow && data.pWindow->m_pWLSurface->resource() == data.surface ? data.pWindow->opaque() : false; const bool CANDISABLEBLEND = ALPHA >= 1.f && OVERALL_ALPHA >= 1.f && rounding == 0 && WINDOWOPAQUE; @@ -108,14 +111,14 @@ void CSurfacePassElement::draw(const CRegion& damage) { // to what we do for misaligned surfaces (blur the entire thing and then render shit without blur) if (data.surfaceCounter == 0 && !data.popup) { if (BLUR) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, data.blockBlurOptimization, data.fadeAlpha, OVERALL_ALPHA); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, roundingPower, data.blockBlurOptimization, data.fadeAlpha, OVERALL_ALPHA); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, false, true); + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true); } else { if (BLUR && data.popup) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, true, data.fadeAlpha, OVERALL_ALPHA); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, roundingPower, true, data.fadeAlpha, OVERALL_ALPHA); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, false, true); + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true); } if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) diff --git a/src/render/pass/SurfacePassElement.hpp b/src/render/pass/SurfacePassElement.hpp index 746c5a64..14d8ef14 100644 --- a/src/render/pass/SurfacePassElement.hpp +++ b/src/render/pass/SurfacePassElement.hpp @@ -35,6 +35,9 @@ class CSurfacePassElement : public IPassElement { // for custom round values int rounding = -1; // -1 means not set + // for custom rounding powers + float roundingPower = 2.0f; + // for blurring bool blur = false; bool blockBlurOptimization = false; @@ -79,4 +82,4 @@ class CSurfacePassElement : public IPassElement { SRenderData data; CBox getTexBox(); -}; \ No newline at end of file +}; diff --git a/src/render/pass/TexPassElement.cpp b/src/render/pass/TexPassElement.cpp index 05f756dc..0624a786 100644 --- a/src/render/pass/TexPassElement.cpp +++ b/src/render/pass/TexPassElement.cpp @@ -18,7 +18,8 @@ void CTexPassElement::draw(const CRegion& damage) { if (data.replaceProjection) g_pHyprOpenGL->m_RenderData.monitorProjection = *data.replaceProjection; - g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, &data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.syncTimeline, data.syncPoint); + g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, &data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.roundingPower, data.syncTimeline, + data.syncPoint); if (data.replaceProjection) g_pHyprOpenGL->m_RenderData.monitorProjection = g_pHyprOpenGL->m_RenderData.pMonitor->projMatrix; } diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp index bf896951..036b89fe 100644 --- a/src/render/pass/TexPassElement.hpp +++ b/src/render/pass/TexPassElement.hpp @@ -13,8 +13,9 @@ class CTexPassElement : public IPassElement { CBox box; float a = 1.F; CRegion damage; - int round = 0; - bool flipEndFrame = false; + int round = 0; + float roundingPower = 2.0f; + bool flipEndFrame = false; SP syncTimeline; int64_t syncPoint = 0; std::optional replaceProjection; @@ -36,4 +37,4 @@ class CTexPassElement : public IPassElement { private: SRenderData data; -}; \ No newline at end of file +}; diff --git a/src/render/shaders/Border.hpp b/src/render/shaders/Border.hpp index acd3f3ff..3b9a91f0 100644 --- a/src/render/shaders/Border.hpp +++ b/src/render/shaders/Border.hpp @@ -15,6 +15,7 @@ uniform vec2 fullSize; uniform vec2 fullSizeUntransformed; uniform float radius; uniform float radiusOuter; +uniform float roundingPower; uniform float thick; // Gradients are in OkLabA!!!! {l, a, b, alpha} @@ -138,9 +139,9 @@ void main() { const float SMOOTHING_CONSTANT = )#" + std::format("{:.7f}", SHADER_ROUNDED_SMOOTHING_FACTOR) + R"#(; - float dist = length(pixCoord); - float distOuter = length(pixCoordOuter); - float h = (thick / 2.0); + float dist = pow(pow(pixCoord.x,roundingPower)+pow(pixCoord.y,roundingPower),1.0/roundingPower); + float distOuter = pow(pow(pixCoordOuter.x,roundingPower)+pow(pixCoordOuter.y,roundingPower),1.0/roundingPower); + float h = (thick / 2.0); if (dist < radius - h) { // lower diff --git a/src/render/shaders/Shadow.hpp b/src/render/shaders/Shadow.hpp index 0acab6b7..c04d4bf3 100644 --- a/src/render/shaders/Shadow.hpp +++ b/src/render/shaders/Shadow.hpp @@ -11,6 +11,7 @@ uniform vec2 topLeft; uniform vec2 bottomRight; uniform vec2 fullSize; uniform float radius; +uniform float roundingPower; uniform float range; uniform float shadowPower; @@ -26,6 +27,10 @@ float pixAlphaRoundedDistance(float distanceToCorner) { return 1.0; } +float modifiedLength(vec2 a) { + return pow(pow(abs(a.x),roundingPower)+pow(abs(a.y),roundingPower),1.0/roundingPower); +} + void main() { vec4 pixColor = v_color; @@ -40,21 +45,21 @@ void main() { if (pixCoord[0] < topLeft[0]) { if (pixCoord[1] < topLeft[1]) { // top left - pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, topLeft)); + pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - topLeft)); done = true; } else if (pixCoord[1] > bottomRight[1]) { // bottom left - pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, vec2(topLeft[0], bottomRight[1]))); + pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - vec2(topLeft[0], bottomRight[1]))); done = true; } } else if (pixCoord[0] > bottomRight[0]) { if (pixCoord[1] < topLeft[1]) { // top right - pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, vec2(bottomRight[0], topLeft[1]))); + pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - vec2(bottomRight[0], topLeft[1]))); done = true; } else if (pixCoord[1] > bottomRight[1]) { // bottom right - pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, bottomRight)); + pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(modifiedLength(pixCoord - bottomRight)); done = true; } } diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp index b203ad04..49d27b4c 100644 --- a/src/render/shaders/Textures.hpp +++ b/src/render/shaders/Textures.hpp @@ -19,23 +19,18 @@ inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVar const float SMOOTHING_CONSTANT = )#" + std::format("{:.7f}", SHADER_ROUNDED_SMOOTHING_FACTOR) + R"#(; - if (pixCoord.x + pixCoord.y > radius) { + //if (pixCoord.x + pixCoord.y > radius) { - float dist = length(pixCoord); + float dist = pow(pow(pixCoord.x, roundingPower) + pow(pixCoord.y, roundingPower), 1.0/roundingPower); - if (dist > radius + SMOOTHING_CONSTANT * 2.0) - discard; + if (dist > radius + SMOOTHING_CONSTANT) + discard; - if (dist > radius - SMOOTHING_CONSTANT * 2.0) { - float dist = length(pixCoord); + float normalized = 1.0 - smoothstep(0.0, 1.0, (dist - radius + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0)); - float normalized = 1.0 - smoothstep(0.0, 1.0, (dist - radius + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0)); - - )#" + + )#" + colorVarName + R"#( = )#" + colorVarName + R"#( * normalized; - } - - } + //} )#"; }; @@ -63,6 +58,7 @@ varying vec4 v_color; uniform vec2 topLeft; uniform vec2 fullSize; uniform float radius; +uniform float roundingPower; void main() { @@ -107,6 +103,7 @@ uniform float alpha; uniform vec2 topLeft; uniform vec2 fullSize; uniform float radius; +uniform float roundingPower; uniform int discardOpaque; uniform int discardAlpha; @@ -167,6 +164,7 @@ uniform float alpha; uniform vec2 topLeft; uniform vec2 fullSize; uniform float radius; +uniform float roundingPower; uniform int discardOpaque; uniform int discardAlpha; @@ -440,6 +438,7 @@ uniform float alpha; uniform vec2 topLeft; uniform vec2 fullSize; uniform float radius; +uniform float roundingPower; uniform int discardOpaque; uniform int discardAlpha; From 391ff29110e3fb9711b98e92cee44182dda2e2ba Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 5 Jan 2025 19:49:27 +0100 Subject: [PATCH 0075/1444] pass: improve pass debug mode --- src/render/pass/Pass.cpp | 42 +++++++++++++++++++++++++++++++++++----- src/render/pass/Pass.hpp | 6 +++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 3e1282f0..0489e985 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -88,7 +88,7 @@ void CRenderPass::simplify() { } newDamage.subtract(opaque); if (*PDEBUGPASS) - occludedRegion.add(opaque); + occludedRegions.emplace_back(opaque); } } @@ -114,9 +114,11 @@ CRegion CRenderPass::render(const CRegion& damage_) { const auto WILLBLUR = std::ranges::any_of(m_vPassElements, [](const auto& el) { return el->element->needsLiveBlur(); }); - damage = *PDEBUGPASS ? CRegion{CBox{{}, {INT32_MAX, INT32_MAX}}} : damage_.copy(); - occludedRegion = CRegion{}; - totalLiveBlurRegion = CRegion{}; + damage = *PDEBUGPASS ? CRegion{CBox{{}, {INT32_MAX, INT32_MAX}}} : damage_.copy(); + if (*PDEBUGPASS) { + occludedRegions.clear(); + totalLiveBlurRegion = CRegion{}; + } if (damage.empty()) { g_pHyprOpenGL->m_RenderData.damage = damage; @@ -198,7 +200,9 @@ CRegion CRenderPass::render(const CRegion& damage_) { void CRenderPass::renderDebugData() { CBox box = {{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}; - g_pHyprOpenGL->renderRectWithDamage(&box, Colors::RED.modifyA(0.1F), occludedRegion); + for (const auto& rg : occludedRegions) { + g_pHyprOpenGL->renderRectWithDamage(&box, Colors::RED.modifyA(0.1F), rg); + } g_pHyprOpenGL->renderRectWithDamage(&box, Colors::GREEN.modifyA(0.1F), totalLiveBlurRegion); std::unordered_map offsets; @@ -239,6 +243,34 @@ void CRenderPass::renderDebugData() { renderHLSurface(debugData.pointerFocusText, g_pSeatManager->state.pointerFocus.lock(), Colors::ORANGE.modifyA(0.1F)); if (g_pCompositor->m_pLastWindow) renderHLSurface(debugData.lastWindowText, g_pCompositor->m_pLastWindow->m_pWLSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F)); + + const auto DISCARDED_ELEMENTS = std::count_if(m_vPassElements.begin(), m_vPassElements.end(), [](const auto& e) { return e->discard; }); + auto tex = g_pHyprOpenGL->renderText(std::format("occlusion layers: {}\npass elements: {} ({} discarded)\nviewport: {:X0}", occludedRegions.size(), m_vPassElements.size(), + DISCARDED_ELEMENTS, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize), + Colors::WHITE, 12); + + if (tex) { + box = CBox{{0.F, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.y - tex->m_vSize.y}, tex->m_vSize}.scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); + g_pHyprOpenGL->renderTexture(tex, &box, 1.F); + } + + std::string passStructure; + auto yn = [](const bool val) -> const char* { return val ? "yes" : "no"; }; + auto tick = [](const bool val) -> const char* { return val ? "✔" : "✖"; }; + for (const auto& el : m_vPassElements | std::views::reverse) { + passStructure += std::format("{} {} (bb: {} op: {})\n", tick(!el->discard), el->element->passName(), yn(el->element->boundingBox().has_value()), + yn(!el->element->opaqueRegion().empty())); + } + + if (!passStructure.empty()) + passStructure.pop_back(); + + tex = g_pHyprOpenGL->renderText(passStructure, Colors::WHITE, 12); + if (tex) { + box = CBox{{g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.x - tex->m_vSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.y - tex->m_vSize.y}, tex->m_vSize}.scale( + g_pHyprOpenGL->m_RenderData.pMonitor->scale); + g_pHyprOpenGL->renderTexture(tex, &box, 1.F); + } } float CRenderPass::oneBlurRadius() { diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp index 5fa25fc3..a0810155 100644 --- a/src/render/pass/Pass.hpp +++ b/src/render/pass/Pass.hpp @@ -19,9 +19,9 @@ class CRenderPass { CRegion render(const CRegion& damage_); private: - CRegion damage; - CRegion occludedRegion; - CRegion totalLiveBlurRegion; + CRegion damage; + std::vector occludedRegions; + CRegion totalLiveBlurRegion; struct SPassElementData { CRegion elementDamage; From 1b06d222cf5abfc9802f7787315a8190f011d43e Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 5 Jan 2025 20:35:24 +0100 Subject: [PATCH 0076/1444] pass/surface: fixup invalid expansion by old -1 rounding param fixes #8889 --- src/render/pass/SurfacePassElement.hpp | 36 +++++++------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/render/pass/SurfacePassElement.hpp b/src/render/pass/SurfacePassElement.hpp index 14d8ef14..12387367 100644 --- a/src/render/pass/SurfacePassElement.hpp +++ b/src/render/pass/SurfacePassElement.hpp @@ -9,38 +9,22 @@ class CSyncTimeline; class CSurfacePassElement : public IPassElement { public: struct SRenderData { - PHLMONITORREF pMonitor; - timespec* when = nullptr; - Vector2D pos, localPos; + PHLMONITORREF pMonitor; + timespec* when = nullptr; + Vector2D pos, localPos; - // for iters void* data = nullptr; SP surface = nullptr; SP texture = nullptr; bool mainSurface = true; double w = 0, h = 0; - - // for rounding - bool dontRound = true; - - // for fade - float fadeAlpha = 1.f; - - // for alpha settings - float alpha = 1.f; - - // for decorations (border) - bool decorate = false; - - // for custom round values - int rounding = -1; // -1 means not set - - // for custom rounding powers - float roundingPower = 2.0f; - - // for blurring - bool blur = false; - bool blockBlurOptimization = false; + int rounding = 0; + bool dontRound = true; + float roundingPower = 2.0F; + bool decorate = false; + float alpha = 1.F, fadeAlpha = 1.F; + bool blur = false; + bool blockBlurOptimization = false; // only for windows, not popups bool squishOversized = true; From f390f48a07d117e24acec59dcf6791bcb3a81110 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 5 Jan 2025 23:19:13 +0100 Subject: [PATCH 0077/1444] pass: fixup debug mode rendering of input boxes --- src/render/pass/Pass.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 0489e985..b72248c2 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -226,12 +226,13 @@ void CRenderPass::renderDebugData() { if (box.intersection(CBox{{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize}).empty()) return; + g_pHyprOpenGL->renderRectWithDamage(&box, color, CRegion{0, 0, INT32_MAX, INT32_MAX}); + if (offsets.contains(surface.get())) box.translate(Vector2D{0.F, offsets[surface.get()]}); else offsets[surface.get()] = 0; - g_pHyprOpenGL->renderRectWithDamage(&box, Colors::PURPLE.modifyA(0.1F), CRegion{0, 0, INT32_MAX, INT32_MAX}); box = {box.pos(), texture->m_vSize}; g_pHyprOpenGL->renderRectWithDamage(&box, CHyprColor{0.F, 0.F, 0.F, 0.2F}, CRegion{0, 0, INT32_MAX, INT32_MAX}, std::min(5.0, box.size().y)); g_pHyprOpenGL->renderTexture(texture, &box, 1.F); From f1a7a7497e9b058092e915acd5164dcc162a8260 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 6 Jan 2025 15:27:57 +0100 Subject: [PATCH 0078/1444] datadevice: guard XWayland server against crashes The server might be dead or restarting, and we'd deref null ref #7822 --- src/protocols/core/DataDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 6ad17d7b..722eb9fd 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -417,7 +417,7 @@ void CWLDataDeviceProtocol::destroyResource(CWLDataOfferResource* resource) { SP CWLDataDeviceProtocol::dataDeviceForClient(wl_client* c) { #ifndef NO_XWAYLAND - if (c == g_pXWayland->pServer->xwaylandClient) + if (g_pXWayland->pServer && c == g_pXWayland->pServer->xwaylandClient) return g_pXWayland->pWM->getDataDevice(); #endif From 780e3dd542c9706dd37b715f95eb1134b14e6624 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Mon, 6 Jan 2025 14:29:29 +0000 Subject: [PATCH 0079/1444] [gha] Nix: update inputs --- flake.lock | 73 +++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/flake.lock b/flake.lock index 76d371bc..f16ecaa7 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1734906446, - "narHash": "sha256-6OWluVE2A8xi+8V3jN9KA72RCgJjYdyyuLBUjxZ2q2U=", + "lastModified": 1736102453, + "narHash": "sha256-5qb4kb7Xbt8jJFL/oDqOor9Z2+E+A+ql3PiyDvsfWZ0=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "eecb74dc79bb6752a2a507e6edee3042390a6091", + "rev": "4846091641f3be0ad7542086d52769bb7932bde6", "type": "github" }, "original": { @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1734906236, - "narHash": "sha256-vH/ysV2ONGQgYZPtcJKwc8jJivzyVxru2aaOxC20ZOE=", + "lastModified": 1736115290, + "narHash": "sha256-Jcn6yAzfUMcxy3tN/iZRbi/QgrYm7XLyVRl9g/nbUl4=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "6dea3fba08fd704dd624b6d4b261638fb4003c9c", + "rev": "52202272d89da32a9f866c0d10305a5e3d954c50", "type": "github" }, "original": { @@ -128,11 +128,11 @@ ] }, "locked": { - "lastModified": 1735734474, - "narHash": "sha256-9OV4lOqrEJVLdOrpNN/9msNwAhI6FQTu4N7fufilG08=", + "lastModified": 1735774328, + "narHash": "sha256-vIRwLS9w+N99EU1aJ+XNOU6mJTxrUBa31i1r82l0V7s=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "271df559dd30e4bc5ec6af02d017ac0aaabd63a7", + "rev": "e3b6af97ddcfaafbda8e2828c719a5af84f662cb", "type": "github" }, "original": { @@ -154,11 +154,11 @@ ] }, "locked": { - "lastModified": 1734906472, - "narHash": "sha256-pWPRv/GA/X/iAwoE6gMNUqn/ZeJX1IeLPRpZI0tTPK0=", + "lastModified": 1736114838, + "narHash": "sha256-FxbuGQExtN37ToWYnGmO6weOYN6WPHN/RAqbr7gNPek=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "c77109d7e1ddbcdb87cafd32ce411f76328ae152", + "rev": "6997fe382dcf396704227d2b98ffdd5066da6959", "type": "github" }, "original": { @@ -180,11 +180,11 @@ ] }, "locked": { - "lastModified": 1734906259, - "narHash": "sha256-P79t/7HbACO4/PuJBroGpTptvCWJtXTv+gWsF+sM6MI=", + "lastModified": 1735393019, + "narHash": "sha256-NPpqA8rtmDLsEmZOmz+qR67zsB6Y503Jnv+nSFLKJZ8=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "0404833ea18d543df44df935ebf1b497310eb046", + "rev": "55608efdaa387af7bfdc0eddb404c409958efa43", "type": "github" }, "original": { @@ -203,11 +203,11 @@ ] }, "locked": { - "lastModified": 1735316583, - "narHash": "sha256-AiiUwHWHfEdpFzXy7l1x3zInCUa1xcRMrbZ1XRSkzwU=", + "lastModified": 1736164519, + "narHash": "sha256-1LimBKvDpBbeX+qW7T240WEyw+DBVpDotZB4JYm8Aps=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "8f15d45b120b33712f6db477fe5ffb18034d0ea8", + "rev": "3c895da64b0eb19870142196fa48c07090b441c4", "type": "github" }, "original": { @@ -226,11 +226,11 @@ ] }, "locked": { - "lastModified": 1734793513, - "narHash": "sha256-rrrHcXapXJvGFqX+L/Bb0182L25jofAZ0fm1FInvrTQ=", + "lastModified": 1735493474, + "narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "4d7367b6eee87397e2dbca2e78078dd0a4ef4c61", + "rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b", "type": "github" }, "original": { @@ -241,11 +241,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1735291276, - "narHash": "sha256-NYVcA06+blsLG6wpAbSPTCyLvxD/92Hy4vlY9WxFI1M=", + "lastModified": 1736012469, + "narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "634fd46801442d760e09493a794c4f15db2d0cbb", + "rev": "8f3e1f807051e32d8c95cd12b9b421623850a34d", "type": "github" }, "original": { @@ -255,37 +255,20 @@ "type": "github" } }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1730741070, - "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.05", - "repo": "nixpkgs", - "type": "github" - } - }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" + ] }, "locked": { - "lastModified": 1734797603, - "narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=", + "lastModified": 1735882644, + "narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498", + "rev": "a5a961387e75ae44cc20f0a57ae463da5e959656", "type": "github" }, "original": { From 602d6b73563e56fe003bbf3d25b45a53c51bad24 Mon Sep 17 00:00:00 2001 From: Mike Will Date: Mon, 6 Jan 2025 11:37:13 -0500 Subject: [PATCH 0080/1444] snap: don't snap to any windows if workspace has a fullscreen window (#8870) --- src/layout/IHyprLayout.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index e90ab0f0..f875b99c 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -421,11 +421,13 @@ static void performSnap(Vector2D& sourcePos, Vector2D& sourceSize, PHLWINDOW DRA SRange sourceY = {sourcePos.y, sourcePos.y + sourceSize.y}; if (*SNAPWINDOWGAP) { - const double GAPSIZE = *SNAPWINDOWGAP; - const auto WSID = DRAGGINGWINDOW->workspaceID(); + const double GAPSIZE = *SNAPWINDOWGAP; + const auto WSID = DRAGGINGWINDOW->workspaceID(); + const bool HASFULLSCREEN = DRAGGINGWINDOW->m_pWorkspace && DRAGGINGWINDOW->m_pWorkspace->m_bHasFullscreenWindow; for (auto& other : g_pCompositor->m_vWindows) { - if (other == DRAGGINGWINDOW || other->workspaceID() != WSID || !other->m_bIsMapped || other->m_bFadingOut || other->isX11OverrideRedirect()) + if ((HASFULLSCREEN && !other->m_bCreatedOverFullscreen) || other == DRAGGINGWINDOW || other->workspaceID() != WSID || !other->m_bIsMapped || other->m_bFadingOut || + other->isX11OverrideRedirect()) continue; const int OTHERBORDERSIZE = other->getRealBorderSize(); From 6a90b505456cc708ec2779e0943eb9764e7630a5 Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:52:35 +0300 Subject: [PATCH 0081/1444] core/compositor: fix too early buffer release (#8966) --- src/protocols/core/Compositor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index ee1e6224..6213f987 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -428,6 +428,7 @@ void CWLSurfaceResource::commitPendingState() { pending.damage.clear(); pending.bufferDamage.clear(); pending.newBuffer = false; + dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore events.roleCommit.emit(); @@ -448,10 +449,9 @@ void CWLSurfaceResource::commitPendingState() { // release the buffer if it's synchronous as update() has done everything thats needed // so we can let the app know we're done. - if (current.buffer->buffer->isSynchronous()) { - dropCurrentBuffer(); - dropPendingBuffer(); // pending atm is just a copied ref of the current, drop it too to send a release - } + // Some clients aren't ready to receive a release this early. Should be fine to release it on the next commitPendingState. + // if (current.buffer->buffer->isSynchronous()) + // dropCurrentBuffer(); } // TODO: we should _accumulate_ and not replace above if sync From 1bf4937b0292dc156e2530185c231608280be27f Mon Sep 17 00:00:00 2001 From: Byso Date: Mon, 6 Jan 2025 17:52:59 +0100 Subject: [PATCH 0082/1444] hyprctl: fix hyprctl --batch not working with exec rules (#8952) --- src/debug/HyprCtl.cpp | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index b946da6e..8724d2c7 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1150,34 +1150,26 @@ static std::string cursorPosRequest(eHyprCtlOutputFormat format, std::string req } static std::string dispatchBatch(eHyprCtlOutputFormat format, std::string request) { - // split by ; - - request = request.substr(9); - std::string curitem = ""; - std::string reply = ""; - - auto nextItem = [&]() { - auto idx = request.find_first_of(';'); - - if (idx != std::string::npos) { - curitem = request.substr(0, idx); - request = request.substr(idx + 1); - } else { - curitem = request; - request = ""; - } - - curitem = trim(curitem); - }; - - nextItem(); + // split by ; ignores ; inside [] and adds ; on last command + request = request.substr(9); + std::string reply = ""; const std::string DELIMITER = "\n\n\n"; + int bracket = 0; + size_t idx = 0; - while (curitem != "" || request != "") { - reply += g_pHyprCtl->getReply(curitem) + DELIMITER; - - nextItem(); + for (size_t i = 0; i <= request.size(); ++i) { + char ch = (i < request.size()) ? request[i] : ';'; + if (ch == '[') + ++bracket; + else if (ch == ']') + --bracket; + else if (ch == ';' && bracket == 0) { + if (idx < i) + reply += g_pHyprCtl->getReply(trim(request.substr(idx, i - idx))).append(DELIMITER); + idx = i + 1; + continue; + } } return reply.substr(0, std::max(static_cast(reply.size() - DELIMITER.size()), 0)); From b9f110ef8726fcba2b4ee69856027731e73003a5 Mon Sep 17 00:00:00 2001 From: Pollux Date: Mon, 6 Jan 2025 13:30:57 -0600 Subject: [PATCH 0083/1444] shaders: fix blank windows when using corner rounding (#8969) (#8971) --- src/render/shaders/Textures.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp index 49d27b4c..78845322 100644 --- a/src/render/shaders/Textures.hpp +++ b/src/render/shaders/Textures.hpp @@ -19,7 +19,7 @@ inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVar const float SMOOTHING_CONSTANT = )#" + std::format("{:.7f}", SHADER_ROUNDED_SMOOTHING_FACTOR) + R"#(; - //if (pixCoord.x + pixCoord.y > radius) { + if (pixCoord.x + pixCoord.y > radius) { float dist = pow(pow(pixCoord.x, roundingPower) + pow(pixCoord.y, roundingPower), 1.0/roundingPower); @@ -30,7 +30,7 @@ inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVar )#" + colorVarName + R"#( = )#" + colorVarName + R"#( * normalized; - //} + } )#"; }; From c7086f936a06abebcc863c35f634760ca1ee90c0 Mon Sep 17 00:00:00 2001 From: Zetta1 Reid0 <79805086+Zetta1Reid0@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:50:34 +0200 Subject: [PATCH 0084/1444] master: add option to show slaves on left in center orientation (#8940) Co-authored-by: Zetta1_Reid0 <11255-Zetta1_Reid0@users.noreply.gitlab.xfce.org> --- src/config/ConfigDescriptions.hpp | 6 ++++++ src/config/ConfigManager.cpp | 1 + src/layout/MasterLayout.cpp | 20 +++++++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 46f91a21..8c35a3b1 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1632,6 +1632,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{2, 0, 10}, //##TODO RANGE? }, + SConfigOptionDescription{ + .value = "master:center_master_slaves_on_right", + .description = "set if the slaves should appear on right of master when slave_count_for_center_master > 2", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, SConfigOptionDescription{ .value = "master:center_ignores_reserved", .description = "centers the master window on monitor ignoring reserved areas", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 732d12e5..927cee9f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -479,6 +479,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("master:mfact", {0.55f}); m_pConfig->addConfigValue("master:new_status", {"slave"}); m_pConfig->addConfigValue("master:slave_count_for_center_master", Hyprlang::INT{2}); + m_pConfig->addConfigValue("master:center_master_slaves_on_right", Hyprlang::INT{1}); m_pConfig->addConfigValue("master:center_ignores_reserved", Hyprlang::INT{0}); m_pConfig->addConfigValue("master:new_on_active", {"none"}); m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0}); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index fb7df84f..225246f0 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -328,6 +328,7 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { eOrientation orientation = getDynamicOrientation(pWorkspace); bool centerMasterWindow = false; static auto SLAVECOUNTFORCENTER = CConfigValue("master:slave_count_for_center_master"); + static auto CMSLAVESONRIGHT = CConfigValue("master:center_master_slaves_on_right"); static auto PIGNORERESERVED = CConfigValue("master:center_ignores_reserved"); static auto PSMARTRESIZING = CConfigValue("master:smart_resizing"); @@ -341,7 +342,10 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { if (STACKWINDOWS >= *SLAVECOUNTFORCENTER) { centerMasterWindow = true; } else { - orientation = ORIENTATION_LEFT; + if (*CMSLAVESONRIGHT) + orientation = ORIENTATION_LEFT; + else + orientation = ORIENTATION_RIGHT; } } @@ -515,15 +519,20 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { float nextY = 0; float nextYL = 0; float nextYR = 0; - bool onRight = true; + bool onRight = *CMSLAVESONRIGHT; + int slavesLeftL = 1 + (slavesLeft - 1) / 2; + int slavesLeftR = slavesLeft - slavesLeftL; - int slavesLeftR = 1 + (slavesLeft - 1) / 2; - int slavesLeftL = slavesLeft - slavesLeftR; + if (*CMSLAVESONRIGHT) { + slavesLeftR = 1 + (slavesLeft - 1) / 2; + slavesLeftL = slavesLeft - slavesLeftR; + } const float slaveAverageHeightL = WSSIZE.y / slavesLeftL; const float slaveAverageHeightR = WSSIZE.y / slavesLeftR; float slaveAccumulatedHeightL = 0; float slaveAccumulatedHeightR = 0; + if (*PSMARTRESIZING) { for (auto const& nd : m_lMasterNodesData) { if (nd.workspaceID != pWorkspace->m_iID || nd.isMaster) @@ -536,7 +545,8 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { } onRight = !onRight; } - onRight = true; + + onRight = *CMSLAVESONRIGHT; } for (auto& nd : m_lMasterNodesData) { From 5642ed331df56375c55cd8d56a14054af8bdf8f2 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:55:14 +0000 Subject: [PATCH 0085/1444] core: move parts of the animation system to hyprutils (#8868) * core: change animation manager to use Hyprutils::Animation * config: move animation config to hyprutils animation tree * use g_pAnimationManager->createAnimation and the new PHLANIMVAR template * core: use CGenericAnimatedVariabled::{enabled,setConfig,getStyle} and adapt callbacks * core: adapt animated variable usage (dereference the shared pointer) * misc: bump CMakeLists to hyprutils 0.3.3 --- CMakeLists.txt | 2 +- src/Compositor.cpp | 78 +-- src/config/ConfigManager.cpp | 156 ++--- src/config/ConfigManager.hpp | 87 ++- src/debug/HyprCtl.cpp | 23 +- src/desktop/LayerSurface.cpp | 88 ++- src/desktop/LayerSurface.hpp | 18 +- src/desktop/Popup.cpp | 4 +- src/desktop/Subsurface.cpp | 2 +- src/desktop/WLSurface.cpp | 2 +- src/desktop/Window.cpp | 198 +++--- src/desktop/Window.hpp | 42 +- src/desktop/Workspace.cpp | 99 ++- src/desktop/Workspace.hpp | 6 +- src/events/Windows.cpp | 100 +-- src/helpers/AnimatedVariable.cpp | 87 --- src/helpers/AnimatedVariable.hpp | 275 +-------- src/helpers/BezierCurve.cpp | 90 --- src/helpers/BezierCurve.hpp | 28 - src/helpers/Monitor.cpp | 8 +- src/helpers/WLClasses.hpp | 1 - src/hyprerror/HyprError.cpp | 30 +- src/hyprerror/HyprError.hpp | 20 +- src/layout/DwindleLayout.cpp | 38 +- src/layout/IHyprLayout.cpp | 100 +-- src/layout/MasterLayout.cpp | 36 +- src/managers/AnimationManager.cpp | 584 +++++++----------- src/managers/AnimationManager.hpp | 75 ++- src/managers/KeybindManager.cpp | 64 +- src/managers/XWaylandManager.cpp | 6 +- src/managers/input/InputManager.cpp | 12 +- src/managers/input/Swipe.cpp | 120 ++-- src/managers/input/Tablets.cpp | 2 +- src/managers/input/Touch.cpp | 16 +- src/protocols/CTMControl.cpp | 14 +- src/protocols/CTMControl.hpp | 4 +- src/protocols/ToplevelExport.cpp | 8 +- src/render/OpenGL.cpp | 8 +- src/render/Renderer.cpp | 94 +-- .../decorations/CHyprBorderDecoration.cpp | 14 +- .../decorations/CHyprDropShadowDecoration.cpp | 28 +- .../decorations/CHyprGroupBarDecoration.cpp | 10 +- .../decorations/DecorationPositioner.cpp | 6 +- src/render/pass/SurfacePassElement.cpp | 12 +- 44 files changed, 1031 insertions(+), 1664 deletions(-) delete mode 100644 src/helpers/AnimatedVariable.cpp delete mode 100644 src/helpers/BezierCurve.cpp delete mode 100644 src/helpers/BezierCurve.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d5c58b7..aa746d2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION}) pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5) pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2) pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) -pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.2.3) +pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.3.3) pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1) add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}") diff --git a/src/Compositor.cpp b/src/Compositor.cpp index c80f05e6..5805eff9 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -569,7 +569,7 @@ void CCompositor::initManagers(eManagersInitStage stage) { g_pKeybindManager = std::make_unique(); Debug::log(LOG, "Creating the AnimationManager!"); - g_pAnimationManager = std::make_unique(); + g_pAnimationManager = std::make_unique(); Debug::log(LOG, "Creating the ConfigManager!"); g_pConfigManager = std::make_unique(); @@ -964,11 +964,11 @@ SP CCompositor::vectorWindowToSurface(const Vector2D& pos, P if (PPOPUP) { const auto OFF = PPOPUP->coordsRelativeToParent(); - sl = pos - pWindow->m_vRealPosition.goal() - OFF; + sl = pos - pWindow->m_vRealPosition->goal() - OFF; return PPOPUP->m_pWLSurface->resource(); } - auto [surf, local] = pWindow->m_pWLSurface->resource()->at(pos - pWindow->m_vRealPosition.goal(), true); + auto [surf, local] = pWindow->m_pWLSurface->resource()->at(pos - pWindow->m_vRealPosition->goal(), true); if (surf) { sl = local; return surf; @@ -982,7 +982,7 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo return {}; if (pWindow->m_bIsX11) - return vec - pWindow->m_vRealPosition.goal(); + return vec - pWindow->m_vRealPosition->goal(); const auto PPOPUP = pWindow->m_pPopupHead->at(vec); if (PPOPUP) @@ -1001,9 +1001,9 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo CBox geom = pWindow->m_pXDGSurface->current.geometry; if (std::get<1>(iterData) == Vector2D{-1337, -1337}) - return vec - pWindow->m_vRealPosition.goal(); + return vec - pWindow->m_vRealPosition->goal(); - return vec - pWindow->m_vRealPosition.goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y}; + return vec - pWindow->m_vRealPosition->goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y}; } PHLMONITOR CCompositor::getMonitorFromOutput(SP out) { @@ -1211,7 +1211,7 @@ void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindo SP CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { for (auto const& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) { for (auto const& ls : lsl | std::views::reverse) { - if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha.value() == 0.f) + if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha->value() == 0.f) continue; auto SURFACEAT = ls->popupHead->at(pos, true); @@ -1229,7 +1229,7 @@ SP CCompositor::vectorToLayerPopupSurface(const Vector2D& po SP CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { for (auto const& ls : *layerSurfaces | std::views::reverse) { - if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f) + if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha->value() == 0.f) continue; auto [surf, local] = ls->layerSurface->surface->at(pos - ls->geometry.pos(), true); @@ -1378,7 +1378,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) { if (w->monitorID() != monid && w->m_pMonitor) continue; - if (!w->m_bFadingOut || w->m_fAlpha.value() == 0.f) { + if (!w->m_bFadingOut || w->m_fAlpha->value() == 0.f) { w->m_bFadingOut = false; @@ -1831,8 +1831,8 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { pWindow->m_cRealBorderColorPrevious = pWindow->m_cRealBorderColor; pWindow->m_cRealBorderColor = grad; - pWindow->m_fBorderFadeAnimationProgress.setValueAndWarp(0.f); - pWindow->m_fBorderFadeAnimationProgress = 1.f; + pWindow->m_fBorderFadeAnimationProgress->setValueAndWarp(0.f); + *pWindow->m_fBorderFadeAnimationProgress = 1.f; }; const bool IS_SHADOWED_BY_MODAL = pWindow->m_pXDGSurface && pWindow->m_pXDGSurface->toplevel && pWindow->m_pXDGSurface->toplevel->anyChildModal(); @@ -1855,18 +1855,18 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { } // tick angle if it's not running (aka dead) - if (!pWindow->m_fBorderAngleAnimationProgress.isBeingAnimated()) - pWindow->m_fBorderAngleAnimationProgress.setValueAndWarp(0.f); + if (!pWindow->m_fBorderAngleAnimationProgress->isBeingAnimated()) + pWindow->m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); // opacity const auto PWORKSPACE = pWindow->m_pWorkspace; if (pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) { - pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA); + *pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA); } else { if (pWindow == m_pLastWindow) - pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alpha.valueOrDefault().applyAlpha(*PACTIVEALPHA); + *pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alpha.valueOrDefault().applyAlpha(*PACTIVEALPHA); else - pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaInactive.valueOrDefault().applyAlpha(*PINACTIVEALPHA); + *pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaInactive.valueOrDefault().applyAlpha(*PINACTIVEALPHA); } // dim @@ -1879,16 +1879,16 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { if (IS_SHADOWED_BY_MODAL) goalDim += (1.F - goalDim) / 2.F; - pWindow->m_fDimPercent = goalDim; + *pWindow->m_fDimPercent = goalDim; // shadow if (!pWindow->isX11OverrideRedirect() && !pWindow->m_bX11DoesntWantBorders) { if (pWindow == m_pLastWindow) - pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOL); + *pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOL); else - pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != INT64_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL); + *pWindow->m_cRealShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != INT64_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL); } else { - pWindow->m_cRealShadowColor.setValueAndWarp(CHyprColor(0, 0, 0, 0)); // no shadow + pWindow->m_cRealShadowColor->setValueAndWarp(CHyprColor(0, 0, 0, 0)); // no shadow } pWindow->updateWindowDecos(); @@ -1932,11 +1932,11 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor // additionally, move floating and fs windows manually if (w->m_bIsFloating) - w->m_vRealPosition = w->m_vRealPosition.goal() - pMonitorA->vecPosition + pMonitorB->vecPosition; + *w->m_vRealPosition = w->m_vRealPosition->goal() - pMonitorA->vecPosition + pMonitorB->vecPosition; if (w->isFullscreen()) { - w->m_vRealPosition = pMonitorB->vecPosition; - w->m_vRealSize = pMonitorB->vecSize; + *w->m_vRealPosition = pMonitorB->vecPosition; + *w->m_vRealSize = pMonitorB->vecSize; } w->updateToplevel(); @@ -1957,11 +1957,11 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor // additionally, move floating and fs windows manually if (w->m_bIsFloating) - w->m_vRealPosition = w->m_vRealPosition.goal() - pMonitorB->vecPosition + pMonitorA->vecPosition; + *w->m_vRealPosition = w->m_vRealPosition->goal() - pMonitorB->vecPosition + pMonitorA->vecPosition; if (w->isFullscreen()) { - w->m_vRealPosition = pMonitorA->vecPosition; - w->m_vRealSize = pMonitorA->vecSize; + *w->m_vRealPosition = pMonitorA->vecPosition; + *w->m_vRealSize = pMonitorA->vecSize; } w->updateToplevel(); @@ -2135,14 +2135,14 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo if (w->m_bIsMapped && !w->isHidden()) { if (POLDMON) { if (w->m_bIsFloating) - w->m_vRealPosition = w->m_vRealPosition.goal() - POLDMON->vecPosition + pMonitor->vecPosition; + *w->m_vRealPosition = w->m_vRealPosition->goal() - POLDMON->vecPosition + pMonitor->vecPosition; if (w->isFullscreen()) { - w->m_vRealPosition = pMonitor->vecPosition; - w->m_vRealSize = pMonitor->vecSize; + *w->m_vRealPosition = pMonitor->vecPosition; + *w->m_vRealSize = pMonitor->vecSize; } } else { - w->m_vRealPosition = Vector2D{(int)w->m_vRealPosition.goal().x % (int)pMonitor->vecSize.x, (int)w->m_vRealPosition.goal().y % (int)pMonitor->vecSize.y}; + *w->m_vRealPosition = Vector2D{(int)w->m_vRealPosition->goal().x % (int)pMonitor->vecSize.x, (int)w->m_vRealPosition->goal().y % (int)pMonitor->vecSize.y}; } } @@ -2216,9 +2216,9 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) { continue; if (!FULLSCREEN) - w->m_fAlpha = 1.f; + *w->m_fAlpha = 1.f; else if (!w->isFullscreen()) - w->m_fAlpha = !w->m_bCreatedOverFullscreen ? 0.f : 1.f; + *w->m_fAlpha = !w->m_bCreatedOverFullscreen ? 0.f : 1.f; } } @@ -2227,7 +2227,7 @@ void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) { if (pWorkspace->m_iID == PMONITOR->activeWorkspaceID() || pWorkspace->m_iID == PMONITOR->activeSpecialWorkspaceID()) { for (auto const& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { if (!ls->fadingOut) - ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f; + *ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f; } } } @@ -2317,7 +2317,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS updateFullscreenFadeOnWorkspace(PWORKSPACE); - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal(), true); + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize->goal(), true); PWORKSPACE->forceReportSizesToWindows(); @@ -2573,7 +2573,7 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO const auto PWORKSPACE = m_vWorkspaces.emplace_back(CWorkspace::create(id, getMonitorFromID(monID), NAME, SPECIAL, isEmpty)); - PWORKSPACE->m_fAlpha.setValueAndWarp(0); + PWORKSPACE->m_fAlpha->setValueAndWarp(0); return PWORKSPACE; } @@ -2659,7 +2659,7 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor const PHLWINDOW pFirstWindowOnWorkspace = pWorkspace->getFirstWindow(); const int visibleWindowsOnWorkspace = pWorkspace->getWindows(std::nullopt, true); const auto PWINDOWMONITOR = pWindow->m_pMonitor.lock(); - const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition; + const auto POSTOMON = pWindow->m_vRealPosition->goal() - PWINDOWMONITOR->vecPosition; const auto PWORKSPACEMONITOR = pWorkspace->m_pMonitor.lock(); if (!pWindow->m_bIsFloating) @@ -2696,7 +2696,7 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow); if (pWindow->m_bIsFloating) - pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition; + *pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition; } pWindow->updateToplevel(); @@ -2721,8 +2721,8 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor g_pCompositor->updateSuspendedStates(); if (!WASVISIBLE && pWindow->m_pWorkspace && pWindow->m_pWorkspace->isVisible()) { - pWindow->m_fMovingFromWorkspaceAlpha.setValueAndWarp(0.F); - pWindow->m_fMovingFromWorkspaceAlpha = 1.F; + pWindow->m_fMovingFromWorkspaceAlpha->setValueAndWarp(0.F); + *pWindow->m_fMovingFromWorkspaceAlpha = 1.F; } } diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 927cee9f..1ab29b1f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -11,6 +11,7 @@ #include "../protocols/LayerShell.hpp" #include "../xwayland/XWayland.hpp" #include "../protocols/OutputManagement.hpp" +#include "managers/AnimationManager.hpp" #include #include @@ -32,6 +33,7 @@ #include #include using namespace Hyprutils::String; +using namespace Hyprutils::Animation; //NOLINTNEXTLINE extern "C" char** environ; @@ -681,7 +683,6 @@ CConfigManager::CConfigManager() { m_pConfig->commence(); - setDefaultAnimationVars(); resetHLConfig(); Debug::log(INFO, @@ -780,76 +781,46 @@ void CConfigManager::reload() { } void CConfigManager::setDefaultAnimationVars() { - if (isFirstLaunch) { - INITANIMCFG("__internal_fadeCTM"); + m_AnimationTree.createNode("__internal_fadeCTM"); + m_AnimationTree.createNode("global"); - INITANIMCFG("global"); - INITANIMCFG("windows"); - INITANIMCFG("layers"); - INITANIMCFG("fade"); - INITANIMCFG("border"); - INITANIMCFG("borderangle"); + // global + m_AnimationTree.createNode("windows", "global"); + m_AnimationTree.createNode("layers", "global"); + m_AnimationTree.createNode("fade", "global"); + m_AnimationTree.createNode("border", "global"); + m_AnimationTree.createNode("borderangle", "global"); + m_AnimationTree.createNode("workspaces", "global"); - // windows - INITANIMCFG("windowsIn"); - INITANIMCFG("windowsOut"); - INITANIMCFG("windowsMove"); + // layer + m_AnimationTree.createNode("layersIn", "layers"); + m_AnimationTree.createNode("layersOut", "layers"); - // layers - INITANIMCFG("layersIn"); - INITANIMCFG("layersOut"); + // windows + m_AnimationTree.createNode("windowsIn", "windows"); + m_AnimationTree.createNode("windowsOut", "windows"); + m_AnimationTree.createNode("windowsMove", "windows"); - // fade - INITANIMCFG("fadeIn"); - INITANIMCFG("fadeOut"); - INITANIMCFG("fadeSwitch"); - INITANIMCFG("fadeShadow"); - INITANIMCFG("fadeDim"); + // fade + m_AnimationTree.createNode("fadeIn", "fade"); + m_AnimationTree.createNode("fadeOut", "fade"); + m_AnimationTree.createNode("fadeSwitch", "fade"); + m_AnimationTree.createNode("fadeShadow", "fade"); + m_AnimationTree.createNode("fadeDim", "fade"); + m_AnimationTree.createNode("fadeLayers", "fade"); + m_AnimationTree.createNode("fadeLayersIn", "fadeLayers"); + m_AnimationTree.createNode("fadeLayersOut", "fadeLayers"); - // border + // workspaces + m_AnimationTree.createNode("workspacesIn", "workspaces"); + m_AnimationTree.createNode("workspacesOut", "workspaces"); + m_AnimationTree.createNode("specialWorkspace", "workspaces"); + m_AnimationTree.createNode("specialWorkspaceIn", "specialWorkspace"); + m_AnimationTree.createNode("specialWorkspaceOut", "specialWorkspace"); - // workspaces - INITANIMCFG("workspaces"); - INITANIMCFG("workspacesIn"); - INITANIMCFG("workspacesOut"); - INITANIMCFG("specialWorkspace"); - INITANIMCFG("specialWorkspaceIn"); - INITANIMCFG("specialWorkspaceOut"); - } - - // init the values - animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr}; - - animationConfig["__internal_fadeCTM"] = {false, "linear", "", 5.F, 1, &animationConfig["__internal_fadeCTM"], nullptr}; - - CREATEANIMCFG("windows", "global"); - CREATEANIMCFG("layers", "global"); - CREATEANIMCFG("fade", "global"); - CREATEANIMCFG("border", "global"); - CREATEANIMCFG("borderangle", "global"); - CREATEANIMCFG("workspaces", "global"); - - CREATEANIMCFG("layersIn", "layers"); - CREATEANIMCFG("layersOut", "layers"); - - CREATEANIMCFG("windowsIn", "windows"); - CREATEANIMCFG("windowsOut", "windows"); - CREATEANIMCFG("windowsMove", "windows"); - - CREATEANIMCFG("fadeIn", "fade"); - CREATEANIMCFG("fadeOut", "fade"); - CREATEANIMCFG("fadeSwitch", "fade"); - CREATEANIMCFG("fadeShadow", "fade"); - CREATEANIMCFG("fadeDim", "fade"); - CREATEANIMCFG("fadeLayers", "fade"); - CREATEANIMCFG("fadeLayersIn", "fadeLayers"); - CREATEANIMCFG("fadeLayersOut", "fadeLayers"); - - CREATEANIMCFG("workspacesIn", "workspaces"); - CREATEANIMCFG("workspacesOut", "workspaces"); - CREATEANIMCFG("specialWorkspace", "workspaces"); - CREATEANIMCFG("specialWorkspaceIn", "specialWorkspace"); - CREATEANIMCFG("specialWorkspaceOut", "specialWorkspace"); + // init the root nodes + m_AnimationTree.setConfigForNode("global", 1, 8.f, "", "default"); + m_AnimationTree.setConfigForNode("__internal_fadeCTM", 1, 5.f, "", "linear"); } std::optional CConfigManager::resetHLConfig() { @@ -857,6 +828,8 @@ std::optional CConfigManager::resetHLConfig() { m_vWindowRules.clear(); g_pKeybindManager->clearKeybinds(); g_pAnimationManager->removeAllBeziers(); + g_pAnimationManager->addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)); + m_mAdditionalReservedAreas.clear(); m_dBlurLSNamespaces.clear(); m_vWorkspaceRules.clear(); @@ -1647,8 +1620,8 @@ void CConfigManager::ensureVRR(PHLMONITOR pMonitor) { } } -SAnimationPropertyConfig* CConfigManager::getAnimationPropertyConfig(const std::string& name) { - return &animationConfig[name]; +SP CConfigManager::getAnimationPropertyConfig(const std::string& name) { + return m_AnimationTree.getConfig(name); } void CConfigManager::addParseError(const std::string& err) { @@ -1711,8 +1684,8 @@ ICustomConfigValueData::~ICustomConfigValueData() { ; // empty } -std::unordered_map CConfigManager::getAnimationConfig() { - return animationConfig; +const std::unordered_map>& CConfigManager::getAnimationConfig() { + return m_AnimationTree.getFullConfig(); } void CConfigManager::addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value) { @@ -2058,17 +2031,6 @@ std::optional CConfigManager::handleBezier(const std::string& comma return {}; } -void CConfigManager::setAnimForChildren(SAnimationPropertyConfig* const ANIM) { - for (auto& [name, anim] : animationConfig) { - if (anim.pParentAnimation == ANIM && !anim.overridden) { - // if a child isnt overridden, set the values of the parent - anim.pValues = ANIM->pValues; - - setAnimForChildren(&anim); - } - } -}; - std::optional CConfigManager::handleAnimation(const std::string& command, const std::string& args) { const auto ARGS = CVarList(args); @@ -2077,14 +2039,9 @@ std::optional CConfigManager::handleAnimation(const std::string& co // anim name const auto ANIMNAME = ARGS[0]; - const auto PANIM = animationConfig.find(ANIMNAME); - - if (PANIM == animationConfig.end()) + if (!m_AnimationTree.nodeExists(ANIMNAME)) return "no such animation"; - PANIM->second.overridden = true; - PANIM->second.pValues = &PANIM->second; - // This helper casts strings like "1", "true", "off", "yes"... to int. int64_t enabledInt = configStringToInt(ARGS[1]).value_or(0) == 1; @@ -2092,33 +2049,31 @@ std::optional CConfigManager::handleAnimation(const std::string& co if (enabledInt != 0 && enabledInt != 1) return "invalid animation on/off state"; - PANIM->second.internalEnabled = configStringToInt(ARGS[1]).value_or(0) == 1; + if (enabledInt) { + int64_t speed = -1; - if (PANIM->second.internalEnabled) { // speed if (isNumber(ARGS[2], true)) { - PANIM->second.internalSpeed = std::stof(ARGS[2]); + speed = std::stof(ARGS[2]); - if (PANIM->second.internalSpeed <= 0) { - PANIM->second.internalSpeed = 1.f; + if (speed <= 0) { + speed = 1.f; return "invalid speed"; } } else { - PANIM->second.internalSpeed = 10.f; + speed = 10.f; return "invalid speed"; } - // curve - PANIM->second.internalBezier = ARGS[3]; + std::string bezierName = ARGS[3]; + m_AnimationTree.setConfigForNode(ANIMNAME, enabledInt, speed, ARGS[3], ARGS[4]); - if (!g_pAnimationManager->bezierExists(ARGS[3])) { - PANIM->second.internalBezier = "default"; + if (!g_pAnimationManager->bezierExists(bezierName)) { + const auto PANIMNODE = m_AnimationTree.getConfig(ANIMNAME); + PANIMNODE->internalBezier = "default"; return "no such bezier"; } - // style - PANIM->second.internalStyle = ARGS[4]; - if (ARGS[4] != "") { auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]); @@ -2127,9 +2082,6 @@ std::optional CConfigManager::handleAnimation(const std::string& co } } - // now, check for children, recursively - setAnimForChildren(&PANIM->second); - return {}; } diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 436362ae..53772401 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -1,5 +1,6 @@ #pragma once +#include #define CONFIG_MANAGER_H #include @@ -23,9 +24,6 @@ #include -#define INITANIMCFG(name) animationConfig[name] = {} -#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]} - #define HANDLE void* struct SWorkspaceRule { @@ -54,18 +52,6 @@ struct SMonitorAdditionalReservedArea { int right = 0; }; -struct SAnimationPropertyConfig { - bool overridden = true; - - std::string internalBezier = ""; - std::string internalStyle = ""; - float internalSpeed = 0.f; - int internalEnabled = -1; - - SAnimationPropertyConfig* pValues = nullptr; - SAnimationPropertyConfig* pParentAnimation = nullptr; -}; - struct SPluginKeyword { HANDLE handle = nullptr; std::string name = ""; @@ -181,32 +167,32 @@ class CConfigManager { std::unordered_map m_mAdditionalReservedAreas; - std::unordered_map getAnimationConfig(); + const std::unordered_map>& getAnimationConfig(); - void addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value); + void addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value); void addPluginKeyword(HANDLE handle, const std::string& name, Hyprlang::PCONFIGHANDLERFUNC fun, Hyprlang::SHandlerOptions opts = {}); void removePluginConfig(HANDLE handle); // no-op when done. - void dispatchExecOnce(); - void dispatchExecShutdown(); + void dispatchExecOnce(); + void dispatchExecShutdown(); - void performMonitorReload(); - void ensureMonitorStatus(); - void ensureVRR(PHLMONITOR pMonitor = nullptr); + void performMonitorReload(); + void ensureMonitorStatus(); + void ensureVRR(PHLMONITOR pMonitor = nullptr); - bool shouldUseSoftwareCursors(); + bool shouldUseSoftwareCursors(); - std::string parseKeyword(const std::string&, const std::string&); + std::string parseKeyword(const std::string&, const std::string&); - void addParseError(const std::string&); + void addParseError(const std::string&); - SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&); + SP getAnimationPropertyConfig(const std::string&); - void addExecRule(const SExecRequestedRule&); + void addExecRule(const SExecRequestedRule&); - void handlePluginLoads(); - std::string getErrors(); + void handlePluginLoads(); + std::string getErrors(); // keywords std::optional handleRawExec(const std::string&, const std::string&); @@ -269,39 +255,38 @@ class CConfigManager { bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking private: - std::unique_ptr m_pConfig; + std::unique_ptr m_pConfig; - std::vector configPaths; // stores all the config paths - std::unordered_map configModifyTimes; // stores modify times + std::vector configPaths; // stores all the config paths + std::unordered_map configModifyTimes; // stores modify times - std::unordered_map animationConfig; // stores all the animations with their set values + Hyprutils::Animation::CAnimationConfigTree m_AnimationTree; - std::string m_szCurrentSubmap = ""; // For storing the current keybind submap + std::string m_szCurrentSubmap = ""; // For storing the current keybind submap - std::vector execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty + std::vector execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty - std::vector m_vDeclaredPlugins; - std::vector pluginKeywords; - std::vector pluginVariables; + std::vector m_vDeclaredPlugins; + std::vector pluginKeywords; + std::vector pluginVariables; - bool isFirstLaunch = true; // For exec-once + bool isFirstLaunch = true; // For exec-once - std::vector m_vMonitorRules; - std::vector m_vWorkspaceRules; - std::vector> m_vWindowRules; - std::vector> m_vLayerRules; - std::vector m_dBlurLSNamespaces; + std::vector m_vMonitorRules; + std::vector m_vWorkspaceRules; + std::vector> m_vWindowRules; + std::vector> m_vLayerRules; + std::vector m_dBlurLSNamespaces; - bool firstExecDispatched = false; - bool m_bManualCrashInitiated = false; - std::vector firstExecRequests; - std::vector finalExecRequests; + bool firstExecDispatched = false; + bool m_bManualCrashInitiated = false; + std::vector firstExecRequests; + std::vector finalExecRequests; - std::vector> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins - std::string m_szConfigErrors = ""; + std::vector> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins + std::string m_szConfigErrors = ""; // internal methods - void setAnimForChildren(SAnimationPropertyConfig* const); void updateBlurredLS(const std::string&, const bool); void setDefaultAnimationVars(); std::optional resetHLConfig(); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 8724d2c7..7edace21 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -248,8 +248,8 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { "focusHistoryID": {}, "inhibitingIdle": {} }},)#", - (uintptr_t)w.get(), (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, - (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, + (uintptr_t)w.get(), (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition->goal().x, (int)w->m_vRealPosition->goal().y, + (int)w->m_vRealSize->goal().x, (int)w->m_vRealSize->goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, escapeJSONStrings(!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), ((int)w->m_bIsFloating == 1 ? "true" : "false"), (w->m_bIsPseudotiled ? "true" : "false"), (int64_t)w->monitorID(), escapeJSONStrings(w->m_szClass), escapeJSONStrings(w->m_szTitle), escapeJSONStrings(w->m_szInitialClass), escapeJSONStrings(w->m_szInitialTitle), w->getPID(), ((int)w->m_bIsX11 == 1 ? "true" : "false"), (w->m_bPinned ? "true" : "false"), @@ -261,11 +261,12 @@ std::string CHyprCtl::getWindowData(PHLWINDOW w, eHyprCtlOutputFormat format) { "{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: " "{}\n\txwayland: {}\n\tpinned: " "{}\n\tfullscreen: {}\n\tfullscreenClient: {}\n\tgrouped: {}\n\ttags: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\tinhibitingIdle: {}\n\n", - (uintptr_t)w.get(), w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, - (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, (!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), - (int)w->m_bIsFloating, (int)w->m_bIsPseudotiled, (int64_t)w->monitorID(), w->m_szClass, w->m_szTitle, w->m_szInitialClass, w->m_szInitialTitle, w->getPID(), - (int)w->m_bIsX11, (int)w->m_bPinned, (uint8_t)w->m_sFullscreenState.internal, (uint8_t)w->m_sFullscreenState.client, getGroupedData(w, format), getTagsData(w, format), - (uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w), (int)g_pInputManager->isWindowInhibiting(w, false)); + (uintptr_t)w.get(), w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition->goal().x, (int)w->m_vRealPosition->goal().y, + (int)w->m_vRealSize->goal().x, (int)w->m_vRealSize->goal().y, w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID, + (!w->m_pWorkspace ? "" : w->m_pWorkspace->m_szName), (int)w->m_bIsFloating, (int)w->m_bIsPseudotiled, (int64_t)w->monitorID(), w->m_szClass, w->m_szTitle, + w->m_szInitialClass, w->m_szInitialTitle, w->getPID(), (int)w->m_bIsX11, (int)w->m_bPinned, (uint8_t)w->m_sFullscreenState.internal, + (uint8_t)w->m_sFullscreenState.client, getGroupedData(w, format), getTagsData(w, format), (uintptr_t)w->m_pSwallowed.lock().get(), getFocusHistoryID(w), + (int)g_pInputManager->isWindowInhibiting(w, false)); } } @@ -732,8 +733,8 @@ static std::string animationsRequest(eHyprCtlOutputFormat format, std::string re ret += "animations:\n"; for (auto const& ac : g_pConfigManager->getAnimationConfig()) { - ret += std::format("\n\tname: {}\n\t\toverriden: {}\n\t\tbezier: {}\n\t\tenabled: {}\n\t\tspeed: {:.2f}\n\t\tstyle: {}\n", ac.first, (int)ac.second.overridden, - ac.second.internalBezier, ac.second.internalEnabled, ac.second.internalSpeed, ac.second.internalStyle); + ret += std::format("\n\tname: {}\n\t\toverriden: {}\n\t\tbezier: {}\n\t\tenabled: {}\n\t\tspeed: {:.2f}\n\t\tstyle: {}\n", ac.first, (int)ac.second->overridden, + ac.second->internalBezier, ac.second->internalEnabled, ac.second->internalSpeed, ac.second->internalStyle); } ret += "beziers:\n"; @@ -755,8 +756,8 @@ static std::string animationsRequest(eHyprCtlOutputFormat format, std::string re "speed": {:.2f}, "style": "{}" }},)#", - ac.first, ac.second.overridden ? "true" : "false", escapeJSONStrings(ac.second.internalBezier), ac.second.internalEnabled ? "true" : "false", - ac.second.internalSpeed, escapeJSONStrings(ac.second.internalStyle)); + ac.first, ac.second->overridden ? "true" : "false", escapeJSONStrings(ac.second->internalBezier), ac.second->internalEnabled ? "true" : "false", + ac.second->internalSpeed, escapeJSONStrings(ac.second->internalStyle)); } ret[ret.length() - 1] = ']'; diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 05ea4473..fe11f3f3 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -4,6 +4,7 @@ #include "../protocols/LayerShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../managers/SeatManager.hpp" +#include "../managers/AnimationManager.hpp" PHLLS CLayerSurface::create(SP resource) { PHLLS pLS = SP(new CLayerSurface(resource)); @@ -31,16 +32,13 @@ PHLLS CLayerSurface::create(SP resource) { pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace); - pLS->alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE); - pLS->realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE); - pLS->realSize.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE); - pLS->alpha.registerVar(); - pLS->realPosition.registerVar(); - pLS->realSize.registerVar(); + g_pAnimationManager->createAnimation(0.f, pLS->alpha, g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realPosition, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realSize, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE); pLS->registerCallbacks(); - pLS->alpha.setValueAndWarp(0.f); + pLS->alpha->setValueAndWarp(0.f); Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName); @@ -48,7 +46,7 @@ PHLLS CLayerSurface::create(SP resource) { } void CLayerSurface::registerCallbacks() { - alpha.setUpdateCallback([this](void*) { + alpha->setUpdateCallback([this](auto) { if (dimAround) g_pHyprRenderer->damageMonitor(monitor.lock()); }); @@ -93,7 +91,7 @@ void CLayerSurface::onDestroy() { onUnmap(); } else { Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); - alpha.setValueAndWarp(0.f); + alpha->setValueAndWarp(0.f); fadingOut = true; g_pCompositor->addToFadingOutSafe(self.lock()); } @@ -307,17 +305,17 @@ void CLayerSurface::onCommit() { } } - if (realPosition.goal() != geometry.pos()) { - if (realPosition.isBeingAnimated()) - realPosition = geometry.pos(); + if (realPosition->goal() != geometry.pos()) { + if (realPosition->isBeingAnimated()) + *realPosition = geometry.pos(); else - realPosition.setValueAndWarp(geometry.pos()); + realPosition->setValueAndWarp(geometry.pos()); } - if (realSize.goal() != geometry.size()) { - if (realSize.isBeingAnimated()) - realSize = geometry.size(); + if (realSize->goal() != geometry.size()) { + if (realSize->isBeingAnimated()) + *realSize = geometry.size(); else - realSize.setValueAndWarp(geometry.size()); + realSize->setValueAndWarp(geometry.size()); } if (mapped && (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_INTERACTIVITY)) { @@ -434,17 +432,17 @@ void CLayerSurface::applyRules() { } void CLayerSurface::startAnimation(bool in, bool instant) { - const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle); if (in) { - realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn"); - realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn"); - alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"); + realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn")); + realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn")); + alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn")); } else { - realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut"); - realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut"); - alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"); + realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut")); + realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut")); + alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut")); } + const auto ANIMSTYLE = animationStyle.value_or(realPosition->getStyle()); if (ANIMSTYLE.starts_with("slide")) { // get closest edge const auto MIDDLE = geometry.middle(); @@ -485,9 +483,9 @@ void CLayerSurface::startAnimation(bool in, bool instant) { } } - realSize.setValueAndWarp(geometry.size()); - alpha.setValueAndWarp(in ? 0.f : 1.f); - alpha = in ? 1.f : 0.f; + realSize->setValueAndWarp(geometry.size()); + alpha->setValueAndWarp(in ? 0.f : 1.f); + *alpha = in ? 1.f : 0.f; Vector2D prePos; @@ -512,11 +510,11 @@ void CLayerSurface::startAnimation(bool in, bool instant) { } if (in) { - realPosition.setValueAndWarp(prePos); - realPosition = geometry.pos(); + realPosition->setValueAndWarp(prePos); + *realPosition = geometry.pos(); } else { - realPosition.setValueAndWarp(geometry.pos()); - realPosition = prePos; + realPosition->setValueAndWarp(geometry.pos()); + *realPosition = prePos; } } else if (ANIMSTYLE.starts_with("popin")) { @@ -535,25 +533,25 @@ void CLayerSurface::startAnimation(bool in, bool instant) { const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5}); const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f; - alpha.setValueAndWarp(in ? 0.f : 1.f); - alpha = in ? 1.f : 0.f; + alpha->setValueAndWarp(in ? 0.f : 1.f); + *alpha = in ? 1.f : 0.f; if (in) { - realSize.setValueAndWarp(GOALSIZE); - realPosition.setValueAndWarp(GOALPOS); - realSize = geometry.size(); - realPosition = geometry.pos(); + realSize->setValueAndWarp(GOALSIZE); + realPosition->setValueAndWarp(GOALPOS); + *realSize = geometry.size(); + *realPosition = geometry.pos(); } else { - realSize.setValueAndWarp(geometry.size()); - realPosition.setValueAndWarp(geometry.pos()); - realSize = GOALSIZE; - realPosition = GOALPOS; + realSize->setValueAndWarp(geometry.size()); + realPosition->setValueAndWarp(geometry.pos()); + *realSize = GOALSIZE; + *realPosition = GOALPOS; } } else { // fade - realPosition.setValueAndWarp(geometry.pos()); - realSize.setValueAndWarp(geometry.size()); - alpha = in ? 1.f : 0.f; + realPosition->setValueAndWarp(geometry.pos()); + realSize->setValueAndWarp(geometry.size()); + *alpha = in ? 1.f : 0.f; } if (!in) @@ -564,7 +562,7 @@ bool CLayerSurface::isFadedOut() { if (!fadingOut) return false; - return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated(); + return !realPosition->isBeingAnimated() && !realSize->isBeingAnimated() && !alpha->isBeingAnimated(); } int CLayerSurface::popupsCount() { diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index e906fc6f..3a03e57e 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -18,17 +18,17 @@ class CLayerSurface { public: ~CLayerSurface(); - void applyRules(); - void startAnimation(bool in, bool instant = false); - bool isFadedOut(); - int popupsCount(); + void applyRules(); + void startAnimation(bool in, bool instant = false); + bool isFadedOut(); + int popupsCount(); - CAnimatedVariable realPosition; - CAnimatedVariable realSize; - CAnimatedVariable alpha; + PHLANIMVAR realPosition; + PHLANIMVAR realSize; + PHLANIMVAR alpha; - WP layerSurface; - wl_list link; + WP layerSurface; + wl_list link; // the header providing the enum type cannot be imported here int interactivity = 0; diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 692a75e3..ce286b28 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -243,9 +243,9 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) { Vector2D CPopup::t1ParentCoords() { if (!m_pWindowOwner.expired()) - return m_pWindowOwner->m_vRealPosition.value(); + return m_pWindowOwner->m_vRealPosition->value(); if (!m_pLayerOwner.expired()) - return m_pLayerOwner->realPosition.value(); + return m_pLayerOwner->realPosition->value(); ASSERT(false); return {}; diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 893411bd..62854f80 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -169,7 +169,7 @@ Vector2D CSubsurface::coordsGlobal() { Vector2D coords = coordsRelativeToParent(); if (!m_pWindowParent.expired()) - coords += m_pWindowParent->m_vRealPosition.value(); + coords += m_pWindowParent->m_vRealPosition->value(); else if (m_pPopupParent) coords += m_pPopupParent->coordsGlobal(); diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 5e88f507..9ed8ec49 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -72,7 +72,7 @@ Vector2D CWLSurface::correctSmallVec() const { const auto SIZE = getViewporterCorrectedSize(); const auto O = m_pWindowOwner.lock(); - return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize.value() / O->m_vReportedSize); + return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize->value() / O->m_vReportedSize); } Vector2D CWLSurface::correctSmallVecBuf() const { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 60914198..8175fc57 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -11,12 +12,16 @@ #include "../render/decorations/CHyprBorderDecoration.hpp" #include "../config/ConfigValue.hpp" #include "../managers/TokenManager.hpp" +#include "../managers/AnimationManager.hpp" #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../xwayland/XWayland.hpp" +#include "../helpers/Color.hpp" #include + using namespace Hyprutils::String; +using namespace Hyprutils::Animation; PHLWINDOW CWindow::create(SP surface) { PHLWINDOW pWindow = SP(new CWindow(surface)); @@ -24,16 +29,16 @@ PHLWINDOW CWindow::create(SP surface) { pWindow->m_pSelf = pWindow; pWindow->m_bIsX11 = true; - pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER); - pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER); - pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); - pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fMovingFromWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealPosition, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealSize, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderFadeAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderAngleAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER); + g_pAnimationManager->createAnimation(1.f, pWindow->m_fAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(1.f, pWindow->m_fActiveInactiveAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(CHyprColor(), pWindow->m_cRealShadowColor, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fDimPercent, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(std::make_unique(pWindow)); pWindow->addWindowDeco(std::make_unique(pWindow)); @@ -47,16 +52,16 @@ PHLWINDOW CWindow::create(SP resource) { pWindow->m_pSelf = pWindow; resource->toplevel->window = pWindow; - pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER); - pWindow->m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER); - pWindow->m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); - pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->m_fMovingFromWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealPosition, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_vRealSize, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderFadeAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("border"), pWindow, AVARDAMAGE_BORDER); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fBorderAngleAnimationProgress, g_pConfigManager->getAnimationPropertyConfig("borderangle"), pWindow, AVARDAMAGE_BORDER); + g_pAnimationManager->createAnimation(1.f, pWindow->m_fAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(1.f, pWindow->m_fActiveInactiveAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(CHyprColor(), pWindow->m_cRealShadowColor, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fDimPercent, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(std::make_unique(pWindow)); pWindow->addWindowDeco(std::make_unique(pWindow)); @@ -118,8 +123,8 @@ SBoxExtents CWindow::getFullWindowExtents() { if (m_sWindowData.dimAround.valueOrDefault()) { if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) - return {{m_vRealPosition.value().x - PMONITOR->vecPosition.x, m_vRealPosition.value().y - PMONITOR->vecPosition.y}, - {PMONITOR->vecSize.x - (m_vRealPosition.value().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition.value().y - PMONITOR->vecPosition.y)}}; + return {{m_vRealPosition->value().x - PMONITOR->vecPosition.x, m_vRealPosition->value().y - PMONITOR->vecPosition.y}, + {PMONITOR->vecSize.x - (m_vRealPosition->value().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition->value().y - PMONITOR->vecPosition.y)}}; } SBoxExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}}; @@ -183,8 +188,8 @@ CBox CWindow::getFullWindowBoundingBox() { auto maxExtents = getFullWindowExtents(); - CBox finalBox = {m_vRealPosition.value().x - maxExtents.topLeft.x, m_vRealPosition.value().y - maxExtents.topLeft.y, - m_vRealSize.value().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize.value().y + maxExtents.topLeft.y + maxExtents.bottomRight.y}; + CBox finalBox = {m_vRealPosition->value().x - maxExtents.topLeft.x, m_vRealPosition->value().y - maxExtents.topLeft.y, + m_vRealSize->value().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize->value().y + maxExtents.topLeft.y + maxExtents.bottomRight.y}; return finalBox; } @@ -238,7 +243,7 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) { if (properties & FULL_EXTENTS) EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(m_pSelf.lock(), false)); - CBox box = {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y}; + CBox box = {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y}; box.addExtents(EXTENTS); return box; @@ -409,9 +414,9 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { const auto OLDWORKSPACE = m_pWorkspace; m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; - m_fMovingToWorkspaceAlpha.setValueAndWarp(1.F); - m_fMovingToWorkspaceAlpha = 0.F; - m_fMovingToWorkspaceAlpha.setCallbackOnEnd([this](void* thisptr) { m_iMonitorMovedFrom = -1; }); + m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); + m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F); + *m_fMovingToWorkspaceAlpha = 0.F; m_pWorkspace = pWorkspace; @@ -439,7 +444,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { } // update xwayland coords - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.value()); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize->value()); if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && OLDWORKSPACE->getWindows() == 0 && *PCLOSEONLASTSPECIAL) { if (const auto PMONITOR = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR) @@ -475,10 +480,6 @@ PHLWINDOW CWindow::x11TransientFor() { return nullptr; } -static void unregisterVar(void* ptr) { - ((CBaseAnimatedVariable*)ptr)->unregister(); -} - void CWindow::onUnmap() { static auto PCLOSEONLASTSPECIAL = CConfigValue("misc:close_special_on_empty"); static auto PINITIALWSTRACKING = CConfigValue("misc:initial_workspace_tracking"); @@ -497,19 +498,6 @@ void CWindow::onUnmap() { m_iLastWorkspace = m_pWorkspace->m_iID; - m_vRealPosition.setCallbackOnEnd(unregisterVar); - m_vRealSize.setCallbackOnEnd(unregisterVar); - m_fBorderFadeAnimationProgress.setCallbackOnEnd(unregisterVar); - m_fBorderAngleAnimationProgress.setCallbackOnEnd(unregisterVar); - m_fActiveInactiveAlpha.setCallbackOnEnd(unregisterVar); - m_fAlpha.setCallbackOnEnd(unregisterVar); - m_cRealShadowColor.setCallbackOnEnd(unregisterVar); - m_fDimPercent.setCallbackOnEnd(unregisterVar); - m_fMovingToWorkspaceAlpha.setCallbackOnEnd(unregisterVar); - m_fMovingFromWorkspaceAlpha.setCallbackOnEnd(unregisterVar); - - m_vRealSize.setCallbackOnBegin(nullptr); - std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other.expired() || other.lock().get() == this; }); if (*PCLOSEONLASTSPECIAL && m_pWorkspace && m_pWorkspace->getWindows() == 0 && onSpecialWorkspace()) { @@ -541,34 +529,24 @@ void CWindow::onUnmap() { void CWindow::onMap() { // JIC, reset the callbacks. If any are set, we'll make sure they are cleared so we don't accidentally unset them. (In case a window got remapped) - m_vRealPosition.resetAllCallbacks(); - m_vRealSize.resetAllCallbacks(); - m_fBorderFadeAnimationProgress.resetAllCallbacks(); - m_fBorderAngleAnimationProgress.resetAllCallbacks(); - m_fActiveInactiveAlpha.resetAllCallbacks(); - m_fAlpha.resetAllCallbacks(); - m_cRealShadowColor.resetAllCallbacks(); - m_fDimPercent.resetAllCallbacks(); - m_fMovingToWorkspaceAlpha.resetAllCallbacks(); - m_fMovingFromWorkspaceAlpha.resetAllCallbacks(); + m_vRealPosition->resetAllCallbacks(); + m_vRealSize->resetAllCallbacks(); + m_fBorderFadeAnimationProgress->resetAllCallbacks(); + m_fBorderAngleAnimationProgress->resetAllCallbacks(); + m_fActiveInactiveAlpha->resetAllCallbacks(); + m_fAlpha->resetAllCallbacks(); + m_cRealShadowColor->resetAllCallbacks(); + m_fDimPercent->resetAllCallbacks(); + m_fMovingToWorkspaceAlpha->resetAllCallbacks(); + m_fMovingFromWorkspaceAlpha->resetAllCallbacks(); - m_vRealPosition.registerVar(); - m_vRealSize.registerVar(); - m_fBorderFadeAnimationProgress.registerVar(); - m_fBorderAngleAnimationProgress.registerVar(); - m_fActiveInactiveAlpha.registerVar(); - m_fAlpha.registerVar(); - m_cRealShadowColor.registerVar(); - m_fDimPercent.registerVar(); - m_fMovingToWorkspaceAlpha.registerVar(); - m_fMovingFromWorkspaceAlpha.registerVar(); + m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); + m_fBorderAngleAnimationProgress->setCallbackOnEnd([&](WP p) { onBorderAngleAnimEnd(p); }, false); - m_fBorderAngleAnimationProgress.setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false); + m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); + *m_fBorderAngleAnimationProgress = 1.f; - m_fBorderAngleAnimationProgress.setValueAndWarp(0.f); - m_fBorderAngleAnimationProgress = 1.f; - - m_fMovingFromWorkspaceAlpha.setValueAndWarp(1.F); + m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf); @@ -584,20 +562,22 @@ void CWindow::onMap() { m_pPopupHead = std::make_unique(m_pSelf.lock()); } -void CWindow::onBorderAngleAnimEnd(void* ptr) { - const auto PANIMVAR = (CAnimatedVariable*)ptr; - - const std::string STYLE = PANIMVAR->getConfig()->pValues->internalStyle; - - if (STYLE != "loop" || !PANIMVAR->getConfig()->pValues->internalEnabled) +void CWindow::onBorderAngleAnimEnd(WP pav) { + const auto PAV = pav.lock(); + if (!PAV) return; + if (PAV->getStyle() != "loop" || !PAV->enabled()) + return; + + const auto PANIMVAR = dynamic_cast*>(PAV.get()); + PANIMVAR->setCallbackOnEnd(nullptr); // we remove the callback here because otherwise setvalueandwarp will recurse this PANIMVAR->setValueAndWarp(0); *PANIMVAR = 1.f; - PANIMVAR->setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false); + PANIMVAR->setCallbackOnEnd([&](WP pav) { onBorderAngleAnimEnd(pav); }, false); } void CWindow::setHidden(bool hidden) { @@ -830,10 +810,10 @@ bool CWindow::isInCurvedCorner(double x, double y) { return false; // (x0, y0), (x0, y1), ... are the center point of rounding at each corner - double x0 = m_vRealPosition.value().x + ROUNDING; - double y0 = m_vRealPosition.value().y + ROUNDING; - double x1 = m_vRealPosition.value().x + m_vRealSize.value().x - ROUNDING; - double y1 = m_vRealPosition.value().y + m_vRealSize.value().y - ROUNDING; + double x0 = m_vRealPosition->value().x + ROUNDING; + double y0 = m_vRealPosition->value().y + ROUNDING; + double x1 = m_vRealPosition->value().x + m_vRealSize->value().x - ROUNDING; + double y1 = m_vRealPosition->value().y + m_vRealSize->value().y - ROUNDING; if (x < x0 && y < y0) { return std::pow(x0 - x, ROUNDINGPOWER) + std::pow(y0 - y, ROUNDINGPOWER) > std::pow((double)ROUNDING, ROUNDINGPOWER); @@ -1032,8 +1012,8 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) { if (FULLSCREEN) g_pCompositor->setWindowFullscreenInternal(PCURRENT, FSMODE_NONE); - const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal(); - const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal(); + const auto PWINDOWSIZE = PCURRENT->m_vRealSize->goal(); + const auto PWINDOWPOS = PCURRENT->m_vRealPosition->goal(); PCURRENT->setHidden(true); pWindow->setHidden(false); // can remove m_pLastWindow @@ -1041,8 +1021,8 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) { g_pLayoutManager->getCurrentLayout()->replaceWindowDataWith(PCURRENT, pWindow); if (PCURRENT->m_bIsFloating) { - pWindow->m_vRealPosition.setValueAndWarp(PWINDOWPOS); - pWindow->m_vRealSize.setValueAndWarp(PWINDOWSIZE); + pWindow->m_vRealPosition->setValueAndWarp(PWINDOWPOS); + pWindow->m_vRealSize->setValueAndWarp(PWINDOWSIZE); } g_pCompositor->updateAllWindowsAnimatedDecorationValues(); @@ -1124,22 +1104,22 @@ void CWindow::updateGroupOutputs() { curr->m_pMonitor = m_pMonitor; curr->moveToWorkspace(WS); - curr->m_vRealPosition = m_vRealPosition.goal(); - curr->m_vRealSize = m_vRealSize.goal(); + *curr->m_vRealPosition = m_vRealPosition->goal(); + *curr->m_vRealSize = m_vRealSize->goal(); curr = curr->m_sGroupData.pNextWindow.lock(); } } Vector2D CWindow::middle() { - return m_vRealPosition.goal() + m_vRealSize.goal() / 2.f; + return m_vRealPosition->goal() + m_vRealSize->goal() / 2.f; } bool CWindow::opaque() { - if (m_fAlpha.value() != 1.f || m_fActiveInactiveAlpha.value() != 1.f) + if (m_fAlpha->value() != 1.f || m_fActiveInactiveAlpha->value() != 1.f) return false; - if (m_vRealSize.goal().floor() != m_vReportedSize) + if (m_vRealSize->goal().floor() != m_vReportedSize) return false; const auto PWORKSPACE = m_pWorkspace; @@ -1147,7 +1127,7 @@ bool CWindow::opaque() { if (m_pWLSurface->small() && !m_pWLSurface->m_bFillIgnoreSmall) return false; - if (PWORKSPACE->m_fAlpha.value() != 1.f) + if (PWORKSPACE->m_fAlpha->value() != 1.f) return false; if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface && m_pXWaylandSurface->surface->current.texture) @@ -1237,15 +1217,13 @@ void CWindow::setSuspended(bool suspend) { } bool CWindow::visibleOnMonitor(PHLMONITOR pMonitor) { - CBox wbox = {m_vRealPosition.value(), m_vRealSize.value()}; + CBox wbox = {m_vRealPosition->value(), m_vRealSize->value()}; return !wbox.intersection({pMonitor->vecPosition, pMonitor->vecSize}).empty(); } void CWindow::setAnimationsToMove() { - auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove"); - m_vRealPosition.setConfig(PANIMCFG); - m_vRealSize.setConfig(PANIMCFG); + m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove")); m_bAnimatingIn = false; } @@ -1266,16 +1244,16 @@ void CWindow::onWorkspaceAnimUpdate() { return; const auto WINBB = getFullWindowBoundingBox(); - if (PWORKSPACE->m_vRenderOffset.value().x != 0) { - const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().x / PWSMON->vecSize.x; + if (PWORKSPACE->m_vRenderOffset->value().x != 0) { + const auto PROGRESS = PWORKSPACE->m_vRenderOffset->value().x / PWSMON->vecSize.x; if (WINBB.x < PWSMON->vecPosition.x) offset.x += (PWSMON->vecPosition.x - WINBB.x) * PROGRESS; if (WINBB.x + WINBB.width > PWSMON->vecPosition.x + PWSMON->vecSize.x) offset.x += (WINBB.x + WINBB.width - PWSMON->vecPosition.x - PWSMON->vecSize.x) * PROGRESS; - } else if (PWORKSPACE->m_vRenderOffset.value().y != 0) { - const auto PROGRESS = PWORKSPACE->m_vRenderOffset.value().y / PWSMON->vecSize.y; + } else if (PWORKSPACE->m_vRenderOffset->value().y != 0) { + const auto PROGRESS = PWORKSPACE->m_vRenderOffset->value().y / PWSMON->vecSize.y; if (WINBB.y < PWSMON->vecPosition.y) offset.y += (PWSMON->vecPosition.y - WINBB.y) * PROGRESS; @@ -1306,12 +1284,12 @@ int CWindow::surfacesCount() { } void CWindow::clampWindowSize(const std::optional minSize, const std::optional maxSize) { - const Vector2D REALSIZE = m_vRealSize.goal(); + const Vector2D REALSIZE = m_vRealSize->goal(); const Vector2D NEWSIZE = REALSIZE.clamp(minSize.value_or(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), maxSize.value_or(Vector2D{INFINITY, INFINITY})); const Vector2D DELTA = REALSIZE - NEWSIZE; - m_vRealPosition = m_vRealPosition.goal() + DELTA / 2.0; - m_vRealSize = NEWSIZE; + *m_vRealPosition = m_vRealPosition->goal() + DELTA / 2.0; + *m_vRealSize = NEWSIZE; g_pXWaylandManager->setWindowSize(m_pSelf.lock(), NEWSIZE); } @@ -1525,7 +1503,7 @@ void CWindow::onX11Configure(CBox box) { g_pHyprRenderer->damageWindow(m_pSelf.lock()); if (!m_bIsFloating || isFullscreen() || g_pInputManager->currentlyDraggedWindow == m_pSelf) { - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal(), true); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize->goal(), true); g_pInputManager->refocus(); g_pHyprRenderer->damageWindow(m_pSelf.lock()); return; @@ -1538,19 +1516,19 @@ void CWindow::onX11Configure(CBox box) { const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(box.pos()); - m_vRealPosition.setValueAndWarp(LOGICALPOS); - m_vRealSize.setValueAndWarp(box.size()); + m_vRealPosition->setValueAndWarp(LOGICALPOS); + m_vRealSize->setValueAndWarp(box.size()); static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); if (*PXWLFORCESCALEZERO) { if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) { - m_vRealSize.setValueAndWarp(m_vRealSize.goal() / PMONITOR->scale); + m_vRealSize->setValueAndWarp(m_vRealSize->goal() / PMONITOR->scale); m_fX11SurfaceScaledBy = PMONITOR->scale; } } - m_vPosition = m_vRealPosition.value(); - m_vSize = m_vRealSize.value(); + m_vPosition = m_vRealPosition->value(); + m_vSize = m_vRealSize->value(); m_pXWaylandSurface->configure(box); @@ -1562,7 +1540,7 @@ void CWindow::onX11Configure(CBox box) { if (!m_pWorkspace || !m_pWorkspace->isVisible()) return; // further things are only for visible windows - m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition.value() + m_vRealSize.value() / 2.f)->activeWorkspace; + m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition->value() + m_vRealSize->value() / 2.f)->activeWorkspace; g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true); diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 3ceaf594..37189a00 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -233,8 +233,8 @@ class CWindow { Vector2D m_vSize = Vector2D(0, 0); // this is the real position and size used to draw the thing - CAnimatedVariable m_vRealPosition; - CAnimatedVariable m_vRealSize; + PHLANIMVAR m_vRealPosition; + PHLANIMVAR m_vRealSize; // for not spamming the protocols Vector2D m_vReportedPosition; @@ -298,19 +298,19 @@ class CWindow { std::unique_ptr m_pPopupHead; // Animated border - CGradientValueData m_cRealBorderColor = {0}; - CGradientValueData m_cRealBorderColorPrevious = {0}; - CAnimatedVariable m_fBorderFadeAnimationProgress; - CAnimatedVariable m_fBorderAngleAnimationProgress; + CGradientValueData m_cRealBorderColor = {0}; + CGradientValueData m_cRealBorderColorPrevious = {0}; + PHLANIMVAR m_fBorderFadeAnimationProgress; + PHLANIMVAR m_fBorderAngleAnimationProgress; // Fade in-out - CAnimatedVariable m_fAlpha; - bool m_bFadingOut = false; - bool m_bReadyToDelete = false; - Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in - Vector2D m_vOriginalClosedSize; // drawing the closing animations - SBoxExtents m_eOriginalClosedExtents; - bool m_bAnimatingIn = false; + PHLANIMVAR m_fAlpha; + bool m_bFadingOut = false; + bool m_bReadyToDelete = false; + Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in + Vector2D m_vOriginalClosedSize; // drawing the closing animations + SBoxExtents m_eOriginalClosedExtents; + bool m_bAnimatingIn = false; // For pinned (sticky) windows bool m_bPinned = false; @@ -336,18 +336,18 @@ class CWindow { std::vector> m_vTransformers; // for alpha - CAnimatedVariable m_fActiveInactiveAlpha; - CAnimatedVariable m_fMovingFromWorkspaceAlpha; + PHLANIMVAR m_fActiveInactiveAlpha; + PHLANIMVAR m_fMovingFromWorkspaceAlpha; // animated shadow color - CAnimatedVariable m_cRealShadowColor; + PHLANIMVAR m_cRealShadowColor; // animated tint - CAnimatedVariable m_fDimPercent; + PHLANIMVAR m_fDimPercent; // animate moving to an invisible workspace - int m_iMonitorMovedFrom = -1; // -1 means not moving - CAnimatedVariable m_fMovingToWorkspaceAlpha; + int m_iMonitorMovedFrom = -1; // -1 means not moving + PHLANIMVAR m_fMovingToWorkspaceAlpha; // swallowing PHLWINDOWREF m_pSwallowed; @@ -432,7 +432,7 @@ class CWindow { float getScrollTouchpad(); void updateWindowData(); void updateWindowData(const struct SWorkspaceRule&); - void onBorderAngleAnimEnd(void* ptr); + void onBorderAngleAnimEnd(WP pav); bool isInCurvedCorner(double x, double y); bool hasPopupAt(const Vector2D& pos); int popupsCount(); @@ -467,7 +467,7 @@ class CWindow { Vector2D requestedMaxSize(); CBox getWindowMainSurfaceBox() const { - return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y}; + return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y}; } // listeners diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 0930ef00..cab19254 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -1,7 +1,10 @@ #include "Workspace.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "config/ConfigManager.hpp" +#include "managers/AnimationManager.hpp" +#include #include using namespace Hyprutils::String; @@ -19,16 +22,10 @@ CWorkspace::CWorkspace(WORKSPACEID id, PHLMONITOR monitor, std::string name, boo void CWorkspace::init(PHLWORKSPACE self) { m_pSelf = self; - m_vRenderOffset.create(m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn") : - g_pConfigManager->getAnimationPropertyConfig("workspacesIn"), - self, AVARDAMAGE_ENTIRE); - m_fAlpha.create(AVARTYPE_FLOAT, - m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn") : g_pConfigManager->getAnimationPropertyConfig("workspacesIn"), self, - AVARDAMAGE_ENTIRE); - m_fAlpha.setValueAndWarp(1.f); - - m_vRenderOffset.registerVar(); - m_fAlpha.registerVar(); + g_pAnimationManager->createAnimation(Vector2D(0, 0), m_vRenderOffset, + g_pConfigManager->getAnimationPropertyConfig(m_bIsSpecialWorkspace ? "specialWorkspaceIn" : "workspacesIn"), self, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(1.f, m_fAlpha, g_pConfigManager->getAnimationPropertyConfig(m_bIsSpecialWorkspace ? "specialWorkspaceIn" : "workspacesIn"), self, + AVARDAMAGE_ENTIRE); const auto RULEFORTHIS = g_pConfigManager->getWorkspaceRuleFor(self); if (RULEFORTHIS.defaultName.has_value()) @@ -63,8 +60,6 @@ SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName(bool perMonitor) const { } CWorkspace::~CWorkspace() { - m_vRenderOffset.unregister(); - Debug::log(LOG, "Destroying workspace ID {}", m_iID); // check if g_pHookSystem and g_pEventManager exist, they might be destroyed as in when the compositor is closing. @@ -82,15 +77,15 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { if (!instant) { const std::string ANIMNAME = std::format("{}{}", m_bIsSpecialWorkspace ? "specialWorkspace" : "workspaces", in ? "In" : "Out"); - m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig(ANIMNAME); - m_vRenderOffset.m_pConfig = g_pConfigManager->getAnimationPropertyConfig(ANIMNAME); + m_fAlpha->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME)); + m_vRenderOffset->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME)); } - const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle; + const auto ANIMSTYLE = m_fAlpha->getStyle(); static auto PWORKSPACEGAP = CConfigValue("general:gaps_workspaces"); // set floating windows offset callbacks - m_vRenderOffset.setUpdateCallback([&](void*) { + m_vRenderOffset->setUpdateCallback([&](auto) { for (auto const& w : g_pCompositor->m_vWindows) { if (!validMapped(w) || w->workspaceID() != m_iID) continue; @@ -110,84 +105,84 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) { } catch (std::exception& e) { Debug::log(ERR, "Error in startAnim: invalid percentage"); } } - m_fAlpha.setValueAndWarp(1.f); - m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); + m_fAlpha->setValueAndWarp(1.f); + m_vRenderOffset->setValueAndWarp(Vector2D(0, 0)); if (ANIMSTYLE.starts_with("slidefadevert")) { if (in) { - m_fAlpha.setValueAndWarp(0.f); - m_vRenderOffset.setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->vecSize.y : -PMONITOR->vecSize.y) * (movePerc / 100.f))); - m_fAlpha = 1.f; - m_vRenderOffset = Vector2D(0, 0); + m_fAlpha->setValueAndWarp(0.f); + m_vRenderOffset->setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->vecSize.y : -PMONITOR->vecSize.y) * (movePerc / 100.f))); + *m_fAlpha = 1.f; + *m_vRenderOffset = Vector2D(0, 0); } else { - m_fAlpha.setValueAndWarp(1.f); - m_fAlpha = 0.f; - m_vRenderOffset = Vector2D(0.0, (left ? -PMONITOR->vecSize.y : PMONITOR->vecSize.y) * (movePerc / 100.f)); + m_fAlpha->setValueAndWarp(1.f); + *m_fAlpha = 0.f; + *m_vRenderOffset = Vector2D(0.0, (left ? -PMONITOR->vecSize.y : PMONITOR->vecSize.y) * (movePerc / 100.f)); } } else { if (in) { - m_fAlpha.setValueAndWarp(0.f); - m_vRenderOffset.setValueAndWarp(Vector2D((left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0)); - m_fAlpha = 1.f; - m_vRenderOffset = Vector2D(0, 0); + m_fAlpha->setValueAndWarp(0.f); + m_vRenderOffset->setValueAndWarp(Vector2D((left ? PMONITOR->vecSize.x : -PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0)); + *m_fAlpha = 1.f; + *m_vRenderOffset = Vector2D(0, 0); } else { - m_fAlpha.setValueAndWarp(1.f); - m_fAlpha = 0.f; - m_vRenderOffset = Vector2D((left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0); + m_fAlpha->setValueAndWarp(1.f); + *m_fAlpha = 0.f; + *m_vRenderOffset = Vector2D((left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x) * (movePerc / 100.f), 0.0); } } } else if (ANIMSTYLE == "fade") { - m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade. + m_vRenderOffset->setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade. if (in) { - m_fAlpha.setValueAndWarp(0.f); - m_fAlpha = 1.f; + m_fAlpha->setValueAndWarp(0.f); + *m_fAlpha = 1.f; } else { - m_fAlpha.setValueAndWarp(1.f); - m_fAlpha = 0.f; + m_fAlpha->setValueAndWarp(1.f); + *m_fAlpha = 0.f; } } else if (ANIMSTYLE == "slidevert") { // fallback is slide const auto PMONITOR = m_pMonitor.lock(); const auto YDISTANCE = PMONITOR->vecSize.y + *PWORKSPACEGAP; - m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. + m_fAlpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. if (in) { - m_vRenderOffset.setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE)); - m_vRenderOffset = Vector2D(0, 0); + m_vRenderOffset->setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE)); + *m_vRenderOffset = Vector2D(0, 0); } else { - m_vRenderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE); + *m_vRenderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE); } } else { // fallback is slide const auto PMONITOR = m_pMonitor.lock(); const auto XDISTANCE = PMONITOR->vecSize.x + *PWORKSPACEGAP; - m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. + m_fAlpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. if (in) { - m_vRenderOffset.setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0)); - m_vRenderOffset = Vector2D(0, 0); + m_vRenderOffset->setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0)); + *m_vRenderOffset = Vector2D(0, 0); } else { - m_vRenderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0); + *m_vRenderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0); } } if (m_bIsSpecialWorkspace) { // required for open/close animations if (in) { - m_fAlpha.setValueAndWarp(0.f); - m_fAlpha = 1.f; + m_fAlpha->setValueAndWarp(0.f); + *m_fAlpha = 1.f; } else { - m_fAlpha.setValueAndWarp(1.f); - m_fAlpha = 0.f; + m_fAlpha->setValueAndWarp(1.f); + *m_fAlpha = 0.f; } } if (instant) { - m_vRenderOffset.warp(); - m_fAlpha.warp(); + m_vRenderOffset->warp(); + m_fAlpha->warp(); } } @@ -633,7 +628,7 @@ void CWorkspace::forceReportSizesToWindows() { if (w->m_pWorkspace != m_pSelf || !w->m_bIsMapped || w->isHidden()) continue; - g_pXWaylandManager->setWindowSize(w, w->m_vRealSize.value(), true); + g_pXWaylandManager->setWindowSize(w, w->m_vRealSize->value(), true); } } diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index 606485a2..f86dd656 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -37,9 +37,9 @@ class CWorkspace { wl_array m_wlrCoordinateArr; // for animations - CAnimatedVariable m_vRenderOffset; - CAnimatedVariable m_fAlpha; - bool m_bForceRendering = false; + PHLANIMVAR m_vRenderOffset; + PHLANIMVAR m_fAlpha; + bool m_bForceRendering = false; // allows damage to propagate. bool m_bVisible = false; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index a20cbcad..8082cdc9 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -12,10 +12,12 @@ #include "../protocols/core/Compositor.hpp" #include "../protocols/ToplevelExport.hpp" #include "../xwayland/XSurface.hpp" +#include "managers/AnimationManager.hpp" #include "managers/PointerManager.hpp" #include using namespace Hyprutils::String; +using namespace Hyprutils::Animation; // ------------------------------------------------------------ // // __ _______ _ _ _____ ______ _______ // @@ -27,15 +29,17 @@ using namespace Hyprutils::String; // // // ------------------------------------------------------------ // -static void setAnimToMove(void* data) { - auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove"); +static void setVector2DAnimToMove(WP pav) { + const auto PAV = pav.lock(); + if (!PAV) + return; - CBaseAnimatedVariable* animvar = (CBaseAnimatedVariable*)data; + CAnimatedVariable* animvar = dynamic_cast*>(PAV.get()); + animvar->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove")); - animvar->setConfig(PANIMCFG); - - if (animvar->getWindow() && !animvar->getWindow()->m_vRealPosition.isBeingAnimated() && !animvar->getWindow()->m_vRealSize.isBeingAnimated()) - animvar->getWindow()->m_bAnimatingIn = false; + const auto PHLWINDOW = animvar->m_Context.pWindow.lock(); + if (PHLWINDOW && PHLWINDOW->m_vRealPosition->isBeingAnimated() && PHLWINDOW->m_vRealSize->isBeingAnimated()) + PHLWINDOW->m_bAnimatingIn = false; } void Events::listener_mapWindow(void* owner, void* data) { @@ -378,10 +382,10 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto MAXSIZE = PWINDOW->requestedMaxSize(); const float SIZEX = SIZEXSTR == "max" ? std::clamp(MAXSIZE.x, MIN_WINDOW_SIZE, PMONITOR->vecSize.x) : - stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize.goal().x, PMONITOR->vecSize.x); + stringToFloatClamp(SIZEXSTR, PWINDOW->m_vRealSize->goal().x, PMONITOR->vecSize.x); const float SIZEY = SIZEYSTR == "max" ? std::clamp(MAXSIZE.y, MIN_WINDOW_SIZE, PMONITOR->vecSize.y) : - stringToFloatClamp(SIZEYSTR, PWINDOW->m_vRealSize.goal().y, PMONITOR->vecSize.y); + stringToFloatClamp(SIZEYSTR, PWINDOW->m_vRealSize->goal().y, PMONITOR->vecSize.y); Debug::log(LOG, "Rule size, applying to {}", PWINDOW); @@ -418,7 +422,7 @@ void Events::listener_mapWindow(void* owner, void* data) { (!POSXRAW.contains('%') ? std::stoi(POSXRAW) : std::stof(POSXRAW.substr(0, POSXRAW.length() - 1)) * 0.01 * PMONITOR->vecSize.x); if (subtractWindow) - posX -= PWINDOW->m_vRealSize.goal().x; + posX -= PWINDOW->m_vRealSize->goal().x; if (CURSOR) Debug::log(ERR, "Cursor is not compatible with 100%-, ignoring cursor!"); @@ -430,7 +434,7 @@ void Events::listener_mapWindow(void* owner, void* data) { posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x; } else { posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x + - (!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stof(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goal().x); + (!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stof(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize->goal().x); } } @@ -441,7 +445,7 @@ void Events::listener_mapWindow(void* owner, void* data) { (!POSYRAW.contains('%') ? std::stoi(POSYRAW) : std::stof(POSYRAW.substr(0, POSYRAW.length() - 1)) * 0.01 * PMONITOR->vecSize.y); if (subtractWindow) - posY -= PWINDOW->m_vRealSize.goal().y; + posY -= PWINDOW->m_vRealSize->goal().y; if (CURSOR) Debug::log(ERR, "Cursor is not compatible with 100%-, ignoring cursor!"); @@ -453,7 +457,7 @@ void Events::listener_mapWindow(void* owner, void* data) { posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y; } else { posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y + - (!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stof(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goal().y); + (!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stof(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize->goal().y); } } @@ -461,15 +465,15 @@ void Events::listener_mapWindow(void* owner, void* data) { int borderSize = PWINDOW->getRealBorderSize(); posX = std::clamp(posX, (int)(PMONITOR->vecReservedTopLeft.x + borderSize), - (int)(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PWINDOW->m_vRealSize.goal().x - borderSize)); + (int)(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PWINDOW->m_vRealSize->goal().x - borderSize)); posY = std::clamp(posY, (int)(PMONITOR->vecReservedTopLeft.y + borderSize), - (int)(PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PWINDOW->m_vRealSize.goal().y - borderSize)); + (int)(PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PWINDOW->m_vRealSize->goal().y - borderSize)); } Debug::log(LOG, "Rule move, applying to {}", PWINDOW); - PWINDOW->m_vRealPosition = Vector2D(posX, posY) + PMONITOR->vecPosition; + *PWINDOW->m_vRealPosition = Vector2D(posX, posY) + PMONITOR->vecPosition; PWINDOW->setHidden(false); } catch (...) { Debug::log(LOG, "Rule move failed, rule: {} -> {}", r->szRule, r->szValue); } @@ -481,7 +485,7 @@ void Events::listener_mapWindow(void* owner, void* data) { if (ARGS[1] == "1") RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f; - PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goal() / 2.f + RESERVEDOFFSET; + *PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize->goal() / 2.f + RESERVEDOFFSET; break; } @@ -491,7 +495,7 @@ void Events::listener_mapWindow(void* owner, void* data) { // set the pseudo size to the GOAL of our current size // because the windows are animated on RealSize - PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal(); + PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize->goal(); g_pCompositor->changeWindowZOrder(PWINDOW, true); } else { @@ -524,7 +528,7 @@ void Events::listener_mapWindow(void* owner, void* data) { } if (!setPseudo) - PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal() - Vector2D(10, 10); + PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize->goal() - Vector2D(10, 10); } const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow.lock(); @@ -554,11 +558,11 @@ void Events::listener_mapWindow(void* owner, void* data) { (!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) && !g_pInputManager->isConstrained()) { g_pCompositor->focusWindow(PWINDOW); - PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA); - PWINDOW->m_fDimPercent.setValueAndWarp(PWINDOW->m_sWindowData.noDim.valueOrDefault() ? 0.f : *PDIMSTRENGTH); + PWINDOW->m_fActiveInactiveAlpha->setValueAndWarp(*PACTIVEALPHA); + PWINDOW->m_fDimPercent->setValueAndWarp(PWINDOW->m_sWindowData.noDim.valueOrDefault() ? 0.f : *PDIMSTRENGTH); } else { - PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA); - PWINDOW->m_fDimPercent.setValueAndWarp(0); + PWINDOW->m_fActiveInactiveAlpha->setValueAndWarp(*PINACTIVEALPHA); + PWINDOW->m_fDimPercent->setValueAndWarp(0); } if (requestedClientFSMode.has_value() && (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) @@ -571,8 +575,8 @@ void Events::listener_mapWindow(void* owner, void* data) { if (PWINDOW->m_pWorkspace->m_bHasFullscreenWindow) g_pCompositor->setWindowFullscreenInternal(PWINDOW->m_pWorkspace->getFullscreenWindow(), FSMODE_NONE); - PWINDOW->m_vRealPosition.warp(); - PWINDOW->m_vRealSize.warp(); + PWINDOW->m_vRealPosition->warp(); + PWINDOW->m_vRealSize->warp(); if (requestedFSState.has_value()) { PWINDOW->m_sWindowData.syncFullscreen = CWindowOverridableVar(false, PRIORITY_WINDOW_RULE); g_pCompositor->setWindowFullscreenState(PWINDOW, requestedFSState.value()); @@ -607,7 +611,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_bFirstMap = false; - Debug::log(LOG, "Map request dispatched, monitor {}, window pos: {:5j}, window size: {:5j}", PMONITOR->szName, PWINDOW->m_vRealPosition.goal(), PWINDOW->m_vRealSize.goal()); + Debug::log(LOG, "Map request dispatched, monitor {}, window pos: {:5j}, window size: {:5j}", PMONITOR->szName, PWINDOW->m_vRealPosition->goal(), PWINDOW->m_vRealSize->goal()); auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName; g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", PWINDOW, workspaceID, PWINDOW->m_szClass, PWINDOW->m_szTitle)}); @@ -620,17 +624,17 @@ void Events::listener_mapWindow(void* owner, void* data) { // do animations g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false); - PWINDOW->m_fAlpha.setValueAndWarp(0.f); - PWINDOW->m_fAlpha = 1.f; + PWINDOW->m_fAlpha->setValueAndWarp(0.f); + *PWINDOW->m_fAlpha = 1.f; - PWINDOW->m_vRealPosition.setCallbackOnEnd(setAnimToMove); - PWINDOW->m_vRealSize.setCallbackOnEnd(setAnimToMove); + PWINDOW->m_vRealPosition->setCallbackOnEnd(setVector2DAnimToMove); + PWINDOW->m_vRealSize->setCallbackOnEnd(setVector2DAnimToMove); // recalc the values for this window g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW); // avoid this window being visible if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->isFullscreen() && !PWINDOW->m_bIsFloating) - PWINDOW->m_fAlpha.setValueAndWarp(0.f); + PWINDOW->m_fAlpha->setValueAndWarp(0.f); g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->scale); g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->transform); @@ -666,8 +670,8 @@ void Events::listener_unmapWindow(void* owner, void* data) { const auto PMONITOR = PWINDOW->m_pMonitor.lock(); if (PMONITOR) { - PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.value() - PMONITOR->vecPosition; - PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.value(); + PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition->value() - PMONITOR->vecPosition; + PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize->value(); PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents(); } @@ -757,12 +761,12 @@ void Events::listener_unmapWindow(void* owner, void* data) { g_pCompositor->addToFadingOutSafe(PWINDOW); - if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in. - PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it + if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in. + *PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition->value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it // anims g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true); - PWINDOW->m_fAlpha = 0.f; + *PWINDOW->m_fAlpha = 0.f; // recheck idle inhibitors g_pInputManager->recheckIdleInhibitorStatus(); @@ -812,7 +816,7 @@ void Events::listener_commitWindow(void* owner, void* data) { g_pSeatManager->isPointerFrameSkipped = false; g_pSeatManager->isPointerFrameCommit = false; } else - g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y, + g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition->goal().x, PWINDOW->m_vRealPosition->goal().y, PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0); if (g_pSeatManager->isPointerFrameSkipped) { @@ -903,8 +907,8 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { if (!PWINDOW->m_bIsMapped || !PWINDOW->m_pXWaylandSurface || !PWINDOW->m_pXWaylandSurface->overrideRedirect) return; - const auto POS = PWINDOW->m_vRealPosition.goal(); - const auto SIZ = PWINDOW->m_vRealSize.goal(); + const auto POS = PWINDOW->m_vRealPosition->goal(); + const auto SIZ = PWINDOW->m_vRealSize->goal(); if (PWINDOW->m_pXWaylandSurface->geometry.size() > Vector2D{1, 1}) PWINDOW->setHidden(false); @@ -912,7 +916,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { PWINDOW->setHidden(true); if (PWINDOW->isFullscreen() || !PWINDOW->m_bIsFloating) { - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal(), true); + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize->goal(), true); g_pHyprRenderer->damageWindow(PWINDOW); return; } @@ -926,27 +930,27 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { Debug::log(LOG, "Unmanaged window {} requests geometry update to {:j} {:j}", PWINDOW, LOGICALPOS, PWINDOW->m_pXWaylandSurface->geometry.size()); g_pHyprRenderer->damageWindow(PWINDOW); - PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(LOGICALPOS.x, LOGICALPOS.y)); + PWINDOW->m_vRealPosition->setValueAndWarp(Vector2D(LOGICALPOS.x, LOGICALPOS.y)); if (abs(std::floor(SIZ.x) - PWINDOW->m_pXWaylandSurface->geometry.w) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_pXWaylandSurface->geometry.h) > 2) - PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_pXWaylandSurface->geometry.size()); + PWINDOW->m_vRealSize->setValueAndWarp(PWINDOW->m_pXWaylandSurface->geometry.size()); if (*PXWLFORCESCALEZERO) { if (const auto PMONITOR = PWINDOW->m_pMonitor.lock(); PMONITOR) { - PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goal() / PMONITOR->scale); + PWINDOW->m_vRealSize->setValueAndWarp(PWINDOW->m_vRealSize->goal() / PMONITOR->scale); } } - PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goal(); - PWINDOW->m_vSize = PWINDOW->m_vRealSize.goal(); + PWINDOW->m_vPosition = PWINDOW->m_vRealPosition->goal(); + PWINDOW->m_vSize = PWINDOW->m_vRealSize->goal(); - PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace; + PWINDOW->m_pWorkspace = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition->value() + PWINDOW->m_vRealSize->value() / 2.f)->activeWorkspace; g_pCompositor->changeWindowZOrder(PWINDOW, true); PWINDOW->updateWindowDecos(); g_pHyprRenderer->damageWindow(PWINDOW); - PWINDOW->m_vReportedPosition = PWINDOW->m_vRealPosition.goal(); - PWINDOW->m_vPendingReportedSize = PWINDOW->m_vRealSize.goal(); + PWINDOW->m_vReportedPosition = PWINDOW->m_vRealPosition->goal(); + PWINDOW->m_vPendingReportedSize = PWINDOW->m_vRealSize->goal(); } } diff --git a/src/helpers/AnimatedVariable.cpp b/src/helpers/AnimatedVariable.cpp deleted file mode 100644 index ab5643a6..00000000 --- a/src/helpers/AnimatedVariable.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "AnimatedVariable.hpp" -#include "../managers/AnimationManager.hpp" -#include "../config/ConfigManager.hpp" - -CBaseAnimatedVariable::CBaseAnimatedVariable(eAnimatedVarType type) : m_Type(type) { - ; // dummy var -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - m_pWindow = pWindow; - - m_bDummy = false; -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - m_pLayer = pLayer; - - m_bDummy = false; -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - m_pWorkspace = pWorkspace; - - m_bDummy = false; -} - -void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy) { - m_eDamagePolicy = policy; - m_pConfig = pAnimConfig; - - m_bDummy = false; -} - -CBaseAnimatedVariable::~CBaseAnimatedVariable() { - unregister(); -} - -void CBaseAnimatedVariable::unregister() { - if (!g_pAnimationManager) - return; - std::erase_if(g_pAnimationManager->m_vAnimatedVariables, [&](const auto& other) { return other == this; }); - m_bIsRegistered = false; - disconnectFromActive(); -} - -void CBaseAnimatedVariable::registerVar() { - if (!m_bIsRegistered) - g_pAnimationManager->m_vAnimatedVariables.push_back(this); - m_bIsRegistered = true; -} - -float CBaseAnimatedVariable::getPercent() { - const auto DURATIONPASSED = std::chrono::duration_cast(std::chrono::steady_clock::now() - animationBegin).count(); - return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f); -} - -float CBaseAnimatedVariable::getCurveValue() { - if (!m_bIsBeingAnimated) - return 1.f; - - const auto SPENT = getPercent(); - - if (SPENT >= 1.f) - return 1.f; - - return g_pAnimationManager->getBezier(m_pConfig->pValues->internalBezier)->getYForPoint(SPENT); -} - -void CBaseAnimatedVariable::connectToActive() { - g_pAnimationManager->scheduleTick(); // otherwise the animation manager will never pick this up - - if (!m_bIsConnectedToActive) - g_pAnimationManager->m_vActiveAnimatedVariables.push_back(this); - - m_bIsConnectedToActive = true; -} - -void CBaseAnimatedVariable::disconnectFromActive() { - std::erase_if(g_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == this; }); - m_bIsConnectedToActive = false; -} diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index a1da00da..e7d5fd8c 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -1,15 +1,18 @@ #pragma once -#include -#include -#include -#include -#include "math/Math.hpp" +#include + #include "Color.hpp" #include "../defines.hpp" -#include "../debug/Log.hpp" #include "../desktop/DesktopTypes.hpp" +enum eAVarDamagePolicy : int8_t { + AVARDAMAGE_NONE = -1, + AVARDAMAGE_ENTIRE = 0, + AVARDAMAGE_BORDER, + AVARDAMAGE_SHADOW +}; + enum eAnimatedVarType : int8_t { AVARTYPE_INVALID = -1, AVARTYPE_FLOAT, @@ -42,20 +45,6 @@ struct STypeToAnimatedVarType_t { template inline constexpr eAnimatedVarType typeToeAnimatedVarType = STypeToAnimatedVarType_t::value; -enum eAVarDamagePolicy : int8_t { - AVARDAMAGE_NONE = -1, - AVARDAMAGE_ENTIRE = 0, - AVARDAMAGE_BORDER, - AVARDAMAGE_SHADOW -}; - -class CAnimationManager; -struct SAnimationPropertyConfig; -class CHyprRenderer; -class CWindow; -class CWorkspace; -class CLayerSurface; - // Utility to define a concept as a list of possible type template concept OneOf = (... or std::same_as); @@ -66,245 +55,19 @@ concept OneOf = (... or std::same_as); template concept Animable = OneOf; -class CBaseAnimatedVariable { - public: - CBaseAnimatedVariable(eAnimatedVarType type); - void create(SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy); - void create(SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy); - void create(SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy); - void create(SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy); +struct SAnimationContext { + PHLWINDOWREF pWindow; + PHLWORKSPACEREF pWorkspace; + PHLLSREF pLayer; - CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete; - CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete; - CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete; - CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete; - - virtual ~CBaseAnimatedVariable(); - - void unregister(); - void registerVar(); - - virtual void warp(bool endCallback = true) = 0; - - // - void setConfig(SAnimationPropertyConfig* pConfig) { - m_pConfig = pConfig; - } - - SAnimationPropertyConfig* getConfig() { - return m_pConfig; - } - - /* returns the spent (completion) % */ - float getPercent(); - - /* returns the current curve value */ - float getCurveValue(); - - // checks if an animation is in progress - bool isBeingAnimated() const { - return m_bIsBeingAnimated; - } - - /* sets a function to be ran when the animation finishes. - if an animation is not running, runs instantly. - if "remove" is set to true, will remove the callback when ran. */ - void setCallbackOnEnd(std::function func, bool remove = true) { - m_fEndCallback = std::move(func); - m_bRemoveEndAfterRan = remove; - - if (!isBeingAnimated()) - onAnimationEnd(); - } - - /* sets a function to be ran when an animation is started. - if "remove" is set to true, will remove the callback when ran. */ - void setCallbackOnBegin(std::function func, bool remove = true) { - m_fBeginCallback = std::move(func); - m_bRemoveBeginAfterRan = remove; - } - - /* Sets the update callback, called every time the value is animated and a step is done - Warning: calling unregisterVar/registerVar in this handler will cause UB */ - void setUpdateCallback(std::function func) { - m_fUpdateCallback = std::move(func); - } - - /* resets all callbacks. Does not call any. */ - void resetAllCallbacks() { - m_fBeginCallback = nullptr; - m_fEndCallback = nullptr; - m_fUpdateCallback = nullptr; - m_bRemoveBeginAfterRan = false; - m_bRemoveEndAfterRan = false; - } - - PHLWINDOW getWindow() { - return m_pWindow.lock(); - } - - protected: - PHLWINDOWREF m_pWindow; - PHLWORKSPACEREF m_pWorkspace; - PHLLSREF m_pLayer; - - SAnimationPropertyConfig* m_pConfig = nullptr; - - bool m_bDummy = true; - bool m_bIsRegistered = false; - bool m_bIsBeingAnimated = false; - - std::chrono::steady_clock::time_point animationBegin; - - eAVarDamagePolicy m_eDamagePolicy = AVARDAMAGE_NONE; - eAnimatedVarType m_Type; - - bool m_bRemoveEndAfterRan = true; - bool m_bRemoveBeginAfterRan = true; - std::function m_fEndCallback; - std::function m_fBeginCallback; - std::function m_fUpdateCallback; - - bool m_bIsConnectedToActive = false; - - void connectToActive(); - - void disconnectFromActive(); - - // methods - void onAnimationEnd() { - m_bIsBeingAnimated = false; - disconnectFromActive(); - - if (m_fEndCallback) { - // loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false. - auto removeEndCallback = m_bRemoveEndAfterRan; - m_fEndCallback(this); - if (removeEndCallback) - m_fEndCallback = nullptr; // reset - } - } - - void onAnimationBegin() { - m_bIsBeingAnimated = true; - connectToActive(); - - if (m_fBeginCallback) { - m_fBeginCallback(this); - if (m_bRemoveBeginAfterRan) - m_fBeginCallback = nullptr; // reset - } - } - - friend class CAnimationManager; - friend class CWorkspace; - friend class CLayerSurface; - friend class CHyprRenderer; + eAVarDamagePolicy eDamagePolicy = AVARDAMAGE_NONE; }; template -class CAnimatedVariable : public CBaseAnimatedVariable { - public: - CAnimatedVariable() : CBaseAnimatedVariable(typeToeAnimatedVarType) { - ; - } // dummy var +using CAnimatedVariable = Hyprutils::Animation::CGenericAnimatedVariable; - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) { - create(pAnimConfig, pWindow, policy); - m_Value = value; - m_Goal = value; - } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLLS pLayer, eAVarDamagePolicy policy) { - create(pAnimConfig, pLayer, policy); - m_Value = value; - m_Goal = value; - } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) { - create(pAnimConfig, pWorkspace, policy); - m_Value = value; - m_Goal = value; - } - void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, eAVarDamagePolicy policy) { - create(pAnimConfig, policy); - m_Value = value; - m_Goal = value; - } +template +using PHLANIMVAR = SP>; - using CBaseAnimatedVariable::create; - - CAnimatedVariable(const CAnimatedVariable&) = delete; - CAnimatedVariable(CAnimatedVariable&&) = delete; - CAnimatedVariable& operator=(const CAnimatedVariable&) = delete; - CAnimatedVariable& operator=(CAnimatedVariable&&) = delete; - - ~CAnimatedVariable() = default; - - // gets the current vector value (real time) - const VarType& value() const { - return m_Value; - } - - // gets the goal vector value - const VarType& goal() const { - return m_Goal; - } - - CAnimatedVariable& operator=(const VarType& v) { - if (v == m_Goal) - return *this; - - m_Goal = v; - animationBegin = std::chrono::steady_clock::now(); - m_Begun = m_Value; - - onAnimationBegin(); - - return *this; - } - - // Sets the actual stored value, without affecting the goal, but resets the timer - void setValue(const VarType& v) { - if (v == m_Value) - return; - - m_Value = v; - animationBegin = std::chrono::steady_clock::now(); - m_Begun = m_Value; - - onAnimationBegin(); - } - - // Sets the actual value and goal - void setValueAndWarp(const VarType& v) { - m_Goal = v; - m_bIsBeingAnimated = true; - warp(); - } - - void warp(bool endCallback = true) override { - if (!m_bIsBeingAnimated) - return; - - m_Value = m_Goal; - - m_bIsBeingAnimated = false; - - if (m_fUpdateCallback) - m_fUpdateCallback(this); - - if (endCallback) - onAnimationEnd(); - } - - private: - VarType m_Value{}; - VarType m_Goal{}; - VarType m_Begun{}; - - // owners - - friend class CAnimationManager; - friend class CWorkspace; - friend class CLayerSurface; - friend class CHyprRenderer; -}; +template +using PHLANIMVARREF = WP>; diff --git a/src/helpers/BezierCurve.cpp b/src/helpers/BezierCurve.cpp deleted file mode 100644 index a0610fc9..00000000 --- a/src/helpers/BezierCurve.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "BezierCurve.hpp" -#include "../debug/Log.hpp" -#include "../macros.hpp" - -#include -#include - -void CBezierCurve::setup(std::vector* pVec) { - const auto BEGIN = std::chrono::high_resolution_clock::now(); - - // Avoid reallocations by reserving enough memory upfront - m_vPoints.resize(pVec->size() + 2); - m_vPoints[0] = Vector2D(0, 0); // Start point - size_t index = 1; // Start after the first element - for (const auto& vec : *pVec) { - if (index < m_vPoints.size() - 1) { // Bounds check to ensure safety - m_vPoints[index] = vec; - ++index; - } - } - m_vPoints.back() = Vector2D(1, 1); // End point - - RASSERT(m_vPoints.size() == 4, "CBezierCurve only supports cubic beziers! (points num: {})", m_vPoints.size()); - - // bake BAKEDPOINTS points for faster lookups - // T -> X ( / BAKEDPOINTS ) - for (int i = 0; i < BAKEDPOINTS; ++i) { - float const t = (i + 1) / (float)BAKEDPOINTS; - m_aPointsBaked[i] = Vector2D(getXForT(t), getYForT(t)); - } - - const auto ELAPSEDUS = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - BEGIN).count() / 1000.f; - const auto POINTSSIZE = m_aPointsBaked.size() * sizeof(m_aPointsBaked[0]) / 1000.f; - - const auto BEGINCALC = std::chrono::high_resolution_clock::now(); - for (int j = 1; j < 10; ++j) { - float i = j / 10.0f; - getYForPoint(i); - } - const auto ELAPSEDCALCAVG = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - BEGINCALC).count() / 1000.f / 10.f; - - Debug::log(LOG, "Created a bezier curve, baked {} points, mem usage: {:.2f}kB, time to bake: {:.2f}µs. Estimated average calc time: {:.2f}µs.", BAKEDPOINTS, POINTSSIZE, - ELAPSEDUS, ELAPSEDCALCAVG); -} - -float CBezierCurve::getXForT(float const& t) const { - float t2 = t * t; - float t3 = t2 * t; - - return 3 * t * (1 - t) * (1 - t) * m_vPoints[1].x + 3 * t2 * (1 - t) * m_vPoints[2].x + t3 * m_vPoints[3].x; -} - -float CBezierCurve::getYForT(float const& t) const { - float t2 = t * t; - float t3 = t2 * t; - - return 3 * t * (1 - t) * (1 - t) * m_vPoints[1].y + 3 * t2 * (1 - t) * m_vPoints[2].y + t3 * m_vPoints[3].y; -} - -// Todo: this probably can be done better and faster -float CBezierCurve::getYForPoint(float const& x) const { - if (x >= 1.f) - return 1.f; - if (x <= 0.f) - return 0.f; - - int index = 0; - bool below = true; - for (int step = (BAKEDPOINTS + 1) / 2; step > 0; step /= 2) { - if (below) - index += step; - else - index -= step; - - below = m_aPointsBaked[index].x < x; - } - - int lowerIndex = index - (!below || index == BAKEDPOINTS - 1); - - // in the name of performance i shall make a hack - const auto LOWERPOINT = &m_aPointsBaked[lowerIndex]; - const auto UPPERPOINT = &m_aPointsBaked[lowerIndex + 1]; - - const auto PERCINDELTA = (x - LOWERPOINT->x) / (UPPERPOINT->x - LOWERPOINT->x); - - if (std::isnan(PERCINDELTA) || std::isinf(PERCINDELTA)) // can sometimes happen for VERY small x - return 0.f; - - return LOWERPOINT->y + (UPPERPOINT->y - LOWERPOINT->y) * PERCINDELTA; -} diff --git a/src/helpers/BezierCurve.hpp b/src/helpers/BezierCurve.hpp deleted file mode 100644 index e643fb41..00000000 --- a/src/helpers/BezierCurve.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include -#include -#include "math/Math.hpp" - -constexpr int BAKEDPOINTS = 255; -constexpr float INVBAKEDPOINTS = 1.f / BAKEDPOINTS; - -// an implementation of a cubic bezier curve -// might do better later -class CBezierCurve { - public: - // sets up the bezier curve. - // this EXCLUDES the 0,0 and 1,1 points, - void setup(std::vector* points); - - float getYForT(float const& t) const; - float getXForT(float const& t) const; - float getYForPoint(float const& x) const; - - private: - // this INCLUDES the 0,0 and 1,1 points. - std::vector m_vPoints; - - std::array m_aPointsBaked; -}; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 76df00b3..e833e661 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1127,16 +1127,16 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) { if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && !w->isX11OverrideRedirect()) { // if it's floating and the middle isnt on the current mon, move it to the center const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE); - Vector2D pos = w->m_vRealPosition.goal(); + Vector2D pos = w->m_vRealPosition->goal(); if (!VECINRECT(MIDDLE, PMONFROMMIDDLE->vecPosition.x, PMONFROMMIDDLE->vecPosition.y, PMONFROMMIDDLE->vecPosition.x + PMONFROMMIDDLE->vecSize.x, PMONFROMMIDDLE->vecPosition.y + PMONFROMMIDDLE->vecSize.y)) { // not on any monitor, center - pos = middle() / 2.f - w->m_vRealSize.goal() / 2.f; + pos = middle() / 2.f - w->m_vRealSize->goal() / 2.f; } else pos = pos - PMONFROMMIDDLE->vecPosition + vecPosition; - w->m_vRealPosition = pos; - w->m_vPosition = pos; + *w->m_vRealPosition = pos; + w->m_vPosition = pos; } } } diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 0a6ef55d..b6e3ac12 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -5,7 +5,6 @@ #include "../desktop/Window.hpp" #include "../desktop/Subsurface.hpp" #include "../desktop/Popup.hpp" -#include "AnimatedVariable.hpp" #include "../desktop/WLSurface.hpp" #include "signal/Signal.hpp" #include "math/Math.hpp" diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index d3cd8273..5e0dcf5e 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -3,13 +3,13 @@ #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" #include "../render/pass/TexPassElement.hpp" +#include "../managers/AnimationManager.hpp" #include -using namespace Hyprutils::Utils; +using namespace Hyprutils::Animation; CHyprError::CHyprError() { - m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), AVARDAMAGE_NONE); - m_fFadeOpacity.registerVar(); + g_pAnimationManager->createAnimation(0.f, m_fFadeOpacity, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), AVARDAMAGE_NONE); static auto P = g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) { if (!m_bIsCreated) @@ -23,16 +23,14 @@ CHyprError::CHyprError() { if (!m_bIsCreated) return; - if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged) + if (m_fFadeOpacity->isBeingAnimated() || m_bMonitorChanged) g_pHyprRenderer->damageBox(&m_bDamageBox); }); m_pTexture = makeShared(); } -CHyprError::~CHyprError() { - m_fFadeOpacity.unregister(); -} +CHyprError::~CHyprError() = default; void CHyprError::queueCreate(std::string message, const CHyprColor& color) { m_szQueued = message; @@ -43,10 +41,10 @@ void CHyprError::createQueued() { if (m_bIsCreated) m_pTexture->destroyTexture(); - m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn")); + m_fFadeOpacity->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn")); - m_fFadeOpacity.setValueAndWarp(0.f); - m_fFadeOpacity = 1.f; + m_fFadeOpacity->setValueAndWarp(0.f); + *m_fFadeOpacity = 1.f; const auto PMONITOR = g_pCompositor->m_vMonitors.front(); @@ -176,8 +174,8 @@ void CHyprError::draw() { } if (m_bQueuedDestroy) { - if (!m_fFadeOpacity.isBeingAnimated()) { - if (m_fFadeOpacity.value() == 0.f) { + if (!m_fFadeOpacity->isBeingAnimated()) { + if (m_fFadeOpacity->value() == 0.f) { m_bQueuedDestroy = false; m_pTexture->destroyTexture(); m_bIsCreated = false; @@ -189,8 +187,8 @@ void CHyprError::draw() { return; } else { - m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut")); - m_fFadeOpacity = 0.f; + m_fFadeOpacity->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut")); + *m_fFadeOpacity = 0.f; } } } @@ -202,7 +200,7 @@ void CHyprError::draw() { m_bDamageBox.x = (int)PMONITOR->vecPosition.x; m_bDamageBox.y = (int)PMONITOR->vecPosition.y; - if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged) + if (m_fFadeOpacity->isBeingAnimated() || m_bMonitorChanged) g_pHyprRenderer->damageBox(&m_bDamageBox); m_bMonitorChanged = false; @@ -210,7 +208,7 @@ void CHyprError::draw() { CTexPassElement::SRenderData data; data.tex = m_pTexture; data.box = monbox; - data.a = m_fFadeOpacity.value(); + data.a = m_fFadeOpacity->value(); g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } diff --git a/src/hyprerror/HyprError.hpp b/src/hyprerror/HyprError.hpp index 042dccd0..9a662423 100644 --- a/src/hyprerror/HyprError.hpp +++ b/src/hyprerror/HyprError.hpp @@ -19,17 +19,17 @@ class CHyprError { float height(); // logical private: - void createQueued(); - std::string m_szQueued = ""; - CHyprColor m_cQueued; - bool m_bQueuedDestroy = false; - bool m_bIsCreated = false; - SP m_pTexture; - CAnimatedVariable m_fFadeOpacity; - CBox m_bDamageBox = {0, 0, 0, 0}; - float m_fLastHeight = 0.F; + void createQueued(); + std::string m_szQueued = ""; + CHyprColor m_cQueued; + bool m_bQueuedDestroy = false; + bool m_bIsCreated = false; + SP m_pTexture; + PHLANIMVAR m_fFadeOpacity; + CBox m_bDamageBox = {0, 0, 0, 0}; + float m_fLastHeight = 0.F; - bool m_bMonitorChanged = false; + bool m_bMonitorChanged = false; }; inline std::unique_ptr g_pHyprError; // This is a full-screen error. Treat it with respect, and there can only be one at a time. diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index dc6e37dd..2ee41eba 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -192,16 +192,16 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR}; wb.round(); // avoid rounding mess - PWINDOW->m_vRealPosition = wb.pos(); - PWINDOW->m_vRealSize = wb.size(); + *PWINDOW->m_vRealPosition = wb.pos(); + *PWINDOW->m_vRealSize = wb.size(); g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); } else { CBox wb = {calcPos, calcSize}; wb.round(); // avoid rounding mess - PWINDOW->m_vRealSize = wb.size(); - PWINDOW->m_vRealPosition = wb.pos(); + *PWINDOW->m_vRealSize = wb.size(); + *PWINDOW->m_vRealPosition = wb.pos(); g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); } @@ -209,8 +209,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for if (force) { g_pHyprRenderer->damageWindow(PWINDOW); - PWINDOW->m_vRealPosition.warp(); - PWINDOW->m_vRealSize.warp(); + PWINDOW->m_vRealPosition->warp(); + PWINDOW->m_vRealSize->warp(); g_pHyprRenderer->damageWindow(PWINDOW); } @@ -508,8 +508,8 @@ void CHyprDwindleLayout::calculateWorkspace(const PHLWORKSPACE& pWorkspace) { const auto PFULLWINDOW = pWorkspace->getFullscreenWindow(); if (pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) { - PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; - PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; + *PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; + *PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; } else if (pWorkspace->m_efFullscreenMode == FSMODE_MAXIMIZED) { SDwindleNodeData fakeNode; fakeNode.pWindow = PFULLWINDOW; @@ -554,8 +554,8 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn const auto PNODE = getNodeFromWindow(PWINDOW); if (!PNODE) { - PWINDOW->m_vRealSize = - (PWINDOW->m_vRealSize.goal() + pixResize) + *PWINDOW->m_vRealSize = + (PWINDOW->m_vRealSize->goal() + pixResize) .clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY})); PWINDOW->updateWindowDecos(); return; @@ -575,7 +575,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn if (!m_PseudoDragFlags.started) { m_PseudoDragFlags.started = true; - const auto pseudoSize = PWINDOW->m_vRealSize.goal(); + const auto pseudoSize = PWINDOW->m_vRealSize->goal(); const auto mouseOffset = g_pInputManager->getMouseCoordsInternal() - (PNODE->box.pos() + ((PNODE->box.size() / 2) - (pseudoSize / 2))); if (mouseOffset.x > 0 && mouseOffset.x < pseudoSize.x && mouseOffset.y > 0 && mouseOffset.y < pseudoSize.y) { @@ -743,10 +743,10 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFu // save position and size if floating if (pWindow->m_bIsFloating && CURRENT_EFFECTIVE_MODE == FSMODE_NONE) { - pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goal(); - pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goal(); - pWindow->m_vPosition = pWindow->m_vRealPosition.goal(); - pWindow->m_vSize = pWindow->m_vRealSize.goal(); + pWindow->m_vLastFloatingSize = pWindow->m_vRealSize->goal(); + pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition->goal(); + pWindow->m_vPosition = pWindow->m_vRealPosition->goal(); + pWindow->m_vSize = pWindow->m_vRealSize->goal(); } if (EFFECTIVE_MODE == FSMODE_NONE) { @@ -756,8 +756,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFu applyNodeDataToWindow(PNODE); else { // get back its' dimensions from position and size - pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition; - pWindow->m_vRealSize = pWindow->m_vLastFloatingSize; + *pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition; + *pWindow->m_vRealSize = pWindow->m_vLastFloatingSize; pWindow->unsetWindowData(PRIORITY_LAYOUT); pWindow->updateWindowData(); @@ -765,8 +765,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFu } else { // apply new pos and size being monitors' box if (EFFECTIVE_MODE == FSMODE_FULLSCREEN) { - pWindow->m_vRealPosition = PMONITOR->vecPosition; - pWindow->m_vRealSize = PMONITOR->vecSize; + *pWindow->m_vRealPosition = PMONITOR->vecPosition; + *pWindow->m_vRealSize = PMONITOR->vecSize; } else { // This is a massive hack. // We make a fake "only" node and apply diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index f875b99c..eeebd815 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -106,7 +106,7 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) { if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) { const auto PWINDOWSURFACE = pWindow->m_pWLSurface->resource(); - pWindow->m_vRealSize = PWINDOWSURFACE->current.size; + *pWindow->m_vRealSize = PWINDOWSURFACE->current.size; if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect()) { // XDG windows should be fine. TODO: check for weird atoms? @@ -115,23 +115,23 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) { } // reject any windows with size <= 5x5 - if (pWindow->m_vRealSize.goal().x <= 5 || pWindow->m_vRealSize.goal().y <= 5) - pWindow->m_vRealSize = PMONITOR->vecSize / 2.f; + if (pWindow->m_vRealSize->goal().x <= 5 || pWindow->m_vRealSize->goal().y <= 5) + *pWindow->m_vRealSize = PMONITOR->vecSize / 2.f; if (pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect()) { if (pWindow->m_pXWaylandSurface->geometry.x != 0 && pWindow->m_pXWaylandSurface->geometry.y != 0) - pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_pXWaylandSurface->geometry.pos()); + *pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_pXWaylandSurface->geometry.pos()); else - pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f, - PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f); + *pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize->goal().x) / 2.f, + PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize->goal().y) / 2.f); } else { - pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f, - PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f); + *pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize->goal().x) / 2.f, + PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize->goal().y) / 2.f); } } else { // we respect the size. - pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height); + *pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height); // check if it's on the correct monitor! Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f; @@ -150,35 +150,35 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) { if ((desiredGeometry.x == 0 && desiredGeometry.y == 0) || !visible || !pWindow->m_bIsX11) { // if the pos isn't set, fall back to the center placement if it's not a child, otherwise middle of parent if available if (!pWindow->m_bIsX11 && pWindow->m_pXDGSurface->toplevel->parent && validMapped(pWindow->m_pXDGSurface->toplevel->parent->window)) - pWindow->m_vRealPosition = pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealPosition.goal() + - pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealSize.goal() / 2.F - desiredGeometry.size() / 2.F; + *pWindow->m_vRealPosition = pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealPosition->goal() + + pWindow->m_pXDGSurface->toplevel->parent->window->m_vRealSize->goal() / 2.F - desiredGeometry.size() / 2.F; else - pWindow->m_vRealPosition = PMONITOR->vecPosition + PMONITOR->vecSize / 2.F - desiredGeometry.size() / 2.F; + *pWindow->m_vRealPosition = PMONITOR->vecPosition + PMONITOR->vecSize / 2.F - desiredGeometry.size() / 2.F; } else { // if it is, we respect where it wants to put itself, but apply monitor offset if outside // most of these are popups if (const auto POPENMON = g_pCompositor->getMonitorFromVector(middlePoint); POPENMON->ID != PMONITOR->ID) - pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition; + *pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition; else - pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y); + *pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y); } } if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11) - pWindow->m_vRealSize = pWindow->m_vRealSize.goal() / PMONITOR->scale; + *pWindow->m_vRealSize = pWindow->m_vRealSize->goal() / PMONITOR->scale; if (pWindow->m_bX11DoesntWantBorders || (pWindow->m_bIsX11 && pWindow->isX11OverrideRedirect())) { - pWindow->m_vRealPosition.warp(); - pWindow->m_vRealSize.warp(); + pWindow->m_vRealPosition->warp(); + pWindow->m_vRealSize->warp(); } if (!pWindow->isX11OverrideRedirect()) { - g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal()); + g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize->goal()); g_pCompositor->changeWindowZOrder(pWindow, true); } else { - pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goal(); + pWindow->m_vPendingReportedSize = pWindow->m_vRealSize->goal(); pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize; } } @@ -250,18 +250,18 @@ void IHyprLayout::onBeginDragWindow() { if (!DRAGGINGWINDOW->m_bIsFloating) { if (g_pInputManager->dragMode == MBIND_MOVE) { - DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize.goal() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor(); + DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize->goal() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor(); changeWindowFloatingMode(DRAGGINGWINDOW); DRAGGINGWINDOW->m_bIsFloating = true; DRAGGINGWINDOW->m_bDraggingTiled = true; - DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize.goal() / 2.f; + *DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize->goal() / 2.f; } } m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal(); - m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.goal(); - m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goal(); + m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition->goal(); + m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize->goal(); m_vLastDragXY = m_vBeginDragXY; // get the grab corner @@ -348,10 +348,10 @@ void IHyprLayout::onEndDragWindow() { if (DRAGGINGWINDOW->m_sGroupData.pNextWindow) { PHLWINDOW next = DRAGGINGWINDOW->m_sGroupData.pNextWindow.lock(); while (next != DRAGGINGWINDOW) { - next->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of group members - next->m_vRealSize = pWindow->m_vRealSize.goal(); // match the size of group members - next->m_vRealPosition = pWindow->m_vRealPosition.goal(); // match the position of group members - next = next->m_sGroupData.pNextWindow.lock(); + next->m_bIsFloating = pWindow->m_bIsFloating; // match the floating state of group members + *next->m_vRealSize = pWindow->m_vRealSize->goal(); // match the size of group members + *next->m_vRealPosition = pWindow->m_vRealPosition->goal(); // match the position of group members + next = next->m_sGroupData.pNextWindow.lock(); } } @@ -360,7 +360,7 @@ void IHyprLayout::onEndDragWindow() { DRAGGINGWINDOW->m_bDraggingTiled = false; if (pWindow->m_bIsFloating) - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize.goal()); // match the size of the window + g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize->goal()); // match the size of the window static auto USECURRPOS = CConfigValue("group:insert_after_current"); (*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW); @@ -593,7 +593,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { if (g_pInputManager->dragMode == MBIND_MOVE) { Vector2D newPos = m_vBeginDragPositionXY + DELTA; - Vector2D newSize = DRAGGINGWINDOW->m_vRealSize.goal(); + Vector2D newSize = DRAGGINGWINDOW->m_vRealSize->goal(); if (*SNAPENABLED && !DRAGGINGWINDOW->m_bDraggingTiled) performSnap(newPos, newSize, DRAGGINGWINDOW, MBIND_MOVE, -1, m_vBeginDragSizeXY); @@ -602,11 +602,11 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { wb.round(); if (*PANIMATEMOUSE) - DRAGGINGWINDOW->m_vRealPosition = wb.pos(); + *DRAGGINGWINDOW->m_vRealPosition = wb.pos(); else - DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos()); + DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos()); - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal()); + g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize->goal()); } else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) { if (DRAGGINGWINDOW->m_bIsFloating) { @@ -671,21 +671,21 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { wb.round(); if (*PANIMATE) { - DRAGGINGWINDOW->m_vRealSize = wb.size(); - DRAGGINGWINDOW->m_vRealPosition = wb.pos(); + *DRAGGINGWINDOW->m_vRealSize = wb.size(); + *DRAGGINGWINDOW->m_vRealPosition = wb.pos(); } else { - DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(wb.size()); - DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos()); + DRAGGINGWINDOW->m_vRealSize->setValueAndWarp(wb.size()); + DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos()); } - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal()); + g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize->goal()); } else { resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW); } } // get middle point - Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.value() + DRAGGINGWINDOW->m_vRealSize.value() / 2.f; + Vector2D middle = DRAGGINGWINDOW->m_vRealPosition->value() + DRAGGINGWINDOW->m_vRealSize->value() / 2.f; // and check its monitor const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle); @@ -719,7 +719,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { EMIT_HOOK_EVENT("changeFloatingMode", pWindow); if (!TILED) { - const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f); + const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition->value() + pWindow->m_vRealSize->value() / 2.f); pWindow->m_pMonitor = PNEWMON; pWindow->moveToWorkspace(PNEWMON->activeSpecialWorkspace ? PNEWMON->activeSpecialWorkspace : PNEWMON->activeWorkspace); pWindow->updateGroupOutputs(); @@ -730,12 +730,12 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { g_pCompositor->setWindowFullscreenInternal(PWORKSPACE->getFullscreenWindow(), FSMODE_NONE); // save real pos cuz the func applies the default 5,5 mid - const auto PSAVEDPOS = pWindow->m_vRealPosition.goal(); - const auto PSAVEDSIZE = pWindow->m_vRealSize.goal(); + const auto PSAVEDPOS = pWindow->m_vRealPosition->goal(); + const auto PSAVEDSIZE = pWindow->m_vRealSize->goal(); // if the window is pseudo, update its size if (!pWindow->m_bDraggingTiled) - pWindow->m_vPseudoSize = pWindow->m_vRealSize.goal(); + pWindow->m_vPseudoSize = pWindow->m_vRealSize->goal(); pWindow->m_vLastFloatingSize = PSAVEDSIZE; @@ -744,8 +744,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { onWindowCreatedTiling(pWindow); - pWindow->m_vRealPosition.setValue(PSAVEDPOS); - pWindow->m_vRealSize.setValue(PSAVEDSIZE); + pWindow->m_vRealPosition->setValue(PSAVEDPOS); + pWindow->m_vRealSize->setValue(PSAVEDSIZE); // fix pseudo leaving artifacts g_pHyprRenderer->damageMonitor(pWindow->m_pMonitor.lock()); @@ -757,16 +757,16 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { g_pCompositor->changeWindowZOrder(pWindow, true); - CBox wb = {pWindow->m_vRealPosition.goal() + (pWindow->m_vRealSize.goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize}; + CBox wb = {pWindow->m_vRealPosition->goal() + (pWindow->m_vRealSize->goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize}; wb.round(); - if (!(pWindow->m_bIsFloating && pWindow->m_bIsPseudotiled) && DELTALESSTHAN(pWindow->m_vRealSize.value().x, pWindow->m_vLastFloatingSize.x, 10) && - DELTALESSTHAN(pWindow->m_vRealSize.value().y, pWindow->m_vLastFloatingSize.y, 10)) { + if (!(pWindow->m_bIsFloating && pWindow->m_bIsPseudotiled) && DELTALESSTHAN(pWindow->m_vRealSize->value().x, pWindow->m_vLastFloatingSize.x, 10) && + DELTALESSTHAN(pWindow->m_vRealSize->value().y, pWindow->m_vLastFloatingSize.y, 10)) { wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}}; } - pWindow->m_vRealPosition = wb.pos(); - pWindow->m_vRealSize = wb.size(); + *pWindow->m_vRealPosition = wb.pos(); + *pWindow->m_vRealSize = wb.size(); pWindow->m_vSize = wb.pos(); pWindow->m_vPosition = wb.size(); @@ -798,7 +798,7 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) { PWINDOW->setAnimationsToMove(); - PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + delta; + *PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition->goal() + delta; g_pHyprRenderer->damageWindow(PWINDOW); } diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 225246f0..e6e22326 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -301,8 +301,8 @@ void CHyprMasterLayout::calculateWorkspace(PHLWORKSPACE pWorkspace) { const auto PFULLWINDOW = pWorkspace->getFullscreenWindow(); if (pWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) { - PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; - PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; + *PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition; + *PFULLWINDOW->m_vRealSize = PMONITOR->vecSize; } else if (pWorkspace->m_efFullscreenMode == FSMODE_MAXIMIZED) { SMasterNodeData fakeNode; fakeNode.pWindow = PFULLWINDOW; @@ -672,16 +672,16 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR}; wb.round(); // avoid rounding mess - PWINDOW->m_vRealPosition = wb.pos(); - PWINDOW->m_vRealSize = wb.size(); + *PWINDOW->m_vRealPosition = wb.pos(); + *PWINDOW->m_vRealSize = wb.size(); g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); } else { CBox wb = {calcPos, calcSize}; wb.round(); // avoid rounding mess - PWINDOW->m_vRealPosition = wb.pos(); - PWINDOW->m_vRealSize = wb.size(); + *PWINDOW->m_vRealPosition = wb.pos(); + *PWINDOW->m_vRealSize = wb.size(); g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); } @@ -689,8 +689,8 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { if (m_bForceWarps && !*PANIMATE) { g_pHyprRenderer->damageWindow(PWINDOW); - PWINDOW->m_vRealPosition.warp(); - PWINDOW->m_vRealSize.warp(); + PWINDOW->m_vRealPosition->warp(); + PWINDOW->m_vRealSize->warp(); g_pHyprRenderer->damageWindow(PWINDOW); } @@ -711,8 +711,8 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne const auto PNODE = getNodeFromWindow(PWINDOW); if (!PNODE) { - PWINDOW->m_vRealSize = - (PWINDOW->m_vRealSize.goal() + pixResize) + *PWINDOW->m_vRealSize = + (PWINDOW->m_vRealSize->goal() + pixResize) .clamp(PWINDOW->m_sWindowData.minSize.valueOr(Vector2D{MIN_WINDOW_SIZE, MIN_WINDOW_SIZE}), PWINDOW->m_sWindowData.maxSize.valueOr(Vector2D{INFINITY, INFINITY})); PWINDOW->updateWindowDecos(); return; @@ -852,10 +852,10 @@ void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFul // save position and size if floating if (pWindow->m_bIsFloating && CURRENT_EFFECTIVE_MODE == FSMODE_NONE) { - pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goal(); - pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goal(); - pWindow->m_vPosition = pWindow->m_vRealPosition.goal(); - pWindow->m_vSize = pWindow->m_vRealSize.goal(); + pWindow->m_vLastFloatingSize = pWindow->m_vRealSize->goal(); + pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition->goal(); + pWindow->m_vPosition = pWindow->m_vRealPosition->goal(); + pWindow->m_vSize = pWindow->m_vRealSize->goal(); } if (EFFECTIVE_MODE == FSMODE_NONE) { @@ -865,8 +865,8 @@ void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFul applyNodeDataToWindow(PNODE); else { // get back its' dimensions from position and size - pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition; - pWindow->m_vRealSize = pWindow->m_vLastFloatingSize; + *pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition; + *pWindow->m_vRealSize = pWindow->m_vLastFloatingSize; pWindow->unsetWindowData(PRIORITY_LAYOUT); pWindow->updateWindowData(); @@ -874,8 +874,8 @@ void CHyprMasterLayout::fullscreenRequestForWindow(PHLWINDOW pWindow, const eFul } else { // apply new pos and size being monitors' box if (EFFECTIVE_MODE == FSMODE_FULLSCREEN) { - pWindow->m_vRealPosition = PMONITOR->vecPosition; - pWindow->m_vRealSize = PMONITOR->vecSize; + *pWindow->m_vRealPosition = PMONITOR->vecPosition; + *pWindow->m_vRealSize = PMONITOR->vecSize; } else { // This is a massive hack. // We make a fake "only" node and apply diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index cff438b1..6bfeed83 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -1,6 +1,9 @@ #include "AnimationManager.hpp" #include "../Compositor.hpp" #include "HookSystemManager.hpp" +#include "config/ConfigManager.hpp" +#include "desktop/DesktopTypes.hpp" +#include "helpers/AnimatedVariable.hpp" #include "macros.hpp" #include "../config/ConfigValue.hpp" #include "../desktop/Window.hpp" @@ -9,6 +12,8 @@ #include "../helpers/varlist/VarList.hpp" #include +#include +#include static int wlTick(SP self, void* data) { if (g_pAnimationManager) @@ -26,324 +31,245 @@ static int wlTick(SP self, void* data) { return 0; } -CAnimationManager::CAnimationManager() { - std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; - m_mBezierCurves["default"].setup(&points); - - points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)}; - m_mBezierCurves["linear"].setup(&points); - +CHyprAnimationManager::CHyprAnimationManager() { m_pAnimationTimer = SP(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr)); g_pEventLoopManager->addTimer(m_pAnimationTimer); + + addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)); } -void CAnimationManager::removeAllBeziers() { - m_mBezierCurves.clear(); +template +void updateVariable(CAnimatedVariable& av, const float POINTY, bool warp = false) { + if (POINTY >= 1.f || warp || av.value() == av.goal()) { + av.warp(); + return; + } - // add the default one - std::vector points = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)}; - m_mBezierCurves["default"].setup(&points); - - points = {Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)}; - m_mBezierCurves["linear"].setup(&points); + const auto DELTA = av.goal() - av.begun(); + av.value() = av.begun() + DELTA * POINTY; } -void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) { - std::vector points = {p1, p2}; - m_mBezierCurves[name].setup(&points); +void updateColorVariable(CAnimatedVariable& av, const float POINTY, bool warp) { + if (POINTY >= 1.f || warp || av.value() == av.goal()) { + av.warp(); + return; + } + + // convert both to OkLab, then lerp that, and convert back. + // This is not as fast as just lerping rgb, but it's WAY more precise... + // Use the CHyprColor cache for OkLab + + const auto& L1 = av.begun().asOkLab(); + const auto& L2 = av.goal().asOkLab(); + + static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; }; + + const Hyprgraphics::CColor lerped = Hyprgraphics::CColor::SOkLab{ + .l = lerp(L1.l, L2.l, POINTY), + .a = lerp(L1.a, L2.a, POINTY), + .b = lerp(L1.b, L2.b, POINTY), + }; + + av.value() = {lerped, lerp(av.begun().a, av.goal().a, POINTY)}; } -void CAnimationManager::onTicked() { - m_bTickScheduled = false; +template +static void handleUpdate(CAnimatedVariable& av, bool warp) { + PHLWINDOW PWINDOW = av.m_Context.pWindow.lock(); + PHLWORKSPACE PWORKSPACE = av.m_Context.pWorkspace.lock(); + PHLLS PLAYER = av.m_Context.pLayer.lock(); + PHLMONITOR PMONITOR = nullptr; + bool animationsDisabled = warp; + + if (PWINDOW) { + if (av.m_Context.eDamagePolicy == AVARDAMAGE_ENTIRE) + g_pHyprRenderer->damageWindow(PWINDOW); + else if (av.m_Context.eDamagePolicy == AVARDAMAGE_BORDER) { + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER); + PDECO->damageEntire(); + } else if (av.m_Context.eDamagePolicy == AVARDAMAGE_SHADOW) { + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW); + PDECO->damageEntire(); + } + + PMONITOR = PWINDOW->m_pMonitor.lock(); + if (!PMONITOR) + return; + + animationsDisabled = PWINDOW->m_sWindowData.noAnim.valueOr(animationsDisabled); + } else if (PWORKSPACE) { + PMONITOR = PWORKSPACE->m_pMonitor.lock(); + if (!PMONITOR) + return; + + // dont damage the whole monitor on workspace change, unless it's a special workspace, because dim/blur etc + if (PWORKSPACE->m_bIsSpecialWorkspace) + g_pHyprRenderer->damageMonitor(PMONITOR); + + // TODO: just make this into a damn callback already vax... + for (auto const& w : g_pCompositor->m_vWindows) { + if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != PWORKSPACE) + continue; + + if (w->m_bIsFloating && !w->m_bPinned) { + // still doing the full damage hack for floating because sometimes when the window + // goes through multiple monitors the last rendered frame is missing damage somehow?? + const CBox windowBoxNoOffset = w->getFullWindowBoundingBox(); + const CBox monitorBox = {PMONITOR->vecPosition, PMONITOR->vecSize}; + if (windowBoxNoOffset.intersection(monitorBox) != windowBoxNoOffset) // on edges between multiple monitors + g_pHyprRenderer->damageWindow(w, true); + } + + if (PWORKSPACE->m_bIsSpecialWorkspace) + g_pHyprRenderer->damageWindow(w, true); // hack for special too because it can cross multiple monitors + } + + // damage any workspace window that is on any monitor + for (auto const& w : g_pCompositor->m_vWindows) { + if (!validMapped(w) || w->m_pWorkspace != PWORKSPACE || w->m_bPinned) + continue; + + g_pHyprRenderer->damageWindow(w); + } + } else if (PLAYER) { + // "some fucking layers miss 1 pixel???" -- vaxry + CBox expandBox = CBox{PLAYER->realPosition->value(), PLAYER->realSize->value()}; + expandBox.expand(5); + g_pHyprRenderer->damageBox(&expandBox); + + PMONITOR = g_pCompositor->getMonitorFromVector(PLAYER->realPosition->goal() + PLAYER->realSize->goal() / 2.F); + if (!PMONITOR) + return; + animationsDisabled = animationsDisabled || PLAYER->noAnimations; + } + + const auto SPENT = av.getPercent(); + const auto PBEZIER = g_pAnimationManager->getBezier(av.getBezierName()); + const auto POINTY = PBEZIER->getYForPoint(SPENT); + + if constexpr (std::same_as) { + updateColorVariable(av, POINTY, animationsDisabled); + } else { + updateVariable(av, POINTY, animationsDisabled); + } + + av.onUpdate(); + + switch (av.m_Context.eDamagePolicy) { + case AVARDAMAGE_ENTIRE: { + if (PWINDOW) { + PWINDOW->updateWindowDecos(); + g_pHyprRenderer->damageWindow(PWINDOW); + } else if (PWORKSPACE) { + for (auto const& w : g_pCompositor->m_vWindows) { + if (!validMapped(w) || w->m_pWorkspace != PWORKSPACE) + continue; + + w->updateWindowDecos(); + + // damage any workspace window that is on any monitor + if (!w->m_bPinned) + g_pHyprRenderer->damageWindow(w); + } + } else if (PLAYER) { + if (PLAYER->layer <= 1) + g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); + + // some fucking layers miss 1 pixel??? + CBox expandBox = CBox{PLAYER->realPosition->value(), PLAYER->realSize->value()}; + expandBox.expand(5); + g_pHyprRenderer->damageBox(&expandBox); + } + break; + } + case AVARDAMAGE_BORDER: { + RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!"); + + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER); + PDECO->damageEntire(); + + break; + } + case AVARDAMAGE_SHADOW: { + RASSERT(PWINDOW, "Tried to AVARDAMAGE_SHADOW a non-window AVAR!"); + + const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW); + + PDECO->damageEntire(); + + break; + } + default: { + break; + } + } + + // manually schedule a frame + if (PMONITOR) + g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION); } -void CAnimationManager::tick() { +void CHyprAnimationManager::tick() { static std::chrono::time_point lastTick = std::chrono::high_resolution_clock::now(); m_fLastTickTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - lastTick).count() / 1000.0; lastTick = std::chrono::high_resolution_clock::now(); - if (m_vActiveAnimatedVariables.empty()) - return; - - bool animGlobalDisabled = false; - static auto PANIMENABLED = CConfigValue("animations:enabled"); - - if (!*PANIMENABLED) - animGlobalDisabled = true; - - static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:shadow:enabled"); - - const auto DEFAULTBEZIER = m_mBezierCurves.find("default"); - - std::vector animationEndedVars; - - for (auto const& av : m_vActiveAnimatedVariables) { - - if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !*PSHADOWSENABLED) { - av->warp(false); - animationEndedVars.push_back(av); + for (auto const& pav : m_vActiveAnimatedVariables) { + const auto PAV = pav.lock(); + if (!PAV) continue; - } - // get the spent % (0 - 1) - const float SPENT = av->getPercent(); + // for disabled anims just warp + bool warp = !*PANIMENABLED || !PAV->enabled(); - // window stuff - PHLWINDOW PWINDOW = av->m_pWindow.lock(); - PHLWORKSPACE PWORKSPACE = av->m_pWorkspace.lock(); - PHLLS PLAYER = av->m_pLayer.lock(); - PHLMONITOR PMONITOR = nullptr; - bool animationsDisabled = animGlobalDisabled; - - if (PWINDOW) { - if (av->m_eDamagePolicy == AVARDAMAGE_ENTIRE) { - g_pHyprRenderer->damageWindow(PWINDOW); - } else if (av->m_eDamagePolicy == AVARDAMAGE_BORDER) { - const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER); - PDECO->damageEntire(); - } else if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW) { - const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW); - PDECO->damageEntire(); - } - - PMONITOR = PWINDOW->m_pMonitor.lock(); - if (!PMONITOR) - continue; - animationsDisabled = PWINDOW->m_sWindowData.noAnim.valueOr(animationsDisabled); - } else if (PWORKSPACE) { - PMONITOR = PWORKSPACE->m_pMonitor.lock(); - if (!PMONITOR) - continue; - - // dont damage the whole monitor on workspace change, unless it's a special workspace, because dim/blur etc - if (PWORKSPACE->m_bIsSpecialWorkspace) - g_pHyprRenderer->damageMonitor(PMONITOR); - - // TODO: just make this into a damn callback already vax... - for (auto const& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden() || w->m_pWorkspace != PWORKSPACE) - continue; - - if (w->m_bIsFloating && !w->m_bPinned) { - // still doing the full damage hack for floating because sometimes when the window - // goes through multiple monitors the last rendered frame is missing damage somehow?? - const CBox windowBoxNoOffset = w->getFullWindowBoundingBox(); - const CBox monitorBox = {PMONITOR->vecPosition, PMONITOR->vecSize}; - if (windowBoxNoOffset.intersection(monitorBox) != windowBoxNoOffset) // on edges between multiple monitors - g_pHyprRenderer->damageWindow(w, true); - } - - if (PWORKSPACE->m_bIsSpecialWorkspace) - g_pHyprRenderer->damageWindow(w, true); // hack for special too because it can cross multiple monitors - } - - // damage any workspace window that is on any monitor - for (auto const& w : g_pCompositor->m_vWindows) { - if (!validMapped(w) || w->m_pWorkspace != PWORKSPACE || w->m_bPinned) - continue; - - g_pHyprRenderer->damageWindow(w); - } - } else if (PLAYER) { - // "some fucking layers miss 1 pixel???" -- vaxry - CBox expandBox = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()}; - expandBox.expand(5); - g_pHyprRenderer->damageBox(&expandBox); - - PMONITOR = g_pCompositor->getMonitorFromVector(PLAYER->realPosition.goal() + PLAYER->realSize.goal() / 2.F); - if (!PMONITOR) - continue; - animationsDisabled = animationsDisabled || PLAYER->noAnimations; - } - - const bool VISIBLE = PWINDOW && PWINDOW->m_pWorkspace ? PWINDOW->m_pWorkspace->isVisible() : true; - - // beziers are with a switch unforto - // TODO: maybe do something cleaner - - static const auto updateVariable = [this](CAnimatedVariable& av, const float SPENT, const CBezierCurve& DEFAULTBEZIER, const bool DISABLED) { - // for disabled anims just warp - if (av.m_pConfig->pValues->internalEnabled == 0 || DISABLED) { - av.warp(false); - return; - } - - if (SPENT >= 1.f || av.m_Begun == av.m_Goal) { - av.warp(false); - return; - } - - const auto BEZIER = m_mBezierCurves.find(av.m_pConfig->pValues->internalBezier); - const auto POINTY = BEZIER != m_mBezierCurves.end() ? BEZIER->second.getYForPoint(SPENT) : DEFAULTBEZIER.getYForPoint(SPENT); - - const auto DELTA = av.m_Goal - av.m_Begun; - - if (BEZIER != m_mBezierCurves.end()) - av.m_Value = av.m_Begun + DELTA * POINTY; - else - av.m_Value = av.m_Begun + DELTA * POINTY; - }; - - static const auto updateColorVariable = [this](CAnimatedVariable& av, const float SPENT, const CBezierCurve& DEFAULTBEZIER, const bool DISABLED) { - // for disabled anims just warp - if (av.m_pConfig->pValues->internalEnabled == 0 || DISABLED) { - av.warp(false); - return; - } - - if (SPENT >= 1.f || av.m_Begun == av.m_Goal) { - av.warp(false); - return; - } - - const auto BEZIER = m_mBezierCurves.find(av.m_pConfig->pValues->internalBezier); - const auto POINTY = BEZIER != m_mBezierCurves.end() ? BEZIER->second.getYForPoint(SPENT) : DEFAULTBEZIER.getYForPoint(SPENT); - - // convert both to OkLab, then lerp that, and convert back. - // This is not as fast as just lerping rgb, but it's WAY more precise... - // Use the CHyprColor cache for OkLab - - const auto& L1 = av.m_Begun.asOkLab(); - const auto& L2 = av.m_Goal.asOkLab(); - - static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; }; - - const Hyprgraphics::CColor lerped = Hyprgraphics::CColor::SOkLab{ - .l = lerp(L1.l, L2.l, POINTY), - .a = lerp(L1.a, L2.a, POINTY), - .b = lerp(L1.b, L2.b, POINTY), - }; - - av.m_Value = {lerped, lerp(av.m_Begun.a, av.m_Goal.a, POINTY)}; - - return; - }; - - switch (av->m_Type) { + switch (PAV->m_Type) { case AVARTYPE_FLOAT: { - auto typedAv = dynamic_cast*>(av); - updateVariable(*typedAv, SPENT, DEFAULTBEZIER->second, animationsDisabled); - break; - } + auto pTypedAV = dynamic_cast*>(PAV.get()); + RASSERT(pTypedAV, "Failed to upcast animated float"); + handleUpdate(*pTypedAV, warp); + } break; case AVARTYPE_VECTOR: { - auto typedAv = dynamic_cast*>(av); - updateVariable(*typedAv, SPENT, DEFAULTBEZIER->second, animationsDisabled); - break; - } + auto pTypedAV = dynamic_cast*>(PAV.get()); + RASSERT(pTypedAV, "Failed to upcast animated Vector2D"); + handleUpdate(*pTypedAV, warp); + } break; case AVARTYPE_COLOR: { - auto typedAv = dynamic_cast*>(av); - updateColorVariable(*typedAv, SPENT, DEFAULTBEZIER->second, animationsDisabled); - break; - } + auto pTypedAV = dynamic_cast*>(PAV.get()); + RASSERT(pTypedAV, "Failed to upcast animated CHyprColor"); + handleUpdate(*pTypedAV, warp); + } break; default: UNREACHABLE(); } - // set size and pos if valid, but only if damage policy entire (dont if border for example) - if (validMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && !PWINDOW->isX11OverrideRedirect()) - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal()); - - // check if we did not finish animating. If so, trigger onAnimationEnd. - if (!av->isBeingAnimated()) - animationEndedVars.push_back(av); - - // lastly, handle damage, but only if whatever we are animating is visible. - if (!VISIBLE) - continue; - - if (av->m_fUpdateCallback) - av->m_fUpdateCallback(av); - - switch (av->m_eDamagePolicy) { - case AVARDAMAGE_ENTIRE: { - if (PWINDOW) { - PWINDOW->updateWindowDecos(); - g_pHyprRenderer->damageWindow(PWINDOW); - } else if (PWORKSPACE) { - for (auto const& w : g_pCompositor->m_vWindows) { - if (!validMapped(w) || w->m_pWorkspace != PWORKSPACE) - continue; - - w->updateWindowDecos(); - - // damage any workspace window that is on any monitor - if (!w->m_bPinned) - g_pHyprRenderer->damageWindow(w); - } - } else if (PLAYER) { - if (PLAYER->layer <= 1) - g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); - - // some fucking layers miss 1 pixel??? - CBox expandBox = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()}; - expandBox.expand(5); - g_pHyprRenderer->damageBox(&expandBox); - } - break; - } - case AVARDAMAGE_BORDER: { - RASSERT(PWINDOW, "Tried to AVARDAMAGE_BORDER a non-window AVAR!"); - - const auto PDECO = PWINDOW->getDecorationByType(DECORATION_BORDER); - PDECO->damageEntire(); - - break; - } - case AVARDAMAGE_SHADOW: { - RASSERT(PWINDOW, "Tried to AVARDAMAGE_SHADOW a non-window AVAR!"); - - const auto PDECO = PWINDOW->getDecorationByType(DECORATION_SHADOW); - - PDECO->damageEntire(); - - break; - } - default: { - break; - } - } - - // manually schedule a frame - if (PMONITOR) - g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION); } - // do it here, because if this alters the animation vars vec we would be in trouble above. - for (auto const& ave : animationEndedVars) { - ave->onAnimationEnd(); - } + tickDone(); } -bool CAnimationManager::deltaSmallToFlip(const Vector2D& a, const Vector2D& b) { - return std::abs(a.x - b.x) < 0.5f && std::abs(a.y - b.y) < 0.5f; -} +void CHyprAnimationManager::scheduleTick() { + if (m_bTickScheduled) + return; -bool CAnimationManager::deltaSmallToFlip(const CHyprColor& a, const CHyprColor& b) { - return std::abs(a.r - b.r) < 0.5f && std::abs(a.g - b.g) < 0.5f && std::abs(a.b - b.b) < 0.5f && std::abs(a.a - b.a) < 0.5f; -} + m_bTickScheduled = true; -bool CAnimationManager::deltaSmallToFlip(const float& a, const float& b) { - return std::abs(a - b) < 0.5f; -} + const auto PMOSTHZ = g_pHyprRenderer->m_pMostHzMonitor; -bool CAnimationManager::deltazero(const Vector2D& a, const Vector2D& b) { - return a.x == b.x && a.y == b.y; -} - -bool CAnimationManager::deltazero(const float& a, const float& b) { - return a == b; -} - -bool CAnimationManager::deltazero(const CHyprColor& a, const CHyprColor& b) { - return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a; -} - -bool CAnimationManager::bezierExists(const std::string& bezier) { - for (auto const& [bc, bz] : m_mBezierCurves) { - if (bc == bezier) - return true; + if (!PMOSTHZ) { + m_pAnimationTimer->updateTimeout(std::chrono::milliseconds(16)); + return; } - return false; + float refreshDelayMs = std::floor(1000.f / PMOSTHZ->refreshRate); + + const float SINCEPRES = std::chrono::duration_cast(std::chrono::steady_clock::now() - PMOSTHZ->lastPresentationTimer.chrono()).count() / 1000.f; + + const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it + + m_pAnimationTimer->updateTimeout(std::chrono::milliseconds((int)std::floor(TOPRES))); +} + +void CHyprAnimationManager::onTicked() { + m_bTickScheduled = false; } // @@ -351,24 +277,24 @@ bool CAnimationManager::bezierExists(const std::string& bezier) { // // -void CAnimationManager::animationPopin(PHLWINDOW pWindow, bool close, float minPerc) { - const auto GOALPOS = pWindow->m_vRealPosition.goal(); - const auto GOALSIZE = pWindow->m_vRealSize.goal(); +void CHyprAnimationManager::animationPopin(PHLWINDOW pWindow, bool close, float minPerc) { + const auto GOALPOS = pWindow->m_vRealPosition->goal(); + const auto GOALSIZE = pWindow->m_vRealSize->goal(); if (!close) { - pWindow->m_vRealSize.setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y})); - pWindow->m_vRealPosition.setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_Value / 2.f); + pWindow->m_vRealSize->setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y})); + pWindow->m_vRealPosition->setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize->value() / 2.f); } else { - pWindow->m_vRealSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}); - pWindow->m_vRealPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_Goal / 2.f; + *pWindow->m_vRealSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}); + *pWindow->m_vRealPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize->goal() / 2.f; } } -void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, bool close) { - pWindow->m_vRealSize.warp(false); // size we preserve in slide +void CHyprAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, bool close) { + pWindow->m_vRealSize->warp(false); // size we preserve in slide - const auto GOALPOS = pWindow->m_vRealPosition.goal(); - const auto GOALSIZE = pWindow->m_vRealSize.goal(); + const auto GOALPOS = pWindow->m_vRealPosition->goal(); + const auto GOALSIZE = pWindow->m_vRealSize->goal(); const auto PMONITOR = pWindow->m_pMonitor.lock(); @@ -388,9 +314,9 @@ void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, boo posOffset = Vector2D(GOALPOS.x, PMONITOR->vecPosition.y - GOALSIZE.y); if (!close) - pWindow->m_vRealPosition.setValue(posOffset); + pWindow->m_vRealPosition->setValue(posOffset); else - pWindow->m_vRealPosition = posOffset; + *pWindow->m_vRealPosition = posOffset; return; } @@ -423,33 +349,33 @@ void CAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, boo } if (!close) - pWindow->m_vRealPosition.setValue(posOffset); + pWindow->m_vRealPosition->setValue(posOffset); else - pWindow->m_vRealPosition = posOffset; + *pWindow->m_vRealPosition = posOffset; } -void CAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) { +void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) { if (!close) { - pWindow->m_vRealPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsIn"); - pWindow->m_vRealSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsIn"); - pWindow->m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeIn"); + pWindow->m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn")); + pWindow->m_vRealSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn")); + pWindow->m_fAlpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn")); } else { - pWindow->m_vRealPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsOut"); - pWindow->m_vRealSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("windowsOut"); - pWindow->m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeOut"); + pWindow->m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut")); + pWindow->m_vRealSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut")); + pWindow->m_fAlpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut")); } - auto ANIMSTYLE = pWindow->m_vRealPosition.m_pConfig->pValues->internalStyle; + std::string ANIMSTYLE = pWindow->m_vRealPosition->getStyle(); transform(ANIMSTYLE.begin(), ANIMSTYLE.end(), ANIMSTYLE.begin(), ::tolower); CVarList animList(ANIMSTYLE, 0, 's'); // if the window is not being animated, that means the layout set a fixed size for it, don't animate. - if (!pWindow->m_vRealPosition.isBeingAnimated() && !pWindow->m_vRealSize.isBeingAnimated()) + if (!pWindow->m_vRealPosition->isBeingAnimated() && !pWindow->m_vRealSize->isBeingAnimated()) return; // if the animation is disabled and we are leaving, ignore the anim to prevent the snapshot being fucked - if (!pWindow->m_vRealPosition.m_pConfig->pValues->internalEnabled) + if (!pWindow->m_vRealPosition->enabled()) return; if (pWindow->m_sWindowData.animationStyle.hasValue()) { @@ -494,7 +420,7 @@ void CAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) { } } -std::string CAnimationManager::styleValidInConfigVar(const std::string& config, const std::string& style) { +std::string CHyprAnimationManager::styleValidInConfigVar(const std::string& config, const std::string& style) { if (config.starts_with("window")) { if (style.starts_with("slide")) return ""; @@ -568,39 +494,3 @@ std::string CAnimationManager::styleValidInConfigVar(const std::string& config, return ""; } - -CBezierCurve* CAnimationManager::getBezier(const std::string& name) { - const auto BEZIER = std::find_if(m_mBezierCurves.begin(), m_mBezierCurves.end(), [&](const auto& other) { return other.first == name; }); - - return BEZIER == m_mBezierCurves.end() ? &m_mBezierCurves["default"] : &BEZIER->second; -} - -std::unordered_map CAnimationManager::getAllBeziers() { - return m_mBezierCurves; -} - -bool CAnimationManager::shouldTickForNext() { - return !m_vActiveAnimatedVariables.empty(); -} - -void CAnimationManager::scheduleTick() { - if (m_bTickScheduled) - return; - - m_bTickScheduled = true; - - const auto PMOSTHZ = g_pHyprRenderer->m_pMostHzMonitor; - - if (!PMOSTHZ) { - m_pAnimationTimer->updateTimeout(std::chrono::milliseconds(16)); - return; - } - - float refreshDelayMs = std::floor(1000.f / PMOSTHZ->refreshRate); - - const float SINCEPRES = std::chrono::duration_cast(std::chrono::steady_clock::now() - PMOSTHZ->lastPresentationTimer.chrono()).count() / 1000.f; - - const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it - - m_pAnimationTimer->updateTimeout(std::chrono::milliseconds((int)std::floor(TOPRES))); -} diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index 3960f261..7bf73f97 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -1,57 +1,64 @@ #pragma once +#include +#include + #include "../defines.hpp" -#include -#include #include "../helpers/AnimatedVariable.hpp" -#include "../helpers/BezierCurve.hpp" -#include "../helpers/Timer.hpp" +#include "desktop/DesktopTypes.hpp" #include "eventLoop/EventLoopTimer.hpp" -class CWindow; - -class CAnimationManager { +class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { public: - CAnimationManager(); + CHyprAnimationManager(); - void tick(); - bool shouldTickForNext(); - void onTicked(); - void scheduleTick(); - void addBezierWithName(std::string, const Vector2D&, const Vector2D&); - void removeAllBeziers(); + void tick(); + virtual void scheduleTick(); + virtual void onTicked(); - void onWindowPostCreateClose(PHLWINDOW, bool close = false); + using SAnimationPropertyConfig = Hyprutils::Animation::SAnimationPropertyConfig; + template + void createAnimation(const VarType& v, PHLANIMVAR& pav, SP pConfig, eAVarDamagePolicy policy) { + constexpr const eAnimatedVarType EAVTYPE = typeToeAnimatedVarType; + const auto PAV = makeShared>(); - bool bezierExists(const std::string&); - CBezierCurve* getBezier(const std::string&); + PAV->create(EAVTYPE, static_cast(this), PAV, v); + PAV->setConfig(pConfig); + PAV->m_Context.eDamagePolicy = policy; - std::string styleValidInConfigVar(const std::string&, const std::string&); + pav = std::move(PAV); + } - std::unordered_map getAllBeziers(); + template + void createAnimation(const VarType& v, PHLANIMVAR& pav, SP pConfig, PHLWINDOW pWindow, eAVarDamagePolicy policy) { + createAnimation(v, pav, pConfig, policy); + pav->m_Context.pWindow = pWindow; + } + template + void createAnimation(const VarType& v, PHLANIMVAR& pav, SP pConfig, PHLWORKSPACE pWorkspace, eAVarDamagePolicy policy) { + createAnimation(v, pav, pConfig, policy); + pav->m_Context.pWorkspace = pWorkspace; + } + template + void createAnimation(const VarType& v, PHLANIMVAR& pav, SP pConfig, PHLLS pLayer, eAVarDamagePolicy policy) { + createAnimation(v, pav, pConfig, policy); + pav->m_Context.pLayer = pLayer; + } - std::vector m_vAnimatedVariables; - std::vector m_vActiveAnimatedVariables; + void onWindowPostCreateClose(PHLWINDOW, bool close = false); - SP m_pAnimationTimer; + std::string styleValidInConfigVar(const std::string&, const std::string&); - float m_fLastTickTime; // in ms + SP m_pAnimationTimer; + + float m_fLastTickTime; // in ms private: - bool deltaSmallToFlip(const Vector2D& a, const Vector2D& b); - bool deltaSmallToFlip(const CHyprColor& a, const CHyprColor& b); - bool deltaSmallToFlip(const float& a, const float& b); - bool deltazero(const Vector2D& a, const Vector2D& b); - bool deltazero(const CHyprColor& a, const CHyprColor& b); - bool deltazero(const float& a, const float& b); - - std::unordered_map m_mBezierCurves; - - bool m_bTickScheduled = false; + bool m_bTickScheduled = false; // Anim stuff void animationPopin(PHLWINDOW, bool close = false, float minPerc = 0.f); void animationSlide(PHLWINDOW, std::string force = "", bool close = false); }; -inline std::unique_ptr g_pAnimationManager; +inline std::unique_ptr g_pAnimationManager; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index d368d14c..fd4992eb 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -377,8 +377,8 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE); // warp the position + size animation, otherwise it looks weird. - PWINDOWTOCHANGETO->m_vRealPosition.warp(); - PWINDOWTOCHANGETO->m_vRealSize.warp(); + PWINDOWTOCHANGETO->m_vRealPosition->warp(); + PWINDOWTOCHANGETO->m_vRealSize->warp(); } else { updateRelativeCursorCoords(); g_pCompositor->focusWindow(PWINDOWTOCHANGETO); @@ -1070,8 +1070,8 @@ SDispatchResult CKeybindManager::centerWindow(std::string args) { if (args == "1") RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f; - PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goal() / 2.f + RESERVEDOFFSET; - PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goal(); + *PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize->goal() / 2.f + RESERVEDOFFSET; + PWINDOW->m_vPosition = PWINDOW->m_vRealPosition->goal(); return {}; } @@ -1557,14 +1557,14 @@ SDispatchResult CKeybindManager::moveActiveTo(std::string args) { switch (arg) { case 'l': vPosx = PMONITOR->vecReservedTopLeft.x + BORDERSIZE + PMONITOR->vecPosition.x; break; - case 'r': vPosx = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PLASTWINDOW->m_vRealSize.goal().x - BORDERSIZE + PMONITOR->vecPosition.x; break; + case 'r': vPosx = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PLASTWINDOW->m_vRealSize->goal().x - BORDERSIZE + PMONITOR->vecPosition.x; break; case 't': case 'u': vPosy = PMONITOR->vecReservedTopLeft.y + BORDERSIZE + PMONITOR->vecPosition.y; break; case 'b': - case 'd': vPosy = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PLASTWINDOW->m_vRealSize.goal().y - BORDERSIZE + PMONITOR->vecPosition.y; break; + case 'd': vPosy = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PLASTWINDOW->m_vRealSize->goal().y - BORDERSIZE + PMONITOR->vecPosition.y; break; } - PLASTWINDOW->m_vRealPosition = Vector2D(vPosx.value_or(PLASTWINDOW->m_vRealPosition.goal().x), vPosy.value_or(PLASTWINDOW->m_vRealPosition.goal().y)); + *PLASTWINDOW->m_vRealPosition = Vector2D(vPosx.value_or(PLASTWINDOW->m_vRealPosition->goal().x), vPosy.value_or(PLASTWINDOW->m_vRealPosition->goal().y)); return {}; } @@ -1735,20 +1735,20 @@ SDispatchResult CKeybindManager::moveCursorToCorner(std::string arg) { switch (CORNER) { case 0: // bottom left - g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y}, true); + g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition->value().x, PWINDOW->m_vRealPosition->value().y + PWINDOW->m_vRealSize->value().y}, true); break; case 1: // bottom right - g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y}, - true); + g_pCompositor->warpCursorTo( + {PWINDOW->m_vRealPosition->value().x + PWINDOW->m_vRealSize->value().x, PWINDOW->m_vRealPosition->value().y + PWINDOW->m_vRealSize->value().y}, true); break; case 2: // top right - g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealPosition.value().y}, true); + g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition->value().x + PWINDOW->m_vRealSize->value().x, PWINDOW->m_vRealPosition->value().y}, true); break; case 3: // top left - g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y}, true); + g_pCompositor->warpCursorTo({PWINDOW->m_vRealPosition->value().x, PWINDOW->m_vRealPosition->value().y}, true); break; } @@ -1817,18 +1817,18 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) { continue; if (!w->m_bRequestsFloat && w->m_bIsFloating != PWORKSPACE->m_bDefaultFloating) { - const auto SAVEDPOS = w->m_vRealPosition.value(); - const auto SAVEDSIZE = w->m_vRealSize.value(); + const auto SAVEDPOS = w->m_vRealPosition->value(); + const auto SAVEDSIZE = w->m_vRealSize->value(); w->m_bIsFloating = PWORKSPACE->m_bDefaultFloating; g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(w); if (PWORKSPACE->m_bDefaultFloating) { - w->m_vRealPosition.setValueAndWarp(SAVEDPOS); - w->m_vRealSize.setValueAndWarp(SAVEDSIZE); + w->m_vRealPosition->setValueAndWarp(SAVEDPOS); + w->m_vRealSize->setValueAndWarp(SAVEDSIZE); g_pXWaylandManager->setWindowSize(w, SAVEDSIZE); - w->m_vRealSize = w->m_vRealSize.value() + Vector2D(4, 4); - w->m_vRealPosition = w->m_vRealPosition.value() - Vector2D(2, 2); + *w->m_vRealSize = w->m_vRealSize->value() + Vector2D(4, 4); + *w->m_vRealPosition = w->m_vRealPosition->value() - Vector2D(2, 2); } } } @@ -2043,14 +2043,14 @@ SDispatchResult CKeybindManager::resizeActive(std::string args) { if (!PLASTWINDOW || PLASTWINDOW->isFullscreen()) return {}; - const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_vRealSize.goal()); + const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_vRealSize->goal()); if (SIZ.x < 1 || SIZ.y < 1) return {}; - g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PLASTWINDOW->m_vRealSize.goal()); + g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PLASTWINDOW->m_vRealSize->goal()); - if (PLASTWINDOW->m_vRealSize.goal().x > 1 && PLASTWINDOW->m_vRealSize.goal().y > 1) + if (PLASTWINDOW->m_vRealSize->goal().x > 1 && PLASTWINDOW->m_vRealSize->goal().y > 1) PLASTWINDOW->setHidden(false); return {}; @@ -2062,9 +2062,9 @@ SDispatchResult CKeybindManager::moveActive(std::string args) { if (!PLASTWINDOW || PLASTWINDOW->isFullscreen()) return {}; - const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_vRealPosition.goal()); + const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_vRealPosition->goal()); - g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PLASTWINDOW->m_vRealPosition.goal()); + g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PLASTWINDOW->m_vRealPosition->goal()); return {}; } @@ -2084,9 +2084,9 @@ SDispatchResult CKeybindManager::moveWindow(std::string args) { if (PWINDOW->isFullscreen()) return {}; - const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition.goal()); + const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition->goal()); - g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition.goal(), PWINDOW); + g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition->goal(), PWINDOW); return {}; } @@ -2106,14 +2106,14 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) { if (PWINDOW->isFullscreen()) return {}; - const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goal()); + const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize->goal()); if (SIZ.x < 1 || SIZ.y < 1) return {}; - g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goal(), CORNER_NONE, PWINDOW); + g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize->goal(), CORNER_NONE, PWINDOW); - if (PWINDOW->m_vRealSize.goal().x > 1 && PWINDOW->m_vRealSize.goal().y > 1) + if (PWINDOW->m_vRealSize->goal().x > 1 && PWINDOW->m_vRealSize->goal().y > 1) PWINDOW->setHidden(false); return {}; @@ -2192,8 +2192,8 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) { g_pCompositor->setWindowFullscreenClient(PWINDOW, FSMODE); // warp the position + size animation, otherwise it looks weird. - PWINDOW->m_vRealPosition.warp(); - PWINDOW->m_vRealSize.warp(); + PWINDOW->m_vRealPosition->warp(); + PWINDOW->m_vRealSize->warp(); } } else g_pCompositor->focusWindow(PWINDOW); @@ -2311,7 +2311,7 @@ SDispatchResult CKeybindManager::pass(std::string regexp) { } } - const auto SL = PWINDOW->m_vRealPosition.goal() - g_pInputManager->getMouseCoordsInternal(); + const auto SL = PWINDOW->m_vRealPosition->goal() - g_pInputManager->getMouseCoordsInternal(); if (g_pKeybindManager->m_uLastCode != 0) g_pSeatManager->setKeyboardFocus(LASTKBSURF); @@ -2466,7 +2466,7 @@ SDispatchResult CKeybindManager::sendshortcut(std::string args) { } } - const auto SL = PWINDOW->m_vRealPosition.goal() - g_pInputManager->getMouseCoordsInternal(); + const auto SL = PWINDOW->m_vRealPosition->goal() - g_pInputManager->getMouseCoordsInternal(); if (!isMouse) g_pSeatManager->setKeyboardFocus(LASTSURFACE); diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index ca31752d..bc988f39 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -55,7 +55,7 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { if (pWindow->m_bIsX11) { if (activate) { - setWindowSize(pWindow, pWindow->m_vRealSize.value()); // update xwayland output pos + setWindowSize(pWindow, pWindow->m_vRealSize->value()); // update xwayland output pos pWindow->m_pXWaylandSurface->setMinimized(false); if (!pWindow->isX11OverrideRedirect()) @@ -123,7 +123,7 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool // calculate pos // TODO: this should be decoupled from setWindowSize IMO - Vector2D windowPos = pWindow->m_vRealPosition.value(); + Vector2D windowPos = pWindow->m_vRealPosition->value(); if (pWindow->m_bIsX11 && PMONITOR) { windowPos -= PMONITOR->vecPosition; // normalize to monitor @@ -273,4 +273,4 @@ Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) { result += pMonitor->vecPosition; return result; -} \ No newline at end of file +} diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index cccaa43e..8a50a7bf 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -137,7 +137,7 @@ void CInputManager::sendMotionEventsToFocused() { timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_vRealPosition.goal() : (PLS ? Vector2D{PLS->geometry.x, PLS->geometry.y} : Vector2D{})); + const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_vRealPosition->goal() : (PLS ? Vector2D{PLS->geometry.x, PLS->geometry.y} : Vector2D{})); m_bEmptyFocusCursorSet = false; @@ -243,7 +243,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { if (forcedFocus) { pFoundWindow = forcedFocus; - surfacePos = pFoundWindow->m_vRealPosition.value(); + surfacePos = pFoundWindow->m_vRealPosition->value(); foundSurface = pFoundWindow->m_pWLSurface->resource(); } @@ -320,7 +320,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { surfacePos = Vector2D(-1337, -1337); } else { foundSurface = pFoundWindow->m_pWLSurface->resource(); - surfacePos = pFoundWindow->m_vRealPosition.value(); + surfacePos = pFoundWindow->m_vRealPosition->value(); } } @@ -362,11 +362,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); if (!foundSurface) { foundSurface = pFoundWindow->m_pWLSurface->resource(); - surfacePos = pFoundWindow->m_vRealPosition.value(); + surfacePos = pFoundWindow->m_vRealPosition->value(); } } else { foundSurface = pFoundWindow->m_pWLSurface->resource(); - surfacePos = pFoundWindow->m_vRealPosition.value(); + surfacePos = pFoundWindow->m_vRealPosition->value(); } } } @@ -689,7 +689,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) { // TODO detect click on LS properly if (*PRESIZEONBORDER && !m_bLastFocusOnLS && e.state == WL_POINTER_BUTTON_STATE_PRESSED && (!w || !w->isX11OverrideRedirect())) { if (w && !w->isFullscreen()) { - const CBox real = {w->m_vRealPosition.value().x, w->m_vRealPosition.value().y, w->m_vRealSize.value().x, w->m_vRealSize.value().y}; + const CBox real = {w->m_vRealPosition->value().x, w->m_vRealPosition->value().y, w->m_vRealSize->value().x, w->m_vRealSize->value().y}; const CBox grab = {real.x - BORDER_GRAB_AREA, real.y - BORDER_GRAB_AREA, real.width + 2 * BORDER_GRAB_AREA, real.height + 2 * BORDER_GRAB_AREA}; if ((grab.containsPoint(mouseCoords) && (!real.containsPoint(mouseCoords) || w->isInCurvedCorner(mouseCoords.x, mouseCoords.y))) && !w->hasPopupAt(mouseCoords)) { diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 6cfe5a24..3e03c4c7 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -38,7 +38,7 @@ void CInputManager::beginWorkspaceSwipe() { if (PWORKSPACE->m_bHasFullscreenWindow) { for (auto const& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLayers[2]) { - ls->alpha = 1.f; + *ls->alpha = 1.f; } } } @@ -58,8 +58,8 @@ void CInputManager::endWorkspaceSwipe() { static auto PSWIPENEW = CConfigValue("gestures:workspace_swipe_create_new"); static auto PSWIPEUSER = CConfigValue("gestures:workspace_swipe_use_r"); static auto PWORKSPACEGAP = CConfigValue("general:gaps_workspaces"); - const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + const auto ANIMSTYLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->getStyle(); + const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert"); // commit auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id; @@ -86,7 +86,7 @@ void CInputManager::endWorkspaceSwipe() { auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER - const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.value(); + const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->value(); const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP; const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; @@ -97,35 +97,35 @@ void CInputManager::endWorkspaceSwipe() { // revert if (abs(m_sActiveSwipe.delta) < 2) { if (PWORKSPACEL) - PWORKSPACEL->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); + PWORKSPACEL->m_vRenderOffset->setValueAndWarp(Vector2D(0, 0)); if (PWORKSPACER) - PWORKSPACER->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0)); + PWORKSPACER->m_vRenderOffset->setValueAndWarp(Vector2D(0, 0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(0, 0)); } else { if (m_sActiveSwipe.delta < 0) { // to left if (PWORKSPACEL) { if (VERTANIMS) - PWORKSPACEL->m_vRenderOffset = Vector2D{0.0, -YDISTANCE}; + *PWORKSPACEL->m_vRenderOffset = Vector2D{0.0, -YDISTANCE}; else - PWORKSPACEL->m_vRenderOffset = Vector2D{-XDISTANCE, 0.0}; + *PWORKSPACEL->m_vRenderOffset = Vector2D{-XDISTANCE, 0.0}; } } else if (PWORKSPACER) { // to right if (VERTANIMS) - PWORKSPACER->m_vRenderOffset = Vector2D{0.0, YDISTANCE}; + *PWORKSPACER->m_vRenderOffset = Vector2D{0.0, YDISTANCE}; else - PWORKSPACER->m_vRenderOffset = Vector2D{XDISTANCE, 0.0}; + *PWORKSPACER->m_vRenderOffset = Vector2D{XDISTANCE, 0.0}; } - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(); + *m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(); } pSwitchedTo = m_sActiveSwipe.pWorkspaceBegin; } else if (m_sActiveSwipe.delta < 0) { // switch to left - const auto RENDEROFFSET = PWORKSPACEL ? PWORKSPACEL->m_vRenderOffset.value() : Vector2D(); + const auto RENDEROFFSET = PWORKSPACEL ? PWORKSPACEL->m_vRenderOffset->value() : Vector2D(); if (PWORKSPACEL) m_sActiveSwipe.pMonitor->changeWorkspace(workspaceIDLeft); @@ -134,15 +134,15 @@ void CInputManager::endWorkspaceSwipe() { PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); } - PWORKSPACEL->m_vRenderOffset.setValue(RENDEROFFSET); - PWORKSPACEL->m_fAlpha.setValueAndWarp(1.f); + PWORKSPACEL->m_vRenderOffset->setValue(RENDEROFFSET); + PWORKSPACEL->m_fAlpha->setValueAndWarp(1.f); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValue(RENDEROFFSETMIDDLE); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0.0, YDISTANCE); + *m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0.0, YDISTANCE); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(XDISTANCE, 0.0); - m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(1.f); + *m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(XDISTANCE, 0.0); + m_sActiveSwipe.pWorkspaceBegin->m_fAlpha->setValueAndWarp(1.f); g_pInputManager->unconstrainMouse(); @@ -151,7 +151,7 @@ void CInputManager::endWorkspaceSwipe() { pSwitchedTo = PWORKSPACEL; } else { // switch to right - const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_vRenderOffset.value() : Vector2D(); + const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_vRenderOffset->value() : Vector2D(); if (PWORKSPACER) m_sActiveSwipe.pMonitor->changeWorkspace(workspaceIDRight); @@ -160,15 +160,15 @@ void CInputManager::endWorkspaceSwipe() { PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); } - PWORKSPACER->m_vRenderOffset.setValue(RENDEROFFSET); - PWORKSPACER->m_fAlpha.setValueAndWarp(1.f); + PWORKSPACER->m_vRenderOffset->setValue(RENDEROFFSET); + PWORKSPACER->m_fAlpha->setValueAndWarp(1.f); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValue(RENDEROFFSETMIDDLE); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0.0, -YDISTANCE); + *m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(0.0, -YDISTANCE); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(-XDISTANCE, 0.0); - m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(1.f); + *m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D(-XDISTANCE, 0.0); + m_sActiveSwipe.pWorkspaceBegin->m_fAlpha->setValueAndWarp(1.f); g_pInputManager->unconstrainMouse(); @@ -193,7 +193,7 @@ void CInputManager::endWorkspaceSwipe() { // apply alpha for (auto const& ls : g_pCompositor->m_pLastMonitor->m_aLayerSurfaceLayers[2]) { - ls->alpha = pSwitchedTo->m_bHasFullscreenWindow && pSwitchedTo->m_efFullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f; + *ls->alpha = pSwitchedTo->m_bHasFullscreenWindow && pSwitchedTo->m_efFullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f; } } @@ -202,30 +202,30 @@ void CInputManager::onSwipeUpdate(IPointer::SSwipeUpdateEvent e) { if (!m_sActiveSwipe.pWorkspaceBegin) return; - static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); - const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); + const auto ANIMSTYLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->getStyle(); + const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert"); const double delta = m_sActiveSwipe.delta + (VERTANIMS ? (*PSWIPEINVR ? -e.delta.y : e.delta.y) : (*PSWIPEINVR ? -e.delta.x : e.delta.x)); updateWorkspaceSwipe(delta); } void CInputManager::updateWorkspaceSwipe(double delta) { - static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); - static auto PSWIPENEW = CConfigValue("gestures:workspace_swipe_create_new"); - static auto PSWIPEDIRLOCK = CConfigValue("gestures:workspace_swipe_direction_lock"); - static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue("gestures:workspace_swipe_direction_lock_threshold"); - static auto PSWIPEFOREVER = CConfigValue("gestures:workspace_swipe_forever"); - static auto PSWIPEUSER = CConfigValue("gestures:workspace_swipe_use_r"); - static auto PWORKSPACEGAP = CConfigValue("general:gaps_workspaces"); + static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); + static auto PSWIPENEW = CConfigValue("gestures:workspace_swipe_create_new"); + static auto PSWIPEDIRLOCK = CConfigValue("gestures:workspace_swipe_direction_lock"); + static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue("gestures:workspace_swipe_direction_lock_threshold"); + static auto PSWIPEFOREVER = CConfigValue("gestures:workspace_swipe_forever"); + static auto PSWIPEUSER = CConfigValue("gestures:workspace_swipe_use_r"); + static auto PWORKSPACEGAP = CConfigValue("general:gaps_workspaces"); - const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, (int64_t)1LL, (int64_t)UINT32_MAX); - const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP; - const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; - const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); - const double d = m_sActiveSwipe.delta - delta; - m_sActiveSwipe.delta = delta; + const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, (int64_t)1LL, (int64_t)UINT32_MAX); + const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP; + const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; + const auto ANIMSTYLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->getStyle(); + const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert"); + const double d = m_sActiveSwipe.delta - delta; + m_sActiveSwipe.delta = delta; m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(d)) / (m_sActiveSwipe.speedPoints + 1); m_sActiveSwipe.speedPoints++; @@ -265,9 +265,9 @@ void CInputManager::updateWorkspaceSwipe(double delta) { g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock()); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); m_sActiveSwipe.pWorkspaceBegin->updateWindowDecos(); return; @@ -277,23 +277,23 @@ void CInputManager::updateWorkspaceSwipe(double delta) { } PWORKSPACE->m_bForceRendering = true; - PWORKSPACE->m_fAlpha.setValueAndWarp(1.f); + PWORKSPACE->m_fAlpha->setValueAndWarp(1.f); if (workspaceIDLeft != workspaceIDRight && workspaceIDRight != m_sActiveSwipe.pWorkspaceBegin->m_iID) { const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); if (PWORKSPACER) { PWORKSPACER->m_bForceRendering = false; - PWORKSPACER->m_fAlpha.setValueAndWarp(0.f); + PWORKSPACER->m_fAlpha->setValueAndWarp(0.f); } } if (VERTANIMS) { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE - YDISTANCE)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + PWORKSPACE->m_vRenderOffset->setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE - YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); } else { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE - XDISTANCE, 0.0)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); + PWORKSPACE->m_vRenderOffset->setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE - XDISTANCE, 0.0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); } PWORKSPACE->updateWindowDecos(); @@ -305,9 +305,9 @@ void CInputManager::updateWorkspaceSwipe(double delta) { g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor.lock()); if (VERTANIMS) - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); else - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); m_sActiveSwipe.pWorkspaceBegin->updateWindowDecos(); return; @@ -317,23 +317,23 @@ void CInputManager::updateWorkspaceSwipe(double delta) { } PWORKSPACE->m_bForceRendering = true; - PWORKSPACE->m_fAlpha.setValueAndWarp(1.f); + PWORKSPACE->m_fAlpha->setValueAndWarp(1.f); if (workspaceIDLeft != workspaceIDRight && workspaceIDLeft != m_sActiveSwipe.pWorkspaceBegin->m_iID) { const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); if (PWORKSPACEL) { PWORKSPACEL->m_bForceRendering = false; - PWORKSPACEL->m_fAlpha.setValueAndWarp(0.f); + PWORKSPACEL->m_fAlpha->setValueAndWarp(0.f); } } if (VERTANIMS) { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE + YDISTANCE)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); + PWORKSPACE->m_vRenderOffset->setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE + YDISTANCE)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(0.0, ((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * YDISTANCE)); } else { - PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE + XDISTANCE, 0.0)); - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); + PWORKSPACE->m_vRenderOffset->setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE + XDISTANCE, 0.0)); + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0)); } PWORKSPACE->updateWindowDecos(); diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index aba54387..d7ebfe87 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -69,7 +69,7 @@ static void refocusTablet(SP tab, SP tool, bool motion = f // yes, this technically ignores any regions set by the app. Too bad! if (LASTHLSURFACE->getWindow()) - local = tool->absolutePos * LASTHLSURFACE->getWindow()->m_vRealSize.goal(); + local = tool->absolutePos * LASTHLSURFACE->getWindow()->m_vRealSize->goal(); else local = tool->absolutePos * BOX->size(); diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 4e3980aa..7212ba61 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -3,6 +3,7 @@ #include "../../config/ConfigValue.hpp" #include "../../devices/ITouch.hpp" #include "../SeatManager.hpp" +#include "managers/AnimationManager.hpp" void CInputManager::onTouchDown(ITouch::SDownEvent e) { m_bLastInputTouch = true; @@ -36,9 +37,9 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) { return; // TODO: Don't swipe if you touched a floating window. } else if (*PSWIPETOUCH && (m_pFoundLSToFocus.expired() || m_pFoundLSToFocus->layer <= 1)) { - const auto PWORKSPACE = PMONITOR->activeWorkspace; - const bool VERTANIMS = PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || - PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + const auto PWORKSPACE = PMONITOR->activeWorkspace; + const auto STYLE = PWORKSPACE->m_vRenderOffset->getStyle(); + const bool VERTANIMS = STYLE == "slidevert" || STYLE.starts_with("slidefadevert"); const double TARGETLEFT = ((VERTANIMS ? gapsOut.top : gapsOut.left) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x); const double TARGETRIGHT = 1 - (((VERTANIMS ? gapsOut.bottom : gapsOut.right) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x)); const double POSITION = (VERTANIMS ? e.pos.y : e.pos.x); @@ -62,8 +63,8 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) { if (!m_sTouchData.touchFocusWindow.expired()) { if (m_sTouchData.touchFocusWindow->m_bIsX11) { - local = (g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusWindow->m_vRealPosition.goal()) * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy; - m_sTouchData.touchSurfaceOrigin = m_sTouchData.touchFocusWindow->m_vRealPosition.goal(); + local = (g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusWindow->m_vRealPosition->goal()) * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy; + m_sTouchData.touchSurfaceOrigin = m_sTouchData.touchFocusWindow->m_vRealPosition->goal(); } else { g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), m_sTouchData.touchFocusWindow.lock(), local); m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local; @@ -101,8 +102,9 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) { // Do nothing if this is using a different finger. if (e.touchID != m_sActiveSwipe.touch_id) return; - const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || - m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + + const auto ANIMSTYLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset->getStyle(); + const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert"); static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_touch_invert"); static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, (int64_t)1LL, (int64_t)UINT32_MAX); diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index 250c6326..fd7cdcd6 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -3,6 +3,7 @@ #include "../render/Renderer.hpp" #include "core/Output.hpp" #include "../config/ConfigValue.hpp" +#include "managers/AnimationManager.hpp" CHyprlandCTMControlResource::CHyprlandCTMControlResource(SP resource_) : resource(resource_) { if (!good()) @@ -92,8 +93,7 @@ bool CHyprlandCTMControlProtocol::isCTMAnimationEnabled() { } CHyprlandCTMControlProtocol::SCTMData::SCTMData() { - progress.create(g_pConfigManager->getAnimationPropertyConfig("__internal_fadeCTM"), AVARDAMAGE_NONE); - progress.setValueAndWarp(0.F); + g_pAnimationManager->createAnimation(0.f, progress, g_pConfigManager->getAnimationPropertyConfig("__internal_fadeCTM"), AVARDAMAGE_NONE); } void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) { @@ -112,18 +112,18 @@ void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) data->ctmFrom = data->ctmTo; data->ctmTo = ctm; - data->progress.setValueAndWarp(0.F); - data->progress = 1.F; + data->progress->setValueAndWarp(0.F); + *data->progress = 1.F; monitor->setCTM(data->ctmFrom); - data->progress.setUpdateCallback([monitor = PHLMONITORREF{monitor}, this](void* self) { + data->progress->setUpdateCallback([monitor = PHLMONITORREF{monitor}, this](auto) { if (!monitor || !m_mCTMDatas.contains(monitor)) return; auto& data = m_mCTMDatas.at(monitor); const auto from = data->ctmFrom.getMatrix(); const auto to = data->ctmTo.getMatrix(); - const auto PROGRESS = data->progress.getPercent(); + const auto PROGRESS = data->progress->getPercent(); static const auto lerp = [](const float one, const float two, const float progress) -> float { return one + (two - one) * progress; }; @@ -135,7 +135,7 @@ void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) monitor->setCTM(mtx); }); - data->progress.setCallbackOnEnd([monitor = PHLMONITORREF{monitor}, this](void* self) { + data->progress->setCallbackOnEnd([monitor = PHLMONITORREF{monitor}, this](auto) { if (!monitor || !m_mCTMDatas.contains(monitor)) { monitor->setCTM(Mat3x3::identity()); return; diff --git a/src/protocols/CTMControl.hpp b/src/protocols/CTMControl.hpp index dea2c258..2639d176 100644 --- a/src/protocols/CTMControl.hpp +++ b/src/protocols/CTMControl.hpp @@ -42,8 +42,8 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { // struct SCTMData { SCTMData(); - Mat3x3 ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity(); - CAnimatedVariable progress; + Mat3x3 ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity(); + PHLANIMVAR progress; }; std::map> m_mCTMDatas; diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index f5fbaa0c..2c934b40 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -119,7 +119,7 @@ CToplevelExportFrame::CToplevelExportFrame(SP re dmabufFormat = PMONITOR->output->state->state().drmFormat; - box = {0, 0, (int)(pWindow->m_vRealSize.value().x * PMONITOR->scale), (int)(pWindow->m_vRealSize.value().y * PMONITOR->scale)}; + box = {0, 0, (int)(pWindow->m_vRealSize->value().x * PMONITOR->scale), (int)(pWindow->m_vRealSize->value().y * PMONITOR->scale)}; box.transform(wlTransformToHyprutils(PMONITOR->transform), PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y).round(); @@ -263,7 +263,7 @@ bool CToplevelExportFrame::copyShm(timespec* now) { g_pHyprRenderer->m_bBlockSurfaceFeedback = false; if (overlayCursor) - g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.value()); + g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition->value()); const auto PFORMAT = NFormatUtils::getPixelFormatFromDRM(shm.format); if (!PFORMAT) { @@ -315,7 +315,7 @@ bool CToplevelExportFrame::copyDmabuf(timespec* now) { g_pHyprRenderer->m_bBlockSurfaceFeedback = false; if (overlayCursor) - g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.value()); + g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition->value()); g_pHyprOpenGL->m_RenderData.blockScreenShader = true; g_pHyprRenderer->endRender(); @@ -386,7 +386,7 @@ void CToplevelExportProtocol::onOutputCommit(PHLMONITOR pMonitor) { if (pMonitor != PWINDOW->m_pMonitor.lock()) continue; - CBox geometry = {PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y, PWINDOW->m_vRealSize.value().x, PWINDOW->m_vRealSize.value().y}; + CBox geometry = {PWINDOW->m_vRealPosition->value().x, PWINDOW->m_vRealPosition->value().y, PWINDOW->m_vRealSize->value().x, PWINDOW->m_vRealSize->value().y}; if (geometry.intersection({pMonitor->vecPosition, pMonitor->vecSize}).empty()) continue; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 94b70acf..93ab5fdf 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -713,7 +713,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(PHLMONITOR pMonitor) { if (!ws->m_bIsSpecialWorkspace || ws->m_pMonitor != pMonitor) continue; - if (ws->m_fAlpha.value() == 0) + if (ws->m_fAlpha->value() == 0) continue; return true; @@ -1517,7 +1517,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB if (allowDim && m_RenderData.currentWindow) { glUniform1i(shader->applyTint, 1); - const auto DIM = m_RenderData.currentWindow->m_fDimPercent.value(); + const auto DIM = m_RenderData.currentWindow->m_fDimPercent->value(); glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); } else { glUniform1i(shader->applyTint, 0); @@ -1931,7 +1931,7 @@ void CHyprOpenGLImpl::preRender(PHLMONITOR pMonitor) { const auto PSURFACE = pWindow->m_pWLSurface->resource(); const auto PWORKSPACE = pWindow->m_pWorkspace; - const float A = pWindow->m_fAlpha.value() * pWindow->m_fActiveInactiveAlpha.value() * PWORKSPACE->m_fAlpha.value(); + const float A = pWindow->m_fAlpha->value() * pWindow->m_fActiveInactiveAlpha->value() * PWORKSPACE->m_fAlpha->value(); if (A >= 1.f) { // if (PSURFACE->opaque) @@ -1969,7 +1969,7 @@ void CHyprOpenGLImpl::preRender(PHLMONITOR pMonitor) { if (!ls->layerSurface || ls->xray != 1) continue; - // if (ls->layerSurface->surface->opaque && ls->alpha.value() >= 1.f) + // if (ls->layerSurface->surface->opaque && ls->alpha->value() >= 1.f) // continue; hasWindows = true; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index d154e64a..4d93d92f 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -172,21 +172,21 @@ bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor) { return true; // if the window is being moved to a workspace that is not invisible, and the alpha is > 0.F, render it. - if (pWindow->m_iMonitorMovedFrom != -1 && pWindow->m_fMovingToWorkspaceAlpha.isBeingAnimated() && pWindow->m_fMovingToWorkspaceAlpha.value() > 0.F && pWindow->m_pWorkspace && + if (pWindow->m_iMonitorMovedFrom != -1 && pWindow->m_fMovingToWorkspaceAlpha->isBeingAnimated() && pWindow->m_fMovingToWorkspaceAlpha->value() > 0.F && pWindow->m_pWorkspace && !pWindow->m_pWorkspace->isVisible()) return true; const auto PWINDOWWORKSPACE = pWindow->m_pWorkspace; if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_pMonitor == pMonitor) { - if (PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() || PWINDOWWORKSPACE->m_bForceRendering) + if (PWINDOWWORKSPACE->m_vRenderOffset->isBeingAnimated() || PWINDOWWORKSPACE->m_fAlpha->isBeingAnimated() || PWINDOWWORKSPACE->m_bForceRendering) return true; // if hidden behind fullscreen if (PWINDOWWORKSPACE->m_bHasFullscreenWindow && !pWindow->isFullscreen() && (!pWindow->m_bIsFloating || !pWindow->m_bCreatedOverFullscreen) && - pWindow->m_fAlpha.value() == 0) + pWindow->m_fAlpha->value() == 0) return false; - if (!PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha.isBeingAnimated() && !PWINDOWWORKSPACE->isVisible()) + if (!PWINDOWWORKSPACE->m_vRenderOffset->isBeingAnimated() && !PWINDOWWORKSPACE->m_fAlpha->isBeingAnimated() && !PWINDOWWORKSPACE->isVisible()) return false; } @@ -204,17 +204,17 @@ bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor) { return true; // if window is tiled and it's flying in, don't render on other mons (for slide) - if (!pWindow->m_bIsFloating && pWindow->m_vRealPosition.isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_pMonitor != pMonitor) + if (!pWindow->m_bIsFloating && pWindow->m_vRealPosition->isBeingAnimated() && pWindow->m_bAnimatingIn && pWindow->m_pMonitor != pMonitor) return false; - if (pWindow->m_vRealPosition.isBeingAnimated()) { - if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) + if (pWindow->m_vRealPosition->isBeingAnimated()) { + if (PWINDOWWORKSPACE && !PWINDOWWORKSPACE->m_bIsSpecialWorkspace && PWINDOWWORKSPACE->m_vRenderOffset->isBeingAnimated()) return false; // render window if window and monitor intersect // (when moving out of or through a monitor) CBox windowBox = pWindow->getFullWindowBoundingBox(); - if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated()) - windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset->isBeingAnimated()) + windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset->value()); windowBox.translate(pWindow->m_vFloatingOffset); const CBox monitorBox = {pMonitor->vecPosition, pMonitor->vecSize}; @@ -242,7 +242,7 @@ bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow) { return true; for (auto const& m : g_pCompositor->m_vMonitors) { - if (PWORKSPACE && PWORKSPACE->m_pMonitor == m && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())) + if (PWORKSPACE && PWORKSPACE->m_pMonitor == m && (PWORKSPACE->m_vRenderOffset->isBeingAnimated() || PWORKSPACE->m_fAlpha->isBeingAnimated())) return true; if (m->activeSpecialWorkspace && pWindow->onSpecialWorkspace()) @@ -262,7 +262,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR if (!shouldRenderWindow(w, pMonitor)) continue; - if (w->m_fAlpha.value() == 0.f) + if (w->m_fAlpha->value() == 0.f) continue; if (w->isFullscreen() || w->m_bIsFloating) @@ -279,7 +279,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR if (!shouldRenderWindow(w, pMonitor)) continue; - if (w->m_fAlpha.value() == 0.f) + if (w->m_fAlpha->value() == 0.f) continue; if (w->isFullscreen() || !w->m_bIsFloating) @@ -299,7 +299,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR const auto PWORKSPACE = w->m_pWorkspace; if (w->m_pWorkspace != pWorkspace || !w->isFullscreen()) { - if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated() || PWORKSPACE->m_bForceRendering))) + if (!(PWORKSPACE && (PWORKSPACE->m_vRenderOffset->isBeingAnimated() || PWORKSPACE->m_fAlpha->isBeingAnimated() || PWORKSPACE->m_bForceRendering))) continue; if (w->m_pMonitor != pMonitor) @@ -432,12 +432,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe TRACY_GPU_ZONE("RenderWindow"); const auto PWORKSPACE = pWindow->m_pWorkspace; - const auto REALPOS = pWindow->m_vRealPosition.value() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset.value()); + const auto REALPOS = pWindow->m_vRealPosition->value() + (pWindow->m_bPinned ? Vector2D{} : PWORKSPACE->m_vRenderOffset->value()); static auto PDIMAROUND = CConfigValue("decoration:dim_around"); static auto PBLUR = CConfigValue("decoration:blur:enabled"); CSurfacePassElement::SRenderData renderdata = {pMonitor, time}; - CBox textureBox = {REALPOS.x, REALPOS.y, std::max(pWindow->m_vRealSize.value().x, 5.0), std::max(pWindow->m_vRealSize.value().y, 5.0)}; + CBox textureBox = {REALPOS.x, REALPOS.y, std::max(pWindow->m_vRealSize->value().x, 5.0), std::max(pWindow->m_vRealSize->value().y, 5.0)}; renderdata.pos.x = textureBox.x; renderdata.pos.y = textureBox.y; @@ -458,9 +458,9 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.surface = pWindow->m_pWLSurface->resource(); renderdata.dontRound = pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN) || pWindow->m_sWindowData.noRounding.valueOrDefault(); - renderdata.fadeAlpha = pWindow->m_fAlpha.value() * (pWindow->m_bPinned || USE_WORKSPACE_FADE_ALPHA ? 1.f : PWORKSPACE->m_fAlpha.value()) * - (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha.value() : 1.F) * pWindow->m_fMovingFromWorkspaceAlpha.value(); - renderdata.alpha = pWindow->m_fActiveInactiveAlpha.value(); + renderdata.fadeAlpha = pWindow->m_fAlpha->value() * (pWindow->m_bPinned || USE_WORKSPACE_FADE_ALPHA ? 1.f : PWORKSPACE->m_fAlpha->value()) * + (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha->value() : 1.F) * pWindow->m_fMovingFromWorkspaceAlpha->value(); + renderdata.alpha = pWindow->m_fActiveInactiveAlpha->value(); renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; renderdata.roundingPower = ignoreAllGeometry || renderdata.dontRound ? 2.0f : pWindow->roundingPower(); @@ -492,9 +492,9 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.pos.y += pWindow->m_vFloatingOffset.y; // if window is floating and we have a slide animation, clip it to its full bb - if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->isFullscreen() && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) { + if (!ignorePosition && pWindow->m_bIsFloating && !pWindow->isFullscreen() && PWORKSPACE->m_vRenderOffset->isBeingAnimated() && !pWindow->m_bPinned) { CRegion rg = - pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset.value() + pWindow->m_vFloatingOffset).scale(pMonitor->scale); + pWindow->getFullWindowBoundingBox().translate(-pMonitor->vecPosition + PWORKSPACE->m_vRenderOffset->value() + pWindow->m_vFloatingOffset).scale(pMonitor->scale); renderdata.clipBox = rg.getExtents(); } @@ -657,7 +657,7 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim if (*PDIMAROUND && pLayer->dimAround && !m_bRenderingSnapshot && !popups) { CRectPassElement::SRectData data; data.box = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y}; - data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pLayer->alpha.value()); + data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pLayer->alpha->value()); m_sRenderPass.add(makeShared(data)); } @@ -671,11 +671,11 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim TRACY_GPU_ZONE("RenderLayer"); - const auto REALPOS = pLayer->realPosition.value(); - const auto REALSIZ = pLayer->realSize.value(); + const auto REALPOS = pLayer->realPosition->value(); + const auto REALSIZ = pLayer->realSize->value(); CSurfacePassElement::SRenderData renderdata = {pMonitor, time, REALPOS}; - renderdata.fadeAlpha = pLayer->alpha.value(); + renderdata.fadeAlpha = pLayer->alpha->value(); renderdata.blur = pLayer->forceBlur && *PBLUR; renderdata.surface = pLayer->surface->resource(); renderdata.decorate = false; @@ -866,8 +866,8 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA // and then special for (auto const& ws : g_pCompositor->m_vWorkspaces) { - if (ws->m_pMonitor == pMonitor && ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) { - const auto SPECIALANIMPROGRS = ws->m_vRenderOffset.isBeingAnimated() ? ws->m_vRenderOffset.getCurveValue() : ws->m_fAlpha.getCurveValue(); + if (ws->m_pMonitor == pMonitor && ws->m_fAlpha->value() > 0.f && ws->m_bIsSpecialWorkspace) { + const auto SPECIALANIMPROGRS = ws->m_vRenderOffset->isBeingAnimated() ? ws->m_vRenderOffset->getCurveValue() : ws->m_fAlpha->getCurveValue(); const bool ANIMOUT = !pMonitor->activeSpecialWorkspace; if (*PDIMSPECIAL != 0.f) { @@ -894,7 +894,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA // special for (auto const& ws : g_pCompositor->m_vWorkspaces) { - if (ws->m_fAlpha.value() > 0.f && ws->m_bIsSpecialWorkspace) { + if (ws->m_fAlpha->value() > 0.f && ws->m_bIsSpecialWorkspace) { if (ws->m_bHasFullscreenWindow) renderWorkspaceWindowsFullscreen(pMonitor, ws, time); else @@ -1617,8 +1617,8 @@ void CHyprRenderer::arrangeLayerArray(PHLMONITOR pMonitor, const std::vectorlayerSurface->configure(box.size()); - ls->realPosition = box.pos(); - ls->realSize = box.size(); + *ls->realPosition = box.pos(); + *ls->realSize = box.size(); } } @@ -1727,8 +1727,8 @@ void CHyprRenderer::damageWindow(PHLWINDOW pWindow, bool forceFull) { CBox windowBox = pWindow->getFullWindowBoundingBox(); const auto PWINDOWWORKSPACE = pWindow->m_pWorkspace; - if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !pWindow->m_bPinned) - windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset->isBeingAnimated() && !pWindow->m_bPinned) + windowBox.translate(PWINDOWWORKSPACE->m_vRenderOffset->value()); windowBox.translate(pWindow->m_vFloatingOffset); for (auto const& m : g_pCompositor->m_vMonitors) { @@ -1977,8 +1977,8 @@ void CHyprRenderer::recheckSolitaryForMonitor(PHLMONITOR pMonitor) { const auto PWORKSPACE = pMonitor->activeWorkspace; - if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || PROTO::data->dndActive() || pMonitor->activeSpecialWorkspace || PWORKSPACE->m_fAlpha.value() != 1.f || - PWORKSPACE->m_vRenderOffset.value() != Vector2D{}) + if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || PROTO::data->dndActive() || pMonitor->activeSpecialWorkspace || PWORKSPACE->m_fAlpha->value() != 1.f || + PWORKSPACE->m_vRenderOffset->value() != Vector2D{}) return; const auto PCANDIDATE = PWORKSPACE->getFullscreenWindow(); @@ -1989,15 +1989,15 @@ void CHyprRenderer::recheckSolitaryForMonitor(PHLMONITOR pMonitor) { if (!PCANDIDATE->opaque()) return; - if (PCANDIDATE->m_vRealSize.value() != pMonitor->vecSize || PCANDIDATE->m_vRealPosition.value() != pMonitor->vecPosition || PCANDIDATE->m_vRealPosition.isBeingAnimated() || - PCANDIDATE->m_vRealSize.isBeingAnimated()) + if (PCANDIDATE->m_vRealSize->value() != pMonitor->vecSize || PCANDIDATE->m_vRealPosition->value() != pMonitor->vecPosition || PCANDIDATE->m_vRealPosition->isBeingAnimated() || + PCANDIDATE->m_vRealSize->isBeingAnimated()) return; if (!pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY].empty()) return; for (auto const& topls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { - if (topls->alpha.value() != 0.f) + if (topls->alpha->value() != 0.f) return; } @@ -2410,13 +2410,13 @@ void CHyprRenderer::renderSnapshot(PHLWINDOW pWindow) { CBox windowBox; // some mafs to figure out the correct box // the originalClosedPos is relative to the monitor's pos - Vector2D scaleXY = Vector2D((PMONITOR->scale * pWindow->m_vRealSize.value().x / (pWindow->m_vOriginalClosedSize.x * PMONITOR->scale)), - (PMONITOR->scale * pWindow->m_vRealSize.value().y / (pWindow->m_vOriginalClosedSize.y * PMONITOR->scale))); + Vector2D scaleXY = Vector2D((PMONITOR->scale * pWindow->m_vRealSize->value().x / (pWindow->m_vOriginalClosedSize.x * PMONITOR->scale)), + (PMONITOR->scale * pWindow->m_vRealSize->value().y / (pWindow->m_vOriginalClosedSize.y * PMONITOR->scale))); windowBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; - windowBox.x = ((pWindow->m_vRealPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x); - windowBox.y = ((pWindow->m_vRealPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y); + windowBox.x = ((pWindow->m_vRealPosition->value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x); + windowBox.y = ((pWindow->m_vRealPosition->value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((pWindow->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y); CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; @@ -2425,7 +2425,7 @@ void CHyprRenderer::renderSnapshot(PHLWINDOW pWindow) { CRectPassElement::SRectData data; data.box = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y}; - data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pWindow->m_fAlpha.value()); + data.color = CHyprColor(0, 0, 0, *PDIMAROUND * pWindow->m_fAlpha->value()); m_sRenderPass.add(makeShared(data)); damageMonitor(PMONITOR); @@ -2435,7 +2435,7 @@ void CHyprRenderer::renderSnapshot(PHLWINDOW pWindow) { data.flipEndFrame = true; data.tex = FBDATA->getTexture(); data.box = windowBox; - data.a = pWindow->m_fAlpha.value(); + data.a = pWindow->m_fAlpha->value(); data.damage = fakeDamage; m_sRenderPass.add(makeShared(data)); @@ -2455,13 +2455,13 @@ void CHyprRenderer::renderSnapshot(PHLLS pLayer) { CBox layerBox; // some mafs to figure out the correct box // the originalClosedPos is relative to the monitor's pos - Vector2D scaleXY = Vector2D((PMONITOR->scale * pLayer->realSize.value().x / (pLayer->geometry.w * PMONITOR->scale)), - (PMONITOR->scale * pLayer->realSize.value().y / (pLayer->geometry.h * PMONITOR->scale))); + Vector2D scaleXY = Vector2D((PMONITOR->scale * pLayer->realSize->value().x / (pLayer->geometry.w * PMONITOR->scale)), + (PMONITOR->scale * pLayer->realSize->value().y / (pLayer->geometry.h * PMONITOR->scale))); layerBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; layerBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; - layerBox.x = ((pLayer->realPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((pLayer->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x); - layerBox.y = ((pLayer->realPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((pLayer->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y); + layerBox.x = ((pLayer->realPosition->value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((pLayer->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x); + layerBox.y = ((pLayer->realPosition->value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((pLayer->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y); CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; @@ -2469,7 +2469,7 @@ void CHyprRenderer::renderSnapshot(PHLLS pLayer) { data.flipEndFrame = true; data.tex = FBDATA->getTexture(); data.box = layerBox; - data.a = pLayer->alpha.value(); + data.a = pLayer->alpha->value(); data.damage = fakeDamage; m_sRenderPass.add(makeShared(data)); diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 2bc894ef..7261431f 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -43,7 +43,7 @@ CBox CHyprBorderDecoration::assignedBoxGlobal() { if (!PWORKSPACE) return box; - const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.value() : Vector2D(); + const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset->value() : Vector2D(); return box.translate(WORKSPACEOFFSET); } @@ -60,10 +60,10 @@ void CHyprBorderDecoration::draw(PHLMONITOR pMonitor, float const& a) { return; auto grad = m_pWindow->m_cRealBorderColor; - const bool ANIMATED = m_pWindow->m_fBorderFadeAnimationProgress.isBeingAnimated(); + const bool ANIMATED = m_pWindow->m_fBorderFadeAnimationProgress->isBeingAnimated(); - if (m_pWindow->m_fBorderAngleAnimationProgress.getConfig()->pValues->internalEnabled) { - grad.m_fAngle += m_pWindow->m_fBorderAngleAnimationProgress.value() * M_PI * 2; + if (m_pWindow->m_fBorderAngleAnimationProgress->enabled()) { + grad.m_fAngle += m_pWindow->m_fBorderAngleAnimationProgress->value() * M_PI * 2; grad.m_fAngle = normalizeAngleRad(grad.m_fAngle); } @@ -83,7 +83,7 @@ void CHyprBorderDecoration::draw(PHLMONITOR pMonitor, float const& a) { data.hasGrad2 = true; data.grad1 = m_pWindow->m_cRealBorderColorPrevious; data.grad2 = grad; - data.lerp = m_pWindow->m_fBorderFadeAnimationProgress.value(); + data.lerp = m_pWindow->m_fBorderFadeAnimationProgress->value(); } g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); @@ -117,8 +117,8 @@ void CHyprBorderDecoration::damageEntire() { const auto BORDERSIZE = m_pWindow->getRealBorderSize() + 1; const auto PWINDOWWORKSPACE = m_pWindow->m_pWorkspace; - if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset.isBeingAnimated() && !m_pWindow->m_bPinned) - surfaceBox.translate(PWINDOWWORKSPACE->m_vRenderOffset.value()); + if (PWINDOWWORKSPACE && PWINDOWWORKSPACE->m_vRenderOffset->isBeingAnimated() && !m_pWindow->m_bPinned) + surfaceBox.translate(PWINDOWWORKSPACE->m_vRenderOffset->value()); surfaceBox.translate(m_pWindow->m_vFloatingOffset); CBox surfaceBoxExpandedBorder = surfaceBox; diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 07dbb436..ddd5198d 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -44,13 +44,13 @@ void CHyprDropShadowDecoration::damageEntire() { const auto PWINDOW = m_pWindow.lock(); - CBox shadowBox = {PWINDOW->m_vRealPosition.value().x - m_seExtents.topLeft.x, PWINDOW->m_vRealPosition.value().y - m_seExtents.topLeft.y, - PWINDOW->m_vRealSize.value().x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, - PWINDOW->m_vRealSize.value().y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y}; + CBox shadowBox = {PWINDOW->m_vRealPosition->value().x - m_seExtents.topLeft.x, PWINDOW->m_vRealPosition->value().y - m_seExtents.topLeft.y, + PWINDOW->m_vRealSize->value().x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, + PWINDOW->m_vRealSize->value().y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y}; const auto PWORKSPACE = PWINDOW->m_pWorkspace; - if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOW->m_bPinned) - shadowBox.translate(PWORKSPACE->m_vRenderOffset.value()); + if (PWORKSPACE && PWORKSPACE->m_vRenderOffset->isBeingAnimated() && !PWINDOW->m_bPinned) + shadowBox.translate(PWORKSPACE->m_vRenderOffset->value()); shadowBox.translate(PWINDOW->m_vFloatingOffset); static auto PSHADOWIGNOREWINDOW = CConfigValue("decoration:shadow:ignore_window"); @@ -61,8 +61,8 @@ void CHyprDropShadowDecoration::damageEntire() { CRegion shadowRegion(shadowBox); if (*PSHADOWIGNOREWINDOW) { CBox surfaceBox = PWINDOW->getWindowMainSurfaceBox(); - if (PWORKSPACE && PWORKSPACE->m_vRenderOffset.isBeingAnimated() && !PWINDOW->m_bPinned) - surfaceBox.translate(PWORKSPACE->m_vRenderOffset.value()); + if (PWORKSPACE && PWORKSPACE->m_vRenderOffset->isBeingAnimated() && !PWINDOW->m_bPinned) + surfaceBox.translate(PWORKSPACE->m_vRenderOffset->value()); surfaceBox.translate(PWINDOW->m_vFloatingOffset); surfaceBox.expand(-ROUNDINGSIZE); shadowRegion.subtract(CRegion(surfaceBox)); @@ -81,8 +81,8 @@ void CHyprDropShadowDecoration::damageEntire() { void CHyprDropShadowDecoration::updateWindow(PHLWINDOW pWindow) { const auto PWINDOW = m_pWindow.lock(); - m_vLastWindowPos = PWINDOW->m_vRealPosition.value(); - m_vLastWindowSize = PWINDOW->m_vRealSize.value(); + m_vLastWindowPos = PWINDOW->m_vRealPosition->value(); + m_vLastWindowSize = PWINDOW->m_vRealSize->value(); m_bLastWindowBox = {m_vLastWindowPos.x, m_vLastWindowPos.y, m_vLastWindowSize.x, m_vLastWindowSize.y}; m_bLastWindowBoxWithDecos = g_pDecorationPositioner->getBoxWithIncludedDecos(pWindow); @@ -101,7 +101,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { if (!validMapped(PWINDOW)) return; - if (PWINDOW->m_cRealShadowColor.value() == CHyprColor(0, 0, 0, 0)) + if (PWINDOW->m_cRealShadowColor->value() == CHyprColor(0, 0, 0, 0)) return; // don't draw invisible shadows if (!PWINDOW->m_sWindowData.decorate.valueOrDefault()) @@ -123,7 +123,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { const auto ROUNDINGPOWER = PWINDOW->roundingPower(); const auto ROUNDING = ROUNDINGBASE > 0 ? ROUNDINGBASE + PWINDOW->getRealBorderSize() : 0; const auto PWORKSPACE = PWINDOW->m_pWorkspace; - const auto WORKSPACEOFFSET = PWORKSPACE && !PWINDOW->m_bPinned ? PWORKSPACE->m_vRenderOffset.value() : Vector2D(); + const auto WORKSPACEOFFSET = PWORKSPACE && !PWINDOW->m_bPinned ? PWORKSPACE->m_vRenderOffset->value() : Vector2D(); // draw the shadow CBox fullBox = m_bLastWindowBoxWithDecos; @@ -194,7 +194,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { g_pHyprOpenGL->renderRect(&fullBox, CHyprColor(0, 0, 0, 1), 0); // render white shadow with the alpha of the shadow color (otherwise we clear with alpha later and shit it to 2 bit) - drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, CHyprColor(1, 1, 1, PWINDOW->m_cRealShadowColor.value().a), a); + drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, CHyprColor(1, 1, 1, PWINDOW->m_cRealShadowColor->value().a), a); // render black window box ("clip") g_pHyprOpenGL->renderRect(&windowBox, CHyprColor(0, 0, 0, 1.0), (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->scale, ROUNDINGPOWER); @@ -202,7 +202,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { alphaSwapFB.bind(); // alpha swap just has the shadow color. It will be the "texture" to render. - g_pHyprOpenGL->renderRect(&fullBox, PWINDOW->m_cRealShadowColor.value().stripA(), 0); + g_pHyprOpenGL->renderRect(&fullBox, PWINDOW->m_cRealShadowColor->value().stripA(), 0); LASTFB->bind(); @@ -216,7 +216,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { g_pHyprOpenGL->m_RenderData.damage = saveDamage; } else - drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, PWINDOW->m_cRealShadowColor.value(), a); + drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, PWINDOW->m_cRealShadowColor->value(), a); if (m_seExtents != m_seReportedExtents) g_pDecorationPositioner->repositionDeco(this); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index c6dc5779..970273d7 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -390,9 +390,9 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND // restores the group for (auto it = members.begin(); it != members.end(); ++it) { - (*it)->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of group members - (*it)->m_vRealSize = pWindowInsertAfter->m_vRealSize.goal(); // match the size of group members - (*it)->m_vRealPosition = pWindowInsertAfter->m_vRealPosition.goal(); // match the position of group members + (*it)->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of group members + *(*it)->m_vRealSize = pWindowInsertAfter->m_vRealSize->goal(); // match the size of group members + *(*it)->m_vRealPosition = pWindowInsertAfter->m_vRealPosition->goal(); // match the position of group members if (std::next(it) != members.end()) (*it)->m_sGroupData.pNextWindow = *std::next(it); else @@ -406,7 +406,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND pDraggedWindow->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of the window if (pWindowInsertAfter->m_bIsFloating) - g_pXWaylandManager->setWindowSize(pDraggedWindow, pWindowInsertAfter->m_vRealSize.goal()); // match the size of the window + g_pXWaylandManager->setWindowSize(pDraggedWindow, pWindowInsertAfter->m_vRealSize->goal()); // match the size of the window pWindowInsertAfter->insertWindowToGroup(pDraggedWindow); @@ -515,7 +515,7 @@ CBox CHyprGroupBarDecoration::assignedBoxGlobal() { const auto PWORKSPACE = m_pWindow->m_pWorkspace; if (PWORKSPACE && !m_pWindow->m_bPinned) - box.translate(PWORKSPACE->m_vRenderOffset.value()); + box.translate(PWORKSPACE->m_vRenderOffset->value()); return box; } diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index 6a41cbdc..abfa19ec 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -124,7 +124,7 @@ void CDecorationPositioner::onWindowUpdate(PHLWINDOW pWindow) { datas.push_back(getDataFor(wd.get(), pWindow)); } - if (WINDOWDATA->lastWindowSize == pWindow->m_vRealSize.value() /* position not changed */ + if (WINDOWDATA->lastWindowSize == pWindow->m_vRealSize->value() /* position not changed */ && std::all_of(m_vWindowPositioningDatas.begin(), m_vWindowPositioningDatas.end(), [pWindow](const auto& data) { return pWindow != data->pWindow.lock() || !data->needsReposition; }) /* all window datas are either not for this window or don't need a reposition */ @@ -132,9 +132,9 @@ void CDecorationPositioner::onWindowUpdate(PHLWINDOW pWindow) { ) return; - WINDOWDATA->lastWindowSize = pWindow->m_vRealSize.value(); + WINDOWDATA->lastWindowSize = pWindow->m_vRealSize->value(); WINDOWDATA->needsRecalc = false; - const bool EPHEMERAL = pWindow->m_vRealSize.isBeingAnimated(); + const bool EPHEMERAL = pWindow->m_vRealSize->isBeingAnimated(); std::sort(datas.begin(), datas.end(), [](const auto& a, const auto& b) { return a->positioningInfo.priority > b->positioningInfo.priority; }); diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index 13e9e741..f2f2627a 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -77,7 +77,7 @@ void CSurfacePassElement::draw(const CRegion& damage) { const bool MISALIGNEDFSV1 = std::floor(data.pMonitor->scale) != data.pMonitor->scale /* Fractional */ && data.surface->current.scale == 1 /* fs protocol */ && windowBox.size() != data.surface->current.bufferSize /* misaligned */ && DELTALESSTHAN(windowBox.width, data.surface->current.bufferSize.x, 3) && DELTALESSTHAN(windowBox.height, data.surface->current.bufferSize.y, 3) /* off by one-or-two */ && - (!data.pWindow || (!data.pWindow->m_vRealSize.isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */; + (!data.pWindow || (!data.pWindow->m_vRealSize->isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */; g_pHyprRenderer->calculateUVForSurface(data.pWindow, data.surface, data.pMonitor->self.lock(), data.mainSurface, windowBox.size(), PROJSIZEUNSCALED, MISALIGNEDFSV1); @@ -148,8 +148,8 @@ CBox CSurfacePassElement::getTexBox() { if (!INTERACTIVERESIZEINPROGRESS) { windowBox.translate(CORRECT); - windowBox.width = SIZE.x * (PWINDOW->m_vRealSize.value().x / PWINDOW->m_vReportedSize.x); - windowBox.height = SIZE.y * (PWINDOW->m_vRealSize.value().y / PWINDOW->m_vReportedSize.y); + windowBox.width = SIZE.x * (PWINDOW->m_vRealSize->value().x / PWINDOW->m_vReportedSize.x); + windowBox.height = SIZE.y * (PWINDOW->m_vRealSize->value().y / PWINDOW->m_vReportedSize.y); } else { windowBox.width = SIZE.x; windowBox.height = SIZE.y; @@ -159,10 +159,10 @@ CBox CSurfacePassElement::getTexBox() { } else { // here we clamp to 2, these might be some tiny specks windowBox = {(int)outputX + data.pos.x + data.localPos.x, (int)outputY + data.pos.y + data.localPos.y, std::max((float)data.surface->current.size.x, 2.F), std::max((float)data.surface->current.size.y, 2.F)}; - if (data.pWindow && data.pWindow->m_vRealSize.isBeingAnimated() && data.surface && !data.mainSurface && data.squishOversized /* subsurface */) { + if (data.pWindow && data.pWindow->m_vRealSize->isBeingAnimated() && data.surface && !data.mainSurface && data.squishOversized /* subsurface */) { // adjust subsurfaces to the window - windowBox.width = (windowBox.width / data.pWindow->m_vReportedSize.x) * data.pWindow->m_vRealSize.value().x; - windowBox.height = (windowBox.height / data.pWindow->m_vReportedSize.y) * data.pWindow->m_vRealSize.value().y; + windowBox.width = (windowBox.width / data.pWindow->m_vReportedSize.x) * data.pWindow->m_vRealSize->value().x; + windowBox.height = (windowBox.height / data.pWindow->m_vReportedSize.y) * data.pWindow->m_vRealSize->value().y; } } From 95542e44884d2131a742f92013826a0b5f341b33 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 7 Jan 2025 19:13:35 +0100 Subject: [PATCH 0086/1444] animationmgr: fix invalid include --- src/managers/AnimationManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index 7bf73f97..10eeef05 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -5,7 +5,7 @@ #include "../defines.hpp" #include "../helpers/AnimatedVariable.hpp" -#include "desktop/DesktopTypes.hpp" +#include "../desktop/DesktopTypes.hpp" #include "eventLoop/EventLoopTimer.hpp" class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { From 830350a1f7a5ad653f33f2c62dd1694249a2f1e2 Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:32:50 +0300 Subject: [PATCH 0087/1444] core: Add support for HDR and color management protocols (#8715) --- CMakeLists.txt | 2 + protocols/frog-color-management-v1.xml | 366 ++++++ protocols/meson.build | 2 + protocols/xx-color-management-v4.xml | 1457 +++++++++++++++++++++++ src/Compositor.cpp | 19 + src/Compositor.hpp | 4 + src/config/ConfigDescriptions.hpp | 18 + src/config/ConfigManager.cpp | 4 + src/desktop/WLSurface.hpp | 1 + src/managers/ProtocolManager.cpp | 11 + src/protocols/ColorManagement.cpp | 571 +++++++++ src/protocols/ColorManagement.hpp | 182 +++ src/protocols/FrogColorManagement.cpp | 159 +++ src/protocols/FrogColorManagement.hpp | 55 + src/protocols/core/Compositor.hpp | 3 + src/protocols/types/ColorManagement.hpp | 47 + src/render/Renderer.cpp | 97 ++ src/render/pass/SurfacePassElement.cpp | 2 + 18 files changed, 3000 insertions(+) create mode 100644 protocols/frog-color-management-v1.xml create mode 100644 protocols/xx-color-management-v4.xml create mode 100644 src/protocols/ColorManagement.cpp create mode 100644 src/protocols/ColorManagement.hpp create mode 100644 src/protocols/FrogColorManagement.cpp create mode 100644 src/protocols/FrogColorManagement.hpp create mode 100644 src/protocols/types/ColorManagement.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index aa746d2e..c1ecb14c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -316,6 +316,8 @@ protocolnew("protocols" "kde-server-decoration" true) protocolnew("protocols" "wlr-data-control-unstable-v1" true) protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true) protocolnew("protocols" "wlr-layer-shell-unstable-v1" true) +protocolnew("protocols" "xx-color-management-v4" true) +protocolnew("protocols" "frog-color-management-v1" true) protocolnew("protocols" "wayland-drm" true) protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true) protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-surface-v1" true) diff --git a/protocols/frog-color-management-v1.xml b/protocols/frog-color-management-v1.xml new file mode 100644 index 00000000..aab235a7 --- /dev/null +++ b/protocols/frog-color-management-v1.xml @@ -0,0 +1,366 @@ + + + + + Copyright © 2023 Joshua Ashton for Valve Software + Copyright © 2023 Xaver Hugl + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + The aim of this color management extension is to get HDR games working quickly, + and have an easy way to test implementations in the wild before the upstream + protocol is ready to be merged. + For that purpose it's intentionally limited and cut down and does not serve + all uses cases. + + + + + The color management factory singleton creates color managed surface objects. + + + + + + + + + + + + + + + + Interface for changing surface color management and HDR state. + + An implementation must: support every part of the version + of the frog_color_managed_surface interface it exposes. + Including all known enums associated with a given version. + + + + + Destroying the color managed surface resets all known color + state for the surface back to 'undefined' implementation-specific + values. + + + + + + Extended information on the transfer functions described + here can be found in the Khronos Data Format specification: + https://registry.khronos.org/DataFormat/specs/1.3/dataformat.1.3.html + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extended information on render intents described + here can be found in ICC.1:2022: + + https://www.color.org/specification/ICC.1-2022-05.pdf + + + + + + + NOTE: On a surface with "perceptual" (default) render intent, handling of the container's + color volume + is implementation-specific, and may differ between different transfer functions it is paired + with: + ie. sRGB + 709 rendering may have it's primaries widened to more of the available display's + gamut + to be be more pleasing for the viewer. + Compared to scRGB Linear + 709 being treated faithfully as 709 + (including utilizing negatives out of the 709 gamut triangle) + + + + + + + Forwards HDR metadata from the client to the compositor. + + HDR Metadata Infoframe as per CTA 861.G spec. + + Usage of this HDR metadata is implementation specific and + outside of the scope of this protocol. + + + + Mastering Red Color Primary X Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering Red Color Primary Y Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering Green Color Primary X Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering Green Color Primary Y Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering Blue Color Primary X Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering Blue Color Primary Y Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering White Point X Coordinate of the Data. + + These are coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Mastering White Point Y Coordinate of the Data. + + These are coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Max Mastering Display Luminance. + This value is coded as an unsigned 16-bit value in units of 1 cd/m2, + where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. + + + + + Min Mastering Display Luminance. + This value is coded as an unsigned 16-bit value in units of + 0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF + represents 6.5535 cd/m2. + + + + + Max Content Light Level. + This value is coded as an unsigned 16-bit value in units of 1 cd/m2, + where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. + + + + + Max Frame Average Light Level. + This value is coded as an unsigned 16-bit value in units of 1 cd/m2, + where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. + + + + + + + Current preferred metadata for a surface. + The application should use this information to tone-map its buffers + to this target before committing. + + This metadata does not necessarily correspond to any physical output, but + rather what the compositor thinks would be best for a given surface. + + + + Specifies a known transfer function that corresponds to the + output the surface is targeting. + + + + + Output Red Color Primary X Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output Red Color Primary Y Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output Green Color Primary X Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output Green Color Primary Y Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output Blue Color Primary X Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output Blue Color Primary Y Coordinate of the Data. + + Coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output White Point X Coordinate of the Data. + + These are coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Output White Point Y Coordinate of the Data. + + These are coded as unsigned 16-bit values in units of + 0.00002, where 0x0000 represents zero and 0xC350 + represents 1.0000. + + + + + Max Output Luminance + The max luminance in nits that the output is capable of rendering in small areas. + Content should: not exceed this value to avoid clipping. + + This value is coded as an unsigned 16-bit value in units of 1 cd/m2, + where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. + + + + + Min Output Luminance + The min luminance that the output is capable of rendering. + Content should: not exceed this value to avoid clipping. + + This value is coded as an unsigned 16-bit value in units of + 0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF + represents 6.5535 cd/m2. + + + + + Max Full Frame Luminance + The max luminance in nits that the output is capable of rendering for the + full frame sustained. + + This value is coded as an unsigned 16-bit value in units of 1 cd/m2, + where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. + + + + + \ No newline at end of file diff --git a/protocols/meson.build b/protocols/meson.build index a39602b7..fdbbf181 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -33,6 +33,8 @@ protocols = [ 'wayland-drm.xml', 'wlr-data-control-unstable-v1.xml', 'wlr-screencopy-unstable-v1.xml', + 'xx-color-management-v4.xml', + 'frog-color-management-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-global-shortcuts-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml', diff --git a/protocols/xx-color-management-v4.xml b/protocols/xx-color-management-v4.xml new file mode 100644 index 00000000..23ff716e --- /dev/null +++ b/protocols/xx-color-management-v4.xml @@ -0,0 +1,1457 @@ + + + + Copyright 2019 Sebastian Wick + Copyright 2019 Erwin Burema + Copyright 2020 AMD + Copyright 2020-2024 Collabora, Ltd. + Copyright 2024 Xaver Hugl + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + The aim of the color management extension is to allow clients to know + the color properties of outputs, and to tell the compositor about the color + properties of their content on surfaces. Doing this enables a compositor + to perform automatic color management of content for different outputs + according to how content is intended to look like. + + The color properties are represented as an image description object which + is immutable after it has been created. A wl_output always has an + associated image description that clients can observe. A wl_surface + always has an associated preferred image description as a hint chosen by + the compositor that clients can also observe. Clients can set an image + description on a wl_surface to denote the color characteristics of the + surface contents. + + An image description includes SDR and HDR colorimetry and encoding, HDR + metadata, and viewing environment parameters. An image description does + not include the properties set through color-representation extension. + It is expected that the color-representation extension is used in + conjunction with the color management extension when necessary, + particularly with the YUV family of pixel formats. + + Recommendation ITU-T H.273 + "Coding-independent code points for video signal type identification" + shall be referred to as simply H.273 here. + + The color-and-hdr repository + (https://gitlab.freedesktop.org/pq/color-and-hdr) contains + background information on the protocol design and legacy color management. + It also contains a glossary, learning resources for digital color, tools, + samples and more. + + The terminology used in this protocol is based on common color science and + color encoding terminology where possible. The glossary in the color-and-hdr + repository shall be the authority on the definition of terms in this + protocol. + + + + + A global interface used for getting color management extensions for + wl_surface and wl_output objects, and for creating client defined image + description objects. The extension interfaces allow + getting the image description of outputs and setting the image + description of surfaces. + + + + + Destroy the xx_color_manager_v4 object. This does not affect any other + objects in any way. + + + + + + + + + + + See the ICC.1:2022 specification from the International Color Consortium + for more details about rendering intents. + + The principles of ICC defined rendering intents apply with all types of + image descriptions, not only those with ICC file profiles. + + Compositors must support the perceptual rendering intent. Other + rendering intents are optional. + + + + + + + + + + + + + + + + + + + + The compositor supports set_mastering_display_primaries request with a + target color volume fully contained inside the primary color volume. + + + + + The compositor additionally supports target color volumes that + extend outside of the primary color volume. + + This can only be advertised if feature set_mastering_display_primaries + is supported as well. + + + + + + + Named color primaries used to encode well-known sets of primaries. H.273 + is the authority, when it comes to the exact values of primaries and + authoritative specifications, where an equivalent code point exists. + + Descriptions do list the specifications for convenience. + + + + + Color primaries as defined by + - Rec. ITU-R BT.709-6 + - Rec. ITU-R BT.1361-0 conventional colour gamut system and extended + colour gamut system (historical) + - IEC 61966-2-1 sRGB or sYCC + - IEC 61966-2-4 + - Society of Motion Picture and Television Engineers (SMPTE) RP 177 + (1993) Annex B + Equivalent to H.273 ColourPrimaries code point 1. + + + + + Color primaries as defined by + - Rec. ITU-R BT.470-6 System M (historical) + - United States National Television System Committee 1953 + Recommendation for transmission standards for color television + - United States Federal Communications Commission (2003) Title 47 Code + of Federal Regulations 73.682 (a)(20) + Equivalent to H.273 ColourPrimaries code point 4. + + + + + Color primaries as defined by + - Rec. ITU-R BT.470-6 System B, G (historical) + - Rec. ITU-R BT.601-7 625 + - Rec. ITU-R BT.1358-0 625 (historical) + - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM + Equivalent to H.273 ColourPrimaries code point 5. + + + + + Color primaries as defined by + - Rec. ITU-R BT.601-7 525 + - Rec. ITU-R BT.1358-1 525 or 625 (historical) + - Rec. ITU-R BT.1700-0 NTSC + - SMPTE 170M (2004) + - SMPTE 240M (1999) (historical) + Equivalent to H.273 ColourPrimaries code point 6 and 7. + + + + + Color primaries as defined by H.273 for generic film. + Equivalent to H.273 ColourPrimaries code point 8. + + + + + Color primaries as defined by + - Rec. ITU-R BT.2020-2 + - Rec. ITU-R BT.2100-0 + Equivalent to H.273 ColourPrimaries code point 9. + + + + + Color primaries as defined as the maximum of the CIE 1931 XYZ color + space by + - SMPTE ST 428-1 + - (CIE 1931 XYZ as in ISO 11664-1) + Equivalent to H.273 ColourPrimaries code point 10. + + + + + Color primaries as defined by Digital Cinema System and published in + SMPTE RP 431-2 (2011). Equivalent to H.273 ColourPrimaries code point + 11. + + + + + Color primaries as defined by Digital Cinema System and published in + SMPTE EG 432-1 (2010). + Equivalent to H.273 ColourPrimaries code point 12. + + + + + Color primaries as defined by Adobe as "Adobe RGB" and later published + by ISO 12640-4 (2011). + + + + + + + Named transfer functions used to encode well-known transfer + characteristics. H.273 is the authority, when it comes to the exact + formulas and authoritative specifications, where an equivalent code + point exists. + + Descriptions do list the specifications for convenience. + + + + + Transfer characteristics as defined by + - Rec. ITU-R BT.709-6 + - Rec. ITU-R BT.1361-0 conventional colour gamut system (historical) + Equivalent to H.273 TransferCharacteristics code point 1, 6, 14, 15. + + + + + Transfer characteristics as defined by + - Rec. ITU-R BT.470-6 System M (historical) + - United States National Television System Committee 1953 + Recommendation for transmission standards for color television + - United States Federal Communications Commission (2003) Title 47 Code + of Federal Regulations 73.682 (a) (20) + - Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM + Equivalent to H.273 TransferCharacteristics code point 4. + + + + + Transfer characteristics as defined by + - Rec. ITU-R BT.470-6 System B, G (historical) + Equivalent to H.273 TransferCharacteristics code point 5. + + + + + Transfer characteristics as defined by + - SMPTE ST 240 (1999) + Equivalent to H.273 TransferCharacteristics code point 7. + + + + + Linear transfer characteristics. + Equivalent to H.273 TransferCharacteristics code point 8. + + + + + Logarithmic transfer characteristic (100:1 range). + Equivalent to H.273 TransferCharacteristics code point 9. + + + + + Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range). + Equivalent to H.273 TransferCharacteristics code point 10. + + + + + Transfer characteristics as defined by + - IEC 61966-2-4 + Equivalent to H.273 TransferCharacteristics code point 11. + + + + + Transfer characteristics as defined by + - Rec. ITU-R BT.1361-0 extended colour gamut system (historical) + Equivalent to H.273 TransferCharacteristics code point 12. + + + + + Transfer characteristics as defined by + - IEC 61966-2-1 sRGB + Equivalent to H.273 TransferCharacteristics code point 13 with + MatrixCoefficients set to 0. + + + + + Transfer characteristics as defined by + - IEC 61966-2-1 sYCC + Equivalent to H.273 TransferCharacteristics code point 13 with + MatrixCoefficients set to anything but 0. + + + + + Transfer characteristics as defined by + - SMPTE ST 2084 (2014) for 10-, 12-, 14- and 16-bit systems + - Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system + Equivalent to H.273 TransferCharacteristics code point 16. + + This TF implies these default luminances + - primary color volume minimum: 0.005 cd/m² + - primary color volume maximum: 10000 cd/m² + - reference white: 203 cd/m² + + + + + Transfer characteristics as defined by + - SMPTE ST 428-1 (2019) + Equivalent to H.273 TransferCharacteristics code point 17. + + + + + Transfer characteristics as defined by + - ARIB STD-B67 (2015) + - Rec. ITU-R BT.2100-2 hybrid log-gamma (HLG) system + Equivalent to H.273 TransferCharacteristics code point 18. + + This TF implies these default luminances + - primary color volume minimum: 0.005 cd/m² + - primary color volume maximum: 1000 cd/m² + - reference white: 203 cd/m² + Note: HLG is a scene referred signal. All absolute luminance values + used here for HLG assume a 1000 cd/m² display. + + + + + + + This creates a new xx_color_management_output_v4 object for the + given wl_output. + + See the xx_color_management_output_v4 interface for more details. + + + + + + + + + If a xx_color_management_surface_v4 object already exists for the given + wl_surface, the protocol error surface_exists is raised. + + This creates a new color xx_color_management_surface_v4 object for the + given wl_surface. + + See the xx_color_management_surface_v4 interface for more details. + + + + + + + + + This creates a new color xx_color_management_feedback_surface_v4 object + for the given wl_surface. + + See the xx_color_management_feedback_surface_v4 interface for more + details. + + + + + + + + + Makes a new ICC-based image description creator object with all + properties initially unset. The client can then use the object's + interface to define all the required properties for an image description + and finally create a xx_image_description_v4 object. + + This request can be used when the compositor advertises + xx_color_manager_v4.feature.icc_v2_v4. + Otherwise this request raises the protocol error unsupported_feature. + + + + + + + + Makes a new parametric image description creator object with all + properties initially unset. The client can then use the object's + interface to define all the required properties for an image description + and finally create a xx_image_description_v4 object. + + This request can be used when the compositor advertises + xx_color_manager_v4.feature.parametric. + Otherwise this request raises the protocol error unsupported_feature. + + + + + + + + When this object is created, it shall immediately send this event once + for each rendering intent the compositor supports. + + + + + + + + When this object is created, it shall immediately send this event once + for each compositor supported feature listed in the enumeration. + + + + + + + + When this object is created, it shall immediately send this event once + for each named transfer function the compositor supports with the + parametric image description creator. + + + + + + + + When this object is created, it shall immediately send this event once + for each named set of primaries the compositor supports with the + parametric image description creator. + + + + + + + + + A xx_color_management_output_v4 describes the color properties of an + output. + + The xx_color_management_output_v4 is associated with the wl_output global + underlying the wl_output object. Therefore the client destroying the + wl_output object has no impact, but the compositor removing the output + global makes the xx_color_management_output_v4 object inert. + + + + + Destroy the color xx_color_management_output_v4 object. This does not + affect any remaining protocol objects. + + + + + + This event is sent whenever the image description of the output changed, + followed by one wl_output.done event common to output events across all + extensions. + + If the client wants to use the updated image description, it needs to do + get_image_description again, because image description objects are + immutable. + + + + + + This creates a new xx_image_description_v4 object for the current image + description of the output. There always is exactly one image description + active for an output so the client should destroy the image description + created by earlier invocations of this request. This request is usually + sent as a reaction to the image_description_changed event or when + creating a xx_color_management_output_v4 object. + + The image description of an output represents the color encoding the + output expects. There might be performance and power advantages, as well + as improved color reproduction, if a content update matches the image + description of the output it is being shown on. If a content update is + shown on any other output than the one it matches the image description + of, then the color reproduction on those outputs might be considerably + worse. + + The created xx_image_description_v4 object preserves the image + description of the output from the time the object was created. + + The resulting image description object allows get_information request. + + If this protocol object is inert, the resulting image description object + shall immediately deliver the xx_image_description_v4.failed event with + the no_output cause. + + If the interface version is inadequate for the output's image + description, meaning that the client does not support all the events + needed to deliver the crucial information, the resulting image + description object shall immediately deliver the + xx_image_description_v4.failed event with the low_version cause. + + Otherwise the object shall immediately deliver the ready event. + + + + + + + + + A xx_color_management_surface_v4 allows the client to set the color + space and HDR properties of a surface. + + If the wl_surface associated with the xx_color_management_surface_v4 is + destroyed, the xx_color_management_surface_v4 object becomes inert. + + + + + Destroy the xx_color_management_surface_v4 object and do the same as + unset_image_description. + + + + + + + + + + + + Set the image description of the underlying surface. The image + description and rendering intent are double-buffered state, see + wl_surface.commit. + + It is the client's responsibility to understand the image description + it sets on a surface, and to provide content that matches that image + description. Compositors might convert images to match their own or any + other image descriptions. + + Image description whose creation gracefully failed (received + xx_image_description_v4.failed) are forbidden in this request, and in + such case the protocol error image_description is raised. + + All image descriptions whose creation succeeded (received + xx_image_description_v4.ready) are allowed and must always be accepted + by the compositor. + + A rendering intent provides the client's preference on how content + colors should be mapped to each output. The render_intent value must + be one advertised by the compositor with + xx_color_manager_v4.render_intent event, otherwise the protocol error + render_intent is raised. + + By default, a surface does not have an associated image description + nor a rendering intent. The handling of color on such surfaces is + compositor implementation defined. Compositors should handle such + surfaces as sRGB but may handle them differently if they have specific + requirements. + + + + + + + + + This request removes any image description from the surface. See + set_image_description for how a compositor handles a surface without + an image description. This is double-buffered state, see + wl_surface.commit. + + + + + + + A xx_color_management_feedback_surface_v4 allows the client to get the + preferred color description of a surface. + + If the wl_surface associated with this object is destroyed, the + xx_color_management_feedback_surface_v4 object becomes inert. + + + + + Destroy the xx_color_management_feedback_surface_v4 object. + + + + + + + + + + + The preferred image description is the one which likely has the most + performance and/or quality benefits for the compositor if used by the + client for its wl_surface contents. This event is sent whenever the + compositor changes the wl_surface's preferred image description. + + This event is merely a notification. When the client wants to know + what the preferred image description is, it shall use the get_preferred + request. + + The preferred image description is not automatically used for anything. + It is only a hint, and clients may set any valid image description with + set_image_description but there might be performance and color accuracy + improvements by providing the wl_surface contents in the preferred + image description. Therefore clients that can, should render according + to the preferred image description + + + + + + If this protocol object is inert, the protocol error inert is raised. + + The preferred image description represents the compositor's preferred + color encoding for this wl_surface at the current time. There might be + performance and power advantages, as well as improved color + reproduction, if the image description of a content update matches the + preferred image description. + + This creates a new xx_image_description_v4 object for the currently + preferred image description for the wl_surface. The client should + stop using and destroy the image descriptions created by earlier + invocations of this request for the associated wl_surface. + This request is usually sent as a reaction to the preferred_changed + event or when creating a xx_color_management_feedback_surface_v4 object + if the client is capable of adapting to image descriptions. + + The created xx_image_description_v4 object preserves the preferred image + description of the wl_surface from the time the object was created. + + The resulting image description object allows get_information request. + + If the interface version is inadequate for the preferred image + description, meaning that the client does not support all the + events needed to deliver the crucial information, the resulting image + description object shall immediately deliver the + xx_image_description_v4.failed event with the low_version cause, + otherwise the object shall immediately deliver the ready event. + + + + + + + + + This type of object is used for collecting all the information required + to create a xx_image_description_v4 object from an ICC file. A complete + set of required parameters consists of these properties: + - ICC file + + Each required property must be set exactly once if the client is to create + an image description. The set requests verify that a property was not + already set. The create request verifies that all required properties are + set. There may be several alternative requests for setting each property, + and in that case the client must choose one of them. + + Once all properties have been set, the create request must be used to + create the image description object, destroying the creator in the + process. + + + + + + + + + + + + + + + Create an image description object based on the ICC information + previously set on this object. A compositor must parse the ICC data in + some undefined but finite amount of time. + + The completeness of the parameter set is verified. If the set is not + complete, the protocol error incomplete_set is raised. For the + definition of a complete set, see the description of this interface. + + If the particular combination of the information is not supported + by the compositor, the resulting image description object shall + immediately deliver the xx_image_description_v4.failed event with the + 'unsupported' cause. If a valid image description was created from the + information, the xx_image_description_v4.ready event will eventually + be sent instead. + + This request destroys the xx_image_description_creator_icc_v4 object. + + The resulting image description object does not allow get_information + request. + + + + + + + + Sets the ICC profile file to be used as the basis of the image + description. + + The data shall be found through the given fd at the given offset, having + the given length. The fd must seekable and readable. Violating these + requirements raises the bad_fd protocol error. + + If reading the data fails due to an error independent of the client, the + compositor shall send the xx_image_description_v4.failed event on the + created xx_image_description_v4 with the 'operating_system' cause. + + The maximum size of the ICC profile is 4 MB. If length is greater than + that or zero, the protocol error bad_size is raised. If offset + length + exceeds the file size, the protocol error out_of_file is raised. + + A compositor may read the file at any time starting from this request + and only until whichever happens first: + - If create request was issued, the xx_image_description_v4 object + delivers either failed or ready event; or + - if create request was not issued, this + xx_image_description_creator_icc_v4 object is destroyed. + + A compositor shall not modify the contents of the file, and the fd may + be sealed for writes and size changes. The client must ensure to its + best ability that the data does not change while the compositor is + reading it. + + The data must represent a valid ICC profile. The ICC profile version + must be 2 or 4, it must be a 3 channel profile and the class must be + Display or ColorSpace. Violating these requirements will not result in a + protocol error but will eventually send the + xx_image_description_v4.failed event on the created + xx_image_description_v4 with the 'unsupported' cause. + + See the International Color Consortium specification ICC.1:2022 for more + details about ICC profiles. + + If ICC file has already been set on this object, the protocol error + already_set is raised. + + + + + + + + + + + This type of object is used for collecting all the parameters required + to create a xx_image_description_v4 object. A complete set of required + parameters consists of these properties: + - transfer characteristic function (tf) + - chromaticities of primaries and white point (primary color volume) + + The following properties are optional and have a well-defined default + if not explicitly set: + - primary color volume luminance range + - reference white luminance level + - mastering display primaries and white point (target color volume) + - mastering luminance range + - maximum content light level + - maximum frame-average light level + + Each required property must be set exactly once if the client is to create + an image description. The set requests verify that a property was not + already set. The create request verifies that all required properties are + set. There may be several alternative requests for setting each property, + and in that case the client must choose one of them. + + Once all properties have been set, the create request must be used to + create the image description object, destroying the creator in the + process. + + + + + + + + + + + + + + + + + + Create an image description object based on the parameters previously + set on this object. + + The completeness of the parameter set is verified. If the set is not + complete, the protocol error incomplete_set is raised. For the + definition of a complete set, see the description of this interface. + + Also, the combination of the parameter set is verified. If the set is + not consistent, the protocol error inconsistent_set is raised. + + If the particular combination of the parameter set is not supported + by the compositor, the resulting image description object shall + immediately deliver the xx_image_description_v4.failed event with the + 'unsupported' cause. If a valid image description was created from the + parameter set, the xx_image_description_v4.ready event will eventually + be sent instead. + + This request destroys the xx_image_description_creator_params_v4 + object. + + The resulting image description object does not allow get_information + request. + + + + + + + + Sets the transfer characteristic using explicitly enumerated named + functions. + + When the resulting image description is attached to an image, the + content should be encoded and decoded according to the industry standard + practices for the transfer characteristic. + + Only names advertised with xx_color_manager_v4 event supported_tf_named + are allowed. Other values shall raise the protocol error invalid_tf. + + If transfer characteristic has already been set on this object, the + protocol error already_set is raised. + + + + + + + + Sets the color component transfer characteristic to a power curve with + the given exponent. This curve represents the conversion from electrical + to optical pixel or color values. + + When the resulting image description is attached to an image, the + content should be encoded with the inverse of the power curve. + + The curve exponent shall be multiplied by 10000 to get the argument eexp + value to carry the precision of 4 decimals. + + The curve exponent must be at least 1.0 and at most 10.0. Otherwise the + protocol error invalid_tf is raised. + + If transfer characteristic has already been set on this object, the + protocol error already_set is raised. + + This request can be used when the compositor advertises + xx_color_manager_v4.feature.set_tf_power. Otherwise this request raises + the protocol error unsupported_feature. + + + + + + + + Sets the color primaries and white point using explicitly named sets. + This describes the primary color volume which is the basis for color + value encoding. + + Only names advertised with xx_color_manager_v4 event + supported_primaries_named are allowed. Other values shall raise the + protocol error invalid_primaries. + + If primaries have already been set on this object, the protocol error + already_set is raised. + + + + + + + + Sets the color primaries and white point using CIE 1931 xy chromaticity + coordinates. This describes the primary color volume which is the basis + for color value encoding. + + Each coordinate value is multiplied by 10000 to get the argument value + to carry precision of 4 decimals. + + If primaries have already been set on this object, the protocol error + already_set is raised. + + This request can be used if the compositor advertises + xx_color_manager_v4.feature.set_primaries. Otherwise this request raises + the protocol error unsupported_feature. + + + + + + + + + + + + + + + Sets the primary color volume luminance range and the reference white + luminance level. + + The default luminances are + - primary color volume minimum: 0.2 cd/m² + - primary color volume maximum: 80 cd/m² + - reference white: 80 cd/m² + + Setting a named transfer characteristic can imply other default + luminances. + + The default luminances get overwritten when this request is used. + + 'min_lum' and 'max_lum' specify the minimum and maximum luminances of + the primary color volume as reproduced by the targeted display. + + 'reference_lum' specifies the luminance of the reference white as + reproduced by the targeted display, and reflects the targeted viewing + environment. + + Compositors should make sure that all content is anchored, meaning that + an input signal level of 'reference_lum' on one image description and + another input signal level of 'reference_lum' on another image + description should produce the same output level, even though the + 'reference_lum' on both image representations can be different. + + If 'max_lum' is less than the 'reference_lum', or 'reference_lum' is + less than or equal to 'min_lum', the protocol error invalid_luminance is + raised. + + The minimum luminance is multiplied by 10000 to get the argument + 'min_lum' value and carries precision of 4 decimals. The maximum + luminance and reference white luminance values are unscaled. + + If the primary color volume luminance range and the reference white + luminance level have already been set on this object, the protocol error + already_set is raised. + + This request can be used if the compositor advertises + xx_color_manager_v4.feature.set_luminances. Otherwise this request + raises the protocol error unsupported_feature. + + + + + + + + + + Provides the color primaries and white point of the mastering display + using CIE 1931 xy chromaticity coordinates. This is compatible with the + SMPTE ST 2086 definition of HDR static metadata. + + The mastering display primaries define the target color volume. + + If mastering display primaries are not explicitly set, the target color + volume is assumed to be equal to the primary color volume. + + The target color volume is defined by all tristimulus values between 0.0 + and 1.0 (inclusive) of the color space defined by the given mastering + display primaries and white point. The colorimetry is identical between + the container color space and the mastering display color space, + including that no chromatic adaptation is applied even if the white + points differ. + + The target color volume can exceed the primary color volume to allow for + a greater color volume with an existing color space definition (for + example scRGB). It can be smaller than the primary color volume to + minimize gamut and tone mapping distances for big color spaces (HDR + metadata). + + To make use of the entire target color volume a suitable pixel format + has to be chosen (e.g. floating point to exceed the primary color + volume, or abusing limited quantization range as with xvYCC). + + Each coordinate value is multiplied by 10000 to get the argument value + to carry precision of 4 decimals. + + If mastering display primaries have already been set on this object, the + protocol error already_set is raised. + + This request can be used if the compositor advertises + xx_color_manager_v4.feature.set_mastering_display_primaries. Otherwise + this request raises the protocol error unsupported_feature. The + advertisement implies support only for target color volumes fully + contained within the primary color volume. + + If a compositor additionally supports target color volume exceeding the + primary color volume, it must advertise + xx_color_manager_v4.feature.extended_target_volume. If a client uses + target color volume exceeding the primary color volume and the + compositor does not support it, the result is implementation defined. + Compositors are recommended to detect this case and fail the image + description gracefully, but it may as well result in color artifacts. + + + + + + + + + + + + + + + Sets the luminance range that was used during the content mastering + process as the minimum and maximum absolute luminance L. This is + compatible with the SMPTE ST 2086 definition of HDR static metadata. + + The mastering luminance range is undefined by default. + + If max L is less than or equal to min L, the protocol error + invalid_luminance is raised. + + Min L value is multiplied by 10000 to get the argument min_lum value + and carry precision of 4 decimals. Max L value is unscaled for max_lum. + + + + + + + + + Sets the maximum content light level (max_cll) as defined by CTA-861-H. + + This can only be set when set_tf_cicp is used to set the transfer + characteristic to Rec. ITU-R BT.2100-2 perceptual quantization system. + Otherwise, 'create' request shall raise inconsistent_set protocol + error. + + max_cll is undefined by default. + + + + + + + + Sets the maximum frame-average light level (max_fall) as defined by + CTA-861-H. + + This can only be set when set_tf_cicp is used to set the transfer + characteristic to Rec. ITU-R BT.2100-2 perceptual quantization system. + Otherwise, 'create' request shall raise inconsistent_set protocol error. + + max_fall is undefined by default. + + + + + + + + + An image description carries information about the color encoding used on + a surface when attached to a wl_surface via + xx_color_management_surface_v4.set_image_description. A compositor can use + this information to decode pixel values into colorimetrically meaningful + quantities. + + Note, that the xx_image_description_v4 object is not ready to be used + immediately after creation. The object eventually delivers either the + 'ready' or the 'failed' event, specified in all requests creating it. The + object is deemed "ready" after receiving the 'ready' event. + + An object which is not ready is illegal to use, it can only be destroyed. + Any other request in this interface shall result in the 'not_ready' + protocol error. Attempts to use an object which is not ready through other + interfaces shall raise protocol errors defined there. + + Once created and regardless of how it was created, a + xx_image_description_v4 object always refers to one fixed image + description. It cannot change after creation. + + + + + Destroy this object. It is safe to destroy an object which is not ready. + + Destroying a xx_image_description_v4 object has no side-effects, not + even if a xx_color_management_surface_v4.set_image_description has not + yet been followed by a wl_surface.commit. + + + + + + + + + + + + + + + + + + + + + + If creating a xx_image_description_v4 object fails for a reason that is + not defined as a protocol error, this event is sent. + + The requests that create image description objects define whether and + when this can occur. Only such creation requests can trigger this event. + This event cannot be triggered after the image description was + successfully formed. + + Once this event has been sent, the xx_image_description_v4 object will + never become ready and it can only be destroyed. + + + + + + + + + Once this event has been sent, the xx_image_description_v4 object is + deemed "ready". Ready objects can be used to send requests and can be + used through other interfaces. + + Every ready xx_image_description_v4 protocol object refers to an + underlying image description record in the compositor. Multiple protocol + objects may end up referring to the same record. Clients may identify + these "copies" by comparing their id numbers: if the numbers from two + protocol objects are identical, the protocol objects refer to the same + image description record. Two different image description records + cannot have the same id number simultaneously. The id number does not + change during the lifetime of the image description record. + + The id number is valid only as long as the protocol object is alive. If + all protocol objects referring to the same image description record are + destroyed, the id number may be recycled for a different image + description record. + + Image description id number is not a protocol object id. Zero is + reserved as an invalid id number. It shall not be possible for a client + to refer to an image description by its id number in protocol. The id + numbers might not be portable between Wayland connections. + + This identity allows clients to de-duplicate image description records + and avoid get_information request if they already have the image + description information. + + + + + + + + Creates a xx_image_description_info_v4 object which delivers the + information that makes up the image description. + + Not all image description protocol objects allow get_information + request. Whether it is allowed or not is defined by the request that + created the object. If get_information is not allowed, the protocol + error no_information is raised. + + + + + + + + + Sends all matching events describing an image description object exactly + once and finally sends the 'done' event. + + Once a xx_image_description_info_v4 object has delivered a 'done' event it + is automatically destroyed. + + Every xx_image_description_info_v4 created from the same + xx_image_description_v4 shall always return the exact same data. + + + + + Signals the end of information events and destroys the object. + + + + + + The icc argument provides a file descriptor to the client which may be + memory-mapped to provide the ICC profile matching the image description. + The fd is read-only, and if mapped then it must be mapped with + MAP_PRIVATE by the client. + + The ICC profile version and other details are determined by the + compositor. There is no provision for a client to ask for a specific + kind of a profile. + + + + + + + + + + Delivers the primary color volume primaries and white point using CIE + 1931 xy chromaticity coordinates. + + Each coordinate value is multiplied by 10000 to get the argument value + to carry precision of 4 decimals. + + + + + + + + + + + + + + + Delivers the primary color volume primaries and white point using an + explicitly enumerated named set. + + + + + + + + The color component transfer characteristic of this image description is + a pure power curve. This event provides the exponent of the power + function. This curve represents the conversion from electrical to + optical pixel or color values. + + The curve exponent has been multiplied by 10000 to get the argument eexp + value to carry the precision of 4 decimals. + + + + + + + + Delivers the transfer characteristic using an explicitly enumerated + named function. + + + + + + + + Delivers the primary color volume luminance range and the reference + white luminance level. + + The minimum luminance is multiplied by 10000 to get the argument + 'min_lum' value and carries precision of 4 decimals. The maximum + luminance and reference white luminance values are unscaled. + + + + + + + + + + Provides the color primaries and white point of the target color volume + using CIE 1931 xy chromaticity coordinates. This is compatible with the + SMPTE ST 2086 definition of HDR static metadata for mastering displays. + + While primary color volume is about how color is encoded, the target + color volume is the actually displayable color volume. If target color + volume is equal to the primary color volume, then this event is not + sent. + + Each coordinate value is multiplied by 10000 to get the argument value + to carry precision of 4 decimals. + + + + + + + + + + + + + + + Provides the luminance range that the image description is targeting as + the minimum and maximum absolute luminance L. This is compatible with + the SMPTE ST 2086 definition of HDR static metadata. + + This luminance range is only theoretical and may not correspond to the + luminance of light emitted on an actual display. + + Min L value is multiplied by 10000 to get the argument min_lum value and + carry precision of 4 decimals. Max L value is unscaled for max_lum. + + + + + + + + + Provides the targeted max_cll of the image description. max_cll is + defined by CTA-861-H. + + This luminance is only theoretical and may not correspond to the + luminance of light emitted on an actual display. + + + + + + + + Provides the targeted max_fall of the image description. max_fall is + defined by CTA-861-H. + + This luminance is only theoretical and may not correspond to the + luminance of light emitted on an actual display. + + + + + + \ No newline at end of file diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 5805eff9..3d159042 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -31,6 +31,7 @@ #include "protocols/XDGShell.hpp" #include "protocols/XDGOutput.hpp" #include "protocols/SecurityContext.hpp" +#include "protocols/ColorManagement.hpp" #include "protocols/core/Compositor.hpp" #include "protocols/core/Subcompositor.hpp" #include "desktop/LayerSurface.hpp" @@ -2985,4 +2986,22 @@ void CCompositor::onNewMonitor(SP output) { g_pHyprRenderer->damageMonitor(PNEWMONITOR); PNEWMONITOR->onMonitorFrame(); + + if (PROTO::colorManagement && shouldChangePreferredImageDescription()) + PROTO::colorManagement->onImagePreferredChanged(); +} + +SImageDescription CCompositor::getPreferredImageDescription() { + if (!PROTO::colorManagement) { + Debug::log(ERR, "FIXME: color management protocol is not enabled, returning empty image description"); + return SImageDescription{}; + } + Debug::log(WARN, "FIXME: color management protocol is enabled, determine correct preferred image description"); + // should determine some common settings to avoid unnecessary transformations while keeping maximum displayable precision + return SImageDescription{.primaries = NColorPrimaries::BT709}; +} + +bool CCompositor::shouldChangePreferredImageDescription() { + Debug::log(WARN, "FIXME: color management protocol is enabled and outputs changed, check preferred image description changes"); + return false; } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 4c428fca..629b71bc 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -23,6 +23,7 @@ #include "helpers/Monitor.hpp" #include "desktop/Workspace.hpp" #include "desktop/Window.hpp" +#include "protocols/types/ColorManagement.hpp" #include "render/Renderer.hpp" #include "render/OpenGL.hpp" #include "hyprerror/HyprError.hpp" @@ -169,6 +170,9 @@ class CCompositor { void updateSuspendedStates(); void onNewMonitor(SP output); + SImageDescription getPreferredImageDescription(); + bool shouldChangePreferredImageDescription(); + std::string explicitConfigPath; private: diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 8c35a3b1..686b996a 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1658,4 +1658,22 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{true}, }, + SConfigOptionDescription{ + .value = "experimental:wide_color_gamut", + .description = "force wide color gamut for all supported outputs", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, + SConfigOptionDescription{ + .value = "experimental:hdr", + .description = "force static hdr for all supported outputs", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, + SConfigOptionDescription{ + .value = "experimental:xx_color_management_v4", + .description = "enable color management protocol", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, }; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 1ab29b1f..bbb3e68f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -622,6 +622,10 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0}); + m_pConfig->addConfigValue("experimental:wide_color_gamut", Hyprlang::INT{0}); + m_pConfig->addConfigValue("experimental:hdr", Hyprlang::INT{0}); + m_pConfig->addConfigValue("experimental:xx_color_management_v4", Hyprlang::INT{0}); + // devices m_pConfig->addSpecialCategory("device", {"name"}); m_pConfig->addSpecialConfigValue("device", "sensitivity", {0.F}); diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 07af13df..057a6f90 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -119,4 +119,5 @@ class CWLSurface { } listeners; friend class CPointerConstraint; + friend class CXxColorManagerV4; }; diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 0e1c21f5..b7d61f67 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -55,6 +55,8 @@ #include "../protocols/core/Subcompositor.hpp" #include "../protocols/core/Output.hpp" #include "../protocols/core/Shm.hpp" +#include "../protocols/ColorManagement.hpp" +#include "../protocols/FrogColorManagement.hpp" #include "../helpers/Monitor.hpp" #include "../render/Renderer.hpp" @@ -77,11 +79,15 @@ void CProtocolManager::onMonitorModeChange(PHLMONITOR pMonitor) { PROTO::outputs.erase(pMonitor->szName); PROTO::outputs.emplace(pMonitor->szName, makeShared(&wl_output_interface, 4, std::format("WLOutput ({})", pMonitor->szName), pMonitor->self.lock())); } + + if (PROTO::colorManagement && g_pCompositor->shouldChangePreferredImageDescription()) + PROTO::colorManagement->onImagePreferredChanged(); } CProtocolManager::CProtocolManager() { static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); + static const auto PENABLEXXCM = CConfigValue("experimental:xx_color_management_v4"); // Outputs are a bit dumb, we have to agree. static auto P = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any param) { @@ -162,6 +168,11 @@ CProtocolManager::CProtocolManager() { PROTO::ctm = std::make_unique(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl"); PROTO::hyprlandSurface = std::make_unique(&hyprland_surface_manager_v1_interface, 1, "HyprlandSurface"); + if (*PENABLEXXCM) { + PROTO::colorManagement = std::make_unique(&xx_color_manager_v4_interface, 1, "ColorManagement"); + PROTO::frogColorManagement = std::make_unique(&frog_color_management_factory_v1_interface, 1, "FrogColorManagement"); + } + for (auto const& b : g_pCompositor->m_pAqBackend->getImplementations()) { if (b->type() != Aquamarine::AQ_BACKEND_DRM) continue; diff --git a/src/protocols/ColorManagement.cpp b/src/protocols/ColorManagement.cpp new file mode 100644 index 00000000..7ff4db4f --- /dev/null +++ b/src/protocols/ColorManagement.cpp @@ -0,0 +1,571 @@ +#include "ColorManagement.hpp" +#include "Compositor.hpp" + +CColorManager::CColorManager(SP resource_) : resource(resource_) { + if (!good()) + return; + + resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_PARAMETRIC); + resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_EXTENDED_TARGET_VOLUME); + resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES); + resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_SET_PRIMARIES); + resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_SET_LUMINANCES); + + resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_SRGB); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_PAL_M); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_PAL); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_NTSC); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_GENERIC_FILM); + resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_BT2020); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_CIE1931_XYZ); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_DCI_P3); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_DISPLAY_P3); + // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_ADOBE_RGB); + + // resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22); + resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB); + resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ); + // resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR); + + resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL); + // resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE); + // resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_ABSOLUTE); + // resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE_BPC); + + resource->setDestroy([](CXxColorManagerV4* r) { LOGM(TRACE, "Destroy xx_color_manager at {:x} (generated default)", (uintptr_t)r); }); + resource->setGetOutput([](CXxColorManagerV4* r, uint32_t id, wl_resource* output) { + LOGM(TRACE, "Get output for id={}, output={}", id, (uintptr_t)output); + const auto RESOURCE = + PROTO::colorManagement->m_vOutputs.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vOutputs.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + }); + resource->setGetSurface([](CXxColorManagerV4* r, uint32_t id, wl_resource* surface) { + LOGM(TRACE, "Get surface for id={}, surface={}", id, (uintptr_t)surface); + auto SURF = CWLSurfaceResource::fromResource(surface); + + if (!SURF) { + LOGM(ERR, "No surface for resource {}", (uintptr_t)surface); + r->error(-1, "Invalid surface (2)"); + return; + } + + if (SURF->colorManagement) { + r->error(XX_COLOR_MANAGER_V4_ERROR_SURFACE_EXISTS, "CM Surface already exists"); + return; + } + + const auto RESOURCE = + PROTO::colorManagement->m_vSurfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id), SURF)); + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vSurfaces.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + + SURF->colorManagement = RESOURCE; + }); + resource->setGetFeedbackSurface([](CXxColorManagerV4* r, uint32_t id, wl_resource* surface) { + LOGM(TRACE, "Get feedback surface for id={}, surface={}", id, (uintptr_t)surface); + auto SURF = CWLSurfaceResource::fromResource(surface); + + if (!SURF) { + LOGM(ERR, "No surface for resource {}", (uintptr_t)surface); + r->error(-1, "Invalid surface (2)"); + return; + } + + const auto RESOURCE = PROTO::colorManagement->m_vFeedbackSurfaces.emplace_back( + makeShared(makeShared(r->client(), r->version(), id), SURF)); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vFeedbackSurfaces.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + }); + resource->setNewIccCreator([](CXxColorManagerV4* r, uint32_t id) { + LOGM(WARN, "New ICC creator for id={} (unsupported)", id); + r->error(XX_COLOR_MANAGER_V4_ERROR_UNSUPPORTED_FEATURE, "ICC profiles are not supported"); + }); + resource->setNewParametricCreator([](CXxColorManagerV4* r, uint32_t id) { + LOGM(TRACE, "New parametric creator for id={}", id); + + const auto RESOURCE = PROTO::colorManagement->m_vParametricCreators.emplace_back( + makeShared(makeShared(r->client(), r->version(), id))); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vParametricCreators.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + }); + + resource->setOnDestroy([this](CXxColorManagerV4* r) { PROTO::colorManagement->destroyResource(this); }); +} + +bool CColorManager::good() { + return resource->resource(); +} + +CColorManagementOutput::CColorManagementOutput(SP resource_) : resource(resource_) { + if (!good()) + return; + + pClient = resource->client(); + + resource->setDestroy([this](CXxColorManagementOutputV4* r) { PROTO::colorManagement->destroyResource(this); }); + resource->setOnDestroy([this](CXxColorManagementOutputV4* r) { PROTO::colorManagement->destroyResource(this); }); + + resource->setGetImageDescription([this](CXxColorManagementOutputV4* r, uint32_t id) { + LOGM(TRACE, "Get image description for output={}, id={}", (uintptr_t)r, id); + if (imageDescription.valid()) + PROTO::colorManagement->destroyResource(imageDescription.get()); + + const auto RESOURCE = PROTO::colorManagement->m_vImageDescriptions.emplace_back( + makeShared(makeShared(r->client(), r->version(), id))); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vImageDescriptions.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + }); +} + +bool CColorManagementOutput::good() { + return resource->resource(); +} + +wl_client* CColorManagementOutput::client() { + return pClient; +} + +CColorManagementSurface::CColorManagementSurface(SP surface_) : surface(surface_) { + // only for frog cm untill wayland cm is adopted +} + +CColorManagementSurface::CColorManagementSurface(SP resource_, SP surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; + + pClient = resource->client(); + + resource->setDestroy([this](CXxColorManagementSurfaceV4* r) { + LOGM(TRACE, "Destroy xx cm surface {}", (uintptr_t)surface); + PROTO::colorManagement->destroyResource(this); + }); + resource->setOnDestroy([this](CXxColorManagementSurfaceV4* r) { + LOGM(TRACE, "Destroy xx cm surface {}", (uintptr_t)surface); + PROTO::colorManagement->destroyResource(this); + }); + + resource->setSetImageDescription([this](CXxColorManagementSurfaceV4* r, wl_resource* image_description, uint32_t render_intent) { + LOGM(TRACE, "Set image description for surface={}, desc={}, intent={}", (uintptr_t)r, (uintptr_t)image_description, render_intent); + + const auto PO = (CXxImageDescriptionV4*)wl_resource_get_user_data(image_description); + if (!PO) { // FIXME check validity + r->error(XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION, "Image description creation failed"); + return; + } + if (render_intent != XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL) { + r->error(XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_RENDER_INTENT, "Unsupported render intent"); + return; + } + + const auto imageDescription = std::find_if(PROTO::colorManagement->m_vImageDescriptions.begin(), PROTO::colorManagement->m_vImageDescriptions.end(), + [&](const auto& other) { return other->resource()->resource() == image_description; }); + if (imageDescription == PROTO::colorManagement->m_vImageDescriptions.end()) { + r->error(XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION, "Image description not found"); + return; + } + + m_hasImageDescription = true; + m_imageDescription = imageDescription->get()->settings; + }); + resource->setUnsetImageDescription([this](CXxColorManagementSurfaceV4* r) { + LOGM(TRACE, "Unset image description for surface={}", (uintptr_t)r); + m_imageDescription = SImageDescription{}; + m_hasImageDescription = false; + }); +} + +bool CColorManagementSurface::good() { + return resource && resource->resource(); +} + +wl_client* CColorManagementSurface::client() { + return pClient; +} + +const SImageDescription& CColorManagementSurface::imageDescription() { + if (!hasImageDescription()) + LOGM(WARN, "Reading imageDescription while none set. Returns default or empty values"); + return m_imageDescription; +} + +bool CColorManagementSurface::hasImageDescription() { + return m_hasImageDescription; +} + +CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP resource_, SP surface_) : + surface(surface_), resource(resource_) { + if (!good()) + return; + + pClient = resource->client(); + + resource->setDestroy([this](CXxColorManagementFeedbackSurfaceV4* r) { + LOGM(TRACE, "Destroy xx cm feedback surface {}", (uintptr_t)surface); + if (m_currentPreferred.valid()) + PROTO::colorManagement->destroyResource(m_currentPreferred.get()); + PROTO::colorManagement->destroyResource(this); + }); + resource->setOnDestroy([this](CXxColorManagementFeedbackSurfaceV4* r) { + LOGM(TRACE, "Destroy xx cm feedback surface {}", (uintptr_t)surface); + if (m_currentPreferred.valid()) + PROTO::colorManagement->destroyResource(m_currentPreferred.get()); + PROTO::colorManagement->destroyResource(this); + }); + + resource->setGetPreferred([this](CXxColorManagementFeedbackSurfaceV4* r, uint32_t id) { + LOGM(TRACE, "Get preferred for id {}", id); + + if (m_currentPreferred.valid()) + PROTO::colorManagement->destroyResource(m_currentPreferred.get()); + + const auto RESOURCE = PROTO::colorManagement->m_vImageDescriptions.emplace_back( + makeShared(makeShared(r->client(), r->version(), id), true)); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vImageDescriptions.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + m_currentPreferred = RESOURCE; + + m_currentPreferred->settings = g_pCompositor->getPreferredImageDescription(); + + RESOURCE->resource()->sendReady(id); + }); +} + +bool CColorManagementFeedbackSurface::good() { + return resource->resource(); +} + +wl_client* CColorManagementFeedbackSurface::client() { + return pClient; +} + +CColorManagementParametricCreator::CColorManagementParametricCreator(SP resource_) : resource(resource_) { + if (!good()) + return; + // + pClient = resource->client(); + + resource->setOnDestroy([this](CXxImageDescriptionCreatorParamsV4* r) { PROTO::colorManagement->destroyResource(this); }); + + resource->setCreate([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t id) { + LOGM(TRACE, "Create image description from params for id {}", id); + + // FIXME actually check completeness + if (!valuesSet) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INCOMPLETE_SET, "Missing required settings"); + return; + } + + // FIXME actually check consistency + if (!valuesSet) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INCONSISTENT_SET, "Set is not consistent"); + return; + } + + const auto RESOURCE = PROTO::colorManagement->m_vImageDescriptions.emplace_back( + makeShared(makeShared(r->client(), r->version(), id))); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::colorManagement->m_vImageDescriptions.pop_back(); + return; + } + + // FIXME actually check support + if (!valuesSet) { + RESOURCE->resource()->sendFailed(XX_IMAGE_DESCRIPTION_V4_CAUSE_UNSUPPORTED, "unsupported"); + return; + } + + RESOURCE->self = RESOURCE; + RESOURCE->settings = settings; + RESOURCE->resource()->sendReady(id); + + PROTO::colorManagement->destroyResource(this); + }); + resource->setSetTfNamed([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t tf) { + LOGM(TRACE, "Set image description transfer function to {}", tf); + if (valuesSet & PC_TF) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Transfer function already set"); + return; + } + + switch (tf) { + case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB: break; + case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ: break; + default: r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_TF, "Unsupported transfer function"); return; + } + + settings.transferFunction = (xxColorManagerV4TransferFunction)tf; + valuesSet |= PC_TF; + }); + resource->setSetTfPower([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t eexp) { + LOGM(TRACE, "Set image description tf power to {}", eexp); + if (valuesSet & PC_TF_POWER) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Transfer function power already set"); + return; + } + settings.transferFunctionPower = eexp / 10000.0f; + valuesSet |= PC_TF_POWER; + }); + resource->setSetPrimariesNamed([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t primaries) { + LOGM(TRACE, "Set image description primaries by name {}", primaries); + if (valuesSet & PC_PRIMARIES) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Primaries already set"); + return; + } + + switch (primaries) { + case XX_COLOR_MANAGER_V4_PRIMARIES_SRGB: + settings.primariesNameSet = true; + settings.primariesNamed = XX_COLOR_MANAGER_V4_PRIMARIES_SRGB; + settings.primaries = NColorPrimaries::BT709; + valuesSet |= PC_PRIMARIES; + break; + case XX_COLOR_MANAGER_V4_PRIMARIES_BT2020: + settings.primariesNameSet = true; + settings.primariesNamed = XX_COLOR_MANAGER_V4_PRIMARIES_BT2020; + settings.primaries = NColorPrimaries::BT2020; + valuesSet |= PC_PRIMARIES; + break; + default: r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_PRIMARIES, "Unsupported primaries"); + } + }); + resource->setSetPrimaries( + [this](CXxImageDescriptionCreatorParamsV4* r, int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y) { + LOGM(TRACE, "Set image description primaries by values r:{},{} g:{},{} b:{},{} w:{},{}", r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y); + if (valuesSet & PC_PRIMARIES) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Primaries already set"); + return; + } + settings.primariesNameSet = false; + settings.primaries = + SImageDescription::SPCPRimaries{.red = {.x = r_x, .y = r_y}, .green = {.x = g_x, .y = g_y}, .blue = {.x = b_x, .y = b_y}, .white = {.x = w_x, .y = w_y}}; + valuesSet |= PC_PRIMARIES; + }); + resource->setSetLuminances([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t min_lum, uint32_t max_lum, uint32_t reference_lum) { + auto min = min_lum / 10000.0f; + LOGM(TRACE, "Set image description luminances to {} - {} ({})", min, max_lum, reference_lum); + if (valuesSet & PC_LUMINANCES) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Luminances already set"); + return; + } + if (max_lum < reference_lum || reference_lum <= min) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_LUMINANCE, "Invalid luminances"); + return; + } + settings.luminances = SImageDescription::SPCLuminances{.min = min, .max = max_lum, .reference = reference_lum}; + valuesSet |= PC_LUMINANCES; + }); + resource->setSetMasteringDisplayPrimaries( + [this](CXxImageDescriptionCreatorParamsV4* r, int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y) { + LOGM(TRACE, "Set image description mastering primaries by values r:{},{} g:{},{} b:{},{} w:{},{}", r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y); + // if (valuesSet & PC_MASTERING_PRIMARIES) { + // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Mastering primaries already set"); + // return; + // } + settings.masteringPrimaries = + SImageDescription::SPCPRimaries{.red = {.x = r_x, .y = r_y}, .green = {.x = g_x, .y = g_y}, .blue = {.x = b_x, .y = b_y}, .white = {.x = w_x, .y = w_y}}; + valuesSet |= PC_MASTERING_PRIMARIES; + }); + resource->setSetMasteringLuminance([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t min_lum, uint32_t max_lum) { + auto min = min_lum / 10000.0f; + LOGM(TRACE, "Set image description mastering luminances to {} - {}", min, max_lum); + // if (valuesSet & PC_MASTERING_LUMINANCES) { + // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Mastering luminances already set"); + // return; + // } + if (min > 0 && max_lum > 0 && max_lum <= min) { + r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_LUMINANCE, "Invalid luminances"); + return; + } + settings.masteringLuminances = SImageDescription::SPCMasteringLuminances{.min = min, .max = max_lum}; + valuesSet |= PC_MASTERING_LUMINANCES; + }); + resource->setSetMaxCll([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t max_cll) { + LOGM(TRACE, "Set image description max content light level to {}", max_cll); + // if (valuesSet & PC_CLL) { + // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Max CLL already set"); + // return; + // } + settings.maxCLL = max_cll; + valuesSet |= PC_CLL; + }); + resource->setSetMaxFall([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t max_fall) { + LOGM(TRACE, "Set image description max frame-average light level to {}", max_fall); + // if (valuesSet & PC_FALL) { + // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Max FALL already set"); + // return; + // } + settings.maxFALL = max_fall; + valuesSet |= PC_FALL; + }); +} + +bool CColorManagementParametricCreator::good() { + return resource->resource(); +} + +wl_client* CColorManagementParametricCreator::client() { + return pClient; +} + +CColorManagementImageDescription::CColorManagementImageDescription(SP resource_, bool allowGetInformation) : + m_resource(resource_), m_allowGetInformation(allowGetInformation) { + if (!good()) + return; + + pClient = m_resource->client(); + + m_resource->setDestroy([this](CXxImageDescriptionV4* r) { PROTO::colorManagement->destroyResource(this); }); + m_resource->setOnDestroy([this](CXxImageDescriptionV4* r) { PROTO::colorManagement->destroyResource(this); }); + + m_resource->setGetInformation([this](CXxImageDescriptionV4* r, uint32_t id) { + LOGM(TRACE, "Get image information for image={}, id={}", (uintptr_t)r, id); + if (!m_allowGetInformation) { + r->error(XX_IMAGE_DESCRIPTION_V4_ERROR_NO_INFORMATION, "Image descriptions doesn't allow get_information request"); + return; + } + + auto RESOURCE = makeShared(makeShared(r->client(), r->version(), id), settings); + + if (!RESOURCE->good()) + r->noMemory(); + + // CColorManagementImageDescriptionInfo should send everything in the constructor and be ready for destroying at this point + RESOURCE.reset(); + }); +} + +bool CColorManagementImageDescription::good() { + return m_resource->resource(); +} + +wl_client* CColorManagementImageDescription::client() { + return pClient; +} + +SP CColorManagementImageDescription::resource() { + return m_resource; +} + +CColorManagementImageDescriptionInfo::CColorManagementImageDescriptionInfo(SP resource_, const SImageDescription& settings_) : + m_resource(resource_), settings(settings_) { + if (!good()) + return; + + pClient = m_resource->client(); + + const auto toProto = [](float value) { return int32_t(std::round(value * 10000)); }; + + if (settings.iccFd >= 0) + m_resource->sendIccFile(settings.iccFd, settings.iccSize); + + // send preferred client paramateres + m_resource->sendPrimaries(toProto(settings.primaries.red.x), toProto(settings.primaries.red.y), toProto(settings.primaries.green.x), toProto(settings.primaries.green.y), + toProto(settings.primaries.blue.x), toProto(settings.primaries.blue.y), toProto(settings.primaries.white.x), toProto(settings.primaries.white.y)); + if (settings.primariesNameSet) + m_resource->sendPrimariesNamed(settings.primariesNamed); + m_resource->sendTfPower(std::round(settings.transferFunctionPower * 10000)); + m_resource->sendTfNamed(settings.transferFunction); + m_resource->sendLuminances(std::round(settings.luminances.min * 10000), settings.luminances.max, settings.luminances.reference); + + // send expexted display paramateres + m_resource->sendTargetPrimaries(toProto(settings.masteringPrimaries.red.x), toProto(settings.masteringPrimaries.red.y), toProto(settings.masteringPrimaries.green.x), + toProto(settings.masteringPrimaries.green.y), toProto(settings.masteringPrimaries.blue.x), toProto(settings.masteringPrimaries.blue.y), + toProto(settings.masteringPrimaries.white.x), toProto(settings.masteringPrimaries.white.y)); + m_resource->sendTargetLuminance(std::round(settings.masteringLuminances.min * 10000), settings.masteringLuminances.max); + m_resource->sendTargetMaxCll(settings.maxCLL); + m_resource->sendTargetMaxFall(settings.maxFALL); + + m_resource->sendDone(); +} + +bool CColorManagementImageDescriptionInfo::good() { + return m_resource->resource(); +} + +wl_client* CColorManagementImageDescriptionInfo::client() { + return pClient; +} + +CColorManagementProtocol::CColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CColorManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); + + if (!RESOURCE->good()) { + wl_client_post_no_memory(client); + m_vManagers.pop_back(); + return; + } + + LOGM(TRACE, "New xx_color_manager at {:x}", (uintptr_t)RESOURCE.get()); +} + +void CColorManagementProtocol::onImagePreferredChanged() { + for (auto const& feedback : m_vFeedbackSurfaces) { + feedback->resource->sendPreferredChanged(); + } +} + +void CColorManagementProtocol::destroyResource(CColorManager* resource) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; }); +} + +void CColorManagementProtocol::destroyResource(CColorManagementOutput* resource) { + std::erase_if(m_vOutputs, [&](const auto& other) { return other.get() == resource; }); +} + +void CColorManagementProtocol::destroyResource(CColorManagementSurface* resource) { + std::erase_if(m_vSurfaces, [&](const auto& other) { return other.get() == resource; }); +} + +void CColorManagementProtocol::destroyResource(CColorManagementFeedbackSurface* resource) { + std::erase_if(m_vFeedbackSurfaces, [&](const auto& other) { return other.get() == resource; }); +} + +void CColorManagementProtocol::destroyResource(CColorManagementParametricCreator* resource) { + std::erase_if(m_vParametricCreators, [&](const auto& other) { return other.get() == resource; }); +} + +void CColorManagementProtocol::destroyResource(CColorManagementImageDescription* resource) { + std::erase_if(m_vImageDescriptions, [&](const auto& other) { return other.get() == resource; }); +} diff --git a/src/protocols/ColorManagement.hpp b/src/protocols/ColorManagement.hpp new file mode 100644 index 00000000..573abf69 --- /dev/null +++ b/src/protocols/ColorManagement.hpp @@ -0,0 +1,182 @@ +#pragma once + +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "protocols/core/Compositor.hpp" +#include "xx-color-management-v4.hpp" +#include "types/ColorManagement.hpp" + +class CColorManager; +class CColorManagementOutput; +class CColorManagementImageDescription; +class CColorManagementProtocol; + +class CColorManager { + public: + CColorManager(SP resource_); + + bool good(); + + private: + SP resource; +}; + +class CColorManagementOutput { + public: + CColorManagementOutput(SP resource_); + + bool good(); + wl_client* client(); + + WP self; + WP imageDescription; + + private: + SP resource; + wl_client* pClient = nullptr; + + friend class CColorManagementProtocol; + friend class CColorManagementImageDescription; +}; + +class CColorManagementSurface { + public: + CColorManagementSurface(SP surface_); // temporary interface for frog CM + CColorManagementSurface(SP resource_, SP surface_); + + bool good(); + wl_client* client(); + + WP self; + WP surface; + + const SImageDescription& imageDescription(); + bool hasImageDescription(); + + private: + SP resource; + wl_client* pClient = nullptr; + SImageDescription m_imageDescription; + bool m_hasImageDescription = false; + + friend class CFrogColorManagementSurface; +}; + +class CColorManagementFeedbackSurface { + public: + CColorManagementFeedbackSurface(SP resource_, SP surface_); + + bool good(); + wl_client* client(); + + WP self; + WP surface; + + private: + SP resource; + wl_client* pClient = nullptr; + + WP m_currentPreferred; + + friend class CColorManagementProtocol; +}; + +class CColorManagementParametricCreator { + public: + CColorManagementParametricCreator(SP resource_); + + bool good(); + wl_client* client(); + + WP self; + + SImageDescription settings; + + private: + enum eValuesSet : uint32_t { // NOLINT + PC_TF = (1 << 0), + PC_TF_POWER = (1 << 1), + PC_PRIMARIES = (1 << 2), + PC_LUMINANCES = (1 << 3), + PC_MASTERING_PRIMARIES = (1 << 4), + PC_MASTERING_LUMINANCES = (1 << 5), + PC_CLL = (1 << 6), + PC_FALL = (1 << 7), + }; + + SP resource; + wl_client* pClient = nullptr; + uint32_t valuesSet = 0; // enum eValuesSet +}; + +class CColorManagementImageDescription { + public: + CColorManagementImageDescription(SP resource_, bool allowGetInformation = false); + + bool good(); + wl_client* client(); + SP resource(); + + WP self; + + SImageDescription settings; + + private: + SP m_resource; + wl_client* pClient = nullptr; + bool m_allowGetInformation = false; + + friend class CColorManagementOutput; +}; + +class CColorManagementImageDescriptionInfo { + public: + CColorManagementImageDescriptionInfo(SP resource_, const SImageDescription& settings_); + + bool good(); + wl_client* client(); + + private: + SP m_resource; + wl_client* pClient = nullptr; + SImageDescription settings; +}; + +class CColorManagementProtocol : public IWaylandProtocol { + public: + CColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + void onImagePreferredChanged(); + + private: + void destroyResource(CColorManager* resource); + void destroyResource(CColorManagementOutput* resource); + void destroyResource(CColorManagementSurface* resource); + void destroyResource(CColorManagementFeedbackSurface* resource); + void destroyResource(CColorManagementParametricCreator* resource); + void destroyResource(CColorManagementImageDescription* resource); + + std::vector> m_vManagers; + std::vector> m_vOutputs; + std::vector> m_vSurfaces; + std::vector> m_vFeedbackSurfaces; + std::vector> m_vParametricCreators; + std::vector> m_vImageDescriptions; + + friend class CColorManager; + friend class CColorManagementOutput; + friend class CColorManagementSurface; + friend class CColorManagementFeedbackSurface; + friend class CColorManagementParametricCreator; + friend class CColorManagementImageDescription; + + friend class CFrogColorManagementSurface; +}; + +namespace PROTO { + inline UP colorManagement; +}; diff --git a/src/protocols/FrogColorManagement.cpp b/src/protocols/FrogColorManagement.cpp new file mode 100644 index 00000000..3ea20405 --- /dev/null +++ b/src/protocols/FrogColorManagement.cpp @@ -0,0 +1,159 @@ +#include "FrogColorManagement.hpp" +#include "protocols/ColorManagement.hpp" +#include "protocols/core/Subcompositor.hpp" + +CFrogColorManager::CFrogColorManager(SP resource_) : resource(resource_) { + if (!good()) + return; + + resource->setDestroy([](CFrogColorManagementFactoryV1* r) { LOGM(TRACE, "Destroy frog_color_management at {:x} (generated default)", (uintptr_t)r); }); + resource->setOnDestroy([this](CFrogColorManagementFactoryV1* r) { PROTO::frogColorManagement->destroyResource(this); }); + + resource->setGetColorManagedSurface([](CFrogColorManagementFactoryV1* r, wl_resource* surface, uint32_t id) { + LOGM(TRACE, "Get surface for id={}, surface={}", id, (uintptr_t)surface); + auto SURF = CWLSurfaceResource::fromResource(surface); + + if (!SURF) { + LOGM(ERR, "No surface for resource {}", (uintptr_t)surface); + r->error(-1, "Invalid surface (2)"); + return; + } + + if (SURF->role->role() == SURFACE_ROLE_SUBSURFACE) + SURF = ((CSubsurfaceRole*)SURF->role.get())->subsurface->t1Parent(); + + const auto RESOURCE = PROTO::frogColorManagement->m_vSurfaces.emplace_back( + makeShared(makeShared(r->client(), r->version(), id), SURF)); + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::frogColorManagement->m_vSurfaces.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + }); +} + +bool CFrogColorManager::good() { + return resource->resource(); +} + +CFrogColorManagementSurface::CFrogColorManagementSurface(SP resource_, SP surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; + + pClient = resource->client(); + + if (!surface->colorManagement.valid()) { + const auto RESOURCE = PROTO::colorManagement->m_vSurfaces.emplace_back(makeShared(surface_)); + if (!RESOURCE) { + resource->noMemory(); + PROTO::colorManagement->m_vSurfaces.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + + surface->colorManagement = RESOURCE; + + resource->setOnDestroy([this](CFrogColorManagedSurface* r) { + LOGM(TRACE, "Destroy frog cm and xx cm for surface {}", (uintptr_t)surface); + if (surface.valid()) + PROTO::colorManagement->destroyResource(surface->colorManagement.get()); + PROTO::frogColorManagement->destroyResource(this); + }); + } else + resource->setOnDestroy([this](CFrogColorManagedSurface* r) { + LOGM(TRACE, "Destroy frog cm surface {}", (uintptr_t)surface); + PROTO::frogColorManagement->destroyResource(this); + }); + + resource->setDestroy([this](CFrogColorManagedSurface* r) { + LOGM(TRACE, "Destroy frog cm surface {}", (uintptr_t)surface); + PROTO::frogColorManagement->destroyResource(this); + }); + + resource->setSetKnownTransferFunction([this](CFrogColorManagedSurface* r, frogColorManagedSurfaceTransferFunction tf) { + LOGM(TRACE, "Set frog cm transfer function {} for {}", (uint32_t)tf, surface->id()); + switch (tf) { + case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_ST2084_PQ: + surface->colorManagement->m_imageDescription.transferFunction = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ; + break; + ; + case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_GAMMA_22: + if (pqIntentSent) { + LOGM(TRACE, + "FIXME: assuming broken enum value 2 (FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_GAMMA_22) referring to eotf value 2 (TRANSFER_FUNCTION_ST2084_PQ)"); + surface->colorManagement->m_imageDescription.transferFunction = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ; + break; + }; // intended fall through + case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_UNDEFINED: + case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_SCRGB_LINEAR: LOGM(TRACE, std::format("FIXME: add tf support for {}", (uint32_t)tf)); // intended fall through + case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_SRGB: + surface->colorManagement->m_imageDescription.transferFunction = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB; + + surface->colorManagement->m_hasImageDescription = true; + } + }); + resource->setSetKnownContainerColorVolume([this](CFrogColorManagedSurface* r, frogColorManagedSurfacePrimaries primariesName) { + LOGM(TRACE, "Set frog cm primaries {}", (uint32_t)primariesName); + switch (primariesName) { + case FROG_COLOR_MANAGED_SURFACE_PRIMARIES_UNDEFINED: + case FROG_COLOR_MANAGED_SURFACE_PRIMARIES_REC709: surface->colorManagement->m_imageDescription.primaries = NColorPrimaries::BT709; break; + case FROG_COLOR_MANAGED_SURFACE_PRIMARIES_REC2020: surface->colorManagement->m_imageDescription.primaries = NColorPrimaries::BT2020; break; + } + + surface->colorManagement->m_hasImageDescription = true; + }); + resource->setSetRenderIntent([this](CFrogColorManagedSurface* r, frogColorManagedSurfaceRenderIntent intent) { + LOGM(TRACE, "Set frog cm intent {}", (uint32_t)intent); + pqIntentSent = intent == FROG_COLOR_MANAGED_SURFACE_RENDER_INTENT_PERCEPTUAL; + surface->colorManagement->m_hasImageDescription = true; + }); + resource->setSetHdrMetadata([this](CFrogColorManagedSurface* r, uint32_t r_x, uint32_t r_y, uint32_t g_x, uint32_t g_y, uint32_t b_x, uint32_t b_y, uint32_t w_x, uint32_t w_y, + uint32_t max_lum, uint32_t min_lum, uint32_t cll, uint32_t fall) { + LOGM(TRACE, "Set frog primaries r:{},{} g:{},{} b:{},{} w:{},{} luminances {} - {} cll {} fall {}", r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y, min_lum, max_lum, cll, fall); + surface->colorManagement->m_imageDescription.masteringPrimaries = SImageDescription::SPCPRimaries{.red = {.x = r_x / 50000.0f, .y = r_y / 50000.0f}, + .green = {.x = g_x / 50000.0f, .y = g_y / 50000.0f}, + .blue = {.x = b_x / 50000.0f, .y = b_y / 50000.0f}, + .white = {.x = w_x / 50000.0f, .y = w_y / 50000.0f}}; + surface->colorManagement->m_imageDescription.masteringLuminances.min = min_lum / 10000.0f; + surface->colorManagement->m_imageDescription.masteringLuminances.max = max_lum; + surface->colorManagement->m_imageDescription.maxCLL = cll; + surface->colorManagement->m_imageDescription.maxFALL = fall; + + surface->colorManagement->m_hasImageDescription = true; + }); +} + +bool CFrogColorManagementSurface::good() { + return resource->resource(); +} + +wl_client* CFrogColorManagementSurface::client() { + return pClient; +} + +CFrogColorManagementProtocol::CFrogColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CFrogColorManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); + + if (!RESOURCE->good()) { + wl_client_post_no_memory(client); + m_vManagers.pop_back(); + return; + } + + LOGM(TRACE, "New frog_color_management at {:x}", (uintptr_t)RESOURCE.get()); +} + +void CFrogColorManagementProtocol::destroyResource(CFrogColorManager* resource) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; }); +} + +void CFrogColorManagementProtocol::destroyResource(CFrogColorManagementSurface* resource) { + std::erase_if(m_vSurfaces, [&](const auto& other) { return other.get() == resource; }); +} diff --git a/src/protocols/FrogColorManagement.hpp b/src/protocols/FrogColorManagement.hpp new file mode 100644 index 00000000..6c00e38d --- /dev/null +++ b/src/protocols/FrogColorManagement.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include "WaylandProtocol.hpp" +#include "protocols/core/Compositor.hpp" +#include "frog-color-management-v1.hpp" + +class CFrogColorManager { + public: + CFrogColorManager(SP resource_); + + bool good(); + + private: + SP resource; +}; + +class CFrogColorManagementSurface { + public: + CFrogColorManagementSurface(SP resource_, SP surface_); + + bool good(); + wl_client* client(); + + WP self; + WP surface; + + bool pqIntentSent = false; + + private: + SP resource; + wl_client* pClient = nullptr; +}; + +class CFrogColorManagementProtocol : public IWaylandProtocol { + public: + CFrogColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + private: + void destroyResource(CFrogColorManager* resource); + void destroyResource(CFrogColorManagementSurface* resource); + + std::vector> m_vManagers; + std::vector> m_vSurfaces; + + friend class CFrogColorManager; + friend class CFrogColorManagementSurface; +}; + +namespace PROTO { + inline UP frogColorManagement; +}; diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index 2a6f96f6..b347eb64 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -25,6 +25,8 @@ class CWLSurfaceResource; class CWLSubsurfaceResource; class CViewportResource; class CDRMSyncobjSurfaceResource; +class CColorManagementSurface; +class CFrogColorManagementSurface; class CWLCallbackResource { public: @@ -121,6 +123,7 @@ class CWLSurfaceResource { SP role; WP viewportResource; WP syncobj; // may not be present + WP colorManagement; void breadthfirst(std::function, const Vector2D&, void*)> fn, void* data); CRegion accumulateCurrentBufferDamage(); diff --git a/src/protocols/types/ColorManagement.hpp b/src/protocols/types/ColorManagement.hpp new file mode 100644 index 00000000..e18f0b84 --- /dev/null +++ b/src/protocols/types/ColorManagement.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "xx-color-management-v4.hpp" + +struct SImageDescription { + int iccFd = -1; + uint32_t iccSize = 0; + + xxColorManagerV4TransferFunction transferFunction = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB; + float transferFunctionPower = 1.0f; + + bool primariesNameSet = false; + xxColorManagerV4Primaries primariesNamed = XX_COLOR_MANAGER_V4_PRIMARIES_SRGB; + // primaries are stored as FP values with the same scale as standard defines (0.0 - 1.0) + // wayland protocol expects int32_t values multiplied by 10000 + // drm expects uint16_t values multiplied by 50000 + // frog protocol expects drm values + struct SPCPRimaries { + struct { + float x = 0; + float y = 0; + } red, green, blue, white; + } primaries, masteringPrimaries; + + // luminances in cd/m² + // protos and drm expect min * 10000 + struct SPCLuminances { + float min = 0.2; // 0.2 cd/m² + uint32_t max = 80; // 80 cd/m² + uint32_t reference = 80; // 80 cd/m² + } luminances; + struct SPCMasteringLuminances { + float min = 0; + uint32_t max = 0; + } masteringLuminances; + + uint32_t maxCLL = 0; + uint32_t maxFALL = 0; +}; + +namespace NColorPrimaries { + static const auto BT709 = + SImageDescription::SPCPRimaries{.red = {.x = 0.64, .y = 0.33}, .green = {.x = 0.30, .y = 0.60}, .blue = {.x = 0.15, .y = 0.06}, .white = {.x = 0.3127, .y = 0.3290}}; + + static const auto BT2020 = + SImageDescription::SPCPRimaries{.red = {.x = 0.708, .y = 0.292}, .green = {.x = 0.170, .y = 0.797}, .blue = {.x = 0.131, .y = 0.046}, .white = {.x = 0.3127, .y = 0.3290}}; +} \ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 4d93d92f..978384d5 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -25,6 +25,7 @@ #include "pass/RendererHintsPassElement.hpp" #include "pass/SurfacePassElement.hpp" #include "debug/Log.hpp" +#include "protocols/ColorManagement.hpp" #include using namespace Hyprutils::Utils; @@ -1374,6 +1375,82 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { } } +static const auto BT709 = Aquamarine::IOutput::SChromaticityCoords{ + .red = Aquamarine::IOutput::xy{.x = 0.64, .y = 0.33}, + .green = Aquamarine::IOutput::xy{.x = 0.30, .y = 0.60}, + .blue = Aquamarine::IOutput::xy{.x = 0.15, .y = 0.06}, + .white = Aquamarine::IOutput::xy{.x = 0.3127, .y = 0.3290}, +}; + +static hdr_output_metadata createHDRMetadata(uint8_t eotf, Aquamarine::IOutput::SParsedEDID edid) { + if (eotf == 0) + return hdr_output_metadata{.hdmi_metadata_type1 = hdr_metadata_infoframe{.eotf = 0}}; // empty metadata for SDR + + const auto toNits = [](float value) { return uint16_t(std::round(value)); }; + const auto to16Bit = [](float value) { return uint16_t(std::round(value * 50000)); }; + const auto colorimetry = edid.chromaticityCoords.value_or(BT709); + + Debug::log(TRACE, "ColorManagement primaries {},{} {},{} {},{} {},{}", colorimetry.red.x, colorimetry.red.y, colorimetry.green.x, colorimetry.green.y, colorimetry.blue.x, + colorimetry.blue.y, colorimetry.white.x, colorimetry.white.y); + Debug::log(TRACE, "ColorManagement max avg {}, min {}, max {}", edid.hdrMetadata->desiredMaxFrameAverageLuminance, edid.hdrMetadata->desiredContentMinLuminance, + edid.hdrMetadata->desiredContentMaxLuminance); + return hdr_output_metadata{ + .metadata_type = 0, + .hdmi_metadata_type1 = + hdr_metadata_infoframe{ + .eotf = eotf, + .metadata_type = 0, + .display_primaries = + { + {.x = to16Bit(colorimetry.red.x), .y = to16Bit(colorimetry.red.y)}, + {.x = to16Bit(colorimetry.green.x), .y = to16Bit(colorimetry.green.y)}, + {.x = to16Bit(colorimetry.blue.x), .y = to16Bit(colorimetry.blue.y)}, + }, + .white_point = {.x = to16Bit(colorimetry.white.x), .y = to16Bit(colorimetry.white.y)}, + .max_display_mastering_luminance = toNits(edid.hdrMetadata->desiredMaxFrameAverageLuminance), + .min_display_mastering_luminance = toNits(edid.hdrMetadata->desiredContentMinLuminance * 10000), + .max_cll = toNits(edid.hdrMetadata->desiredMaxFrameAverageLuminance), + .max_fall = toNits(edid.hdrMetadata->desiredMaxFrameAverageLuminance), + }, + }; +} + +static hdr_output_metadata createHDRMetadata(SImageDescription settings, Aquamarine::IOutput::SParsedEDID edid) { + if (settings.transferFunction != XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ) + return hdr_output_metadata{.hdmi_metadata_type1 = hdr_metadata_infoframe{.eotf = 0}}; // empty metadata for SDR + + const auto toNits = [](uint32_t value) { return uint16_t(std::round(value)); }; + const auto to16Bit = [](uint32_t value) { return uint16_t(std::round(value * 50000)); }; + + auto colorimetry = settings.primaries; + auto luminances = settings.masteringLuminances.max > 0 ? + settings.masteringLuminances : + SImageDescription::SPCMasteringLuminances{.min = edid.hdrMetadata->desiredContentMinLuminance, .max = edid.hdrMetadata->desiredContentMaxLuminance}; + + Debug::log(TRACE, "ColorManagement primaries {},{} {},{} {},{} {},{}", colorimetry.red.x, colorimetry.red.y, colorimetry.green.x, colorimetry.green.y, colorimetry.blue.x, + colorimetry.blue.y, colorimetry.white.x, colorimetry.white.y); + Debug::log(TRACE, "ColorManagement min {}, max {}, cll {}, fall {}", luminances.min, luminances.max, settings.maxCLL, settings.maxFALL); + return hdr_output_metadata{ + .metadata_type = 0, + .hdmi_metadata_type1 = + hdr_metadata_infoframe{ + .eotf = 2, + .metadata_type = 0, + .display_primaries = + { + {.x = to16Bit(colorimetry.red.x), .y = to16Bit(colorimetry.red.y)}, + {.x = to16Bit(colorimetry.green.x), .y = to16Bit(colorimetry.green.y)}, + {.x = to16Bit(colorimetry.blue.x), .y = to16Bit(colorimetry.blue.y)}, + }, + .white_point = {.x = to16Bit(colorimetry.white.x), .y = to16Bit(colorimetry.white.y)}, + .max_display_mastering_luminance = toNits(luminances.max), + .min_display_mastering_luminance = toNits(luminances.min * 10000), + .max_cll = toNits(settings.maxCLL), + .max_fall = toNits(settings.maxFALL), + }, + }; +} + bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { // apply timelines for explicit sync // save inFD otherwise reset will reset it @@ -1382,6 +1459,26 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { if (inFD >= 0) pMonitor->output->state->setExplicitInFence(inFD); + static auto PWIDE = CConfigValue("experimental:wide_color_gamut"); + if (pMonitor->output->state->state().wideColorGamut != *PWIDE) + Debug::log(TRACE, "Setting wide color gamut {}", *PWIDE ? "on" : "off"); + pMonitor->output->state->setWideColorGamut(*PWIDE); + + static auto PHDR = CConfigValue("experimental:hdr"); + + Debug::log(TRACE, "ColorManagement supportsBT2020 {}, supportsPQ {}", pMonitor->output->parsedEDID.supportsBT2020, pMonitor->output->parsedEDID.hdrMetadata->supportsPQ); + if (pMonitor->output->parsedEDID.supportsBT2020 && pMonitor->output->parsedEDID.hdrMetadata->supportsPQ) { + if (pMonitor->activeWorkspace && pMonitor->activeWorkspace->m_bHasFullscreenWindow && pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) { + const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow(); + const auto SURF = WINDOW->m_pWLSurface->resource(); + if (SURF->colorManagement.valid() && SURF->colorManagement->hasImageDescription()) + pMonitor->output->state->setHDRMetadata(createHDRMetadata(SURF->colorManagement.get()->imageDescription(), pMonitor->output->parsedEDID)); + else + pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); + } else + pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); + } + if (pMonitor->ctmUpdated) { pMonitor->ctmUpdated = false; pMonitor->output->state->setCTM(pMonitor->ctm); diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index f2f2627a..71aa26be 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -79,6 +79,8 @@ void CSurfacePassElement::draw(const CRegion& damage) { DELTALESSTHAN(windowBox.height, data.surface->current.bufferSize.y, 3) /* off by one-or-two */ && (!data.pWindow || (!data.pWindow->m_vRealSize->isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */; + if (data.surface->colorManagement.valid()) + Debug::log(TRACE, "FIXME: rendering surface with color management enabled, should apply necessary transformations"); g_pHyprRenderer->calculateUVForSurface(data.pWindow, data.surface, data.pMonitor->self.lock(), data.mainSurface, windowBox.size(), PROJSIZEUNSCALED, MISALIGNEDFSV1); // check for fractional scale surfaces misaligning the buffer size From c14390785745972903865c824fd324aa708f296a Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 7 Jan 2025 20:27:07 +0100 Subject: [PATCH 0088/1444] config: update animation even if disabled --- src/config/ConfigManager.cpp | 44 +++++++++++++++++------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index bbb3e68f..5839204f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2053,37 +2053,35 @@ std::optional CConfigManager::handleAnimation(const std::string& co if (enabledInt != 0 && enabledInt != 1) return "invalid animation on/off state"; - if (enabledInt) { - int64_t speed = -1; + int64_t speed = -1; - // speed - if (isNumber(ARGS[2], true)) { - speed = std::stof(ARGS[2]); + // speed + if (isNumber(ARGS[2], true)) { + speed = std::stof(ARGS[2]); - if (speed <= 0) { - speed = 1.f; - return "invalid speed"; - } - } else { - speed = 10.f; + if (speed <= 0) { + speed = 1.f; return "invalid speed"; } + } else { + speed = 10.f; + return "invalid speed"; + } - std::string bezierName = ARGS[3]; - m_AnimationTree.setConfigForNode(ANIMNAME, enabledInt, speed, ARGS[3], ARGS[4]); + std::string bezierName = ARGS[3]; + m_AnimationTree.setConfigForNode(ANIMNAME, enabledInt, speed, ARGS[3], ARGS[4]); - if (!g_pAnimationManager->bezierExists(bezierName)) { - const auto PANIMNODE = m_AnimationTree.getConfig(ANIMNAME); - PANIMNODE->internalBezier = "default"; - return "no such bezier"; - } + if (!g_pAnimationManager->bezierExists(bezierName)) { + const auto PANIMNODE = m_AnimationTree.getConfig(ANIMNAME); + PANIMNODE->internalBezier = "default"; + return "no such bezier"; + } - if (ARGS[4] != "") { - auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]); + if (ARGS[4] != "") { + auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]); - if (ERR != "") - return ERR; - } + if (ERR != "") + return ERR; } return {}; From 308b1f3afbb150fa008e3147faeee5d3ba7e6876 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 7 Jan 2025 20:30:44 +0100 Subject: [PATCH 0089/1444] core: minor fixes for animation rewrite --- src/desktop/Workspace.cpp | 2 +- src/managers/AnimationManager.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index cab19254..376288ed 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -628,7 +628,7 @@ void CWorkspace::forceReportSizesToWindows() { if (w->m_pWorkspace != m_pSelf || !w->m_bIsMapped || w->isHidden()) continue; - g_pXWaylandManager->setWindowSize(w, w->m_vRealSize->value(), true); + g_pXWaylandManager->setWindowSize(w, w->m_vRealSize->goal(), true); } } diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 6bfeed83..c1ea1d27 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -147,11 +147,10 @@ static void handleUpdate(CAnimatedVariable& av, bool warp) { const auto PBEZIER = g_pAnimationManager->getBezier(av.getBezierName()); const auto POINTY = PBEZIER->getYForPoint(SPENT); - if constexpr (std::same_as) { + if constexpr (std::same_as) updateColorVariable(av, POINTY, animationsDisabled); - } else { + else updateVariable(av, POINTY, animationsDisabled); - } av.onUpdate(); From 67e1e46f9b6285ea260bc88844f85dec6b7d7d02 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 7 Jan 2025 20:58:49 +0100 Subject: [PATCH 0090/1444] window: fixup fade out animation on silent moves --- src/desktop/Window.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 8175fc57..2bd82ad3 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -413,10 +413,10 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { const auto OLDWORKSPACE = m_pWorkspace; - m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; - m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F); *m_fMovingToWorkspaceAlpha = 0.F; + m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); + m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; m_pWorkspace = pWorkspace; @@ -541,9 +541,9 @@ void CWindow::onMap() { m_fMovingFromWorkspaceAlpha->resetAllCallbacks(); m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); - m_fBorderAngleAnimationProgress->setCallbackOnEnd([&](WP p) { onBorderAngleAnimEnd(p); }, false); m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); + m_fBorderAngleAnimationProgress->setCallbackOnEnd([&](WP p) { onBorderAngleAnimEnd(p); }, false); *m_fBorderAngleAnimationProgress = 1.f; m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); From 75727e7c17f31d97d518df8fdb11ec9d802ca5f3 Mon Sep 17 00:00:00 2001 From: staz Date: Wed, 8 Jan 2025 15:28:47 +0500 Subject: [PATCH 0091/1444] protocols: fix compilation error (#8988) --- src/protocols/FrogColorManagement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocols/FrogColorManagement.cpp b/src/protocols/FrogColorManagement.cpp index 3ea20405..6a921981 100644 --- a/src/protocols/FrogColorManagement.cpp +++ b/src/protocols/FrogColorManagement.cpp @@ -88,7 +88,7 @@ CFrogColorManagementSurface::CFrogColorManagementSurface(SPcolorManagement->m_imageDescription.transferFunction = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB; From 5fa2594659f9f4ad19a1afe456ee34bd1c1907b7 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:28:55 +0000 Subject: [PATCH 0092/1444] renderer: don't access hdrMetadata optional if it has no value (#8987) --- src/render/Renderer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 978384d5..cf25d477 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1466,8 +1466,9 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { static auto PHDR = CConfigValue("experimental:hdr"); - Debug::log(TRACE, "ColorManagement supportsBT2020 {}, supportsPQ {}", pMonitor->output->parsedEDID.supportsBT2020, pMonitor->output->parsedEDID.hdrMetadata->supportsPQ); - if (pMonitor->output->parsedEDID.supportsBT2020 && pMonitor->output->parsedEDID.hdrMetadata->supportsPQ) { + const bool SUPPORTSPQ = pMonitor->output->parsedEDID.hdrMetadata.has_value() ? pMonitor->output->parsedEDID.hdrMetadata->supportsPQ : false; + Debug::log(TRACE, "ColorManagement supportsBT2020 {}, supportsPQ {}", pMonitor->output->parsedEDID.supportsBT2020, SUPPORTSPQ); + if (pMonitor->output->parsedEDID.supportsBT2020 && SUPPORTSPQ) { if (pMonitor->activeWorkspace && pMonitor->activeWorkspace->m_bHasFullscreenWindow && pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) { const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow(); const auto SURF = WINDOW->m_pWLSurface->resource(); From ad64726f5df0fa3cabcd6af9f872d5e8e1f65dbc Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 8 Jan 2025 11:33:41 +0100 Subject: [PATCH 0093/1444] opengl: only allocate offMainFB on demand These are not used by hyprland, only potentially plugins. No need to keep the VRAM allocated all the time --- src/render/OpenGL.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 93ab5fdf..819791e8 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -843,7 +843,6 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb m_RenderData.pCurrentMonData->offloadFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat); m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat); m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat); - m_RenderData.pCurrentMonData->offMainFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->output->state->state().drmFormat); m_RenderData.pCurrentMonData->offloadFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); m_RenderData.pCurrentMonData->mirrorFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); @@ -954,6 +953,12 @@ void CHyprOpenGLImpl::end() { m_RenderData.mainFB = nullptr; m_RenderData.outFB = nullptr; + // if we dropped to offMain, release it now. + // if there is a plugin constantly using it, this might be a bit slow, + // but I havent seen a single plugin yet use these, so it's better to drop a bit of vram. + if (m_RenderData.pCurrentMonData->offMainFB.isAllocated()) + m_RenderData.pCurrentMonData->offMainFB.release(); + // check for gl errors const GLenum ERR = glGetError(); @@ -2881,6 +2886,9 @@ void CHyprOpenGLImpl::restoreMatrix() { } void CHyprOpenGLImpl::bindOffMain() { + if (!m_RenderData.pCurrentMonData->offMainFB.isAllocated()) + m_RenderData.pCurrentMonData->offMainFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y, + m_RenderData.pMonitor->output->state->state().drmFormat); m_RenderData.pCurrentMonData->offMainFB.bind(); clear(CHyprColor(0, 0, 0, 0)); m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offMainFB; From b320bc2dc6e308360936ce4396010359b74558bf Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 8 Jan 2025 12:29:24 +0100 Subject: [PATCH 0094/1444] core: use cpu-buffer hw cursors on nvidia by default --- src/config/ConfigManager.cpp | 6 +++--- src/managers/PointerManager.cpp | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 5839204f..def15f26 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -578,7 +578,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1}); m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{1}); // TODO: remove this. I don't think it does us any good to disable intro. - m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{2}); + m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24}); m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0}); @@ -593,7 +593,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("cursor:sync_gsettings_theme", Hyprlang::INT{1}); m_pConfig->addConfigValue("cursor:hide_on_key_press", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:hide_on_touch", Hyprlang::INT{1}); - m_pConfig->addConfigValue("cursor:use_cpu_buffer", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:use_cpu_buffer", Hyprlang::INT{2}); m_pConfig->addConfigValue("cursor:warp_back_after_non_mouse_input", Hyprlang::INT{0}); m_pConfig->addConfigValue("autogenerated", Hyprlang::INT{0}); @@ -2741,7 +2741,7 @@ bool CConfigManager::shouldUseSoftwareCursors() { switch (*PNOHW) { case 0: return false; case 1: return true; - default: return g_pHyprRenderer->isNvidia(); + default: break; } return true; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index bc166825..85e1c601 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -376,7 +376,9 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->output->cursorPlaneSize(); auto const& cursorSize = currentCursorImage.size; - static auto PDUMB = CConfigValue("cursor:use_cpu_buffer"); + static auto PCPUBUFFER = CConfigValue("cursor:use_cpu_buffer"); + + const bool shouldUseCpuBuffer = *PCPUBUFFER == 1 || (*PCPUBUFFER != 0 && g_pHyprRenderer->isNvidia()); if (maxSize == Vector2D{}) return nullptr; @@ -390,12 +392,12 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->cursorSwapchain || maxSize != state->monitor->cursorSwapchain->currentOptions().size || - *PDUMB != (state->monitor->cursorSwapchain->getAllocator()->type() != Aquamarine::AQ_ALLOCATOR_TYPE_GBM)) { + shouldUseCpuBuffer != (state->monitor->cursorSwapchain->getAllocator()->type() != Aquamarine::AQ_ALLOCATOR_TYPE_GBM)) { - if (!state->monitor->cursorSwapchain || *PDUMB != (state->monitor->cursorSwapchain->getAllocator()->type() != Aquamarine::AQ_ALLOCATOR_TYPE_GBM)) { + if (!state->monitor->cursorSwapchain || shouldUseCpuBuffer != (state->monitor->cursorSwapchain->getAllocator()->type() != Aquamarine::AQ_ALLOCATOR_TYPE_GBM)) { auto allocator = state->monitor->output->getBackend()->preferredAllocator(); - if (*PDUMB) { + if (shouldUseCpuBuffer) { for (const auto& a : state->monitor->output->getBackend()->getAllocators()) { if (a->type() == Aquamarine::AQ_ALLOCATOR_TYPE_DRM_DUMB) { allocator = a; @@ -415,7 +417,7 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_iDRMFD; // We do not set the format (unless shm). If it's unset (DRM_FORMAT_INVALID) then the swapchain will pick for us, // but if it's set, we don't wanna change it. - if (*PDUMB) + if (shouldUseCpuBuffer) options.format = DRM_FORMAT_ARGB8888; if (!state->monitor->cursorSwapchain->reconfigure(options)) { @@ -438,7 +440,7 @@ SP CPointerManager::renderHWCursorBuffer(SPdataCopy(); if (texData.empty()) { From 983bc067dac2e737bc724721c79d87cd81f27501 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 8 Jan 2025 12:34:43 +0100 Subject: [PATCH 0095/1444] opengl: fix crash on null fb stencil op --- src/render/OpenGL.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 819791e8..3a4781e7 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -847,7 +847,6 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb m_RenderData.pCurrentMonData->offloadFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); m_RenderData.pCurrentMonData->mirrorFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); m_RenderData.pCurrentMonData->mirrorSwapFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); - m_RenderData.pCurrentMonData->offMainFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); } if (m_RenderData.pCurrentMonData->monitorMirrorFB.isAllocated() && m_RenderData.pMonitor->mirrors.empty()) @@ -2886,9 +2885,13 @@ void CHyprOpenGLImpl::restoreMatrix() { } void CHyprOpenGLImpl::bindOffMain() { - if (!m_RenderData.pCurrentMonData->offMainFB.isAllocated()) + if (!m_RenderData.pCurrentMonData->offMainFB.isAllocated()) { m_RenderData.pCurrentMonData->offMainFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y, m_RenderData.pMonitor->output->state->state().drmFormat); + + m_RenderData.pCurrentMonData->offMainFB.addStencil(m_RenderData.pCurrentMonData->stencilTex); + } + m_RenderData.pCurrentMonData->offMainFB.bind(); clear(CHyprColor(0, 0, 0, 0)); m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offMainFB; From c9822b08f914da2997e8ef47c8bef8016e5ff313 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Thu, 9 Jan 2025 05:16:34 +0800 Subject: [PATCH 0096/1444] keybinds: add new window destruction dispatchers (#8962) --- src/managers/KeybindManager.cpp | 84 +++++++++++++++++++++++++++++++-- src/managers/KeybindManager.hpp | 6 ++- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index fd4992eb..09f6f928 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -12,6 +12,7 @@ #include "eventLoop/EventLoopManager.hpp" #include "debug/Log.hpp" #include "helpers/varlist/VarList.hpp" +#include "../helpers/signal/Signal.hpp" #include #include @@ -63,8 +64,12 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["exec"] = spawn; m_mDispatchers["execr"] = spawnRaw; - m_mDispatchers["killactive"] = killActive; - m_mDispatchers["closewindow"] = kill; + m_mDispatchers["killactive"] = closeActive; + m_mDispatchers["forcekillactive"] = killActive; + m_mDispatchers["closewindow"] = closeWindow; + m_mDispatchers["killwindow"] = killWindow; + m_mDispatchers["signal"] = signalActive; + m_mDispatchers["signalwindow"] = signalWindow; m_mDispatchers["togglefloating"] = toggleActiveFloating; m_mDispatchers["setfloating"] = setActiveFloating; m_mDispatchers["settiled"] = setActiveTiled; @@ -978,17 +983,23 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo } SDispatchResult CKeybindManager::killActive(std::string args) { + kill(g_pCompositor->m_pLastWindow.lock()->getPID(), SIGKILL); + + return {}; +} + +SDispatchResult CKeybindManager::closeActive(std::string args) { g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow.lock()); return {}; } -SDispatchResult CKeybindManager::kill(std::string args) { +SDispatchResult CKeybindManager::closeWindow(std::string args) { const auto PWINDOW = g_pCompositor->getWindowByRegex(args); if (!PWINDOW) { - Debug::log(ERR, "kill: no window found"); - return {.success = false, .error = "kill: no window found"}; + Debug::log(ERR, "closeWindow: no window found"); + return {.success = false, .error = "closeWindow: no window found"}; } g_pCompositor->closeWindow(PWINDOW); @@ -996,6 +1007,69 @@ SDispatchResult CKeybindManager::kill(std::string args) { return {}; } +SDispatchResult CKeybindManager::killWindow(std::string args) { + const auto PWINDOW = g_pCompositor->getWindowByRegex(args); + + if (!PWINDOW) { + Debug::log(ERR, "killWindow: no window found"); + return {.success = false, .error = "killWindow: no window found"}; + } + + kill(PWINDOW->getPID(), SIGKILL); + + return {}; +} + +SDispatchResult CKeybindManager::signalActive(std::string args) { + if (!std::all_of(args.begin(), args.end(), ::isdigit)) + return {.success = false, .error = "signalActive: signal has to be int"}; + + try { + const auto SIGNALNUM = std::stoi(args); + if (SIGNALNUM < 1 || SIGNALNUM > 31) { + Debug::log(ERR, "signalActive: invalid signal number {}", SIGNALNUM); + return {.success = false, .error = std::format("signalActive: invalid signal number {}", SIGNALNUM)}; + } + kill(g_pCompositor->m_pLastWindow.lock()->getPID(), SIGNALNUM); + } catch (const std::exception& e) { + Debug::log(ERR, "signalActive: invalid signal format \"{}\"", args); + return {.success = false, .error = std::format("signalActive: invalid signal format \"{}\"", args)}; + } + + kill(g_pCompositor->m_pLastWindow.lock()->getPID(), std::stoi(args)); + + return {}; +} + +SDispatchResult CKeybindManager::signalWindow(std::string args) { + const auto WINDOWREGEX = args.substr(0, args.find_first_of(',')); + const auto SIGNAL = args.substr(args.find_first_of(',') + 1); + + const auto PWINDOW = g_pCompositor->getWindowByRegex(WINDOWREGEX); + + if (!PWINDOW) { + Debug::log(ERR, "signalWindow: no window"); + return {.success = false, .error = "signalWindow: no window"}; + } + + if (!std::all_of(SIGNAL.begin(), SIGNAL.end(), ::isdigit)) + return {.success = false, .error = "signalWindow: signal has to be int"}; + + try { + const auto SIGNALNUM = std::stoi(SIGNAL); + if (SIGNALNUM < 1 || SIGNALNUM > 31) { + Debug::log(ERR, "signalWindow: invalid signal number {}", SIGNALNUM); + return {.success = false, .error = std::format("signalWindow: invalid signal number {}", SIGNALNUM)}; + } + kill(PWINDOW->getPID(), SIGNALNUM); + } catch (const std::exception& e) { + Debug::log(ERR, "signalWindow: invalid signal format \"{}\"", SIGNAL); + return {.success = false, .error = std::format("signalWindow: invalid signal format \"{}\"", SIGNAL)}; + } + + return {}; +} + void CKeybindManager::clearKeybinds() { m_vKeybinds.clear(); } diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 02a39df9..76c72187 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -152,8 +152,12 @@ class CKeybindManager { static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace); // -------------- Dispatchers -------------- // + static SDispatchResult closeActive(std::string); static SDispatchResult killActive(std::string); - static SDispatchResult kill(std::string); + static SDispatchResult closeWindow(std::string); + static SDispatchResult killWindow(std::string); + static SDispatchResult signalActive(std::string); + static SDispatchResult signalWindow(std::string); static SDispatchResult spawn(std::string); static SDispatchResult spawnRaw(std::string); static SDispatchResult toggleActiveFloating(std::string); From e66eab7b6a90514251439f661454c536afa3e5c8 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:13:47 +0000 Subject: [PATCH 0097/1444] animationmgr: don't warp based on POINTY value (#9000) --- src/managers/AnimationManager.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index c1ea1d27..f0f6a980 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -40,7 +40,7 @@ CHyprAnimationManager::CHyprAnimationManager() { template void updateVariable(CAnimatedVariable& av, const float POINTY, bool warp = false) { - if (POINTY >= 1.f || warp || av.value() == av.goal()) { + if (warp || av.value() == av.goal()) { av.warp(); return; } @@ -50,7 +50,7 @@ void updateVariable(CAnimatedVariable& av, const float POINTY, bool war } void updateColorVariable(CAnimatedVariable& av, const float POINTY, bool warp) { - if (POINTY >= 1.f || warp || av.value() == av.goal()) { + if (warp || av.value() == av.goal()) { av.warp(); return; } @@ -146,11 +146,12 @@ static void handleUpdate(CAnimatedVariable& av, bool warp) { const auto SPENT = av.getPercent(); const auto PBEZIER = g_pAnimationManager->getBezier(av.getBezierName()); const auto POINTY = PBEZIER->getYForPoint(SPENT); + const bool WARP = animationsDisabled || SPENT >= 1.f; if constexpr (std::same_as) - updateColorVariable(av, POINTY, animationsDisabled); + updateColorVariable(av, POINTY, WARP); else - updateVariable(av, POINTY, animationsDisabled); + updateVariable(av, POINTY, WARP); av.onUpdate(); From 2d1ebadb9b65ef8d57f998031f022b29842b40e4 Mon Sep 17 00:00:00 2001 From: zakk4223 Date: Thu, 9 Jan 2025 14:52:26 -0600 Subject: [PATCH 0098/1444] selectors: add a tag: to for matching window tag(s) by regex (#8985) --- src/Compositor.cpp | 15 +++++++++++++++ src/managers/KeybindManager.hpp | 1 + 2 files changed, 16 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3d159042..79574084 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2401,6 +2401,9 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) { } else if (regexp.starts_with("initialtitle:")) { mode = MODE_INITIAL_TITLE_REGEX; regexCheck = regexp.substr(13); + } else if (regexp.starts_with("tag:")) { + mode = MODE_TAG_REGEX; + regexCheck = regexp.substr(4); } else if (regexp.starts_with("address:")) { mode = MODE_ADDRESS; matchCheck = regexp.substr(8); @@ -2438,6 +2441,18 @@ PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp_) { continue; break; } + case MODE_TAG_REGEX: { + bool tagMatched = false; + for (auto const& t : w->m_tags.getTags()) { + if (RE2::FullMatch(t, regexCheck)) { + tagMatched = true; + break; + } + } + if (!tagMatched) + continue; + break; + } case MODE_ADDRESS: { std::string addr = std::format("0x{:x}", (uintptr_t)w.get()); if (matchCheck != addr) diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 76c72187..d01ec75b 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -49,6 +49,7 @@ enum eFocusWindowMode : uint8_t { MODE_INITIAL_CLASS_REGEX, MODE_TITLE_REGEX, MODE_INITIAL_TITLE_REGEX, + MODE_TAG_REGEX, MODE_ADDRESS, MODE_PID, MODE_ACTIVE_WINDOW From 85aba23cbeea2e651fa1d3f88345f9ba4d4bd4a8 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Fri, 10 Jan 2025 04:54:25 +0800 Subject: [PATCH 0099/1444] ci(clang-format): directly do the clang-format instead of error (#8955) Will suggest a clang-format fix on every MR that violates it. --- .github/workflows/ci.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 22421d18..65bfa1ca 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -126,3 +126,27 @@ jobs: - name: clang-format check run: ninja -C build clang-format-check + + - name: clang-format apply + if: ${{ failure() && github.event_name == 'pull_request' }} + run: ninja -C build clang-format + + - name: Create patch + if: ${{ failure() && github.event_name == 'pull_request' }} + run: | + echo 'Please fix the formatting issues by running [`clang-format`](https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/#code-style), or directly apply this patch:' > clang-format.patch + echo '
' >> clang-format.patch + echo 'clang-format.patch' >> clang-format.patch + echo >> clang-format.patch + echo '```diff' >> clang-format.patch + git diff >> clang-format.patch + echo '```' >> clang-format.patch + echo >> clang-format.patch + echo '
' >> clang-format.patch + + - name: Comment patch + if: ${{ failure() && github.event_name == 'pull_request' }} + uses: mshick/add-pr-comment@v2 + with: + message-path: | + clang-format.patch From 9dc9366fc65ca8b4f18f6554d0b147baceda01f0 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 9 Jan 2025 22:08:16 +0100 Subject: [PATCH 0100/1444] config: fix animations requiring all args fixes #9009 --- src/config/ConfigManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index def15f26..b575a167 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2053,6 +2053,11 @@ std::optional CConfigManager::handleAnimation(const std::string& co if (enabledInt != 0 && enabledInt != 1) return "invalid animation on/off state"; + if (!enabledInt) { + m_AnimationTree.setConfigForNode(ANIMNAME, enabledInt, 1, "default"); + return {}; + } + int64_t speed = -1; // speed From f9c37ca43b14a4564d92b5788c81bf16f7bb719c Mon Sep 17 00:00:00 2001 From: Dardo D Kleiner Date: Thu, 9 Jan 2025 17:38:38 -0500 Subject: [PATCH 0101/1444] windows: honor xdg_toplevel_set_fullscreen output hint (#8965) Co-authored-by: Dardo D Kleiner --- src/desktop/Window.cpp | 21 ++++++++++++++++----- src/desktop/Window.hpp | 4 +++- src/events/Windows.cpp | 25 +++++++++++++++++++++++++ src/protocols/XDGShell.cpp | 8 +++++++- src/protocols/XDGShell.hpp | 7 ++++--- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 2bd82ad3..65e1eb79 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1382,15 +1382,26 @@ void CWindow::activate(bool force) { } void CWindow::onUpdateState() { - std::optional requestsFS = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreen : m_pXWaylandSurface->state.requestsFullscreen; - std::optional requestsMX = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsMaximize : m_pXWaylandSurface->state.requestsMaximize; + std::optional requestsFS = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreen : m_pXWaylandSurface->state.requestsFullscreen; + std::optional requestsID = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreenMonitor : MONITOR_INVALID; + std::optional requestsMX = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsMaximize : m_pXWaylandSurface->state.requestsMaximize; if (requestsFS.has_value() && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) { - bool fs = requestsFS.value(); - if (m_bIsMapped) { - g_pCompositor->changeWindowFullscreenModeClient(m_pSelf.lock(), FSMODE_FULLSCREEN, requestsFS.value()); + if (requestsID.has_value() && (requestsID.value() != MONITOR_INVALID) && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)) { + if (m_bIsMapped) { + const auto monitor = g_pCompositor->getMonitorFromID(requestsID.value()); + g_pCompositor->moveWindowToWorkspaceSafe(m_pSelf.lock(), monitor->activeWorkspace); + g_pCompositor->setActiveMonitor(monitor); + } + + if (!m_bIsMapped) + m_iWantsInitialFullscreenMonitor = requestsID.value(); } + bool fs = requestsFS.value(); + if (m_bIsMapped) + g_pCompositor->changeWindowFullscreenModeClient(m_pSelf.lock(), FSMODE_FULLSCREEN, requestsFS.value()); + if (!m_bIsMapped) m_bWantsInitialFullscreen = fs; } diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 37189a00..d503ac3b 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -57,6 +57,7 @@ enum eSuppressEvents : uint8_t { SUPPRESS_MAXIMIZE = 1 << 1, SUPPRESS_ACTIVATE = 1 << 2, SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3, + SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4, }; class IWindowTransformer; @@ -288,7 +289,8 @@ class CWindow { bool m_bNoInitialFocus = false; // Fullscreen and Maximize - bool m_bWantsInitialFullscreen = false; + bool m_bWantsInitialFullscreen = false; + MONITORID m_iWantsInitialFullscreenMonitor = MONITOR_INVALID; // bitfield eSuppressEvents uint64_t m_eSuppressedEvents = SUPPRESS_NONE; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 8082cdc9..ff69e83f 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -131,6 +131,7 @@ void Events::listener_mapWindow(void* owner, void* data) { std::optional requestedFSState; if (PWINDOW->m_bWantsInitialFullscreen || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->fullscreen)) requestedClientFSMode = FSMODE_FULLSCREEN; + MONITORID requestedFSMonitor = PWINDOW->m_iWantsInitialFullscreenMonitor; for (auto const& r : PWINDOW->m_vMatchedRules) { switch (r->ruleType) { @@ -168,6 +169,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWORKSPACE = PWINDOW->m_pWorkspace; Debug::log(LOG, "Rule monitor, applying to {:mw}", PWINDOW); + requestedFSMonitor = MONITOR_INVALID; } catch (std::exception& e) { Debug::log(ERR, "Rule monitor failed, rule: {} -> {} | err: {}", r->szRule, r->szValue, e.what()); } break; } @@ -186,6 +188,7 @@ void Events::listener_mapWindow(void* owner, void* data) { requestedWorkspace = ""; Debug::log(LOG, "Rule workspace matched by {}, {} applied.", PWINDOW, r->szValue); + requestedFSMonitor = MONITOR_INVALID; break; } case CWindowRule::RULE_FLOAT: { @@ -227,6 +230,8 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE; else if (vars[i] == "activatefocus") PWINDOW->m_eSuppressedEvents |= SUPPRESS_ACTIVATE_FOCUSONLY; + else if (vars[i] == "fullscreenoutput") + PWINDOW->m_eSuppressedEvents |= SUPPRESS_FULLSCREEN_OUTPUT; else Debug::log(ERR, "Error while parsing suppressevent windowrule: unknown event type {}", vars[i]); } @@ -337,10 +342,30 @@ void Events::listener_mapWindow(void* owner, void* data) { PMONITOR = g_pCompositor->m_pLastMonitor.lock(); } + + requestedFSMonitor = MONITOR_INVALID; } else workspaceSilent = false; } + if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT) + requestedFSMonitor = MONITOR_INVALID; + else if (requestedFSMonitor != MONITOR_INVALID) { + if (const auto PM = g_pCompositor->getMonitorFromID(requestedFSMonitor); PM) + PWINDOW->m_pMonitor = PM; + + const auto PMONITORFROMID = PWINDOW->m_pMonitor.lock(); + + if (PWINDOW->m_pMonitor != PMONITOR) { + g_pKeybindManager->m_mDispatchers["focusmonitor"](std::to_string(PWINDOW->monitorID())); + PMONITOR = PMONITORFROMID; + } + PWINDOW->m_pWorkspace = PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace; + PWORKSPACE = PWINDOW->m_pWorkspace; + + Debug::log(LOG, "Requested monitor, applying to {:mw}", PWINDOW); + } + if (PWORKSPACE->m_bDefaultFloating) PWINDOW->m_bIsFloating = true; diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 282aec47..6b7cb3c1 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -5,6 +5,7 @@ #include "../managers/SeatManager.hpp" #include "core/Seat.hpp" #include "core/Compositor.hpp" +#include "protocols/core/Output.hpp" #include #include @@ -191,9 +192,14 @@ CXDGToplevelResource::CXDGToplevelResource(SP resource_, SPsetSetFullscreen([this](CXdgToplevel* r, wl_resource* output) { + if (output) + if (const auto PM = CWLOutputResource::fromResource(output)->monitor; PM) + state.requestsFullscreenMonitor = PM->ID; + state.requestsFullscreen = true; events.stateChanged.emit(); state.requestsFullscreen.reset(); + state.requestsFullscreenMonitor.reset(); }); resource->setUnsetFullscreen([this](CXdgToplevel* r) { @@ -205,7 +211,7 @@ CXDGToplevelResource::CXDGToplevelResource(SP resource_, SPsetSetMinimized([this](CXdgToplevel* r) { state.requestsMinimize = true; events.stateChanged.emit(); - state.requestsFullscreen.reset(); + state.requestsMinimize.reset(); }); resource->setSetParent([this](CXdgToplevel* r, wl_resource* parentR) { diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp index ef847f3b..6eef99bb 100644 --- a/src/protocols/XDGShell.hpp +++ b/src/protocols/XDGShell.hpp @@ -123,9 +123,10 @@ class CXDGToplevelResource { std::string appid; // volatile state: is reset after the stateChanged signal fires - std::optional requestsMaximize; - std::optional requestsFullscreen; - std::optional requestsMinimize; + std::optional requestsMaximize; + std::optional requestsFullscreen; + std::optional requestsFullscreenMonitor; + std::optional requestsMinimize; } state; struct { From 8475a8ef992fd45be41b3217ac0f0dd71235f257 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 10 Jan 2025 14:09:09 +0100 Subject: [PATCH 0102/1444] core: always use goal size to send to clients --- src/desktop/Window.cpp | 2 +- src/managers/KeybindManager.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 65e1eb79..5608daef 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -444,7 +444,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { } // update xwayland coords - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize->value()); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize->goal()); if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && OLDWORKSPACE->getWindows() == 0 && *PCLOSEONLASTSPECIAL) { if (const auto PMONITOR = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 09f6f928..b0bd0e9c 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1891,8 +1891,8 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) { continue; if (!w->m_bRequestsFloat && w->m_bIsFloating != PWORKSPACE->m_bDefaultFloating) { - const auto SAVEDPOS = w->m_vRealPosition->value(); - const auto SAVEDSIZE = w->m_vRealSize->value(); + const auto SAVEDPOS = w->m_vRealPosition->goal(); + const auto SAVEDSIZE = w->m_vRealSize->goal(); w->m_bIsFloating = PWORKSPACE->m_bDefaultFloating; g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(w); From da9252a23e69fc4d34beca73ebcc90b03af0ed2a Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Fri, 10 Jan 2025 23:16:52 +0800 Subject: [PATCH 0103/1444] keybinds: fix nullptr deref in forcekillactive (#9021) --- src/managers/KeybindManager.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index b0bd0e9c..4cd97913 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -983,7 +983,14 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo } SDispatchResult CKeybindManager::killActive(std::string args) { - kill(g_pCompositor->m_pLastWindow.lock()->getPID(), SIGKILL); + const auto PWINDOW = g_pCompositor->m_pLastWindow.lock(); + + if (!PWINDOW) { + Debug::log(ERR, "killActive: no window found"); + return {.success = false, .error = "killActive: no window found"}; + } + + kill(PWINDOW->getPID(), SIGKILL); return {}; } From b5fb6110ab1f75440b4b90d09f95d304d8c2080b Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Fri, 10 Jan 2025 19:09:40 +0100 Subject: [PATCH 0104/1444] core: Add a periodic donation request (#8981) Will fire once in december and july. Disableable with `ecosystem:no_donation:nag` --- src/Compositor.cpp | 9 +- src/config/ConfigManager.cpp | 1 + src/helpers/MiscFunctions.cpp | 27 ------ src/helpers/MiscFunctions.hpp | 1 - src/helpers/fs/FsUtils.cpp | 107 ++++++++++++++++++++++++ src/helpers/fs/FsUtils.hpp | 15 ++++ src/managers/DonationNagManager.cpp | 114 ++++++++++++++++++++++++++ src/managers/DonationNagManager.hpp | 16 ++++ src/managers/VersionKeeperManager.cpp | 92 +++------------------ src/managers/VersionKeeperManager.hpp | 11 +-- 10 files changed, 278 insertions(+), 115 deletions(-) create mode 100644 src/helpers/fs/FsUtils.cpp create mode 100644 src/helpers/fs/FsUtils.hpp create mode 100644 src/managers/DonationNagManager.cpp create mode 100644 src/managers/DonationNagManager.hpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 79574084..fcd15312 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -9,6 +9,7 @@ #include "managers/PointerManager.hpp" #include "managers/SeatManager.hpp" #include "managers/VersionKeeperManager.hpp" +#include "managers/DonationNagManager.hpp" #include "managers/eventLoop/EventLoopManager.hpp" #include #include @@ -25,6 +26,7 @@ #endif #include #include "helpers/varlist/VarList.hpp" +#include "helpers/fs/FsUtils.hpp" #include "protocols/FractionalScale.hpp" #include "protocols/PointerConstraints.hpp" #include "protocols/LayerShell.hpp" @@ -544,6 +546,8 @@ void CCompositor::cleanup() { g_pSeatManager.reset(); g_pHyprCtl.reset(); g_pEventLoopManager.reset(); + g_pVersionKeeperMgr.reset(); + g_pDonationNagManager.reset(); if (m_pAqBackend) m_pAqBackend.reset(); @@ -645,6 +649,9 @@ void CCompositor::initManagers(eManagersInitStage stage) { Debug::log(LOG, "Creating the VersionKeeper!"); g_pVersionKeeperMgr = std::make_unique(); + Debug::log(LOG, "Creating the DonationNag!"); + g_pDonationNagManager = std::make_unique(); + Debug::log(LOG, "Starting XWayland"); g_pXWayland = std::make_unique(g_pCompositor->m_bEnableXwayland); } break; @@ -2645,7 +2652,7 @@ void CCompositor::performUserChecks() { } if (!*PNOCHECKQTUTILS) { - if (!executableExistsInPath("hyprland-dialog")) { + if (!NFsUtils::executableExistsInPath("hyprland-dialog")) { g_pHyprNotificationOverlay->addNotification( "Your system does not have hyprland-qtutils installed. This is a runtime dependency for some dialogs. Consider installing it.", CHyprColor{}, 15000, ICON_WARNING); } diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index b575a167..3f8862ee 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -621,6 +621,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("render:ctm_animation", Hyprlang::INT{2}); m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0}); + m_pConfig->addConfigValue("ecosystem:no_donation_nag", Hyprlang::INT{0}); m_pConfig->addConfigValue("experimental:wide_color_gamut", Hyprlang::INT{0}); m_pConfig->addConfigValue("experimental:hdr", Hyprlang::INT{0}); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index e970b781..08a1106a 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -911,30 +911,3 @@ float stringToPercentage(const std::string& VALUE, const float REL) { else return std::stof(VALUE); } - -bool executableExistsInPath(const std::string& exe) { - if (!getenv("PATH")) - return false; - - static CVarList paths(getenv("PATH"), 0, ':', true); - - for (auto& p : paths) { - std::string path = p + std::string{"/"} + exe; - std::error_code ec; - if (!std::filesystem::exists(path, ec) || ec) - continue; - - if (!std::filesystem::is_regular_file(path, ec) || ec) - continue; - - auto stat = std::filesystem::status(path, ec); - if (ec) - continue; - - auto perms = stat.permissions(); - - return std::filesystem::perms::none != (perms & std::filesystem::perms::others_exec); - } - - return false; -} diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index b179b3d6..64802279 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -40,7 +40,6 @@ bool envEnabled(const std::string& env); int allocateSHMFile(size_t len); bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr); float stringToPercentage(const std::string& VALUE, const float REL); -bool executableExistsInPath(const std::string& exe); template [[deprecated("use std::format instead")]] std::string getFormat(std::format_string fmt, Args&&... args) { diff --git a/src/helpers/fs/FsUtils.cpp b/src/helpers/fs/FsUtils.cpp new file mode 100644 index 00000000..0bc2e685 --- /dev/null +++ b/src/helpers/fs/FsUtils.cpp @@ -0,0 +1,107 @@ +#include "FsUtils.hpp" +#include "../../debug/Log.hpp" + +#include +#include + +#include +#include +using namespace Hyprutils::String; + +std::optional NFsUtils::getDataHome() { + const auto DATA_HOME = getenv("XDG_DATA_HOME"); + + std::string dataRoot; + + if (!DATA_HOME) { + const auto HOME = getenv("HOME"); + + if (!HOME) { + Debug::log(ERR, "FsUtils::getDataHome: can't get data home: no $HOME or $XDG_DATA_HOME"); + return std::nullopt; + } + + dataRoot = HOME + std::string{"/.local/share/"}; + } else + dataRoot = DATA_HOME + std::string{"/"}; + + std::error_code ec; + if (!std::filesystem::exists(dataRoot, ec) || ec) { + Debug::log(ERR, "FsUtils::getDataHome: can't get data home: inaccessible / missing"); + return std::nullopt; + } + + dataRoot += "hyprland/"; + + if (!std::filesystem::exists(dataRoot, ec) || ec) { + Debug::log(LOG, "FsUtils::getDataHome: no hyprland data home, creating."); + std::filesystem::create_directory(dataRoot, ec); + if (ec) { + Debug::log(ERR, "FsUtils::getDataHome: can't create new data home for hyprland"); + return std::nullopt; + } + std::filesystem::permissions(dataRoot, std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | std::filesystem::perms::owner_exec, ec); + if (ec) + Debug::log(WARN, "FsUtils::getDataHome: couldn't set perms on hyprland data store. Proceeding anyways."); + } + + if (!std::filesystem::exists(dataRoot, ec) || ec) { + Debug::log(ERR, "FsUtils::getDataHome: no hyprland data home, failed to create."); + return std::nullopt; + } + + return dataRoot; +} + +std::optional NFsUtils::readFileAsString(const std::string& path) { + std::error_code ec; + + if (!std::filesystem::exists(path, ec) || ec) + return std::nullopt; + + std::ifstream file(path); + if (!file.good()) + return std::nullopt; + + return trim(std::string((std::istreambuf_iterator(file)), (std::istreambuf_iterator()))); +} + +bool NFsUtils::writeToFile(const std::string& path, const std::string& content) { + std::ofstream of(path, std::ios::trunc); + if (!of.good()) { + Debug::log(ERR, "CVersionKeeperManager: couldn't open an ofstream for writing the version file."); + return false; + } + + of << content; + of.close(); + + return true; +} + +bool NFsUtils::executableExistsInPath(const std::string& exe) { + if (!getenv("PATH")) + return false; + + static CVarList paths(getenv("PATH"), 0, ':', true); + + for (auto& p : paths) { + std::string path = p + std::string{"/"} + exe; + std::error_code ec; + if (!std::filesystem::exists(path, ec) || ec) + continue; + + if (!std::filesystem::is_regular_file(path, ec) || ec) + continue; + + auto stat = std::filesystem::status(path, ec); + if (ec) + continue; + + auto perms = stat.permissions(); + + return std::filesystem::perms::none != (perms & std::filesystem::perms::others_exec); + } + + return false; +} diff --git a/src/helpers/fs/FsUtils.hpp b/src/helpers/fs/FsUtils.hpp new file mode 100644 index 00000000..bc3b3bf1 --- /dev/null +++ b/src/helpers/fs/FsUtils.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include + +namespace NFsUtils { + // Returns the path to the hyprland directory in data home. + std::optional getDataHome(); + + std::optional readFileAsString(const std::string& path); + + // overwrites the file if exists + bool writeToFile(const std::string& path, const std::string& content); + + bool executableExistsInPath(const std::string& exe); +}; diff --git a/src/managers/DonationNagManager.cpp b/src/managers/DonationNagManager.cpp new file mode 100644 index 00000000..d7eab9ae --- /dev/null +++ b/src/managers/DonationNagManager.cpp @@ -0,0 +1,114 @@ +#include "DonationNagManager.hpp" +#include "../debug/Log.hpp" +#include "VersionKeeperManager.hpp" +#include "eventLoop/EventLoopManager.hpp" +#include "../config/ConfigValue.hpp" + +#include +#include + +#include "../helpers/fs/FsUtils.hpp" + +#include +using namespace Hyprutils::OS; + +constexpr const char* LAST_NAG_FILE_NAME = "lastNag"; +constexpr uint64_t DAY_IN_SECONDS = 3600ULL * 24; +constexpr uint64_t MONTH_IN_SECONDS = DAY_IN_SECONDS * 30; + +struct SNagDatePoint { + // Counted from 1, as in Jan 1st is 1, 1 + // No month-boundaries because I am lazy + uint8_t month = 0, dayStart = 0, dayEnd = 0; +}; + +// clang-format off +const std::vector NAG_DATE_POINTS = { + SNagDatePoint { + 7, 20, 31, + }, + SNagDatePoint { + 12, 1, 28 + }, +}; +// clang-format on + +CDonationNagManager::CDonationNagManager() { + static auto PNONAG = CConfigValue("ecosystem:no_donation_nag"); + + if (g_pVersionKeeperMgr->fired() || *PNONAG) + return; + + const auto DATAROOT = NFsUtils::getDataHome(); + + if (!DATAROOT) + return; + + const auto EPOCH = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + + const auto LASTNAGSTR = NFsUtils::readFileAsString(*DATAROOT + "/" + LAST_NAG_FILE_NAME); + + if (!LASTNAGSTR) { + const auto EPOCHSTR = std::format("{}", EPOCH); + NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR); + return; + } + + uint64_t LAST_EPOCH = 0; + + try { + LAST_EPOCH = std::stoull(*LASTNAGSTR); + } catch (std::exception& e) { + Debug::log(ERR, "DonationNag: Last epoch invalid? Failed to parse \"{}\". Setting to today.", *LASTNAGSTR); + const auto EPOCHSTR = std::format("{}", EPOCH); + NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR); + return; + } + + // don't nag if the last nag was less than a month ago. This is + // mostly for first-time nags, as other nags happen in specific time frames shorter than a month + if (EPOCH - LAST_EPOCH < MONTH_IN_SECONDS) { + Debug::log(LOG, "DonationNag: last nag was {} days ago, too early for a nag.", (int)std::round((EPOCH - LAST_EPOCH) / (double)MONTH_IN_SECONDS)); + return; + } + + if (!NFsUtils::executableExistsInPath("hyprland-donate-screen")) { + Debug::log(ERR, "DonationNag: executable doesn't exist, skipping."); + return; + } + + auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + auto local = *localtime(&tt); + + const auto MONTH = local.tm_mon + 1; + const auto DAY = local.tm_mday; + + for (const auto& nagPoint : NAG_DATE_POINTS) { + if (MONTH != nagPoint.month) + continue; + + if (DAY < nagPoint.dayStart || DAY > nagPoint.dayEnd) + continue; + + Debug::log(LOG, "DonationNag: hit nag month {} days {}-{}, it's {} today, nagging", MONTH, nagPoint.dayStart, nagPoint.dayEnd, DAY); + + m_bFired = true; + + const auto EPOCHSTR = std::format("{}", EPOCH); + NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR); + + g_pEventLoopManager->doLater([] { + CProcess proc("hyprland-donate-screen", {}); + proc.runAsync(); + }); + + break; + } + + if (!m_bFired) + Debug::log(LOG, "DonationNag: didn't hit any nagging periods"); +} + +bool CDonationNagManager::fired() { + return m_bFired; +} \ No newline at end of file diff --git a/src/managers/DonationNagManager.hpp b/src/managers/DonationNagManager.hpp new file mode 100644 index 00000000..e296d815 --- /dev/null +++ b/src/managers/DonationNagManager.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +class CDonationNagManager { + public: + CDonationNagManager(); + + // whether the donation nag was shown this boot. + bool fired(); + + private: + bool m_bFired = false; +}; + +inline std::unique_ptr g_pDonationNagManager; \ No newline at end of file diff --git a/src/managers/VersionKeeperManager.cpp b/src/managers/VersionKeeperManager.cpp index 1ef1040e..cc03a7b9 100644 --- a/src/managers/VersionKeeperManager.cpp +++ b/src/managers/VersionKeeperManager.cpp @@ -6,6 +6,7 @@ #include "../helpers/varlist/VarList.hpp" #include "eventLoop/EventLoopManager.hpp" #include "../config/ConfigValue.hpp" +#include "../helpers/fs/FsUtils.hpp" #include #include @@ -20,12 +21,12 @@ constexpr const char* VERSION_FILE_NAME = "lastVersion"; CVersionKeeperManager::CVersionKeeperManager() { static auto PNONOTIFY = CConfigValue("ecosystem:no_update_news"); - const auto DATAROOT = getDataHome(); + const auto DATAROOT = NFsUtils::getDataHome(); if (!DATAROOT) return; - const auto LASTVER = getDataLastVersion(*DATAROOT); + const auto LASTVER = NFsUtils::readFileAsString(*DATAROOT + "/" + VERSION_FILE_NAME); if (!LASTVER) return; @@ -35,101 +36,26 @@ CVersionKeeperManager::CVersionKeeperManager() { return; } - writeVersionToVersionFile(*DATAROOT); + NFsUtils::writeToFile(*DATAROOT + "/" + VERSION_FILE_NAME, HYPRLAND_VERSION); if (*PNONOTIFY) { Debug::log(LOG, "CVersionKeeperManager: updated, but update news is disabled in the config :("); return; } - if (!executableExistsInPath("hyprland-update-screen")) { + if (!NFsUtils::executableExistsInPath("hyprland-update-screen")) { Debug::log(ERR, "CVersionKeeperManager: hyprland-update-screen doesn't seem to exist, skipping notif about update..."); return; } + m_bFired = true; + g_pEventLoopManager->doLater([]() { CProcess proc("hyprland-update-screen", {"--new-version", HYPRLAND_VERSION}); proc.runAsync(); }); } -std::optional CVersionKeeperManager::getDataHome() { - const auto DATA_HOME = getenv("XDG_DATA_HOME"); - - std::string dataRoot; - - if (!DATA_HOME) { - const auto HOME = getenv("HOME"); - - if (!HOME) { - Debug::log(ERR, "CVersionKeeperManager: can't get data home: no $HOME or $XDG_DATA_HOME"); - return std::nullopt; - } - - dataRoot = HOME + std::string{"/.local/share/"}; - } else - dataRoot = DATA_HOME + std::string{"/"}; - - std::error_code ec; - if (!std::filesystem::exists(dataRoot, ec) || ec) { - Debug::log(ERR, "CVersionKeeperManager: can't get data home: inaccessible / missing"); - return std::nullopt; - } - - dataRoot += "hyprland/"; - - if (!std::filesystem::exists(dataRoot, ec) || ec) { - Debug::log(LOG, "CVersionKeeperManager: no hyprland data home, creating."); - std::filesystem::create_directory(dataRoot, ec); - if (ec) { - Debug::log(ERR, "CVersionKeeperManager: can't create new data home for hyprland"); - return std::nullopt; - } - std::filesystem::permissions(dataRoot, std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | std::filesystem::perms::owner_exec, ec); - if (ec) - Debug::log(WARN, "CVersionKeeperManager: couldn't set perms on hyprland data store. Proceeding anyways."); - } - - if (!std::filesystem::exists(dataRoot, ec) || ec) { - Debug::log(ERR, "CVersionKeeperManager: no hyprland data home, failed to create."); - return std::nullopt; - } - - return dataRoot; -} - -std::optional CVersionKeeperManager::getDataLastVersion(const std::string& dataRoot) { - std::error_code ec; - std::string lastVerFile = dataRoot + "/" + VERSION_FILE_NAME; - - if (!std::filesystem::exists(lastVerFile, ec) || ec) { - Debug::log(LOG, "CVersionKeeperManager: no hyprland last version file, creating."); - writeVersionToVersionFile(dataRoot); - - return "0.0.0"; - } - - std::ifstream file(lastVerFile); - if (!file.good()) { - Debug::log(ERR, "CVersionKeeperManager: couldn't open an ifstream for reading the version file."); - return std::nullopt; - } - - return trim(std::string((std::istreambuf_iterator(file)), (std::istreambuf_iterator()))); -} - -void CVersionKeeperManager::writeVersionToVersionFile(const std::string& dataRoot) { - std::string lastVerFile = dataRoot + "/" + VERSION_FILE_NAME; - std::ofstream of(lastVerFile, std::ios::trunc); - if (!of.good()) { - Debug::log(ERR, "CVersionKeeperManager: couldn't open an ofstream for writing the version file."); - return; - } - - of << HYPRLAND_VERSION; - of.close(); -} - bool CVersionKeeperManager::isVersionOlderThanRunning(const std::string& ver) { const CVarList verStrings(ver, 0, '.', true); @@ -151,3 +77,7 @@ bool CVersionKeeperManager::isVersionOlderThanRunning(const std::string& ver) { return true; return false; } + +bool CVersionKeeperManager::fired() { + return m_bFired; +} diff --git a/src/managers/VersionKeeperManager.hpp b/src/managers/VersionKeeperManager.hpp index f0dc05ce..eb404d88 100644 --- a/src/managers/VersionKeeperManager.hpp +++ b/src/managers/VersionKeeperManager.hpp @@ -1,17 +1,18 @@ #pragma once #include -#include class CVersionKeeperManager { public: CVersionKeeperManager(); + // whether the update screen was shown this boot. + bool fired(); + private: - std::optional getDataHome(); - std::optional getDataLastVersion(const std::string& dataRoot); - void writeVersionToVersionFile(const std::string& dataRoot); - bool isVersionOlderThanRunning(const std::string& ver); + bool isVersionOlderThanRunning(const std::string& ver); + + bool m_bFired = false; }; inline std::unique_ptr g_pVersionKeeperMgr; \ No newline at end of file From a8b568c6c451cdce3c8d40ae010247be3f25728b Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:42:26 +0300 Subject: [PATCH 0105/1444] core: Add render:allow_early_buffer_release to make buffer release configurable (#9019) --- src/config/ConfigDescriptions.hpp | 6 ++++++ src/config/ConfigManager.cpp | 1 + src/protocols/core/Compositor.cpp | 15 ++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 686b996a..483f1f1f 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1313,6 +1313,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{2, 0, 2}, }, + SConfigOptionDescription{ + .value = "render:allow_early_buffer_release", + .description = "Allow early buffer release event. Fixes stuttering and missing frames for some apps. May cause graphical glitches and memory leaks in others", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, /* * cursor: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 3f8862ee..299dfbc3 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -619,6 +619,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("render:expand_undersized_textures", Hyprlang::INT{1}); m_pConfig->addConfigValue("render:xp_mode", Hyprlang::INT{0}); m_pConfig->addConfigValue("render:ctm_animation", Hyprlang::INT{2}); + m_pConfig->addConfigValue("render:allow_early_buffer_release", Hyprlang::INT{1}); m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0}); m_pConfig->addConfigValue("ecosystem:no_donation_nag", Hyprlang::INT{0}); diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 6213f987..e1d6ef7d 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -11,6 +11,7 @@ #include "../PresentationTime.hpp" #include "../DRMSyncobj.hpp" #include "../../render/Renderer.hpp" +#include "config/ConfigValue.hpp" #include class CDefaultSurfaceRole : public ISurfaceRole { @@ -423,12 +424,14 @@ void CWLSurfaceResource::unlockPendingState() { } void CWLSurfaceResource::commitPendingState() { - auto const previousBuffer = current.buffer; - current = pending; + static auto PDROP = CConfigValue("render:allow_early_buffer_release"); + auto const previousBuffer = current.buffer; + current = pending; pending.damage.clear(); pending.bufferDamage.clear(); pending.newBuffer = false; - dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore + if (!*PDROP) + dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore events.roleCommit.emit(); @@ -450,8 +453,10 @@ void CWLSurfaceResource::commitPendingState() { // release the buffer if it's synchronous as update() has done everything thats needed // so we can let the app know we're done. // Some clients aren't ready to receive a release this early. Should be fine to release it on the next commitPendingState. - // if (current.buffer->buffer->isSynchronous()) - // dropCurrentBuffer(); + if (current.buffer->buffer->isSynchronous() && *PDROP) { + dropCurrentBuffer(); + dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore + } } // TODO: we should _accumulate_ and not replace above if sync From cef09fbfe6624d2133d81be863bd48bcfc5939d3 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 10 Jan 2025 21:55:19 +0100 Subject: [PATCH 0106/1444] animation: avoid crashes in ::tick() on mutations mutating the active variables is valid during a tick, we can't let it crash --- src/managers/AnimationManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index f0f6a980..ea74ffd2 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -215,7 +215,11 @@ void CHyprAnimationManager::tick() { lastTick = std::chrono::high_resolution_clock::now(); static auto PANIMENABLED = CConfigValue("animations:enabled"); - for (auto const& pav : m_vActiveAnimatedVariables) { + + // We need to do this because it's perfectly valid to add/change a var during this (via callbacks) + // FIXME: instead of doing this, make a fn to defer adding until tick is done and not in progress anymore. + const auto PAVS = m_vActiveAnimatedVariables; + for (auto const& pav : PAVS) { const auto PAV = pav.lock(); if (!PAV) continue; From 3b85690aa6d9c14bb926692e25cc4480b85200ab Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Sat, 11 Jan 2025 23:58:05 +0800 Subject: [PATCH 0107/1444] config: add exec(-onec) with rules and execr(-once) (#8953) --- src/config/ConfigManager.cpp | 51 +++++++++++++++++++++++++++++++++--- src/config/ConfigManager.hpp | 10 ++++++- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 299dfbc3..60723220 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -130,6 +130,18 @@ static void configHandleGapDestroy(void** data) { delete reinterpret_cast(*data); } +static Hyprlang::CParseResult handleExec(const char* c, const char* v) { + const std::string VALUE = v; + const std::string COMMAND = c; + + const auto RESULT = g_pConfigManager->handleExec(COMMAND, VALUE); + + Hyprlang::CParseResult result; + if (RESULT.has_value()) + result.setError(RESULT.value().c_str()); + return result; +} + static Hyprlang::CParseResult handleRawExec(const char* c, const char* v) { const std::string VALUE = v; const std::string COMMAND = c; @@ -154,6 +166,18 @@ static Hyprlang::CParseResult handleExecOnce(const char* c, const char* v) { return result; } +static Hyprlang::CParseResult handleExecRawOnce(const char* c, const char* v) { + const std::string VALUE = v; + const std::string COMMAND = c; + + const auto RESULT = g_pConfigManager->handleExecRawOnce(COMMAND, VALUE); + + Hyprlang::CParseResult result; + if (RESULT.has_value()) + result.setError(RESULT.value().c_str()); + return result; +} + static Hyprlang::CParseResult handleExecShutdown(const char* c, const char* v) { const std::string VALUE = v; const std::string COMMAND = c; @@ -666,8 +690,10 @@ CConfigManager::CConfigManager() { m_pConfig->addSpecialConfigValue("device", "active_area_size", Hyprlang::VEC2{0, 0}); // only for tablets // keywords - m_pConfig->registerHandler(&::handleRawExec, "exec", {false}); + m_pConfig->registerHandler(&::handleExec, "exec", {false}); + m_pConfig->registerHandler(&::handleRawExec, "execr", {false}); m_pConfig->registerHandler(&::handleExecOnce, "exec-once", {false}); + m_pConfig->registerHandler(&::handleExecRawOnce, "execr-once", {false}); m_pConfig->registerHandler(&::handleExecShutdown, "exec-shutdown", {false}); m_pConfig->registerHandler(&::handleMonitor, "monitor", {false}); m_pConfig->registerHandler(&::handleBind, "bind", {true}); @@ -1441,7 +1467,7 @@ void CConfigManager::dispatchExecOnce() { isLaunchingExecOnce = true; for (auto const& c : firstExecRequests) { - handleRawExec("", c); + c.withRules ? handleExec("", c.exec) : handleRawExec("", c.exec); } firstExecRequests.clear(); // free some kb of memory :P @@ -1744,7 +1770,17 @@ std::string CConfigManager::getDefaultWorkspaceFor(const std::string& name) { std::optional CConfigManager::handleRawExec(const std::string& command, const std::string& args) { if (isFirstLaunch) { - firstExecRequests.push_back(args); + firstExecRequests.push_back({args, false}); + return {}; + } + + g_pKeybindManager->spawnRaw(args); + return {}; +} + +std::optional CConfigManager::handleExec(const std::string& command, const std::string& args) { + if (isFirstLaunch) { + firstExecRequests.push_back({args, true}); return {}; } @@ -1754,7 +1790,14 @@ std::optional CConfigManager::handleRawExec(const std::string& comm std::optional CConfigManager::handleExecOnce(const std::string& command, const std::string& args) { if (isFirstLaunch) - firstExecRequests.push_back(args); + firstExecRequests.push_back({args, true}); + + return {}; +} + +std::optional CConfigManager::handleExecRawOnce(const std::string& command, const std::string& args) { + if (isFirstLaunch) + firstExecRequests.push_back({args, false}); return {}; } diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 53772401..a27ee7ab 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -132,6 +132,11 @@ struct SConfigOptionDescription { std::variant data; }; +struct SFirstExecRequest { + std::string exec = ""; + bool withRules = false; +}; + class CConfigManager { public: CConfigManager(); @@ -196,7 +201,9 @@ class CConfigManager { // keywords std::optional handleRawExec(const std::string&, const std::string&); + std::optional handleExec(const std::string&, const std::string&); std::optional handleExecOnce(const std::string&, const std::string&); + std::optional handleExecRawOnce(const std::string&, const std::string&); std::optional handleExecShutdown(const std::string&, const std::string&); std::optional handleMonitor(const std::string&, const std::string&); std::optional handleBind(const std::string&, const std::string&); @@ -280,7 +287,8 @@ class CConfigManager { bool firstExecDispatched = false; bool m_bManualCrashInitiated = false; - std::vector firstExecRequests; + + std::vector firstExecRequests; // bool is for if with rules std::vector finalExecRequests; std::vector> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins From 15dc024a398d35957ccfb50ddade5f456a1646b5 Mon Sep 17 00:00:00 2001 From: Alexander <51529891+Truenya@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:05:53 +0300 Subject: [PATCH 0108/1444] keybinds: fix previous_per_monitor logic (#9010) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Крылов Александр --- src/desktop/Workspace.cpp | 10 ++-------- src/desktop/Workspace.hpp | 22 +++++++++++----------- src/helpers/MiscFunctions.cpp | 2 +- src/helpers/Monitor.cpp | 24 ++++++++++++++++++++++++ src/helpers/Monitor.hpp | 15 +++++++++++---- src/managers/KeybindManager.cpp | 33 ++++++++++++++------------------- 6 files changed, 63 insertions(+), 43 deletions(-) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 376288ed..07c1a435 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -52,10 +52,7 @@ void CWorkspace::init(PHLWORKSPACE self) { EMIT_HOOK_EVENT("createWorkspace", this); } -SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName(bool perMonitor) const { - if (perMonitor) - return m_sPrevWorkspacePerMonitor; - +SWorkspaceIDName CWorkspace::getPrevWorkspaceIDName() const { return m_sPrevWorkspace; } @@ -216,10 +213,7 @@ void CWorkspace::rememberPrevWorkspace(const PHLWORKSPACE& prev) { m_sPrevWorkspace.id = prev->m_iID; m_sPrevWorkspace.name = prev->m_szName; - if (prev->m_pMonitor == m_pMonitor) { - m_sPrevWorkspacePerMonitor.id = prev->m_iID; - m_sPrevWorkspacePerMonitor.name = prev->m_szName; - } + prev->m_pMonitor->addPrevWorkspaceID(prev->m_iID); } std::string CWorkspace::getConfigName() { diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index f86dd656..e9859d4f 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -24,17 +24,14 @@ class CWorkspace { // Workspaces ID-based have IDs > 0 // and workspaces name-based have IDs starting with -1337 - WORKSPACEID m_iID = WORKSPACE_INVALID; - std::string m_szName = ""; - PHLMONITORREF m_pMonitor; - // Previous workspace ID and name is stored during a workspace change, allowing travel - // to the previous workspace. - SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor; + WORKSPACEID m_iID = WORKSPACE_INVALID; + std::string m_szName = ""; + PHLMONITORREF m_pMonitor; - bool m_bHasFullscreenWindow = false; - eFullscreenMode m_efFullscreenMode = FSMODE_NONE; + bool m_bHasFullscreenWindow = false; + eFullscreenMode m_efFullscreenMode = FSMODE_NONE; - wl_array m_wlrCoordinateArr; + wl_array m_wlrCoordinateArr; // for animations PHLANIMVAR m_vRenderOffset; @@ -72,7 +69,7 @@ class CWorkspace { std::string getConfigName(); bool matchesStaticSelector(const std::string& selector); void markInert(); - SWorkspaceIDName getPrevWorkspaceIDName(bool perMonitor) const; + SWorkspaceIDName getPrevWorkspaceIDName() const; void updateWindowDecos(); void updateWindowData(); int getWindows(std::optional onlyTiled = {}, std::optional onlyVisible = {}); @@ -88,7 +85,10 @@ class CWorkspace { void updateWindows(); private: - void init(PHLWORKSPACE self); + void init(PHLWORKSPACE self); + // Previous workspace ID and name is stored during a workspace change, allowing travel + // to the previous workspace. + SWorkspaceIDName m_sPrevWorkspace; SP m_pFocusedWindowHook; bool m_bInert = true; diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 08a1106a..0fa73e45 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -258,7 +258,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) { if (!valid(PWORKSPACE)) return {WORKSPACE_INVALID}; - const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->m_sPrevWorkspace.id); + const auto PLASTWORKSPACE = g_pCompositor->getWorkspaceByID(PWORKSPACE->getPrevWorkspaceIDName().id); if (!PLASTWORKSPACE) return {WORKSPACE_INVALID}; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index e833e661..cf62bc54 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1,5 +1,6 @@ #include "Monitor.hpp" #include "MiscFunctions.hpp" +#include "macros.hpp" #include "math/Math.hpp" #include "sync/SyncReleaser.hpp" #include "../Compositor.hpp" @@ -1169,6 +1170,29 @@ void CMonitor::moveTo(const Vector2D& pos) { vecPosition = pos; } +SWorkspaceIDName CMonitor::getPrevWorkspaceIDName(const WORKSPACEID id) { + while (!prevWorkSpaces.empty()) { + const int PREVID = prevWorkSpaces.top(); + prevWorkSpaces.pop(); + if (PREVID == id) // skip same workspace + continue; + + // recheck if previous workspace's was moved to another monitor + const auto ws = g_pCompositor->getWorkspaceByID(PREVID); + if (ws && ws->monitorID() == ID) + return {.id = PREVID, .name = ws->m_szName}; + } + + return {.id = WORKSPACE_INVALID}; +} + +void CMonitor::addPrevWorkspaceID(const WORKSPACEID id) { + if (!prevWorkSpaces.empty() && prevWorkSpaces.top() == id) + return; + + prevWorkSpaces.emplace(id); +} + Vector2D CMonitor::middle() { return vecPosition + vecSize / 2.f; } diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index b075df81..8085c460 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -1,7 +1,9 @@ #pragma once #include "../defines.hpp" +#include #include +#include "SharedDefs.hpp" #include "WLClasses.hpp" #include #include @@ -196,11 +198,16 @@ class CMonitor { return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName; } - private: - void setupDefaultWS(const SMonitorRule&); - WORKSPACEID findAvailableDefaultWS(); + // workspace previous per monitor functionality + SWorkspaceIDName getPrevWorkspaceIDName(const WORKSPACEID id); + void addPrevWorkspaceID(const WORKSPACEID id); - bool doneScheduled = false; + private: + void setupDefaultWS(const SMonitorRule&); + WORKSPACEID findAvailableDefaultWS(); + + bool doneScheduled = false; + std::stack prevWorkSpaces; struct { CHyprSignalListener frame; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 4cd97913..720d27f6 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1176,27 +1176,24 @@ SDispatchResult CKeybindManager::toggleActivePseudo(std::string args) { return {}; } -static SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE) { +static SWorkspaceIDName getWorkspaceToChangeFromArgs(std::string args, PHLWORKSPACE PCURRENTWORKSPACE, PHLMONITORREF PMONITOR) { if (!args.starts_with("previous")) { return getWorkspaceIDNameFromString(args); } const bool PER_MON = args.contains("_per_monitor"); - const SWorkspaceIDName PPREVWS = PCURRENTWORKSPACE->getPrevWorkspaceIDName(PER_MON); + const SWorkspaceIDName PPREVWS = PER_MON ? PMONITOR->getPrevWorkspaceIDName(PCURRENTWORKSPACE->m_iID) : PCURRENTWORKSPACE->getPrevWorkspaceIDName(); // Do nothing if there's no previous workspace, otherwise switch to it. - if (PPREVWS.id == -1) { + if (PPREVWS.id == -1 || PPREVWS.id == PCURRENTWORKSPACE->m_iID) { Debug::log(LOG, "No previous workspace to change to"); - return {WORKSPACE_NOT_CHANGED, ""}; + return {.id = WORKSPACE_NOT_CHANGED}; } - const auto ID = PCURRENTWORKSPACE->m_iID; if (const auto PWORKSPACETOCHANGETO = g_pCompositor->getWorkspaceByID(PPREVWS.id); PWORKSPACETOCHANGETO) { - if (PER_MON && PCURRENTWORKSPACE->m_pMonitor != PWORKSPACETOCHANGETO->m_pMonitor) - return {WORKSPACE_NOT_CHANGED, ""}; - return {ID, PWORKSPACETOCHANGETO->m_szName}; + return {.id = PWORKSPACETOCHANGETO->m_iID, .name = PWORKSPACETOCHANGETO->m_szName}; } - return {ID, PPREVWS.name.empty() ? std::to_string(PPREVWS.id) : PPREVWS.name}; + return {.id = PPREVWS.id, .name = PPREVWS.name.empty() ? std::to_string(PPREVWS.id) : PPREVWS.name}; } SDispatchResult CKeybindManager::changeworkspace(std::string args) { @@ -1214,7 +1211,7 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) { const auto PCURRENTWORKSPACE = PMONITOR->activeWorkspace; const bool EXPLICITPREVIOUS = args.contains("previous"); - const auto& [workspaceToChangeTo, workspaceName] = getWorkspaceToChangeFromArgs(args, PCURRENTWORKSPACE); + const auto& [workspaceToChangeTo, workspaceName] = getWorkspaceToChangeFromArgs(args, PCURRENTWORKSPACE, PMONITOR); if (workspaceToChangeTo == WORKSPACE_INVALID) { Debug::log(ERR, "Error in changeworkspace, invalid value"); return {.success = false, .error = "Error in changeworkspace, invalid value"}; @@ -1223,19 +1220,19 @@ SDispatchResult CKeybindManager::changeworkspace(std::string args) { if (workspaceToChangeTo == WORKSPACE_NOT_CHANGED) return {}; - const auto PREVWS = PCURRENTWORKSPACE->getPrevWorkspaceIDName(args.contains("_per_monitor")); + const SWorkspaceIDName PPREVWS = args.contains("_per_monitor") ? PMONITOR->getPrevWorkspaceIDName(PCURRENTWORKSPACE->m_iID) : PCURRENTWORKSPACE->getPrevWorkspaceIDName(); - const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID; - if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PREVWS.id == -1)) + const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID; + if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PPREVWS.id == -1)) return {.success = false, .error = "Previous workspace doesn't exist"}; g_pInputManager->unconstrainMouse(); g_pInputManager->m_bEmptyFocusCursorSet = false; - auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PREVWS.id : workspaceToChangeTo); + auto pWorkspaceToChangeTo = g_pCompositor->getWorkspaceByID(BISWORKSPACECURRENT ? PPREVWS.id : workspaceToChangeTo); if (!pWorkspaceToChangeTo) pWorkspaceToChangeTo = - g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PREVWS.id : workspaceToChangeTo, PMONITOR->ID, BISWORKSPACECURRENT ? PREVWS.name : workspaceName); + g_pCompositor->createNewWorkspace(BISWORKSPACECURRENT ? PPREVWS.id : workspaceToChangeTo, PMONITOR->ID, BISWORKSPACECURRENT ? PPREVWS.name : workspaceName); if (!BISWORKSPACECURRENT && pWorkspaceToChangeTo->m_bIsSpecialWorkspace) { PMONITOR->setSpecialWorkspace(pWorkspaceToChangeTo); @@ -1407,9 +1404,7 @@ SDispatchResult CKeybindManager::moveActiveToWorkspace(std::string args) { } SDispatchResult CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { - PHLWINDOW PWINDOW = nullptr; - - const auto ORIGINALARGS = args; + PHLWINDOW PWINDOW = nullptr; if (args.contains(',')) { PWINDOW = g_pCompositor->getWindowByRegex(args.substr(args.find_last_of(',') + 1)); @@ -2033,7 +2028,7 @@ SDispatchResult CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args } static auto PBACKANDFORTH = CConfigValue("binds:workspace_back_and_forth"); - const auto PREVWS = pWorkspace->getPrevWorkspaceIDName(false); + const auto PREVWS = pWorkspace->getPrevWorkspaceIDName(); if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspaceID() == workspaceID && PREVWS.id != -1) { // Workspace to focus is previous workspace From 9e4f90aedf2f51d3e7f3dbe5391cb193aa0bddf5 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:35:57 +0000 Subject: [PATCH 0109/1444] animation: fixup adding animvars during ::tick (#9030) --- src/managers/AnimationManager.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index ea74ffd2..28adc330 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -216,11 +216,8 @@ void CHyprAnimationManager::tick() { static auto PANIMENABLED = CConfigValue("animations:enabled"); - // We need to do this because it's perfectly valid to add/change a var during this (via callbacks) - // FIXME: instead of doing this, make a fn to defer adding until tick is done and not in progress anymore. - const auto PAVS = m_vActiveAnimatedVariables; - for (auto const& pav : PAVS) { - const auto PAV = pav.lock(); + for (size_t i = 0; i < m_vActiveAnimatedVariables.size(); i++) { + const auto PAV = m_vActiveAnimatedVariables[i].lock(); if (!PAV) continue; From 2778aff08fba59a34b404751039d7acb6bfb3bdf Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:38:04 +0000 Subject: [PATCH 0110/1444] animations: fix XWayland cursor glitch and refactor skill issues (#9033) --- src/events/Windows.cpp | 2 +- src/managers/XWaylandManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index ff69e83f..14e89b4b 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -38,7 +38,7 @@ static void setVector2DAnimToMove(WP pav) { animvar->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove")); const auto PHLWINDOW = animvar->m_Context.pWindow.lock(); - if (PHLWINDOW && PHLWINDOW->m_vRealPosition->isBeingAnimated() && PHLWINDOW->m_vRealSize->isBeingAnimated()) + if (PHLWINDOW && !PHLWINDOW->m_vRealPosition->isBeingAnimated() && !PHLWINDOW->m_vRealSize->isBeingAnimated()) PHLWINDOW->m_bAnimatingIn = false; } diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index bc988f39..ab0bfb88 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -123,7 +123,7 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool // calculate pos // TODO: this should be decoupled from setWindowSize IMO - Vector2D windowPos = pWindow->m_vRealPosition->value(); + Vector2D windowPos = pWindow->m_vRealPosition->goal(); if (pWindow->m_bIsX11 && PMONITOR) { windowPos -= PMONITOR->vecPosition; // normalize to monitor From 2671656a75708452e9408a111e69e4436b6ad301 Mon Sep 17 00:00:00 2001 From: Toria Date: Sun, 12 Jan 2025 16:35:10 +0000 Subject: [PATCH 0111/1444] helpers/Monitor.cpp: fix include path (#9039) --- src/helpers/Monitor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 8085c460..8c7566e2 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -3,7 +3,7 @@ #include "../defines.hpp" #include #include -#include "SharedDefs.hpp" +#include "../SharedDefs.hpp" #include "WLClasses.hpp" #include #include From b117fae3b493b9d5ac7ada3140cac555c3979dfd Mon Sep 17 00:00:00 2001 From: staz Date: Sun, 12 Jan 2025 22:00:56 +0500 Subject: [PATCH 0112/1444] keybinds: fix movefocus fallback for special workspaces (#9040) --- src/managers/KeybindManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 720d27f6..9a719130 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1534,7 +1534,8 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) { break; } - const auto PWINDOWCANDIDATE = g_pCompositor->getWindowInDirection(box, PMONITOR->activeWorkspace, arg, PLASTWINDOW, PLASTWINDOW->m_bIsFloating); + const auto PWINDOWCANDIDATE = g_pCompositor->getWindowInDirection(box, PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace : PMONITOR->activeWorkspace, arg, + PLASTWINDOW, PLASTWINDOW->m_bIsFloating); if (PWINDOWCANDIDATE) switchToWindow(PWINDOWCANDIDATE); From a3a74993173662c06025ca633faa68b5590e2c5b Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Sun, 12 Jan 2025 20:02:41 +0300 Subject: [PATCH 0113/1444] renderer: Do not set hdr metadata unless needed (#9014) --- src/protocols/ColorManagement.cpp | 26 ++++++++++++++++++++++---- src/protocols/ColorManagement.hpp | 7 +++++++ src/protocols/FrogColorManagement.cpp | 10 +++++----- src/render/Renderer.cpp | 23 ++++++++++++++++------- src/render/Renderer.hpp | 1 + 5 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/protocols/ColorManagement.cpp b/src/protocols/ColorManagement.cpp index 7ff4db4f..a76e13c0 100644 --- a/src/protocols/ColorManagement.cpp +++ b/src/protocols/ColorManagement.cpp @@ -194,13 +194,13 @@ CColorManagementSurface::CColorManagementSurface(SP return; } - m_hasImageDescription = true; - m_imageDescription = imageDescription->get()->settings; + setHasImageDescription(true); + m_imageDescription = imageDescription->get()->settings; }); resource->setUnsetImageDescription([this](CXxColorManagementSurfaceV4* r) { LOGM(TRACE, "Unset image description for surface={}", (uintptr_t)r); - m_imageDescription = SImageDescription{}; - m_hasImageDescription = false; + m_imageDescription = SImageDescription{}; + setHasImageDescription(false); }); } @@ -222,6 +222,24 @@ bool CColorManagementSurface::hasImageDescription() { return m_hasImageDescription; } +void CColorManagementSurface::setHasImageDescription(bool has) { + m_hasImageDescription = has; + m_needsNewMetadata = true; +} + +const hdr_output_metadata& CColorManagementSurface::hdrMetadata() { + return m_hdrMetadata; +} + +void CColorManagementSurface::setHDRMetadata(const hdr_output_metadata& metadata) { + m_hdrMetadata = metadata; + m_needsNewMetadata = false; +} + +bool CColorManagementSurface::needsHdrMetadataUpdate() { + return m_needsNewMetadata; +} + CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP resource_, SP surface_) : surface(surface_), resource(resource_) { if (!good()) diff --git a/src/protocols/ColorManagement.hpp b/src/protocols/ColorManagement.hpp index 573abf69..e387b3b7 100644 --- a/src/protocols/ColorManagement.hpp +++ b/src/protocols/ColorManagement.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -54,12 +55,18 @@ class CColorManagementSurface { const SImageDescription& imageDescription(); bool hasImageDescription(); + void setHasImageDescription(bool has); + const hdr_output_metadata& hdrMetadata(); + void setHDRMetadata(const hdr_output_metadata& metadata); + bool needsHdrMetadataUpdate(); private: SP resource; wl_client* pClient = nullptr; SImageDescription m_imageDescription; bool m_hasImageDescription = false; + bool m_needsNewMetadata = false; + hdr_output_metadata m_hdrMetadata; friend class CFrogColorManagementSurface; }; diff --git a/src/protocols/FrogColorManagement.cpp b/src/protocols/FrogColorManagement.cpp index 6a921981..f27af5c8 100644 --- a/src/protocols/FrogColorManagement.cpp +++ b/src/protocols/FrogColorManagement.cpp @@ -92,7 +92,7 @@ CFrogColorManagementSurface::CFrogColorManagementSurface(SPcolorManagement->m_imageDescription.transferFunction = XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB; - surface->colorManagement->m_hasImageDescription = true; + surface->colorManagement->setHasImageDescription(true); } }); resource->setSetKnownContainerColorVolume([this](CFrogColorManagedSurface* r, frogColorManagedSurfacePrimaries primariesName) { @@ -103,12 +103,12 @@ CFrogColorManagementSurface::CFrogColorManagementSurface(SPcolorManagement->m_imageDescription.primaries = NColorPrimaries::BT2020; break; } - surface->colorManagement->m_hasImageDescription = true; + surface->colorManagement->setHasImageDescription(true); }); resource->setSetRenderIntent([this](CFrogColorManagedSurface* r, frogColorManagedSurfaceRenderIntent intent) { LOGM(TRACE, "Set frog cm intent {}", (uint32_t)intent); - pqIntentSent = intent == FROG_COLOR_MANAGED_SURFACE_RENDER_INTENT_PERCEPTUAL; - surface->colorManagement->m_hasImageDescription = true; + pqIntentSent = intent == FROG_COLOR_MANAGED_SURFACE_RENDER_INTENT_PERCEPTUAL; + surface->colorManagement->setHasImageDescription(true); }); resource->setSetHdrMetadata([this](CFrogColorManagedSurface* r, uint32_t r_x, uint32_t r_y, uint32_t g_x, uint32_t g_y, uint32_t b_x, uint32_t b_y, uint32_t w_x, uint32_t w_y, uint32_t max_lum, uint32_t min_lum, uint32_t cll, uint32_t fall) { @@ -122,7 +122,7 @@ CFrogColorManagementSurface::CFrogColorManagementSurface(SPcolorManagement->m_imageDescription.maxCLL = cll; surface->colorManagement->m_imageDescription.maxFALL = fall; - surface->colorManagement->m_hasImageDescription = true; + surface->colorManagement->setHasImageDescription(true); }); } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index cf25d477..b9c8dd98 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1460,9 +1460,10 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { pMonitor->output->state->setExplicitInFence(inFD); static auto PWIDE = CConfigValue("experimental:wide_color_gamut"); - if (pMonitor->output->state->state().wideColorGamut != *PWIDE) + if (pMonitor->output->state->state().wideColorGamut != *PWIDE) { Debug::log(TRACE, "Setting wide color gamut {}", *PWIDE ? "on" : "off"); - pMonitor->output->state->setWideColorGamut(*PWIDE); + pMonitor->output->state->setWideColorGamut(*PWIDE); + } static auto PHDR = CConfigValue("experimental:hdr"); @@ -1472,12 +1473,20 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { if (pMonitor->activeWorkspace && pMonitor->activeWorkspace->m_bHasFullscreenWindow && pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) { const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow(); const auto SURF = WINDOW->m_pWLSurface->resource(); - if (SURF->colorManagement.valid() && SURF->colorManagement->hasImageDescription()) - pMonitor->output->state->setHDRMetadata(createHDRMetadata(SURF->colorManagement.get()->imageDescription(), pMonitor->output->parsedEDID)); - else + if (SURF->colorManagement.valid() && SURF->colorManagement->hasImageDescription()) { + bool needsHdrMetadataUpdate = SURF->colorManagement->needsHdrMetadataUpdate() || m_previousFSWindow != WINDOW; + if (SURF->colorManagement->needsHdrMetadataUpdate()) + SURF->colorManagement->setHDRMetadata(createHDRMetadata(SURF->colorManagement.get()->imageDescription(), pMonitor->output->parsedEDID)); + if (needsHdrMetadataUpdate) + pMonitor->output->state->setHDRMetadata(SURF->colorManagement->hdrMetadata()); + } else pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); - } else - pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); + m_previousFSWindow = WINDOW; + } else { + if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != *PHDR) + pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); + m_previousFSWindow.reset(); + } } if (pMonitor->ctmUpdated) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 6900c775..f3e0c5a2 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -129,6 +129,7 @@ class CHyprRenderer { bool commitPendingAndDoExplicitSync(PHLMONITOR pMonitor); + WP m_previousFSWindow; bool m_bCursorHidden = false; bool m_bCursorHasSurface = false; SP m_pCurrentRenderbuffer = nullptr; From 4f0f512cab5a8052c80b365449b69b953a97e169 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 12 Jan 2025 09:09:02 -0800 Subject: [PATCH 0114/1444] protocols: do not capture cursor in toplevel without pointer focus (#9042) --- src/protocols/ToplevelExport.cpp | 21 ++++++++++++++++++++- src/protocols/ToplevelExport.hpp | 7 ++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 2c934b40..68561533 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -2,6 +2,7 @@ #include "../Compositor.hpp" #include "ForeignToplevelWlr.hpp" #include "../managers/PointerManager.hpp" +#include "../managers/SeatManager.hpp" #include "types/WLBuffer.hpp" #include "types/Buffer.hpp" #include "../helpers/Format.hpp" @@ -77,7 +78,7 @@ CToplevelExportFrame::CToplevelExportFrame(SP re if (!good()) return; - overlayCursor = !!overlayCursor_; + cursorOverlayRequested = !!overlayCursor_; if (!pWindow) { LOGM(ERR, "Client requested sharing of window handle {:x} which does not exist!", pWindow); @@ -247,6 +248,8 @@ bool CToplevelExportFrame::copyShm(timespec* now) { CFramebuffer outFB; outFB.alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->output->state->state().drmFormat); + auto overlayCursor = shouldOverlayCursor(); + if (overlayCursor) { g_pPointerManager->lockSoftwareForMonitor(PMONITOR->self.lock()); g_pPointerManager->damageCursor(PMONITOR->self.lock()); @@ -300,6 +303,8 @@ bool CToplevelExportFrame::copyDmabuf(timespec* now) { CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX}; + auto overlayCursor = shouldOverlayCursor(); + if (overlayCursor) { g_pPointerManager->lockSoftwareForMonitor(PMONITOR->self.lock()); g_pPointerManager->damageCursor(PMONITOR->self.lock()); @@ -328,6 +333,20 @@ bool CToplevelExportFrame::copyDmabuf(timespec* now) { return true; } +bool CToplevelExportFrame::shouldOverlayCursor() const { + if (!cursorOverlayRequested) + return false; + + auto pointerSurfaceResource = g_pSeatManager->state.pointerFocus.lock(); + + if (!pointerSurfaceResource) + return false; + + auto pointerSurface = CWLSurface::fromResource(pointerSurfaceResource); + + return pointerSurface && pointerSurface->getWindow() == pWindow; +} + bool CToplevelExportFrame::good() { return resource->resource(); } diff --git a/src/protocols/ToplevelExport.hpp b/src/protocols/ToplevelExport.hpp index 1ca3e5aa..956a085b 100644 --- a/src/protocols/ToplevelExport.hpp +++ b/src/protocols/ToplevelExport.hpp @@ -51,9 +51,9 @@ class CToplevelExportFrame { SP resource; PHLWINDOW pWindow; - bool overlayCursor = false; - bool ignoreDamage = false; - bool lockedSWCursors = false; + bool cursorOverlayRequested = false; + bool ignoreDamage = false; + bool lockedSWCursors = false; WP buffer; bool bufferDMA = false; @@ -66,6 +66,7 @@ class CToplevelExportFrame { bool copyDmabuf(timespec* now); bool copyShm(timespec* now); void share(); + bool shouldOverlayCursor() const; friend class CToplevelExportProtocol; }; From a6b263713a2b862ed41362082e2147e081934077 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 12 Jan 2025 09:10:36 -0800 Subject: [PATCH 0115/1444] protocols: allow hyprland-toplevel-export to capture hidden windows (#9041) --- src/protocols/ToplevelExport.cpp | 4 ++-- src/render/Renderer.cpp | 14 +++++++------- src/render/Renderer.hpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 68561533..0ddd84c8 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -87,7 +87,7 @@ CToplevelExportFrame::CToplevelExportFrame(SP re return; } - if (!pWindow->m_bIsMapped || pWindow->isHidden()) { + if (!pWindow->m_bIsMapped) { LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable!", pWindow); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); @@ -148,7 +148,7 @@ void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resou return; } - if (!pWindow->m_bIsMapped || pWindow->isHidden()) { + if (!pWindow->m_bIsMapped) { LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", pWindow); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b9c8dd98..d4523a31 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -417,8 +417,8 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo } } -void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespec* time, bool decorate, eRenderPassMode mode, bool ignorePosition, bool ignoreAllGeometry) { - if (pWindow->isHidden()) +void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespec* time, bool decorate, eRenderPassMode mode, bool ignorePosition, bool standalone) { + if (pWindow->isHidden() && !standalone) return; if (pWindow->m_bFadingOut) { @@ -450,7 +450,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.pos.y = pMonitor->vecPosition.y; } - if (ignoreAllGeometry) + if (standalone) decorate = false; // whether to use m_fMovingToWorkspaceAlpha, only if fading out into an invisible ws @@ -463,12 +463,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe (USE_WORKSPACE_FADE_ALPHA ? pWindow->m_fMovingToWorkspaceAlpha->value() : 1.F) * pWindow->m_fMovingFromWorkspaceAlpha->value(); renderdata.alpha = pWindow->m_fActiveInactiveAlpha->value(); renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && !pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN); - renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; - renderdata.roundingPower = ignoreAllGeometry || renderdata.dontRound ? 2.0f : pWindow->roundingPower(); - renderdata.blur = !ignoreAllGeometry && *PBLUR && !DONT_BLUR; + renderdata.rounding = standalone || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale; + renderdata.roundingPower = standalone || renderdata.dontRound ? 2.0f : pWindow->roundingPower(); + renderdata.blur = !standalone && *PBLUR && !DONT_BLUR; renderdata.pWindow = pWindow; - if (ignoreAllGeometry) { + if (standalone) { renderdata.alpha = 1.f; renderdata.fadeAlpha = 1.f; } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index f3e0c5a2..8b4988c3 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -117,7 +117,7 @@ class CHyprRenderer { void arrangeLayerArray(PHLMONITOR, const std::vector&, bool, CBox*); void renderWorkspaceWindowsFullscreen(PHLMONITOR, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) void renderWorkspaceWindows(PHLMONITOR, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) - void renderWindow(PHLWINDOW, PHLMONITOR, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); + void renderWindow(PHLWINDOW, PHLMONITOR, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool standalone = false); void renderLayer(PHLLS, PHLMONITOR, timespec*, bool popups = false); void renderSessionLockSurface(SSessionLockSurface*, PHLMONITOR, timespec*); void renderDragIcon(PHLMONITOR, timespec*); From f16f170433540d85cf672217bca2d64c6db9eb01 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 14 Jan 2025 08:44:09 -0800 Subject: [PATCH 0116/1444] protocols: immediately copy toplevel content when ignoreDamage set (#9049) Also sets m_ignoreDamage, as it wasn't set before. --- src/protocols/ToplevelExport.cpp | 9 +++++++-- src/protocols/ToplevelExport.hpp | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 0ddd84c8..73e5cad9 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -202,7 +202,12 @@ void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resou buffer = PBUFFER->buffer; - PROTO::toplevelExport->m_vFramesAwaitingWrite.emplace_back(self); + m_ignoreDamage = ignoreDamage; + + if (ignoreDamage && validMapped(pWindow)) + share(); + else + PROTO::toplevelExport->m_vFramesAwaitingWrite.emplace_back(self); } void CToplevelExportFrame::share() { @@ -226,7 +231,7 @@ void CToplevelExportFrame::share() { resource->sendFlags((hyprlandToplevelExportFrameV1Flags)0); - if (!ignoreDamage) { + if (!m_ignoreDamage) { resource->sendDamage(0, 0, box.width, box.height); } diff --git a/src/protocols/ToplevelExport.hpp b/src/protocols/ToplevelExport.hpp index 956a085b..8d734dbd 100644 --- a/src/protocols/ToplevelExport.hpp +++ b/src/protocols/ToplevelExport.hpp @@ -52,7 +52,7 @@ class CToplevelExportFrame { PHLWINDOW pWindow; bool cursorOverlayRequested = false; - bool ignoreDamage = false; + bool m_ignoreDamage = false; bool lockedSWCursors = false; WP buffer; From 25add26881d7b98d2b80eb7a95d3aee0449b72b9 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 14 Jan 2025 17:52:19 +0100 Subject: [PATCH 0117/1444] renderer: unload background texture if it's disabled ref #9031 --- src/config/ConfigManager.cpp | 5 +++-- src/render/OpenGL.cpp | 21 ++++++++++++++------- src/render/OpenGL.hpp | 4 +++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 60723220..17957899 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -899,11 +899,12 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { g_pInputManager->setPointerConfigs(); g_pInputManager->setTouchDeviceConfigs(); g_pInputManager->setTabletConfigs(); - } - if (!isFirstLaunch) g_pHyprOpenGL->m_bReloadScreenShader = true; + g_pHyprOpenGL->ensureBackgroundTexturePresence(); + } + // parseError will be displayed next frame if (result.error) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 3a4781e7..b68448ae 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2699,10 +2699,6 @@ void CHyprOpenGLImpl::initMissingAssetTexture() { void CHyprOpenGLImpl::initAssets() { initMissingAssetTexture(); - static auto PFORCEWALLPAPER = CConfigValue("misc:force_default_wallpaper"); - - const auto FORCEWALLPAPER = std::clamp(*PFORCEWALLPAPER, static_cast(-1L), static_cast(2L)); - m_pLockDeadTexture = loadAsset("lockdead.png"); m_pLockDead2Texture = loadAsset("lockdead2.png"); @@ -2712,9 +2708,20 @@ void CHyprOpenGLImpl::initAssets() { "unknown"), CHyprColor{0.9F, 0.9F, 0.9F, 0.7F}, 20, true); - // create the default background texture - { - std::string texPath = std::format("{}", "wall"); + ensureBackgroundTexturePresence(); +} + +void CHyprOpenGLImpl::ensureBackgroundTexturePresence() { + static auto PNOWALLPAPER = CConfigValue("misc:disable_hyprland_logo"); + static auto PFORCEWALLPAPER = CConfigValue("misc:force_default_wallpaper"); + + const auto FORCEWALLPAPER = std::clamp(*PFORCEWALLPAPER, static_cast(-1L), static_cast(2L)); + + if (*PNOWALLPAPER) + m_pBackgroundTexture.reset(); + else if (!m_pBackgroundTexture) { + // create the default background texture + std::string texPath = "wall"; // get the adequate tex if (FORCEWALLPAPER == -1) { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 3f117a5a..2b600a03 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -223,6 +223,8 @@ class CHyprOpenGLImpl { void setDamage(const CRegion& damage, std::optional finalDamage = {}); + void ensureBackgroundTexturePresence(); + uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); std::vector getDRMFormats(); EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); @@ -293,7 +295,7 @@ class CHyprOpenGLImpl { CShader m_sFinalScreenShader; CTimer m_tGlobalTimer; - SP m_pMissingAssetTexture, m_pBackgroundTexture, m_pLockDeadTexture, m_pLockDead2Texture, m_pLockTtyTextTexture; + SP m_pMissingAssetTexture, m_pBackgroundTexture, m_pLockDeadTexture, m_pLockDead2Texture, m_pLockTtyTextTexture; // TODO: don't always load lock void logShaderError(const GLuint&, bool program = false); GLuint createProgram(const std::string&, const std::string&, bool dynamic = false); From 52b9ae592b90cc9f857743ae7f59e787cc58fc8a Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:13:47 +0300 Subject: [PATCH 0118/1444] renderer: fix fullscreen hdr check (#9076) --- src/render/Renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index d4523a31..6c77b27a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1479,7 +1479,7 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { SURF->colorManagement->setHDRMetadata(createHDRMetadata(SURF->colorManagement.get()->imageDescription(), pMonitor->output->parsedEDID)); if (needsHdrMetadataUpdate) pMonitor->output->state->setHDRMetadata(SURF->colorManagement->hdrMetadata()); - } else + } else if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != *PHDR) pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); m_previousFSWindow = WINDOW; } else { From 0dc7367a7006cc3cc877d52bf34c4998144bff84 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:42:39 +0100 Subject: [PATCH 0119/1444] renderer: use cairo for cpu buffer rendering (#9071) Instead of a wonky memcpy which doesn't work when anything non-standard is used (size, pos, transform), just use cairo --- src/managers/PointerManager.cpp | 58 +++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 85e1c601..522187b4 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -12,6 +12,7 @@ #include "SeatManager.hpp" #include #include +#include CPointerManager::CPointerManager() { hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) { @@ -481,15 +482,58 @@ SP CPointerManager::renderHWCursorBuffer(SPdmabuf(); auto [data, fmt, size] = buf->beginDataPtr(0); - memset(data, 0, size); - if (buf->dmabuf().size.x > texture->m_vSize.x) { - size_t STRIDE = 4 * texture->m_vSize.x; - for (int i = 0; i < texture->m_vSize.y; i++) - memcpy(data + i * buf->dmabuf().strides[0], texData.data() + i * STRIDE, STRIDE); - } else - memcpy(data, texData.data(), std::min(size, texData.size())); + auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, DMABUF.size.x, DMABUF.size.y); + auto CAIRODATASURFACE = + cairo_image_surface_create_for_data((unsigned char*)texData.data(), CAIRO_FORMAT_ARGB32, texture->m_vSize.x, texture->m_vSize.y, texture->m_vSize.x * 4); + + auto CAIRO = cairo_create(CAIROSURFACE); + + cairo_set_operator(CAIRO, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba(CAIRO, 0, 0, 0, 0); + cairo_rectangle(CAIRO, 0, 0, texture->m_vSize.x, texture->m_vSize.y); + cairo_fill(CAIRO); + + const auto PATTERNPRE = cairo_pattern_create_for_surface(CAIRODATASURFACE); + cairo_pattern_set_filter(PATTERNPRE, CAIRO_FILTER_BILINEAR); + cairo_matrix_t matrixPre; + cairo_matrix_init_identity(&matrixPre); + + const auto TR = state->monitor->transform; + + if (TR) { + cairo_matrix_rotate(&matrixPre, M_PI_2 * (double)TR); + + // FIXME: this is wrong, and doesnt work for 5, 6 and 7. (flipped + rot) + // cba to do it rn, does anyone fucking use that?? + if (TR >= WL_OUTPUT_TRANSFORM_FLIPPED) { + cairo_matrix_scale(&matrixPre, -1, 1); + cairo_matrix_translate(&matrixPre, -DMABUF.size.x, 0); + } + + if (TR == 3 || TR == 7) + cairo_matrix_translate(&matrixPre, -DMABUF.size.x, 0); + else if (TR == 2 || TR == 6) + cairo_matrix_translate(&matrixPre, -DMABUF.size.x, -DMABUF.size.y); + else if (TR == 1 || TR == 5) + cairo_matrix_translate(&matrixPre, 0, -DMABUF.size.y); + } + + cairo_pattern_set_matrix(PATTERNPRE, &matrixPre); + cairo_set_source(CAIRO, PATTERNPRE); + cairo_paint(CAIRO); + + cairo_surface_flush(CAIROSURFACE); + + cairo_pattern_destroy(PATTERNPRE); + + memcpy(data, cairo_image_surface_get_data(CAIROSURFACE), (size_t)cairo_image_surface_get_height(CAIROSURFACE) * cairo_image_surface_get_stride(CAIROSURFACE)); + + cairo_destroy(CAIRO); + cairo_surface_destroy(CAIROSURFACE); + cairo_surface_destroy(CAIRODATASURFACE); buf->endDataPtr(); From 2bad73354a5dbb9be8ba9a39b6238017a216a25b Mon Sep 17 00:00:00 2001 From: user111111111111111111111111111111111 <192911676+user111111111111111111111111111111111@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:21:35 +0000 Subject: [PATCH 0120/1444] core: cleanup header includes (#9088) Cleanup some unneeded includes to speed up compilation --- src/Compositor.cpp | 19 +++++++++++++++++++ src/Compositor.hpp | 18 ------------------ src/SharedDefs.hpp | 1 + src/config/ConfigManager.cpp | 13 ++++++++++++- src/config/ConfigManager.hpp | 13 +++++++------ src/config/ConfigValue.hpp | 3 +-- src/debug/CrashReporter.cpp | 1 + src/debug/HyprCtl.cpp | 10 ++++++++++ src/debug/HyprCtl.hpp | 2 +- src/debug/HyprDebugOverlay.cpp | 1 + src/debug/HyprDebugOverlay.hpp | 3 +-- src/debug/HyprNotificationOverlay.cpp | 4 ++++ src/debug/HyprNotificationOverlay.hpp | 1 - src/debug/Log.cpp | 1 - src/debug/Log.hpp | 2 -- src/defines.hpp | 2 ++ src/desktop/DesktopTypes.hpp | 2 +- src/desktop/LayerSurface.cpp | 6 ++++++ src/desktop/LayerSurface.hpp | 1 - src/desktop/Popup.cpp | 4 ++++ src/desktop/Subsurface.cpp | 2 ++ src/desktop/WLSurface.cpp | 4 +++- src/desktop/Window.cpp | 7 +++++++ src/desktop/Window.hpp | 2 +- src/desktop/Workspace.cpp | 2 ++ src/devices/Keyboard.cpp | 1 - src/events/Windows.cpp | 5 +++++ src/helpers/Color.hpp | 1 - src/helpers/MiscFunctions.cpp | 2 ++ src/helpers/MiscFunctions.hpp | 2 -- src/helpers/Monitor.cpp | 6 ++++++ src/helpers/Monitor.hpp | 1 + src/helpers/WLClasses.hpp | 6 +++--- src/hyprerror/HyprError.cpp | 2 ++ src/layout/DwindleLayout.cpp | 4 ++++ src/layout/IHyprLayout.cpp | 5 +++++ src/layout/MasterLayout.cpp | 4 ++++ src/layout/MasterLayout.hpp | 2 +- src/macros.hpp | 1 + src/managers/AnimationManager.cpp | 1 + src/managers/CursorManager.cpp | 1 + src/managers/HookSystemManager.hpp | 2 +- src/managers/KeybindManager.cpp | 6 ++++++ src/managers/PointerManager.cpp | 4 ++++ src/managers/ProtocolManager.hpp | 1 - src/managers/SeatManager.cpp | 3 +++ src/managers/SeatManager.hpp | 1 - src/managers/SessionLockManager.cpp | 4 +++- src/managers/input/InputManager.cpp | 5 +++++ src/managers/input/InputMethodPopup.cpp | 2 ++ src/managers/input/InputMethodRelay.cpp | 1 + src/managers/input/Swipe.cpp | 3 +++ src/managers/input/Tablets.cpp | 2 +- src/managers/input/TextInput.hpp | 2 +- src/managers/input/Touch.cpp | 2 ++ src/plugins/HookSystem.cpp | 4 ++-- src/plugins/PluginAPI.cpp | 5 +++++ src/plugins/PluginSystem.cpp | 4 +++- src/protocols/CTMControl.cpp | 1 + src/protocols/DRMLease.cpp | 1 + src/protocols/ForeignToplevel.cpp | 1 + src/protocols/ForeignToplevelWlr.cpp | 1 + src/protocols/GammaControl.cpp | 2 +- src/protocols/GlobalShortcuts.cpp | 1 - src/protocols/LayerShell.cpp | 2 ++ src/protocols/MesaDRM.cpp | 1 + src/protocols/OutputManagement.cpp | 3 +++ src/protocols/OutputPower.cpp | 2 +- src/protocols/PointerConstraints.cpp | 3 +++ src/protocols/PointerGestures.cpp | 1 - src/protocols/RelativePointer.cpp | 3 +-- src/protocols/Screencopy.cpp | 4 ++++ src/protocols/SessionLock.cpp | 3 ++- src/protocols/SinglePixel.cpp | 1 + src/protocols/Tablet.cpp | 1 + src/protocols/TearingControl.cpp | 1 + src/protocols/TextInputV1.cpp | 1 - src/protocols/ToplevelExport.cpp | 3 +++ src/protocols/XDGOutput.cpp | 4 ++-- src/protocols/XDGShell.cpp | 1 + src/protocols/core/DataDevice.cpp | 4 ++++ src/protocols/core/Shm.cpp | 2 +- src/protocols/types/DMABuffer.cpp | 1 + src/protocols/types/WLBuffer.cpp | 1 - src/render/OpenGL.cpp | 3 +++ src/render/OpenGL.hpp | 1 - src/render/Renderbuffer.cpp | 3 ++- src/render/Renderer.cpp | 7 +++++++ src/render/Renderer.hpp | 1 + .../decorations/CHyprBorderDecoration.cpp | 2 ++ .../decorations/CHyprDropShadowDecoration.cpp | 1 + .../decorations/CHyprGroupBarDecoration.cpp | 2 ++ .../decorations/DecorationPositioner.cpp | 4 +++- src/render/pass/Pass.cpp | 1 + src/render/pass/SurfacePassElement.cpp | 1 + src/xwayland/XSurface.cpp | 1 - src/xwayland/XWM.hpp | 1 - 97 files changed, 224 insertions(+), 72 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index fcd15312..496ca4fe 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -42,6 +42,25 @@ #include "helpers/ByteOperations.hpp" #include "render/decorations/CHyprGroupBarDecoration.hpp" +#include "managers/KeybindManager.hpp" +#include "managers/SessionLockManager.hpp" +#include "managers/ThreadManager.hpp" +#include "managers/XWaylandManager.hpp" + +#include "config/ConfigManager.hpp" +#include "render/OpenGL.hpp" +#include "managers/input/InputManager.hpp" +#include "managers/AnimationManager.hpp" +#include "managers/EventManager.hpp" +#include "managers/HookSystemManager.hpp" +#include "managers/ProtocolManager.hpp" +#include "managers/LayoutManager.hpp" +#include "plugins/PluginSystem.hpp" +#include "helpers/Watchdog.hpp" +#include "hyprerror/HyprError.hpp" +#include "debug/HyprNotificationOverlay.hpp" +#include "debug/HyprDebugOverlay.hpp" + #include #include diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 629b71bc..0a701a59 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -5,30 +5,12 @@ #include #include "defines.hpp" -#include "debug/Log.hpp" -#include "events/Events.hpp" -#include "config/ConfigManager.hpp" #include "managers/ThreadManager.hpp" #include "managers/XWaylandManager.hpp" -#include "managers/input/InputManager.hpp" -#include "managers/LayoutManager.hpp" #include "managers/KeybindManager.hpp" -#include "managers/AnimationManager.hpp" -#include "managers/EventManager.hpp" -#include "managers/ProtocolManager.hpp" #include "managers/SessionLockManager.hpp" -#include "managers/HookSystemManager.hpp" -#include "debug/HyprDebugOverlay.hpp" -#include "debug/HyprNotificationOverlay.hpp" -#include "helpers/Monitor.hpp" -#include "desktop/Workspace.hpp" #include "desktop/Window.hpp" #include "protocols/types/ColorManagement.hpp" -#include "render/Renderer.hpp" -#include "render/OpenGL.hpp" -#include "hyprerror/HyprError.hpp" -#include "plugins/PluginSystem.hpp" -#include "helpers/Watchdog.hpp" #include #include diff --git a/src/SharedDefs.hpp b/src/SharedDefs.hpp index a6271556..a46a2429 100644 --- a/src/SharedDefs.hpp +++ b/src/SharedDefs.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include enum eIcons : uint8_t { diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 17957899..52f2e316 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -11,8 +11,19 @@ #include "../protocols/LayerShell.hpp" #include "../xwayland/XWayland.hpp" #include "../protocols/OutputManagement.hpp" -#include "managers/AnimationManager.hpp" +#include "../managers/AnimationManager.hpp" +#include "../desktop/LayerSurface.hpp" +#include "defaultConfig.hpp" +#include "../render/Renderer.hpp" +#include "../hyprerror/HyprError.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/EventManager.hpp" +#include "../debug/HyprNotificationOverlay.hpp" +#include "../plugins/PluginSystem.hpp" + +#include "managers/HookSystemManager.hpp" #include #include #include diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index a27ee7ab..1ba1df62 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -4,23 +4,24 @@ #define CONFIG_MANAGER_H #include -#include "../debug/Log.hpp" #include #include "../defines.hpp" #include #include -#include #include #include #include -#include "../helpers/WLClasses.hpp" #include "../helpers/Monitor.hpp" -#include "../helpers/varlist/VarList.hpp" #include "../desktop/Window.hpp" -#include "../desktop/LayerSurface.hpp" +#include "../desktop/LayerRule.hpp" -#include "defaultConfig.hpp" #include "ConfigDataValues.hpp" +#include "SharedDefs.hpp" +#include "helpers/Color.hpp" +#include "desktop/DesktopTypes.hpp" +#include "helpers/memory/Memory.hpp" +#include "desktop/WindowRule.hpp" +#include "managers/XWaylandManager.hpp" #include diff --git a/src/config/ConfigValue.hpp b/src/config/ConfigValue.hpp index 181fdd0f..089ae8bf 100644 --- a/src/config/ConfigValue.hpp +++ b/src/config/ConfigValue.hpp @@ -3,7 +3,6 @@ #include #include #include -#include "../debug/Log.hpp" #include "../macros.hpp" #include "ConfigManager.hpp" @@ -71,4 +70,4 @@ template <> inline Hyprlang::CUSTOMTYPE CConfigValue::operator*() const { RASSERT(false, "Impossible to implement operator* of CConfigValue, use ptr()"); return *ptr(); -} \ No newline at end of file +} diff --git a/src/debug/CrashReporter.cpp b/src/debug/CrashReporter.cpp index 7bff7295..f6e0b55f 100644 --- a/src/debug/CrashReporter.cpp +++ b/src/debug/CrashReporter.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "../helpers/MiscFunctions.hpp" #include "../plugins/PluginSystem.hpp" #include "../signal-safe.hpp" diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 7edace21..41b0abe1 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -39,8 +39,18 @@ using namespace Hyprutils::String; #include "debug/RollingLogFollow.hpp" #include "config/ConfigManager.hpp" #include "helpers/MiscFunctions.hpp" +#include "../desktop/LayerSurface.hpp" #include "../version.h" +#include "../Compositor.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/XWaylandManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../plugins/PluginSystem.hpp" +#include "../managers/AnimationManager.hpp" +#include "../debug/HyprNotificationOverlay.hpp" +#include "../render/Renderer.hpp" + static void trimTrailingComma(std::string& str) { if (!str.empty() && str.back() == ',') str.pop_back(); diff --git a/src/debug/HyprCtl.hpp b/src/debug/HyprCtl.hpp index c1bf51ca..2603612c 100644 --- a/src/debug/HyprCtl.hpp +++ b/src/debug/HyprCtl.hpp @@ -1,8 +1,8 @@ #pragma once -#include "../Compositor.hpp" #include #include "../helpers/MiscFunctions.hpp" +#include "../desktop/Window.hpp" #include // exposed for main.cpp diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp index d72e2144..6e7a0407 100644 --- a/src/debug/HyprDebugOverlay.cpp +++ b/src/debug/HyprDebugOverlay.cpp @@ -4,6 +4,7 @@ #include "../Compositor.hpp" #include "../render/pass/TexPassElement.hpp" #include "../render/Renderer.hpp" +#include "../managers/AnimationManager.hpp" CHyprDebugOverlay::CHyprDebugOverlay() { m_pTexture = makeShared(); diff --git a/src/debug/HyprDebugOverlay.hpp b/src/debug/HyprDebugOverlay.hpp index 42cdac55..a58ecffc 100644 --- a/src/debug/HyprDebugOverlay.hpp +++ b/src/debug/HyprDebugOverlay.hpp @@ -1,7 +1,6 @@ #pragma once #include "../defines.hpp" -#include "../helpers/Monitor.hpp" #include "../render/Texture.hpp" #include #include @@ -49,4 +48,4 @@ class CHyprDebugOverlay { friend class CHyprRenderer; }; -inline std::unique_ptr g_pDebugOverlay; \ No newline at end of file +inline std::unique_ptr g_pDebugOverlay; diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index 504ad6c9..09125243 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -5,6 +5,10 @@ #include "../config/ConfigValue.hpp" #include "../render/pass/TexPassElement.hpp" +#include "../managers/AnimationManager.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../render/Renderer.hpp" + static inline auto iconBackendFromLayout(PangoLayout* layout) { // preference: Nerd > FontAwesome > text auto eIconBackendChecks = std::array{ICONS_BACKEND_NF, ICONS_BACKEND_FA}; diff --git a/src/debug/HyprNotificationOverlay.hpp b/src/debug/HyprNotificationOverlay.hpp index 3ff0b35c..2546d04f 100644 --- a/src/debug/HyprNotificationOverlay.hpp +++ b/src/debug/HyprNotificationOverlay.hpp @@ -2,7 +2,6 @@ #include "../defines.hpp" #include "../helpers/Timer.hpp" -#include "../helpers/Monitor.hpp" #include "../render/Texture.hpp" #include "../SharedDefs.hpp" diff --git a/src/debug/Log.cpp b/src/debug/Log.cpp index 1563628c..9cf86345 100644 --- a/src/debug/Log.cpp +++ b/src/debug/Log.cpp @@ -1,6 +1,5 @@ #include "Log.hpp" #include "../defines.hpp" -#include "../Compositor.hpp" #include "RollingLogFollow.hpp" #include diff --git a/src/debug/Log.hpp b/src/debug/Log.hpp index 9696aa90..3791aeac 100644 --- a/src/debug/Log.hpp +++ b/src/debug/Log.hpp @@ -5,8 +5,6 @@ #include #include #include -#include "../includes.hpp" -#include "../helpers/MiscFunctions.hpp" #define LOGMESSAGESIZE 1024 #define ROLLING_LOG_SIZE 4096 diff --git a/src/defines.hpp b/src/defines.hpp index 41ee4502..5c70f21a 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "includes.hpp" #include "debug/Log.hpp" #include "helpers/Color.hpp" diff --git a/src/desktop/DesktopTypes.hpp b/src/desktop/DesktopTypes.hpp index 7f812cc1..ae2ac366 100644 --- a/src/desktop/DesktopTypes.hpp +++ b/src/desktop/DesktopTypes.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../macros.hpp" +#include "helpers/memory/Memory.hpp" class CWorkspace; class CWindow; class CLayerSurface; diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index fe11f3f3..c572f6b2 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -5,6 +5,12 @@ #include "../protocols/core/Compositor.hpp" #include "../managers/SeatManager.hpp" #include "../managers/AnimationManager.hpp" +#include "../render/Renderer.hpp" +#include "../config/ConfigManager.hpp" +#include "../helpers/Monitor.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../managers/EventManager.hpp" PHLLS CLayerSurface::create(SP resource) { PHLLS pLS = SP(new CLayerSurface(resource)); diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index 3a03e57e..591dfd99 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -4,7 +4,6 @@ #include "../defines.hpp" #include "WLSurface.hpp" #include "../helpers/AnimatedVariable.hpp" -#include "LayerRule.hpp" class CLayerShellResource; diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index ce286b28..ce6ab9a0 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -6,6 +6,10 @@ #include "../protocols/core/Compositor.hpp" #include "../managers/SeatManager.hpp" #include "../managers/eventLoop/EventLoopManager.hpp" +#include "../desktop/LayerSurface.hpp" +#include "../managers/input/InputManager.hpp" +#include "../render/Renderer.hpp" +#include "../render/OpenGL.hpp" #include CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) { diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 62854f80..26638f7a 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -4,6 +4,8 @@ #include "../config/ConfigValue.hpp" #include "../protocols/core/Compositor.hpp" #include "../protocols/core/Subcompositor.hpp" +#include "../render/Renderer.hpp" +#include "../managers/input/InputManager.hpp" CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) { initSignals(); diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp index 9ed8ec49..e86ac036 100644 --- a/src/desktop/WLSurface.cpp +++ b/src/desktop/WLSurface.cpp @@ -1,7 +1,9 @@ #include "WLSurface.hpp" -#include "../Compositor.hpp" +#include "LayerSurface.hpp" +#include "../desktop/Window.hpp" #include "../protocols/core/Compositor.hpp" #include "../protocols/LayerShell.hpp" +#include "../render/Renderer.hpp" void CWLSurface::assign(SP pSurface) { m_pResource = pSurface; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 5608daef..241a17d7 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -17,6 +17,13 @@ #include "../protocols/core/Compositor.hpp" #include "../xwayland/XWayland.hpp" #include "../helpers/Color.hpp" +#include "../events/Events.hpp" +#include "../managers/XWaylandManager.hpp" +#include "../render/Renderer.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../managers/EventManager.hpp" +#include "../managers/input/InputManager.hpp" #include diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index d503ac3b..ebda235c 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -4,7 +4,6 @@ #include #include "../config/ConfigDataValues.hpp" -#include "../defines.hpp" #include "../helpers/AnimatedVariable.hpp" #include "../helpers/math/Math.hpp" #include "../helpers/signal/Signal.hpp" @@ -12,6 +11,7 @@ #include "../macros.hpp" #include "../managers/XWaylandManager.hpp" #include "../render/decorations/IHyprWindowDecoration.hpp" +#include "../render/Transformer.hpp" #include "DesktopTypes.hpp" #include "Popup.hpp" #include "Subsurface.hpp" diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 07c1a435..99ba441d 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -3,6 +3,8 @@ #include "../config/ConfigValue.hpp" #include "config/ConfigManager.hpp" #include "managers/AnimationManager.hpp" +#include "../managers/EventManager.hpp" +#include "../managers/HookSystemManager.hpp" #include #include diff --git a/src/devices/Keyboard.cpp b/src/devices/Keyboard.cpp index 0a8f6b57..191cc6b2 100644 --- a/src/devices/Keyboard.cpp +++ b/src/devices/Keyboard.cpp @@ -1,6 +1,5 @@ #include "Keyboard.hpp" #include "../defines.hpp" -#include "../Compositor.hpp" #include diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 14e89b4b..cadd4cbc 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -14,6 +14,11 @@ #include "../xwayland/XSurface.hpp" #include "managers/AnimationManager.hpp" #include "managers/PointerManager.hpp" +#include "../desktop/LayerSurface.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/EventManager.hpp" +#include "../managers/AnimationManager.hpp" #include using namespace Hyprutils::String; diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp index 0ea816f3..8050bebd 100644 --- a/src/helpers/Color.hpp +++ b/src/helpers/Color.hpp @@ -2,7 +2,6 @@ #include #include -#include "../debug/Log.hpp" #include "../macros.hpp" class CHyprColor { diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 0fa73e45..fafe1811 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -3,6 +3,8 @@ #include #include "../Compositor.hpp" #include "../managers/TokenManager.hpp" +#include "Monitor.hpp" +#include "../config/ConfigManager.hpp" #include #include #include diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index 64802279..d0824284 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -1,9 +1,7 @@ #pragma once #include -#include #include -#include "math/Math.hpp" #include #include #include diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index cf62bc54..718baf23 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -17,9 +17,15 @@ #include "../managers/PointerManager.hpp" #include "../managers/eventLoop/EventLoopManager.hpp" #include "../protocols/core/Compositor.hpp" +#include "../render/Renderer.hpp" +#include "../managers/EventManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/input/InputManager.hpp" #include "sync/SyncTimeline.hpp" +#include "../desktop/LayerSurface.hpp" #include #include "debug/Log.hpp" +#include "debug/HyprNotificationOverlay.hpp" #include #include #include diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 8c7566e2..3335a896 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -4,6 +4,7 @@ #include #include #include "../SharedDefs.hpp" +#include "MiscFunctions.hpp" #include "WLClasses.hpp" #include #include diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index b6e3ac12..c2e828e7 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -1,13 +1,13 @@ #pragma once -#include "../events/Events.hpp" #include "../defines.hpp" -#include "../desktop/Window.hpp" #include "../desktop/Subsurface.hpp" #include "../desktop/Popup.hpp" #include "../desktop/WLSurface.hpp" +#include "macros.hpp" +#include "desktop/DesktopTypes.hpp" +#include "helpers/memory/Memory.hpp" #include "signal/Signal.hpp" -#include "math/Math.hpp" class CMonitor; class IPointer; diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 5e0dcf5e..d14173bf 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -4,6 +4,8 @@ #include "../config/ConfigValue.hpp" #include "../render/pass/TexPassElement.hpp" #include "../managers/AnimationManager.hpp" +#include "../render/Renderer.hpp" +#include "../managers/HookSystemManager.hpp" #include using namespace Hyprutils::Animation; diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 2ee41eba..c6cf2b4c 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -2,6 +2,10 @@ #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp" +#include "../render/Renderer.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/EventManager.hpp" void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) { if (children[0]) { diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index eeebd815..156141f6 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -7,6 +7,11 @@ #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../xwayland/XSurface.hpp" +#include "../render/Renderer.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/EventManager.hpp" +#include "../managers/HookSystemManager.hpp" void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) { CBox desiredGeometry = {}; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index e6e22326..3b8ff734 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -4,6 +4,10 @@ #include "config/ConfigDataValues.hpp" #include #include "../config/ConfigValue.hpp" +#include "../render/Renderer.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/EventManager.hpp" SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(PHLWINDOW pWindow) { for (auto& nd : m_lMasterNodesData) { diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 03ca3c3b..381ccc9d 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -2,7 +2,7 @@ #include "IHyprLayout.hpp" #include "../desktop/DesktopTypes.hpp" -#include "../config/ConfigManager.hpp" +#include "../helpers/varlist/VarList.hpp" #include #include #include diff --git a/src/macros.hpp b/src/macros.hpp index de2fd009..08c17952 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -6,6 +6,7 @@ #include #include "helpers/memory/Memory.hpp" +#include "debug/Log.hpp" #ifndef NDEBUG #ifdef HYPRLAND_DEBUG diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 28adc330..9cf35116 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -10,6 +10,7 @@ #include "../desktop/LayerSurface.hpp" #include "eventLoop/EventLoopManager.hpp" #include "../helpers/varlist/VarList.hpp" +#include "../render/Renderer.hpp" #include #include diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index 2dd97feb..d6584f35 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -3,6 +3,7 @@ #include "../config/ConfigValue.hpp" #include "PointerManager.hpp" #include "../xwayland/XWayland.hpp" +#include "../managers/HookSystemManager.hpp" static int cursorAnimTimer(SP self, void* data) { const auto cursorMgr = reinterpret_cast(data); diff --git a/src/managers/HookSystemManager.hpp b/src/managers/HookSystemManager.hpp index 75377aaa..5a9d0c00 100644 --- a/src/managers/HookSystemManager.hpp +++ b/src/managers/HookSystemManager.hpp @@ -57,4 +57,4 @@ class CHookSystemManager { std::unordered_map> m_mRegisteredHooks; }; -inline std::unique_ptr g_pHookSystem; \ No newline at end of file +inline std::unique_ptr g_pHookSystem; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 9a719130..a1979206 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -13,6 +13,12 @@ #include "debug/Log.hpp" #include "helpers/varlist/VarList.hpp" #include "../helpers/signal/Signal.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/EventManager.hpp" +#include "../render/Renderer.hpp" +#include "../hyprerror/HyprError.hpp" #include #include diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 522187b4..df145f6d 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -9,6 +9,10 @@ #include "../protocols/core/Seat.hpp" #include "eventLoop/EventLoopManager.hpp" #include "../render/pass/TexPassElement.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../render/Renderer.hpp" +#include "../render/OpenGL.hpp" #include "SeatManager.hpp" #include #include diff --git a/src/managers/ProtocolManager.hpp b/src/managers/ProtocolManager.hpp index 69dadd0f..6ceff9ad 100644 --- a/src/managers/ProtocolManager.hpp +++ b/src/managers/ProtocolManager.hpp @@ -1,7 +1,6 @@ #pragma once #include "../defines.hpp" -#include "../helpers/Monitor.hpp" #include "../helpers/memory/Memory.hpp" #include "../helpers/signal/Signal.hpp" #include diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp index 3b9a4925..8fee6b16 100644 --- a/src/managers/SeatManager.cpp +++ b/src/managers/SeatManager.cpp @@ -6,6 +6,9 @@ #include "../protocols/core/Compositor.hpp" #include "../Compositor.hpp" #include "../devices/IKeyboard.hpp" +#include "../desktop/LayerSurface.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/HookSystemManager.hpp" #include "wlr-layer-shell-unstable-v1.hpp" #include #include diff --git a/src/managers/SeatManager.hpp b/src/managers/SeatManager.hpp index ccfe5e76..32472aa3 100644 --- a/src/managers/SeatManager.hpp +++ b/src/managers/SeatManager.hpp @@ -2,7 +2,6 @@ #include #include -#include "../macros.hpp" #include "../helpers/signal/Signal.hpp" #include "../helpers/math/Math.hpp" #include "../protocols/types/DataDevice.hpp" diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp index b7110990..3d77f05a 100644 --- a/src/managers/SessionLockManager.cpp +++ b/src/managers/SessionLockManager.cpp @@ -4,6 +4,8 @@ #include "../protocols/FractionalScale.hpp" #include "../protocols/SessionLock.hpp" #include "../managers/SeatManager.hpp" +#include "../render/Renderer.hpp" +#include "../managers/input/InputManager.hpp" #include #include @@ -185,4 +187,4 @@ bool CSessionLockManager::shallConsiderLockMissing() { static auto LOCKDEAD_SCREEN_DELAY = CConfigValue("misc:lockdead_screen_delay"); return m_pSessionLock->mLockTimer.getMillis() > *LOCKDEAD_SCREEN_DELAY; -} \ No newline at end of file +} diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 8a50a7bf..3d8c6de8 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -5,6 +5,7 @@ #include #include "../../config/ConfigValue.hpp" #include "../../desktop/Window.hpp" +#include "../../desktop/LayerSurface.hpp" #include "../../protocols/CursorShape.hpp" #include "../../protocols/IdleInhibit.hpp" #include "../../protocols/RelativePointer.hpp" @@ -29,6 +30,10 @@ #include "../../managers/PointerManager.hpp" #include "../../managers/SeatManager.hpp" #include "../../managers/KeybindManager.hpp" +#include "../../render/Renderer.hpp" +#include "../../managers/HookSystemManager.hpp" +#include "../../managers/EventManager.hpp" +#include "../../managers/LayoutManager.hpp" #include diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp index ffb4edcc..8c55416b 100644 --- a/src/managers/input/InputMethodPopup.cpp +++ b/src/managers/input/InputMethodPopup.cpp @@ -4,6 +4,8 @@ #include "../../protocols/FractionalScale.hpp" #include "../../protocols/InputMethodV2.hpp" #include "../../protocols/core/Compositor.hpp" +#include "../../helpers/Monitor.hpp" +#include "../../render/Renderer.hpp" CInputPopup::CInputPopup(SP popup_) : popup(popup_) { listeners.commit = popup_->events.commit.registerListener([this](std::any d) { onCommit(); }); diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 88439924..58cff043 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -5,6 +5,7 @@ #include "../../protocols/TextInputV1.hpp" #include "../../protocols/InputMethodV2.hpp" #include "../../protocols/core/Compositor.hpp" +#include "../../managers/HookSystemManager.hpp" CInputMethodRelay::CInputMethodRelay() { static auto P = diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 3e03c4c7..b5282e3c 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -1,6 +1,9 @@ #include "InputManager.hpp" #include "../../Compositor.hpp" +#include "../../desktop/LayerSurface.hpp" #include "../../config/ConfigValue.hpp" +#include "../../managers/HookSystemManager.hpp" +#include "../../render/Renderer.hpp" void CInputManager::onSwipeBegin(IPointer::SSwipeBeginEvent e) { static auto PSWIPE = CConfigValue("gestures:workspace_swipe"); diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index d7ebfe87..f61d8184 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -1,5 +1,5 @@ #include "InputManager.hpp" -#include "../../Compositor.hpp" +#include "../../desktop/Window.hpp" #include "../../protocols/Tablet.hpp" #include "../../devices/Tablet.hpp" #include "../../managers/PointerManager.hpp" diff --git a/src/managers/input/TextInput.hpp b/src/managers/input/TextInput.hpp index 3cf07006..c0b590ac 100644 --- a/src/managers/input/TextInput.hpp +++ b/src/managers/input/TextInput.hpp @@ -1,8 +1,8 @@ #pragma once -#include "../../macros.hpp" #include "../../helpers/math/Math.hpp" #include "../../helpers/signal/Signal.hpp" +#include "../../helpers/memory/Memory.hpp" #include struct wl_client; diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 7212ba61..990fbc41 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -1,9 +1,11 @@ #include "InputManager.hpp" #include "../../Compositor.hpp" +#include "../../desktop/LayerSurface.hpp" #include "../../config/ConfigValue.hpp" #include "../../devices/ITouch.hpp" #include "../SeatManager.hpp" #include "managers/AnimationManager.hpp" +#include "../HookSystemManager.hpp" void CInputManager::onTouchDown(ITouch::SDownEvent e) { m_bLastInputTouch = true; diff --git a/src/plugins/HookSystem.cpp b/src/plugins/HookSystem.cpp index 3baca5b1..c19f6f46 100644 --- a/src/plugins/HookSystem.cpp +++ b/src/plugins/HookSystem.cpp @@ -2,7 +2,7 @@ #include "../debug/Log.hpp" #include "../helpers/varlist/VarList.hpp" #include "../managers/TokenManager.hpp" -#include "../Compositor.hpp" +#include "../helpers/MiscFunctions.hpp" #define register #include @@ -383,4 +383,4 @@ uint64_t CHookSystem::getAddressForTrampo() { Debug::log(LOG, "getAddressForTrampo: Returning addr 0x{:x} for page at 0x{:x}", ADDRFORCONSUMER, page->addr); return ADDRFORCONSUMER; -} \ No newline at end of file +} diff --git a/src/plugins/PluginAPI.cpp b/src/plugins/PluginAPI.cpp index 5e1d9e58..b6bbc460 100644 --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -1,6 +1,11 @@ #include "PluginAPI.hpp" #include "../Compositor.hpp" #include "../debug/HyprCtl.hpp" +#include "../plugins/PluginSystem.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../config/ConfigManager.hpp" +#include "../debug/HyprNotificationOverlay.hpp" #include #include diff --git a/src/plugins/PluginSystem.cpp b/src/plugins/PluginSystem.cpp index 52a3bace..ce7dd7c7 100644 --- a/src/plugins/PluginSystem.cpp +++ b/src/plugins/PluginSystem.cpp @@ -2,7 +2,9 @@ #include #include -#include "../Compositor.hpp" +#include "../config/ConfigManager.hpp" +#include "../managers/LayoutManager.hpp" +#include "../managers/HookSystemManager.hpp" CPluginSystem::CPluginSystem() { g_pFunctionHookSystem = std::make_unique(); diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index fd7cdcd6..91e05ac4 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -4,6 +4,7 @@ #include "core/Output.hpp" #include "../config/ConfigValue.hpp" #include "managers/AnimationManager.hpp" +#include "../helpers/Monitor.hpp" CHyprlandCTMControlResource::CHyprlandCTMControlResource(SP resource_) : resource(resource_) { if (!good()) diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp index be5a6985..4ab46a46 100644 --- a/src/protocols/DRMLease.cpp +++ b/src/protocols/DRMLease.cpp @@ -1,5 +1,6 @@ #include "DRMLease.hpp" #include "../Compositor.hpp" +#include "../helpers/Monitor.hpp" #include "managers/eventLoop/EventLoopManager.hpp" #include #include diff --git a/src/protocols/ForeignToplevel.cpp b/src/protocols/ForeignToplevel.cpp index 38bb5e69..f6513a1d 100644 --- a/src/protocols/ForeignToplevel.cpp +++ b/src/protocols/ForeignToplevel.cpp @@ -1,5 +1,6 @@ #include "ForeignToplevel.hpp" #include "../Compositor.hpp" +#include "../managers/HookSystemManager.hpp" CForeignToplevelHandle::CForeignToplevelHandle(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { if (!resource_->resource()) diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp index 6bbd377c..45ef3f93 100644 --- a/src/protocols/ForeignToplevelWlr.cpp +++ b/src/protocols/ForeignToplevelWlr.cpp @@ -3,6 +3,7 @@ #include "../Compositor.hpp" #include "protocols/core/Output.hpp" #include "render/Renderer.hpp" +#include "../managers/HookSystemManager.hpp" CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { if (!resource_->resource()) diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp index 14c6596f..b0da29a2 100644 --- a/src/protocols/GammaControl.cpp +++ b/src/protocols/GammaControl.cpp @@ -2,8 +2,8 @@ #include #include #include "../helpers/Monitor.hpp" -#include "../Compositor.hpp" #include "../protocols/core/Output.hpp" +#include "../render/Renderer.hpp" CGammaControl::CGammaControl(SP resource_, wl_resource* output) : resource(resource_) { if (!resource_->resource()) diff --git a/src/protocols/GlobalShortcuts.cpp b/src/protocols/GlobalShortcuts.cpp index b02126ef..ca67f063 100644 --- a/src/protocols/GlobalShortcuts.cpp +++ b/src/protocols/GlobalShortcuts.cpp @@ -1,5 +1,4 @@ #include "GlobalShortcuts.hpp" -#include "../Compositor.hpp" CShortcutClient::CShortcutClient(SP resource_) : resource(resource_) { if (!good()) diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp index 5ceae5f2..0777149f 100644 --- a/src/protocols/LayerShell.cpp +++ b/src/protocols/LayerShell.cpp @@ -1,8 +1,10 @@ #include "LayerShell.hpp" #include "../Compositor.hpp" +#include "../desktop/LayerSurface.hpp" #include "XDGShell.hpp" #include "core/Compositor.hpp" #include "core/Output.hpp" +#include "../helpers/Monitor.hpp" void CLayerShellResource::SState::reset() { anchor = 0; diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp index b4efd2c8..41536988 100644 --- a/src/protocols/MesaDRM.cpp +++ b/src/protocols/MesaDRM.cpp @@ -3,6 +3,7 @@ #include #include "../Compositor.hpp" #include "types/WLBuffer.hpp" +#include "../render/OpenGL.hpp" CMesaDRMBufferResource::CMesaDRMBufferResource(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs attrs_) { LOGM(LOG, "Creating a Mesa dmabuf, with id {}: size {}, fmt {}, planes {}", id, attrs_.size, attrs_.format, attrs_.planes); diff --git a/src/protocols/OutputManagement.cpp b/src/protocols/OutputManagement.cpp index 4f7d48c4..4a976021 100644 --- a/src/protocols/OutputManagement.cpp +++ b/src/protocols/OutputManagement.cpp @@ -1,6 +1,9 @@ #include "OutputManagement.hpp" #include #include "../Compositor.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../config/ConfigManager.hpp" using namespace Aquamarine; diff --git a/src/protocols/OutputPower.cpp b/src/protocols/OutputPower.cpp index 257155e4..dd3e8e1a 100644 --- a/src/protocols/OutputPower.cpp +++ b/src/protocols/OutputPower.cpp @@ -1,6 +1,6 @@ #include "OutputPower.hpp" -#include "../Compositor.hpp" #include "core/Output.hpp" +#include "../helpers/Monitor.hpp" COutputPower::COutputPower(SP resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) { if (!resource->resource()) diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp index 0a787414..e12fa75f 100644 --- a/src/protocols/PointerConstraints.cpp +++ b/src/protocols/PointerConstraints.cpp @@ -4,6 +4,9 @@ #include "../config/ConfigValue.hpp" #include "../managers/SeatManager.hpp" #include "core/Compositor.hpp" +#include "../managers/input/InputManager.hpp" +#include "../render/Renderer.hpp" +#include "../helpers/Monitor.hpp" CPointerConstraint::CPointerConstraint(SP resource_, SP surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) : resourceL(resource_), locked(true), lifetime(lifetime_) { diff --git a/src/protocols/PointerGestures.cpp b/src/protocols/PointerGestures.cpp index 4eb74102..5dfb9d51 100644 --- a/src/protocols/PointerGestures.cpp +++ b/src/protocols/PointerGestures.cpp @@ -1,5 +1,4 @@ #include "PointerGestures.hpp" -#include "../Compositor.hpp" #include "../managers/SeatManager.hpp" #include "core/Seat.hpp" #include "core/Compositor.hpp" diff --git a/src/protocols/RelativePointer.cpp b/src/protocols/RelativePointer.cpp index 16248c02..b7cf75c6 100644 --- a/src/protocols/RelativePointer.cpp +++ b/src/protocols/RelativePointer.cpp @@ -1,5 +1,4 @@ #include "RelativePointer.hpp" -#include "../Compositor.hpp" #include "../managers/SeatManager.hpp" #include "core/Seat.hpp" #include @@ -71,4 +70,4 @@ void CRelativePointerProtocol::sendRelativeMotion(uint64_t time, const Vector2D& rp->sendRelativeMotion(time, delta, deltaUnaccel); } -} \ No newline at end of file +} diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 898a1d6b..da0a9412 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -2,6 +2,10 @@ #include "../Compositor.hpp" #include "../managers/eventLoop/EventLoopManager.hpp" #include "../managers/PointerManager.hpp" +#include "../managers/EventManager.hpp" +#include "../render/Renderer.hpp" +#include "../render/OpenGL.hpp" +#include "../helpers/Monitor.hpp" #include "core/Output.hpp" #include "types/WLBuffer.hpp" #include "types/Buffer.hpp" diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp index 642a5b89..c3f19e53 100644 --- a/src/protocols/SessionLock.cpp +++ b/src/protocols/SessionLock.cpp @@ -4,6 +4,7 @@ #include "FractionalScale.hpp" #include "core/Compositor.hpp" #include "core/Output.hpp" +#include "../helpers/Monitor.hpp" CSessionLockSurface::CSessionLockSurface(SP resource_, SP surface_, PHLMONITOR pMonitor_, WP owner_) : resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) { @@ -208,4 +209,4 @@ void CSessionLockProtocol::onGetLockSurface(CExtSessionLockV1* lock, uint32_t id bool CSessionLockProtocol::isLocked() { return locked; -} \ No newline at end of file +} diff --git a/src/protocols/SinglePixel.cpp b/src/protocols/SinglePixel.cpp index 41771ce2..91154671 100644 --- a/src/protocols/SinglePixel.cpp +++ b/src/protocols/SinglePixel.cpp @@ -1,4 +1,5 @@ #include "SinglePixel.hpp" +#include "../desktop/LayerSurface.hpp" #include #include "render/Renderer.hpp" diff --git a/src/protocols/Tablet.cpp b/src/protocols/Tablet.cpp index b4ab6ea0..2fdd8731 100644 --- a/src/protocols/Tablet.cpp +++ b/src/protocols/Tablet.cpp @@ -2,6 +2,7 @@ #include "../devices/Tablet.hpp" #include "../Compositor.hpp" #include "../managers/SeatManager.hpp" +#include "../managers/input/InputManager.hpp" #include "core/Seat.hpp" #include "core/Compositor.hpp" #include diff --git a/src/protocols/TearingControl.cpp b/src/protocols/TearingControl.cpp index 66a4efd2..eb1a53cb 100644 --- a/src/protocols/TearingControl.cpp +++ b/src/protocols/TearingControl.cpp @@ -3,6 +3,7 @@ #include "../desktop/Window.hpp" #include "../Compositor.hpp" #include "core/Compositor.hpp" +#include "../managers/HookSystemManager.hpp" CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { static auto P = diff --git a/src/protocols/TextInputV1.cpp b/src/protocols/TextInputV1.cpp index 6395e158..b8eb5835 100644 --- a/src/protocols/TextInputV1.cpp +++ b/src/protocols/TextInputV1.cpp @@ -1,6 +1,5 @@ #include "TextInputV1.hpp" -#include "../Compositor.hpp" #include "core/Compositor.hpp" CTextInputV1::~CTextInputV1() { diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 73e5cad9..8e34cf4b 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -6,6 +6,9 @@ #include "types/WLBuffer.hpp" #include "types/Buffer.hpp" #include "../helpers/Format.hpp" +#include "../managers/EventManager.hpp" +#include "../managers/input/InputManager.hpp" +#include "../render/Renderer.hpp" #include diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp index deb87829..fadc48a1 100644 --- a/src/protocols/XDGOutput.cpp +++ b/src/protocols/XDGOutput.cpp @@ -1,7 +1,7 @@ #include "XDGOutput.hpp" -#include "../Compositor.hpp" #include "../config/ConfigValue.hpp" #include "../xwayland/XWayland.hpp" +#include "../managers/HookSystemManager.hpp" #include "core/Output.hpp" #define OUTPUT_MANAGER_VERSION 3 @@ -119,4 +119,4 @@ void CXDGOutput::sendDetails() { if (resource->version() < OUTPUT_DONE_DEPRECATED_SINCE_VERSION) resource->sendDone(); -} \ No newline at end of file +} diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 6b7cb3c1..aabb225a 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -3,6 +3,7 @@ #include #include "../Compositor.hpp" #include "../managers/SeatManager.hpp" +#include "../helpers/Monitor.hpp" #include "core/Seat.hpp" #include "core/Compositor.hpp" #include "protocols/core/Output.hpp" diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 722eb9fd..fd3cd1fa 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -9,6 +9,10 @@ #include "Compositor.hpp" #include "../../xwayland/XWayland.hpp" #include "../../xwayland/Server.hpp" +#include "../../managers/input/InputManager.hpp" +#include "../../managers/HookSystemManager.hpp" +#include "../../helpers/Monitor.hpp" +#include "../../render/Renderer.hpp" CWLDataOfferResource::CWLDataOfferResource(SP resource_, SP source_) : source(source_), resource(resource_) { if (!good()) diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp index fddd4e9a..6365c5d6 100644 --- a/src/protocols/core/Shm.cpp +++ b/src/protocols/core/Shm.cpp @@ -5,8 +5,8 @@ #include #include "../../render/Texture.hpp" #include "../types/WLBuffer.hpp" -#include "../../Compositor.hpp" #include "../../helpers/Format.hpp" +#include "../../render/Renderer.hpp" CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t offset_, const Vector2D& size_, int32_t stride_, uint32_t fmt_) { if (!pool_->pool->data) diff --git a/src/protocols/types/DMABuffer.cpp b/src/protocols/types/DMABuffer.cpp index ae684424..9f31f6a2 100644 --- a/src/protocols/types/DMABuffer.cpp +++ b/src/protocols/types/DMABuffer.cpp @@ -1,5 +1,6 @@ #include "DMABuffer.hpp" #include "WLBuffer.hpp" +#include "../../desktop/LayerSurface.hpp" #include "../../render/Renderer.hpp" #include "../../helpers/Format.hpp" diff --git a/src/protocols/types/WLBuffer.cpp b/src/protocols/types/WLBuffer.cpp index eb7d1fde..a9e6400a 100644 --- a/src/protocols/types/WLBuffer.cpp +++ b/src/protocols/types/WLBuffer.cpp @@ -3,7 +3,6 @@ #include "../core/Compositor.hpp" #include "../DRMSyncobj.hpp" #include "../../helpers/sync/SyncTimeline.hpp" -#include "../../Compositor.hpp" #include CWLBufferResource::CWLBufferResource(SP resource_) : resource(resource_) { diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index b68448ae..c5bb3620 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2,12 +2,15 @@ #include #include "Shaders.hpp" #include "OpenGL.hpp" +#include "Renderer.hpp" #include "../Compositor.hpp" #include "../helpers/MiscFunctions.hpp" #include "../config/ConfigValue.hpp" #include "../desktop/LayerSurface.hpp" #include "../protocols/LayerShell.hpp" #include "../protocols/core/Compositor.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../managers/input/InputManager.hpp" #include "pass/TexPassElement.hpp" #include "pass/RectPassElement.hpp" #include "pass/PreBlurElement.hpp" diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 2b600a03..8098485e 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -17,7 +17,6 @@ #include "Shader.hpp" #include "Texture.hpp" #include "Framebuffer.hpp" -#include "Transformer.hpp" #include "Renderbuffer.hpp" #include "pass/Pass.hpp" diff --git a/src/render/Renderbuffer.cpp b/src/render/Renderbuffer.cpp index c4425ce9..887f31a9 100644 --- a/src/render/Renderbuffer.cpp +++ b/src/render/Renderbuffer.cpp @@ -1,4 +1,5 @@ #include "Renderbuffer.hpp" +#include "Renderer.hpp" #include "OpenGL.hpp" #include "../Compositor.hpp" #include "../protocols/types/Buffer.hpp" @@ -76,4 +77,4 @@ void CRenderbuffer::unbind() { CFramebuffer* CRenderbuffer::getFB() { return &m_sFramebuffer; -} \ No newline at end of file +} diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 6c77b27a..fddb9a9a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -8,6 +8,10 @@ #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" #include "../managers/PointerManager.hpp" +#include "../managers/input/InputManager.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../managers/AnimationManager.hpp" +#include "../managers/LayoutManager.hpp" #include "../desktop/Window.hpp" #include "../desktop/LayerSurface.hpp" #include "../protocols/SessionLock.hpp" @@ -19,6 +23,9 @@ #include "../protocols/DRMSyncobj.hpp" #include "../protocols/LinuxDMABUF.hpp" #include "../helpers/sync/SyncTimeline.hpp" +#include "../hyprerror/HyprError.hpp" +#include "../debug/HyprDebugOverlay.hpp" +#include "../debug/HyprNotificationOverlay.hpp" #include "pass/TexPassElement.hpp" #include "pass/ClearPassElement.hpp" #include "pass/RectPassElement.hpp" diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 8b4988c3..6ba7a654 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -3,6 +3,7 @@ #include "../defines.hpp" #include #include "../helpers/Monitor.hpp" +#include "../desktop/LayerSurface.hpp" #include "OpenGL.hpp" #include "Renderbuffer.hpp" #include "../helpers/Timer.hpp" diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 7261431f..6fb0ff88 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -3,6 +3,8 @@ #include "../../config/ConfigValue.hpp" #include "../../managers/eventLoop/EventLoopManager.hpp" #include "../pass/BorderPassElement.hpp" +#include "../Renderer.hpp" +#include "../../managers/HookSystemManager.hpp" CHyprBorderDecoration::CHyprBorderDecoration(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow), m_pWindow(pWindow) { ; diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index ddd5198d..022e123e 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -3,6 +3,7 @@ #include "../../Compositor.hpp" #include "../../config/ConfigValue.hpp" #include "../pass/ShadowPassElement.hpp" +#include "../Renderer.hpp" CHyprDropShadowDecoration::CHyprDropShadowDecoration(PHLWINDOW pWindow) : IHyprWindowDecoration(pWindow), m_pWindow(pWindow) { ; diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 970273d7..4a411b6c 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -6,6 +6,8 @@ #include #include "../pass/TexPassElement.hpp" #include "../pass/RectPassElement.hpp" +#include "../Renderer.hpp" +#include "../../managers/input/InputManager.hpp" // shared things to conserve VRAM static SP m_tGradientActive = makeShared(); diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index abfa19ec..c2d34fb6 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -1,5 +1,7 @@ #include "DecorationPositioner.hpp" -#include "../../Compositor.hpp" +#include "../../desktop/Window.hpp" +#include "../../managers/HookSystemManager.hpp" +#include "../../managers/LayoutManager.hpp" CDecorationPositioner::CDecorationPositioner() { static auto P = g_pHookSystem->hookDynamic("closeWindow", [this](void* call, SCallbackInfo& info, std::any data) { diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index b72248c2..5b133b7d 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -6,6 +6,7 @@ #include "../../desktop/WLSurface.hpp" #include "../../managers/SeatManager.hpp" #include "../../managers/eventLoop/EventLoopManager.hpp" +#include "../../render/Renderer.hpp" #include "../../Compositor.hpp" bool CRenderPass::empty() const { diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index 71aa26be..d720081f 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -1,6 +1,7 @@ #include "SurfacePassElement.hpp" #include "../OpenGL.hpp" #include "../../desktop/WLSurface.hpp" +#include "../../desktop/Window.hpp" #include "../../protocols/core/Compositor.hpp" #include "../../protocols/DRMSyncobj.hpp" #include "../../managers/input/InputManager.hpp" diff --git a/src/xwayland/XSurface.cpp b/src/xwayland/XSurface.cpp index 6048269a..b5ee75f6 100644 --- a/src/xwayland/XSurface.cpp +++ b/src/xwayland/XSurface.cpp @@ -6,7 +6,6 @@ #ifndef NO_XWAYLAND #include -#include "../Compositor.hpp" CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : xID(xID_), geometry(geometry_), overrideRedirect(OR) { xcb_res_query_client_ids_cookie_t client_id_cookie = {0}; diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index 38fdab94..bc5aa47b 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -1,6 +1,5 @@ #pragma once -#include "../macros.hpp" #include "XDataSource.hpp" #include "Dnd.hpp" #include "../helpers/memory/Memory.hpp" From b7a3c4526990d6601ff2cac748ff860cda6bc16d Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 17 Jan 2025 18:21:34 +0100 Subject: [PATCH 0121/1444] core: add LIKELY and UNLIKELY macros helps the compiler optimize --- src/devices/VirtualPointer.cpp | 2 +- src/macros.hpp | 3 ++ src/protocols/AlphaModifier.cpp | 4 +- src/protocols/CTMControl.cpp | 8 +-- src/protocols/ColorManagement.cpp | 32 ++++++------ src/protocols/CursorShape.cpp | 2 +- src/protocols/DRMLease.cpp | 16 +++--- src/protocols/DRMSyncobj.cpp | 18 +++---- src/protocols/DataDeviceWlr.cpp | 16 +++--- src/protocols/FocusGrab.cpp | 14 +++--- src/protocols/ForeignToplevel.cpp | 20 ++++---- src/protocols/ForeignToplevelWlr.cpp | 70 +++++++++++++-------------- src/protocols/FractionalScale.cpp | 2 +- src/protocols/FrogColorManagement.cpp | 10 ++-- src/protocols/GammaControl.cpp | 20 ++++---- src/protocols/GlobalShortcuts.cpp | 8 +-- src/protocols/HyprlandSurface.cpp | 8 +-- src/protocols/IdleNotify.cpp | 4 +- src/protocols/InputMethodV2.cpp | 16 +++--- src/protocols/LayerShell.cpp | 8 +-- src/protocols/LinuxDMABUF.cpp | 26 +++++----- src/protocols/MesaDRM.cpp | 6 +-- src/protocols/OutputManagement.cpp | 22 ++++----- src/protocols/OutputPower.cpp | 6 +-- src/protocols/PointerConstraints.cpp | 12 ++--- src/protocols/PointerGestures.cpp | 12 ++--- src/protocols/PresentationTime.cpp | 8 +-- src/protocols/PrimarySelection.cpp | 16 +++--- src/protocols/RelativePointer.cpp | 4 +- src/protocols/Screencopy.cpp | 17 +++---- src/protocols/SecurityContext.cpp | 26 +++++----- src/protocols/ServerDecorationKDE.cpp | 4 +- src/protocols/SessionLock.cpp | 8 +-- src/protocols/ShortcutsInhibit.cpp | 6 +-- src/protocols/SinglePixel.cpp | 8 +-- src/protocols/Tablet.cpp | 28 +++++------ src/protocols/TearingControl.cpp | 4 +- src/protocols/TextInputV1.cpp | 6 +-- src/protocols/TextInputV3.cpp | 4 +- src/protocols/ToplevelExport.cpp | 29 ++++++----- src/protocols/Viewporter.cpp | 16 +++--- src/protocols/VirtualKeyboard.cpp | 14 +++--- src/protocols/VirtualPointer.cpp | 10 ++-- src/protocols/WaylandProtocol.cpp | 2 +- src/protocols/XDGActivation.cpp | 12 ++--- src/protocols/XDGDecoration.cpp | 6 +-- src/protocols/XDGDialog.cpp | 14 +++--- src/protocols/XDGOutput.cpp | 10 ++-- src/protocols/XDGShell.cpp | 34 ++++++------- src/protocols/XWaylandShell.cpp | 8 +-- src/protocols/core/Compositor.cpp | 34 ++++++------- src/protocols/core/DataDevice.cpp | 18 +++---- src/protocols/core/Output.cpp | 10 ++-- src/protocols/core/Seat.cpp | 16 +++--- src/protocols/core/Shm.cpp | 32 ++++++------ src/protocols/core/Subcompositor.cpp | 14 +++--- src/protocols/types/DMABuffer.cpp | 6 +-- src/protocols/types/WLBuffer.cpp | 2 +- 58 files changed, 395 insertions(+), 396 deletions(-) diff --git a/src/devices/VirtualPointer.cpp b/src/devices/VirtualPointer.cpp index 514c8c32..7cfb0631 100644 --- a/src/devices/VirtualPointer.cpp +++ b/src/devices/VirtualPointer.cpp @@ -11,7 +11,7 @@ SP CVirtualPointer::create(SP resour } CVirtualPointer::CVirtualPointer(SP resource) : pointer(resource) { - if (!resource->good()) + if UNLIKELY (!resource->good()) return; listeners.destroy = pointer->events.destroy.registerListener([this](std::any d) { diff --git a/src/macros.hpp b/src/macros.hpp index 08c17952..0a3be8bc 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -114,3 +114,6 @@ namespace Aquamarine { \ class name; \ } + +#define UNLIKELY(expr) (expr) [[unlikely]] +#define LIKELY(expr) (expr) [[likely]] diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp index d695b58f..dc32bb8c 100644 --- a/src/protocols/AlphaModifier.cpp +++ b/src/protocols/AlphaModifier.cpp @@ -15,7 +15,7 @@ bool CAlphaModifier::good() { void CAlphaModifier::setResource(SP resource) { m_pResource = std::move(resource); - if (!m_pResource->resource()) + if UNLIKELY (!m_pResource->resource()) return; m_pResource->setDestroy([this](CWpAlphaModifierSurfaceV1* resource) { destroy(); }); @@ -98,7 +98,7 @@ void CAlphaModifierProtocol::getSurface(CWpAlphaModifierV1* manager, uint32_t id .first->second.get(); } - if (!alphaModifier->good()) { + if UNLIKELY (!alphaModifier->good()) { manager->noMemory(); m_mAlphaModifiers.erase(surface); } diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index 91e05ac4..91f4501f 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -7,7 +7,7 @@ #include "../helpers/Monitor.hpp" CHyprlandCTMControlResource::CHyprlandCTMControlResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CHyprlandCtmControlManagerV1* pMgr) { PROTO::ctm->destroyResource(this); }); @@ -17,12 +17,12 @@ CHyprlandCTMControlResource::CHyprlandCTMControlResource(SPmonitor.lock(); - if (!PMONITOR) + if UNLIKELY (!PMONITOR) return; // ?!?! const std::array MAT = {wl_fixed_to_double(mat0), wl_fixed_to_double(mat1), wl_fixed_to_double(mat2), wl_fixed_to_double(mat3), wl_fixed_to_double(mat4), @@ -72,7 +72,7 @@ void CHyprlandCTMControlProtocol::bindManager(wl_client* client, void* data, uin const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/ColorManagement.cpp b/src/protocols/ColorManagement.cpp index a76e13c0..c2814361 100644 --- a/src/protocols/ColorManagement.cpp +++ b/src/protocols/ColorManagement.cpp @@ -2,7 +2,7 @@ #include "Compositor.hpp" CColorManager::CColorManager(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_PARAMETRIC); @@ -38,7 +38,7 @@ CColorManager::CColorManager(SP resource_) : resource(resourc const auto RESOURCE = PROTO::colorManagement->m_vOutputs.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vOutputs.pop_back(); return; @@ -63,7 +63,7 @@ CColorManager::CColorManager(SP resource_) : resource(resourc const auto RESOURCE = PROTO::colorManagement->m_vSurfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id), SURF)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vSurfaces.pop_back(); return; @@ -86,7 +86,7 @@ CColorManager::CColorManager(SP resource_) : resource(resourc const auto RESOURCE = PROTO::colorManagement->m_vFeedbackSurfaces.emplace_back( makeShared(makeShared(r->client(), r->version(), id), SURF)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vFeedbackSurfaces.pop_back(); return; @@ -104,7 +104,7 @@ CColorManager::CColorManager(SP resource_) : resource(resourc const auto RESOURCE = PROTO::colorManagement->m_vParametricCreators.emplace_back( makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vParametricCreators.pop_back(); return; @@ -121,7 +121,7 @@ bool CColorManager::good() { } CColorManagementOutput::CColorManagementOutput(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); @@ -137,7 +137,7 @@ CColorManagementOutput::CColorManagementOutput(SP re const auto RESOURCE = PROTO::colorManagement->m_vImageDescriptions.emplace_back( makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vImageDescriptions.pop_back(); return; @@ -160,7 +160,7 @@ CColorManagementSurface::CColorManagementSurface(SP surface_ } CColorManagementSurface::CColorManagementSurface(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); @@ -242,7 +242,7 @@ bool CColorManagementSurface::needsHdrMetadataUpdate() { CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); @@ -269,7 +269,7 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SPm_vImageDescriptions.emplace_back( makeShared(makeShared(r->client(), r->version(), id), true)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vImageDescriptions.pop_back(); return; @@ -293,7 +293,7 @@ wl_client* CColorManagementFeedbackSurface::client() { } CColorManagementParametricCreator::CColorManagementParametricCreator(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; // pClient = resource->client(); @@ -318,7 +318,7 @@ CColorManagementParametricCreator::CColorManagementParametricCreator(SPm_vImageDescriptions.emplace_back( makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::colorManagement->m_vImageDescriptions.pop_back(); return; @@ -465,7 +465,7 @@ wl_client* CColorManagementParametricCreator::client() { CColorManagementImageDescription::CColorManagementImageDescription(SP resource_, bool allowGetInformation) : m_resource(resource_), m_allowGetInformation(allowGetInformation) { - if (!good()) + if UNLIKELY (!good()) return; pClient = m_resource->client(); @@ -482,7 +482,7 @@ CColorManagementImageDescription::CColorManagementImageDescription(SP(makeShared(r->client(), r->version(), id), settings); - if (!RESOURCE->good()) + if UNLIKELY (!RESOURCE->good()) r->noMemory(); // CColorManagementImageDescriptionInfo should send everything in the constructor and be ready for destroying at this point @@ -504,7 +504,7 @@ SP CColorManagementImageDescription::resource() { CColorManagementImageDescriptionInfo::CColorManagementImageDescriptionInfo(SP resource_, const SImageDescription& settings_) : m_resource(resource_), settings(settings_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = m_resource->client(); @@ -549,7 +549,7 @@ CColorManagementProtocol::CColorManagementProtocol(const wl_interface* iface, co void CColorManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/CursorShape.cpp b/src/protocols/CursorShape.cpp index 233a5df9..429d604f 100644 --- a/src/protocols/CursorShape.cpp +++ b/src/protocols/CursorShape.cpp @@ -41,7 +41,7 @@ void CCursorShapeProtocol::createCursorShapeDevice(CWpCursorShapeManagerV1* pMgr } void CCursorShapeProtocol::onSetShape(CWpCursorShapeDeviceV1* pMgr, uint32_t serial, wpCursorShapeDeviceV1Shape shape) { - if ((uint32_t)shape == 0 || (uint32_t)shape > CURSOR_SHAPE_NAMES.size()) { + if UNLIKELY ((uint32_t)shape == 0 || (uint32_t)shape > CURSOR_SHAPE_NAMES.size()) { pMgr->error(WP_CURSOR_SHAPE_DEVICE_V1_ERROR_INVALID_SHAPE, "The shape is invalid"); return; } diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp index 4ab46a46..fce1e345 100644 --- a/src/protocols/DRMLease.cpp +++ b/src/protocols/DRMLease.cpp @@ -6,7 +6,7 @@ #include CDRMLeaseResource::CDRMLeaseResource(SP resource_, SP request) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWpDrmLeaseV1* r) { PROTO::lease->destroyResource(this); }); @@ -79,7 +79,7 @@ CDRMLeaseResource::~CDRMLeaseResource() { } CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWpDrmLeaseRequestV1* r) { PROTO::lease->destroyResource(this); }); @@ -109,7 +109,7 @@ CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP reso } auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id), self.lock()); - if (!RESOURCE) { + if UNLIKELY (!RESOURCE) { resource->noMemory(); return; } @@ -131,7 +131,7 @@ SP CDRMLeaseConnectorResource::fromResource(wl_resou } CDRMLeaseConnectorResource::CDRMLeaseConnectorResource(SP resource_, PHLMONITOR monitor_) : monitor(monitor_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWpDrmLeaseConnectorV1* r) { PROTO::lease->destroyResource(this); }); @@ -160,7 +160,7 @@ void CDRMLeaseConnectorResource::sendData() { } CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWpDrmLeaseDeviceV1* r) { PROTO::lease->destroyResource(this); }); @@ -168,7 +168,7 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP resourc resource->setCreateLeaseRequest([this](CWpDrmLeaseDeviceV1* r, uint32_t id) { auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id)); - if (!RESOURCE) { + if UNLIKELY (!RESOURCE) { resource->noMemory(); return; } @@ -209,7 +209,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) { return; auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), 0), monitor); - if (!RESOURCE) { + if UNLIKELY (!RESOURCE) { resource->noMemory(); return; } @@ -262,7 +262,7 @@ CDRMLeaseProtocol::CDRMLeaseProtocol(const wl_interface* iface, const int& ver, void CDRMLeaseProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp index 1da4baaf..ce598385 100644 --- a/src/protocols/DRMSyncobj.cpp +++ b/src/protocols/DRMSyncobj.cpp @@ -8,7 +8,7 @@ #include CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -104,7 +104,7 @@ bool CDRMSyncobjSurfaceResource::good() { } CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP resource_, int fd_) : fd(fd_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -135,31 +135,31 @@ bool CDRMSyncobjTimelineResource::good() { } CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWpLinuxDrmSyncobjManagerV1* r) { PROTO::sync->destroyResource(this); }); resource->setDestroy([this](CWpLinuxDrmSyncobjManagerV1* r) { PROTO::sync->destroyResource(this); }); resource->setGetSurface([this](CWpLinuxDrmSyncobjManagerV1* r, uint32_t id, wl_resource* surf) { - if (!surf) { + if UNLIKELY (!surf) { resource->error(-1, "Invalid surface"); return; } auto SURF = CWLSurfaceResource::fromResource(surf); - if (!SURF) { + if UNLIKELY (!SURF) { resource->error(-1, "Invalid surface (2)"); return; } - if (SURF->syncobj) { + if UNLIKELY (SURF->syncobj) { resource->error(WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_SURFACE_EXISTS, "Surface already has a syncobj attached"); return; } auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id), SURF); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); return; } @@ -172,7 +172,7 @@ CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(SPsetImportTimeline([this](CWpLinuxDrmSyncobjManagerV1* r, uint32_t id, int32_t fd) { auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id), fd); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); return; } @@ -195,7 +195,7 @@ CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& v void CDRMSyncobjProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/DataDeviceWlr.cpp b/src/protocols/DataDeviceWlr.cpp index d8103d11..71ee1c4a 100644 --- a/src/protocols/DataDeviceWlr.cpp +++ b/src/protocols/DataDeviceWlr.cpp @@ -4,7 +4,7 @@ #include "core/Seat.hpp" CWLRDataOffer::CWLRDataOffer(SP resource_, SP source_) : source(source_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwlrDataControlOfferV1* r) { PROTO::dataWlr->destroyResource(this); }); @@ -34,7 +34,7 @@ bool CWLRDataOffer::good() { } void CWLRDataOffer::sendData() { - if (!source) + if UNLIKELY (!source) return; for (auto const& m : source->mimes()) { @@ -43,7 +43,7 @@ void CWLRDataOffer::sendData() { } CWLRDataSource::CWLRDataSource(SP resource_, SP device_) : device(device_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -104,7 +104,7 @@ void CWLRDataSource::error(uint32_t code, const std::string& msg) { } CWLRDataDevice::CWLRDataDevice(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); @@ -173,7 +173,7 @@ void CWLRDataDevice::sendPrimarySelection(SP selection) { } CWLRDataControlManagerResource::CWLRDataControlManagerResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwlrDataControlManagerV1* r) { PROTO::dataWlr->destroyResource(this); }); @@ -182,7 +182,7 @@ CWLRDataControlManagerResource::CWLRDataControlManagerResource(SPsetGetDataDevice([this](CZwlrDataControlManagerV1* r, uint32_t id, wl_resource* seat) { const auto RESOURCE = PROTO::dataWlr->m_vDevices.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::dataWlr->m_vDevices.pop_back(); return; @@ -208,7 +208,7 @@ CWLRDataControlManagerResource::CWLRDataControlManagerResource(SPm_vSources.emplace_back(makeShared(makeShared(r->client(), r->version(), id), device.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::dataWlr->m_vSources.pop_back(); return; @@ -236,7 +236,7 @@ CDataDeviceWLRProtocol::CDataDeviceWLRProtocol(const wl_interface* iface, const void CDataDeviceWLRProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp index aff232e4..ee30343f 100644 --- a/src/protocols/FocusGrab.cpp +++ b/src/protocols/FocusGrab.cpp @@ -17,7 +17,7 @@ CFocusGrabSurfaceState::~CFocusGrabSurfaceState() { } CFocusGrab::CFocusGrab(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; grab = makeShared(); @@ -63,9 +63,8 @@ void CFocusGrab::finish(bool sendCleared) { if (m_bGrabActive) { m_bGrabActive = false; - if (g_pSeatManager->seatGrab == grab) { + if (g_pSeatManager->seatGrab == grab) g_pSeatManager->setGrab(nullptr); - } grab->clear(); m_mSurfaces.clear(); @@ -77,17 +76,16 @@ void CFocusGrab::finish(bool sendCleared) { void CFocusGrab::addSurface(SP surface) { auto iter = std::find_if(m_mSurfaces.begin(), m_mSurfaces.end(), [surface](const auto& e) { return e.first == surface; }); - if (iter == m_mSurfaces.end()) { + if (iter == m_mSurfaces.end()) m_mSurfaces.emplace(surface, std::make_unique(this, surface)); - } } void CFocusGrab::removeSurface(SP surface) { auto iter = m_mSurfaces.find(surface); if (iter != m_mSurfaces.end()) { - if (iter->second->state == CFocusGrabSurfaceState::PendingAddition) { + if (iter->second->state == CFocusGrabSurfaceState::PendingAddition) m_mSurfaces.erase(iter); - } else + else iter->second->state = CFocusGrabSurfaceState::PendingRemoval; } } @@ -172,7 +170,7 @@ void CFocusGrabProtocol::onCreateGrab(CHyprlandFocusGrabManagerV1* pMgr, uint32_ m_vGrabs.push_back(std::make_unique(makeShared(pMgr->client(), pMgr->version(), id))); const auto RESOURCE = m_vGrabs.back().get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vGrabs.pop_back(); } diff --git a/src/protocols/ForeignToplevel.cpp b/src/protocols/ForeignToplevel.cpp index f6513a1d..6880164f 100644 --- a/src/protocols/ForeignToplevel.cpp +++ b/src/protocols/ForeignToplevel.cpp @@ -3,7 +3,7 @@ #include "../managers/HookSystemManager.hpp" CForeignToplevelHandle::CForeignToplevelHandle(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource->setOnDestroy([this](CExtForeignToplevelHandleV1* h) { PROTO::foreignToplevel->destroyHandle(this); }); @@ -19,7 +19,7 @@ PHLWINDOW CForeignToplevelHandle::window() { } CForeignToplevelList::CForeignToplevelList(SP resource_) : resource(resource_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource->setOnDestroy([this](CExtForeignToplevelListV1* h) { PROTO::foreignToplevel->onManagerResourceDestroy(this); }); @@ -40,7 +40,7 @@ CForeignToplevelList::CForeignToplevelList(SP resourc } void CForeignToplevelList::onMap(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto NEWHANDLE = PROTO::foreignToplevel->m_vHandles.emplace_back( @@ -72,11 +72,11 @@ SP CForeignToplevelList::handleForWindow(PHLWINDOW pWind } void CForeignToplevelList::onTitle(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; H->resource->sendTitle(pWindow->m_szTitle.c_str()); @@ -84,11 +84,11 @@ void CForeignToplevelList::onTitle(PHLWINDOW pWindow) { } void CForeignToplevelList::onClass(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; H->resource->sendAppId(pWindow->m_szClass.c_str()); @@ -96,11 +96,11 @@ void CForeignToplevelList::onClass(PHLWINDOW pWindow) { } void CForeignToplevelList::onUnmap(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H) + if UNLIKELY (!H) return; H->resource->sendClosed(); @@ -149,7 +149,7 @@ CForeignToplevelProtocol::CForeignToplevelProtocol(const wl_interface* iface, co void CForeignToplevelProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(makeShared(client, ver, id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { LOGM(ERR, "Couldn't create a foreign list"); wl_client_post_no_memory(client); m_vManagers.pop_back(); diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp index 45ef3f93..e18f6e23 100644 --- a/src/protocols/ForeignToplevelWlr.cpp +++ b/src/protocols/ForeignToplevelWlr.cpp @@ -6,7 +6,7 @@ #include "../managers/HookSystemManager.hpp" CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP resource_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource->setOnDestroy([this](CZwlrForeignToplevelHandleV1* h) { PROTO::foreignToplevelWlr->destroyHandle(this); }); @@ -15,7 +15,7 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SPsetActivate([this](CZwlrForeignToplevelHandleV1* p, wl_resource* seat) { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW) + if UNLIKELY (!PWINDOW) return; // these requests bypass the config'd stuff cuz it's usually like @@ -26,13 +26,13 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SPsetSetFullscreen([this](CZwlrForeignToplevelHandleV1* p, wl_resource* output) { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW) + if UNLIKELY (!PWINDOW) return; - if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN) + if UNLIKELY (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN) return; - if (!PWINDOW->m_bIsMapped) { + if UNLIKELY (!PWINDOW->m_bIsMapped) { PWINDOW->m_bWantsInitialFullscreen = true; return; } @@ -57,10 +57,10 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SPsetUnsetFullscreen([this](CZwlrForeignToplevelHandleV1* p) { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW) + if UNLIKELY (!PWINDOW) return; - if (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN) + if UNLIKELY (PWINDOW->m_eSuppressedEvents & SUPPRESS_FULLSCREEN) return; g_pCompositor->changeWindowFullscreenModeClient(PWINDOW, FSMODE_FULLSCREEN, false); @@ -69,13 +69,13 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SPsetSetMaximized([this](CZwlrForeignToplevelHandleV1* p) { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW) + if UNLIKELY (!PWINDOW) return; - if (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE) + if UNLIKELY (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE) return; - if (!PWINDOW->m_bIsMapped) { + if UNLIKELY (!PWINDOW->m_bIsMapped) { PWINDOW->m_bWantsInitialFullscreen = true; return; } @@ -86,10 +86,10 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SPsetUnsetMaximized([this](CZwlrForeignToplevelHandleV1* p) { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW) + if UNLIKELY (!PWINDOW) return; - if (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE) + if UNLIKELY (PWINDOW->m_eSuppressedEvents & SUPPRESS_MAXIMIZE) return; g_pCompositor->changeWindowFullscreenModeClient(PWINDOW, FSMODE_MAXIMIZED, false); @@ -98,7 +98,7 @@ CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SPsetClose([this](CZwlrForeignToplevelHandleV1* p) { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW) + if UNLIKELY (!PWINDOW) return; g_pCompositor->closeWindow(PWINDOW); @@ -126,14 +126,14 @@ void CForeignToplevelHandleWlr::sendMonitor(PHLMONITOR pMonitor) { if (const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(lastMonitorID); PLASTMONITOR && PROTO::outputs.contains(PLASTMONITOR->szName)) { const auto OLDRESOURCE = PROTO::outputs.at(PLASTMONITOR->szName)->outputResourceFrom(CLIENT); - if (OLDRESOURCE) + if LIKELY (OLDRESOURCE) resource->sendOutputLeave(OLDRESOURCE->getResource()->resource()); } if (PROTO::outputs.contains(pMonitor->szName)) { const auto NEWRESOURCE = PROTO::outputs.at(pMonitor->szName)->outputResourceFrom(CLIENT); - if (NEWRESOURCE) + if LIKELY (NEWRESOURCE) resource->sendOutputEnter(NEWRESOURCE->getResource()->resource()); } @@ -143,7 +143,7 @@ void CForeignToplevelHandleWlr::sendMonitor(PHLMONITOR pMonitor) { void CForeignToplevelHandleWlr::sendState() { const auto PWINDOW = pWindow.lock(); - if (!PWINDOW || !PWINDOW->m_pWorkspace || !PWINDOW->m_bIsMapped) + if UNLIKELY (!PWINDOW || !PWINDOW->m_pWorkspace || !PWINDOW->m_bIsMapped) return; wl_array state; @@ -168,7 +168,7 @@ void CForeignToplevelHandleWlr::sendState() { } CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP resource_) : resource(resource_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource->setOnDestroy([this](CZwlrForeignToplevelManagerV1* h) { PROTO::foreignToplevelWlr->onManagerResourceDestroy(this); }); @@ -191,13 +191,13 @@ CForeignToplevelWlrManager::CForeignToplevelWlrManager(SPm_vHandles.emplace_back( makeShared(makeShared(resource->client(), resource->version(), 0), pWindow)); - if (!NEWHANDLE->good()) { + if UNLIKELY (!NEWHANDLE->good()) { LOGM(ERR, "Couldn't create a foreign handle"); resource->noMemory(); PROTO::foreignToplevelWlr->m_vHandles.pop_back(); @@ -208,7 +208,7 @@ void CForeignToplevelWlrManager::onMap(PHLWINDOW pWindow) { resource->sendToplevel(NEWHANDLE->resource.get()); NEWHANDLE->resource->sendAppId(pWindow->m_szClass.c_str()); NEWHANDLE->resource->sendTitle(pWindow->m_szTitle.c_str()); - if (const auto PMONITOR = pWindow->m_pMonitor.lock(); PMONITOR) + if LIKELY (const auto PMONITOR = pWindow->m_pMonitor.lock(); PMONITOR) NEWHANDLE->sendMonitor(PMONITOR); NEWHANDLE->sendState(); NEWHANDLE->resource->sendDone(); @@ -223,11 +223,11 @@ SP CForeignToplevelWlrManager::handleForWindow(PHLWIN } void CForeignToplevelWlrManager::onTitle(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; H->resource->sendTitle(pWindow->m_szTitle.c_str()); @@ -235,11 +235,11 @@ void CForeignToplevelWlrManager::onTitle(PHLWINDOW pWindow) { } void CForeignToplevelWlrManager::onClass(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; H->resource->sendAppId(pWindow->m_szClass.c_str()); @@ -247,11 +247,11 @@ void CForeignToplevelWlrManager::onClass(PHLWINDOW pWindow) { } void CForeignToplevelWlrManager::onUnmap(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H) + if UNLIKELY (!H) return; H->resource->sendClosed(); @@ -260,16 +260,16 @@ void CForeignToplevelWlrManager::onUnmap(PHLWINDOW pWindow) { } void CForeignToplevelWlrManager::onMoveMonitor(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; const auto PMONITOR = pWindow->m_pMonitor.lock(); - if (!PMONITOR) + if UNLIKELY (!PMONITOR) return; H->sendMonitor(PMONITOR); @@ -277,11 +277,11 @@ void CForeignToplevelWlrManager::onMoveMonitor(PHLWINDOW pWindow) { } void CForeignToplevelWlrManager::onFullscreen(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; H->sendState(); @@ -289,10 +289,10 @@ void CForeignToplevelWlrManager::onFullscreen(PHLWINDOW pWindow) { } void CForeignToplevelWlrManager::onNewFocus(PHLWINDOW pWindow) { - if (finished) + if UNLIKELY (finished) return; - if (const auto HOLD = handleForWindow(lastFocus.lock()); HOLD) { + if LIKELY (const auto HOLD = handleForWindow(lastFocus.lock()); HOLD) { HOLD->sendState(); HOLD->resource->sendDone(); } @@ -300,7 +300,7 @@ void CForeignToplevelWlrManager::onNewFocus(PHLWINDOW pWindow) { lastFocus = pWindow; const auto H = handleForWindow(pWindow); - if (!H || H->closed) + if UNLIKELY (!H || H->closed) return; H->sendState(); @@ -378,7 +378,7 @@ CForeignToplevelWlrProtocol::CForeignToplevelWlrProtocol(const wl_interface* ifa void CForeignToplevelWlrProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(makeShared(client, ver, id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { LOGM(ERR, "Couldn't create a foreign list"); wl_client_post_no_memory(client); m_vManagers.pop_back(); diff --git a/src/protocols/FractionalScale.cpp b/src/protocols/FractionalScale.cpp index d8010eac..d1e0a604 100644 --- a/src/protocols/FractionalScale.cpp +++ b/src/protocols/FractionalScale.cpp @@ -35,7 +35,7 @@ void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1* const auto PADDON = m_mAddons.emplace(surface, std::make_unique(makeShared(pMgr->client(), pMgr->version(), id), surface)).first->second.get(); - if (!PADDON->good()) { + if UNLIKELY (!PADDON->good()) { m_mAddons.erase(surface); pMgr->noMemory(); return; diff --git a/src/protocols/FrogColorManagement.cpp b/src/protocols/FrogColorManagement.cpp index f27af5c8..cb2eed12 100644 --- a/src/protocols/FrogColorManagement.cpp +++ b/src/protocols/FrogColorManagement.cpp @@ -3,7 +3,7 @@ #include "protocols/core/Subcompositor.hpp" CFrogColorManager::CFrogColorManager(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([](CFrogColorManagementFactoryV1* r) { LOGM(TRACE, "Destroy frog_color_management at {:x} (generated default)", (uintptr_t)r); }); @@ -24,7 +24,7 @@ CFrogColorManager::CFrogColorManager(SP resource_ const auto RESOURCE = PROTO::frogColorManagement->m_vSurfaces.emplace_back( makeShared(makeShared(r->client(), r->version(), id), SURF)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::frogColorManagement->m_vSurfaces.pop_back(); return; @@ -39,14 +39,14 @@ bool CFrogColorManager::good() { } CFrogColorManagementSurface::CFrogColorManagementSurface(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); if (!surface->colorManagement.valid()) { const auto RESOURCE = PROTO::colorManagement->m_vSurfaces.emplace_back(makeShared(surface_)); - if (!RESOURCE) { + if UNLIKELY (!RESOURCE) { resource->noMemory(); PROTO::colorManagement->m_vSurfaces.pop_back(); return; @@ -141,7 +141,7 @@ CFrogColorManagementProtocol::CFrogColorManagementProtocol(const wl_interface* i void CFrogColorManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp index b0da29a2..299d7717 100644 --- a/src/protocols/GammaControl.cpp +++ b/src/protocols/GammaControl.cpp @@ -6,12 +6,12 @@ #include "../render/Renderer.hpp" CGammaControl::CGammaControl(SP resource_, wl_resource* output) : resource(resource_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; auto OUTPUTRES = CWLOutputResource::fromResource(output); - if (!OUTPUTRES) { + if UNLIKELY (!OUTPUTRES) { LOGM(ERR, "No output in CGammaControl"); resource->sendFailed(); return; @@ -19,14 +19,14 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out pMonitor = OUTPUTRES->monitor; - if (!pMonitor || !pMonitor->output) { + if UNLIKELY (!pMonitor || !pMonitor->output) { LOGM(ERR, "No CMonitor"); resource->sendFailed(); return; } for (auto const& g : PROTO::gamma->m_vGammaControllers) { - if (g->pMonitor == pMonitor) { + if UNLIKELY (g->pMonitor == pMonitor) { resource->sendFailed(); return; } @@ -34,7 +34,7 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out gammaSize = pMonitor->output->getGammaSize(); - if (gammaSize <= 0) { + if UNLIKELY (gammaSize <= 0) { LOGM(ERR, "Output {} doesn't support gamma", pMonitor->szName); resource->sendFailed(); return; @@ -46,7 +46,7 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out resource->setOnDestroy([this](CZwlrGammaControlV1* gamma) { PROTO::gamma->destroyGammaControl(this); }); resource->setSetGamma([this](CZwlrGammaControlV1* gamma, int32_t fd) { - if (!pMonitor) { + if UNLIKELY (!pMonitor) { LOGM(ERR, "setGamma for a dead monitor"); resource->sendFailed(); close(fd); @@ -56,14 +56,14 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out LOGM(LOG, "setGamma for {}", pMonitor->szName); int fdFlags = fcntl(fd, F_GETFL, 0); - if (fdFlags < 0) { + if UNLIKELY (fdFlags < 0) { LOGM(ERR, "Failed to get fd flags"); resource->sendFailed(); close(fd); return; } - if (fcntl(fd, F_SETFL, fdFlags | O_NONBLOCK) < 0) { + if UNLIKELY (fcntl(fd, F_SETFL, fdFlags | O_NONBLOCK) < 0) { LOGM(ERR, "Failed to set fd flags"); resource->sendFailed(); close(fd); @@ -126,7 +126,7 @@ bool CGammaControl::good() { } void CGammaControl::applyToMonitor() { - if (!pMonitor || !pMonitor->output) + if UNLIKELY (!pMonitor || !pMonitor->output) return; // ?? LOGM(LOG, "setting to monitor {}", pMonitor->szName); @@ -179,7 +179,7 @@ void CGammaControlProtocol::onGetGammaControl(CZwlrGammaControlManagerV1* pMgr, const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vGammaControllers.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), output)).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vGammaControllers.pop_back(); return; diff --git a/src/protocols/GlobalShortcuts.cpp b/src/protocols/GlobalShortcuts.cpp index ca67f063..6fac2d7f 100644 --- a/src/protocols/GlobalShortcuts.cpp +++ b/src/protocols/GlobalShortcuts.cpp @@ -1,7 +1,7 @@ #include "GlobalShortcuts.hpp" CShortcutClient::CShortcutClient(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CHyprlandGlobalShortcutsManagerV1* pMgr) { PROTO::globalShortcuts->destroyResource(this); }); @@ -9,7 +9,7 @@ CShortcutClient::CShortcutClient(SP resource_ resource->setRegisterShortcut([this](CHyprlandGlobalShortcutsManagerV1* pMgr, uint32_t shortcut, const char* id, const char* app_id, const char* description, const char* trigger_description) { - if (PROTO::globalShortcuts->isTaken(id, app_id)) { + if UNLIKELY (PROTO::globalShortcuts->isTaken(id, app_id)) { resource->error(HYPRLAND_GLOBAL_SHORTCUTS_MANAGER_V1_ERROR_ALREADY_TAKEN, "Combination is taken"); return; } @@ -20,7 +20,7 @@ CShortcutClient::CShortcutClient(SP resource_ PSHORTCUT->appid = app_id; PSHORTCUT->shortcut = shortcut; - if (!PSHORTCUT->resource->resource()) { + if UNLIKELY (!PSHORTCUT->resource->resource()) { PSHORTCUT->resource->noMemory(); shortcuts.pop_back(); return; @@ -41,7 +41,7 @@ CGlobalShortcutsProtocol::CGlobalShortcutsProtocol(const wl_interface* iface, co void CGlobalShortcutsProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESROUCE = m_vClients.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESROUCE->good()) { + if UNLIKELY (!RESROUCE->good()) { wl_client_post_no_memory(client); m_vClients.pop_back(); return; diff --git a/src/protocols/HyprlandSurface.cpp b/src/protocols/HyprlandSurface.cpp index ce6fc77a..bcf4905c 100644 --- a/src/protocols/HyprlandSurface.cpp +++ b/src/protocols/HyprlandSurface.cpp @@ -15,20 +15,20 @@ bool CHyprlandSurface::good() const { void CHyprlandSurface::setResource(SP resource) { m_pResource = std::move(resource); - if (!m_pResource->resource()) + if UNLIKELY (!m_pResource->resource()) return; m_pResource->setDestroy([this](CHyprlandSurfaceV1* resource) { destroy(); }); m_pResource->setOnDestroy([this](CHyprlandSurfaceV1* resource) { destroy(); }); m_pResource->setSetOpacity([this](CHyprlandSurfaceV1* resource, uint32_t opacity) { - if (!m_pSurface) { + if UNLIKELY (!m_pSurface) { m_pResource->error(HYPRLAND_SURFACE_V1_ERROR_NO_SURFACE, "set_opacity called for destroyed wl_surface"); return; } auto fOpacity = wl_fixed_to_double(opacity); - if (fOpacity < 0.0 || fOpacity > 1.0) { + if UNLIKELY (fOpacity < 0.0 || fOpacity > 1.0) { m_pResource->error(HYPRLAND_SURFACE_V1_ERROR_OUT_OF_RANGE, "set_opacity called with an opacity value larger than 1.0 or smaller than 0.0."); return; } @@ -104,7 +104,7 @@ void CHyprlandSurfaceProtocol::getSurface(CHyprlandSurfaceManagerV1* manager, ui .first->second.get(); } - if (!hyprlandSurface->good()) { + if UNLIKELY (!hyprlandSurface->good()) { manager->noMemory(); m_mSurfaces.erase(surface); } diff --git a/src/protocols/IdleNotify.cpp b/src/protocols/IdleNotify.cpp index 3517a62d..85a9f8e2 100644 --- a/src/protocols/IdleNotify.cpp +++ b/src/protocols/IdleNotify.cpp @@ -11,7 +11,7 @@ static int onTimer(SP self, void* data) { } CExtIdleNotification::CExtIdleNotification(SP resource_, uint32_t timeoutMs_) : resource(resource_), timeoutMs(timeoutMs_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource->setDestroy([this](CExtIdleNotificationV1* r) { PROTO::idle->destroyNotification(this); }); @@ -78,7 +78,7 @@ void CIdleNotifyProtocol::onGetNotification(CExtIdleNotifierV1* pMgr, uint32_t i const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vNotifications.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id), timeout)).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vNotifications.pop_back(); return; diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp index 5fd1e893..cf777f45 100644 --- a/src/protocols/InputMethodV2.cpp +++ b/src/protocols/InputMethodV2.cpp @@ -7,7 +7,7 @@ #include CInputMethodKeyboardGrabV2::CInputMethodKeyboardGrabV2(SP resource_, SP owner_) : resource(resource_), owner(owner_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setRelease([this](CZwpInputMethodKeyboardGrabV2* r) { PROTO::ime->destroyResource(this); }); @@ -34,13 +34,13 @@ void CInputMethodKeyboardGrabV2::sendKeyboardData(SP keyboard) { pLastKeyboard = keyboard; int keymapFD = allocateSHMFile(keyboard->xkbKeymapString.length() + 1); - if (keymapFD < 0) { + if UNLIKELY (keymapFD < 0) { LOGM(ERR, "Failed to create a keymap file for keyboard grab"); return; } void* data = mmap(nullptr, keyboard->xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD, 0); - if (data == MAP_FAILED) { + if UNLIKELY (data == MAP_FAILED) { LOGM(ERR, "Failed to mmap a keymap file for keyboard grab"); close(keymapFD); return; @@ -83,7 +83,7 @@ wl_client* CInputMethodKeyboardGrabV2::client() { } CInputMethodPopupV2::CInputMethodPopupV2(SP resource_, SP owner_, SP surface) : resource(resource_), owner(owner_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CZwpInputPopupSurfaceV2* r) { PROTO::ime->destroyResource(this); }); @@ -149,7 +149,7 @@ void CInputMethodV2::SState::reset() { } CInputMethodV2::CInputMethodV2(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CZwpInputMethodV2* r) { @@ -189,7 +189,7 @@ CInputMethodV2::CInputMethodV2(SP resource_) : resource(resou const auto RESOURCE = PROTO::ime->m_vPopups.emplace_back( makeShared(makeShared(r->client(), r->version(), id), self.lock(), CWLSurfaceResource::fromResource(surface))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::ime->m_vPopups.pop_back(); return; @@ -206,7 +206,7 @@ CInputMethodV2::CInputMethodV2(SP resource_) : resource(resou const auto RESOURCE = PROTO::ime->m_vGrabs.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::ime->m_vGrabs.pop_back(); return; @@ -360,7 +360,7 @@ void CInputMethodV2Protocol::destroyResource(CInputMethodV2* ime) { void CInputMethodV2Protocol::onGetIME(CZwpInputMethodManagerV2* mgr, wl_resource* seat, uint32_t id) { const auto RESOURCE = m_vIMEs.emplace_back(makeShared(makeShared(mgr->client(), mgr->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { mgr->noMemory(); m_vIMEs.pop_back(); return; diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp index 0777149f..82d00a30 100644 --- a/src/protocols/LayerShell.cpp +++ b/src/protocols/LayerShell.cpp @@ -18,7 +18,7 @@ void CLayerShellResource::SState::reset() { CLayerShellResource::CLayerShellResource(SP resource_, SP surf_, std::string namespace_, PHLMONITOR pMonitor, zwlrLayerShellV1Layer layer) : layerNamespace(namespace_), surface(surf_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; current.layer = layer; @@ -223,19 +223,19 @@ void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id const auto PMONITOR = output ? CWLOutputResource::fromResource(output)->monitor.lock() : nullptr; auto SURF = CWLSurfaceResource::fromResource(surface); - if (!SURF) { + if UNLIKELY (!SURF) { pMgr->error(-1, "Invalid surface"); return; } - if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) { + if UNLIKELY (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) { pMgr->error(-1, "Surface already has a different role"); return; } const auto RESOURCE = m_vLayers.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id), SURF, namespace_, PMONITOR, layer)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vLayers.pop_back(); return; diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index 24b8f62c..85f7b1c6 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -126,7 +126,7 @@ bool CLinuxDMABuffer::good() { } CLinuxDMABBUFParamsResource::CLinuxDMABBUFParamsResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CZwpLinuxBufferParamsV1* r) { PROTO::linuxDma->destroyResource(this); }); @@ -208,12 +208,12 @@ bool CLinuxDMABBUFParamsResource::good() { void CLinuxDMABBUFParamsResource::create(uint32_t id) { used = true; - if (!verify()) { + if UNLIKELY (!verify()) { LOGM(ERR, "Failed creating a dmabuf: verify() said no"); return; // if verify failed, we errored the resource. } - if (!commence()) { + if UNLIKELY (!commence()) { LOGM(ERR, "Failed creating a dmabuf: commence() said no"); resource->sendFailed(); return; @@ -226,7 +226,7 @@ void CLinuxDMABBUFParamsResource::create(uint32_t id) { auto buf = PROTO::linuxDma->m_vBuffers.emplace_back(makeShared(id, resource->client(), *attrs)); - if (!buf->good() || !buf->buffer->success) { + if UNLIKELY (!buf->good() || !buf->buffer->success) { resource->sendFailed(); return; } @@ -259,12 +259,12 @@ bool CLinuxDMABBUFParamsResource::commence() { } bool CLinuxDMABBUFParamsResource::verify() { - if (attrs->planes <= 0) { + if UNLIKELY (attrs->planes <= 0) { resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "No planes added"); return false; } - if (attrs->fds.at(0) < 0) { + if UNLIKELY (attrs->fds.at(0) < 0) { resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "No plane 0"); return false; } @@ -282,7 +282,7 @@ bool CLinuxDMABBUFParamsResource::verify() { } } - if (attrs->size.x < 1 || attrs->size.y < 1) { + if UNLIKELY (attrs->size.x < 1 || attrs->size.y < 1) { resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS, "x/y < 1"); return false; } @@ -300,7 +300,7 @@ bool CLinuxDMABBUFParamsResource::verify() { } CLinuxDMABUFFeedbackResource::CLinuxDMABUFFeedbackResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CZwpLinuxDmabufFeedbackV1* r) { PROTO::linuxDma->destroyResource(this); }); @@ -355,7 +355,7 @@ void CLinuxDMABUFFeedbackResource::sendDefaultFeedback() { } CLinuxDMABUFResource::CLinuxDMABUFResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CZwpLinuxDmabufV1* r) { PROTO::linuxDma->destroyResource(this); }); @@ -365,7 +365,7 @@ CLinuxDMABUFResource::CLinuxDMABUFResource(SP resource_) : re const auto RESOURCE = PROTO::linuxDma->m_vFeedbacks.emplace_back(makeShared(makeShared(r->client(), r->version(), id), nullptr)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::linuxDma->m_vFeedbacks.pop_back(); return; @@ -376,7 +376,7 @@ CLinuxDMABUFResource::CLinuxDMABUFResource(SP resource_) : re const auto RESOURCE = PROTO::linuxDma->m_vFeedbacks.emplace_back( makeShared(makeShared(r->client(), r->version(), id), CWLSurfaceResource::fromResource(surf))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::linuxDma->m_vFeedbacks.pop_back(); return; @@ -386,7 +386,7 @@ CLinuxDMABUFResource::CLinuxDMABUFResource(SP resource_) : re resource->setCreateParams([](CZwpLinuxDmabufV1* r, uint32_t id) { const auto RESOURCE = PROTO::linuxDma->m_vParams.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::linuxDma->m_vParams.pop_back(); return; @@ -535,7 +535,7 @@ CLinuxDMABufV1Protocol::~CLinuxDMABufV1Protocol() { void CLinuxDMABufV1Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp index 41536988..caa539a2 100644 --- a/src/protocols/MesaDRM.cpp +++ b/src/protocols/MesaDRM.cpp @@ -35,7 +35,7 @@ bool CMesaDRMBufferResource::good() { } CMesaDRMResource::CMesaDRMResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlDrm* r) { PROTO::mesaDRM->destroyResource(this); }); @@ -87,7 +87,7 @@ CMesaDRMResource::CMesaDRMResource(SP resource_) : resource(resource_) { const auto RESOURCE = PROTO::mesaDRM->m_vBuffers.emplace_back(makeShared(id, resource->client(), attrs)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::mesaDRM->m_vBuffers.pop_back(); return; @@ -140,7 +140,7 @@ CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, co void CMesaDRMProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/OutputManagement.cpp b/src/protocols/OutputManagement.cpp index 4a976021..ecca0c48 100644 --- a/src/protocols/OutputManagement.cpp +++ b/src/protocols/OutputManagement.cpp @@ -8,7 +8,7 @@ using namespace Aquamarine; COutputManager::COutputManager(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; LOGM(LOG, "New OutputManager registered"); @@ -23,7 +23,7 @@ COutputManager::COutputManager(SP resource_) : resource(re const auto RESOURCE = PROTO::outputManagement->m_vConfigurations.emplace_back( makeShared(makeShared(resource->client(), resource->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::outputManagement->m_vConfigurations.pop_back(); return; @@ -48,13 +48,13 @@ bool COutputManager::good() { } void COutputManager::makeAndSendNewHead(PHLMONITOR pMonitor) { - if (stopped) + if UNLIKELY (stopped) return; const auto RESOURCE = PROTO::outputManagement->m_vHeads.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), pMonitor)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::outputManagement->m_vHeads.pop_back(); return; @@ -90,7 +90,7 @@ void COutputManager::sendDone() { } COutputHead::COutputHead(SP resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](CZwlrOutputHeadV1* r) { PROTO::outputManagement->destroyResource(this); }); @@ -213,7 +213,7 @@ void COutputHead::updateMode() { void COutputHead::makeAndSendNewMode(SP mode) { const auto RESOURCE = PROTO::outputManagement->m_vModes.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), mode)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::outputManagement->m_vModes.pop_back(); return; @@ -229,7 +229,7 @@ PHLMONITOR COutputHead::monitor() { } COutputMode::COutputMode(SP resource_, SP mode_) : resource(resource_), mode(mode_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](CZwlrOutputModeV1* r) { PROTO::outputManagement->destroyResource(this); }); @@ -258,7 +258,7 @@ SP COutputMode::getMode() { } COutputConfiguration::COutputConfiguration(SP resource_, SP owner_) : resource(resource_), owner(owner_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwlrOutputConfigurationV1* r) { PROTO::outputManagement->destroyResource(this); }); @@ -282,7 +282,7 @@ COutputConfiguration::COutputConfiguration(SP resour const auto RESOURCE = PROTO::outputManagement->m_vConfigurationHeads.emplace_back( makeShared(makeShared(resource->client(), resource->version(), id), PMONITOR)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::outputManagement->m_vConfigurationHeads.pop_back(); return; @@ -428,7 +428,7 @@ bool COutputConfiguration::applyTestConfiguration(bool test) { } COutputConfigurationHead::COutputConfigurationHead(SP resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CZwlrOutputConfigurationHeadV1* r) { PROTO::outputManagement->destroyResource(this); }); @@ -581,7 +581,7 @@ COutputManagementProtocol::COutputManagementProtocol(const wl_interface* iface, void COutputManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/OutputPower.cpp b/src/protocols/OutputPower.cpp index dd3e8e1a..f97babc2 100644 --- a/src/protocols/OutputPower.cpp +++ b/src/protocols/OutputPower.cpp @@ -3,7 +3,7 @@ #include "../helpers/Monitor.hpp" COutputPower::COutputPower(SP resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CZwlrOutputPowerV1* r) { PROTO::outputPower->destroyOutputPower(this); }); @@ -62,7 +62,7 @@ void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uin const auto OUTPUT = CWLOutputResource::fromResource(output); - if (!OUTPUT) { + if UNLIKELY (!OUTPUT) { pMgr->error(0, "Invalid output resource"); return; } @@ -70,7 +70,7 @@ void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uin const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vOutputPowers.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), OUTPUT->monitor.lock())).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vOutputPowers.pop_back(); return; diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp index e12fa75f..c0531799 100644 --- a/src/protocols/PointerConstraints.cpp +++ b/src/protocols/PointerConstraints.cpp @@ -10,7 +10,7 @@ CPointerConstraint::CPointerConstraint(SP resource_, SP surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) : resourceL(resource_), locked(true), lifetime(lifetime_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource_->setOnDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); }); @@ -49,7 +49,7 @@ CPointerConstraint::CPointerConstraint(SP resource_, SP resource_, SP surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) : resourceC(resource_), lifetime(lifetime_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource_->setOnDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); }); @@ -185,7 +185,7 @@ bool CPointerConstraint::isLocked() { } Vector2D CPointerConstraint::logicPositionHint() { - if (!pHLSurface) + if UNLIKELY (!pHLSurface) return {}; const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal(); @@ -218,14 +218,14 @@ void CPointerConstraintsProtocol::destroyPointerConstraint(CPointerConstraint* h } void CPointerConstraintsProtocol::onNewConstraint(SP constraint, CZwpPointerConstraintsV1* pMgr) { - if (!constraint->good()) { + if UNLIKELY (!constraint->good()) { LOGM(ERR, "Couldn't create constraint??"); pMgr->noMemory(); m_vConstraints.pop_back(); return; } - if (!constraint->owner()) { + if UNLIKELY (!constraint->owner()) { LOGM(ERR, "New constraint has no CWLSurface owner??"); return; } @@ -234,7 +234,7 @@ void CPointerConstraintsProtocol::onNewConstraint(SP constra const auto DUPES = std::count_if(m_vConstraints.begin(), m_vConstraints.end(), [OWNER](const auto& c) { return c->owner() == OWNER; }); - if (DUPES > 1) { + if UNLIKELY (DUPES > 1) { LOGM(ERR, "Constraint for surface duped"); pMgr->error(ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED, "Surface already confined"); m_vConstraints.pop_back(); diff --git a/src/protocols/PointerGestures.cpp b/src/protocols/PointerGestures.cpp index 5dfb9d51..4df51b47 100644 --- a/src/protocols/PointerGestures.cpp +++ b/src/protocols/PointerGestures.cpp @@ -4,7 +4,7 @@ #include "core/Compositor.hpp" CPointerGestureSwipe::CPointerGestureSwipe(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setOnDestroy([this](CZwpPointerGestureSwipeV1* p) { PROTO::pointerGestures->onGestureDestroy(this); }); @@ -16,7 +16,7 @@ bool CPointerGestureSwipe::good() { } CPointerGestureHold::CPointerGestureHold(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setOnDestroy([this](CZwpPointerGestureHoldV1* p) { PROTO::pointerGestures->onGestureDestroy(this); }); @@ -28,7 +28,7 @@ bool CPointerGestureHold::good() { } CPointerGesturePinch::CPointerGesturePinch(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setOnDestroy([this](CZwpPointerGesturePinchV1* p) { PROTO::pointerGestures->onGestureDestroy(this); }); @@ -73,7 +73,7 @@ void CPointerGesturesProtocol::onGetPinchGesture(CZwpPointerGesturesV1* pMgr, ui const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vPinches.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); LOGM(ERR, "Couldn't create gesture"); return; @@ -84,7 +84,7 @@ void CPointerGesturesProtocol::onGetSwipeGesture(CZwpPointerGesturesV1* pMgr, ui const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vSwipes.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); LOGM(ERR, "Couldn't create gesture"); return; @@ -95,7 +95,7 @@ void CPointerGesturesProtocol::onGetHoldGesture(CZwpPointerGesturesV1* pMgr, uin const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vHolds.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); LOGM(ERR, "Couldn't create gesture"); return; diff --git a/src/protocols/PresentationTime.cpp b/src/protocols/PresentationTime.cpp index 411036c3..1654041c 100644 --- a/src/protocols/PresentationTime.cpp +++ b/src/protocols/PresentationTime.cpp @@ -27,7 +27,7 @@ void CQueuedPresentationData::discarded() { } CPresentationFeedback::CPresentationFeedback(SP resource_, SP surf) : resource(resource_), surface(surf) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWpPresentationFeedback* pMgr) { @@ -43,8 +43,8 @@ bool CPresentationFeedback::good() { void CPresentationFeedback::sendQueued(SP data, timespec* when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) { auto client = resource->client(); - if (PROTO::outputs.contains(data->pMonitor->szName)) { - if (auto outputResource = PROTO::outputs.at(data->pMonitor->szName)->outputResourceFrom(client); outputResource) + if LIKELY (PROTO::outputs.contains(data->pMonitor->szName)) { + if LIKELY (auto outputResource = PROTO::outputs.at(data->pMonitor->szName)->outputResourceFrom(client); outputResource) resource->sendSyncOutput(outputResource->getResource()->resource()); } @@ -100,7 +100,7 @@ void CPresentationProtocol::onGetFeedback(CWpPresentation* pMgr, wl_resource* su m_vFeedbacks.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))) .get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vFeedbacks.pop_back(); return; diff --git a/src/protocols/PrimarySelection.cpp b/src/protocols/PrimarySelection.cpp index ecc4ee71..567bfdd2 100644 --- a/src/protocols/PrimarySelection.cpp +++ b/src/protocols/PrimarySelection.cpp @@ -5,7 +5,7 @@ #include "../config/ConfigValue.hpp" CPrimarySelectionOffer::CPrimarySelectionOffer(SP resource_, SP source_) : source(source_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); }); @@ -35,7 +35,7 @@ bool CPrimarySelectionOffer::good() { } void CPrimarySelectionOffer::sendData() { - if (!source) + if UNLIKELY (!source) return; for (auto const& m : source->mimes()) { @@ -44,7 +44,7 @@ void CPrimarySelectionOffer::sendData() { } CPrimarySelectionSource::CPrimarySelectionSource(SP resource_, SP device_) : device(device_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -105,7 +105,7 @@ void CPrimarySelectionSource::error(uint32_t code, const std::string& msg) { } CPrimarySelectionDevice::CPrimarySelectionDevice(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); @@ -159,7 +159,7 @@ void CPrimarySelectionDevice::sendSelection(SP selection } CPrimarySelectionManager::CPrimarySelectionManager(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CZwpPrimarySelectionDeviceManagerV1* r) { PROTO::primarySelection->destroyResource(this); }); @@ -168,7 +168,7 @@ CPrimarySelectionManager::CPrimarySelectionManager(SPm_vDevices.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::primarySelection->m_vDevices.pop_back(); return; @@ -192,7 +192,7 @@ CPrimarySelectionManager::CPrimarySelectionManager(SPm_vSources.emplace_back( makeShared(makeShared(r->client(), r->version(), id), device.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::primarySelection->m_vSources.pop_back(); return; @@ -220,7 +220,7 @@ CPrimarySelectionProtocol::CPrimarySelectionProtocol(const wl_interface* iface, void CPrimarySelectionProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/RelativePointer.cpp b/src/protocols/RelativePointer.cpp index b7cf75c6..842af894 100644 --- a/src/protocols/RelativePointer.cpp +++ b/src/protocols/RelativePointer.cpp @@ -4,7 +4,7 @@ #include CRelativePointer::CRelativePointer(SP resource_) : resource(resource_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; pClient = resource->client(); @@ -50,7 +50,7 @@ void CRelativePointerProtocol::onGetRelativePointer(CZwpRelativePointerManagerV1 const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vRelativePointers.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vRelativePointers.pop_back(); return; diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index da0a9412..8bdaf8f9 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -19,7 +19,7 @@ CScreencopyFrame::~CScreencopyFrame() { } CScreencopyFrame::CScreencopyFrame(SP resource_, int32_t overlay_cursor, wl_resource* output, CBox box_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; overlayCursor = !!overlay_cursor; @@ -77,21 +77,20 @@ CScreencopyFrame::CScreencopyFrame(SP resource_, int32_t resource->sendBuffer(NFormatUtils::drmToShm(shmFormat), box.width, box.height, shmStride); if (resource->version() >= 3) { - if (dmabufFormat != DRM_FORMAT_INVALID) { + if LIKELY (dmabufFormat != DRM_FORMAT_INVALID) resource->sendLinuxDmabuf(dmabufFormat, box.width, box.height); - } resource->sendBufferDone(); } } void CScreencopyFrame::copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer_) { - if (!good()) { + if UNLIKELY (!good()) { LOGM(ERR, "No frame in copyFrame??"); return; } - if (!g_pCompositor->monitorExists(pMonitor.lock())) { + if UNLIKELY (!g_pCompositor->monitorExists(pMonitor.lock())) { LOGM(ERR, "Client requested sharing of a monitor that is gone"); resource->sendFailed(); PROTO::screencopy->destroyResource(this); @@ -99,7 +98,7 @@ void CScreencopyFrame::copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer_ } const auto PBUFFER = CWLBufferResource::fromResource(buffer_); - if (!PBUFFER) { + if UNLIKELY (!PBUFFER) { LOGM(ERR, "Invalid buffer in {:x}", (uintptr_t)this); resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer"); PROTO::screencopy->destroyResource(this); @@ -108,14 +107,14 @@ void CScreencopyFrame::copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer_ PBUFFER->buffer->lock(); - if (PBUFFER->buffer->size != box.size()) { + if UNLIKELY (PBUFFER->buffer->size != box.size()) { LOGM(ERR, "Invalid dimensions in {:x}", (uintptr_t)this); resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions"); PROTO::screencopy->destroyResource(this); return; } - if (buffer) { + if UNLIKELY (buffer) { LOGM(ERR, "Buffer used in {:x}", (uintptr_t)this); resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_ALREADY_USED, "frame already used"); PROTO::screencopy->destroyResource(this); @@ -308,7 +307,7 @@ CScreencopyClient::~CScreencopyClient() { } CScreencopyClient::CScreencopyClient(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); }); diff --git a/src/protocols/SecurityContext.cpp b/src/protocols/SecurityContext.cpp index 0818907f..e5b3cf2a 100644 --- a/src/protocols/SecurityContext.cpp +++ b/src/protocols/SecurityContext.cpp @@ -49,7 +49,7 @@ void CSecurityContextSandboxedClient::onDestroy() { } CSecurityContext::CSecurityContext(SP resource_, int listenFD_, int closeFD_) : listenFD(listenFD_), closeFD(closeFD_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CWpSecurityContextV1* r) { @@ -64,12 +64,12 @@ CSecurityContext::CSecurityContext(SP resource_, int liste LOGM(LOG, "New security_context at 0x{:x}", (uintptr_t)this); resource->setSetSandboxEngine([this](CWpSecurityContextV1* r, const char* engine) { - if (!sandboxEngine.empty()) { + if UNLIKELY (!sandboxEngine.empty()) { r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_SET, "Sandbox engine already set"); return; } - if (committed) { + if UNLIKELY (committed) { r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_USED, "Context already committed"); return; } @@ -79,12 +79,12 @@ CSecurityContext::CSecurityContext(SP resource_, int liste }); resource->setSetAppId([this](CWpSecurityContextV1* r, const char* appid) { - if (!appID.empty()) { + if UNLIKELY (!appID.empty()) { r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_SET, "Sandbox appid already set"); return; } - if (committed) { + if UNLIKELY (committed) { r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_USED, "Context already committed"); return; } @@ -94,12 +94,12 @@ CSecurityContext::CSecurityContext(SP resource_, int liste }); resource->setSetInstanceId([this](CWpSecurityContextV1* r, const char* instance) { - if (!instanceID.empty()) { + if UNLIKELY (!instanceID.empty()) { r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_SET, "Sandbox instance already set"); return; } - if (committed) { + if UNLIKELY (committed) { r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_USED, "Context already committed"); return; } @@ -135,7 +135,7 @@ bool CSecurityContext::good() { } void CSecurityContext::onListen(uint32_t mask) { - if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) { + if UNLIKELY (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) { LOGM(ERR, "security_context at 0x{:x} got an error in listen", (uintptr_t)this); PROTO::securityContext->destroyContext(this); return; @@ -145,13 +145,13 @@ void CSecurityContext::onListen(uint32_t mask) { return; int clientFD = accept(listenFD, nullptr, nullptr); - if (clientFD < 0) { + if UNLIKELY (clientFD < 0) { LOGM(ERR, "security_context at 0x{:x} couldn't accept", (uintptr_t)this); return; } auto newClient = CSecurityContextSandboxedClient::create(clientFD); - if (!newClient) { + if UNLIKELY (!newClient) { LOGM(ERR, "security_context at 0x{:x} couldn't create a client", (uintptr_t)this); close(clientFD); return; @@ -170,7 +170,7 @@ void CSecurityContext::onClose(uint32_t mask) { } CSecurityContextManagerResource::CSecurityContextManagerResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CWpSecurityContextManagerV1* r) { PROTO::securityContext->destroyResource(this); }); @@ -180,7 +180,7 @@ CSecurityContextManagerResource::CSecurityContextManagerResource(SPm_vContexts.emplace_back(makeShared(makeShared(r->client(), r->version(), id), lfd, cfd)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::securityContext->m_vContexts.pop_back(); return; @@ -199,7 +199,7 @@ CSecurityContextProtocol::CSecurityContextProtocol(const wl_interface* iface, co void CSecurityContextProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/ServerDecorationKDE.cpp b/src/protocols/ServerDecorationKDE.cpp index c7b98a9c..3e33db52 100644 --- a/src/protocols/ServerDecorationKDE.cpp +++ b/src/protocols/ServerDecorationKDE.cpp @@ -2,7 +2,7 @@ #include "core/Compositor.hpp" CServerDecorationKDE::CServerDecorationKDE(SP resource_, SP surf) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); }); @@ -44,7 +44,7 @@ void CServerDecorationKDEProtocol::createDecoration(COrgKdeKwinServerDecorationM m_vDecos.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))) .get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vDecos.pop_back(); return; diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp index c3f19e53..db65ee5f 100644 --- a/src/protocols/SessionLock.cpp +++ b/src/protocols/SessionLock.cpp @@ -8,7 +8,7 @@ CSessionLockSurface::CSessionLockSurface(SP resource_, SP surface_, PHLMONITOR pMonitor_, WP owner_) : resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CExtSessionLockSurfaceV1* r) { @@ -92,7 +92,7 @@ SP CSessionLockSurface::surface() { } CSessionLock::CSessionLock(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CExtSessionLockV1* r) { PROTO::sessionLock->destroyResource(this); }); @@ -170,7 +170,7 @@ void CSessionLockProtocol::onLock(CExtSessionLockManagerV1* pMgr, uint32_t id) { const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vLocks.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vLocks.pop_back(); return; @@ -198,7 +198,7 @@ void CSessionLockProtocol::onGetLockSurface(CExtSessionLockV1* lock, uint32_t id const auto RESOURCE = m_vLockSurfaces.emplace_back(makeShared(makeShared(lock->client(), lock->version(), id), PSURFACE, PMONITOR, sessionLock)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { lock->noMemory(); m_vLockSurfaces.pop_back(); return; diff --git a/src/protocols/ShortcutsInhibit.cpp b/src/protocols/ShortcutsInhibit.cpp index 308b385d..a0d29f92 100644 --- a/src/protocols/ShortcutsInhibit.cpp +++ b/src/protocols/ShortcutsInhibit.cpp @@ -4,7 +4,7 @@ #include "core/Compositor.hpp" CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP resource_, SP surf) : resource(resource_), pSurface(surf) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); }); @@ -49,7 +49,7 @@ void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitMa const auto CLIENT = pMgr->client(); for (auto const& in : m_vInhibitors) { - if (in->surface() != surf) + if LIKELY (in->surface() != surf) continue; pMgr->error(ZWP_KEYBOARD_SHORTCUTS_INHIBIT_MANAGER_V1_ERROR_ALREADY_INHIBITED, "Already inhibited for surface resource"); @@ -59,7 +59,7 @@ void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitMa const auto RESOURCE = m_vInhibitors.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), surf)).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vInhibitors.pop_back(); LOGM(ERR, "Failed to create an inhibitor resource"); diff --git a/src/protocols/SinglePixel.cpp b/src/protocols/SinglePixel.cpp index 91154671..2fbfc93d 100644 --- a/src/protocols/SinglePixel.cpp +++ b/src/protocols/SinglePixel.cpp @@ -63,7 +63,7 @@ bool CSinglePixelBuffer::good() { CSinglePixelBufferResource::CSinglePixelBufferResource(uint32_t id, wl_client* client, CHyprColor color) { buffer = makeShared(id, client, color); - if (!buffer->good()) + if UNLIKELY (!buffer->good()) return; buffer->resource->buffer = buffer; @@ -83,7 +83,7 @@ bool CSinglePixelBufferResource::good() { } CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); }); @@ -94,7 +94,7 @@ CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(SP::max()}; const auto RESOURCE = PROTO::singlePixel->m_vBuffers.emplace_back(makeShared(id, resource->client(), color)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { res->noMemory(); PROTO::singlePixel->m_vBuffers.pop_back(); return; @@ -113,7 +113,7 @@ CSinglePixelProtocol::CSinglePixelProtocol(const wl_interface* iface, const int& void CSinglePixelProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/Tablet.cpp b/src/protocols/Tablet.cpp index 2fdd8731..62e8b2d2 100644 --- a/src/protocols/Tablet.cpp +++ b/src/protocols/Tablet.cpp @@ -9,7 +9,7 @@ #include CTabletPadStripV2Resource::CTabletPadStripV2Resource(SP resource_, uint32_t id_) : id(id_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletPadStripV2* r) { PROTO::tablet->destroyResource(this); }); @@ -21,7 +21,7 @@ bool CTabletPadStripV2Resource::good() { } CTabletPadRingV2Resource::CTabletPadRingV2Resource(SP resource_, uint32_t id_) : id(id_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletPadRingV2* r) { PROTO::tablet->destroyResource(this); }); @@ -33,7 +33,7 @@ bool CTabletPadRingV2Resource::good() { } CTabletPadGroupV2Resource::CTabletPadGroupV2Resource(SP resource_, size_t idx_) : idx(idx_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletPadGroupV2* r) { PROTO::tablet->destroyResource(this); }); @@ -58,7 +58,7 @@ void CTabletPadGroupV2Resource::sendData(SP pad, SPm_vStrips.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), i)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::tablet->m_vStrips.pop_back(); return; @@ -71,7 +71,7 @@ void CTabletPadGroupV2Resource::sendData(SP pad, SPm_vRings.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), i)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::tablet->m_vRings.pop_back(); return; @@ -84,7 +84,7 @@ void CTabletPadGroupV2Resource::sendData(SP pad, SP resource_, SP pad_, SP seat_) : pad(pad_), seat(seat_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletPadV2* r) { PROTO::tablet->destroyResource(this); }); @@ -114,7 +114,7 @@ void CTabletPadV2Resource::createGroup(SPm_vGroups.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), idx)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::tablet->m_vGroups.pop_back(); return; @@ -126,7 +126,7 @@ void CTabletPadV2Resource::createGroup(SP resource_, SP tablet_, SP seat_) : tablet(tablet_), seat(seat_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletV2* r) { PROTO::tablet->destroyResource(this); }); @@ -149,7 +149,7 @@ void CTabletV2Resource::sendData() { } CTabletToolV2Resource::CTabletToolV2Resource(SP resource_, SP tool_, SP seat_) : tool(tool_), seat(seat_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); }); @@ -228,7 +228,7 @@ void CTabletToolV2Resource::sendFrame(bool removeSource) { } CTabletSeat::CTabletSeat(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpTabletSeatV2* r) { PROTO::tablet->destroyResource(this); }); @@ -243,7 +243,7 @@ void CTabletSeat::sendTool(SP tool) { const auto RESOURCE = PROTO::tablet->m_vTools.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), tool, self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::tablet->m_vTools.pop_back(); return; @@ -259,7 +259,7 @@ void CTabletSeat::sendPad(SP pad) { const auto RESOURCE = PROTO::tablet->m_vPads.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), pad, self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::tablet->m_vPads.pop_back(); return; @@ -275,7 +275,7 @@ void CTabletSeat::sendTablet(SP tablet) { const auto RESOURCE = PROTO::tablet->m_vTablets.emplace_back(makeShared(makeShared(resource->client(), resource->version(), 0), tablet, self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); PROTO::tablet->m_vTablets.pop_back(); return; @@ -357,7 +357,7 @@ void CTabletV2Protocol::destroyResource(CTabletPadStripV2Resource* resource) { void CTabletV2Protocol::onGetSeat(CZwpTabletManagerV2* pMgr, uint32_t id, wl_resource* seat) { const auto RESOURCE = m_vSeats.emplace_back(makeShared(makeShared(pMgr->client(), pMgr->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vSeats.pop_back(); return; diff --git a/src/protocols/TearingControl.cpp b/src/protocols/TearingControl.cpp index eb1a53cb..14c80052 100644 --- a/src/protocols/TearingControl.cpp +++ b/src/protocols/TearingControl.cpp @@ -27,7 +27,7 @@ void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) { void CTearingControlProtocol::onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, SP surf) { const auto CONTROLLER = m_vTearingControllers.emplace_back(std::make_unique(makeShared(client, pMgr->version(), id), surf)).get(); - if (!CONTROLLER->good()) { + if UNLIKELY (!CONTROLLER->good()) { pMgr->noMemory(); m_vTearingControllers.pop_back(); return; @@ -67,7 +67,7 @@ void CTearingControl::onHint(wpTearingControlV1PresentationHint hint_) { } void CTearingControl::updateWindow() { - if (pWindow.expired()) + if UNLIKELY (pWindow.expired()) return; pWindow->m_bTearingHint = hint == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC; diff --git a/src/protocols/TextInputV1.cpp b/src/protocols/TextInputV1.cpp index b8eb5835..4bf5e9e1 100644 --- a/src/protocols/TextInputV1.cpp +++ b/src/protocols/TextInputV1.cpp @@ -7,13 +7,13 @@ CTextInputV1::~CTextInputV1() { } CTextInputV1::CTextInputV1(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CZwpTextInputV1* pMgr) { PROTO::textInputV1->destroyResource(this); }); resource->setActivate([this](CZwpTextInputV1* pMgr, wl_resource* seat, wl_resource* surface) { - if (!surface) { + if UNLIKELY (!surface) { LOGM(WARN, "Text-input-v1 PTI{:x}: No surface to activate text input on!", (uintptr_t)this); return; } @@ -105,7 +105,7 @@ void CTextInputV1Protocol::bindManager(wl_client* client, void* data, uint32_t v const auto PTI = m_vClients.emplace_back(makeShared(makeShared(pMgr->client(), pMgr->version(), id))); LOGM(LOG, "New TI V1 at {:x}", (uintptr_t)PTI.get()); - if (!PTI->good()) { + if UNLIKELY (!PTI->good()) { LOGM(ERR, "Could not alloc wl_resource for TIV1"); pMgr->noMemory(); PROTO::textInputV1->destroyResource(PTI.get()); diff --git a/src/protocols/TextInputV3.cpp b/src/protocols/TextInputV3.cpp index 30374104..71ef6dac 100644 --- a/src/protocols/TextInputV3.cpp +++ b/src/protocols/TextInputV3.cpp @@ -10,7 +10,7 @@ void CTextInputV3::SState::reset() { } CTextInputV3::CTextInputV3(SP resource_) : resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; LOGM(LOG, "New tiv3 at {:016x}", (uintptr_t)this); @@ -129,7 +129,7 @@ void CTextInputV3Protocol::onGetTextInput(CZwpTextInputManagerV3* pMgr, uint32_t const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vTextInputs.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vTextInputs.pop_back(); LOGM(ERR, "Failed to create a tiv3 resource"); diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 8e34cf4b..2d40cb78 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -13,7 +13,7 @@ #include CToplevelExportClient::CToplevelExportClient(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); }); @@ -35,7 +35,7 @@ void CToplevelExportClient::captureToplevel(CHyprlandToplevelExportManagerV1* pM const auto FRAME = PROTO::toplevelExport->m_vFrames.emplace_back( makeShared(makeShared(resource->client(), resource->version(), frame), overlayCursor_, handle)); - if (!FRAME->good()) { + if UNLIKELY (!FRAME->good()) { LOGM(ERR, "Couldn't alloc frame for sharing! (no memory)"); resource->noMemory(); PROTO::toplevelExport->destroyResource(FRAME.get()); @@ -78,19 +78,19 @@ CToplevelExportFrame::~CToplevelExportFrame() { } CToplevelExportFrame::CToplevelExportFrame(SP resource_, int32_t overlayCursor_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) { - if (!good()) + if UNLIKELY (!good()) return; cursorOverlayRequested = !!overlayCursor_; - if (!pWindow) { + if UNLIKELY (!pWindow) { LOGM(ERR, "Client requested sharing of window handle {:x} which does not exist!", pWindow); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); return; } - if (!pWindow->m_bIsMapped) { + if UNLIKELY (!pWindow->m_bIsMapped) { LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable!", pWindow); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); @@ -106,7 +106,7 @@ CToplevelExportFrame::CToplevelExportFrame(SP re g_pHyprRenderer->makeEGLCurrent(); shmFormat = g_pHyprOpenGL->getPreferredReadFormat(PMONITOR); - if (shmFormat == DRM_FORMAT_INVALID) { + if UNLIKELY (shmFormat == DRM_FORMAT_INVALID) { LOGM(ERR, "No format supported by renderer in capture toplevel"); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); @@ -114,7 +114,7 @@ CToplevelExportFrame::CToplevelExportFrame(SP re } const auto PSHMINFO = NFormatUtils::getPixelFormatFromDRM(shmFormat); - if (!PSHMINFO) { + if UNLIKELY (!PSHMINFO) { LOGM(ERR, "No pixel format supported by renderer in capture toplevel"); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); @@ -131,27 +131,26 @@ CToplevelExportFrame::CToplevelExportFrame(SP re resource->sendBuffer(NFormatUtils::drmToShm(shmFormat), box.width, box.height, shmStride); - if (dmabufFormat != DRM_FORMAT_INVALID) { + if LIKELY (dmabufFormat != DRM_FORMAT_INVALID) resource->sendLinuxDmabuf(dmabufFormat, box.width, box.height); - } resource->sendBufferDone(); } void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resource* buffer_, int32_t ignoreDamage) { - if (!good()) { + if UNLIKELY (!good()) { LOGM(ERR, "No frame in copyFrame??"); return; } - if (!validMapped(pWindow)) { + if UNLIKELY (!validMapped(pWindow)) { LOGM(ERR, "Client requested sharing of window handle {:x} which is gone!", pWindow); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); return; } - if (!pWindow->m_bIsMapped) { + if UNLIKELY (!pWindow->m_bIsMapped) { LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", pWindow); resource->sendFailed(); PROTO::toplevelExport->destroyResource(this); @@ -159,7 +158,7 @@ void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resou } const auto PBUFFER = CWLBufferResource::fromResource(buffer_); - if (!PBUFFER) { + if UNLIKELY (!PBUFFER) { resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer"); PROTO::toplevelExport->destroyResource(this); return; @@ -167,13 +166,13 @@ void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resou PBUFFER->buffer->lock(); - if (PBUFFER->buffer->size != box.size()) { + if UNLIKELY (PBUFFER->buffer->size != box.size()) { resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions"); PROTO::toplevelExport->destroyResource(this); return; } - if (buffer) { + if UNLIKELY (buffer) { resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_ALREADY_USED, "frame already used"); PROTO::toplevelExport->destroyResource(this); return; diff --git a/src/protocols/Viewporter.cpp b/src/protocols/Viewporter.cpp index 58cb851d..4964bead 100644 --- a/src/protocols/Viewporter.cpp +++ b/src/protocols/Viewporter.cpp @@ -3,14 +3,14 @@ #include CViewportResource::CViewportResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CWpViewport* r) { PROTO::viewport->destroyResource(this); }); resource->setOnDestroy([this](CWpViewport* r) { PROTO::viewport->destroyResource(this); }); resource->setSetDestination([this](CWpViewport* r, int32_t x, int32_t y) { - if (!surface) { + if UNLIKELY (!surface) { r->error(WP_VIEWPORT_ERROR_NO_SURFACE, "Surface is gone"); return; } @@ -20,7 +20,7 @@ CViewportResource::CViewportResource(SP resource_, SPerror(WP_VIEWPORT_ERROR_BAD_SIZE, "Size was <= 0"); return; } @@ -30,7 +30,7 @@ CViewportResource::CViewportResource(SP resource_, SPsetSetSource([this](CWpViewport* r, wl_fixed_t fx, wl_fixed_t fy, wl_fixed_t fw, wl_fixed_t fh) { - if (!surface) { + if UNLIKELY (!surface) { r->error(WP_VIEWPORT_ERROR_NO_SURFACE, "Surface is gone"); return; } @@ -42,7 +42,7 @@ CViewportResource::CViewportResource(SP resource_, SPerror(WP_VIEWPORT_ERROR_BAD_SIZE, "Pos was < 0"); return; } @@ -80,7 +80,7 @@ bool CViewportResource::good() { } CViewporterResource::CViewporterResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CWpViewporter* r) { PROTO::viewport->destroyResource(this); }); @@ -90,7 +90,7 @@ CViewporterResource::CViewporterResource(SP resource_) : resource const auto RESOURCE = PROTO::viewport->m_vViewports.emplace_back( makeShared(makeShared(r->client(), r->version(), id), CWLSurfaceResource::fromResource(surf))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::viewport->m_vViewports.pop_back(); return; @@ -109,7 +109,7 @@ CViewporterProtocol::CViewporterProtocol(const wl_interface* iface, const int& v void CViewporterProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp index bb51315d..7da1fe01 100644 --- a/src/protocols/VirtualKeyboard.cpp +++ b/src/protocols/VirtualKeyboard.cpp @@ -3,7 +3,7 @@ #include "../devices/IKeyboard.hpp" CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwpVirtualKeyboardV1* r) { @@ -18,7 +18,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP }); resource->setKey([this](CZwpVirtualKeyboardV1* r, uint32_t timeMs, uint32_t key, uint32_t state) { - if (!hasKeymap) { + if UNLIKELY (!hasKeymap) { r->error(ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP, "Key event received before a keymap was set"); return; } @@ -37,7 +37,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP }); resource->setModifiers([this](CZwpVirtualKeyboardV1* r, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) { - if (!hasKeymap) { + if UNLIKELY (!hasKeymap) { r->error(ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP, "Mods event received before a keymap was set"); return; } @@ -52,7 +52,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP resource->setKeymap([this](CZwpVirtualKeyboardV1* r, uint32_t fmt, int32_t fd, uint32_t len) { auto xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!xkbContext) { + if UNLIKELY (!xkbContext) { LOGM(ERR, "xkbContext creation failed"); r->noMemory(); close(fd); @@ -60,7 +60,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP } auto keymapData = mmap(nullptr, len, PROT_READ, MAP_PRIVATE, fd, 0); - if (keymapData == MAP_FAILED) { + if UNLIKELY (keymapData == MAP_FAILED) { LOGM(ERR, "keymapData alloc failed"); xkb_context_unref(xkbContext); r->noMemory(); @@ -71,7 +71,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP auto xkbKeymap = xkb_keymap_new_from_string(xkbContext, (const char*)keymapData, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(keymapData, len); - if (!xkbKeymap) { + if UNLIKELY (!xkbKeymap) { LOGM(ERR, "xkbKeymap creation failed"); xkb_context_unref(xkbContext); r->noMemory(); @@ -142,7 +142,7 @@ void CVirtualKeyboardProtocol::onCreateKeeb(CZwpVirtualKeyboardManagerV1* pMgr, const auto RESOURCE = m_vKeyboards.emplace_back(makeShared(makeShared(pMgr->client(), pMgr->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vKeyboards.pop_back(); return; diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp index 4c5aa13a..3e0b00eb 100644 --- a/src/protocols/VirtualPointer.cpp +++ b/src/protocols/VirtualPointer.cpp @@ -2,7 +2,7 @@ #include "core/Output.hpp" CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP resource_, PHLMONITORREF boundOutput_) : boundOutput(boundOutput_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CZwlrVirtualPointerV1* r) { @@ -41,7 +41,7 @@ CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP r }); resource->setAxis([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_, wl_fixed_t value) { - if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) { + if UNLIKELY (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) { r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis"); return; } @@ -64,7 +64,7 @@ CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP r resource->setAxisSource([this](CZwlrVirtualPointerV1* r, uint32_t source) { axisEvents[axis].source = (wl_pointer_axis_source)source; }); resource->setAxisStop([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_) { - if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) { + if UNLIKELY (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) { r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis"); return; } @@ -77,7 +77,7 @@ CVirtualPointerV1Resource::CVirtualPointerV1Resource(SP r }); resource->setAxisDiscrete([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_, wl_fixed_t value, int32_t discrete) { - if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) { + if UNLIKELY (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) { r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis"); return; } @@ -138,7 +138,7 @@ void CVirtualPointerProtocol::onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr const auto RESOURCE = m_vPointers.emplace_back(makeShared(makeShared(pMgr->client(), pMgr->version(), id), output)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vPointers.pop_back(); return; diff --git a/src/protocols/WaylandProtocol.cpp b/src/protocols/WaylandProtocol.cpp index 5c6a4a56..7fef5179 100644 --- a/src/protocols/WaylandProtocol.cpp +++ b/src/protocols/WaylandProtocol.cpp @@ -20,7 +20,7 @@ void IWaylandProtocol::onDisplayDestroy() { IWaylandProtocol::IWaylandProtocol(const wl_interface* iface, const int& ver, const std::string& name) : m_szName(name), m_pGlobal(wl_global_create(g_pCompositor->m_sWLDisplay, iface, ver, this, &bindManagerInternal)) { - if (!m_pGlobal) { + if UNLIKELY (!m_pGlobal) { LOGM(ERR, "could not create a global [{}]", m_szName); return; } diff --git a/src/protocols/XDGActivation.cpp b/src/protocols/XDGActivation.cpp index 4a6c7bfe..c49dc3dc 100644 --- a/src/protocols/XDGActivation.cpp +++ b/src/protocols/XDGActivation.cpp @@ -5,7 +5,7 @@ #include CXDGActivationToken::CXDGActivationToken(SP resource_) : resource(resource_) { - if (!resource_->resource()) + if UNLIKELY (!resource_->resource()) return; resource->setDestroy([this](CXdgActivationTokenV1* r) { PROTO::activation->destroyToken(this); }); @@ -18,7 +18,7 @@ CXDGActivationToken::CXDGActivationToken(SP resource_) : resource->setCommit([this](CXdgActivationTokenV1* r) { // TODO: should we send a protocol error of already_used here // if it was used? the protocol spec doesn't say _when_ it should be sent... - if (committed) { + if UNLIKELY (committed) { LOGM(WARN, "possible protocol error, two commits from one token. Ignoring."); return; } @@ -36,7 +36,7 @@ CXDGActivationToken::CXDGActivationToken(SP resource_) : auto count = std::count_if(PROTO::activation->m_vSentTokens.begin(), PROTO::activation->m_vSentTokens.end(), [this](const auto& other) { return other.client == resource->client(); }); - if (count > 10) { + if UNLIKELY (count > 10) { // remove first token. Too many, dear app. for (auto i = PROTO::activation->m_vSentTokens.begin(); i != PROTO::activation->m_vSentTokens.end(); ++i) { if (i->client == resource->client()) { @@ -70,7 +70,7 @@ void CXDGActivationProtocol::bindManager(wl_client* client, void* data, uint32_t RESOURCE->setActivate([this](CXdgActivationV1* pMgr, const char* token, wl_resource* surface) { auto TOKEN = std::find_if(m_vSentTokens.begin(), m_vSentTokens.end(), [token](const auto& t) { return t.token == token; }); - if (TOKEN == m_vSentTokens.end()) { + if UNLIKELY (TOKEN == m_vSentTokens.end()) { LOGM(WARN, "activate event for non-existent token {}??", token); return; } @@ -81,7 +81,7 @@ void CXDGActivationProtocol::bindManager(wl_client* client, void* data, uint32_t SP surf = CWLSurfaceResource::fromResource(surface); const auto PWINDOW = g_pCompositor->getWindowFromSurface(surf); - if (!PWINDOW) { + if UNLIKELY (!PWINDOW) { LOGM(WARN, "activate event for non-window or gone surface with token {}, ignoring", token); return; } @@ -102,7 +102,7 @@ void CXDGActivationProtocol::onGetToken(CXdgActivationV1* pMgr, uint32_t id) { const auto CLIENT = pMgr->client(); const auto RESOURCE = m_vTokens.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_vTokens.pop_back(); return; diff --git a/src/protocols/XDGDecoration.cpp b/src/protocols/XDGDecoration.cpp index 07b1694c..8ec0d5b0 100644 --- a/src/protocols/XDGDecoration.cpp +++ b/src/protocols/XDGDecoration.cpp @@ -2,7 +2,7 @@ #include CXDGDecoration::CXDGDecoration(SP resource_, wl_resource* toplevel) : resource(resource_), pToplevelResource(toplevel) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([this](CZxdgToplevelDecorationV1* pMgr) { PROTO::xdgDecoration->destroyDecoration(this); }); @@ -57,7 +57,7 @@ void CXDGDecorationProtocol::destroyDecoration(CXDGDecoration* decoration) { } void CXDGDecorationProtocol::onGetDecoration(CZxdgDecorationManagerV1* pMgr, uint32_t id, wl_resource* xdgToplevel) { - if (m_mDecorations.contains(xdgToplevel)) { + if UNLIKELY (m_mDecorations.contains(xdgToplevel)) { pMgr->error(ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED, "Decoration object already exists"); return; } @@ -66,7 +66,7 @@ void CXDGDecorationProtocol::onGetDecoration(CZxdgDecorationManagerV1* pMgr, uin const auto RESOURCE = m_mDecorations.emplace(xdgToplevel, std::make_unique(makeShared(CLIENT, pMgr->version(), id), xdgToplevel)).first->second.get(); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); m_mDecorations.erase(xdgToplevel); return; diff --git a/src/protocols/XDGDialog.cpp b/src/protocols/XDGDialog.cpp index 3f58f326..675d4e78 100644 --- a/src/protocols/XDGDialog.cpp +++ b/src/protocols/XDGDialog.cpp @@ -5,7 +5,7 @@ #include CXDGDialogV1Resource::CXDGDialogV1Resource(SP resource_, SP toplevel_) : resource(resource_), toplevel(toplevel_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CXdgDialogV1* r) { PROTO::xdgDialog->destroyResource(this); }); @@ -23,11 +23,11 @@ CXDGDialogV1Resource::CXDGDialogV1Resource(SP resource_, SPparent || !toplevel->parent->owner) + if UNLIKELY (!toplevel || !toplevel->parent || !toplevel->parent->owner) return; auto HLSurface = CWLSurface::fromResource(toplevel->parent->owner->surface.lock()); - if (!HLSurface || !HLSurface->getWindow()) + if UNLIKELY (!HLSurface || !HLSurface->getWindow()) return; g_pCompositor->updateWindowAnimatedDecorationValues(HLSurface->getWindow()); @@ -38,7 +38,7 @@ bool CXDGDialogV1Resource::good() { } CXDGWmDialogManagerResource::CXDGWmDialogManagerResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CXdgWmDialogV1* r) { PROTO::xdgDialog->destroyResource(this); }); @@ -46,14 +46,14 @@ CXDGWmDialogManagerResource::CXDGWmDialogManagerResource(SP reso resource->setGetXdgDialog([](CXdgWmDialogV1* r, uint32_t id, wl_resource* toplevel) { auto tl = CXDGToplevelResource::fromResource(toplevel); - if (!tl) { + if UNLIKELY (!tl) { r->error(-1, "Toplevel inert"); return; } const auto RESOURCE = PROTO::xdgDialog->m_vDialogs.emplace_back(makeShared(makeShared(r->client(), r->version(), id), tl)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); return; } @@ -73,7 +73,7 @@ CXDGDialogProtocol::CXDGDialogProtocol(const wl_interface* iface, const int& ver void CXDGDialogProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); return; } diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp index fadc48a1..5be16d07 100644 --- a/src/protocols/XDGOutput.cpp +++ b/src/protocols/XDGOutput.cpp @@ -23,7 +23,7 @@ void CXDGOutputProtocol::onOutputResourceDestroy(wl_resource* res) { void CXDGOutputProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagerResources.emplace_back(std::make_unique(client, ver, id)).get(); - if (!RESOURCE->resource()) { + if UNLIKELY (!RESOURCE->resource()) { LOGM(LOG, "Couldn't bind XDGOutputMgr"); wl_client_post_no_memory(client); return; @@ -53,13 +53,13 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(CZxdgOutputManagerV1* mgr, uint32 pXDGOutput->outputProto = OUTPUT->owner; - if (!pXDGOutput->resource->resource()) { + if UNLIKELY (!pXDGOutput->resource->resource()) { m_vXDGOutputs.pop_back(); mgr->noMemory(); return; } - if (!PMONITOR) { + if UNLIKELY (!PMONITOR) { LOGM(ERR, "New xdg_output from client {:x} ({}) has no CMonitor?!", (uintptr_t)CLIENT, pXDGOutput->isXWayland ? "xwayland" : "not xwayland"); return; } @@ -96,7 +96,7 @@ void CXDGOutputProtocol::updateAllOutputs() { // CXDGOutput::CXDGOutput(SP resource_, PHLMONITOR monitor_) : monitor(monitor_), resource(resource_) { - if (!resource->resource()) + if UNLIKELY (!resource->resource()) return; resource->setDestroy([](CZxdgOutputV1* pMgr) { PROTO::xdgOutput->onOutputResourceDestroy(pMgr->resource()); }); @@ -106,7 +106,7 @@ CXDGOutput::CXDGOutput(SP resource_, PHLMONITOR monitor_) : monit void CXDGOutput::sendDetails() { static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); - if (!monitor || !outputProto || outputProto->isDefunct()) + if UNLIKELY (!monitor || !outputProto || outputProto->isDefunct()) return; const auto POS = isXWayland ? monitor->vecXWaylandPosition : monitor->vecPosition; diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index aabb225a..f5d1a8fa 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -26,7 +26,7 @@ void SXDGPositionerState::setGravity(xdgPositionerGravity edges) { CXDGPopupResource::CXDGPopupResource(SP resource_, SP owner_, SP surface_, SP positioner) : surface(surface_), parent(owner_), resource(resource_), positionerRules(positioner) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -79,7 +79,7 @@ void CXDGPopupResource::applyPositioning(const CBox& box, const Vector2D& t1coor configure(geometry); - if (lastRepositionToken) + if UNLIKELY (lastRepositionToken) repositioned(); } @@ -118,7 +118,7 @@ void CXDGPopupResource::done() { } void CXDGPopupResource::repositioned() { - if (!lastRepositionToken) + if LIKELY (!lastRepositionToken) return; LOGM(LOG, "repositioned: sending reposition token {}", lastRepositionToken); @@ -128,7 +128,7 @@ void CXDGPopupResource::repositioned() { } CXDGToplevelResource::CXDGToplevelResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -350,7 +350,7 @@ Vector2D CXDGToplevelResource::layoutMaxSize() { CXDGSurfaceResource::CXDGSurfaceResource(SP resource_, SP owner_, SP surface_) : owner(owner_), surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -386,7 +386,7 @@ CXDGSurfaceResource::CXDGSurfaceResource(SP resource_, SPcurrent = toplevel->pending; - if (initialCommit && surface->pending.texture) { + if UNLIKELY (initialCommit && surface->pending.texture) { resource->error(-1, "Buffer attached before initial commit"); return; } @@ -416,7 +416,7 @@ CXDGSurfaceResource::CXDGSurfaceResource(SP resource_, SPsetGetToplevel([this](CXdgSurface* r, uint32_t id) { const auto RESOURCE = PROTO::xdgShell->m_vToplevels.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::xdgShell->m_vToplevels.pop_back(); return; @@ -442,7 +442,7 @@ CXDGSurfaceResource::CXDGSurfaceResource(SP resource_, SPm_vPopups.emplace_back(makeShared(makeShared(r->client(), r->version(), id), parent, self.lock(), positioner)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::xdgShell->m_vPopups.pop_back(); return; @@ -511,7 +511,7 @@ void CXDGSurfaceResource::configure() { } CXDGPositionerResource::CXDGPositionerResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -520,7 +520,7 @@ CXDGPositionerResource::CXDGPositionerResource(SP resource_, SP< resource->setOnDestroy([this](CXdgPositioner* r) { PROTO::xdgShell->destroyResource(this); }); resource->setSetSize([this](CXdgPositioner* r, int32_t x, int32_t y) { - if (x <= 0 || y <= 0) { + if UNLIKELY (x <= 0 || y <= 0) { r->error(XDG_POSITIONER_ERROR_INVALID_INPUT, "Invalid size"); return; } @@ -529,7 +529,7 @@ CXDGPositionerResource::CXDGPositionerResource(SP resource_, SP< }); resource->setSetAnchorRect([this](CXdgPositioner* r, int32_t x, int32_t y, int32_t w, int32_t h) { - if (w <= 0 || h <= 0) { + if UNLIKELY (w <= 0 || h <= 0) { r->error(XDG_POSITIONER_ERROR_INVALID_INPUT, "Invalid box"); return; } @@ -686,7 +686,7 @@ CBox CXDGPositionerRules::getPosition(CBox constraint, const Vector2D& parentCoo } CXDGWMBase::CXDGWMBase(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CXdgWmBase* r) { PROTO::xdgShell->destroyResource(this); }); @@ -698,7 +698,7 @@ CXDGWMBase::CXDGWMBase(SP resource_) : resource(resource_) { const auto RESOURCE = PROTO::xdgShell->m_vPositioners.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::xdgShell->m_vPositioners.pop_back(); return; @@ -714,19 +714,19 @@ CXDGWMBase::CXDGWMBase(SP resource_) : resource(resource_) { resource->setGetXdgSurface([this](CXdgWmBase* r, uint32_t id, wl_resource* surf) { auto SURF = CWLSurfaceResource::fromResource(surf); - if (!SURF) { + if UNLIKELY (!SURF) { r->error(-1, "Invalid surface passed"); return; } - if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) { + if UNLIKELY (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) { r->error(-1, "Surface already has a different role"); return; } const auto RESOURCE = PROTO::xdgShell->m_vSurfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock(), SURF)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::xdgShell->m_vSurfaces.pop_back(); return; @@ -765,7 +765,7 @@ CXDGShellProtocol::CXDGShellProtocol(const wl_interface* iface, const int& ver, void CXDGShellProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vWMBases.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vWMBases.pop_back(); return; diff --git a/src/protocols/XWaylandShell.cpp b/src/protocols/XWaylandShell.cpp index 81194163..b4615e19 100644 --- a/src/protocols/XWaylandShell.cpp +++ b/src/protocols/XWaylandShell.cpp @@ -3,7 +3,7 @@ #include CXWaylandSurfaceResource::CXWaylandSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CXwaylandSurfaceV1* r) { @@ -36,7 +36,7 @@ wl_client* CXWaylandSurfaceResource::client() { } CXWaylandShellResource::CXWaylandShellResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CXwaylandShellV1* r) { PROTO::xwaylandShell->destroyResource(this); }); @@ -46,7 +46,7 @@ CXWaylandShellResource::CXWaylandShellResource(SP resource_) : const auto RESOURCE = PROTO::xwaylandShell->m_vSurfaces.emplace_back( makeShared(makeShared(r->client(), r->version(), id), CWLSurfaceResource::fromResource(surface))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::xwaylandShell->m_vSurfaces.pop_back(); return; @@ -67,7 +67,7 @@ CXWaylandShellProtocol::CXWaylandShellProtocol(const wl_interface* iface, const void CXWaylandShellProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index e1d6ef7d..93683993 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -34,7 +34,7 @@ void CWLCallbackResource::send(timespec* now) { } CWLRegionResource::CWLRegionResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -56,7 +56,7 @@ SP CWLRegionResource::fromResource(wl_resource* res) { } CWLSurfaceResource::CWLSurfaceResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; pClient = resource->client(); @@ -187,20 +187,20 @@ void CWLSurfaceResource::enter(PHLMONITOR monitor) { if (std::find(enteredOutputs.begin(), enteredOutputs.end(), monitor) != enteredOutputs.end()) return; - if (!PROTO::outputs.contains(monitor->szName)) { + if UNLIKELY (!PROTO::outputs.contains(monitor->szName)) { // can happen on unplug/replug LOGM(ERR, "enter() called on a non-existent output global"); return; } - if (PROTO::outputs.at(monitor->szName)->isDefunct()) { + if UNLIKELY (PROTO::outputs.at(monitor->szName)->isDefunct()) { LOGM(ERR, "enter() called on a defunct output global"); return; } auto output = PROTO::outputs.at(monitor->szName)->outputResourceFrom(pClient); - if (!output || !output->getResource() || !output->getResource()->resource()) { + if UNLIKELY (!output || !output->getResource() || !output->getResource()->resource()) { LOGM(ERR, "Cannot enter surface {:x} to {}, client hasn't bound the output", (uintptr_t)this, monitor->szName); return; } @@ -211,12 +211,12 @@ void CWLSurfaceResource::enter(PHLMONITOR monitor) { } void CWLSurfaceResource::leave(PHLMONITOR monitor) { - if (std::find(enteredOutputs.begin(), enteredOutputs.end(), monitor) == enteredOutputs.end()) + if UNLIKELY (std::find(enteredOutputs.begin(), enteredOutputs.end(), monitor) == enteredOutputs.end()) return; auto output = PROTO::outputs.at(monitor->szName)->outputResourceFrom(pClient); - if (!output) { + if UNLIKELY (!output) { LOGM(ERR, "Cannot leave surface {:x} from {}, client hasn't bound the output", (uintptr_t)this, monitor->szName); return; } @@ -332,7 +332,7 @@ uint32_t CWLSurfaceResource::id() { } void CWLSurfaceResource::map() { - if (mapped) + if UNLIKELY (mapped) return; mapped = true; @@ -346,7 +346,7 @@ void CWLSurfaceResource::map() { } void CWLSurfaceResource::unmap() { - if (!mapped) + if UNLIKELY (!mapped) return; mapped = false; @@ -385,10 +385,10 @@ CBox CWLSurfaceResource::extends() { } Vector2D CWLSurfaceResource::sourceSize() { - if (!current.texture) + if UNLIKELY (!current.texture) return {}; - if (current.viewport.hasSource) + if UNLIKELY (current.viewport.hasSource) return current.viewport.source.size(); Vector2D trc = current.transform % 2 == 1 ? Vector2D{current.bufferSize.y, current.bufferSize.x} : current.bufferSize; @@ -396,7 +396,7 @@ Vector2D CWLSurfaceResource::sourceSize() { } CRegion CWLSurfaceResource::accumulateCurrentBufferDamage() { - if (!current.texture) + if UNLIKELY (!current.texture) return {}; CRegion surfaceDamage = current.damage; @@ -495,7 +495,7 @@ void CWLSurfaceResource::commitPendingState() { void CWLSurfaceResource::updateCursorShm(CRegion damage) { auto buf = current.buffer ? current.buffer->buffer : lastBuffer; - if (!buf) + if UNLIKELY (!buf) return; auto& shmData = CCursorSurfaceRole::cursorPixelData(self.lock()); @@ -545,7 +545,7 @@ void CWLSurfaceResource::presentFeedback(timespec* when, PHLMONITOR pMonitor, bo } CWLCompositorResource::CWLCompositorResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlCompositor* r) { PROTO::compositor->destroyResource(this); }); @@ -553,7 +553,7 @@ CWLCompositorResource::CWLCompositorResource(SP resource_) : reso resource->setCreateSurface([](CWlCompositor* r, uint32_t id) { const auto RESOURCE = PROTO::compositor->m_vSurfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::compositor->m_vSurfaces.pop_back(); return; @@ -569,7 +569,7 @@ CWLCompositorResource::CWLCompositorResource(SP resource_) : reso resource->setCreateRegion([](CWlCompositor* r, uint32_t id) { const auto RESOURCE = PROTO::compositor->m_vRegions.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::compositor->m_vRegions.pop_back(); return; @@ -592,7 +592,7 @@ CWLCompositorProtocol::CWLCompositorProtocol(const wl_interface* iface, const in void CWLCompositorProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index fd3cd1fa..ade16498 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -15,7 +15,7 @@ #include "../../render/Renderer.hpp" CWLDataOfferResource::CWLDataOfferResource(SP resource_, SP source_) : source(source_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setDestroy([this](CWlDataOffer* r) { PROTO::data->destroyResource(this); }); @@ -127,7 +127,7 @@ SP CWLDataOfferResource::getSource() { } CWLDataSourceResource::CWLDataSourceResource(SP resource_, SP device_) : device(device_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -237,7 +237,7 @@ eDataSourceType CWLDataSourceResource::type() { } CWLDataDeviceResource::CWLDataDeviceResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](CWlDataDevice* r) { PROTO::data->destroyResource(this); }); @@ -333,7 +333,7 @@ SP CWLDataDeviceResource::getX11() { } CWLDataDeviceManagerResource::CWLDataDeviceManagerResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlDataDeviceManager* r) { PROTO::data->destroyResource(this); }); @@ -343,7 +343,7 @@ CWLDataDeviceManagerResource::CWLDataDeviceManagerResource(SPm_vSources.emplace_back(makeShared(makeShared(r->client(), r->version(), id), device.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::data->m_vSources.pop_back(); return; @@ -362,7 +362,7 @@ CWLDataDeviceManagerResource::CWLDataDeviceManagerResource(SPsetGetDataDevice([this](CWlDataDeviceManager* r, uint32_t id, wl_resource* seat) { const auto RESOURCE = PROTO::data->m_vDevices.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::data->m_vDevices.pop_back(); return; @@ -394,7 +394,7 @@ CWLDataDeviceProtocol::CWLDataDeviceProtocol(const wl_interface* iface, const in void CWLDataDeviceProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; @@ -441,7 +441,7 @@ void CWLDataDeviceProtocol::sendSelectionToDevice(SP dev, SPgetWayland(); WL) { const auto OFFER = m_vOffers.emplace_back(makeShared(makeShared(WL->resource->client(), WL->resource->version(), 0), sel)); - if (!OFFER->good()) { + if UNLIKELY (!OFFER->good()) { WL->resource->noMemory(); m_vOffers.pop_back(); return; @@ -455,7 +455,7 @@ void CWLDataDeviceProtocol::sendSelectionToDevice(SP dev, SPpWM->createX11DataOffer(g_pSeatManager->state.keyboardFocus.lock(), sel); #endif - if (!offer) { + if UNLIKELY (!offer) { LOGM(ERR, "No offer could be created in sendSelectionToDevice"); return; } diff --git a/src/protocols/core/Output.cpp b/src/protocols/core/Output.cpp index db580457..77f0661e 100644 --- a/src/protocols/core/Output.cpp +++ b/src/protocols/core/Output.cpp @@ -4,7 +4,7 @@ #include "../../helpers/Monitor.hpp" CWLOutputResource::CWLOutputResource(SP resource_, PHLMONITOR pMonitor) : monitor(pMonitor), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setData(this); @@ -94,12 +94,12 @@ CWLOutputProtocol::CWLOutputProtocol(const wl_interface* iface, const int& ver, } void CWLOutputProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - if (defunct) + if UNLIKELY (defunct) Debug::log(WARN, "[wl_output] Binding a wl_output that's inert?? Possible client bug."); const auto RESOURCE = m_vOutputs.emplace_back(makeShared(makeShared(client, ver, id), monitor.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vOutputs.pop_back(); return; @@ -128,7 +128,7 @@ SP CWLOutputProtocol::outputResourceFrom(wl_client* client) { } void CWLOutputProtocol::remove() { - if (defunct) + if UNLIKELY (defunct) return; defunct = true; @@ -140,7 +140,7 @@ bool CWLOutputProtocol::isDefunct() { } void CWLOutputProtocol::sendDone() { - if (defunct) + if UNLIKELY (defunct) return; for (auto const& r : m_vOutputs) { diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index f7969a4d..c6b2de05 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -10,7 +10,7 @@ #include CWLTouchResource::CWLTouchResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](CWlTouch* r) { PROTO::seat->destroyResource(this); }); @@ -105,7 +105,7 @@ void CWLTouchResource::sendOrientation(int32_t id, double angle) { } CWLPointerResource::CWLPointerResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](CWlPointer* r) { PROTO::seat->destroyResource(this); }); @@ -292,7 +292,7 @@ void CWLPointerResource::sendAxisRelativeDirection(wl_pointer_axis axis, wl_poin } CWLKeyboardResource::CWLKeyboardResource(SP resource_, SP owner_) : owner(owner_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setRelease([this](CWlKeyboard* r) { PROTO::seat->destroyResource(this); }); @@ -419,7 +419,7 @@ void CWLKeyboardResource::repeatInfo(uint32_t rate, uint32_t delayMs) { } CWLSeatResource::CWLSeatResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlSeat* r) { @@ -436,7 +436,7 @@ CWLSeatResource::CWLSeatResource(SP resource_) : resource(resource_) { resource->setGetKeyboard([this](CWlSeat* r, uint32_t id) { const auto RESOURCE = PROTO::seat->m_vKeyboards.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::seat->m_vKeyboards.pop_back(); return; @@ -448,7 +448,7 @@ CWLSeatResource::CWLSeatResource(SP resource_) : resource(resource_) { resource->setGetPointer([this](CWlSeat* r, uint32_t id) { const auto RESOURCE = PROTO::seat->m_vPointers.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::seat->m_vPointers.pop_back(); return; @@ -460,7 +460,7 @@ CWLSeatResource::CWLSeatResource(SP resource_) : resource(resource_) { resource->setGetTouch([this](CWlSeat* r, uint32_t id) { const auto RESOURCE = PROTO::seat->m_vTouches.emplace_back(makeShared(makeShared(r->client(), r->version(), id), self.lock())); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::seat->m_vTouches.pop_back(); return; @@ -506,7 +506,7 @@ CWLSeatProtocol::CWLSeatProtocol(const wl_interface* iface, const int& ver, cons void CWLSeatProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vSeatResources.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vSeatResources.pop_back(); return; diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp index 6365c5d6..28585aeb 100644 --- a/src/protocols/core/Shm.cpp +++ b/src/protocols/core/Shm.cpp @@ -9,7 +9,7 @@ #include "../../render/Renderer.hpp" CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t offset_, const Vector2D& size_, int32_t stride_, uint32_t fmt_) { - if (!pool_->pool->data) + if UNLIKELY (!pool_->pool->data) return; g_pHyprRenderer->makeEGLCurrent(); @@ -32,7 +32,7 @@ CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t of success = texture->m_iTexID; - if (!success) + if UNLIKELY (!success) Debug::log(ERR, "Failed creating a shm texture: null texture id"); } @@ -96,13 +96,13 @@ void CSHMPool::resize(size_t size_) { size = size_; data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) + if UNLIKELY (data == MAP_FAILED) LOGM(ERR, "Couldn't mmap {} bytes from fd {} of shm client", size, fd); } static int shmIsSizeValid(int fd, size_t size) { struct stat st; - if (fstat(fd, &st) == -1) { + if UNLIKELY (fstat(fd, &st) == -1) { LOGM(ERR, "Couldn't get stat for fd {} of shm client", fd); return 0; } @@ -111,10 +111,10 @@ static int shmIsSizeValid(int fd, size_t size) { } CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, int fd_, size_t size_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; - if (!shmIsSizeValid(fd_, size_)) { + if UNLIKELY (!shmIsSizeValid(fd_, size_)) { resource_->error(-1, "The size of the file is not big enough for the shm pool"); return; } @@ -125,11 +125,11 @@ CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, int fd_, size_t resource->setOnDestroy([this](CWlShmPool* r) { PROTO::shm->destroyResource(this); }); resource->setResize([this](CWlShmPool* r, int32_t size_) { - if (size_ < (int32_t)pool->size) { + if UNLIKELY (size_ < (int32_t)pool->size) { r->error(-1, "Shrinking a shm pool is illegal"); return; } - if (!shmIsSizeValid(pool->fd, size_)) { + if UNLIKELY (!shmIsSizeValid(pool->fd, size_)) { r->error(-1, "The size of the file is not big enough for the shm pool"); return; } @@ -138,24 +138,24 @@ CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, int fd_, size_t }); resource->setCreateBuffer([this](CWlShmPool* r, uint32_t id, int32_t offset, int32_t w, int32_t h, int32_t stride, uint32_t fmt) { - if (!pool || !pool->data) { + if UNLIKELY (!pool || !pool->data) { r->error(-1, "The provided shm pool failed to allocate properly"); return; } - if (std::find(PROTO::shm->shmFormats.begin(), PROTO::shm->shmFormats.end(), fmt) == PROTO::shm->shmFormats.end()) { + if UNLIKELY (std::find(PROTO::shm->shmFormats.begin(), PROTO::shm->shmFormats.end(), fmt) == PROTO::shm->shmFormats.end()) { r->error(WL_SHM_ERROR_INVALID_FORMAT, "Format invalid"); return; } - if (offset < 0 || w <= 0 || h <= 0 || stride <= 0) { + if UNLIKELY (offset < 0 || w <= 0 || h <= 0 || stride <= 0) { r->error(WL_SHM_ERROR_INVALID_STRIDE, "Invalid stride, w, h, or offset"); return; } const auto RESOURCE = PROTO::shm->m_vBuffers.emplace_back(makeShared(self.lock(), id, offset, Vector2D{w, h}, stride, fmt)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::shm->m_vBuffers.pop_back(); return; @@ -165,7 +165,7 @@ CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, int fd_, size_t RESOURCE->resource->buffer = RESOURCE; }); - if (pool->data == MAP_FAILED) + if UNLIKELY (pool->data == MAP_FAILED) resource->error(WL_SHM_ERROR_INVALID_FD, "Couldn't mmap from fd"); } @@ -174,7 +174,7 @@ bool CWLSHMPoolResource::good() { } CWLSHMResource::CWLSHMResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlShm* r) { PROTO::shm->destroyResource(this); }); @@ -182,7 +182,7 @@ CWLSHMResource::CWLSHMResource(SP resource_) : resource(resource_) { resource->setCreatePool([](CWlShm* r, uint32_t id, int32_t fd, int32_t size) { const auto RESOURCE = PROTO::shm->m_vPools.emplace_back(makeShared(makeShared(r->client(), r->version(), id), fd, size)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::shm->m_vPools.pop_back(); return; @@ -221,7 +221,7 @@ void CWLSHMProtocol::bindManager(wl_client* client, void* data, uint32_t ver, ui const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/core/Subcompositor.cpp b/src/protocols/core/Subcompositor.cpp index 46e20305..4edb07ff 100644 --- a/src/protocols/core/Subcompositor.cpp +++ b/src/protocols/core/Subcompositor.cpp @@ -4,7 +4,7 @@ CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SP surface_, SP parent_) : surface(surface_), parent(parent_), resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlSubsurface* r) { destroy(); }); @@ -142,7 +142,7 @@ SP CWLSubsurfaceResource::t1Parent() { } CWLSubcompositorResource::CWLSubcompositorResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlSubcompositor* r) { PROTO::subcompositor->destroyResource(this); }); @@ -152,12 +152,12 @@ CWLSubcompositorResource::CWLSubcompositorResource(SP resource auto SURF = CWLSurfaceResource::fromResource(surface); auto PARENT = CWLSurfaceResource::fromResource(parent); - if (!SURF || !PARENT || SURF == PARENT) { + if UNLIKELY (!SURF || !PARENT || SURF == PARENT) { r->error(WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, "Invalid surface/parent"); return; } - if (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) { + if UNLIKELY (SURF->role->role() != SURFACE_ROLE_UNASSIGNED) { r->error(-1, "Surface already has a different role"); return; } @@ -170,7 +170,7 @@ CWLSubcompositorResource::CWLSubcompositorResource(SP resource } else t1Parent = PARENT; - if (t1Parent == SURF) { + if UNLIKELY (t1Parent == SURF) { r->error(WL_SUBCOMPOSITOR_ERROR_BAD_PARENT, "Bad parent, t1 parent == surf"); return; } @@ -178,7 +178,7 @@ CWLSubcompositorResource::CWLSubcompositorResource(SP resource const auto RESOURCE = PROTO::subcompositor->m_vSurfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id), SURF, PARENT)); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { r->noMemory(); PROTO::subcompositor->m_vSurfaces.pop_back(); return; @@ -205,7 +205,7 @@ CWLSubcompositorProtocol::CWLSubcompositorProtocol(const wl_interface* iface, co void CWLSubcompositorProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); - if (!RESOURCE->good()) { + if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); m_vManagers.pop_back(); return; diff --git a/src/protocols/types/DMABuffer.cpp b/src/protocols/types/DMABuffer.cpp index 9f31f6a2..3f53225c 100644 --- a/src/protocols/types/DMABuffer.cpp +++ b/src/protocols/types/DMABuffer.cpp @@ -17,11 +17,11 @@ CDMABuffer::CDMABuffer(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs auto eglImage = g_pHyprOpenGL->createEGLImage(attrs); - if (!eglImage) { + if UNLIKELY (!eglImage) { Debug::log(ERR, "CDMABuffer: failed to import EGLImage, retrying as implicit"); attrs.modifier = DRM_FORMAT_MOD_INVALID; eglImage = g_pHyprOpenGL->createEGLImage(attrs); - if (!eglImage) { + if UNLIKELY (!eglImage) { Debug::log(ERR, "CDMABuffer: failed to import EGLImage"); return; } @@ -31,7 +31,7 @@ CDMABuffer::CDMABuffer(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs opaque = NFormatUtils::isFormatOpaque(attrs.format); success = texture->m_iTexID; - if (!success) + if UNLIKELY (!success) Debug::log(ERR, "Failed to create a dmabuf: texture is null"); } diff --git a/src/protocols/types/WLBuffer.cpp b/src/protocols/types/WLBuffer.cpp index a9e6400a..4bd115a2 100644 --- a/src/protocols/types/WLBuffer.cpp +++ b/src/protocols/types/WLBuffer.cpp @@ -6,7 +6,7 @@ #include CWLBufferResource::CWLBufferResource(SP resource_) : resource(resource_) { - if (!good()) + if UNLIKELY (!good()) return; resource->setOnDestroy([this](CWlBuffer* r) { From 76a899627ecff1f4fa3644ee06d8e1d279634850 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 17 Jan 2025 18:24:10 +0100 Subject: [PATCH 0122/1444] regex: log an error if regex parsing fails --- src/desktop/Rule.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/desktop/Rule.cpp b/src/desktop/Rule.cpp index dd1848d4..ae280642 100644 --- a/src/desktop/Rule.cpp +++ b/src/desktop/Rule.cpp @@ -1,11 +1,16 @@ #include "Rule.hpp" #include +#include "../debug/Log.hpp" CRuleRegexContainer::CRuleRegexContainer(const std::string& regex_) { const bool NEGATIVE = regex_.starts_with("negative:"); negative = NEGATIVE; regex = std::make_unique(NEGATIVE ? regex_.substr(9) : regex_); + + // TODO: maybe pop an error? + if (!regex->ok()) + Debug::log(ERR, "RuleRegexContainer: regex {} failed to parse!", regex_); } bool CRuleRegexContainer::passes(const std::string& str) const { From 401a3bae614ae4863da3e5cd5bf4d9997a893045 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 17 Jan 2025 18:28:53 +0100 Subject: [PATCH 0123/1444] core: fix warning in shadow --- src/render/decorations/CHyprDropShadowDecoration.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 022e123e..c576b966 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -56,7 +56,6 @@ void CHyprDropShadowDecoration::damageEntire() { static auto PSHADOWIGNOREWINDOW = CConfigValue("decoration:shadow:ignore_window"); const auto ROUNDING = PWINDOW->rounding(); - const auto ROUNDINGPOWER = PWINDOW->roundingPower(); const auto ROUNDINGSIZE = ROUNDING - M_SQRT1_2 * ROUNDING + 1; CRegion shadowRegion(shadowBox); From b65f8a87232c13697f0469fb7dfa31ff4f14af22 Mon Sep 17 00:00:00 2001 From: Beau Date: Fri, 17 Jan 2025 18:35:39 +0100 Subject: [PATCH 0124/1444] desktop/DesktopTypes.hpp: fix include (#9104) --- src/desktop/DesktopTypes.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop/DesktopTypes.hpp b/src/desktop/DesktopTypes.hpp index ae2ac366..080f13d3 100644 --- a/src/desktop/DesktopTypes.hpp +++ b/src/desktop/DesktopTypes.hpp @@ -1,5 +1,5 @@ #pragma once -#include "helpers/memory/Memory.hpp" +#include "../helpers/memory/Memory.hpp" class CWorkspace; class CWindow; class CLayerSurface; From 47d645d84a7a290dc974cad552ee4912ca606069 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Fri, 17 Jan 2025 19:14:55 +0100 Subject: [PATCH 0125/1444] core: fixup includes --- src/config/ConfigManager.hpp | 12 ++++++------ src/helpers/Monitor.cpp | 2 +- src/helpers/WLClasses.hpp | 6 +++--- src/managers/AnimationManager.cpp | 8 ++++---- src/protocols/FocusGrab.hpp | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 1ba1df62..bef52584 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -16,12 +16,12 @@ #include "../desktop/LayerRule.hpp" #include "ConfigDataValues.hpp" -#include "SharedDefs.hpp" -#include "helpers/Color.hpp" -#include "desktop/DesktopTypes.hpp" -#include "helpers/memory/Memory.hpp" -#include "desktop/WindowRule.hpp" -#include "managers/XWaylandManager.hpp" +#include "../SharedDefs.hpp" +#include "../helpers/Color.hpp" +#include "../desktop/DesktopTypes.hpp" +#include "../helpers/memory/Memory.hpp" +#include "../desktop/WindowRule.hpp" +#include "../managers/XWaylandManager.hpp" #include diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 718baf23..1f00e4ad 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1,6 +1,6 @@ #include "Monitor.hpp" #include "MiscFunctions.hpp" -#include "macros.hpp" +#include "../macros.hpp" #include "math/Math.hpp" #include "sync/SyncReleaser.hpp" #include "../Compositor.hpp" diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index c2e828e7..bedea065 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -4,9 +4,9 @@ #include "../desktop/Subsurface.hpp" #include "../desktop/Popup.hpp" #include "../desktop/WLSurface.hpp" -#include "macros.hpp" -#include "desktop/DesktopTypes.hpp" -#include "helpers/memory/Memory.hpp" +#include "../macros.hpp" +#include "../desktop/DesktopTypes.hpp" +#include "memory/Memory.hpp" #include "signal/Signal.hpp" class CMonitor; diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 9cf35116..f884acdd 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -1,10 +1,10 @@ #include "AnimationManager.hpp" #include "../Compositor.hpp" #include "HookSystemManager.hpp" -#include "config/ConfigManager.hpp" -#include "desktop/DesktopTypes.hpp" -#include "helpers/AnimatedVariable.hpp" -#include "macros.hpp" +#include "../config/ConfigManager.hpp" +#include "../desktop/DesktopTypes.hpp" +#include "../helpers/AnimatedVariable.hpp" +#include "../macros.hpp" #include "../config/ConfigValue.hpp" #include "../desktop/Window.hpp" #include "../desktop/LayerSurface.hpp" diff --git a/src/protocols/FocusGrab.hpp b/src/protocols/FocusGrab.hpp index 6fe8780f..3c907ed0 100644 --- a/src/protocols/FocusGrab.hpp +++ b/src/protocols/FocusGrab.hpp @@ -2,7 +2,7 @@ #include "WaylandProtocol.hpp" #include "hyprland-focus-grab-v1.hpp" -#include "macros.hpp" +#include "../macros.hpp" #include #include #include From 078e13f463d56a4e773aa104bca5567b9e9c8658 Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Fri, 17 Jan 2025 23:23:57 +0300 Subject: [PATCH 0126/1444] renderer: Auto enable wide color gamut in HDR mode (#9090) --- src/helpers/Monitor.hpp | 1 + src/render/Renderer.cpp | 29 ++++++++++++++++++++--------- src/render/Renderer.hpp | 1 - 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 3335a896..b33725d5 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -192,6 +192,7 @@ class CMonitor { bool m_bEnabled = false; bool m_bRenderingInitPassed = false; + WP m_previousFSWindow; // For the list lookup diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index fddb9a9a..384db1e6 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1466,12 +1466,6 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { if (inFD >= 0) pMonitor->output->state->setExplicitInFence(inFD); - static auto PWIDE = CConfigValue("experimental:wide_color_gamut"); - if (pMonitor->output->state->state().wideColorGamut != *PWIDE) { - Debug::log(TRACE, "Setting wide color gamut {}", *PWIDE ? "on" : "off"); - pMonitor->output->state->setWideColorGamut(*PWIDE); - } - static auto PHDR = CConfigValue("experimental:hdr"); const bool SUPPORTSPQ = pMonitor->output->parsedEDID.hdrMetadata.has_value() ? pMonitor->output->parsedEDID.hdrMetadata->supportsPQ : false; @@ -1481,18 +1475,35 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow(); const auto SURF = WINDOW->m_pWLSurface->resource(); if (SURF->colorManagement.valid() && SURF->colorManagement->hasImageDescription()) { - bool needsHdrMetadataUpdate = SURF->colorManagement->needsHdrMetadataUpdate() || m_previousFSWindow != WINDOW; + bool needsHdrMetadataUpdate = SURF->colorManagement->needsHdrMetadataUpdate() || pMonitor->m_previousFSWindow != WINDOW; if (SURF->colorManagement->needsHdrMetadataUpdate()) SURF->colorManagement->setHDRMetadata(createHDRMetadata(SURF->colorManagement.get()->imageDescription(), pMonitor->output->parsedEDID)); if (needsHdrMetadataUpdate) pMonitor->output->state->setHDRMetadata(SURF->colorManagement->hdrMetadata()); } else if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != *PHDR) pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); - m_previousFSWindow = WINDOW; + pMonitor->m_previousFSWindow = WINDOW; } else { if ((pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2) != *PHDR) pMonitor->output->state->setHDRMetadata(*PHDR ? createHDRMetadata(2, pMonitor->output->parsedEDID) : createHDRMetadata(0, pMonitor->output->parsedEDID)); - m_previousFSWindow.reset(); + pMonitor->m_previousFSWindow.reset(); + } + } + + static auto PWIDE = CConfigValue("experimental:wide_color_gamut"); + const bool needsWCG = *PWIDE || pMonitor->output->state->state().hdrMetadata.hdmi_metadata_type1.eotf == 2; + if (pMonitor->output->state->state().wideColorGamut != needsWCG) { + Debug::log(TRACE, "Setting wide color gamut {}", needsWCG ? "on" : "off"); + pMonitor->output->state->setWideColorGamut(needsWCG); + + // FIXME do not trust enabled10bit, auto switch to 10bit and back if needed + if (needsWCG && !pMonitor->enabled10bit) { + Debug::log(WARN, "Wide color gamut is enabled but the display is not in 10bit mode"); + static bool shown = false; + if (!shown) { + g_pHyprNotificationOverlay->addNotification("Wide color gamut is enabled but the display is not in 10bit mode", CHyprColor{}, 15000, ICON_WARNING); + shown = true; + } } } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 6ba7a654..7aef96e6 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -130,7 +130,6 @@ class CHyprRenderer { bool commitPendingAndDoExplicitSync(PHLMONITOR pMonitor); - WP m_previousFSWindow; bool m_bCursorHidden = false; bool m_bCursorHasSurface = false; SP m_pCurrentRenderbuffer = nullptr; From d01756c1f41977e852eba1cbf45c0149ae0f08e8 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 18 Jan 2025 10:59:25 +0200 Subject: [PATCH 0127/1444] Meson: properly install 'hyprland' symlink (#9091) --- CMakeLists.txt | 11 +++++++++-- src/meson.build | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1ecb14c..532f1d95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,7 +248,15 @@ target_precompile_headers(Hyprland PRIVATE message(STATUS "Setting link libraries") -target_link_libraries(Hyprland rt PkgConfig::aquamarine_dep PkgConfig::hyprlang_dep PkgConfig::hyprutils_dep PkgConfig::hyprcursor_dep PkgConfig::hyprgraphics_dep PkgConfig::deps) +target_link_libraries( + Hyprland + rt + PkgConfig::aquamarine_dep + PkgConfig::hyprlang_dep + PkgConfig::hyprutils_dep + PkgConfig::hyprcursor_dep + PkgConfig::hyprgraphics_dep + PkgConfig::deps) if(udis_dep_FOUND) target_link_libraries(Hyprland PkgConfig::udis_dep) else() @@ -369,7 +377,6 @@ install( ${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \ \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \ )") - # session file install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions) diff --git a/src/meson.build b/src/meson.build index 2efc2213..7054d8e4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -49,3 +49,9 @@ executable( ], install: true, ) + +install_symlink( + 'hyprland', + install_dir: get_option('bindir'), + pointing_to: 'Hyprland', +) From fdfcfc824e715d372b5cc6791d5e1b7c2bc4769b Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 18 Jan 2025 11:04:40 +0200 Subject: [PATCH 0128/1444] CMake, Meson: add option controlling hyprpm building --- CMakeLists.txt | 8 +++++++- meson.build | 5 ++++- meson_options.txt | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 532f1d95..a36d70fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -366,7 +366,13 @@ protocolwayland() # tools add_subdirectory(hyprctl) -add_subdirectory(hyprpm) + +if(NO_HYPRPM) + message(STATUS "hyprpm is disabled") +else() + add_subdirectory(hyprpm) + message(STATUS "hyprpm is enabled (NO_HYPRPM not defined)") +endif() # binary and symlink install(TARGETS Hyprland) diff --git a/meson.build b/meson.build index d79a2845..6b50ff2d 100644 --- a/meson.build +++ b/meson.build @@ -101,11 +101,14 @@ endif subdir('protocols') subdir('src') subdir('hyprctl') -subdir('hyprpm/src') subdir('assets') subdir('example') subdir('docs') +if get_option('hyprpm').enabled() + subdir('hyprpm/src') +endif + # Generate hyprland.pc pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig') diff --git a/meson_options.txt b/meson_options.txt index 9b64fb32..3eb01696 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,4 +2,5 @@ option('xwayland', type: 'feature', value: 'auto', description: 'Enable support option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration') option('uwsm', type: 'feature', value: 'enabled', description: 'Enable uwsm integration (only if systemd is enabled)') option('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer') +option('hyprpm', type: 'feature', value: 'enabled', description: 'Enable hyprpm') option('tracy_enable', type: 'boolean', value: false , description: 'Enable profiling') From a36fa5c229c175f47602f1b92d97e6a4dd3417a8 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 18 Jan 2025 11:05:05 +0200 Subject: [PATCH 0129/1444] Nix: disable hyprpm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It does not work properly on Nix anyway. If you were using hyprpm in some way before, please switch to using the `plugins` option in the HM module (and the upcoming option in the NixOS module, soon™). --- nix/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/default.nix b/nix/default.nix index 8e3af31d..a4ddc63b 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -163,6 +163,7 @@ in "xwayland" = enableXWayland; "legacy_renderer" = legacyRenderer; "uwsm" = false; + "hyprpm" = false; }) (mapAttrsToList mesonBool { "b_pch" = false; From f56153a9c1b0a00fac0932a95e0cfa5a4f6c681f Mon Sep 17 00:00:00 2001 From: Charlie Root Date: Sat, 18 Jan 2025 10:48:38 +0000 Subject: [PATCH 0130/1444] nix/module.nix: expand nixos module for configuring hyprland Expand the nixos module to be able to configure hyprland, just like the current home-manager module does. --- nix/module.nix | 205 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 198 insertions(+), 7 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index 6f553893..46191dfa 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -7,15 +7,206 @@ inputs: { inherit (pkgs.stdenv.hostPlatform) system; cfg = config.programs.hyprland; - package = inputs.self.packages.${system}.hyprland; - portalPackage = inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override { - hyprland = cfg.finalPackage; - }; + # basically 1:1 taken from https://github.com/nix-community/home-manager/blob/master/modules/services/window-managers/hyprland.nix + toHyprconf = { + attrs, + indentLevel ? 0, + importantPrefixes ? ["$"], + }: let + inherit + (lib) + all + concatMapStringsSep + concatStrings + concatStringsSep + filterAttrs + foldl + generators + hasPrefix + isAttrs + isList + mapAttrsToList + replicate + ; + + initialIndent = concatStrings (replicate indentLevel " "); + + toHyprconf' = indent: attrs: let + sections = + filterAttrs (n: v: isAttrs v || (isList v && all isAttrs v)) attrs; + + mkSection = n: attrs: + if lib.isList attrs + then (concatMapStringsSep "\n" (a: mkSection n a) attrs) + else '' + ${indent}${n} { + ${toHyprconf' " ${indent}" attrs}${indent}} + ''; + + mkFields = generators.toKeyValue { + listsAsDuplicateKeys = true; + inherit indent; + }; + + allFields = + filterAttrs (n: v: !(isAttrs v || (isList v && all isAttrs v))) + attrs; + + isImportantField = n: _: + foldl (acc: prev: + if hasPrefix prev n + then true + else acc) + false + importantPrefixes; + + importantFields = filterAttrs isImportantField allFields; + + fields = + builtins.removeAttrs allFields + (mapAttrsToList (n: _: n) importantFields); + in + mkFields importantFields + + concatStringsSep "\n" (mapAttrsToList mkSection sections) + + mkFields fields; + in + toHyprconf' initialIndent attrs; in { - config = { + options = { programs.hyprland = { - package = lib.mkDefault package; - portalPackage = lib.mkDefault portalPackage; + plugins = lib.mkOption { + type = with lib.types; listOf (either package path); + default = []; + description = '' + List of Hyprland plugins to use. Can either be packages or + absolute plugin paths. + ''; + }; + + settings = lib.mkOption { + type = with lib.types; let + valueType = + nullOr (oneOf [ + bool + int + float + str + path + (attrsOf valueType) + (listOf valueType) + ]) + // { + description = "Hyprland configuration value"; + }; + in + valueType; + default = {}; + description = '' + Hyprland configuration written in Nix. Entries with the same key + should be written as lists. Variables' and colors' names should be + quoted. See for more examples. + + ::: {.note} + Use the [](#programs.hyprland.plugins) option to + declare plugins. + ::: + + ''; + example = lib.literalExpression '' + { + decoration = { + shadow_offset = "0 5"; + "col.shadow" = "rgba(00000099)"; + }; + + "$mod" = "SUPER"; + + bindm = [ + # mouse movements + "$mod, mouse:272, movewindow" + "$mod, mouse:273, resizewindow" + "$mod ALT, mouse:272, resizewindow" + ]; + } + ''; + }; + + extraConfig = lib.mkOption { + type = lib.types.lines; + default = ""; + example = '' + # window resize + bind = $mod, S, submap, resize + + submap = resize + binde = , right, resizeactive, 10 0 + binde = , left, resizeactive, -10 0 + binde = , up, resizeactive, 0 -10 + binde = , down, resizeactive, 0 10 + bind = , escape, submap, reset + submap = reset + ''; + description = '' + Extra configuration lines to add to `/etc/xdg/hypr/hyprland.conf`. + ''; + }; + + sourceFirst = + lib.mkEnableOption '' + putting source entries at the top of the configuration + '' + // { + default = true; + }; + + importantPrefixes = lib.mkOption { + type = with lib.types; listOf str; + default = ["$" "bezier" "name"] ++ lib.optionals cfg.sourceFirst ["source"]; + example = ["$" "bezier"]; + description = '' + List of prefix of attributes to source at the top of the config. + ''; + }; }; }; + config = lib.mkMerge [ + { + programs.hyprland = { + package = lib.mkDefault inputs.self.packages.${system}.hyprland; + portalPackage = lib.mkDefault (inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override { + hyprland = cfg.finalPackage; + }); + }; + } + (lib.mkIf cfg.enable { + environment.etc."xdg/hypr/hyprland.conf" = let + shouldGenerate = cfg.extraConfig != "" || cfg.settings != {} || cfg.plugins != []; + + pluginsToHyprconf = plugins: + toHyprconf { + attrs = { + plugin = let + mkEntry = entry: + if lib.types.package.check entry + then "${entry}/lib/lib${entry.pname}.so" + else entry; + in + map mkEntry cfg.plugins; + }; + inherit (cfg) importantPrefixes; + }; + in + lib.mkIf shouldGenerate { + text = + lib.optionalString (cfg.plugins != []) + (pluginsToHyprconf cfg.plugins) + + lib.optionalString (cfg.settings != {}) + (toHyprconf { + attrs = cfg.settings; + inherit (cfg) importantPrefixes; + }) + + lib.optionalString (cfg.extraConfig != "") cfg.extraConfig; + }; + }) + ]; } From 4da9b7cc5b50c346309378fbb5ae8aa07746fd33 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sun, 19 Jan 2025 10:38:42 +0000 Subject: [PATCH 0131/1444] core: reserve vector sizes as much as we can (#9118) avoid reallocations as much as possible with a few edge cases where the reservation overshoots a tiny bit. but a few bytes of memory short term is better used then the overhead of potential reallocation. --- src/Compositor.cpp | 6 ++---- src/desktop/Window.cpp | 2 ++ src/managers/KeybindManager.cpp | 4 +--- src/protocols/DRMLease.cpp | 3 +++ src/protocols/GlobalShortcuts.cpp | 15 +++++++++++++-- src/protocols/Screencopy.cpp | 2 ++ src/protocols/ToplevelExport.cpp | 2 ++ src/render/OpenGL.cpp | 14 +++++++++++--- src/render/decorations/DecorationPositioner.cpp | 3 +++ src/xwayland/Dnd.cpp | 2 ++ src/xwayland/XWM.cpp | 4 ++++ 11 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 496ca4fe..889ae181 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2785,11 +2785,9 @@ PHLWINDOW CCompositor::getForceFocus() { void CCompositor::arrangeMonitors() { static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); - std::vector toArrange; + std::vector toArrange(m_vMonitors.begin(), m_vMonitors.end()); std::vector arranged; - - for (auto const& m : m_vMonitors) - toArrange.push_back(m); + arranged.reserve(toArrange.size()); Debug::log(LOG, "arrangeMonitors: {} to arrange", toArrange.size()); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 241a17d7..829f4e2e 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -282,6 +282,8 @@ void CWindow::updateWindowDecos() { // make a copy because updateWindow can remove decos. std::vector decos; + // reserve to avoid reallocations + decos.reserve(m_dWindowDecorations.size()); for (auto const& wd : m_dWindowDecorations) { decos.push_back(wd.get()); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index a1979206..65891840 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1891,9 +1891,7 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) { // apply // we make a copy because changeWindowFloatingMode might invalidate the iterator - std::vector ptrs; - for (auto const& w : g_pCompositor->m_vWindows) - ptrs.push_back(w); + std::vector ptrs(g_pCompositor->m_vWindows.begin(), g_pCompositor->m_vWindows.end()); for (auto const& w : ptrs) { if (!w->m_bIsMapped || w->m_pWorkspace != PWORKSPACE || w->isHidden()) diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp index fce1e345..6fdbaf4b 100644 --- a/src/protocols/DRMLease.cpp +++ b/src/protocols/DRMLease.cpp @@ -34,6 +34,9 @@ CDRMLeaseResource::CDRMLeaseResource(SP resource_, SP> outputs; + // reserve to avoid reallocations + outputs.reserve(requested.size()); + for (auto const& m : requested) { outputs.emplace_back(m->monitor->output); } diff --git a/src/protocols/GlobalShortcuts.cpp b/src/protocols/GlobalShortcuts.cpp index 6fac2d7f..9f8f422c 100644 --- a/src/protocols/GlobalShortcuts.cpp +++ b/src/protocols/GlobalShortcuts.cpp @@ -83,8 +83,19 @@ void CGlobalShortcutsProtocol::sendGlobalShortcutEvent(std::string appid, std::s std::vector CGlobalShortcutsProtocol::getAllShortcuts() { std::vector copy; - for (auto const& c : m_vClients) { - for (auto const& sh : c->shortcuts) { + // calculate the total number of shortcuts, precomputing size is linear + // and potential reallocation is more costly then the added precompute overhead of looping + // and finding the total size. + size_t totalShortcuts = 0; + for (const auto& c : m_vClients) { + totalShortcuts += c->shortcuts.size(); + } + + // reserve number of elements to avoid reallocations + copy.reserve(totalShortcuts); + + for (const auto& c : m_vClients) { + for (const auto& sh : c->shortcuts) { copy.push_back(*sh); } } diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 8bdaf8f9..5cf54eb4 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -412,6 +412,8 @@ void CScreencopyProtocol::onOutputCommit(PHLMONITOR pMonitor) { } std::vector> framesToRemove; + // reserve number of elements to avoid reallocations + framesToRemove.reserve(m_vFramesAwaitingWrite.size()); // share frame if correct output for (auto const& f : m_vFramesAwaitingWrite) { diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 2d40cb78..fb49f722 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -393,6 +393,8 @@ void CToplevelExportProtocol::onOutputCommit(PHLMONITOR pMonitor) { return; // nothing to share std::vector> framesToRemove; + // reserve number of elements to avoid reallocations + framesToRemove.reserve(m_vFramesAwaitingWrite.size()); // share frame if correct output for (auto const& f : m_vFramesAwaitingWrite) { diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index c5bb3620..ceb94c81 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -400,7 +400,10 @@ std::optional> CHyprOpenGLImpl::getModsForFormat(EGLint fo m_sProc.eglQueryDmaBufModifiersEXT(m_pEglDisplay, format, len, mods.data(), external.data(), &len); std::vector result; - bool linearIsExternal = false; + // reserve number of elements to avoid reallocations + result.reserve(mods.size()); + + bool linearIsExternal = false; for (size_t i = 0; i < mods.size(); ++i) { if (external.at(i)) { if (mods.at(i) == DRM_FORMAT_MOD_LINEAR) @@ -449,6 +452,8 @@ void CHyprOpenGLImpl::initDRMFormats() { Debug::log(LOG, "Supported DMA-BUF formats:"); std::vector dmaFormats; + // reserve number of elements to avoid reallocations + dmaFormats.reserve(formats.size()); for (auto const& fmt : formats) { std::vector mods; @@ -472,8 +477,10 @@ void CHyprOpenGLImpl::initDRMFormats() { }); std::vector> modifierData; + // reserve number of elements to avoid reallocations + modifierData.reserve(mods.size()); - auto fmtName = drmGetFormatName(fmt); + auto fmtName = drmGetFormatName(fmt); Debug::log(LOG, "EGL: GPU Supports Format {} (0x{:x})", fmtName ? fmtName : "?unknown?", fmt); for (auto const& mod : mods) { auto modName = drmGetFormatModifierName(mod); @@ -2942,7 +2949,8 @@ SP CHyprOpenGLImpl::createEGLSync(int fenceFD) { Debug::log(ERR, "createEGLSync: dup failed"); return nullptr; } - + // reserve number of elements to avoid reallocations + attribs.reserve(3); attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID); attribs.push_back(dupFd); attribs.push_back(EGL_NONE); diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index c2d34fb6..2ba3c4a7 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -122,6 +122,9 @@ void CDecorationPositioner::onWindowUpdate(PHLWINDOW pWindow) { // std::vector datas; + // reserve to avoid reallocations + datas.reserve(pWindow->m_dWindowDecorations.size()); + for (auto const& wd : pWindow->m_dWindowDecorations) { datas.push_back(getDataFor(wd.get(), pWindow)); } diff --git a/src/xwayland/Dnd.cpp b/src/xwayland/Dnd.cpp index 58fc6db3..d4ae3780 100644 --- a/src/xwayland/Dnd.cpp +++ b/src/xwayland/Dnd.cpp @@ -75,6 +75,8 @@ void CX11DataDevice::sendEnter(uint32_t serial, SP surf, con data.data32[1] |= 1; std::vector targets; + // reserve to avoid reallocations + targets.reserve(SOURCE->mimes().size()); for (auto& mime : SOURCE->mimes()) { targets.emplace_back(g_pXWayland->pWM->mimeToAtom(mime)); diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 44485381..ae8e0ccc 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -643,6 +643,8 @@ void CXWM::handleSelectionRequest(xcb_selection_request_event_t* e) { Debug::log(WARN, "[xwm] WARNING: No mimes in TARGETS?"); std::vector atoms; + // reserve to avoid reallocations + atoms.reserve(mimes.size() + 2); atoms.push_back(HYPRATOMS["TIMESTAMP"]); atoms.push_back(HYPRATOMS["TARGETS"]); @@ -989,6 +991,8 @@ void CXWM::sendState(SP surf) { } std::vector props; + // reserve to avoid reallocations + props.reserve(6); // props below if (surf->modal) props.push_back(HYPRATOMS["_NET_WM_STATE_MODAL"]); if (surf->fullscreen) From 086fd7ece8cc8904909f5a597ab69fe73ecac34c Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 19 Jan 2025 04:51:42 -0800 Subject: [PATCH 0132/1444] protocols: do not destroy screencopy resources before client request (#9048) --- src/protocols/Screencopy.cpp | 4 ---- src/protocols/ToplevelExport.cpp | 6 ------ 2 files changed, 10 deletions(-) diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index 5cf54eb4..e0e3a559 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -28,7 +28,6 @@ CScreencopyFrame::CScreencopyFrame(SP resource_, int32_t if (!pMonitor) { LOGM(ERR, "Client requested sharing of a monitor that doesnt exist"); resource->sendFailed(); - PROTO::screencopy->destroyResource(this); return; } @@ -46,7 +45,6 @@ CScreencopyFrame::CScreencopyFrame(SP resource_, int32_t if (shmFormat == DRM_FORMAT_INVALID) { LOGM(ERR, "No format supported by renderer in capture output"); resource->sendFailed(); - PROTO::screencopy->destroyResource(this); return; } @@ -58,7 +56,6 @@ CScreencopyFrame::CScreencopyFrame(SP resource_, int32_t if (!PSHMINFO) { LOGM(ERR, "No pixel format supported by renderer in capture output"); resource->sendFailed(); - PROTO::screencopy->destroyResource(this); return; } @@ -93,7 +90,6 @@ void CScreencopyFrame::copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer_ if UNLIKELY (!g_pCompositor->monitorExists(pMonitor.lock())) { LOGM(ERR, "Client requested sharing of a monitor that is gone"); resource->sendFailed(); - PROTO::screencopy->destroyResource(this); return; } diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index fb49f722..8b835b50 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -86,14 +86,12 @@ CToplevelExportFrame::CToplevelExportFrame(SP re if UNLIKELY (!pWindow) { LOGM(ERR, "Client requested sharing of window handle {:x} which does not exist!", pWindow); resource->sendFailed(); - PROTO::toplevelExport->destroyResource(this); return; } if UNLIKELY (!pWindow->m_bIsMapped) { LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable!", pWindow); resource->sendFailed(); - PROTO::toplevelExport->destroyResource(this); return; } @@ -109,7 +107,6 @@ CToplevelExportFrame::CToplevelExportFrame(SP re if UNLIKELY (shmFormat == DRM_FORMAT_INVALID) { LOGM(ERR, "No format supported by renderer in capture toplevel"); resource->sendFailed(); - PROTO::toplevelExport->destroyResource(this); return; } @@ -117,7 +114,6 @@ CToplevelExportFrame::CToplevelExportFrame(SP re if UNLIKELY (!PSHMINFO) { LOGM(ERR, "No pixel format supported by renderer in capture toplevel"); resource->sendFailed(); - PROTO::toplevelExport->destroyResource(this); return; } @@ -146,14 +142,12 @@ void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resou if UNLIKELY (!validMapped(pWindow)) { LOGM(ERR, "Client requested sharing of window handle {:x} which is gone!", pWindow); resource->sendFailed(); - PROTO::toplevelExport->destroyResource(this); return; } if UNLIKELY (!pWindow->m_bIsMapped) { LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", pWindow); resource->sendFailed(); - PROTO::toplevelExport->destroyResource(this); return; } From 0a0e56d99c3b5f900ec561b3fe9a3c8a64fe1217 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 19 Jan 2025 14:02:47 +0100 Subject: [PATCH 0133/1444] core: use readFileAsString instead of cat for os-release --- src/helpers/MiscFunctions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index fafe1811..5ebb0842 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -5,6 +5,7 @@ #include "../managers/TokenManager.hpp" #include "Monitor.hpp" #include "../config/ConfigManager.hpp" +#include "fs/FsUtils.hpp" #include #include #include @@ -621,7 +622,7 @@ void logSystemInfo() { // log etc Debug::log(LOG, "os-release:"); - Debug::log(NONE, "{}", execAndGet("cat /etc/os-release")); + Debug::log(NONE, "{}", NFsUtils::readFileAsString("/etc/os-release").value_or("error")); } int64_t getPPIDof(int64_t pid) { From 8dd2cd41fb4c5a5eb6886cc190419b36084cabfa Mon Sep 17 00:00:00 2001 From: vaxerski Date: Sun, 19 Jan 2025 15:39:19 +0100 Subject: [PATCH 0134/1444] core: move to inotify for monitoring the config files instead of manually polling every second which is not efficient, use inotify. an added bonus is that inotify is much much faster --- src/Compositor.cpp | 7 +- src/Compositor.hpp | 1 - src/config/ConfigManager.cpp | 70 +++++--------------- src/config/ConfigManager.hpp | 7 +- src/config/ConfigWatcher.cpp | 72 +++++++++++++++++++++ src/config/ConfigWatcher.hpp | 32 +++++++++ src/debug/HyprCtl.cpp | 7 +- src/managers/ThreadManager.cpp | 26 -------- src/managers/ThreadManager.hpp | 16 ----- src/managers/eventLoop/EventLoopManager.cpp | 11 ++++ src/managers/eventLoop/EventLoopManager.hpp | 2 + src/plugins/PluginAPI.cpp | 3 +- src/plugins/PluginSystem.cpp | 5 +- 13 files changed, 143 insertions(+), 116 deletions(-) create mode 100644 src/config/ConfigWatcher.cpp create mode 100644 src/config/ConfigWatcher.hpp delete mode 100644 src/managers/ThreadManager.cpp delete mode 100644 src/managers/ThreadManager.hpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 889ae181..325bd882 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -4,6 +4,7 @@ #include "debug/Log.hpp" #include "helpers/Splashes.hpp" #include "config/ConfigValue.hpp" +#include "config/ConfigWatcher.hpp" #include "managers/CursorManager.hpp" #include "managers/TokenManager.hpp" #include "managers/PointerManager.hpp" @@ -44,7 +45,6 @@ #include "managers/KeybindManager.hpp" #include "managers/SessionLockManager.hpp" -#include "managers/ThreadManager.hpp" #include "managers/XWaylandManager.hpp" #include "config/ConfigManager.hpp" @@ -551,7 +551,6 @@ void CCompositor::cleanup() { g_pProtocolManager.reset(); g_pHyprRenderer.reset(); g_pHyprOpenGL.reset(); - g_pThreadManager.reset(); g_pConfigManager.reset(); g_pLayoutManager.reset(); g_pHyprError.reset(); @@ -567,6 +566,7 @@ void CCompositor::cleanup() { g_pEventLoopManager.reset(); g_pVersionKeeperMgr.reset(); g_pDonationNagManager.reset(); + g_pConfigWatcher.reset(); if (m_pAqBackend) m_pAqBackend.reset(); @@ -631,9 +631,6 @@ void CCompositor::initManagers(eManagersInitStage stage) { g_pSeatManager = std::make_unique(); } break; case STAGE_LATE: { - Debug::log(LOG, "Creating the ThreadManager!"); - g_pThreadManager = std::make_unique(); - Debug::log(LOG, "Creating CHyprCtl"); g_pHyprCtl = std::make_unique(); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 0a701a59..430e583c 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -5,7 +5,6 @@ #include #include "defines.hpp" -#include "managers/ThreadManager.hpp" #include "managers/XWaylandManager.hpp" #include "managers/KeybindManager.hpp" #include "managers/SessionLockManager.hpp" diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 52f2e316..ebeb2397 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1,6 +1,7 @@ #include #include "ConfigManager.hpp" +#include "ConfigWatcher.hpp" #include "../managers/KeybindManager.hpp" #include "../Compositor.hpp" @@ -372,8 +373,8 @@ static Hyprlang::CParseResult handlePlugin(const char* c, const char* v) { CConfigManager::CConfigManager() { const auto ERR = verifyConfigExists(); - configPaths.emplace_back(getMainConfigPath()); - m_pConfig = std::make_unique(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); + m_configPaths.emplace_back(getMainConfigPath()); + m_pConfig = std::make_unique(m_configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1}); m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0}); @@ -795,7 +796,7 @@ std::string CConfigManager::getConfigString() { std::string configString; std::string currFileContent; - for (const auto& path : configPaths) { + for (const auto& path : m_configPaths) { std::ifstream configFile(path); configString += ("\n\nConfig File: " + path + ": "); if (!configFile.is_open()) { @@ -883,10 +884,10 @@ std::optional CConfigManager::resetHLConfig() { finalExecRequests.clear(); // paths - configPaths.clear(); + m_configPaths.clear(); std::string mainConfigPath = getMainConfigPath(); Debug::log(LOG, "Using config: {}", mainConfigPath); - configPaths.push_back(mainConfigPath); + m_configPaths.emplace_back(mainConfigPath); const auto RET = verifyConfigExists(); @@ -897,6 +898,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); static int prevEnabledExplicit = *PENABLEEXPLICIT; + g_pConfigWatcher->setWatchList(m_configPaths); + for (auto const& w : g_pCompositor->m_vWindows) { w->uncacheWindowDecos(); } @@ -1029,17 +1032,14 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { void CConfigManager::init() { + g_pConfigWatcher->setOnChange([this](const CConfigWatcher::SConfigWatchEvent& e) { + Debug::log(LOG, "CConfigManager: file {} modified, reloading", e.file); + reload(); + }); + const std::string CONFIGPATH = getMainConfigPath(); reload(); - struct stat fileStat; - int err = stat(CONFIGPATH.c_str(), &fileStat); - if (err != 0) { - Debug::log(WARN, "Error at statting config, error {}", errno); - } - - configModifyTimes[CONFIGPATH] = fileStat.st_mtime; - isFirstLaunch = false; } @@ -1080,37 +1080,6 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std:: return RET.error ? RET.getError() : ""; } -void CConfigManager::tick() { - std::string CONFIGPATH = getMainConfigPath(); - if (!std::filesystem::exists(CONFIGPATH)) { - Debug::log(ERR, "Config doesn't exist??"); - return; - } - - bool parse = false; - - for (auto const& cf : configPaths) { - struct stat fileStat; - int err = stat(cf.c_str(), &fileStat); - if (err != 0) { - Debug::log(WARN, "Error at ticking config at {}, error {}: {}", cf, err, strerror(err)); - continue; - } - - // check if we need to reload cfg - if (fileStat.st_mtime != configModifyTimes[cf] || m_bForceReload) { - parse = true; - configModifyTimes[cf] = fileStat.st_mtime; - } - } - - if (parse) { - m_bForceReload = false; - - reload(); - } -} - Hyprlang::CConfigValue* CConfigManager::getConfigValueSafeDevice(const std::string& dev, const std::string& val, const std::string& fallback) { const auto VAL = m_pConfig->getSpecialConfigValuePtr("device", val.c_str(), dev.c_str()); @@ -1719,8 +1688,7 @@ void CConfigManager::handlePluginLoads() { if (pluginsChanged) { g_pHyprError->destroy(); - m_bForceReload = true; - tick(); + reload(); } } @@ -2732,16 +2700,8 @@ std::optional CConfigManager::handleSource(const std::string& comma Debug::log(ERR, "source= file doesn't exist: {}", value); return "source= file " + value + " doesn't exist!"; } - configPaths.push_back(value); + m_configPaths.emplace_back(value); - struct stat fileStat; - int err = stat(value.c_str(), &fileStat); - if (err != 0) { - Debug::log(WARN, "Error at ticking config at {}, error {}: {}", value, err, strerror(err)); - return {}; - } - - configModifyTimes[value] = fileStat.st_mtime; auto configCurrentPathBackup = configCurrentPath; configCurrentPath = value; diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index bef52584..1962e4d2 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -142,8 +142,8 @@ class CConfigManager { public: CConfigManager(); - void tick(); void init(); + void reload(); int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = ""); float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = ""); @@ -258,15 +258,13 @@ class CConfigManager { {"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}}; bool m_bWantsMonitorReload = false; - bool m_bForceReload = false; bool m_bNoMonitorReload = false; bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking private: std::unique_ptr m_pConfig; - std::vector configPaths; // stores all the config paths - std::unordered_map configModifyTimes; // stores modify times + std::vector m_configPaths; Hyprutils::Animation::CAnimationConfigTree m_AnimationTree; @@ -302,7 +300,6 @@ class CConfigManager { std::optional generateConfig(std::string configPath); std::optional verifyConfigExists(); void postConfigReload(const Hyprlang::CParseResult& result); - void reload(); SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); }; diff --git a/src/config/ConfigWatcher.cpp b/src/config/ConfigWatcher.cpp new file mode 100644 index 00000000..38191e9e --- /dev/null +++ b/src/config/ConfigWatcher.cpp @@ -0,0 +1,72 @@ +#include "ConfigWatcher.hpp" +#include +#include "../debug/Log.hpp" +#include +#include + +CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) { + if (m_inotifyFd < 0) { + Debug::log(ERR, "CConfigWatcher couldn't open an inotify node. Config will not be automatically reloaded"); + return; + } + + const int FLAGS = fcntl(m_inotifyFd, F_GETFL, 0); + if (fcntl(m_inotifyFd, F_SETFL, FLAGS | O_NONBLOCK) < 0) { + Debug::log(ERR, "CConfigWatcher couldn't non-block inotify node. Config will not be automatically reloaded"); + close(m_inotifyFd); + m_inotifyFd = -1; + return; + } +} + +CConfigWatcher::~CConfigWatcher() { + if (m_inotifyFd >= 0) + close(m_inotifyFd); +} + +int CConfigWatcher::getInotifyFD() { + return m_inotifyFd; +} + +void CConfigWatcher::setWatchList(const std::vector& paths) { + + // we clear all watches first, because whichever fired is now invalid + // or that is at least what it seems to be. + // since we don't know which fired, + // plus it doesn't matter that much, these ops are done rarely and fast anyways. + + // cleanup old paths + for (auto& watch : m_watches) { + inotify_rm_watch(m_inotifyFd, watch.wd); + } + + m_watches.clear(); + + // add new paths + for (const auto& path : paths) { + m_watches.emplace_back(SInotifyWatch{ + .wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY), + .file = path, + }); + } +} + +void CConfigWatcher::setOnChange(const std::function& fn) { + m_watchCallback = fn; +} + +void CConfigWatcher::onInotifyEvent() { + inotify_event ev; + while (read(m_inotifyFd, &ev, sizeof(ev)) > 0) { + const auto WD = std::ranges::find_if(m_watches.begin(), m_watches.end(), [wd = ev.wd](const auto& e) { return e.wd == wd; }); + + if (WD == m_watches.end()) { + Debug::log(ERR, "CConfigWatcher: got an event for wd {} which we don't have?!", ev.wd); + return; + } + + m_watchCallback(SConfigWatchEvent{ + .file = WD->file, + }); + } +} diff --git a/src/config/ConfigWatcher.hpp b/src/config/ConfigWatcher.hpp new file mode 100644 index 00000000..0a698fc8 --- /dev/null +++ b/src/config/ConfigWatcher.hpp @@ -0,0 +1,32 @@ +#pragma once +#include +#include +#include +#include + +class CConfigWatcher { + public: + CConfigWatcher(); + ~CConfigWatcher(); + + struct SConfigWatchEvent { + std::string file; + }; + + int getInotifyFD(); + void setWatchList(const std::vector& paths); + void setOnChange(const std::function& fn); + void onInotifyEvent(); + + private: + struct SInotifyWatch { + int wd = -1; + std::string file; + }; + + std::function m_watchCallback; + std::vector m_watches; + int m_inotifyFd = -1; +}; + +inline std::unique_ptr g_pConfigWatcher = std::make_unique(); \ No newline at end of file diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 41b0abe1..cfdba100 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1121,13 +1121,10 @@ static std::string reloadRequest(eHyprCtlOutputFormat format, std::string reques const auto REQMODE = request.substr(request.find_last_of(' ') + 1); - g_pConfigManager->m_bForceReload = true; - - if (REQMODE == "config-only") { + if (REQMODE == "config-only") g_pConfigManager->m_bNoMonitorReload = true; - } - g_pConfigManager->tick(); + g_pConfigManager->reload(); return "ok"; } diff --git a/src/managers/ThreadManager.cpp b/src/managers/ThreadManager.cpp deleted file mode 100644 index bd124c99..00000000 --- a/src/managers/ThreadManager.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "ThreadManager.hpp" -#include "../debug/HyprCtl.hpp" -#include "../Compositor.hpp" -#include "../config/ConfigValue.hpp" - -static int handleTimer(void* data) { - const auto PTM = (CThreadManager*)data; - - static auto PDISABLECFGRELOAD = CConfigValue("misc:disable_autoreload"); - - if (*PDISABLECFGRELOAD != 1) - g_pConfigManager->tick(); - - wl_event_source_timer_update(PTM->m_esConfigTimer, 1000); - - return 0; -} - -CThreadManager::CThreadManager() : m_esConfigTimer(wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, handleTimer, this)) { - wl_event_source_timer_update(m_esConfigTimer, 1000); -} - -CThreadManager::~CThreadManager() { - if (m_esConfigTimer) - wl_event_source_remove(m_esConfigTimer); -} diff --git a/src/managers/ThreadManager.hpp b/src/managers/ThreadManager.hpp deleted file mode 100644 index 13e2fcd8..00000000 --- a/src/managers/ThreadManager.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../defines.hpp" -struct wl_event_source; - -class CThreadManager { - public: - CThreadManager(); - ~CThreadManager(); - - wl_event_source* m_esConfigTimer = nullptr; - - private: -}; - -inline std::unique_ptr g_pThreadManager; \ No newline at end of file diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index db8b49b6..f98efc92 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -1,6 +1,7 @@ #include "EventLoopManager.hpp" #include "../../debug/Log.hpp" #include "../../Compositor.hpp" +#include "../../config/ConfigWatcher.hpp" #include #include @@ -27,6 +28,8 @@ CEventLoopManager::~CEventLoopManager() { wl_event_source_remove(m_sWayland.eventSource); if (m_sIdle.eventSource) wl_event_source_remove(m_sIdle.eventSource); + if (m_configWatcherInotifySource) + wl_event_source_remove(m_configWatcherInotifySource); if (m_sTimers.timerfd >= 0) close(m_sTimers.timerfd); } @@ -42,9 +45,17 @@ static int aquamarineFDWrite(int fd, uint32_t mask, void* data) { return 1; } +static int configWatcherWrite(int fd, uint32_t mask, void* data) { + g_pConfigWatcher->onInotifyEvent(); + return 0; +} + void CEventLoopManager::enterLoop() { m_sWayland.eventSource = wl_event_loop_add_fd(m_sWayland.loop, m_sTimers.timerfd, WL_EVENT_READABLE, timerWrite, nullptr); + if (const auto FD = g_pConfigWatcher->getInotifyFD(); FD >= 0) + m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD, WL_EVENT_READABLE, configWatcherWrite, nullptr); + aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); for (auto const& fd : aqPollFDs) { m_sWayland.aqEventSources.emplace_back(wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get())); diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index 39d8bbeb..90402de2 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -51,6 +51,8 @@ class CEventLoopManager { SIdleData m_sIdle; std::vector> aqPollFDs; + wl_event_source* m_configWatcherInotifySource = nullptr; + friend class CSyncTimeline; }; diff --git a/src/plugins/PluginAPI.cpp b/src/plugins/PluginAPI.cpp index b6bbc460..fbb1ec1b 100644 --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -4,6 +4,7 @@ #include "../plugins/PluginSystem.hpp" #include "../managers/HookSystemManager.hpp" #include "../managers/LayoutManager.hpp" +#include "../managers/eventLoop/EventLoopManager.hpp" #include "../config/ConfigManager.hpp" #include "../debug/HyprNotificationOverlay.hpp" #include @@ -72,7 +73,7 @@ APICALL bool HyprlandAPI::removeLayout(HANDLE handle, IHyprLayout* layout) { } APICALL bool HyprlandAPI::reloadConfig() { - g_pConfigManager->m_bForceReload = true; + g_pEventLoopManager->doLater([] { g_pConfigManager->reload(); }); return true; } diff --git a/src/plugins/PluginSystem.cpp b/src/plugins/PluginSystem.cpp index ce7dd7c7..e849bf11 100644 --- a/src/plugins/PluginSystem.cpp +++ b/src/plugins/PluginSystem.cpp @@ -5,6 +5,7 @@ #include "../config/ConfigManager.hpp" #include "../managers/LayoutManager.hpp" #include "../managers/HookSystemManager.hpp" +#include "../managers/eventLoop/EventLoopManager.hpp" CPluginSystem::CPluginSystem() { g_pFunctionHookSystem = std::make_unique(); @@ -82,7 +83,7 @@ CPlugin* CPluginSystem::loadPlugin(const std::string& path) { PLUGIN->version = PLUGINDATA.version; PLUGIN->name = PLUGINDATA.name; - g_pConfigManager->m_bForceReload = true; + g_pEventLoopManager->doLater([] { g_pConfigManager->reload(); }); Debug::log(LOG, R"( [PluginSystem] Plugin {} loaded. Handle: {:x}, path: "{}", author: "{}", description: "{}", version: "{}")", PLUGINDATA.name, (uintptr_t)MODULE, path, PLUGINDATA.author, PLUGINDATA.description, PLUGINDATA.version); @@ -137,7 +138,7 @@ void CPluginSystem::unloadPlugin(const CPlugin* plugin, bool eject) { Debug::log(LOG, " [PluginSystem] Plugin {} unloaded.", PLNAME); // reload config to fix some stuf like e.g. unloadedPluginVars - g_pConfigManager->m_bForceReload = true; + g_pEventLoopManager->doLater([] { g_pConfigManager->reload(); }); } void CPluginSystem::unloadAllPlugins() { From 407453166ce2a52433c7b0b4ee92a41e47ef8f6d Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sun, 19 Jan 2025 18:21:36 +0000 Subject: [PATCH 0135/1444] protocols: add hyprland_lock_notify_v1 implementation (#9092) --- CMakeLists.txt | 3 +- flake.lock | 6 +-- protocols/meson.build | 3 +- src/managers/ProtocolManager.cpp | 5 +- src/protocols/LockNotify.cpp | 88 ++++++++++++++++++++++++++++++++ src/protocols/LockNotify.hpp | 50 ++++++++++++++++++ src/protocols/SessionLock.cpp | 4 ++ subprojects/hyprland-protocols | 2 +- 8 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 src/protocols/LockNotify.cpp create mode 100644 src/protocols/LockNotify.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a36d70fe..c022f3ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,7 +298,7 @@ endfunction() target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads) -pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0) +pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.0) if(hyprland_protocols_dep_FOUND) pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir) message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}") @@ -329,6 +329,7 @@ protocolnew("protocols" "frog-color-management-v1" true) protocolnew("protocols" "wayland-drm" true) protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true) protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-surface-v1" true) +protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-lock-notify-v1" true) protocolnew("staging/tearing-control" "tearing-control-v1" false) protocolnew("staging/fractional-scale" "fractional-scale-v1" false) diff --git a/flake.lock b/flake.lock index f16ecaa7..7b85bd17 100644 --- a/flake.lock +++ b/flake.lock @@ -128,11 +128,11 @@ ] }, "locked": { - "lastModified": 1735774328, - "narHash": "sha256-vIRwLS9w+N99EU1aJ+XNOU6mJTxrUBa31i1r82l0V7s=", + "lastModified": 1737127640, + "narHash": "sha256-mIQ3/axCZ4g8ySwWRbW4fJcyC9v55uAii3cqlJRtW8g=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "e3b6af97ddcfaafbda8e2828c719a5af84f662cb", + "rev": "455c055883d9639d4fcbfcedb4c6d12ce313791e", "type": "github" }, "original": { diff --git a/protocols/meson.build b/protocols/meson.build index fdbbf181..aa20940d 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -7,7 +7,7 @@ wayland_protos = dependency( hyprland_protos = dependency( 'hyprland-protocols', - version: '>=0.4', + version: '>=0.6', fallback: 'hyprland-protocols', ) @@ -40,6 +40,7 @@ protocols = [ hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml', hyprland_protocol_dir / 'protocols/hyprland-surface-v1.xml', + hyprland_protocol_dir / 'protocols/hyprland-lock-notify-v1.xml', wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml', wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml', wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml', diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index b7d61f67..8e32bdec 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -20,6 +20,7 @@ #include "../protocols/OutputPower.hpp" #include "../protocols/XDGActivation.hpp" #include "../protocols/IdleNotify.hpp" +#include "../protocols/LockNotify.hpp" #include "../protocols/SessionLock.hpp" #include "../protocols/InputMethodV2.hpp" #include "../protocols/VirtualKeyboard.hpp" @@ -145,6 +146,7 @@ CProtocolManager::CProtocolManager() { PROTO::outputPower = std::make_unique(&zwlr_output_power_manager_v1_interface, 1, "OutputPower"); PROTO::activation = std::make_unique(&xdg_activation_v1_interface, 1, "XDGActivation"); PROTO::idle = std::make_unique(&ext_idle_notifier_v1_interface, 1, "IdleNotify"); + PROTO::lockNotify = std::make_unique(&hyprland_lock_notifier_v1_interface, 1, "IdleNotify"); PROTO::sessionLock = std::make_unique(&ext_session_lock_manager_v1_interface, 1, "SessionLock"); PROTO::ime = std::make_unique(&zwp_input_method_manager_v2_interface, 1, "IMEv2"); PROTO::virtualKeyboard = std::make_unique(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard"); @@ -224,6 +226,7 @@ CProtocolManager::~CProtocolManager() { PROTO::outputPower.reset(); PROTO::activation.reset(); PROTO::idle.reset(); + PROTO::lockNotify.reset(); PROTO::sessionLock.reset(); PROTO::ime.reset(); PROTO::virtualKeyboard.reset(); @@ -296,7 +299,7 @@ bool CProtocolManager::isGlobalPrivileged(const wl_global* global) { PROTO::xdgDialog->getGlobal(), PROTO::singlePixel->getGlobal(), PROTO::primarySelection->getGlobal(), - PROTO::hyprlandSurface->getGlobal(), + PROTO::hyprlandSurface->getGlobal(), PROTO::sync ? PROTO::sync->getGlobal() : nullptr, PROTO::mesaDRM ? PROTO::mesaDRM->getGlobal() : nullptr, PROTO::linuxDma ? PROTO::linuxDma->getGlobal() : nullptr, diff --git a/src/protocols/LockNotify.cpp b/src/protocols/LockNotify.cpp new file mode 100644 index 00000000..adcd0b2d --- /dev/null +++ b/src/protocols/LockNotify.cpp @@ -0,0 +1,88 @@ +#include "LockNotify.hpp" + +CHyprlandLockNotification::CHyprlandLockNotification(SP resource_) : m_resource(resource_) { + if UNLIKELY (!m_resource->resource()) + return; + + m_resource->setDestroy([this](CHyprlandLockNotificationV1* r) { PROTO::lockNotify->destroyNotification(this); }); + m_resource->setOnDestroy([this](CHyprlandLockNotificationV1* r) { PROTO::lockNotify->destroyNotification(this); }); +} + +bool CHyprlandLockNotification::good() { + return m_resource->resource(); +} + +void CHyprlandLockNotification::onLocked() { + if LIKELY (!m_locked) + m_resource->sendLocked(); + + m_locked = true; +} + +void CHyprlandLockNotification::onUnlocked() { + if LIKELY (m_locked) + m_resource->sendUnlocked(); + + m_locked = false; +} + +CLockNotifyProtocol::CLockNotifyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CLockNotifyProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = m_managers.emplace_back(std::make_unique(client, ver, id)).get(); + RESOURCE->setOnDestroy([this](CHyprlandLockNotifierV1* p) { this->onManagerResourceDestroy(p->resource()); }); + + RESOURCE->setDestroy([this](CHyprlandLockNotifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); + RESOURCE->setGetLockNotification([this](CHyprlandLockNotifierV1* pMgr, uint32_t id) { this->onGetNotification(pMgr, id); }); +} + +void CLockNotifyProtocol::onManagerResourceDestroy(wl_resource* res) { + std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; }); +} + +void CLockNotifyProtocol::destroyNotification(CHyprlandLockNotification* notif) { + std::erase_if(m_notifications, [&](const auto& other) { return other.get() == notif; }); +} + +void CLockNotifyProtocol::onGetNotification(CHyprlandLockNotifierV1* pMgr, uint32_t id) { + const auto CLIENT = pMgr->client(); + const auto RESOURCE = m_notifications.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id))).get(); + + if UNLIKELY (!RESOURCE->good()) { + pMgr->noMemory(); + m_notifications.pop_back(); + return; + } + + // Already locked?? Send locked right away + if UNLIKELY (m_isLocked) + m_notifications.back()->onLocked(); +} + +void CLockNotifyProtocol::onLocked() { + if UNLIKELY (m_isLocked) { + LOGM(ERR, "Not sending lock notification. Already locked!"); + return; + } + + for (auto const& n : m_notifications) { + n->onLocked(); + } + + m_isLocked = true; +} + +void CLockNotifyProtocol::onUnlocked() { + if UNLIKELY (!m_isLocked) { + LOGM(ERR, "Not sending unlock notification. Not locked!"); + return; + } + + for (auto const& n : m_notifications) { + n->onUnlocked(); + } + + m_isLocked = false; +} diff --git a/src/protocols/LockNotify.hpp b/src/protocols/LockNotify.hpp new file mode 100644 index 00000000..ec71034b --- /dev/null +++ b/src/protocols/LockNotify.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "hyprland-lock-notify-v1.hpp" + +class CEventLoopTimer; + +class CHyprlandLockNotification { + public: + CHyprlandLockNotification(SP resource_); + ~CHyprlandLockNotification() = default; + + bool good(); + void onLocked(); + void onUnlocked(); + + private: + SP m_resource; + bool m_locked = false; +}; + +class CLockNotifyProtocol : public IWaylandProtocol { + public: + CLockNotifyProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + void onLocked(); + void onUnlocked(); + + private: + void onManagerResourceDestroy(wl_resource* res); + void destroyNotification(CHyprlandLockNotification* notif); + void onGetNotification(CHyprlandLockNotifierV1* pMgr, uint32_t id); + + bool m_isLocked = false; + + // + std::vector> m_managers; + std::vector> m_notifications; + + friend class CHyprlandLockNotification; +}; + +namespace PROTO { + inline UP lockNotify; +}; diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp index db65ee5f..8e215ffa 100644 --- a/src/protocols/SessionLock.cpp +++ b/src/protocols/SessionLock.cpp @@ -2,6 +2,7 @@ #include "../Compositor.hpp" #include "../managers/SeatManager.hpp" #include "FractionalScale.hpp" +#include "LockNotify.hpp" #include "core/Compositor.hpp" #include "core/Output.hpp" #include "../helpers/Monitor.hpp" @@ -115,6 +116,8 @@ CSessionLock::CSessionLock(SP resource_) : resource(resource_ PROTO::sessionLock->locked = false; + PROTO::lockNotify->onUnlocked(); + events.unlockAndDestroy.emit(); inert = true; @@ -128,6 +131,7 @@ CSessionLock::~CSessionLock() { void CSessionLock::sendLocked() { resource->sendLocked(); + PROTO::lockNotify->onLocked(); } bool CSessionLock::good() { diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index 271df559..455c0558 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit 271df559dd30e4bc5ec6af02d017ac0aaabd63a7 +Subproject commit 455c055883d9639d4fcbfcedb4c6d12ce313791e From 2d82a923241c0d7cb6209ee035bbac581d4dc555 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:48:04 +0000 Subject: [PATCH 0136/1444] config: fix float animation speeds < 0 (#9123) --- src/config/ConfigManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index ebeb2397..0347ced4 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2083,7 +2083,7 @@ std::optional CConfigManager::handleAnimation(const std::string& co return {}; } - int64_t speed = -1; + float speed = -1; // speed if (isNumber(ARGS[2], true)) { From 9e8d9791c7f9b7d1183110da370772a8b2c1b6f4 Mon Sep 17 00:00:00 2001 From: DDoSolitary Date: Tue, 21 Jan 2025 01:53:29 +0800 Subject: [PATCH 0137/1444] xwayland: support sending clipboard change notification on focus (#9111) --- src/xwayland/XWM.cpp | 13 ++++++++++++- src/xwayland/XWM.hpp | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index ae8e0ccc..3486b286 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -1144,7 +1144,8 @@ void CXWM::initSelection() { XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE; xcb_xfixes_select_selection_input(connection, clipboard.window, HYPRATOMS["CLIPBOARD"], mask2); - clipboard.listeners.setSelection = g_pSeatManager->events.setSelection.registerListener([this](std::any d) { clipboard.onSelection(); }); + clipboard.listeners.setSelection = g_pSeatManager->events.setSelection.registerListener([this](std::any d) { clipboard.onSelection(); }); + clipboard.listeners.keyboardFocusChange = g_pSeatManager->events.keyboardFocusChange.registerListener([this](std::any d) { clipboard.onKeyboardFocus(); }); dndSelection.window = xcb_generate_id(connection); xcb_create_window(connection, XCB_COPY_FROM_PARENT, dndSelection.window, screen->root, 0, 0, 8192, 8192, 0, XCB_WINDOW_CLASS_INPUT_ONLY, screen->root_visual, XCB_CW_EVENT_MASK, @@ -1287,6 +1288,16 @@ void SXSelection::onSelection() { if (g_pSeatManager->selection.currentSelection) { xcb_set_selection_owner(g_pXWayland->pWM->connection, g_pXWayland->pWM->clipboard.window, HYPRATOMS["CLIPBOARD"], XCB_TIME_CURRENT_TIME); xcb_flush(g_pXWayland->pWM->connection); + g_pXWayland->pWM->clipboard.notifyOnFocus = true; + } +} + +void SXSelection::onKeyboardFocus() { + if (!g_pSeatManager->state.keyboardFocusResource || g_pSeatManager->state.keyboardFocusResource->client() != g_pXWayland->pServer->xwaylandClient) + return; + if (g_pXWayland->pWM->clipboard.notifyOnFocus) { + onSelection(); + g_pXWayland->pWM->clipboard.notifyOnFocus = false; } } diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index bc5aa47b..0455c761 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -44,13 +44,16 @@ struct SXSelection { xcb_window_t owner = 0; xcb_timestamp_t timestamp = 0; SP dataSource; + bool notifyOnFocus = false; void onSelection(); + void onKeyboardFocus(); bool sendData(xcb_selection_request_event_t* e, std::string mime); int onRead(int fd, uint32_t mask); struct { CHyprSignalListener setSelection; + CHyprSignalListener keyboardFocusChange; } listeners; std::unique_ptr transfer; From a661203bb6d4714b211572759e2f74b1da194972 Mon Sep 17 00:00:00 2001 From: Zach DeCook Date: Mon, 20 Jan 2025 13:40:51 -0500 Subject: [PATCH 0138/1444] xwayland: fix crash when trying to initialize without Xwayland installed (#9077) --- src/Compositor.cpp | 2 +- src/Compositor.hpp | 2 +- src/config/ConfigManager.cpp | 22 ++++++---------------- src/xwayland/XWayland.cpp | 34 ++++++++++++++++++++++++++++------ src/xwayland/XWayland.hpp | 6 +++++- 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 325bd882..cd0c7c61 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -669,7 +669,7 @@ void CCompositor::initManagers(eManagersInitStage stage) { g_pDonationNagManager = std::make_unique(); Debug::log(LOG, "Starting XWayland"); - g_pXWayland = std::make_unique(g_pCompositor->m_bEnableXwayland); + g_pXWayland = std::make_unique(g_pCompositor->m_bWantsXwayland); } break; default: UNREACHABLE(); } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 430e583c..ebcca5d0 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -74,7 +74,7 @@ class CCompositor { bool m_bIsShuttingDown = false; bool m_bFinalRequests = false; bool m_bDesktopEnvSet = false; - bool m_bEnableXwayland = true; + bool m_bWantsXwayland = true; // ------------------------------------------------- // diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 0347ced4..40f8d9ef 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -950,26 +950,16 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { } #ifndef NO_XWAYLAND - const auto PENABLEXWAYLAND = std::any_cast(m_pConfig->getConfigValue("xwayland:enabled")); + const auto PENABLEXWAYLAND = std::any_cast(m_pConfig->getConfigValue("xwayland:enabled")); + g_pCompositor->m_bWantsXwayland = PENABLEXWAYLAND; // enable/disable xwayland usage if (!isFirstLaunch) { - bool prevEnabledXwayland = g_pCompositor->m_bEnableXwayland; - if (PENABLEXWAYLAND != prevEnabledXwayland) { - g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; - if (PENABLEXWAYLAND) { - Debug::log(LOG, "xwayland has been enabled"); - } else { - Debug::log(LOG, "xwayland has been disabled, cleaning up..."); - for (auto& w : g_pCompositor->m_vWindows) { - if (w->m_pXDGSurface || !w->m_bIsX11) - continue; - g_pCompositor->closeWindow(w); - } - } - g_pXWayland = std::make_unique(g_pCompositor->m_bEnableXwayland); + bool prevEnabledXwayland = g_pXWayland->enabled(); + if (g_pCompositor->m_bWantsXwayland != prevEnabledXwayland) { + g_pXWayland = std::make_unique(g_pCompositor->m_bWantsXwayland); } } else - g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; + g_pCompositor->m_bWantsXwayland = PENABLEXWAYLAND; #endif if (!isFirstLaunch && !g_pCompositor->m_bUnsafeState) diff --git a/src/xwayland/XWayland.cpp b/src/xwayland/XWayland.cpp index 8cdb1fca..6b8a630b 100644 --- a/src/xwayland/XWayland.cpp +++ b/src/xwayland/XWayland.cpp @@ -1,21 +1,39 @@ #include "XWayland.hpp" +#include "../Compositor.hpp" #include "../debug/Log.hpp" +#include "../helpers/fs/FsUtils.hpp" -CXWayland::CXWayland(const bool enabled) { +CXWayland::CXWayland(const bool wantsEnabled) { #ifndef NO_XWAYLAND + // Disable Xwayland and clean up if the user disabled it. + if (!wantsEnabled) { + Debug::log(LOG, "XWayland has been disabled, cleaning up..."); + for (auto& w : g_pCompositor->m_vWindows) { + if (!w->m_bIsX11) + continue; + g_pCompositor->closeWindow(w); + } + unsetenv("DISPLAY"); + m_enabled = false; + return; + } + + if (!NFsUtils::executableExistsInPath("Xwayland")) { + // If Xwayland doesn't exist, don't try to start it. + Debug::log(LOG, "Unable to find XWayland; not starting it."); + return; + } + Debug::log(LOG, "Starting up the XWayland server"); pServer = std::make_unique(); - if (!enabled) { - unsetenv("DISPLAY"); - return; - } - if (!pServer->create()) { Debug::log(ERR, "XWayland failed to start: it will not work."); return; } + + m_enabled = true; #else Debug::log(LOG, "Not starting XWayland: disabled at compile time"); #endif @@ -31,3 +49,7 @@ void CXWayland::setCursor(unsigned char* pixData, uint32_t stride, const Vector2 pWM->setCursor(pixData, stride, size, hotspot); #endif } + +bool CXWayland::enabled() { + return m_enabled; +} diff --git a/src/xwayland/XWayland.hpp b/src/xwayland/XWayland.hpp index 113ca4d4..8347a6a7 100644 --- a/src/xwayland/XWayland.hpp +++ b/src/xwayland/XWayland.hpp @@ -17,18 +17,22 @@ class CXWM; class CXWayland { public: - CXWayland(const bool enabled); + CXWayland(const bool wantsEnabled); #ifndef NO_XWAYLAND std::unique_ptr pServer; std::unique_ptr pWM; #endif + bool enabled(); void setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot); struct { CSignal newSurface; } events; + + private: + bool m_enabled = false; }; inline std::unique_ptr g_pXWayland; From da6e9663135aa492252fe8684747ff734730a323 Mon Sep 17 00:00:00 2001 From: Alexander <51529891+Truenya@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:17:07 +0300 Subject: [PATCH 0139/1444] keybinds: add visible arg for cyclenext (#9045) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Крылов Александр --- src/Compositor.cpp | 89 ++++++++++++--------------------- src/Compositor.hpp | 5 +- src/managers/KeybindManager.cpp | 13 ++--- 3 files changed, 41 insertions(+), 66 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index cd0c7c61..f5f1d1f9 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2,6 +2,7 @@ #include "Compositor.hpp" #include "debug/Log.hpp" +#include "desktop/DesktopTypes.hpp" #include "helpers/Splashes.hpp" #include "config/ConfigValue.hpp" #include "config/ConfigWatcher.hpp" @@ -12,6 +13,7 @@ #include "managers/VersionKeeperManager.hpp" #include "managers/DonationNagManager.hpp" #include "managers/eventLoop/EventLoopManager.hpp" +#include #include #include #include @@ -19,13 +21,13 @@ #include #include #include +#include #include #include "debug/HyprCtl.hpp" #include "debug/CrashReporter.hpp" #ifdef USES_SYSTEMD #include // for SdNotify #endif -#include #include "helpers/varlist/VarList.hpp" #include "helpers/fs/FsUtils.hpp" #include "protocols/FractionalScale.hpp" @@ -1638,62 +1640,37 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks return nullptr; } -PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating) { - bool gotToWindow = false; - for (auto const& w : m_vWindows) { - if (w != pWindow && !gotToWindow) - continue; - - if (w == pWindow) { - gotToWindow = true; - continue; - } - - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; - - if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - for (auto const& w : m_vWindows) { - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; - - if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - return nullptr; +PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating, bool visible) { + auto it = std::ranges::find(m_vWindows, pWindow); + const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); }; + const auto IN_RIGHT = std::find_if(it, m_vWindows.end(), FINDER); + if (IN_RIGHT != m_vWindows.end()) + return *IN_RIGHT; + const auto IN_LEFT = std::find_if(m_vWindows.begin(), it, FINDER); + return *IN_LEFT; } -PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating) { - bool gotToWindow = false; - for (auto const& w : m_vWindows | std::views::reverse) { - if (w != pWindow && !gotToWindow) - continue; +PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating, bool visible) { + auto it = std::ranges::find(std::ranges::reverse_view(m_vWindows), pWindow); + const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); }; + const auto IN_LEFT = std::find_if(it, m_vWindows.rend(), FINDER); + if (IN_LEFT != m_vWindows.rend()) + return *IN_LEFT; + const auto IN_RIGHT = std::find_if(m_vWindows.rbegin(), it, FINDER); + return *IN_RIGHT; +} - if (w == pWindow) { - gotToWindow = true; - continue; - } +inline static bool isWorkspaceMatches(PHLWINDOW pWindow, const PHLWINDOW w, bool anyWorkspace) { + return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace; +} - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; +inline static bool isFloatingMatches(PHLWINDOW w, std::optional floating) { + return !floating.has_value() || w->m_bIsFloating == floating.value(); +}; - if (w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - for (auto const& w : m_vWindows | std::views::reverse) { - if (floating.has_value() && w->m_bIsFloating != floating.value()) - continue; - - if (w != pWindow && w->m_pWorkspace == pWindow->m_pWorkspace && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())) - return w; - } - - return nullptr; +bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace) { + return isFloatingMatches(w, floating) && w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && + (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()); } WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() { @@ -1728,12 +1705,8 @@ PHLWORKSPACE CCompositor::getWorkspaceByString(const std::string& str) { } bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) { - for (auto const& m : m_vMonitors) { - if (VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y)) - return true; - } - - return false; + return std::ranges::any_of( + m_vMonitors, [&](const PHLMONITOR& m) { return VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y); }); } bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR pMonitor) { diff --git a/src/Compositor.hpp b/src/Compositor.hpp index ebcca5d0..0a87ec33 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -106,8 +106,8 @@ class CCompositor { void cleanupFadingOut(const MONITORID& monid); PHLWINDOW getWindowInDirection(PHLWINDOW, char); PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false); - PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); - PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}); + PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); + PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); WORKSPACEID getNextAvailableNamedWorkspace(); bool isPointOnAnyMonitor(const Vector2D&); bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr); @@ -163,6 +163,7 @@ class CCompositor { void setRandomSplash(); void initManagers(eManagersInitStage stage); void prepareFallbackOutput(); + bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace = false); uint64_t m_iHyprlandPID = 0; wl_event_source* m_critSigSource = nullptr; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 65891840..0816de2a 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -750,7 +750,7 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k->handler); } else { // call the dispatcher - Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {})", modmask, key.keyName, key.keysym); + Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {}, {})", modmask, key.keyName, key.keysym, DISPATCHER->first); m_iPassPressed = (int)pressed; @@ -2201,7 +2201,6 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) { } SDispatchResult CKeybindManager::circleNext(std::string arg) { - if (g_pCompositor->m_pLastWindow.expired()) { // if we have a clear focus, find the first window and get the next focusable. const auto PWS = g_pCompositor->m_pLastMonitor->activeWorkspace; @@ -2221,10 +2220,12 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) { else if (args.contains("float") || args.contains("floating")) floatStatus = true; - if (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l")) - switchToWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus)); - else - switchToWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus)); + const auto VISIBLE = args.contains("visible") || args.contains("v"); + const auto& w = (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l")) ? + g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE) : + g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE); + + switchToWindow(w); return {}; } From ce48bc540824fcaefd777959703df9908e258d0a Mon Sep 17 00:00:00 2001 From: Christoph Hrdinka Date: Tue, 21 Jan 2025 20:21:00 +0100 Subject: [PATCH 0140/1444] flake.lock: update (#9128) --- flake.lock | 68 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/flake.lock b/flake.lock index 7b85bd17..31dc720b 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1736102453, - "narHash": "sha256-5qb4kb7Xbt8jJFL/oDqOor9Z2+E+A+ql3PiyDvsfWZ0=", + "lastModified": 1736702516, + "narHash": "sha256-NbJiiPFnmciji3JHpqF/L0SdMQXKXn+q3Q/D8RjF/ak=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "4846091641f3be0ad7542086d52769bb7932bde6", + "rev": "e7719f9b9f5321c7100733773ad9f38cb6db6b6f", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1734906540, - "narHash": "sha256-vQ/L9hZFezC0LquLo4TWXkyniWtYBlFHAKIsDc7PYJE=", + "lastModified": 1737391116, + "narHash": "sha256-wOlplOftCnD2J1VwkRiAzASiXi80LypWqhVJcBYuLG8=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "69270ba8f057d55b0e6c2dca0e165d652856e613", + "rev": "3219b311283803d4dbdacb3c5cc10cf9e9b7c2b5", "type": "github" }, "original": { @@ -141,8 +141,34 @@ "type": "github" } }, + "hyprland-qt-support": { + "inputs": { + "nixpkgs": [ + "hyprland-qtutils", + "nixpkgs" + ], + "systems": [ + "hyprland-qtutils", + "systems" + ] + }, + "locked": { + "lastModified": 1736376766, + "narHash": "sha256-tZG+mkJJzqoi/gH8nN6P/yY1/PEYtom9+2WdYKKv5YM=", + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "rev": "0ecf224f213497c45b12c4dc7bdc2c2edd0e3084", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "type": "github" + } + }, "hyprland-qtutils": { "inputs": { + "hyprland-qt-support": "hyprland-qt-support", "hyprutils": [ "hyprutils" ], @@ -154,11 +180,11 @@ ] }, "locked": { - "lastModified": 1736114838, - "narHash": "sha256-FxbuGQExtN37ToWYnGmO6weOYN6WPHN/RAqbr7gNPek=", + "lastModified": 1736774415, + "narHash": "sha256-pb8v7axHdVKFGhQHEAxIuZP/9REsmlyuDW5eLGIplLc=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "6997fe382dcf396704227d2b98ffdd5066da6959", + "rev": "534cd1badc46ec9bdd986ab41ad2408bf845961e", "type": "github" }, "original": { @@ -203,11 +229,11 @@ ] }, "locked": { - "lastModified": 1736164519, - "narHash": "sha256-1LimBKvDpBbeX+qW7T240WEyw+DBVpDotZB4JYm8Aps=", + "lastModified": 1736613432, + "narHash": "sha256-x7nMS1dFtlzgG13QoguKMZ6SKwSIQw82OANA5ZKF0d0=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "3c895da64b0eb19870142196fa48c07090b441c4", + "rev": "72dfbf52967e4040693164319a027d8ac6315887", "type": "github" }, "original": { @@ -241,11 +267,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1736012469, - "narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=", + "lastModified": 1737062831, + "narHash": "sha256-Tbk1MZbtV2s5aG+iM99U8FqwxU/YNArMcWAv6clcsBc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8f3e1f807051e32d8c95cd12b9b421623850a34d", + "rev": "5df43628fdf08d642be8ba5b3625a6c70731c19c", "type": "github" }, "original": { @@ -264,11 +290,11 @@ ] }, "locked": { - "lastModified": 1735882644, - "narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=", + "lastModified": 1737465171, + "narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "a5a961387e75ae44cc20f0a57ae463da5e959656", + "rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17", "type": "github" }, "original": { @@ -330,11 +356,11 @@ ] }, "locked": { - "lastModified": 1734907020, - "narHash": "sha256-p6HxwpRKVl1KIiY5xrJdjcEeK3pbmc///UOyV6QER+w=", + "lastModified": 1736421203, + "narHash": "sha256-BNe2xnHsSsTZiHp8OWl9UUf697w0gVtzh67AYe+pP+g=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "d7f18dda5e511749fa1511185db3536208fb1a63", + "rev": "7613351375de66ca0d56689e333d460e2db05454", "type": "github" }, "original": { From c8a0443adc2711744e080c28e763443b1eef115e Mon Sep 17 00:00:00 2001 From: amnesiacsardine <56002958+amnesiacsardine@users.noreply.github.com> Date: Wed, 22 Jan 2025 11:16:46 +0100 Subject: [PATCH 0141/1444] config/ConfigManager.cpp: add instruction to edit config (#9130) --- src/config/ConfigManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 40f8d9ef..60b818f0 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -930,7 +930,7 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { g_pHyprError->queueCreate(result.getError(), CHyprColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); else if (std::any_cast(m_pConfig->getConfigValue("autogenerated")) == 1) g_pHyprError->queueCreate( - "Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() + + "Warning: You're using an autogenerated config! Edit the config file to get rid of this message. (config file: " + getMainConfigPath() + " )\nSUPER+Q -> kitty (if it doesn't launch, make sure it's installed or choose a different terminal in the config)\nSUPER+M -> exit Hyprland", CHyprColor(1.0, 1.0, 70.0 / 255.0, 1.0)); else if (*PENABLEEXPLICIT != prevEnabledExplicit) From d335c8f10135e165a1085fd14134c659e4caf05a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 22 Jan 2025 10:41:04 +0000 Subject: [PATCH 0142/1444] fractional-scale: avoid redundant and duplicate scale events fixes #9126 --- example/launch.json | 1 + src/protocols/FractionalScale.cpp | 29 +++++++++++++++-------------- src/protocols/FractionalScale.hpp | 12 +++++------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/example/launch.json b/example/launch.json index c47bdb72..e60cc900 100644 --- a/example/launch.json +++ b/example/launch.json @@ -22,5 +22,6 @@ } ] }, + ] } \ No newline at end of file diff --git a/src/protocols/FractionalScale.cpp b/src/protocols/FractionalScale.cpp index d1e0a604..3b24becd 100644 --- a/src/protocols/FractionalScale.cpp +++ b/src/protocols/FractionalScale.cpp @@ -41,13 +41,14 @@ void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1* return; } - PADDON->resource->setOnDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); }); - PADDON->resource->setDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); }); + PADDON->m_resource->setOnDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); }); + PADDON->m_resource->setDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); }); - if (std::find_if(m_mSurfaceScales.begin(), m_mSurfaceScales.end(), [surface](const auto& e) { return e.first == surface; }) == m_mSurfaceScales.end()) + if (std::ranges::find_if(m_mSurfaceScales, [surface](const auto& e) { return e.first == surface; }) == m_mSurfaceScales.end()) m_mSurfaceScales.emplace(surface, 1.F); - PADDON->setScale(m_mSurfaceScales.at(surface)); + if (surface->mapped) + PADDON->setScale(m_mSurfaceScales.at(surface)); // clean old std::erase_if(m_mSurfaceScales, [](const auto& e) { return e.first.expired(); }); @@ -59,23 +60,23 @@ void CFractionalScaleProtocol::sendScale(SP surf, const floa m_mAddons[surf]->setScale(scale); } -CFractionalScaleAddon::CFractionalScaleAddon(SP resource_, SP surf_) : resource(resource_), surface(surf_) { - resource->setDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); }); - resource->setOnDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); }); -} - -void CFractionalScaleAddon::onSurfaceDestroy() { - surfaceGone = true; +CFractionalScaleAddon::CFractionalScaleAddon(SP resource_, SP surf_) : m_resource(resource_), m_surface(surf_) { + m_resource->setDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); }); + m_resource->setOnDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); }); } void CFractionalScaleAddon::setScale(const float& scale) { - resource->sendPreferredScale(std::round(scale * 120.0)); + if (m_scale == scale) + return; + + m_scale = scale; + m_resource->sendPreferredScale(std::round(scale * 120.0)); } bool CFractionalScaleAddon::good() { - return resource->resource(); + return m_resource->resource(); } SP CFractionalScaleAddon::surf() { - return surface.lock(); + return m_surface.lock(); } diff --git a/src/protocols/FractionalScale.hpp b/src/protocols/FractionalScale.hpp index f6d1f96f..98cd7eaa 100644 --- a/src/protocols/FractionalScale.hpp +++ b/src/protocols/FractionalScale.hpp @@ -13,25 +13,23 @@ class CFractionalScaleAddon { CFractionalScaleAddon(SP resource_, SP surf_); void setScale(const float& scale); - void onSurfaceDestroy(); bool good(); SP surf(); bool operator==(const wl_resource* other) const { - return other == resource->resource(); + return other == m_resource->resource(); } bool operator==(const CFractionalScaleAddon* other) const { - return other->resource == resource; + return other->m_resource == m_resource; } private: - SP resource; - float scale = 1.F; - WP surface; - bool surfaceGone = false; + SP m_resource; + float m_scale = -1.F; // unset + WP m_surface; friend class CFractionalScaleProtocol; }; From c90dbfab6f0f7f295b8b4b211223ea6e82a1021d Mon Sep 17 00:00:00 2001 From: DDoSolitary Date: Wed, 22 Jan 2025 22:26:53 +0800 Subject: [PATCH 0143/1444] xwayland: fix clipboard mime name and atom mismatch (#9137) --- src/xwayland/XDataSource.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp index 54b23937..181955a8 100644 --- a/src/xwayland/XDataSource.cpp +++ b/src/xwayland/XDataSource.cpp @@ -34,7 +34,8 @@ CXDataSource::CXDataSource(SXSelection& sel_) : selection(sel_) { continue; mimeTypes.push_back(type); - } + } else + continue; mimeAtoms.push_back(value[i]); } From fda5626594c3f31bbab08e877a797a623c98c450 Mon Sep 17 00:00:00 2001 From: DDoSolitary Date: Wed, 22 Jan 2025 22:27:46 +0800 Subject: [PATCH 0144/1444] xwayland: fix sending large clipboard data (#9134) --- src/xwayland/XWM.cpp | 55 +++++++++++++++++++++++++++----------------- src/xwayland/XWM.hpp | 1 + 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 3486b286..71a7c44c 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -1168,6 +1168,11 @@ void CXWM::setClipboardToWayland(SXSelection& sel) { g_pSeatManager->setCurrentSelection(sel.dataSource); } +static int writeDataSource(int fd, uint32_t mask, void* data) { + auto selection = (SXSelection*)data; + return selection->onWrite(); +} + void CXWM::getTransferData(SXSelection& sel) { Debug::log(LOG, "[xwm] getTransferData"); @@ -1179,26 +1184,9 @@ void CXWM::getTransferData(SXSelection& sel) { sel.transfer.reset(); return; } else { - char* property = (char*)xcb_get_property_value(sel.transfer->propertyReply); - int remainder = xcb_get_property_value_length(sel.transfer->propertyReply) - sel.transfer->propertyStart; - - ssize_t len = write(sel.transfer->wlFD, property + sel.transfer->propertyStart, remainder); - if (len == -1) { - Debug::log(ERR, "[xwm] write died in transfer get"); - close(sel.transfer->wlFD); - sel.transfer.reset(); - return; - } - - if (len < remainder) { - sel.transfer->propertyStart += len; - Debug::log(ERR, "[xwm] wl client read partially: len {}", len); - return; - } else { - Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len); - close(sel.transfer->wlFD); - sel.transfer.reset(); - } + sel.onWrite(); + if (sel.transfer) + sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD, WL_EVENT_WRITABLE, ::writeDataSource, &sel); } } @@ -1370,7 +1358,8 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) { fcntl(p[0], F_SETFD, FD_CLOEXEC); fcntl(p[0], F_SETFL, O_NONBLOCK); fcntl(p[1], F_SETFD, FD_CLOEXEC); - fcntl(p[1], F_SETFL, O_NONBLOCK); + // the wayland client might not expect a non-blocking fd + // fcntl(p[1], F_SETFL, O_NONBLOCK); transfer->wlFD = p[0]; @@ -1383,6 +1372,30 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) { return true; } +int SXSelection::onWrite() { + char* property = (char*)xcb_get_property_value(transfer->propertyReply); + int remainder = xcb_get_property_value_length(transfer->propertyReply) - transfer->propertyStart; + + ssize_t len = write(transfer->wlFD, property + transfer->propertyStart, remainder); + if (len == -1) { + Debug::log(ERR, "[xwm] write died in transfer get"); + close(transfer->wlFD); + transfer.reset(); + return 0; + } + + if (len < remainder) { + transfer->propertyStart += len; + Debug::log(LOG, "[xwm] wl client read partially: len {}", len); + } else { + Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len); + close(transfer->wlFD); + transfer.reset(); + } + + return 1; +} + SXTransfer::~SXTransfer() { if (wlFD) close(wlFD); diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index 0455c761..02ade80d 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -50,6 +50,7 @@ struct SXSelection { void onKeyboardFocus(); bool sendData(xcb_selection_request_event_t* e, std::string mime); int onRead(int fd, uint32_t mask); + int onWrite(); struct { CHyprSignalListener setSelection; From f1bd62806e538fa2bfa7899c2b2ad02d6a5ca2db Mon Sep 17 00:00:00 2001 From: maround95 <39220886+maround95@users.noreply.github.com> Date: Thu, 23 Jan 2025 13:08:19 +0200 Subject: [PATCH 0145/1444] core/renderer: Add GPU hotplug support (#8980) --- src/managers/eventLoop/EventLoopManager.cpp | 32 +++++++++++++++++---- src/managers/eventLoop/EventLoopManager.hpp | 29 +++++++++++++------ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index f98efc92..4021c171 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -20,8 +21,8 @@ CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEvent } CEventLoopManager::~CEventLoopManager() { - for (auto const& eventSource : m_sWayland.aqEventSources) { - wl_event_source_remove(eventSource); + for (auto const& [_, eventSourceData] : aqEventSources) { + wl_event_source_remove(eventSourceData.eventSource); } if (m_sWayland.eventSource) @@ -56,10 +57,8 @@ void CEventLoopManager::enterLoop() { if (const auto FD = g_pConfigWatcher->getInotifyFD(); FD >= 0) m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD, WL_EVENT_READABLE, configWatcherWrite, nullptr); - aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); - for (auto const& fd : aqPollFDs) { - m_sWayland.aqEventSources.emplace_back(wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get())); - } + syncPollFDs(); + m_sListeners.pollFDsChanged = g_pCompositor->m_pAqBackend->events.pollFDsChanged.registerListener([this](std::any d) { syncPollFDs(); }); // if we have a session, dispatch it to get the pending input devices if (g_pCompositor->m_pAqBackend->hasSession()) @@ -144,3 +143,24 @@ void CEventLoopManager::doLater(const std::function& fn) { }, &m_sIdle); } + +void CEventLoopManager::syncPollFDs() { + auto aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); + + std::erase_if(aqEventSources, [&](const auto& item) { + auto const& [fd, eventSourceData] = item; + + // If no pollFD has the same fd, remove this event source + const bool shouldRemove = std::ranges::none_of(aqPollFDs, [&](const auto& pollFD) { return pollFD->fd == fd; }); + + if (shouldRemove) + wl_event_source_remove(eventSourceData.eventSource); + + return shouldRemove; + }); + + for (auto& fd : aqPollFDs | std::views::filter([&](SP fd) { return !aqEventSources.contains(fd->fd); })) { + auto eventSource = wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get()); + aqEventSources[fd->fd] = {.pollFD = fd, .eventSource = eventSource}; + } +} diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index 90402de2..e1c243d3 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -1,9 +1,11 @@ #pragma once #include +#include #include #include #include +#include "helpers/signal/Signal.hpp" #include "EventLoopTimer.hpp" @@ -36,11 +38,18 @@ class CEventLoopManager { }; private: + // Manages the event sources after AQ pollFDs change. + void syncPollFDs(); + + struct SEventSourceData { + SP pollFD; + wl_event_source* eventSource = nullptr; + }; + struct { - wl_event_loop* loop = nullptr; - wl_display* display = nullptr; - wl_event_source* eventSource = nullptr; - std::vector aqEventSources; + wl_event_loop* loop = nullptr; + wl_display* display = nullptr; + wl_event_source* eventSource = nullptr; } m_sWayland; struct { @@ -48,12 +57,16 @@ class CEventLoopManager { int timerfd = -1; } m_sTimers; - SIdleData m_sIdle; - std::vector> aqPollFDs; + SIdleData m_sIdle; + std::map aqEventSources; - wl_event_source* m_configWatcherInotifySource = nullptr; + struct { + CHyprSignalListener pollFDsChanged; + } m_sListeners; + + wl_event_source* m_configWatcherInotifySource = nullptr; friend class CSyncTimeline; }; -inline std::unique_ptr g_pEventLoopManager; \ No newline at end of file +inline std::unique_ptr g_pEventLoopManager; From ecae3c5e4be11531c2296a22f177e9e7dedb441d Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Thu, 23 Jan 2025 20:32:44 +0800 Subject: [PATCH 0146/1444] ci: fix "Resource not accessible by integration" for cf workflow (#9144) --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 65bfa1ca..34c45d6b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -107,6 +107,7 @@ jobs: run: make release clang-format: + permissions: read-all if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork name: "Code Style (Arch)" runs-on: ubuntu-latest From ae4e38d9d5faddd6e1dbc1750f589ef33d5ac16c Mon Sep 17 00:00:00 2001 From: Junxuan Liao <70618504+MikeWalrus@users.noreply.github.com> Date: Thu, 23 Jan 2025 06:35:13 -0600 Subject: [PATCH 0147/1444] tablet: send `motion`s on tip events (#9132) Typically, the position of the tool tip also changes on tool tip events, so we should forward this update to the clients. --- src/managers/input/Tablets.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index f61d8184..0952a7d4 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -159,12 +159,13 @@ void CInputManager::onTabletAxis(CTablet::SAxisEvent e) { void CInputManager::onTabletTip(CTablet::STipEvent e) { const auto PTAB = e.tablet; const auto PTOOL = ensureTabletToolPresent(e.tool); + const auto POS = e.tip; + g_pPointerManager->warpAbsolute(POS, PTAB); + refocusTablet(PTAB, PTOOL, true); - if (e.in) { - simulateMouseMovement(); - refocusTablet(PTAB, PTOOL); + if (e.in) PROTO::tablet->down(PTOOL); - } else + else PROTO::tablet->up(PTOOL); PTOOL->isDown = e.in; From ae403e6a05452336abd97e61be2706f6a930d827 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Thu, 23 Jan 2025 14:48:37 +0200 Subject: [PATCH 0148/1444] flake.lock: update --- flake.lock | 121 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 33 deletions(-) diff --git a/flake.lock b/flake.lock index 31dc720b..ed1702d1 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1736702516, - "narHash": "sha256-NbJiiPFnmciji3JHpqF/L0SdMQXKXn+q3Q/D8RjF/ak=", + "lastModified": 1737636397, + "narHash": "sha256-F5MbBj3QVorycVSFE9qjuOTLtIQBqt2VWbXa0uwzm98=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "e7719f9b9f5321c7100733773ad9f38cb6db6b6f", + "rev": "7fe006981fae53e931f513026fc754e322f13145", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1737391116, - "narHash": "sha256-wOlplOftCnD2J1VwkRiAzASiXi80LypWqhVJcBYuLG8=", + "lastModified": 1737634937, + "narHash": "sha256-Ffw4ujFpi++6pPHe+gCBOfDgAoNlzVPZN6MReC1beu8=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "3219b311283803d4dbdacb3c5cc10cf9e9b7c2b5", + "rev": "9c5dd1f7c825ee47f72727ad0a4e16ca46a2688e", "type": "github" }, "original": { @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1736115290, - "narHash": "sha256-Jcn6yAzfUMcxy3tN/iZRbi/QgrYm7XLyVRl9g/nbUl4=", + "lastModified": 1737634889, + "narHash": "sha256-9JZE3KxcXOqZH9zs3UeadngDiK/yIACTiAR8HSA/TNI=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "52202272d89da32a9f866c0d10305a5e3d954c50", + "rev": "0d77b4895ad5f1bb3b0ee43103a5246c58b65591", "type": "github" }, "original": { @@ -128,11 +128,11 @@ ] }, "locked": { - "lastModified": 1737127640, - "narHash": "sha256-mIQ3/axCZ4g8ySwWRbW4fJcyC9v55uAii3cqlJRtW8g=", + "lastModified": 1737556638, + "narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "455c055883d9639d4fcbfcedb4c6d12ce313791e", + "rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5", "type": "github" }, "original": { @@ -143,6 +143,7 @@ }, "hyprland-qt-support": { "inputs": { + "hyprlang": "hyprlang", "nixpkgs": [ "hyprland-qtutils", "nixpkgs" @@ -153,11 +154,11 @@ ] }, "locked": { - "lastModified": 1736376766, - "narHash": "sha256-tZG+mkJJzqoi/gH8nN6P/yY1/PEYtom9+2WdYKKv5YM=", + "lastModified": 1737634706, + "narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=", "owner": "hyprwm", "repo": "hyprland-qt-support", - "rev": "0ecf224f213497c45b12c4dc7bdc2c2edd0e3084", + "rev": "8810df502cdee755993cb803eba7b23f189db795", "type": "github" }, "original": { @@ -180,11 +181,11 @@ ] }, "locked": { - "lastModified": 1736774415, - "narHash": "sha256-pb8v7axHdVKFGhQHEAxIuZP/9REsmlyuDW5eLGIplLc=", + "lastModified": 1737634810, + "narHash": "sha256-ZIJ03DeisbQuDaADSgmbgyocjecaozK4yGTa0/9bOr0=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "534cd1badc46ec9bdd986ab41ad2408bf845961e", + "rev": "a9852dbf5a1ec77cf617543728144c1362709e46", "type": "github" }, "original": { @@ -194,6 +195,29 @@ } }, "hyprlang": { + "inputs": { + "hyprutils": [ + "hyprland-qtutils", + "hyprutils" + ], + "nixpkgs": "nixpkgs", + "systems": "systems" + }, + "locked": { + "lastModified": 1737634606, + "narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "f41271d35cc0f370d300413d756c2677f386af9d", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprlang_2": { "inputs": { "hyprutils": [ "hyprutils" @@ -206,11 +230,11 @@ ] }, "locked": { - "lastModified": 1735393019, - "narHash": "sha256-NPpqA8rtmDLsEmZOmz+qR67zsB6Y503Jnv+nSFLKJZ8=", + "lastModified": 1737634606, + "narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "55608efdaa387af7bfdc0eddb404c409958efa43", + "rev": "f41271d35cc0f370d300413d756c2677f386af9d", "type": "github" }, "original": { @@ -229,11 +253,11 @@ ] }, "locked": { - "lastModified": 1736613432, - "narHash": "sha256-x7nMS1dFtlzgG13QoguKMZ6SKwSIQw82OANA5ZKF0d0=", + "lastModified": 1737632363, + "narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "72dfbf52967e4040693164319a027d8ac6315887", + "rev": "006620eb29d54ea9086538891404c78563d1bae1", "type": "github" }, "original": { @@ -267,11 +291,27 @@ }, "nixpkgs": { "locked": { - "lastModified": 1737062831, - "narHash": "sha256-Tbk1MZbtV2s5aG+iM99U8FqwxU/YNArMcWAv6clcsBc=", + "lastModified": 1737469691, + "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5df43628fdf08d642be8ba5b3625a6c70731c19c", + "rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1737469691, + "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab", "type": "github" }, "original": { @@ -310,12 +350,12 @@ "hyprgraphics": "hyprgraphics", "hyprland-protocols": "hyprland-protocols", "hyprland-qtutils": "hyprland-qtutils", - "hyprlang": "hyprlang", + "hyprlang": "hyprlang_2", "hyprutils": "hyprutils", "hyprwayland-scanner": "hyprwayland-scanner", - "nixpkgs": "nixpkgs", + "nixpkgs": "nixpkgs_2", "pre-commit-hooks": "pre-commit-hooks", - "systems": "systems", + "systems": "systems_2", "xdph": "xdph" } }, @@ -334,6 +374,21 @@ "type": "github" } }, + "systems_2": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, "xdph": { "inputs": { "hyprland-protocols": [ @@ -356,11 +411,11 @@ ] }, "locked": { - "lastModified": 1736421203, - "narHash": "sha256-BNe2xnHsSsTZiHp8OWl9UUf697w0gVtzh67AYe+pP+g=", + "lastModified": 1737634991, + "narHash": "sha256-dBAnb7Kbnier30cA7AgxVSxxARmxKZ1vHZT33THSIr8=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "7613351375de66ca0d56689e333d460e2db05454", + "rev": "e09dfe2726c8008f983e45a0aa1a3b7416aaeb8a", "type": "github" }, "original": { From 0a1ae48a9fd6eb76baad27de98c00f653a55e4ac Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Thu, 23 Jan 2025 21:55:41 +0100 Subject: [PATCH 0149/1444] core: move all shared_ptrs from the STL to hyprutils (#9143) --- CMakeLists.txt | 2 +- src/Compositor.cpp | 56 ++++----- src/Compositor.hpp | 4 +- src/config/ConfigManager.cpp | 10 +- src/config/ConfigManager.hpp | 4 +- src/config/ConfigWatcher.hpp | 4 +- src/debug/HyprCtl.hpp | 2 +- src/debug/HyprDebugOverlay.hpp | 2 +- src/debug/HyprNotificationOverlay.cpp | 2 +- src/debug/HyprNotificationOverlay.hpp | 18 +-- src/desktop/LayerRule.cpp | 2 +- src/desktop/LayerSurface.cpp | 2 +- src/desktop/LayerSurface.hpp | 2 +- src/desktop/Popup.cpp | 2 +- src/desktop/Popup.hpp | 6 +- src/desktop/Rule.cpp | 5 +- src/desktop/Rule.hpp | 6 +- src/desktop/Subsurface.cpp | 4 +- src/desktop/Subsurface.hpp | 16 +-- src/desktop/Window.cpp | 18 +-- src/desktop/Window.hpp | 12 +- src/helpers/Monitor.hpp | 2 +- src/helpers/SdDaemon.cpp | 2 +- src/helpers/Watchdog.cpp | 2 +- src/helpers/Watchdog.hpp | 6 +- src/helpers/memory/Memory.hpp | 2 +- src/hyprerror/HyprError.hpp | 2 +- src/layout/IHyprLayout.cpp | 4 +- src/main.cpp | 2 +- src/managers/AnimationManager.hpp | 2 +- src/managers/CursorManager.cpp | 6 +- src/managers/CursorManager.hpp | 27 +++-- src/managers/DonationNagManager.hpp | 4 +- src/managers/EventManager.hpp | 2 +- src/managers/HookSystemManager.hpp | 2 +- src/managers/KeybindManager.cpp | 2 +- src/managers/KeybindManager.hpp | 2 +- src/managers/LayoutManager.hpp | 2 +- src/managers/ProtocolManager.cpp | 108 +++++++++--------- src/managers/ProtocolManager.hpp | 2 +- src/managers/SessionLockManager.cpp | 4 +- src/managers/SessionLockManager.hpp | 10 +- src/managers/TokenManager.hpp | 2 +- src/managers/VersionKeeperManager.hpp | 4 +- src/managers/XCursorManager.cpp | 1 + src/managers/XWaylandManager.hpp | 2 +- src/managers/eventLoop/EventLoopManager.hpp | 2 +- src/managers/input/IdleInhibitor.cpp | 2 +- src/managers/input/InputManager.hpp | 4 +- src/managers/input/InputMethodRelay.cpp | 6 +- src/managers/input/InputMethodRelay.hpp | 6 +- src/managers/input/TextInput.hpp | 1 - src/pch/pch.hpp | 2 +- src/plugins/HookSystem.cpp | 2 +- src/plugins/HookSystem.hpp | 8 +- src/plugins/PluginAPI.cpp | 2 +- src/plugins/PluginAPI.hpp | 2 +- src/plugins/PluginSystem.cpp | 4 +- src/plugins/PluginSystem.hpp | 6 +- src/protocols/AlphaModifier.cpp | 7 +- src/protocols/AlphaModifier.hpp | 1 - src/protocols/CTMControl.cpp | 2 +- src/protocols/CTMControl.hpp | 3 +- src/protocols/ColorManagement.hpp | 1 - src/protocols/CursorShape.cpp | 2 +- src/protocols/CursorShape.hpp | 1 - src/protocols/DRMLease.hpp | 1 - src/protocols/DRMSyncobj.hpp | 1 - src/protocols/DataDeviceWlr.hpp | 1 - src/protocols/FocusGrab.cpp | 7 +- src/protocols/ForeignToplevel.cpp | 2 +- src/protocols/ForeignToplevel.hpp | 1 - src/protocols/ForeignToplevelWlr.cpp | 2 +- src/protocols/ForeignToplevelWlr.hpp | 1 - src/protocols/FractionalScale.cpp | 4 +- src/protocols/FractionalScale.hpp | 1 - src/protocols/FrogColorManagement.hpp | 1 - src/protocols/GammaControl.cpp | 4 +- src/protocols/GammaControl.hpp | 1 - src/protocols/HyprlandSurface.cpp | 6 +- src/protocols/HyprlandSurface.hpp | 1 - src/protocols/IdleInhibit.cpp | 2 +- src/protocols/IdleInhibit.hpp | 1 - src/protocols/IdleNotify.cpp | 2 +- src/protocols/IdleNotify.hpp | 1 - src/protocols/InputMethodV2.cpp | 2 +- src/protocols/InputMethodV2.hpp | 1 - src/protocols/LayerShell.cpp | 2 +- src/protocols/LayerShell.hpp | 1 - src/protocols/LinuxDMABUF.cpp | 4 +- src/protocols/LinuxDMABUF.hpp | 1 - src/protocols/LockNotify.cpp | 2 +- src/protocols/MesaDRM.hpp | 1 - src/protocols/OutputManagement.hpp | 1 - src/protocols/OutputPower.cpp | 4 +- src/protocols/OutputPower.hpp | 1 - src/protocols/PointerConstraints.cpp | 2 +- src/protocols/PointerConstraints.hpp | 1 - src/protocols/PointerGestures.cpp | 8 +- src/protocols/PointerGestures.hpp | 1 - src/protocols/PresentationTime.cpp | 2 +- src/protocols/PresentationTime.hpp | 1 - src/protocols/PrimarySelection.hpp | 1 - src/protocols/RelativePointer.cpp | 4 +- src/protocols/RelativePointer.hpp | 1 - src/protocols/SecurityContext.hpp | 1 - src/protocols/ServerDecorationKDE.cpp | 5 +- src/protocols/ServerDecorationKDE.hpp | 1 - src/protocols/SessionLock.cpp | 2 +- src/protocols/SessionLock.hpp | 1 - src/protocols/ShortcutsInhibit.cpp | 4 +- src/protocols/ShortcutsInhibit.hpp | 1 - src/protocols/SinglePixel.hpp | 1 - src/protocols/Tablet.cpp | 2 +- src/protocols/Tablet.hpp | 1 - src/protocols/TearingControl.cpp | 4 +- src/protocols/TearingControl.hpp | 1 - src/protocols/TextInputV3.cpp | 2 +- src/protocols/TextInputV3.hpp | 1 - src/protocols/Viewporter.hpp | 1 - src/protocols/VirtualKeyboard.cpp | 2 +- src/protocols/VirtualKeyboard.hpp | 1 - src/protocols/VirtualPointer.cpp | 2 +- src/protocols/VirtualPointer.hpp | 1 - src/protocols/WaylandProtocol.hpp | 1 + src/protocols/XDGActivation.cpp | 4 +- src/protocols/XDGActivation.hpp | 1 - src/protocols/XDGDecoration.cpp | 4 +- src/protocols/XDGDecoration.hpp | 1 - src/protocols/XDGDialog.hpp | 1 - src/protocols/XDGOutput.cpp | 4 +- src/protocols/XDGShell.hpp | 1 - src/protocols/XWaylandShell.hpp | 1 - src/protocols/core/Compositor.hpp | 1 - src/protocols/core/DataDevice.hpp | 1 - src/protocols/core/Output.hpp | 1 - src/protocols/core/Seat.hpp | 1 - src/protocols/core/Shm.hpp | 1 - src/protocols/core/Subcompositor.hpp | 1 - src/protocols/types/WLBuffer.hpp | 1 - src/render/OpenGL.hpp | 2 +- src/render/Renderer.hpp | 2 +- .../decorations/CHyprGroupBarDecoration.cpp | 12 +- .../decorations/CHyprGroupBarDecoration.hpp | 4 +- .../decorations/DecorationPositioner.cpp | 2 +- .../decorations/DecorationPositioner.hpp | 14 +-- src/xwayland/Server.cpp | 2 +- src/xwayland/XDataSource.cpp | 2 +- src/xwayland/XWM.cpp | 8 +- src/xwayland/XWM.hpp | 2 +- src/xwayland/XWayland.cpp | 2 +- src/xwayland/XWayland.hpp | 7 +- 152 files changed, 297 insertions(+), 349 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c022f3ba..3cfb8688 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION}) pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5) pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2) pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) -pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.3.3) +pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.4.0) pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1) add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}") diff --git a/src/Compositor.cpp b/src/Compositor.cpp index f5f1d1f9..aeec2830 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -586,92 +586,92 @@ void CCompositor::initManagers(eManagersInitStage stage) { switch (stage) { case STAGE_PRIORITY: { Debug::log(LOG, "Creating the EventLoopManager!"); - g_pEventLoopManager = std::make_unique(m_sWLDisplay, m_sWLEventLoop); + g_pEventLoopManager = makeUnique(m_sWLDisplay, m_sWLEventLoop); Debug::log(LOG, "Creating the HookSystem!"); - g_pHookSystem = std::make_unique(); + g_pHookSystem = makeUnique(); Debug::log(LOG, "Creating the KeybindManager!"); - g_pKeybindManager = std::make_unique(); + g_pKeybindManager = makeUnique(); Debug::log(LOG, "Creating the AnimationManager!"); - g_pAnimationManager = std::make_unique(); + g_pAnimationManager = makeUnique(); Debug::log(LOG, "Creating the ConfigManager!"); - g_pConfigManager = std::make_unique(); + g_pConfigManager = makeUnique(); Debug::log(LOG, "Creating the CHyprError!"); - g_pHyprError = std::make_unique(); + g_pHyprError = makeUnique(); Debug::log(LOG, "Creating the LayoutManager!"); - g_pLayoutManager = std::make_unique(); + g_pLayoutManager = makeUnique(); Debug::log(LOG, "Creating the TokenManager!"); - g_pTokenManager = std::make_unique(); + g_pTokenManager = makeUnique(); g_pConfigManager->init(); - g_pWatchdog = std::make_unique(); // requires config + g_pWatchdog = makeUnique(); // requires config // wait for watchdog to initialize to not hit data races in reading config values. while (!g_pWatchdog->m_bWatchdogInitialized) { std::this_thread::yield(); } Debug::log(LOG, "Creating the PointerManager!"); - g_pPointerManager = std::make_unique(); + g_pPointerManager = makeUnique(); Debug::log(LOG, "Creating the EventManager!"); - g_pEventManager = std::make_unique(); + g_pEventManager = makeUnique(); } break; case STAGE_BASICINIT: { Debug::log(LOG, "Creating the CHyprOpenGLImpl!"); - g_pHyprOpenGL = std::make_unique(); + g_pHyprOpenGL = makeUnique(); Debug::log(LOG, "Creating the ProtocolManager!"); - g_pProtocolManager = std::make_unique(); + g_pProtocolManager = makeUnique(); Debug::log(LOG, "Creating the SeatManager!"); - g_pSeatManager = std::make_unique(); + g_pSeatManager = makeUnique(); } break; case STAGE_LATE: { Debug::log(LOG, "Creating CHyprCtl"); - g_pHyprCtl = std::make_unique(); + g_pHyprCtl = makeUnique(); Debug::log(LOG, "Creating the InputManager!"); - g_pInputManager = std::make_unique(); + g_pInputManager = makeUnique(); Debug::log(LOG, "Creating the HyprRenderer!"); - g_pHyprRenderer = std::make_unique(); + g_pHyprRenderer = makeUnique(); Debug::log(LOG, "Creating the XWaylandManager!"); - g_pXWaylandManager = std::make_unique(); + g_pXWaylandManager = makeUnique(); Debug::log(LOG, "Creating the SessionLockManager!"); - g_pSessionLockManager = std::make_unique(); + g_pSessionLockManager = makeUnique(); Debug::log(LOG, "Creating the HyprDebugOverlay!"); - g_pDebugOverlay = std::make_unique(); + g_pDebugOverlay = makeUnique(); Debug::log(LOG, "Creating the HyprNotificationOverlay!"); - g_pHyprNotificationOverlay = std::make_unique(); + g_pHyprNotificationOverlay = makeUnique(); Debug::log(LOG, "Creating the PluginSystem!"); - g_pPluginSystem = std::make_unique(); + g_pPluginSystem = makeUnique(); g_pConfigManager->handlePluginLoads(); Debug::log(LOG, "Creating the DecorationPositioner!"); - g_pDecorationPositioner = std::make_unique(); + g_pDecorationPositioner = makeUnique(); Debug::log(LOG, "Creating the CursorManager!"); - g_pCursorManager = std::make_unique(); + g_pCursorManager = makeUnique(); Debug::log(LOG, "Creating the VersionKeeper!"); - g_pVersionKeeperMgr = std::make_unique(); + g_pVersionKeeperMgr = makeUnique(); Debug::log(LOG, "Creating the DonationNag!"); - g_pDonationNagManager = std::make_unique(); + g_pDonationNagManager = makeUnique(); Debug::log(LOG, "Starting XWayland"); - g_pXWayland = std::make_unique(g_pCompositor->m_bWantsXwayland); + g_pXWayland = makeUnique(g_pCompositor->m_bWantsXwayland); } break; default: UNREACHABLE(); } @@ -2701,7 +2701,7 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow); if (!pWindow->getDecorationByType(DECORATION_GROUPBAR)) - pWindow->addWindowDeco(std::make_unique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); } else { if (!pWindow->m_bIsFloating) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 0a87ec33..f2e2ca14 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -10,6 +9,7 @@ #include "managers/SessionLockManager.hpp" #include "desktop/Window.hpp" #include "protocols/types/ColorManagement.hpp" +#include "helpers/memory/Memory.hpp" #include #include @@ -170,4 +170,4 @@ class CCompositor { rlimit m_sOriginalNofile = {0}; }; -inline std::unique_ptr g_pCompositor; +inline UP g_pCompositor; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 60b818f0..08f0f33f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -44,6 +44,7 @@ #include #include #include +#include using namespace Hyprutils::String; using namespace Hyprutils::Animation; @@ -374,7 +375,7 @@ CConfigManager::CConfigManager() { const auto ERR = verifyConfigExists(); m_configPaths.emplace_back(getMainConfigPath()); - m_pConfig = std::make_unique(m_configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); + m_pConfig = makeUnique(m_configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1}); m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0}); @@ -955,9 +956,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { // enable/disable xwayland usage if (!isFirstLaunch) { bool prevEnabledXwayland = g_pXWayland->enabled(); - if (g_pCompositor->m_bWantsXwayland != prevEnabledXwayland) { - g_pXWayland = std::make_unique(g_pCompositor->m_bWantsXwayland); - } + if (g_pCompositor->m_bWantsXwayland != prevEnabledXwayland) + g_pXWayland = makeUnique(g_pCompositor->m_bWantsXwayland); } else g_pCompositor->m_bWantsXwayland = PENABLEXWAYLAND; #endif @@ -1659,7 +1659,7 @@ void CConfigManager::addExecRule(const SExecRequestedRule& rule) { } void CConfigManager::handlePluginLoads() { - if (g_pPluginSystem == nullptr) + if (!g_pPluginSystem) return; bool pluginsChanged = false; diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 1962e4d2..31ad81cd 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -262,7 +262,7 @@ class CConfigManager { bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking private: - std::unique_ptr m_pConfig; + UP m_pConfig; std::vector m_configPaths; @@ -303,4 +303,4 @@ class CConfigManager { SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&); }; -inline std::unique_ptr g_pConfigManager; +inline UP g_pConfigManager; diff --git a/src/config/ConfigWatcher.hpp b/src/config/ConfigWatcher.hpp index 0a698fc8..c36ecd17 100644 --- a/src/config/ConfigWatcher.hpp +++ b/src/config/ConfigWatcher.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include "../helpers/memory/Memory.hpp" #include #include #include @@ -29,4 +29,4 @@ class CConfigWatcher { int m_inotifyFd = -1; }; -inline std::unique_ptr g_pConfigWatcher = std::make_unique(); \ No newline at end of file +inline UP g_pConfigWatcher = makeUnique(); \ No newline at end of file diff --git a/src/debug/HyprCtl.hpp b/src/debug/HyprCtl.hpp index 2603612c..eed8265c 100644 --- a/src/debug/HyprCtl.hpp +++ b/src/debug/HyprCtl.hpp @@ -38,4 +38,4 @@ class CHyprCtl { std::string m_socketPath; }; -inline std::unique_ptr g_pHyprCtl; +inline UP g_pHyprCtl; diff --git a/src/debug/HyprDebugOverlay.hpp b/src/debug/HyprDebugOverlay.hpp index a58ecffc..f4ef122f 100644 --- a/src/debug/HyprDebugOverlay.hpp +++ b/src/debug/HyprDebugOverlay.hpp @@ -48,4 +48,4 @@ class CHyprDebugOverlay { friend class CHyprRenderer; }; -inline std::unique_ptr g_pDebugOverlay; +inline UP g_pDebugOverlay; diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index 09125243..66c68d08 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -40,7 +40,7 @@ CHyprNotificationOverlay::~CHyprNotificationOverlay() { } void CHyprNotificationOverlay::addNotification(const std::string& text, const CHyprColor& color, const float timeMs, const eIcons icon, const float fontSize) { - const auto PNOTIF = m_vNotifications.emplace_back(std::make_unique()).get(); + const auto PNOTIF = m_vNotifications.emplace_back(makeUnique()).get(); PNOTIF->text = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text; PNOTIF->color = color == CHyprColor(0) ? ICONS_COLORS[icon] : color; diff --git a/src/debug/HyprNotificationOverlay.hpp b/src/debug/HyprNotificationOverlay.hpp index 2546d04f..b04cb73b 100644 --- a/src/debug/HyprNotificationOverlay.hpp +++ b/src/debug/HyprNotificationOverlay.hpp @@ -46,18 +46,18 @@ class CHyprNotificationOverlay { bool hasAny(); private: - CBox drawNotifications(PHLMONITOR pMonitor); - CBox m_bLastDamage; + CBox drawNotifications(PHLMONITOR pMonitor); + CBox m_bLastDamage; - std::vector> m_vNotifications; + std::vector> m_vNotifications; - cairo_surface_t* m_pCairoSurface = nullptr; - cairo_t* m_pCairo = nullptr; + cairo_surface_t* m_pCairoSurface = nullptr; + cairo_t* m_pCairo = nullptr; - PHLMONITORREF m_pLastMonitor; - Vector2D m_vecLastSize = Vector2D(-1, -1); + PHLMONITORREF m_pLastMonitor; + Vector2D m_vecLastSize = Vector2D(-1, -1); - SP m_pTexture; + SP m_pTexture; }; -inline std::unique_ptr g_pHyprNotificationOverlay; +inline UP g_pHyprNotificationOverlay; diff --git a/src/desktop/LayerRule.cpp b/src/desktop/LayerRule.cpp index 23371947..791a557e 100644 --- a/src/desktop/LayerRule.cpp +++ b/src/desktop/LayerRule.cpp @@ -1,7 +1,7 @@ +#include #include "LayerRule.hpp" #include #include -#include #include "../debug/Log.hpp" static const auto RULES = std::unordered_set{"noanim", "blur", "blurpopups", "dimaround"}; diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index c572f6b2..dd30aa7c 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -32,7 +32,7 @@ PHLLS CLayerSurface::create(SP resource) { pLS->szNamespace = resource->layerNamespace; pLS->layer = resource->current.layer; - pLS->popupHead = std::make_unique(pLS); + pLS->popupHead = makeUnique(pLS); pLS->monitor = pMonitor; pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS); diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index 591dfd99..ab259733 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -59,7 +59,7 @@ class CLayerSurface { CBox geometry = {0, 0, 0, 0}; Vector2D position; std::string szNamespace = ""; - std::unique_ptr popupHead; + UP popupHead; void onDestroy(); void onMap(); diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index ce6ab9a0..831619a5 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -89,7 +89,7 @@ void CPopup::onMap() { g_pInputManager->simulateMouseMovement(); - m_pSubsurfaceHead = std::make_unique(this); + m_pSubsurfaceHead = makeUnique(this); //unconstrain(); sendScale(); diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index e9b3e0f0..2b7b4e82 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -1,9 +1,9 @@ #pragma once #include -#include #include "Subsurface.hpp" #include "../helpers/signal/Signal.hpp" +#include "../helpers/memory/Memory.hpp" class CXDGPopupResource; @@ -61,8 +61,8 @@ class CPopup { bool m_bInert = false; // - std::vector> m_vChildren; - std::unique_ptr m_pSubsurfaceHead; + std::vector> m_vChildren; + UP m_pSubsurfaceHead; struct { CHyprSignalListener newPopup; diff --git a/src/desktop/Rule.cpp b/src/desktop/Rule.cpp index ae280642..aa87a483 100644 --- a/src/desktop/Rule.cpp +++ b/src/desktop/Rule.cpp @@ -1,12 +1,13 @@ -#include "Rule.hpp" #include +#include "../helpers/memory/Memory.hpp" +#include "Rule.hpp" #include "../debug/Log.hpp" CRuleRegexContainer::CRuleRegexContainer(const std::string& regex_) { const bool NEGATIVE = regex_.starts_with("negative:"); negative = NEGATIVE; - regex = std::make_unique(NEGATIVE ? regex_.substr(9) : regex_); + regex = makeUnique(NEGATIVE ? regex_.substr(9) : regex_); // TODO: maybe pop an error? if (!regex->ok()) diff --git a/src/desktop/Rule.hpp b/src/desktop/Rule.hpp index 4b178ee8..858b4ded 100644 --- a/src/desktop/Rule.hpp +++ b/src/desktop/Rule.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //NOLINTNEXTLINE namespace re2 { @@ -16,6 +16,6 @@ class CRuleRegexContainer { bool passes(const std::string& str) const; private: - std::unique_ptr regex; - bool negative = false; + Hyprutils::Memory::CUniquePointer regex; + bool negative = false; }; \ No newline at end of file diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 26638f7a..9cdf3685 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -126,9 +126,9 @@ void CSubsurface::onNewSubsurface(SP pSubsurface) { CSubsurface* PSUBSURFACE = nullptr; if (!m_pWindowParent.expired()) - PSUBSURFACE = m_vChildren.emplace_back(std::make_unique(pSubsurface, m_pWindowParent.lock())).get(); + PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pWindowParent.lock())).get(); else if (m_pPopupParent) - PSUBSURFACE = m_vChildren.emplace_back(std::make_unique(pSubsurface, m_pPopupParent)).get(); + PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pPopupParent)).get(); ASSERT(PSUBSURFACE); diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index 7829c489..aacbad91 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -48,16 +48,16 @@ class CSubsurface { Vector2D m_vLastSize = {}; // if nullptr, means it's a dummy node - CSubsurface* m_pParent = nullptr; + CSubsurface* m_pParent = nullptr; - PHLWINDOWREF m_pWindowParent; - CPopup* m_pPopupParent = nullptr; + PHLWINDOWREF m_pWindowParent; + CPopup* m_pPopupParent = nullptr; - std::vector> m_vChildren; + std::vector> m_vChildren; - bool m_bInert = false; + bool m_bInert = false; - void initSignals(); - void initExistingSubsurfaces(SP pSurface); - void checkSiblingDamage(); + void initSignals(); + void initExistingSubsurfaces(SP pSurface); + void checkSiblingDamage(); }; \ No newline at end of file diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 829f4e2e..fb5904be 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -47,8 +47,8 @@ PHLWINDOW CWindow::create(SP surface) { g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->addWindowDeco(std::make_unique(pWindow)); - pWindow->addWindowDeco(std::make_unique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); return pWindow; } @@ -70,8 +70,8 @@ PHLWINDOW CWindow::create(SP resource) { g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); - pWindow->addWindowDeco(std::make_unique(pWindow)); - pWindow->addWindowDeco(std::make_unique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); pWindow->m_pWLSurface->assign(pWindow->m_pXDGSurface->surface.lock(), pWindow); @@ -296,7 +296,7 @@ void CWindow::updateWindowDecos() { } } -void CWindow::addWindowDeco(std::unique_ptr deco) { +void CWindow::addWindowDeco(UP deco) { m_dWindowDecorations.emplace_back(std::move(deco)); g_pDecorationPositioner->forceRecalcFor(m_pSelf.lock()); updateWindowDecos(); @@ -567,8 +567,8 @@ void CWindow::onMap() { if (m_bIsX11) return; - m_pSubsurfaceHead = std::make_unique(m_pSelf.lock()); - m_pPopupHead = std::make_unique(m_pSelf.lock()); + m_pSubsurfaceHead = makeUnique(m_pSelf.lock()); + m_pPopupHead = makeUnique(m_pSelf.lock()); } void CWindow::onBorderAngleAnimEnd(WP pav) { @@ -870,7 +870,7 @@ void CWindow::createGroup() { m_sGroupData.locked = false; m_sGroupData.deny = false; - addWindowDeco(std::make_unique(m_pSelf.lock())); + addWindowDeco(makeUnique(m_pSelf.lock())); if (m_pWorkspace) { m_pWorkspace->updateWindows(); @@ -1052,7 +1052,7 @@ void CWindow::insertWindowToGroup(PHLWINDOW pWindow) { const auto ENDAT = m_sGroupData.pNextWindow.lock(); if (!pWindow->getDecorationByType(DECORATION_GROUPBAR)) - pWindow->addWindowDeco(std::make_unique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); if (!pWindow->m_sGroupData.pNextWindow.lock()) { BEGINAT->m_sGroupData.pNextWindow = pWindow; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index ebda235c..5b4ad654 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -296,8 +296,8 @@ class CWindow { uint64_t m_eSuppressedEvents = SUPPRESS_NONE; // desktop components - std::unique_ptr m_pSubsurfaceHead; - std::unique_ptr m_pPopupHead; + UP m_pSubsurfaceHead; + UP m_pPopupHead; // Animated border CGradientValueData m_cRealBorderColor = {0}; @@ -328,14 +328,14 @@ class CWindow { // Window decorations // TODO: make this a SP. - std::vector> m_dWindowDecorations; - std::vector m_vDecosToRemove; + std::vector> m_dWindowDecorations; + std::vector m_vDecosToRemove; // Special render data, rules, etc SWindowData m_sWindowData; // Transformers - std::vector> m_vTransformers; + std::vector> m_vTransformers; // for alpha PHLANIMVAR m_fActiveInactiveAlpha; @@ -396,7 +396,7 @@ class CWindow { SBoxExtents getFullWindowExtents(); CBox getWindowBoxUnified(uint64_t props); CBox getWindowIdealBoundingBoxIgnoreReserved(); - void addWindowDeco(std::unique_ptr deco); + void addWindowDeco(UP deco); void updateWindowDecos(); void removeWindowDeco(IHyprWindowDecoration* deco); void uncacheWindowDecos(); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index b33725d5..e07d62c6 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -8,7 +8,7 @@ #include "WLClasses.hpp" #include #include -#include + #include #include "Timer.hpp" #include "math/Math.hpp" diff --git a/src/helpers/SdDaemon.cpp b/src/helpers/SdDaemon.cpp index 018165c0..1cf15741 100644 --- a/src/helpers/SdDaemon.cpp +++ b/src/helpers/SdDaemon.cpp @@ -1,7 +1,7 @@ #include "SdDaemon.hpp" +#include "memory/Memory.hpp" #include - #include #include #include diff --git a/src/helpers/Watchdog.cpp b/src/helpers/Watchdog.cpp index b919bbc7..0956eed5 100644 --- a/src/helpers/Watchdog.cpp +++ b/src/helpers/Watchdog.cpp @@ -14,7 +14,7 @@ CWatchdog::~CWatchdog() { CWatchdog::CWatchdog() : m_iMainThreadPID(pthread_self()) { - m_pWatchdog = std::make_unique([this] { + m_pWatchdog = makeUnique([this] { static auto PTIMEOUT = CConfigValue("debug:watchdog_timeout"); m_bWatchdogInitialized = true; diff --git a/src/helpers/Watchdog.hpp b/src/helpers/Watchdog.hpp index b16cb518..51b71d13 100644 --- a/src/helpers/Watchdog.hpp +++ b/src/helpers/Watchdog.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include "memory/Memory.hpp" #include #include #include @@ -24,11 +24,11 @@ class CWatchdog { std::atomic m_bWatching = false; std::atomic m_bWillWatch = false; - std::unique_ptr m_pWatchdog; + UP m_pWatchdog; std::mutex m_mWatchdogMutex; std::atomic m_bNotified = false; std::atomic m_bExitThread = false; std::condition_variable m_cvWatchdogCondition; }; -inline std::unique_ptr g_pWatchdog; \ No newline at end of file +inline UP g_pWatchdog; \ No newline at end of file diff --git a/src/helpers/memory/Memory.hpp b/src/helpers/memory/Memory.hpp index 07f41154..e67c2c81 100644 --- a/src/helpers/memory/Memory.hpp +++ b/src/helpers/memory/Memory.hpp @@ -7,4 +7,4 @@ using namespace Hyprutils::Memory; #define SP Hyprutils::Memory::CSharedPointer #define WP Hyprutils::Memory::CWeakPointer -#define UP std::unique_ptr +#define UP Hyprutils::Memory::CUniquePointer diff --git a/src/hyprerror/HyprError.hpp b/src/hyprerror/HyprError.hpp index 9a662423..771e50f0 100644 --- a/src/hyprerror/HyprError.hpp +++ b/src/hyprerror/HyprError.hpp @@ -32,4 +32,4 @@ class CHyprError { bool m_bMonitorChanged = false; }; -inline std::unique_ptr g_pHyprError; // This is a full-screen error. Treat it with respect, and there can only be one at a time. +inline UP g_pHyprError; // This is a full-screen error. Treat it with respect, and there can only be one at a time. diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 156141f6..576d80eb 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -215,7 +215,7 @@ bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) { recalculateWindow(pWindow); if (!pWindow->getDecorationByType(DECORATION_GROUPBAR)) - pWindow->addWindowDeco(std::make_unique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); return true; } @@ -374,7 +374,7 @@ void IHyprLayout::onEndDragWindow() { DRAGGINGWINDOW->updateWindowDecos(); if (!DRAGGINGWINDOW->getDecorationByType(DECORATION_GROUPBAR)) - DRAGGINGWINDOW->addWindowDeco(std::make_unique(DRAGGINGWINDOW)); + DRAGGINGWINDOW->addWindowDeco(makeUnique(DRAGGINGWINDOW)); } } } diff --git a/src/main.cpp b/src/main.cpp index ebae055b..bb5e5622 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -155,7 +155,7 @@ int main(int argc, char** argv) { // let's init the compositor. // it initializes basic Wayland stuff in the constructor. try { - g_pCompositor = std::make_unique(); + g_pCompositor = makeUnique(); g_pCompositor->explicitConfigPath = configPath; } catch (const std::exception& e) { std::println(stderr, "Hyprland threw in ctor: {}\nCannot continue.", e.what()); diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index 10eeef05..067fa676 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -61,4 +61,4 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { void animationSlide(PHLWINDOW, std::string force = "", bool close = false); }; -inline std::unique_ptr g_pAnimationManager; +inline UP g_pAnimationManager; diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index d6584f35..160ef2eb 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -64,8 +64,8 @@ void CCursorBuffer::endDataPtr() { } CCursorManager::CCursorManager() { - m_pHyprcursor = std::make_unique(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), hcLogger); - m_pXcursor = std::make_unique(); + m_pHyprcursor = makeUnique(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), hcLogger); + m_pXcursor = makeUnique(); static auto PUSEHYPRCURSOR = CConfigValue("cursor:enable_hyprcursor"); if (m_pHyprcursor->valid() && *PUSEHYPRCURSOR) { @@ -323,7 +323,7 @@ bool CCursorManager::changeTheme(const std::string& name, const int size) { m_szTheme = name.empty() ? "" : name; m_iSize = size; - m_pHyprcursor = std::make_unique(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), options); + m_pHyprcursor = makeUnique(m_szTheme.empty() ? nullptr : m_szTheme.c_str(), options); if (!m_pHyprcursor->valid()) { Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to XCursor.", m_szTheme); m_pXcursor->loadTheme(m_szTheme.empty() ? xcursor_theme : m_szTheme, m_iSize, m_fCursorScale); diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp index 796ab10e..c5ded5da 100644 --- a/src/managers/CursorManager.hpp +++ b/src/managers/CursorManager.hpp @@ -2,7 +2,6 @@ #include #include -#include #include "../includes.hpp" #include "../helpers/math/Math.hpp" #include "../helpers/memory/Memory.hpp" @@ -58,22 +57,22 @@ class CCursorManager { void tickAnimatedCursor(); private: - bool m_bOurBufferConnected = false; - std::vector> m_vCursorBuffers; + bool m_bOurBufferConnected = false; + std::vector> m_vCursorBuffers; - std::unique_ptr m_pHyprcursor; - std::unique_ptr m_pXcursor; - SP m_currentXcursor; + UP m_pHyprcursor; + UP m_pXcursor; + SP m_currentXcursor; - std::string m_szTheme = ""; - int m_iSize = 0; - float m_fCursorScale = 1.0; + std::string m_szTheme = ""; + int m_iSize = 0; + float m_fCursorScale = 1.0; - Hyprcursor::SCursorStyleInfo m_sCurrentStyleInfo; + Hyprcursor::SCursorStyleInfo m_sCurrentStyleInfo; - SP m_pAnimationTimer; - int m_iCurrentAnimationFrame = 0; - Hyprcursor::SCursorShapeData m_sCurrentCursorShapeData; + SP m_pAnimationTimer; + int m_iCurrentAnimationFrame = 0; + Hyprcursor::SCursorShapeData m_sCurrentCursorShapeData; }; -inline std::unique_ptr g_pCursorManager; +inline UP g_pCursorManager; diff --git a/src/managers/DonationNagManager.hpp b/src/managers/DonationNagManager.hpp index e296d815..357f979f 100644 --- a/src/managers/DonationNagManager.hpp +++ b/src/managers/DonationNagManager.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include "../helpers/memory/Memory.hpp" class CDonationNagManager { public: @@ -13,4 +13,4 @@ class CDonationNagManager { bool m_bFired = false; }; -inline std::unique_ptr g_pDonationNagManager; \ No newline at end of file +inline UP g_pDonationNagManager; \ No newline at end of file diff --git a/src/managers/EventManager.hpp b/src/managers/EventManager.hpp index 37716e63..5a88963e 100644 --- a/src/managers/EventManager.hpp +++ b/src/managers/EventManager.hpp @@ -42,4 +42,4 @@ class CEventManager { std::vector m_vClients; }; -inline std::unique_ptr g_pEventManager; +inline UP g_pEventManager; diff --git a/src/managers/HookSystemManager.hpp b/src/managers/HookSystemManager.hpp index 5a9d0c00..6d72a02d 100644 --- a/src/managers/HookSystemManager.hpp +++ b/src/managers/HookSystemManager.hpp @@ -57,4 +57,4 @@ class CHookSystemManager { std::unordered_map> m_mRegisteredHooks; }; -inline std::unique_ptr g_pHookSystem; +inline UP g_pHookSystem; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 0816de2a..f4a55a73 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -2840,7 +2840,7 @@ void CKeybindManager::moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowIn pWindow->warpCursor(); if (!pWindow->getDecorationByType(DECORATION_GROUPBAR)) - pWindow->addWindowDeco(std::make_unique(pWindow)); + pWindow->addWindowDeco(makeUnique(pWindow)); g_pEventManager->postEvent(SHyprIPCEvent{"moveintogroup", std::format("{:x}", (uintptr_t)pWindow.get())}); } diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index d01ec75b..1848ca78 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -229,4 +229,4 @@ class CKeybindManager { friend class CPointerManager; }; -inline std::unique_ptr g_pKeybindManager; +inline UP g_pKeybindManager; diff --git a/src/managers/LayoutManager.hpp b/src/managers/LayoutManager.hpp index 6042b3b2..63e54baa 100644 --- a/src/managers/LayoutManager.hpp +++ b/src/managers/LayoutManager.hpp @@ -28,4 +28,4 @@ class CLayoutManager { std::vector> m_vLayouts; }; -inline std::unique_ptr g_pLayoutManager; +inline UP g_pLayoutManager; diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 8e32bdec..f73a6d3c 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -119,75 +119,75 @@ CProtocolManager::CProtocolManager() { }); // Core - PROTO::seat = std::make_unique(&wl_seat_interface, 9, "WLSeat"); - PROTO::data = std::make_unique(&wl_data_device_manager_interface, 3, "WLDataDevice"); - PROTO::compositor = std::make_unique(&wl_compositor_interface, 6, "WLCompositor"); - PROTO::subcompositor = std::make_unique(&wl_subcompositor_interface, 1, "WLSubcompositor"); - PROTO::shm = std::make_unique(&wl_shm_interface, 1, "WLSHM"); + PROTO::seat = makeUnique(&wl_seat_interface, 9, "WLSeat"); + PROTO::data = makeUnique(&wl_data_device_manager_interface, 3, "WLDataDevice"); + PROTO::compositor = makeUnique(&wl_compositor_interface, 6, "WLCompositor"); + PROTO::subcompositor = makeUnique(&wl_subcompositor_interface, 1, "WLSubcompositor"); + PROTO::shm = makeUnique(&wl_shm_interface, 1, "WLSHM"); // Extensions - PROTO::viewport = std::make_unique(&wp_viewporter_interface, 1, "Viewporter"); - PROTO::tearing = std::make_unique(&wp_tearing_control_manager_v1_interface, 1, "TearingControl"); - PROTO::fractional = std::make_unique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale"); - PROTO::xdgOutput = std::make_unique(&zxdg_output_manager_v1_interface, 3, "XDGOutput"); - PROTO::cursorShape = std::make_unique(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape"); - PROTO::idleInhibit = std::make_unique(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit"); - PROTO::relativePointer = std::make_unique(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer"); - PROTO::xdgDecoration = std::make_unique(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration"); - PROTO::alphaModifier = std::make_unique(&wp_alpha_modifier_v1_interface, 1, "AlphaModifier"); - PROTO::gamma = std::make_unique(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl"); - PROTO::foreignToplevel = std::make_unique(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel"); - PROTO::pointerGestures = std::make_unique(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures"); - PROTO::foreignToplevelWlr = std::make_unique(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr"); - PROTO::shortcutsInhibit = std::make_unique(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit"); - PROTO::textInputV1 = std::make_unique(&zwp_text_input_manager_v1_interface, 1, "TextInputV1"); - PROTO::textInputV3 = std::make_unique(&zwp_text_input_manager_v3_interface, 1, "TextInputV3"); - PROTO::constraints = std::make_unique(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints"); - PROTO::outputPower = std::make_unique(&zwlr_output_power_manager_v1_interface, 1, "OutputPower"); - PROTO::activation = std::make_unique(&xdg_activation_v1_interface, 1, "XDGActivation"); - PROTO::idle = std::make_unique(&ext_idle_notifier_v1_interface, 1, "IdleNotify"); - PROTO::lockNotify = std::make_unique(&hyprland_lock_notifier_v1_interface, 1, "IdleNotify"); - PROTO::sessionLock = std::make_unique(&ext_session_lock_manager_v1_interface, 1, "SessionLock"); - PROTO::ime = std::make_unique(&zwp_input_method_manager_v2_interface, 1, "IMEv2"); - PROTO::virtualKeyboard = std::make_unique(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard"); - PROTO::virtualPointer = std::make_unique(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer"); - PROTO::outputManagement = std::make_unique(&zwlr_output_manager_v1_interface, 4, "OutputManagement"); - PROTO::serverDecorationKDE = std::make_unique(&org_kde_kwin_server_decoration_manager_interface, 1, "ServerDecorationKDE"); - PROTO::focusGrab = std::make_unique(&hyprland_focus_grab_manager_v1_interface, 1, "FocusGrab"); - PROTO::tablet = std::make_unique(&zwp_tablet_manager_v2_interface, 1, "TabletV2"); - PROTO::layerShell = std::make_unique(&zwlr_layer_shell_v1_interface, 5, "LayerShell"); - PROTO::presentation = std::make_unique(&wp_presentation_interface, 1, "Presentation"); - PROTO::xdgShell = std::make_unique(&xdg_wm_base_interface, 6, "XDGShell"); - PROTO::dataWlr = std::make_unique(&zwlr_data_control_manager_v1_interface, 2, "DataDeviceWlr"); - PROTO::primarySelection = std::make_unique(&zwp_primary_selection_device_manager_v1_interface, 1, "PrimarySelection"); - PROTO::xwaylandShell = std::make_unique(&xwayland_shell_v1_interface, 1, "XWaylandShell"); - PROTO::screencopy = std::make_unique(&zwlr_screencopy_manager_v1_interface, 3, "Screencopy"); - PROTO::toplevelExport = std::make_unique(&hyprland_toplevel_export_manager_v1_interface, 2, "ToplevelExport"); - PROTO::globalShortcuts = std::make_unique(&hyprland_global_shortcuts_manager_v1_interface, 1, "GlobalShortcuts"); - PROTO::xdgDialog = std::make_unique(&xdg_dialog_v1_interface, 1, "XDGDialog"); - PROTO::singlePixel = std::make_unique(&wp_single_pixel_buffer_manager_v1_interface, 1, "SinglePixel"); - PROTO::securityContext = std::make_unique(&wp_security_context_manager_v1_interface, 1, "SecurityContext"); - PROTO::ctm = std::make_unique(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl"); - PROTO::hyprlandSurface = std::make_unique(&hyprland_surface_manager_v1_interface, 1, "HyprlandSurface"); + PROTO::viewport = makeUnique(&wp_viewporter_interface, 1, "Viewporter"); + PROTO::tearing = makeUnique(&wp_tearing_control_manager_v1_interface, 1, "TearingControl"); + PROTO::fractional = makeUnique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale"); + PROTO::xdgOutput = makeUnique(&zxdg_output_manager_v1_interface, 3, "XDGOutput"); + PROTO::cursorShape = makeUnique(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape"); + PROTO::idleInhibit = makeUnique(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit"); + PROTO::relativePointer = makeUnique(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer"); + PROTO::xdgDecoration = makeUnique(&zxdg_decoration_manager_v1_interface, 1, "XDGDecoration"); + PROTO::alphaModifier = makeUnique(&wp_alpha_modifier_v1_interface, 1, "AlphaModifier"); + PROTO::gamma = makeUnique(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl"); + PROTO::foreignToplevel = makeUnique(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel"); + PROTO::pointerGestures = makeUnique(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures"); + PROTO::foreignToplevelWlr = makeUnique(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr"); + PROTO::shortcutsInhibit = makeUnique(&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1, "ShortcutsInhibit"); + PROTO::textInputV1 = makeUnique(&zwp_text_input_manager_v1_interface, 1, "TextInputV1"); + PROTO::textInputV3 = makeUnique(&zwp_text_input_manager_v3_interface, 1, "TextInputV3"); + PROTO::constraints = makeUnique(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints"); + PROTO::outputPower = makeUnique(&zwlr_output_power_manager_v1_interface, 1, "OutputPower"); + PROTO::activation = makeUnique(&xdg_activation_v1_interface, 1, "XDGActivation"); + PROTO::idle = makeUnique(&ext_idle_notifier_v1_interface, 1, "IdleNotify"); + PROTO::lockNotify = makeUnique(&hyprland_lock_notifier_v1_interface, 1, "IdleNotify"); + PROTO::sessionLock = makeUnique(&ext_session_lock_manager_v1_interface, 1, "SessionLock"); + PROTO::ime = makeUnique(&zwp_input_method_manager_v2_interface, 1, "IMEv2"); + PROTO::virtualKeyboard = makeUnique(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard"); + PROTO::virtualPointer = makeUnique(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer"); + PROTO::outputManagement = makeUnique(&zwlr_output_manager_v1_interface, 4, "OutputManagement"); + PROTO::serverDecorationKDE = makeUnique(&org_kde_kwin_server_decoration_manager_interface, 1, "ServerDecorationKDE"); + PROTO::focusGrab = makeUnique(&hyprland_focus_grab_manager_v1_interface, 1, "FocusGrab"); + PROTO::tablet = makeUnique(&zwp_tablet_manager_v2_interface, 1, "TabletV2"); + PROTO::layerShell = makeUnique(&zwlr_layer_shell_v1_interface, 5, "LayerShell"); + PROTO::presentation = makeUnique(&wp_presentation_interface, 1, "Presentation"); + PROTO::xdgShell = makeUnique(&xdg_wm_base_interface, 6, "XDGShell"); + PROTO::dataWlr = makeUnique(&zwlr_data_control_manager_v1_interface, 2, "DataDeviceWlr"); + PROTO::primarySelection = makeUnique(&zwp_primary_selection_device_manager_v1_interface, 1, "PrimarySelection"); + PROTO::xwaylandShell = makeUnique(&xwayland_shell_v1_interface, 1, "XWaylandShell"); + PROTO::screencopy = makeUnique(&zwlr_screencopy_manager_v1_interface, 3, "Screencopy"); + PROTO::toplevelExport = makeUnique(&hyprland_toplevel_export_manager_v1_interface, 2, "ToplevelExport"); + PROTO::globalShortcuts = makeUnique(&hyprland_global_shortcuts_manager_v1_interface, 1, "GlobalShortcuts"); + PROTO::xdgDialog = makeUnique(&xdg_dialog_v1_interface, 1, "XDGDialog"); + PROTO::singlePixel = makeUnique(&wp_single_pixel_buffer_manager_v1_interface, 1, "SinglePixel"); + PROTO::securityContext = makeUnique(&wp_security_context_manager_v1_interface, 1, "SecurityContext"); + PROTO::ctm = makeUnique(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl"); + PROTO::hyprlandSurface = makeUnique(&hyprland_surface_manager_v1_interface, 1, "HyprlandSurface"); if (*PENABLEXXCM) { - PROTO::colorManagement = std::make_unique(&xx_color_manager_v4_interface, 1, "ColorManagement"); - PROTO::frogColorManagement = std::make_unique(&frog_color_management_factory_v1_interface, 1, "FrogColorManagement"); + PROTO::colorManagement = makeUnique(&xx_color_manager_v4_interface, 1, "ColorManagement"); + PROTO::frogColorManagement = makeUnique(&frog_color_management_factory_v1_interface, 1, "FrogColorManagement"); } for (auto const& b : g_pCompositor->m_pAqBackend->getImplementations()) { if (b->type() != Aquamarine::AQ_BACKEND_DRM) continue; - PROTO::lease = std::make_unique(&wp_drm_lease_device_v1_interface, 1, "DRMLease"); + PROTO::lease = makeUnique(&wp_drm_lease_device_v1_interface, 1, "DRMLease"); if (*PENABLEEXPLICIT) - PROTO::sync = std::make_unique(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj"); + PROTO::sync = makeUnique(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj"); break; } if (g_pHyprOpenGL->getDRMFormats().size() > 0) { - PROTO::mesaDRM = std::make_unique(&wl_drm_interface, 2, "MesaDRM"); - PROTO::linuxDma = std::make_unique(&zwp_linux_dmabuf_v1_interface, 5, "LinuxDMABUF"); + PROTO::mesaDRM = makeUnique(&wl_drm_interface, 2, "MesaDRM"); + PROTO::linuxDma = makeUnique(&zwp_linux_dmabuf_v1_interface, 5, "LinuxDMABUF"); } else Debug::log(WARN, "ProtocolManager: Not binding linux-dmabuf and MesaDRM: DMABUF not available"); } diff --git a/src/managers/ProtocolManager.hpp b/src/managers/ProtocolManager.hpp index 6ceff9ad..1ec8db4a 100644 --- a/src/managers/ProtocolManager.hpp +++ b/src/managers/ProtocolManager.hpp @@ -18,4 +18,4 @@ class CProtocolManager { void onMonitorModeChange(PHLMONITOR pMonitor); }; -inline std::unique_ptr g_pProtocolManager; +inline UP g_pProtocolManager; diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp index 3d77f05a..ea0d8dfc 100644 --- a/src/managers/SessionLockManager.cpp +++ b/src/managers/SessionLockManager.cpp @@ -57,7 +57,7 @@ void CSessionLockManager::onNewSessionLock(SP pLock) { Debug::log(LOG, "Session got locked by {:x}", (uintptr_t)pLock.get()); - m_pSessionLock = std::make_unique(); + m_pSessionLock = makeUnique(); m_pSessionLock->lock = pLock; m_pSessionLock->mLockTimer.reset(); @@ -66,7 +66,7 @@ void CSessionLockManager::onNewSessionLock(SP pLock) { const auto PMONITOR = SURFACE->monitor(); - const auto NEWSURFACE = m_pSessionLock->vSessionLockSurfaces.emplace_back(std::make_unique(SURFACE)).get(); + const auto NEWSURFACE = m_pSessionLock->vSessionLockSurfaces.emplace_back(makeUnique(SURFACE)).get(); NEWSURFACE->iMonitorID = PMONITOR->ID; PROTO::fractional->sendScale(SURFACE->surface(), PMONITOR->scale); }); diff --git a/src/managers/SessionLockManager.hpp b/src/managers/SessionLockManager.hpp index 59090605..aaf78819 100644 --- a/src/managers/SessionLockManager.hpp +++ b/src/managers/SessionLockManager.hpp @@ -28,11 +28,11 @@ struct SSessionLockSurface { }; struct SSessionLock { - WP lock; - CTimer mLockTimer; + WP lock; + CTimer mLockTimer; - std::vector> vSessionLockSurfaces; - std::unordered_map mMonitorsWithoutMappedSurfaceTimers; + std::vector> vSessionLockSurfaces; + std::unordered_map mMonitorsWithoutMappedSurfaceTimers; struct { CHyprSignalListener newSurface; @@ -74,4 +74,4 @@ class CSessionLockManager { void onNewSessionLock(SP pWlrLock); }; -inline std::unique_ptr g_pSessionLockManager; +inline UP g_pSessionLockManager; diff --git a/src/managers/TokenManager.hpp b/src/managers/TokenManager.hpp index 92638e9b..aaf068bc 100644 --- a/src/managers/TokenManager.hpp +++ b/src/managers/TokenManager.hpp @@ -35,4 +35,4 @@ class CTokenManager { std::unordered_map> m_mTokens; }; -inline std::unique_ptr g_pTokenManager; \ No newline at end of file +inline UP g_pTokenManager; \ No newline at end of file diff --git a/src/managers/VersionKeeperManager.hpp b/src/managers/VersionKeeperManager.hpp index eb404d88..250a36b8 100644 --- a/src/managers/VersionKeeperManager.hpp +++ b/src/managers/VersionKeeperManager.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include "../helpers/memory/Memory.hpp" class CVersionKeeperManager { public: @@ -15,4 +15,4 @@ class CVersionKeeperManager { bool m_bFired = false; }; -inline std::unique_ptr g_pVersionKeeperMgr; \ No newline at end of file +inline UP g_pVersionKeeperMgr; \ No newline at end of file diff --git a/src/managers/XCursorManager.cpp b/src/managers/XCursorManager.cpp index 42c5e427..3473df44 100644 --- a/src/managers/XCursorManager.cpp +++ b/src/managers/XCursorManager.cpp @@ -9,6 +9,7 @@ #include "../managers/CursorManager.hpp" #include "debug/Log.hpp" #include "XCursorManager.hpp" +#include // clang-format off static std::vector HYPR_XCURSOR_PIXELS = { diff --git a/src/managers/XWaylandManager.hpp b/src/managers/XWaylandManager.hpp index 18627a78..8ce239f6 100644 --- a/src/managers/XWaylandManager.hpp +++ b/src/managers/XWaylandManager.hpp @@ -25,4 +25,4 @@ class CHyprXWaylandManager { Vector2D waylandToXWaylandCoords(const Vector2D&); }; -inline std::unique_ptr g_pXWaylandManager; \ No newline at end of file +inline UP g_pXWaylandManager; \ No newline at end of file diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index e1c243d3..95cc6109 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -69,4 +69,4 @@ class CEventLoopManager { friend class CSyncTimeline; }; -inline std::unique_ptr g_pEventLoopManager; +inline UP g_pEventLoopManager; diff --git a/src/managers/input/IdleInhibitor.cpp b/src/managers/input/IdleInhibitor.cpp index 74760c0a..67837c17 100644 --- a/src/managers/input/IdleInhibitor.cpp +++ b/src/managers/input/IdleInhibitor.cpp @@ -5,7 +5,7 @@ #include "../../protocols/core/Compositor.hpp" void CInputManager::newIdleInhibitor(std::any inhibitor) { - const auto PINHIBIT = m_vIdleInhibitors.emplace_back(std::make_unique()).get(); + const auto PINHIBIT = m_vIdleInhibitors.emplace_back(makeUnique()).get(); PINHIBIT->inhibitor = std::any_cast>(inhibitor); Debug::log(LOG, "New idle inhibitor registered for surface {:x}", (uintptr_t)PINHIBIT->inhibitor->surface.get()); diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 36c8144d..c0f1939e 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -268,7 +268,7 @@ class CInputManager { bool nonDesktop = false; CHyprSignalListener surfaceDestroyListener; }; - std::vector> m_vIdleInhibitors; + std::vector> m_vIdleInhibitors; // swipe void beginWorkspaceSwipe(); @@ -304,4 +304,4 @@ class CInputManager { friend class CWLSurface; }; -inline std::unique_ptr g_pInputManager; +inline UP g_pInputManager; diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 58cff043..5f6c4354 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -50,7 +50,7 @@ void CInputMethodRelay::onNewIME(SP pIME) { }); listeners.newPopup = pIME->events.newPopup.registerListener([this](std::any d) { - m_vIMEPopups.emplace_back(std::make_unique(std::any_cast>(d))); + m_vIMEPopups.emplace_back(makeUnique(std::any_cast>(d))); Debug::log(LOG, "New input popup"); }); @@ -86,11 +86,11 @@ CTextInput* CInputMethodRelay::getFocusedTextInput() { } void CInputMethodRelay::onNewTextInput(WP tiv3) { - m_vTextInputs.emplace_back(std::make_unique(tiv3)); + m_vTextInputs.emplace_back(makeUnique(tiv3)); } void CInputMethodRelay::onNewTextInput(WP pTIV1) { - m_vTextInputs.emplace_back(std::make_unique(pTIV1)); + m_vTextInputs.emplace_back(makeUnique(pTIV1)); } void CInputMethodRelay::removeTextInput(CTextInput* pInput) { diff --git a/src/managers/input/InputMethodRelay.hpp b/src/managers/input/InputMethodRelay.hpp index 998e1fc6..602a939a 100644 --- a/src/managers/input/InputMethodRelay.hpp +++ b/src/managers/input/InputMethodRelay.hpp @@ -40,10 +40,10 @@ class CInputMethodRelay { WP m_pIME; private: - std::vector> m_vTextInputs; - std::vector> m_vIMEPopups; + std::vector> m_vTextInputs; + std::vector> m_vIMEPopups; - WP m_pLastKbFocus; + WP m_pLastKbFocus; struct { CHyprSignalListener newTIV3; diff --git a/src/managers/input/TextInput.hpp b/src/managers/input/TextInput.hpp index c0b590ac..37b471af 100644 --- a/src/managers/input/TextInput.hpp +++ b/src/managers/input/TextInput.hpp @@ -3,7 +3,6 @@ #include "../../helpers/math/Math.hpp" #include "../../helpers/signal/Signal.hpp" #include "../../helpers/memory/Memory.hpp" -#include struct wl_client; diff --git a/src/pch/pch.hpp b/src/pch/pch.hpp index 8dc98fac..f9d5b130 100644 --- a/src/pch/pch.hpp +++ b/src/pch/pch.hpp @@ -11,7 +11,7 @@ #include #include #include -#include + #include #include #include diff --git a/src/plugins/HookSystem.cpp b/src/plugins/HookSystem.cpp index c19f6f46..9fa61561 100644 --- a/src/plugins/HookSystem.cpp +++ b/src/plugins/HookSystem.cpp @@ -253,7 +253,7 @@ bool CFunctionHook::unhook() { } CFunctionHook* CHookSystem::initHook(HANDLE owner, void* source, void* destination) { - return m_vHooks.emplace_back(std::make_unique(owner, source, destination)).get(); + return m_vHooks.emplace_back(makeUnique(owner, source, destination)).get(); } bool CHookSystem::removeHook(CFunctionHook* hook) { diff --git a/src/plugins/HookSystem.hpp b/src/plugins/HookSystem.hpp index f0a5a11d..93ca4ff5 100644 --- a/src/plugins/HookSystem.hpp +++ b/src/plugins/HookSystem.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include "../helpers/memory/Memory.hpp" #define HANDLE void* #define HOOK_TRAMPOLINE_MAX_SIZE 64 @@ -60,9 +60,9 @@ class CHookSystem { void removeAllHooksFrom(HANDLE handle); private: - std::vector> m_vHooks; + std::vector> m_vHooks; - uint64_t getAddressForTrampo(); + uint64_t getAddressForTrampo(); struct SAllocatedPage { uint64_t addr = 0; @@ -75,4 +75,4 @@ class CHookSystem { friend class CFunctionHook; }; -inline std::unique_ptr g_pFunctionHookSystem; \ No newline at end of file +inline UP g_pFunctionHookSystem; \ No newline at end of file diff --git a/src/plugins/PluginAPI.cpp b/src/plugins/PluginAPI.cpp index fbb1ec1b..92f043fd 100644 --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -106,7 +106,7 @@ APICALL bool HyprlandAPI::removeFunctionHook(HANDLE handle, CFunctionHook* hook) return g_pFunctionHookSystem->removeHook(hook); } -APICALL bool HyprlandAPI::addWindowDecoration(HANDLE handle, PHLWINDOW pWindow, std::unique_ptr pDecoration) { +APICALL bool HyprlandAPI::addWindowDecoration(HANDLE handle, PHLWINDOW pWindow, UP pDecoration) { auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle); if (!PLUGIN) diff --git a/src/plugins/PluginAPI.hpp b/src/plugins/PluginAPI.hpp index 96c32bf1..c8c9e563 100644 --- a/src/plugins/PluginAPI.hpp +++ b/src/plugins/PluginAPI.hpp @@ -223,7 +223,7 @@ namespace HyprlandAPI { returns: true on success. False otherwise. */ - APICALL bool addWindowDecoration(HANDLE handle, PHLWINDOW pWindow, std::unique_ptr pDecoration); + APICALL bool addWindowDecoration(HANDLE handle, PHLWINDOW pWindow, UP pDecoration); /* Removes a window decoration diff --git a/src/plugins/PluginSystem.cpp b/src/plugins/PluginSystem.cpp index e849bf11..87b9e8ef 100644 --- a/src/plugins/PluginSystem.cpp +++ b/src/plugins/PluginSystem.cpp @@ -8,7 +8,7 @@ #include "../managers/eventLoop/EventLoopManager.hpp" CPluginSystem::CPluginSystem() { - g_pFunctionHookSystem = std::make_unique(); + g_pFunctionHookSystem = makeUnique(); } CPlugin* CPluginSystem::loadPlugin(const std::string& path) { @@ -21,7 +21,7 @@ CPlugin* CPluginSystem::loadPlugin(const std::string& path) { return nullptr; } - auto* const PLUGIN = m_vLoadedPlugins.emplace_back(std::make_unique()).get(); + auto* const PLUGIN = m_vLoadedPlugins.emplace_back(makeUnique()).get(); PLUGIN->path = path; diff --git a/src/plugins/PluginSystem.hpp b/src/plugins/PluginSystem.hpp index 336c484d..95841bef 100644 --- a/src/plugins/PluginSystem.hpp +++ b/src/plugins/PluginSystem.hpp @@ -44,9 +44,9 @@ class CPluginSystem { std::string m_szLastError = ""; private: - std::vector> m_vLoadedPlugins; + std::vector> m_vLoadedPlugins; - jmp_buf m_jbPluginFaultJumpBuf; + jmp_buf m_jbPluginFaultJumpBuf; }; -inline std::unique_ptr g_pPluginSystem; +inline UP g_pPluginSystem; diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp index dc32bb8c..e8766405 100644 --- a/src/protocols/AlphaModifier.cpp +++ b/src/protocols/AlphaModifier.cpp @@ -64,7 +64,7 @@ CAlphaModifierProtocol::CAlphaModifierProtocol(const wl_interface* iface, const } void CAlphaModifierProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CWpAlphaModifierV1* manager) { destroyManager(manager); }); RESOURCE->setDestroy([this](CWpAlphaModifierV1* manager) { destroyManager(manager); }); @@ -93,9 +93,8 @@ void CAlphaModifierProtocol::getSurface(CWpAlphaModifierV1* manager, uint32_t id alphaModifier = iter->second.get(); } } else { - alphaModifier = - m_mAlphaModifiers.emplace(surface, std::make_unique(makeShared(manager->client(), manager->version(), id), surface)) - .first->second.get(); + alphaModifier = m_mAlphaModifiers.emplace(surface, makeUnique(makeShared(manager->client(), manager->version(), id), surface)) + .first->second.get(); } if UNLIKELY (!alphaModifier->good()) { diff --git a/src/protocols/AlphaModifier.hpp b/src/protocols/AlphaModifier.hpp index 43f78bef..9a7873ae 100644 --- a/src/protocols/AlphaModifier.hpp +++ b/src/protocols/AlphaModifier.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index 91f4501f..5560271f 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -106,7 +106,7 @@ void CHyprlandCTMControlProtocol::setCTM(PHLMONITOR monitor, const Mat3x3& ctm) std::erase_if(m_mCTMDatas, [](const auto& el) { return !el.first; }); if (!m_mCTMDatas.contains(monitor)) - m_mCTMDatas[monitor] = std::make_unique(); + m_mCTMDatas[monitor] = makeUnique(); auto& data = m_mCTMDatas.at(monitor); diff --git a/src/protocols/CTMControl.hpp b/src/protocols/CTMControl.hpp index 2639d176..2c168acd 100644 --- a/src/protocols/CTMControl.hpp +++ b/src/protocols/CTMControl.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" @@ -45,7 +44,7 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { Mat3x3 ctmFrom = Mat3x3::identity(), ctmTo = Mat3x3::identity(); PHLANIMVAR progress; }; - std::map> m_mCTMDatas; + std::map> m_mCTMDatas; friend class CHyprlandCTMControlResource; }; diff --git a/src/protocols/ColorManagement.hpp b/src/protocols/ColorManagement.hpp index e387b3b7..39e3f486 100644 --- a/src/protocols/ColorManagement.hpp +++ b/src/protocols/ColorManagement.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/CursorShape.cpp b/src/protocols/CursorShape.cpp index 429d604f..e7eb6159 100644 --- a/src/protocols/CursorShape.cpp +++ b/src/protocols/CursorShape.cpp @@ -15,7 +15,7 @@ void CCursorShapeProtocol::onDeviceResourceDestroy(wl_resource* res) { } void CCursorShapeProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CWpCursorShapeManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CWpCursorShapeManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/CursorShape.hpp b/src/protocols/CursorShape.hpp index 9fcca28d..37b7e6c8 100644 --- a/src/protocols/CursorShape.hpp +++ b/src/protocols/CursorShape.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "../helpers/signal/Signal.hpp" diff --git a/src/protocols/DRMLease.hpp b/src/protocols/DRMLease.hpp index 37de40e3..ec1e73f2 100644 --- a/src/protocols/DRMLease.hpp +++ b/src/protocols/DRMLease.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/DRMSyncobj.hpp b/src/protocols/DRMSyncobj.hpp index bc89a3d3..42ecdb3e 100644 --- a/src/protocols/DRMSyncobj.hpp +++ b/src/protocols/DRMSyncobj.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "linux-drm-syncobj-v1.hpp" diff --git a/src/protocols/DataDeviceWlr.hpp b/src/protocols/DataDeviceWlr.hpp index 193e918c..5eef163c 100644 --- a/src/protocols/DataDeviceWlr.hpp +++ b/src/protocols/DataDeviceWlr.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp index ee30343f..ab9d22ef 100644 --- a/src/protocols/FocusGrab.cpp +++ b/src/protocols/FocusGrab.cpp @@ -5,7 +5,6 @@ #include "../managers/SeatManager.hpp" #include "core/Compositor.hpp" #include -#include #include CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, SP surface) { @@ -77,7 +76,7 @@ void CFocusGrab::finish(bool sendCleared) { void CFocusGrab::addSurface(SP surface) { auto iter = std::find_if(m_mSurfaces.begin(), m_mSurfaces.end(), [surface](const auto& e) { return e.first == surface; }); if (iter == m_mSurfaces.end()) - m_mSurfaces.emplace(surface, std::make_unique(this, surface)); + m_mSurfaces.emplace(surface, makeUnique(this, surface)); } void CFocusGrab::removeSurface(SP surface) { @@ -151,7 +150,7 @@ CFocusGrabProtocol::CFocusGrabProtocol(const wl_interface* iface, const int& ver } void CFocusGrabProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CHyprlandFocusGrabManagerV1* p) { onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CHyprlandFocusGrabManagerV1* p) { onManagerResourceDestroy(p->resource()); }); @@ -167,7 +166,7 @@ void CFocusGrabProtocol::destroyGrab(CFocusGrab* grab) { } void CFocusGrabProtocol::onCreateGrab(CHyprlandFocusGrabManagerV1* pMgr, uint32_t id) { - m_vGrabs.push_back(std::make_unique(makeShared(pMgr->client(), pMgr->version(), id))); + m_vGrabs.push_back(makeUnique(makeShared(pMgr->client(), pMgr->version(), id))); const auto RESOURCE = m_vGrabs.back().get(); if UNLIKELY (!RESOURCE->good()) { diff --git a/src/protocols/ForeignToplevel.cpp b/src/protocols/ForeignToplevel.cpp index 6880164f..4e5fda48 100644 --- a/src/protocols/ForeignToplevel.cpp +++ b/src/protocols/ForeignToplevel.cpp @@ -147,7 +147,7 @@ CForeignToplevelProtocol::CForeignToplevelProtocol(const wl_interface* iface, co } void CForeignToplevelProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(makeShared(client, ver, id))).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(makeShared(client, ver, id))).get(); if UNLIKELY (!RESOURCE->good()) { LOGM(ERR, "Couldn't create a foreign list"); diff --git a/src/protocols/ForeignToplevel.hpp b/src/protocols/ForeignToplevel.hpp index 076bfd7c..712b32e0 100644 --- a/src/protocols/ForeignToplevel.hpp +++ b/src/protocols/ForeignToplevel.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/ForeignToplevelWlr.cpp b/src/protocols/ForeignToplevelWlr.cpp index e18f6e23..e50c85d9 100644 --- a/src/protocols/ForeignToplevelWlr.cpp +++ b/src/protocols/ForeignToplevelWlr.cpp @@ -376,7 +376,7 @@ CForeignToplevelWlrProtocol::CForeignToplevelWlrProtocol(const wl_interface* ifa } void CForeignToplevelWlrProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(makeShared(client, ver, id))).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(makeShared(client, ver, id))).get(); if UNLIKELY (!RESOURCE->good()) { LOGM(ERR, "Couldn't create a foreign list"); diff --git a/src/protocols/ForeignToplevelWlr.hpp b/src/protocols/ForeignToplevelWlr.hpp index 880b7a14..d0479d98 100644 --- a/src/protocols/ForeignToplevelWlr.hpp +++ b/src/protocols/ForeignToplevelWlr.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "wlr-foreign-toplevel-management-unstable-v1.hpp" diff --git a/src/protocols/FractionalScale.cpp b/src/protocols/FractionalScale.cpp index 3b24becd..494de9c5 100644 --- a/src/protocols/FractionalScale.cpp +++ b/src/protocols/FractionalScale.cpp @@ -7,7 +7,7 @@ CFractionalScaleProtocol::CFractionalScaleProtocol(const wl_interface* iface, co } void CFractionalScaleProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CWpFractionalScaleManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CWpFractionalScaleManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -33,7 +33,7 @@ void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1* } const auto PADDON = - m_mAddons.emplace(surface, std::make_unique(makeShared(pMgr->client(), pMgr->version(), id), surface)).first->second.get(); + m_mAddons.emplace(surface, makeUnique(makeShared(pMgr->client(), pMgr->version(), id), surface)).first->second.get(); if UNLIKELY (!PADDON->good()) { m_mAddons.erase(surface); diff --git a/src/protocols/FractionalScale.hpp b/src/protocols/FractionalScale.hpp index 98cd7eaa..ba896c01 100644 --- a/src/protocols/FractionalScale.hpp +++ b/src/protocols/FractionalScale.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "fractional-scale-v1.hpp" diff --git a/src/protocols/FrogColorManagement.hpp b/src/protocols/FrogColorManagement.hpp index 6c00e38d..db467b1d 100644 --- a/src/protocols/FrogColorManagement.hpp +++ b/src/protocols/FrogColorManagement.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "protocols/core/Compositor.hpp" diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp index 299d7717..43ba9d41 100644 --- a/src/protocols/GammaControl.cpp +++ b/src/protocols/GammaControl.cpp @@ -160,7 +160,7 @@ CGammaControlProtocol::CGammaControlProtocol(const wl_interface* iface, const in } void CGammaControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwlrGammaControlManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwlrGammaControlManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -177,7 +177,7 @@ void CGammaControlProtocol::destroyGammaControl(CGammaControl* gamma) { void CGammaControlProtocol::onGetGammaControl(CZwlrGammaControlManagerV1* pMgr, uint32_t id, wl_resource* output) { const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vGammaControllers.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), output)).get(); + const auto RESOURCE = m_vGammaControllers.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id), output)).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/GammaControl.hpp b/src/protocols/GammaControl.hpp index 5cfcd60a..9e21ef08 100644 --- a/src/protocols/GammaControl.hpp +++ b/src/protocols/GammaControl.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/HyprlandSurface.cpp b/src/protocols/HyprlandSurface.cpp index bcf4905c..ca133b78 100644 --- a/src/protocols/HyprlandSurface.cpp +++ b/src/protocols/HyprlandSurface.cpp @@ -70,7 +70,7 @@ CHyprlandSurfaceProtocol::CHyprlandSurfaceProtocol(const wl_interface* iface, co } void CHyprlandSurfaceProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - auto manager = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + auto manager = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); manager->setOnDestroy([this](CHyprlandSurfaceManagerV1* manager) { destroyManager(manager); }); manager->setDestroy([this](CHyprlandSurfaceManagerV1* manager) { destroyManager(manager); }); @@ -100,8 +100,8 @@ void CHyprlandSurfaceProtocol::getSurface(CHyprlandSurfaceManagerV1* manager, ui hyprlandSurface = iter->second.get(); } } else { - hyprlandSurface = m_mSurfaces.emplace(surface, std::make_unique(makeShared(manager->client(), manager->version(), id), surface)) - .first->second.get(); + hyprlandSurface = + m_mSurfaces.emplace(surface, makeUnique(makeShared(manager->client(), manager->version(), id), surface)).first->second.get(); } if UNLIKELY (!hyprlandSurface->good()) { diff --git a/src/protocols/HyprlandSurface.hpp b/src/protocols/HyprlandSurface.hpp index f67de115..a5812b89 100644 --- a/src/protocols/HyprlandSurface.hpp +++ b/src/protocols/HyprlandSurface.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/IdleInhibit.cpp b/src/protocols/IdleInhibit.cpp index 89eb3108..a015cdd0 100644 --- a/src/protocols/IdleInhibit.cpp +++ b/src/protocols/IdleInhibit.cpp @@ -31,7 +31,7 @@ void CIdleInhibitProtocol::onManagerResourceDestroy(wl_resource* res) { } void CIdleInhibitProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpIdleInhibitManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpIdleInhibitManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/IdleInhibit.hpp b/src/protocols/IdleInhibit.hpp index 3cbfd78d..2e024a7a 100644 --- a/src/protocols/IdleInhibit.hpp +++ b/src/protocols/IdleInhibit.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "idle-inhibit-unstable-v1.hpp" diff --git a/src/protocols/IdleNotify.cpp b/src/protocols/IdleNotify.cpp index 85a9f8e2..bc5aabb1 100644 --- a/src/protocols/IdleNotify.cpp +++ b/src/protocols/IdleNotify.cpp @@ -59,7 +59,7 @@ CIdleNotifyProtocol::CIdleNotifyProtocol(const wl_interface* iface, const int& v } void CIdleNotifyProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CExtIdleNotifierV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CExtIdleNotifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/IdleNotify.hpp b/src/protocols/IdleNotify.hpp index d0b40775..e3dcdc98 100644 --- a/src/protocols/IdleNotify.hpp +++ b/src/protocols/IdleNotify.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp index cf777f45..796cec06 100644 --- a/src/protocols/InputMethodV2.cpp +++ b/src/protocols/InputMethodV2.cpp @@ -334,7 +334,7 @@ CInputMethodV2Protocol::CInputMethodV2Protocol(const wl_interface* iface, const } void CInputMethodV2Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpInputMethodManagerV2* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpInputMethodManagerV2* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/InputMethodV2.hpp b/src/protocols/InputMethodV2.hpp index 0b2c7a49..0c249c6c 100644 --- a/src/protocols/InputMethodV2.hpp +++ b/src/protocols/InputMethodV2.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp index 82d00a30..1533a7c0 100644 --- a/src/protocols/LayerShell.cpp +++ b/src/protocols/LayerShell.cpp @@ -201,7 +201,7 @@ CLayerShellProtocol::CLayerShellProtocol(const wl_interface* iface, const int& v } void CLayerShellProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwlrLayerShellV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwlrLayerShellV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/LayerShell.hpp b/src/protocols/LayerShell.hpp index 5e74c91b..b634c63c 100644 --- a/src/protocols/LayerShell.hpp +++ b/src/protocols/LayerShell.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index 85f7b1c6..82d31c84 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -469,7 +469,7 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const }); } - formatTable = std::make_unique(eglTranche, tches); + formatTable = makeUnique(eglTranche, tches); drmDevice* device = nullptr; if (drmGetDeviceFromDevId(mainDevice, 0, &device) != 0) { @@ -501,7 +501,7 @@ void CLinuxDMABufV1Protocol::resetFormatTable() { LOGM(LOG, "Resetting format table"); // this might be a big copy - auto newFormatTable = std::make_unique(formatTable->rendererTranche, formatTable->monitorTranches); + auto newFormatTable = makeUnique(formatTable->rendererTranche, formatTable->monitorTranches); for (auto const& feedback : m_vFeedbacks) { feedback->resource->sendFormatTable(newFormatTable->tableFD, newFormatTable->tableSize); diff --git a/src/protocols/LinuxDMABUF.hpp b/src/protocols/LinuxDMABUF.hpp index e4941a6d..8c574dbc 100644 --- a/src/protocols/LinuxDMABUF.hpp +++ b/src/protocols/LinuxDMABUF.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/LockNotify.cpp b/src/protocols/LockNotify.cpp index adcd0b2d..1855f891 100644 --- a/src/protocols/LockNotify.cpp +++ b/src/protocols/LockNotify.cpp @@ -31,7 +31,7 @@ CLockNotifyProtocol::CLockNotifyProtocol(const wl_interface* iface, const int& v } void CLockNotifyProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_managers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_managers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CHyprlandLockNotifierV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CHyprlandLockNotifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/MesaDRM.hpp b/src/protocols/MesaDRM.hpp index 46811d68..bfa604cf 100644 --- a/src/protocols/MesaDRM.hpp +++ b/src/protocols/MesaDRM.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/OutputManagement.hpp b/src/protocols/OutputManagement.hpp index b9e7ce98..1594df5d 100644 --- a/src/protocols/OutputManagement.hpp +++ b/src/protocols/OutputManagement.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/src/protocols/OutputPower.cpp b/src/protocols/OutputPower.cpp index f97babc2..24106817 100644 --- a/src/protocols/OutputPower.cpp +++ b/src/protocols/OutputPower.cpp @@ -43,7 +43,7 @@ COutputPowerProtocol::COutputPowerProtocol(const wl_interface* iface, const int& } void COutputPowerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwlrOutputPowerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwlrOutputPowerManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -68,7 +68,7 @@ void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uin } const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vOutputPowers.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), OUTPUT->monitor.lock())).get(); + const auto RESOURCE = m_vOutputPowers.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id), OUTPUT->monitor.lock())).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/OutputPower.hpp b/src/protocols/OutputPower.hpp index 91f2c5f3..c61eaa3d 100644 --- a/src/protocols/OutputPower.hpp +++ b/src/protocols/OutputPower.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/PointerConstraints.cpp b/src/protocols/PointerConstraints.cpp index c0531799..30ab0a55 100644 --- a/src/protocols/PointerConstraints.cpp +++ b/src/protocols/PointerConstraints.cpp @@ -199,7 +199,7 @@ CPointerConstraintsProtocol::CPointerConstraintsProtocol(const wl_interface* ifa } void CPointerConstraintsProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpPointerConstraintsV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpPointerConstraintsV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/PointerConstraints.hpp b/src/protocols/PointerConstraints.hpp index 964bf672..1cd2fca9 100644 --- a/src/protocols/PointerConstraints.hpp +++ b/src/protocols/PointerConstraints.hpp @@ -2,7 +2,6 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/PointerGestures.cpp b/src/protocols/PointerGestures.cpp index 4df51b47..8de73ffa 100644 --- a/src/protocols/PointerGestures.cpp +++ b/src/protocols/PointerGestures.cpp @@ -44,7 +44,7 @@ CPointerGesturesProtocol::CPointerGesturesProtocol(const wl_interface* iface, co } void CPointerGesturesProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpPointerGesturesV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setRelease([this](CZwpPointerGesturesV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -71,7 +71,7 @@ void CPointerGesturesProtocol::onGestureDestroy(CPointerGestureHold* gesture) { void CPointerGesturesProtocol::onGetPinchGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer) { const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vPinches.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); + const auto RESOURCE = m_vPinches.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id))).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); @@ -82,7 +82,7 @@ void CPointerGesturesProtocol::onGetPinchGesture(CZwpPointerGesturesV1* pMgr, ui void CPointerGesturesProtocol::onGetSwipeGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer) { const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vSwipes.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); + const auto RESOURCE = m_vSwipes.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id))).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); @@ -93,7 +93,7 @@ void CPointerGesturesProtocol::onGetSwipeGesture(CZwpPointerGesturesV1* pMgr, ui void CPointerGesturesProtocol::onGetHoldGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer) { const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vHolds.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); + const auto RESOURCE = m_vHolds.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id))).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/PointerGestures.hpp b/src/protocols/PointerGestures.hpp index f907a49f..5211ecf3 100644 --- a/src/protocols/PointerGestures.hpp +++ b/src/protocols/PointerGestures.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "WaylandProtocol.hpp" #include "pointer-gestures-unstable-v1.hpp" diff --git a/src/protocols/PresentationTime.cpp b/src/protocols/PresentationTime.cpp index 1654041c..a9139ac0 100644 --- a/src/protocols/PresentationTime.cpp +++ b/src/protocols/PresentationTime.cpp @@ -79,7 +79,7 @@ CPresentationProtocol::CPresentationProtocol(const wl_interface* iface, const in } void CPresentationProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CWpPresentation* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CWpPresentation* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/PresentationTime.hpp b/src/protocols/PresentationTime.hpp index d9b45448..03b59b89 100644 --- a/src/protocols/PresentationTime.hpp +++ b/src/protocols/PresentationTime.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/PrimarySelection.hpp b/src/protocols/PrimarySelection.hpp index c33a00e8..aeebe03c 100644 --- a/src/protocols/PrimarySelection.hpp +++ b/src/protocols/PrimarySelection.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/RelativePointer.cpp b/src/protocols/RelativePointer.cpp index 842af894..f002fac1 100644 --- a/src/protocols/RelativePointer.cpp +++ b/src/protocols/RelativePointer.cpp @@ -31,7 +31,7 @@ CRelativePointerProtocol::CRelativePointerProtocol(const wl_interface* iface, co } void CRelativePointerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpRelativePointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpRelativePointerManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -48,7 +48,7 @@ void CRelativePointerProtocol::destroyRelativePointer(CRelativePointer* pointer) void CRelativePointerProtocol::onGetRelativePointer(CZwpRelativePointerManagerV1* pMgr, uint32_t id, wl_resource* pointer) { const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vRelativePointers.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); + const auto RESOURCE = m_vRelativePointers.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id))).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/RelativePointer.hpp b/src/protocols/RelativePointer.hpp index 453ce157..ce060ed3 100644 --- a/src/protocols/RelativePointer.hpp +++ b/src/protocols/RelativePointer.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/SecurityContext.hpp b/src/protocols/SecurityContext.hpp index d675d660..2bec08d4 100644 --- a/src/protocols/SecurityContext.hpp +++ b/src/protocols/SecurityContext.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/ServerDecorationKDE.cpp b/src/protocols/ServerDecorationKDE.cpp index 3e33db52..0726c8a5 100644 --- a/src/protocols/ServerDecorationKDE.cpp +++ b/src/protocols/ServerDecorationKDE.cpp @@ -21,7 +21,7 @@ CServerDecorationKDEProtocol::CServerDecorationKDEProtocol(const wl_interface* i } void CServerDecorationKDEProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](COrgKdeKwinServerDecorationManager* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setCreate([this](COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* pointer) { this->createDecoration(pMgr, id, pointer); }); @@ -41,8 +41,7 @@ void CServerDecorationKDEProtocol::destroyResource(CServerDecorationKDE* hayperl void CServerDecorationKDEProtocol::createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf) { const auto CLIENT = pMgr->client(); const auto RESOURCE = - m_vDecos.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))) - .get(); + m_vDecos.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/ServerDecorationKDE.hpp b/src/protocols/ServerDecorationKDE.hpp index ab082b17..0d0fa898 100644 --- a/src/protocols/ServerDecorationKDE.hpp +++ b/src/protocols/ServerDecorationKDE.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/SessionLock.cpp b/src/protocols/SessionLock.cpp index 8e215ffa..d87775e9 100644 --- a/src/protocols/SessionLock.cpp +++ b/src/protocols/SessionLock.cpp @@ -148,7 +148,7 @@ CSessionLockProtocol::CSessionLockProtocol(const wl_interface* iface, const int& } void CSessionLockProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CExtSessionLockManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CExtSessionLockManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/SessionLock.hpp b/src/protocols/SessionLock.hpp index a1df6fcf..670e5e1d 100644 --- a/src/protocols/SessionLock.hpp +++ b/src/protocols/SessionLock.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/ShortcutsInhibit.cpp b/src/protocols/ShortcutsInhibit.cpp index a0d29f92..5786de26 100644 --- a/src/protocols/ShortcutsInhibit.cpp +++ b/src/protocols/ShortcutsInhibit.cpp @@ -28,7 +28,7 @@ CKeyboardShortcutsInhibitProtocol::CKeyboardShortcutsInhibitProtocol(const wl_in } void CKeyboardShortcutsInhibitProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpKeyboardShortcutsInhibitManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpKeyboardShortcutsInhibitManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -57,7 +57,7 @@ void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitMa } const auto RESOURCE = - m_vInhibitors.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id), surf)).get(); + m_vInhibitors.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id), surf)).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/ShortcutsInhibit.hpp b/src/protocols/ShortcutsInhibit.hpp index ba1c134c..c093ac6e 100644 --- a/src/protocols/ShortcutsInhibit.hpp +++ b/src/protocols/ShortcutsInhibit.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/SinglePixel.hpp b/src/protocols/SinglePixel.hpp index b20f582a..2a86d050 100644 --- a/src/protocols/SinglePixel.hpp +++ b/src/protocols/SinglePixel.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/Tablet.cpp b/src/protocols/Tablet.cpp index 62e8b2d2..de2ed71b 100644 --- a/src/protocols/Tablet.cpp +++ b/src/protocols/Tablet.cpp @@ -315,7 +315,7 @@ CTabletV2Protocol::CTabletV2Protocol(const wl_interface* iface, const int& ver, } void CTabletV2Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpTabletManagerV2* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpTabletManagerV2* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/Tablet.hpp b/src/protocols/Tablet.hpp index 1ebcb1e5..264c7633 100644 --- a/src/protocols/Tablet.hpp +++ b/src/protocols/Tablet.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/TearingControl.cpp b/src/protocols/TearingControl.cpp index 14c80052..16e85352 100644 --- a/src/protocols/TearingControl.cpp +++ b/src/protocols/TearingControl.cpp @@ -11,7 +11,7 @@ CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, cons } void CTearingControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CWpTearingControlManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CWpTearingControlManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -25,7 +25,7 @@ void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) { } void CTearingControlProtocol::onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, SP surf) { - const auto CONTROLLER = m_vTearingControllers.emplace_back(std::make_unique(makeShared(client, pMgr->version(), id), surf)).get(); + const auto CONTROLLER = m_vTearingControllers.emplace_back(makeUnique(makeShared(client, pMgr->version(), id), surf)).get(); if UNLIKELY (!CONTROLLER->good()) { pMgr->noMemory(); diff --git a/src/protocols/TearingControl.hpp b/src/protocols/TearingControl.hpp index d81a27cd..7763214e 100644 --- a/src/protocols/TearingControl.hpp +++ b/src/protocols/TearingControl.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include "WaylandProtocol.hpp" #include "tearing-control-v1.hpp" diff --git a/src/protocols/TextInputV3.cpp b/src/protocols/TextInputV3.cpp index 71ef6dac..06aea5ae 100644 --- a/src/protocols/TextInputV3.cpp +++ b/src/protocols/TextInputV3.cpp @@ -110,7 +110,7 @@ CTextInputV3Protocol::CTextInputV3Protocol(const wl_interface* iface, const int& } void CTextInputV3Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpTextInputManagerV3* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwpTextInputManagerV3* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); diff --git a/src/protocols/TextInputV3.hpp b/src/protocols/TextInputV3.hpp index ba8b75e6..6cece521 100644 --- a/src/protocols/TextInputV3.hpp +++ b/src/protocols/TextInputV3.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/src/protocols/Viewporter.hpp b/src/protocols/Viewporter.hpp index 3c2a4eef..6824f2ae 100644 --- a/src/protocols/Viewporter.hpp +++ b/src/protocols/Viewporter.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp index 7da1fe01..4fec57c0 100644 --- a/src/protocols/VirtualKeyboard.cpp +++ b/src/protocols/VirtualKeyboard.cpp @@ -124,7 +124,7 @@ CVirtualKeyboardProtocol::CVirtualKeyboardProtocol(const wl_interface* iface, co } void CVirtualKeyboardProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwpVirtualKeyboardManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setCreateVirtualKeyboard([this](CZwpVirtualKeyboardManagerV1* pMgr, wl_resource* seat, uint32_t id) { this->onCreateKeeb(pMgr, seat, id); }); diff --git a/src/protocols/VirtualKeyboard.hpp b/src/protocols/VirtualKeyboard.hpp index 93b63bb5..8157b276 100644 --- a/src/protocols/VirtualKeyboard.hpp +++ b/src/protocols/VirtualKeyboard.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp index 3e0b00eb..33641a7b 100644 --- a/src/protocols/VirtualPointer.cpp +++ b/src/protocols/VirtualPointer.cpp @@ -107,7 +107,7 @@ CVirtualPointerProtocol::CVirtualPointerProtocol(const wl_interface* iface, cons } void CVirtualPointerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZwlrVirtualPointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZwlrVirtualPointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); diff --git a/src/protocols/VirtualPointer.hpp b/src/protocols/VirtualPointer.hpp index 68fe124e..ac8bcae2 100644 --- a/src/protocols/VirtualPointer.hpp +++ b/src/protocols/VirtualPointer.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/src/protocols/WaylandProtocol.hpp b/src/protocols/WaylandProtocol.hpp index e3507708..918ac70f 100644 --- a/src/protocols/WaylandProtocol.hpp +++ b/src/protocols/WaylandProtocol.hpp @@ -1,6 +1,7 @@ #pragma once #include "../defines.hpp" +#include "../helpers/memory/Memory.hpp" #include diff --git a/src/protocols/XDGActivation.cpp b/src/protocols/XDGActivation.cpp index c49dc3dc..4062847b 100644 --- a/src/protocols/XDGActivation.cpp +++ b/src/protocols/XDGActivation.cpp @@ -62,7 +62,7 @@ CXDGActivationProtocol::CXDGActivationProtocol(const wl_interface* iface, const } void CXDGActivationProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CXdgActivationV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CXdgActivationV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -100,7 +100,7 @@ void CXDGActivationProtocol::destroyToken(CXDGActivationToken* token) { void CXDGActivationProtocol::onGetToken(CXdgActivationV1* pMgr, uint32_t id) { const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vTokens.emplace_back(std::make_unique(makeShared(CLIENT, pMgr->version(), id))).get(); + const auto RESOURCE = m_vTokens.emplace_back(makeUnique(makeShared(CLIENT, pMgr->version(), id))).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/XDGActivation.hpp b/src/protocols/XDGActivation.hpp index 80af988d..1db16b3c 100644 --- a/src/protocols/XDGActivation.hpp +++ b/src/protocols/XDGActivation.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/XDGDecoration.cpp b/src/protocols/XDGDecoration.cpp index 8ec0d5b0..f9dbf411 100644 --- a/src/protocols/XDGDecoration.cpp +++ b/src/protocols/XDGDecoration.cpp @@ -41,7 +41,7 @@ CXDGDecorationProtocol::CXDGDecorationProtocol(const wl_interface* iface, const } void CXDGDecorationProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagers.emplace_back(makeUnique(client, ver, id)).get(); RESOURCE->setOnDestroy([this](CZxdgDecorationManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CZxdgDecorationManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); @@ -64,7 +64,7 @@ void CXDGDecorationProtocol::onGetDecoration(CZxdgDecorationManagerV1* pMgr, uin const auto CLIENT = pMgr->client(); const auto RESOURCE = - m_mDecorations.emplace(xdgToplevel, std::make_unique(makeShared(CLIENT, pMgr->version(), id), xdgToplevel)).first->second.get(); + m_mDecorations.emplace(xdgToplevel, makeUnique(makeShared(CLIENT, pMgr->version(), id), xdgToplevel)).first->second.get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); diff --git a/src/protocols/XDGDecoration.hpp b/src/protocols/XDGDecoration.hpp index cbd74be4..33a9b663 100644 --- a/src/protocols/XDGDecoration.hpp +++ b/src/protocols/XDGDecoration.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/XDGDialog.hpp b/src/protocols/XDGDialog.hpp index a635bfac..1b29e692 100644 --- a/src/protocols/XDGDialog.hpp +++ b/src/protocols/XDGDialog.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp index 5be16d07..544deed0 100644 --- a/src/protocols/XDGOutput.cpp +++ b/src/protocols/XDGOutput.cpp @@ -21,7 +21,7 @@ void CXDGOutputProtocol::onOutputResourceDestroy(wl_resource* res) { } void CXDGOutputProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagerResources.emplace_back(std::make_unique(client, ver, id)).get(); + const auto RESOURCE = m_vManagerResources.emplace_back(makeUnique(client, ver, id)).get(); if UNLIKELY (!RESOURCE->resource()) { LOGM(LOG, "Couldn't bind XDGOutputMgr"); @@ -44,7 +44,7 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(CZxdgOutputManagerV1* mgr, uint32 const auto PMONITOR = OUTPUT->monitor.lock(); const auto CLIENT = mgr->client(); - CXDGOutput* pXDGOutput = m_vXDGOutputs.emplace_back(std::make_unique(makeShared(CLIENT, mgr->version(), id), PMONITOR)).get(); + CXDGOutput* pXDGOutput = m_vXDGOutputs.emplace_back(makeUnique(makeShared(CLIENT, mgr->version(), id), PMONITOR)).get(); #ifndef NO_XWAYLAND if (g_pXWayland && g_pXWayland->pServer && g_pXWayland->pServer->xwaylandClient == CLIENT) pXDGOutput->isXWayland = true; diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp index 6eef99bb..4c2b8100 100644 --- a/src/protocols/XDGShell.hpp +++ b/src/protocols/XDGShell.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/src/protocols/XWaylandShell.hpp b/src/protocols/XWaylandShell.hpp index c8c0c04a..f6f91c49 100644 --- a/src/protocols/XWaylandShell.hpp +++ b/src/protocols/XWaylandShell.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "WaylandProtocol.hpp" diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index b347eb64..20614813 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -8,7 +8,6 @@ - wl_callback */ -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/protocols/core/DataDevice.hpp b/src/protocols/core/DataDevice.hpp index ae22e474..5101862e 100644 --- a/src/protocols/core/DataDevice.hpp +++ b/src/protocols/core/DataDevice.hpp @@ -8,7 +8,6 @@ - wl_data_device_manager */ -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/protocols/core/Output.hpp b/src/protocols/core/Output.hpp index a4c81d72..8ade5178 100644 --- a/src/protocols/core/Output.hpp +++ b/src/protocols/core/Output.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index b5670237..a4889379 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -8,7 +8,6 @@ - wl_touch */ -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index 9f4e18f9..23a465fb 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -7,7 +7,6 @@ - wl_buffer with shm */ -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/protocols/core/Subcompositor.hpp b/src/protocols/core/Subcompositor.hpp index 2e6b10bb..dc713044 100644 --- a/src/protocols/core/Subcompositor.hpp +++ b/src/protocols/core/Subcompositor.hpp @@ -7,7 +7,6 @@ - wl_subcompositor */ -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/protocols/types/WLBuffer.hpp b/src/protocols/types/WLBuffer.hpp index 787abe1f..3894affc 100644 --- a/src/protocols/types/WLBuffer.hpp +++ b/src/protocols/types/WLBuffer.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include "../WaylandProtocol.hpp" diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 8098485e..3dc3b43a 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -328,4 +328,4 @@ class CHyprOpenGLImpl { friend class CSurfacePassElement; }; -inline std::unique_ptr g_pHyprOpenGL; +inline UP g_pHyprOpenGL; diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 7aef96e6..1ef1eecc 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -155,4 +155,4 @@ class CHyprRenderer { friend class CMonitor; }; -inline std::unique_ptr g_pHyprRenderer; +inline UP g_pHyprRenderer; diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 4a411b6c..36846fd4 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -176,11 +176,11 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[WINDOWINDEX]->m_szTitle); if (!pTitleTex) - pTitleTex = m_sTitleTexs.titleTexs - .emplace_back(std::make_unique(m_dwGroupMembers[WINDOWINDEX].lock(), - Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2L * BAR_TEXT_PAD) * pMonitor->scale}, - pMonitor->scale)) - .get(); + pTitleTex = + m_sTitleTexs.titleTexs + .emplace_back(makeUnique(m_dwGroupMembers[WINDOWINDEX].lock(), + Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2L * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale)) + .get(); rect.y += std::ceil((rect.height - pTitleTex->texSize.y) / 2.0); rect.height = pTitleTex->texSize.y; rect.width = pTitleTex->texSize.x; @@ -421,7 +421,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND g_pLayoutManager->getCurrentLayout()->recalculateWindow(pDraggedWindow); if (!pDraggedWindow->getDecorationByType(DECORATION_GROUPBAR)) - pDraggedWindow->addWindowDeco(std::make_unique(pDraggedWindow)); + pDraggedWindow->addWindowDeco(makeUnique(pDraggedWindow)); return true; } diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index 653cd11c..7277955d 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -5,7 +5,7 @@ #include #include "../Texture.hpp" #include -#include +#include "../../helpers/memory/Memory.hpp" class CTitleTex { public: @@ -70,6 +70,6 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration { struct STitleTexs { // STitleTexs* overriden = nullptr; // TODO: make shit shared in-group to decrease VRAM usage. - std::vector> titleTexs; + std::vector> titleTexs; } m_sTitleTexs; }; diff --git a/src/render/decorations/DecorationPositioner.cpp b/src/render/decorations/DecorationPositioner.cpp index 2ba3c4a7..9dbb12a6 100644 --- a/src/render/decorations/DecorationPositioner.cpp +++ b/src/render/decorations/DecorationPositioner.cpp @@ -79,7 +79,7 @@ CDecorationPositioner::SWindowPositioningData* CDecorationPositioner::getDataFor if (it != m_vWindowPositioningDatas.end()) return it->get(); - const auto DATA = m_vWindowPositioningDatas.emplace_back(std::make_unique(pWindow, pDecoration)).get(); + const auto DATA = m_vWindowPositioningDatas.emplace_back(makeUnique(pWindow, pDecoration)).get(); DATA->positioningInfo = pDecoration->getPositioningInfo(); diff --git a/src/render/decorations/DecorationPositioner.hpp b/src/render/decorations/DecorationPositioner.hpp index c2d69881..787c6d1f 100644 --- a/src/render/decorations/DecorationPositioner.hpp +++ b/src/render/decorations/DecorationPositioner.hpp @@ -87,13 +87,13 @@ class CDecorationPositioner { bool needsRecalc = false; }; - std::map m_mWindowDatas; - std::vector> m_vWindowPositioningDatas; + std::map m_mWindowDatas; + std::vector> m_vWindowPositioningDatas; - SWindowPositioningData* getDataFor(IHyprWindowDecoration* pDecoration, PHLWINDOW pWindow); - void onWindowUnmap(PHLWINDOW pWindow); - void onWindowMap(PHLWINDOW pWindow); - void sanitizeDatas(); + SWindowPositioningData* getDataFor(IHyprWindowDecoration* pDecoration, PHLWINDOW pWindow); + void onWindowUnmap(PHLWINDOW pWindow); + void onWindowMap(PHLWINDOW pWindow); + void sanitizeDatas(); }; -inline std::unique_ptr g_pDecorationPositioner; \ No newline at end of file +inline UP g_pDecorationPositioner; \ No newline at end of file diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index c67d5830..d5dce333 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -442,7 +442,7 @@ int CXWaylandServer::ready(int fd, uint32_t mask) { // start the wm if (!g_pXWayland->pWM) - g_pXWayland->pWM = std::make_unique(); + g_pXWayland->pWM = makeUnique(); g_pCursorManager->setXWaylandCursor(); diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp index 181955a8..4b0c5a29 100644 --- a/src/xwayland/XDataSource.cpp +++ b/src/xwayland/XDataSource.cpp @@ -71,7 +71,7 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) { Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd); - selection.transfer = std::make_unique(selection); + selection.transfer = makeUnique(selection); selection.transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection); const uint32_t MASK = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE; xcb_create_window(g_pXWayland->pWM->connection, XCB_COPY_FROM_PARENT, selection.transfer->incomingWindow, g_pXWayland->pWM->screen->root, 0, 0, 10, 10, 0, diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 71a7c44c..ef139b38 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -225,7 +225,7 @@ void CXWM::readProp(SP XSURF, uint32_t atom, xcb_get_property_ } } else if (atom == HYPRATOMS["WM_HINTS"]) { if (reply->value_len != 0) { - XSURF->hints = std::make_unique(); + XSURF->hints = makeUnique(); xcb_icccm_get_wm_hints_from_reply(XSURF->hints.get(), reply); if (!(XSURF->hints->flags & XCB_ICCCM_WM_HINT_INPUT)) @@ -254,7 +254,7 @@ void CXWM::readProp(SP XSURF, uint32_t atom, xcb_get_property_ } } else if (atom == HYPRATOMS["WM_NORMAL_HINTS"]) { if (reply->type == HYPRATOMS["WM_SIZE_HINTS"] && reply->value_len > 0) { - XSURF->sizeHints = std::make_unique(); + XSURF->sizeHints = makeUnique(); std::memset(XSURF->sizeHints.get(), 0, sizeof(xcb_size_hints_t)); xcb_icccm_get_wm_size_hints_from_reply(XSURF->sizeHints.get(), reply); @@ -735,7 +735,7 @@ int CXWM::onEvent(int fd, uint32_t mask) { g_pXWayland->pWM.reset(); g_pXWayland->pServer.reset(); // Attempt to create fresh instance - g_pEventLoopManager->doLater([]() { g_pXWayland = std::make_unique(true); }); + g_pEventLoopManager->doLater([]() { g_pXWayland = makeUnique(true); }); return 0; } @@ -1346,7 +1346,7 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) { mime = *MIMES.begin(); } - transfer = std::make_unique(*this); + transfer = makeUnique(*this); transfer->request = *e; int p[2]; diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index 02ade80d..dfaf33b9 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -57,7 +57,7 @@ struct SXSelection { CHyprSignalListener keyboardFocusChange; } listeners; - std::unique_ptr transfer; + UP transfer; }; class CXCBConnection { diff --git a/src/xwayland/XWayland.cpp b/src/xwayland/XWayland.cpp index 6b8a630b..9d2a0ea4 100644 --- a/src/xwayland/XWayland.cpp +++ b/src/xwayland/XWayland.cpp @@ -26,7 +26,7 @@ CXWayland::CXWayland(const bool wantsEnabled) { Debug::log(LOG, "Starting up the XWayland server"); - pServer = std::make_unique(); + pServer = makeUnique(); if (!pServer->create()) { Debug::log(ERR, "XWayland failed to start: it will not work."); diff --git a/src/xwayland/XWayland.hpp b/src/xwayland/XWayland.hpp index 8347a6a7..af8d957c 100644 --- a/src/xwayland/XWayland.hpp +++ b/src/xwayland/XWayland.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include "../helpers/signal/Signal.hpp" #include "../helpers/memory/Memory.hpp" #include "../macros.hpp" @@ -20,8 +19,8 @@ class CXWayland { CXWayland(const bool wantsEnabled); #ifndef NO_XWAYLAND - std::unique_ptr pServer; - std::unique_ptr pWM; + UP pServer; + UP pWM; #endif bool enabled(); @@ -35,7 +34,7 @@ class CXWayland { bool m_enabled = false; }; -inline std::unique_ptr g_pXWayland; +inline UP g_pXWayland; inline std::unordered_map HYPRATOMS = { #ifndef NO_XWAYLAND From 1a0a22ad038bbd51c4e1514868d6dcd505af0242 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 23 Jan 2025 21:27:11 +0000 Subject: [PATCH 0150/1444] configmgr: fix crash on very early plugin loads --- src/config/ConfigManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 08f0f33f..b0665db9 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -954,7 +954,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { const auto PENABLEXWAYLAND = std::any_cast(m_pConfig->getConfigValue("xwayland:enabled")); g_pCompositor->m_bWantsXwayland = PENABLEXWAYLAND; // enable/disable xwayland usage - if (!isFirstLaunch) { + if (!isFirstLaunch && + g_pXWayland /* XWayland has to be initialized by CCompositor::initManagers for this to make sense, and it doesn't have to be (e.g. very early plugin load) */) { bool prevEnabledXwayland = g_pXWayland->enabled(); if (g_pCompositor->m_bWantsXwayland != prevEnabledXwayland) g_pXWayland = makeUnique(g_pCompositor->m_bWantsXwayland); From 465cf66df14c28427ba30580253be6e3908bd28c Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Thu, 23 Jan 2025 13:57:33 -0800 Subject: [PATCH 0151/1444] protocols: add hyprland_surface_v1.set_visible_region implementation (#9120) --- src/desktop/WLSurface.hpp | 3 +- src/managers/ProtocolManager.cpp | 2 +- src/protocols/HyprlandSurface.cpp | 23 +++++++++++- src/protocols/HyprlandSurface.hpp | 5 ++- src/render/OpenGL.cpp | 17 +++++++-- src/render/OpenGL.hpp | 1 + src/render/pass/SurfacePassElement.cpp | 50 ++++++++++++++++++++++++++ src/render/pass/SurfacePassElement.hpp | 1 + subprojects/hyprland-protocols | 2 +- 9 files changed, 96 insertions(+), 8 deletions(-) diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp index 057a6f90..5f8da715 100644 --- a/src/desktop/WLSurface.hpp +++ b/src/desktop/WLSurface.hpp @@ -87,7 +87,8 @@ class CWLSurface { float m_fAlphaModifier = 1.F; // used by the hyprland-surface protocol - float m_fOverallOpacity = 1.F; + float m_fOverallOpacity = 1.F; + CRegion m_visibleRegion; struct { CSignal destroy; diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index f73a6d3c..d3270fe2 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -168,7 +168,7 @@ CProtocolManager::CProtocolManager() { PROTO::singlePixel = makeUnique(&wp_single_pixel_buffer_manager_v1_interface, 1, "SinglePixel"); PROTO::securityContext = makeUnique(&wp_security_context_manager_v1_interface, 1, "SecurityContext"); PROTO::ctm = makeUnique(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl"); - PROTO::hyprlandSurface = makeUnique(&hyprland_surface_manager_v1_interface, 1, "HyprlandSurface"); + PROTO::hyprlandSurface = makeUnique(&hyprland_surface_manager_v1_interface, 2, "HyprlandSurface"); if (*PENABLEXXCM) { PROTO::colorManagement = makeUnique(&xx_color_manager_v4_interface, 1, "ColorManagement"); diff --git a/src/protocols/HyprlandSurface.cpp b/src/protocols/HyprlandSurface.cpp index ca133b78..e3716f10 100644 --- a/src/protocols/HyprlandSurface.cpp +++ b/src/protocols/HyprlandSurface.cpp @@ -3,6 +3,8 @@ #include "../render/Renderer.hpp" #include "core/Compositor.hpp" #include "hyprland-surface-v1.hpp" +#include +#include CHyprlandSurface::CHyprlandSurface(SP resource, SP surface) : m_pSurface(surface) { setResource(std::move(resource)); @@ -36,11 +38,25 @@ void CHyprlandSurface::setResource(SP resource) { m_fOpacity = fOpacity; }); + m_pResource->setSetVisibleRegion([this](CHyprlandSurfaceV1* resource, wl_resource* region) { + if (!region) { + if (!m_visibleRegion.empty()) + m_bVisibleRegionChanged = true; + + m_visibleRegion.clear(); + return; + } + + m_bVisibleRegionChanged = true; + m_visibleRegion = CWLRegionResource::fromResource(region)->region; + }); + listeners.surfaceCommitted = m_pSurface->events.commit.registerListener([this](std::any data) { auto surface = CWLSurface::fromResource(m_pSurface.lock()); - if (surface && surface->m_fOverallOpacity != m_fOpacity) { + if (surface && (surface->m_fOverallOpacity != m_fOpacity || m_bVisibleRegionChanged)) { surface->m_fOverallOpacity = m_fOpacity; + surface->m_visibleRegion = m_visibleRegion; auto box = surface->getSurfaceBoxGlobal(); if (box.has_value()) @@ -61,6 +77,11 @@ void CHyprlandSurface::destroy() { m_pResource.reset(); m_fOpacity = 1.F; + if (!m_visibleRegion.empty()) + m_bVisibleRegionChanged = true; + + m_visibleRegion.clear(); + if (!m_pSurface) PROTO::hyprlandSurface->destroySurface(this); } diff --git a/src/protocols/HyprlandSurface.hpp b/src/protocols/HyprlandSurface.hpp index a5812b89..5c1181c4 100644 --- a/src/protocols/HyprlandSurface.hpp +++ b/src/protocols/HyprlandSurface.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include "WaylandProtocol.hpp" @@ -19,7 +20,9 @@ class CHyprlandSurface { private: SP m_pResource; WP m_pSurface; - float m_fOpacity = 1.0; + float m_fOpacity = 1.0; + bool m_bVisibleRegionChanged = false; + CRegion m_visibleRegion; void destroy(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index ceb94c81..8ae667d2 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -1556,9 +1556,15 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB glEnableVertexAttribArray(shader->posAttrib); glEnableVertexAttribArray(shader->texAttrib); - if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { - CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height}; - damageClip.intersect(damage); + if (!m_RenderData.clipBox.empty() || !m_RenderData.clipRegion.empty()) { + CRegion damageClip = m_RenderData.clipBox; + + if (!m_RenderData.clipRegion.empty()) { + if (m_RenderData.clipBox.empty()) + damageClip = m_RenderData.clipRegion; + else + damageClip.intersect(m_RenderData.clipRegion); + } if (!damageClip.empty()) { for (auto const& RECT : damageClip.getRects()) { @@ -2079,6 +2085,11 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float CRegion texDamage{m_RenderData.damage}; texDamage.intersect(pBox->x, pBox->y, pBox->width, pBox->height); + // While renderTextureInternalWithDamage will clip the blur as well, + // clipping texDamage here allows blur generation to be optimized. + if (!m_RenderData.clipRegion.empty()) + texDamage.intersect(m_RenderData.clipRegion); + if (texDamage.empty()) return; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 3dc3b43a..fd84d478 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -133,6 +133,7 @@ struct SCurrentRenderData { Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); CBox clipBox = {}; // scaled coordinates + CRegion clipRegion; uint32_t discardMode = DISCARD_OPAQUE; float discardOpacity = 0.f; diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index d720081f..b79407c8 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -7,6 +7,8 @@ #include "../../managers/input/InputManager.hpp" #include "../Renderer.hpp" +#include +#include #include using namespace Hyprutils::Utils; @@ -28,6 +30,7 @@ void CSurfacePassElement::draw(const CRegion& damage) { g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; g_pHyprOpenGL->m_RenderData.clipBox = {}; + g_pHyprOpenGL->m_RenderData.clipRegion = {}; g_pHyprOpenGL->m_RenderData.discardMode = 0; g_pHyprOpenGL->m_RenderData.discardOpacity = 0; g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false; @@ -84,6 +87,11 @@ void CSurfacePassElement::draw(const CRegion& damage) { Debug::log(TRACE, "FIXME: rendering surface with color management enabled, should apply necessary transformations"); g_pHyprRenderer->calculateUVForSurface(data.pWindow, data.surface, data.pMonitor->self.lock(), data.mainSurface, windowBox.size(), PROJSIZEUNSCALED, MISALIGNEDFSV1); + auto cancelRender = false; + g_pHyprOpenGL->m_RenderData.clipRegion = visibleRegion(cancelRender); + if (cancelRender) + return; + // check for fractional scale surfaces misaligning the buffer size // in those cases it's better to just force nearest neighbor // as long as the window is not animated. During those it'd look weird. @@ -229,6 +237,48 @@ CRegion CSurfacePassElement::opaqueRegion() { return data.texture && data.texture->m_bOpaque ? boundingBox()->expand(-data.rounding) : CRegion{}; } +CRegion CSurfacePassElement::visibleRegion(bool& cancel) { + auto PSURFACE = CWLSurface::fromResource(data.surface); + if (!PSURFACE) + return {}; + + const auto& bufferSize = data.surface->current.bufferSize; + + auto visibleRegion = PSURFACE->m_visibleRegion.copy(); + if (visibleRegion.empty()) + return {}; + + visibleRegion.intersect(CBox(Vector2D(), bufferSize)); + + if (visibleRegion.empty()) { + cancel = true; + return visibleRegion; + } + + // deal with any rounding errors that might come from scaling + visibleRegion.expand(1); + + auto uvTL = g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft; + auto uvBR = g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight; + + if (uvTL == Vector2D(-1, -1)) + uvTL = Vector2D(0, 0); + + if (uvBR == Vector2D(-1, -1)) + uvBR = Vector2D(1, 1); + + visibleRegion.translate(-uvTL * bufferSize); + + auto texBox = getTexBox(); + texBox.scale(data.pMonitor->scale); + texBox.round(); + + visibleRegion.scale((Vector2D(1, 1) / (uvBR - uvTL)) * (texBox.size() / bufferSize)); + visibleRegion.translate((data.pos + data.localPos) * data.pMonitor->scale - data.pMonitor->vecPosition); + + return visibleRegion; +} + void CSurfacePassElement::discard() { if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) { Debug::log(TRACE, "discard for invisible surface"); diff --git a/src/render/pass/SurfacePassElement.hpp b/src/render/pass/SurfacePassElement.hpp index 12387367..1b6ddb0b 100644 --- a/src/render/pass/SurfacePassElement.hpp +++ b/src/render/pass/SurfacePassElement.hpp @@ -57,6 +57,7 @@ class CSurfacePassElement : public IPassElement { virtual std::optional boundingBox(); virtual CRegion opaqueRegion(); virtual void discard(); + CRegion visibleRegion(bool& cancel); virtual const char* passName() { return "CSurfacePassElement"; diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index 455c0558..4c75dd5c 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit 455c055883d9639d4fcbfcedb4c6d12ce313791e +Subproject commit 4c75dd5c015c8a0e5a34c6d02a018a650f57feb5 From a8c2d5a616b2ac9c0cf66a0bc999ae57338b60d9 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 23 Jan 2025 22:15:09 +0000 Subject: [PATCH 0152/1444] layout: damage window properly on float mode changes fixes #8849 --- src/layout/IHyprLayout.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 576d80eb..9fc84b22 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -717,6 +717,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { pWindow->m_bPinned = false; + g_pHyprRenderer->damageWindow(pWindow); + const auto TILED = isWindowTiled(pWindow); // event @@ -788,6 +790,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); pWindow->updateToplevel(); + + g_pHyprRenderer->damageWindow(pWindow); } void IHyprLayout::moveActiveWindow(const Vector2D& delta, PHLWINDOW pWindow) { From dadb2e0949e61d43ace69c5ae65358c6c38e32b4 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 23 Jan 2025 22:41:46 +0000 Subject: [PATCH 0153/1444] opengl: use uv to avoid rendering the entire blurbox additionally can use smoothing for rounding fixes #9086 --- src/render/OpenGL.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 8ae667d2..0fe9565f 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -1547,11 +1547,10 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); - if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) { + if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts); - } else { + else glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); - } glEnableVertexAttribArray(shader->posAttrib); glEnableVertexAttribArray(shader->texAttrib); @@ -2156,15 +2155,25 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float // stencil done. Render everything. CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; // render our great blurred FB + // calculate the uv for it + const auto LASTTL = m_RenderData.primarySurfaceUVTopLeft; + const auto LASTBR = m_RenderData.primarySurfaceUVBottomRight; + + m_RenderData.primarySurfaceUVTopLeft = pBox->pos() / MONITORBOX.size(); + m_RenderData.primarySurfaceUVBottomRight = (pBox->pos() + pBox->size()) / MONITORBOX.size(); + static auto PBLURIGNOREOPACITY = CConfigValue("decoration:blur:ignore_opacity"); setMonitorTransformEnabled(true); if (!USENEWOPTIMIZE) setRenderModifEnabled(false); - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, 0, 2.0f, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), pBox, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, round, roundingPower, false, false, true); if (!USENEWOPTIMIZE) setRenderModifEnabled(true); setMonitorTransformEnabled(false); + m_RenderData.primarySurfaceUVTopLeft = LASTTL; + m_RenderData.primarySurfaceUVBottomRight = LASTBR; + // render the window, but clear stencil glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); From bb099e5733ae92c1b563efdb32d3d56a1540ab4a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 23 Jan 2025 22:57:14 +0000 Subject: [PATCH 0154/1444] pass/rect: fix box shrinking with bb fixes #9084 --- src/render/pass/RectPassElement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index a57c959e..fe2f1f78 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -24,7 +24,7 @@ bool CRectPassElement::needsPrecomputeBlur() { } std::optional CRectPassElement::boundingBox() { - return data.box.expand(-data.round); + return data.box.copy().expand(-data.round); } CRegion CRectPassElement::opaqueRegion() { From d075d1cab9e8836be4544229486fec004236f3fa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 23 Jan 2025 22:59:06 +0000 Subject: [PATCH 0155/1444] pass/rect: fix bounding box --- src/render/pass/RectPassElement.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index fe2f1f78..55471e78 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -24,9 +24,9 @@ bool CRectPassElement::needsPrecomputeBlur() { } std::optional CRectPassElement::boundingBox() { - return data.box.copy().expand(-data.round); + return data.box; } CRegion CRectPassElement::opaqueRegion() { - return data.color.a >= 1.F ? *boundingBox() : CRegion{}; + return data.color.a >= 1.F ? boundingBox()->expand(-data.round) : CRegion{}; } From 5d8261aee243fd1bd53f9e0eb27f1a460eac83d6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Jan 2025 00:25:14 +0000 Subject: [PATCH 0156/1444] xwayland: avoid sending value of real size to xwayland --- src/managers/XWaylandManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index ab0bfb88..5a933236 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -55,7 +55,7 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { if (pWindow->m_bIsX11) { if (activate) { - setWindowSize(pWindow, pWindow->m_vRealSize->value()); // update xwayland output pos + setWindowSize(pWindow, pWindow->m_vRealSize->goal()); // update xwayland output pos pWindow->m_pXWaylandSurface->setMinimized(false); if (!pWindow->isX11OverrideRedirect()) From 4a1b960cbedb3e2893eeadecdf2b4a7314634306 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Jan 2025 00:49:47 +0000 Subject: [PATCH 0157/1444] layout: set window size after toggling floating --- src/layout/IHyprLayout.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 9fc84b22..49633d94 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -788,9 +788,8 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { } g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); - pWindow->updateToplevel(); - + g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize->goal()); g_pHyprRenderer->damageWindow(pWindow); } From 944e36ea2e71db20cf3f8b2e5cbf978a5bf5268b Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Jan 2025 13:23:23 +0000 Subject: [PATCH 0158/1444] config: fix misc:disable_autoreload fixes #9139 --- src/config/ConfigManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index b0665db9..f5c9b3ee 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -897,9 +897,10 @@ std::optional CConfigManager::resetHLConfig() { void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); + static const auto PDISABLEAUTORELOAD = CConfigValue("misc:disable_autoreload"); static int prevEnabledExplicit = *PENABLEEXPLICIT; - g_pConfigWatcher->setWatchList(m_configPaths); + g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector{} : m_configPaths); for (auto const& w : g_pCompositor->m_vWindows) { w->uncacheWindowDecos(); From 57a39984dddd00fd1aca436e149b7566e5e48d95 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Jan 2025 13:37:23 +0000 Subject: [PATCH 0159/1444] input: abord dnd op on escape pressed ref #9154 --- src/managers/KeybindManager.cpp | 4 ++++ src/protocols/core/DataDevice.cpp | 6 ++++++ src/protocols/core/DataDevice.hpp | 3 +++ 3 files changed, 13 insertions(+) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index f4a55a73..4706c1e1 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -4,6 +4,7 @@ #include "../protocols/LayerShell.hpp" #include "../protocols/ShortcutsInhibit.hpp" #include "../protocols/GlobalShortcuts.hpp" +#include "../protocols/core/DataDevice.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "KeybindManager.hpp" #include "PointerManager.hpp" @@ -432,6 +433,9 @@ bool CKeybindManager::onKeyEvent(std::any event, SP pKeyboard) { const xkb_keysym_t keysym = xkb_state_key_get_one_sym(pKeyboard->resolveBindsBySym ? pKeyboard->xkbSymState : m_pXKBTranslationState, KEYCODE); const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym(pKeyboard->xkbState, KEYCODE); + if (keysym == XKB_KEY_Escape || internalKeysym == XKB_KEY_Escape) + PROTO::data->abortDndIfPresent(); + // handleInternalKeybinds returns true when the key should be suppressed, // while this function returns true when the key event should be sent if (handleInternalKeybinds(internalKeysym)) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index ade16498..36437dd4 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -814,3 +814,9 @@ void CWLDataDeviceProtocol::renderDND(PHLMONITOR pMonitor, timespec* when) { bool CWLDataDeviceProtocol::dndActive() { return dnd.currentSource; } + +void CWLDataDeviceProtocol::abortDndIfPresent() { + if (!dndActive()) + return; + abortDrag(); +} diff --git a/src/protocols/core/DataDevice.hpp b/src/protocols/core/DataDevice.hpp index 5101862e..d8bc2b9c 100644 --- a/src/protocols/core/DataDevice.hpp +++ b/src/protocols/core/DataDevice.hpp @@ -144,6 +144,9 @@ class CWLDataDeviceProtocol : public IWaylandProtocol { // TODO: move handling to seatmgr bool dndActive(); + // called on an escape key pressed, for moments where it gets stuck + void abortDndIfPresent(); + private: void destroyResource(CWLDataDeviceManagerResource* resource); void destroyResource(CWLDataDeviceResource* resource); From 0e5d03a5574efb78f06f2723b345bac867d98696 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:50:15 +0000 Subject: [PATCH 0160/1444] datadevice: do the unfocus surface stuff before dndActive is true (#9157) --- src/managers/SeatManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp index 8fee6b16..6d2b906f 100644 --- a/src/managers/SeatManager.cpp +++ b/src/managers/SeatManager.cpp @@ -194,7 +194,7 @@ void CSeatManager::setPointerFocus(SP surf, const Vector2D& if (state.pointerFocus == surf) return; - if (PROTO::data->dndActive()) { + if (PROTO::data->dndActive() && surf) { if (state.dndPointerFocus == surf) return; Debug::log(LOG, "[seatmgr] Refusing pointer focus during an active dnd, but setting dndPointerFocus"); From 9b3f71390c3db14fd2fa2ff14d533eee34538c55 Mon Sep 17 00:00:00 2001 From: heather7283 <142042427+heather7283@users.noreply.github.com> Date: Fri, 24 Jan 2025 19:51:31 +0400 Subject: [PATCH 0161/1444] layershell: check if layer is valid (#9156) fixes compositor crash when client tried to create a layer surface with invalid layer argument --- src/protocols/LayerShell.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/protocols/LayerShell.cpp b/src/protocols/LayerShell.cpp index 1533a7c0..c88dc925 100644 --- a/src/protocols/LayerShell.cpp +++ b/src/protocols/LayerShell.cpp @@ -233,6 +233,11 @@ void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id return; } + if UNLIKELY (layer > ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) { + pMgr->error(ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER, "Invalid layer"); + return; + } + const auto RESOURCE = m_vLayers.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id), SURF, namespace_, PMONITOR, layer)); if UNLIKELY (!RESOURCE->good()) { From fda9790cde5eb2bd15c19a1e67211eabbebf9024 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Jan 2025 17:51:11 +0000 Subject: [PATCH 0162/1444] layout: force full damage on toggling floating mode fixes #8849 --- src/layout/IHyprLayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 49633d94..ffc08e46 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -717,7 +717,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { pWindow->m_bPinned = false; - g_pHyprRenderer->damageWindow(pWindow); + g_pHyprRenderer->damageWindow(pWindow, true); const auto TILED = isWindowTiled(pWindow); From 80b2fd135b45f2c2e41ceb312314908f6a3e7b30 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Fri, 24 Jan 2025 18:22:05 +0000 Subject: [PATCH 0163/1444] animations: fix borderangle once (#9149) --- src/Compositor.cpp | 5 +---- src/desktop/Window.cpp | 8 ++++++++ src/desktop/Window.hpp | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index aeec2830..cb0665e5 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1155,6 +1155,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface g_pXWaylandManager->activateWindow(pWindow, true); // sets the m_pLastWindow pWindow->updateDynamicRules(); + pWindow->onFocusAnimUpdate(); updateWindowAnimatedDecorationValues(pWindow); @@ -1851,10 +1852,6 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { } } - // tick angle if it's not running (aka dead) - if (!pWindow->m_fBorderAngleAnimationProgress->isBeingAnimated()) - pWindow->m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); - // opacity const auto PWORKSPACE = pWindow->m_pWorkspace; if (pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index fb5904be..5306bbb4 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1274,6 +1274,14 @@ void CWindow::onWorkspaceAnimUpdate() { m_vFloatingOffset = offset; } +void CWindow::onFocusAnimUpdate() { + // borderangle once + if (m_fBorderAngleAnimationProgress->enabled() && !m_fBorderAngleAnimationProgress->isBeingAnimated()) { + m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); + *m_fBorderAngleAnimationProgress = 1.f; + } +} + int CWindow::popupsCount() { if (m_bIsX11) return 0; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 5b4ad654..cff13b03 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -454,6 +454,7 @@ class CWindow { void switchWithWindowInGroup(PHLWINDOW pWindow); void setAnimationsToMove(); void onWorkspaceAnimUpdate(); + void onFocusAnimUpdate(); void onUpdateState(); void onUpdateMeta(); void onX11Configure(CBox box); From d8f79d7678f428738f3173020109bd7b7fbd0840 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 24 Jan 2025 20:30:12 +0000 Subject: [PATCH 0164/1444] core: add --verify-config to verify the config with Hyprland fixes #9135 --- src/Compositor.cpp | 18 ++++++++++++++++-- src/Compositor.hpp | 11 ++++++----- src/config/ConfigManager.cpp | 30 +++++++++++++++++++++++------- src/config/ConfigManager.hpp | 8 +++++--- src/main.cpp | 17 ++++++++++++----- src/managers/AnimationManager.cpp | 3 ++- src/managers/KeybindManager.cpp | 7 +++++-- 7 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index cb0665e5..ab9c16f7 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "debug/HyprCtl.hpp" #include "debug/CrashReporter.hpp" @@ -162,7 +163,10 @@ void CCompositor::restoreNofile() { Debug::log(ERR, "Failed restoring NOFILE limits"); } -CCompositor::CCompositor() : m_iHyprlandPID(getpid()) { +CCompositor::CCompositor(bool onlyConfig) : m_bOnlyConfigVerification(onlyConfig), m_iHyprlandPID(getpid()) { + if (onlyConfig) + return; + m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr"; if (m_szHyprTempDataRoot.starts_with("/hypr")) { @@ -226,7 +230,7 @@ CCompositor::CCompositor() : m_iHyprlandPID(getpid()) { } CCompositor::~CCompositor() { - if (!m_bIsShuttingDown) + if (!m_bIsShuttingDown && !m_bOnlyConfigVerification) cleanup(); } @@ -262,6 +266,16 @@ static bool filterGlobals(const wl_client* client, const wl_global* global, void // void CCompositor::initServer(std::string socketName, int socketFd) { + if (m_bOnlyConfigVerification) { + g_pHookSystem = makeUnique(); + g_pKeybindManager = makeUnique(); + g_pAnimationManager = makeUnique(); + g_pConfigManager = makeUnique(); + + std::println("\n\n======== Config parsing result:\n\n{}", g_pConfigManager->verify()); + return; + } + m_sWLDisplay = wl_display_create(); wl_display_set_global_filter(m_sWLDisplay, ::filterGlobals, nullptr); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index f2e2ca14..295878df 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -24,7 +24,7 @@ enum eManagersInitStage : uint8_t { class CCompositor { public: - CCompositor(); + CCompositor(bool onlyConfig = false); ~CCompositor(); wl_display* m_sWLDisplay; @@ -71,10 +71,11 @@ class CCompositor { bool m_bUnsafeState = false; // unsafe state is when there is no monitors. bool m_bNextIsUnsafe = false; PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state - bool m_bIsShuttingDown = false; - bool m_bFinalRequests = false; - bool m_bDesktopEnvSet = false; - bool m_bWantsXwayland = true; + bool m_bIsShuttingDown = false; + bool m_bFinalRequests = false; + bool m_bDesktopEnvSet = false; + bool m_bWantsXwayland = true; + bool m_bOnlyConfigVerification = false; // ------------------------------------------------- // diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f5c9b3ee..c5d70329 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -19,6 +19,7 @@ #include "../render/Renderer.hpp" #include "../hyprerror/HyprError.hpp" #include "../managers/input/InputManager.hpp" +#include "../managers/eventLoop/EventLoopManager.hpp" #include "../managers/LayoutManager.hpp" #include "../managers/EventManager.hpp" #include "../debug/HyprNotificationOverlay.hpp" @@ -730,15 +731,18 @@ CConfigManager::CConfigManager() { resetHLConfig(); - Debug::log(INFO, - "!!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: " - "https://wiki.hyprland.org/Configuring/Variables/#debug"); + if (!g_pCompositor->m_bOnlyConfigVerification) { + Debug::log( + INFO, + "!!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: " + "https://wiki.hyprland.org/Configuring/Variables/#debug"); + } Debug::disableLogs = reinterpret_cast(m_pConfig->getConfigValuePtr("debug:disable_logs")->getDataStaticPtr()); Debug::disableTime = reinterpret_cast(m_pConfig->getConfigValuePtr("debug:disable_time")->getDataStaticPtr()); - if (ERR.has_value()) - g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0}); + if (g_pEventLoopManager && ERR.has_value()) + g_pEventLoopManager->doLater([ERR] { g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0}); }); } std::optional CConfigManager::generateConfig(std::string configPath) { @@ -820,11 +824,23 @@ void CConfigManager::reload() { EMIT_HOOK_EVENT("preConfigReload", nullptr); setDefaultAnimationVars(); resetHLConfig(); - configCurrentPath = getMainConfigPath(); - const auto ERR = m_pConfig->parse(); + configCurrentPath = getMainConfigPath(); + const auto ERR = m_pConfig->parse(); + m_bLastConfigVerificationWasSuccessful = !ERR.error; postConfigReload(ERR); } +std::string CConfigManager::verify() { + setDefaultAnimationVars(); + resetHLConfig(); + configCurrentPath = getMainConfigPath(); + const auto ERR = m_pConfig->parse(); + m_bLastConfigVerificationWasSuccessful = !ERR.error; + if (ERR.error) + return ERR.getError(); + return "config ok"; +} + void CConfigManager::setDefaultAnimationVars() { m_AnimationTree.createNode("__internal_fadeCTM"); m_AnimationTree.createNode("global"); diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 31ad81cd..564c1ebf 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -144,6 +144,7 @@ class CConfigManager { void init(); void reload(); + std::string verify(); int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = ""); float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = ""); @@ -257,9 +258,10 @@ class CConfigManager { {"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }}, {"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}}; - bool m_bWantsMonitorReload = false; - bool m_bNoMonitorReload = false; - bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking + bool m_bWantsMonitorReload = false; + bool m_bNoMonitorReload = false; + bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking + bool m_bLastConfigVerificationWasSuccessful = true; private: UP m_pConfig; diff --git a/src/main.cpp b/src/main.cpp index bb5e5622..d244f10f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,6 +27,7 @@ static void help() { --wayland-fd FD - Sets the Wayland socket fd (for Wayland socket handover) --systeminfo - Prints system infos --i-am-really-stupid - Omits root user privileges check (why would you do that?) + --verify-config - Do not run Hyprland, only print if the config has any errors --version -v - Print this binary's version)"); } @@ -49,7 +50,7 @@ int main(int argc, char** argv) { std::string configPath; std::string socketName; int socketFd = -1; - bool ignoreSudo = false; + bool ignoreSudo = false, verifyConfig = false; std::vector args{argv + 1, argv + argc}; @@ -124,6 +125,9 @@ int main(int argc, char** argv) { } else if (*it == "--systeminfo") { std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, "")); return 0; + } else if (*it == "--verify-config") { + verifyConfig = true; + continue; } else { std::println(stderr, "[ ERROR ] Unknown option '{}' !", *it); help(); @@ -138,9 +142,8 @@ int main(int argc, char** argv) { " Hint: Use the --i-am-really-stupid flag to omit that check."); return 1; - } else if (ignoreSudo && NInit::isSudo()) { + } else if (ignoreSudo && NInit::isSudo()) std::println("Superuser privileges check is omitted. I hope you know what you're doing."); - } if (socketName.empty() ^ (socketFd == -1)) { std::println(stderr, @@ -150,12 +153,13 @@ int main(int argc, char** argv) { return 1; } - std::println("Welcome to Hyprland!"); + if (!verifyConfig) + std::println("Welcome to Hyprland!"); // let's init the compositor. // it initializes basic Wayland stuff in the constructor. try { - g_pCompositor = makeUnique(); + g_pCompositor = makeUnique(verifyConfig); g_pCompositor->explicitConfigPath = configPath; } catch (const std::exception& e) { std::println(stderr, "Hyprland threw in ctor: {}\nCannot continue.", e.what()); @@ -164,6 +168,9 @@ int main(int argc, char** argv) { g_pCompositor->initServer(socketName, socketFd); + if (verifyConfig) + return !g_pConfigManager->m_bLastConfigVerificationWasSuccessful; + if (!envEnabled("HYPRLAND_NO_RT")) NInit::gainRealTime(); diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index f884acdd..964f7cfa 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -34,7 +34,8 @@ static int wlTick(SP self, void* data) { CHyprAnimationManager::CHyprAnimationManager() { m_pAnimationTimer = SP(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr)); - g_pEventLoopManager->addTimer(m_pAnimationTimer); + if (g_pEventLoopManager) // null in --verify-config mode + g_pEventLoopManager->addTimer(m_pAnimationTimer); addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)); } diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 4706c1e1..e2191bc6 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -172,8 +172,11 @@ CKeybindManager::CKeybindManager() { }, nullptr); - g_pEventLoopManager->addTimer(m_pLongPressTimer); - g_pEventLoopManager->addTimer(m_pRepeatKeyTimer); + // null in --verify-config mode + if (g_pEventLoopManager) { + g_pEventLoopManager->addTimer(m_pLongPressTimer); + g_pEventLoopManager->addTimer(m_pRepeatKeyTimer); + } static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) { // clear cuz realloc'd From 1815f9a2e5e12cafa670e0f4f7eb10dc9436868c Mon Sep 17 00:00:00 2001 From: heather7283 <142042427+heather7283@users.noreply.github.com> Date: Sat, 25 Jan 2025 03:26:46 +0400 Subject: [PATCH 0165/1444] compositor: fix incorrect cast, use lambda capture instead (#9161) --- src/Compositor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index ab9c16f7..fa73be66 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2519,13 +2519,13 @@ PHLLS CCompositor::getLayerSurfaceFromSurface(SP pSurface) { continue; ls->layerSurface->surface->breadthfirst( - [](SP surf, const Vector2D& offset, void* data) { - if (surf == ((std::pair, bool>*)data)->first) { - *(bool*)data = true; + [&result](SP surf, const Vector2D& offset, void* data) { + if (surf == result.first) { + result.second = true; return; } }, - &result); + nullptr); if (result.second) return ls; From 089fdd1ea0d991da5b068db51531f54c90a2df25 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Fri, 24 Jan 2025 23:27:24 +0000 Subject: [PATCH 0166/1444] window: only set m_iMonitorMovedFrom, when moving to a different monitor (#9160) --- src/Compositor.cpp | 1 - src/desktop/Window.cpp | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index fa73be66..e1ded6b6 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1867,7 +1867,6 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { } // opacity - const auto PWORKSPACE = pWindow->m_pWorkspace; if (pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) { *pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA); } else { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 5306bbb4..4be8fac5 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -420,12 +420,13 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { static auto PCLOSEONLASTSPECIAL = CConfigValue("misc:close_special_on_empty"); - const auto OLDWORKSPACE = m_pWorkspace; + const auto OLDWORKSPACE = m_pWorkspace; + const bool TOANOTHERMONITOR = OLDWORKSPACE && OLDWORKSPACE->monitorID() != pWorkspace->monitorID(); m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F); *m_fMovingToWorkspaceAlpha = 0.F; m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); - m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; + m_iMonitorMovedFrom = TOANOTHERMONITOR ? OLDWORKSPACE->monitorID() : -1; m_pWorkspace = pWorkspace; From 354d4594de6a14e89ab337681dac2d898bc18cbf Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 25 Jan 2025 02:35:41 +0000 Subject: [PATCH 0167/1444] xwayland: various window handling fixes I hate this fucking garbage --- src/desktop/Window.cpp | 8 ++++---- src/events/Windows.cpp | 5 ++++- src/managers/XWaylandManager.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 4be8fac5..97d7ecc0 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1556,10 +1556,10 @@ void CWindow::onX11Configure(CBox box) { } } - m_vPosition = m_vRealPosition->value(); - m_vSize = m_vRealSize->value(); + m_vPosition = m_vRealPosition->goal(); + m_vSize = m_vRealSize->goal(); - m_pXWaylandSurface->configure(box); + g_pXWaylandManager->setWindowSize(m_pSelf.lock(), box.size(), true); m_vPendingReportedSize = box.size(); m_vReportedSize = box.size(); @@ -1569,7 +1569,7 @@ void CWindow::onX11Configure(CBox box) { if (!m_pWorkspace || !m_pWorkspace->isVisible()) return; // further things are only for visible windows - m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition->value() + m_vRealSize->value() / 2.f)->activeWorkspace; + m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition->goal() + m_vRealSize->goal() / 2.f)->activeWorkspace; g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index cadd4cbc..525adc02 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -43,7 +43,7 @@ static void setVector2DAnimToMove(WP pav) { animvar->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsMove")); const auto PHLWINDOW = animvar->m_Context.pWindow.lock(); - if (PHLWINDOW && !PHLWINDOW->m_vRealPosition->isBeingAnimated() && !PHLWINDOW->m_vRealSize->isBeingAnimated()) + if (PHLWINDOW) PHLWINDOW->m_bAnimatingIn = false; } @@ -680,6 +680,9 @@ void Events::listener_mapWindow(void* owner, void* data) { if (PMONITOR && PWINDOW->isX11OverrideRedirect()) PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale; + + if (!PWINDOW->isX11OverrideRedirect() && PWINDOW->m_bIsX11 && PWINDOW->m_bIsFloating) + g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize->goal(), true); } void Events::listener_unmapWindow(void* owner, void* data) { diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 5a933236..8956cf3a 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -55,7 +55,7 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { if (pWindow->m_bIsX11) { if (activate) { - setWindowSize(pWindow, pWindow->m_vRealSize->goal()); // update xwayland output pos + setWindowSize(pWindow, pWindow->m_vRealSize->value(), true); // update xwayland output pos pWindow->m_pXWaylandSurface->setMinimized(false); if (!pWindow->isX11OverrideRedirect()) @@ -162,7 +162,9 @@ bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) { if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"]) pWindow->m_bX11ShouldntFocus = true; - pWindow->m_bNoInitialFocus = true; + if (a != HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"]) + pWindow->m_bNoInitialFocus = true; + return true; } From 065e89648b27017871c38831cf34def94feb72d6 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 25 Jan 2025 15:33:27 +0200 Subject: [PATCH 0168/1444] flake.lock: update --- flake.lock | 91 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/flake.lock b/flake.lock index ed1702d1..34249b0a 100644 --- a/flake.lock +++ b/flake.lock @@ -181,11 +181,11 @@ ] }, "locked": { - "lastModified": 1737634810, - "narHash": "sha256-ZIJ03DeisbQuDaADSgmbgyocjecaozK4yGTa0/9bOr0=", + "lastModified": 1737811848, + "narHash": "sha256-WZ7LeiKHk5Y94MU5gHIWn0r8asWxYOvie4LqfCjVIZU=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "a9852dbf5a1ec77cf617543728144c1362709e46", + "rev": "9c0831ff98856c0f312fcb8b57553fbe3dd34d5b", "type": "github" }, "original": { @@ -196,12 +196,17 @@ }, "hyprlang": { "inputs": { - "hyprutils": [ + "hyprutils": "hyprutils", + "nixpkgs": [ "hyprland-qtutils", - "hyprutils" + "hyprland-qt-support", + "nixpkgs" ], - "nixpkgs": "nixpkgs", - "systems": "systems" + "systems": [ + "hyprland-qtutils", + "hyprland-qt-support", + "systems" + ] }, "locked": { "lastModified": 1737634606, @@ -246,9 +251,15 @@ "hyprutils": { "inputs": { "nixpkgs": [ + "hyprland-qtutils", + "hyprland-qt-support", + "hyprlang", "nixpkgs" ], "systems": [ + "hyprland-qtutils", + "hyprland-qt-support", + "hyprlang", "systems" ] }, @@ -266,6 +277,29 @@ "type": "github" } }, + "hyprutils_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "systems": [ + "systems" + ] + }, + "locked": { + "lastModified": 1737725508, + "narHash": "sha256-jGmcPc6y/prg/4A8KGYqJ27nSPaProCMiFadaxNAKvA=", + "owner": "hyprwm", + "repo": "hyprutils", + "rev": "fb0c2d1de3d1ef7396d19c18ac09e12bd956929e", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprutils", + "type": "github" + } + }, "hyprwayland-scanner": { "inputs": { "nixpkgs": [ @@ -291,27 +325,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1737469691, - "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=", + "lastModified": 1737632463, + "narHash": "sha256-38J9QfeGSej341ouwzqf77WIHAScihAKCt8PQJ+NH28=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1737469691, - "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab", + "rev": "0aa475546ed21629c4f5bbf90e38c846a99ec9e9", "type": "github" }, "original": { @@ -351,11 +369,11 @@ "hyprland-protocols": "hyprland-protocols", "hyprland-qtutils": "hyprland-qtutils", "hyprlang": "hyprlang_2", - "hyprutils": "hyprutils", + "hyprutils": "hyprutils_2", "hyprwayland-scanner": "hyprwayland-scanner", - "nixpkgs": "nixpkgs_2", + "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks", - "systems": "systems_2", + "systems": "systems", "xdph": "xdph" } }, @@ -374,21 +392,6 @@ "type": "github" } }, - "systems_2": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, "xdph": { "inputs": { "hyprland-protocols": [ From 107723bdf448223385034a4ea724328de7ba50cc Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:23:36 +0000 Subject: [PATCH 0169/1444] config: disable borderangle by default (#9165) --- src/config/ConfigManager.cpp | 1 + src/desktop/Window.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index c5d70329..fd4783da 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -882,6 +882,7 @@ void CConfigManager::setDefaultAnimationVars() { // init the root nodes m_AnimationTree.setConfigForNode("global", 1, 8.f, "", "default"); m_AnimationTree.setConfigForNode("__internal_fadeCTM", 1, 5.f, "", "linear"); + m_AnimationTree.setConfigForNode("borderangle", 0, 0.f, "", "default"); } std::optional CConfigManager::resetHLConfig() { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 97d7ecc0..962386c8 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -552,9 +552,11 @@ void CWindow::onMap() { m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); - m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); - m_fBorderAngleAnimationProgress->setCallbackOnEnd([&](WP p) { onBorderAngleAnimEnd(p); }, false); - *m_fBorderAngleAnimationProgress = 1.f; + if (m_fBorderAngleAnimationProgress->enabled()) { + m_fBorderAngleAnimationProgress->setValueAndWarp(0.f); + m_fBorderAngleAnimationProgress->setCallbackOnEnd([&](WP p) { onBorderAngleAnimEnd(p); }, false); + *m_fBorderAngleAnimationProgress = 1.f; + } m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); From f3fc8d599a7812a25f2d53957c0692d339359b43 Mon Sep 17 00:00:00 2001 From: heather7283 <142042427+heather7283@users.noreply.github.com> Date: Sat, 25 Jan 2025 22:23:53 +0400 Subject: [PATCH 0170/1444] config/ConfigWatcher.cpp: add missing include needed for clang (#9166) --- src/config/ConfigWatcher.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config/ConfigWatcher.cpp b/src/config/ConfigWatcher.cpp index 38191e9e..c0a9c591 100644 --- a/src/config/ConfigWatcher.cpp +++ b/src/config/ConfigWatcher.cpp @@ -3,6 +3,7 @@ #include "../debug/Log.hpp" #include #include +#include CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) { if (m_inotifyFd < 0) { From bce58d9d6554f1b69ecf38e19f0921230e37ab6d Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 25 Jan 2025 18:34:10 +0000 Subject: [PATCH 0171/1444] dwindle: fix possible crash on null ws --- src/layout/DwindleLayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index c6cf2b4c..6d06a3a1 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -105,8 +105,8 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for break; } } - } else - PMONITOR = g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_pMonitor.lock(); + } else if (const auto WS = g_pCompositor->getWorkspaceByID(pNode->workspaceID); WS) + PMONITOR = WS->m_pMonitor.lock(); if (!PMONITOR) { Debug::log(ERR, "Orphaned Node {}!!", pNode); From 9199a9746d7a9355fd349909cb0f773b513ae912 Mon Sep 17 00:00:00 2001 From: Junxuan Liao <70618504+MikeWalrus@users.noreply.github.com> Date: Sat, 25 Jan 2025 12:44:13 -0600 Subject: [PATCH 0172/1444] input: pass touch events to lock screens (#9129) * refactor: use weak pointers for session lock surfaces * input: pass touch events to lock screens --- src/managers/SessionLockManager.cpp | 10 +++++----- src/managers/SessionLockManager.hpp | 18 ++++++++--------- src/managers/input/InputManager.hpp | 10 ++++++---- src/managers/input/Touch.cpp | 30 ++++++++++++++++++++++++----- src/render/Renderer.cpp | 2 +- src/render/Renderer.hpp | 2 +- 6 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp index ea0d8dfc..996860a1 100644 --- a/src/managers/SessionLockManager.cpp +++ b/src/managers/SessionLockManager.cpp @@ -95,20 +95,20 @@ bool CSessionLockManager::isSessionLocked() { return PROTO::sessionLock->isLocked(); } -SSessionLockSurface* CSessionLockManager::getSessionLockSurfaceForMonitor(uint64_t id) { +WP CSessionLockManager::getSessionLockSurfaceForMonitor(uint64_t id) { if (!m_pSessionLock) - return nullptr; + return {}; for (auto const& sls : m_pSessionLock->vSessionLockSurfaces) { if (sls->iMonitorID == id) { if (sls->mapped) - return sls.get(); + return sls; else - return nullptr; + return {}; } } - return nullptr; + return {}; } // We don't want the red screen to flash. diff --git a/src/managers/SessionLockManager.hpp b/src/managers/SessionLockManager.hpp index aaf78819..51d4cefb 100644 --- a/src/managers/SessionLockManager.hpp +++ b/src/managers/SessionLockManager.hpp @@ -49,20 +49,20 @@ class CSessionLockManager { CSessionLockManager(); ~CSessionLockManager() = default; - SSessionLockSurface* getSessionLockSurfaceForMonitor(uint64_t); + WP getSessionLockSurfaceForMonitor(uint64_t); - float getRedScreenAlphaForMonitor(uint64_t); + float getRedScreenAlphaForMonitor(uint64_t); - bool isSessionLocked(); - bool isSessionLockPresent(); - bool isSurfaceSessionLock(SP); - bool anySessionLockSurfacesPresent(); + bool isSessionLocked(); + bool isSessionLockPresent(); + bool isSurfaceSessionLock(SP); + bool anySessionLockSurfacesPresent(); - void removeSessionLockSurface(SSessionLockSurface*); + void removeSessionLockSurface(SSessionLockSurface*); - void onLockscreenRenderedOnMonitor(uint64_t id); + void onLockscreenRenderedOnMonitor(uint64_t id); - bool shallConsiderLockMissing(); + bool shallConsiderLockMissing(); private: UP m_pSessionLock; diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index c0f1939e..3afb1b88 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -10,6 +10,7 @@ #include "../../devices/IPointer.hpp" #include "../../devices/ITouch.hpp" #include "../../devices/Tablet.hpp" +#include "../SessionLockManager.hpp" class CPointerConstraint; class CWindow; @@ -52,10 +53,11 @@ enum eBorderIconDirection : uint8_t { }; struct STouchData { - PHLWINDOWREF touchFocusWindow; - PHLLSREF touchFocusLS; - WP touchFocusSurface; - Vector2D touchSurfaceOrigin; + WP touchFocusLockSurface; + PHLWINDOWREF touchFocusWindow; + PHLLSREF touchFocusLS; + WP touchFocusSurface; + Vector2D touchSurfaceOrigin; }; // The third row is always 0 0 1 and is not expected by `libinput_device_config_calibration_set_matrix` diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 990fbc41..3d35764e 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -1,4 +1,6 @@ #include "InputManager.hpp" +#include "../SessionLockManager.hpp" +#include "../../protocols/SessionLock.hpp" #include "../../Compositor.hpp" #include "../../desktop/LayerSurface.hpp" #include "../../config/ConfigValue.hpp" @@ -6,6 +8,7 @@ #include "../SeatManager.hpp" #include "managers/AnimationManager.hpp" #include "../HookSystemManager.hpp" +#include "debug/Log.hpp" void CInputManager::onTouchDown(ITouch::SDownEvent e) { m_bLastInputTouch = true; @@ -57,13 +60,25 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) { } } - m_sTouchData.touchFocusWindow = m_pFoundWindowToFocus; - m_sTouchData.touchFocusSurface = m_pFoundSurfaceToFocus; - m_sTouchData.touchFocusLS = m_pFoundLSToFocus; + if (g_pSessionLockManager->isSessionLocked()) { + m_sTouchData.touchFocusLockSurface = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->ID); + if (!m_sTouchData.touchFocusLockSurface) + Debug::log(WARN, "The session is locked but can't find a lock surface"); + else + m_sTouchData.touchFocusSurface = m_sTouchData.touchFocusLockSurface->surface->surface(); + } else { + m_sTouchData.touchFocusLockSurface.reset(); + m_sTouchData.touchFocusWindow = m_pFoundWindowToFocus; + m_sTouchData.touchFocusSurface = m_pFoundSurfaceToFocus; + m_sTouchData.touchFocusLS = m_pFoundLSToFocus; + } Vector2D local; - if (!m_sTouchData.touchFocusWindow.expired()) { + if (m_sTouchData.touchFocusLockSurface) { + local = g_pInputManager->getMouseCoordsInternal() - PMONITOR->vecPosition; + m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local; + } else if (!m_sTouchData.touchFocusWindow.expired()) { if (m_sTouchData.touchFocusWindow->m_bIsX11) { local = (g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusWindow->m_vRealPosition->goal()) * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy; m_sTouchData.touchSurfaceOrigin = m_sTouchData.touchFocusWindow->m_vRealPosition->goal(); @@ -126,7 +141,12 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) { updateWorkspaceSwipe(SWIPEDISTANCE * (1 - (VERTANIMS ? e.pos.y : e.pos.x))); return; } - if (validMapped(m_sTouchData.touchFocusWindow)) { + if (m_sTouchData.touchFocusLockSurface) { + const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusLockSurface->iMonitorID); + g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true); + auto local = g_pInputManager->getMouseCoordsInternal() - PMONITOR->vecPosition; + g_pSeatManager->sendTouchMotion(e.timeMs, e.touchID, local); + } else if (validMapped(m_sTouchData.touchFocusWindow)) { const auto PMONITOR = m_sTouchData.touchFocusWindow->m_pMonitor.lock(); g_pCompositor->warpCursorTo({PMONITOR->vecPosition.x + e.pos.x * PMONITOR->vecSize.x, PMONITOR->vecPosition.y + e.pos.y * PMONITOR->vecSize.y}, true); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 384db1e6..d82d79d1 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -768,7 +768,7 @@ void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, tim &renderdata); } -void CHyprRenderer::renderSessionLockSurface(SSessionLockSurface* pSurface, PHLMONITOR pMonitor, timespec* time) { +void CHyprRenderer::renderSessionLockSurface(WP pSurface, PHLMONITOR pMonitor, timespec* time) { CSurfacePassElement::SRenderData renderdata = {pMonitor, time, pMonitor->vecPosition, pMonitor->vecPosition}; renderdata.blur = false; diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 1ef1eecc..30fba3ca 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -120,7 +120,7 @@ class CHyprRenderer { void renderWorkspaceWindows(PHLMONITOR, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) void renderWindow(PHLWINDOW, PHLMONITOR, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool standalone = false); void renderLayer(PHLLS, PHLMONITOR, timespec*, bool popups = false); - void renderSessionLockSurface(SSessionLockSurface*, PHLMONITOR, timespec*); + void renderSessionLockSurface(WP, PHLMONITOR, timespec*); void renderDragIcon(PHLMONITOR, timespec*); void renderIMEPopup(CInputPopup*, PHLMONITOR, timespec*); void renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry); From 45c3787e75323999d2f43b6f83972f4cb11a81f9 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 25 Jan 2025 19:37:33 +0000 Subject: [PATCH 0173/1444] window: revert only set m_iMonitorMovedFrom, when moving to a different monitor This reverts commit 089fdd1ea0d991da5b068db51531f54c90a2df25. Great commit. --- src/Compositor.cpp | 1 + src/desktop/Window.cpp | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index e1ded6b6..fa73be66 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1867,6 +1867,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { } // opacity + const auto PWORKSPACE = pWindow->m_pWorkspace; if (pWindow->isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) { *pWindow->m_fActiveInactiveAlpha = pWindow->m_sWindowData.alphaFullscreen.valueOrDefault().applyAlpha(*PFULLSCREENALPHA); } else { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 962386c8..5f84aa3a 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -420,13 +420,12 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { static auto PCLOSEONLASTSPECIAL = CConfigValue("misc:close_special_on_empty"); - const auto OLDWORKSPACE = m_pWorkspace; - const bool TOANOTHERMONITOR = OLDWORKSPACE && OLDWORKSPACE->monitorID() != pWorkspace->monitorID(); + const auto OLDWORKSPACE = m_pWorkspace; m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F); *m_fMovingToWorkspaceAlpha = 0.F; m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); - m_iMonitorMovedFrom = TOANOTHERMONITOR ? OLDWORKSPACE->monitorID() : -1; + m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; m_pWorkspace = pWorkspace; From 445acec2a29adbb30196d8b92f86270a038b7ee5 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 25 Jan 2025 20:36:44 +0000 Subject: [PATCH 0174/1444] core: move sendWindowSize off of xwaylandmgr additionally fixes that one weird x11 issue with floating windows being mis-sized on open --- src/Compositor.cpp | 2 +- src/desktop/Window.cpp | 45 +++++++++++++++++-- src/desktop/Window.hpp | 2 + src/desktop/Workspace.cpp | 2 +- src/events/Windows.cpp | 10 +++-- src/layout/DwindleLayout.cpp | 4 +- src/layout/IHyprLayout.cpp | 10 ++--- src/layout/MasterLayout.cpp | 4 +- src/managers/KeybindManager.cpp | 2 +- src/managers/XWaylandManager.cpp | 40 +---------------- src/managers/XWaylandManager.hpp | 1 - .../decorations/CHyprGroupBarDecoration.cpp | 2 +- 12 files changed, 64 insertions(+), 60 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index fa73be66..3f9126b7 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2325,7 +2325,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS updateFullscreenFadeOnWorkspace(PWORKSPACE); - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize->goal(), true); + PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true); PWORKSPACE->forceReportSizesToWindows(); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 5f84aa3a..96b87205 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -453,7 +453,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { } // update xwayland coords - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize->goal()); + sendWindowSize(m_vRealSize->goal()); if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && OLDWORKSPACE->getWindows() == 0 && *PCLOSEONLASTSPECIAL) { if (const auto PMONITOR = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR) @@ -1309,7 +1309,7 @@ void CWindow::clampWindowSize(const std::optional minSize, const std:: *m_vRealPosition = m_vRealPosition->goal() + DELTA / 2.0; *m_vRealSize = NEWSIZE; - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), NEWSIZE); + sendWindowSize(NEWSIZE); } bool CWindow::isFullscreen() { @@ -1533,7 +1533,7 @@ void CWindow::onX11Configure(CBox box) { g_pHyprRenderer->damageWindow(m_pSelf.lock()); if (!m_bIsFloating || isFullscreen() || g_pInputManager->currentlyDraggedWindow == m_pSelf) { - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize->goal(), true); + sendWindowSize(m_vRealSize->goal(), true); g_pInputManager->refocus(); g_pHyprRenderer->damageWindow(m_pSelf.lock()); return; @@ -1560,7 +1560,7 @@ void CWindow::onX11Configure(CBox box) { m_vPosition = m_vRealPosition->goal(); m_vSize = m_vRealSize->goal(); - g_pXWaylandManager->setWindowSize(m_pSelf.lock(), box.size(), true); + sendWindowSize(box.size(), true); m_vPendingReportedSize = box.size(); m_vReportedSize = box.size(); @@ -1690,3 +1690,40 @@ Vector2D CWindow::requestedMaxSize() { return maxSize; } + +void CWindow::sendWindowSize(Vector2D size, bool force, std::optional overridePos) { + static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); + + const auto PMONITOR = m_pMonitor.lock(); + + size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + + // calculate pos + // TODO: this should be decoupled from setWindowSize IMO + Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal()); + + if (m_bIsX11 && PMONITOR) { + windowPos -= PMONITOR->vecPosition; // normalize to monitor + if (*PXWLFORCESCALEZERO) + windowPos *= PMONITOR->scale; // scale if applicable + windowPos += PMONITOR->vecXWaylandPosition; // move to correct position for xwayland + } + + if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11)) + return; + + m_vReportedPosition = windowPos; + m_vPendingReportedSize = size; + + m_fX11SurfaceScaledBy = 1.0f; + + if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR) { + size *= PMONITOR->scale; + m_fX11SurfaceScaledBy = PMONITOR->scale; + } + + if (m_bIsX11 && m_pXWaylandSurface) + m_pXWaylandSurface->configure({windowPos, size}); + else if (m_pXDGSurface && m_pXDGSurface->toplevel) + m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor()); +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index cff13b03..ce2f8eb2 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "../config/ConfigDataValues.hpp" #include "../helpers/AnimatedVariable.hpp" @@ -468,6 +469,7 @@ class CWindow { bool isModal(); Vector2D requestedMinSize(); Vector2D requestedMaxSize(); + void sendWindowSize(Vector2D size, bool force = false, std::optional overridePos = std::nullopt); CBox getWindowMainSurfaceBox() const { return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y}; diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 99ba441d..8dbf30b7 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -624,7 +624,7 @@ void CWorkspace::forceReportSizesToWindows() { if (w->m_pWorkspace != m_pSelf || !w->m_bIsMapped || w->isHidden()) continue; - g_pXWaylandManager->setWindowSize(w, w->m_vRealSize->goal(), true); + w->sendWindowSize(w->m_vRealSize->goal(), true); } } diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 525adc02..9ecf3652 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -681,8 +681,12 @@ void Events::listener_mapWindow(void* owner, void* data) { if (PMONITOR && PWINDOW->isX11OverrideRedirect()) PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale; - if (!PWINDOW->isX11OverrideRedirect() && PWINDOW->m_bIsX11 && PWINDOW->m_bIsFloating) - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize->goal(), true); + // Fix some X11 popups being invisible / having incorrect size on open. + // What the ACTUAL FUCK is going on?????? I HATE X11 + if (!PWINDOW->isX11OverrideRedirect() && PWINDOW->m_bIsX11 && PWINDOW->m_bIsFloating) { + PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true, PWINDOW->m_vRealPosition->goal() - Vector2D{1, 1}); + PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true); + } } void Events::listener_unmapWindow(void* owner, void* data) { @@ -949,7 +953,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { PWINDOW->setHidden(true); if (PWINDOW->isFullscreen() || !PWINDOW->m_bIsFloating) { - g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize->goal(), true); + PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true); g_pHyprRenderer->damageWindow(PWINDOW); return; } diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 6d06a3a1..df6c3bde 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -199,7 +199,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for *PWINDOW->m_vRealPosition = wb.pos(); *PWINDOW->m_vRealSize = wb.size(); - g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); + PWINDOW->sendWindowSize(wb.size()); } else { CBox wb = {calcPos, calcSize}; wb.round(); // avoid rounding mess @@ -207,7 +207,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for *PWINDOW->m_vRealSize = wb.size(); *PWINDOW->m_vRealPosition = wb.pos(); - g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); + PWINDOW->sendWindowSize(wb.size()); } if (force) { diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index ffc08e46..81392be9 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -179,7 +179,7 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) { } if (!pWindow->isX11OverrideRedirect()) { - g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize->goal()); + pWindow->sendWindowSize(pWindow->m_vRealSize->goal()); g_pCompositor->changeWindowZOrder(pWindow, true); } else { @@ -365,7 +365,7 @@ void IHyprLayout::onEndDragWindow() { DRAGGINGWINDOW->m_bDraggingTiled = false; if (pWindow->m_bIsFloating) - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, pWindow->m_vRealSize->goal()); // match the size of the window + DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); // match the size of the window static auto USECURRPOS = CConfigValue("group:insert_after_current"); (*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW); @@ -611,7 +611,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { else DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos()); - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize->goal()); + DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); } else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) { if (DRAGGINGWINDOW->m_bIsFloating) { @@ -683,7 +683,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos()); } - g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize->goal()); + DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); } else { resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW); } @@ -789,7 +789,7 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); pWindow->updateToplevel(); - g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize->goal()); + pWindow->sendWindowSize(pWindow->m_vRealSize->goal()); g_pHyprRenderer->damageWindow(pWindow); } diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 3b8ff734..8aa15e42 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -679,7 +679,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { *PWINDOW->m_vRealPosition = wb.pos(); *PWINDOW->m_vRealSize = wb.size(); - g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); + PWINDOW->sendWindowSize(wb.size()); } else { CBox wb = {calcPos, calcSize}; wb.round(); // avoid rounding mess @@ -687,7 +687,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { *PWINDOW->m_vRealPosition = wb.pos(); *PWINDOW->m_vRealSize = wb.size(); - g_pXWaylandManager->setWindowSize(PWINDOW, wb.size()); + PWINDOW->sendWindowSize(wb.size()); } if (m_bForceWarps && !*PANIMATE) { diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e2191bc6..2cb77d21 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1914,7 +1914,7 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) { if (PWORKSPACE->m_bDefaultFloating) { w->m_vRealPosition->setValueAndWarp(SAVEDPOS); w->m_vRealSize->setValueAndWarp(SAVEDSIZE); - g_pXWaylandManager->setWindowSize(w, SAVEDSIZE); + w->sendWindowSize(SAVEDSIZE); *w->m_vRealSize = w->m_vRealSize->value() + Vector2D(4, 4); *w->m_vRealPosition = w->m_vRealPosition->value() - Vector2D(2, 2); } diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 8956cf3a..ea2a47ea 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -55,7 +55,7 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { if (pWindow->m_bIsX11) { if (activate) { - setWindowSize(pWindow, pWindow->m_vRealSize->value(), true); // update xwayland output pos + pWindow->sendWindowSize(pWindow->m_vRealSize->value(), true); // update xwayland output pos pWindow->m_pXWaylandSurface->setMinimized(false); if (!pWindow->isX11OverrideRedirect()) @@ -113,44 +113,6 @@ void CHyprXWaylandManager::sendCloseWindow(PHLWINDOW pWindow) { pWindow->m_pXDGSurface->toplevel->close(); } -void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool force) { - - static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); - - const auto PMONITOR = pWindow->m_pMonitor.lock(); - - size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); - - // calculate pos - // TODO: this should be decoupled from setWindowSize IMO - Vector2D windowPos = pWindow->m_vRealPosition->goal(); - - if (pWindow->m_bIsX11 && PMONITOR) { - windowPos -= PMONITOR->vecPosition; // normalize to monitor - if (*PXWLFORCESCALEZERO) - windowPos *= PMONITOR->scale; // scale if applicable - windowPos += PMONITOR->vecXWaylandPosition; // move to correct position for xwayland - } - - if (!force && pWindow->m_vPendingReportedSize == size && (windowPos == pWindow->m_vReportedPosition || !pWindow->m_bIsX11)) - return; - - pWindow->m_vReportedPosition = windowPos; - pWindow->m_vPendingReportedSize = size; - - pWindow->m_fX11SurfaceScaledBy = 1.0f; - - if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) { - size *= PMONITOR->scale; - pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale; - } - - if (pWindow->m_bIsX11) - pWindow->m_pXWaylandSurface->configure({windowPos, size}); - else if (pWindow->m_pXDGSurface->toplevel) - pWindow->m_vPendingSizeAcks.emplace_back(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor()); -} - bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) { if (pWindow->m_bIsX11) { for (const auto& a : pWindow->m_pXWaylandSurface->atoms) diff --git a/src/managers/XWaylandManager.hpp b/src/managers/XWaylandManager.hpp index 8ce239f6..edbdd243 100644 --- a/src/managers/XWaylandManager.hpp +++ b/src/managers/XWaylandManager.hpp @@ -17,7 +17,6 @@ class CHyprXWaylandManager { void activateWindow(PHLWINDOW, bool); void getGeometryForWindow(PHLWINDOW, CBox*); void sendCloseWindow(PHLWINDOW); - void setWindowSize(PHLWINDOW, Vector2D, bool force = false); void setWindowFullscreen(PHLWINDOW, bool); bool shouldBeFloated(PHLWINDOW, bool pending = false); void checkBorders(PHLWINDOW); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 36846fd4..7cef21b8 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -408,7 +408,7 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND pDraggedWindow->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of the window if (pWindowInsertAfter->m_bIsFloating) - g_pXWaylandManager->setWindowSize(pDraggedWindow, pWindowInsertAfter->m_vRealSize->goal()); // match the size of the window + pDraggedWindow->sendWindowSize(pWindowInsertAfter->m_vRealSize->goal()); // match the size of the window pWindowInsertAfter->insertWindowToGroup(pDraggedWindow); From 8b1d6e3009c540457068e23e6c2bc201d20ce4d1 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 25 Jan 2025 21:57:58 +0000 Subject: [PATCH 0175/1444] subsurface: damage the entire parent on size change the previous method doesn't exactly work, idk todo fix fixes #8784 --- src/desktop/Subsurface.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 9cdf3685..eb18ee39 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -101,10 +101,19 @@ void CSubsurface::onCommit() { checkSiblingDamage(); if (m_vLastSize != m_pWLSurface->resource()->current.size) { - CBox box{COORDS, m_vLastSize}; - g_pHyprRenderer->damageBox(&box); - m_vLastSize = m_pWLSurface->resource()->current.size; - box = {COORDS, m_vLastSize}; + // TODO: fix this + // CBox box{COORDS, m_vLastSize}; + // g_pHyprRenderer->damageBox(&box); + // m_vLastSize = m_pWLSurface->resource()->current.size; + // box = {COORDS, m_vLastSize}; + // g_pHyprRenderer->damageBox(&box); + + CBox box; + if (m_pPopupParent) + box = m_pPopupParent->m_pWLSurface->getSurfaceBoxGlobal().value_or(CBox{}); + else if (m_pWindowParent) + box = m_pWindowParent->getWindowMainSurfaceBox(); + g_pHyprRenderer->damageBox(&box); } } From 3cd6e3960f0cbf500786497017ff3084cc9deb17 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:23:39 +0000 Subject: [PATCH 0176/1444] xwayland: fix pointer mismatches with multiple monitors (#9179) --- src/desktop/Window.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 96b87205..b1b3c66c 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1702,11 +1702,9 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional // TODO: this should be decoupled from setWindowSize IMO Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal()); - if (m_bIsX11 && PMONITOR) { - windowPos -= PMONITOR->vecPosition; // normalize to monitor - if (*PXWLFORCESCALEZERO) - windowPos *= PMONITOR->scale; // scale if applicable - windowPos += PMONITOR->vecXWaylandPosition; // move to correct position for xwayland + if (m_bIsX11) { + if (const auto XWAYLANDPOS = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); XWAYLANDPOS != Vector2D{}) + windowPos = XWAYLANDPOS; } if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11)) From 0a28e13787a83a48cbca9641a02b8ea4857c733c Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 12:54:32 +0000 Subject: [PATCH 0177/1444] desktop: move desktop types to memory-safe pointers --- src/Compositor.cpp | 1 - src/desktop/LayerSurface.cpp | 11 ++++++----- src/desktop/Popup.cpp | 35 +++++++++++++++++++---------------- src/desktop/Popup.hpp | 11 ++++++----- src/desktop/Subsurface.cpp | 14 ++++++++------ src/desktop/Subsurface.hpp | 30 ++++++++++++++++-------------- src/desktop/Window.cpp | 12 +++++++----- src/main.cpp | 2 ++ src/render/Renderer.cpp | 4 ++-- 9 files changed, 66 insertions(+), 54 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3f9126b7..43efdac1 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -571,7 +571,6 @@ void CCompositor::cleanup() { g_pLayoutManager.reset(); g_pHyprError.reset(); g_pConfigManager.reset(); - g_pAnimationManager.reset(); g_pKeybindManager.reset(); g_pHookSystem.reset(); g_pWatchdog.reset(); diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index dd30aa7c..c2b07c5d 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -31,9 +31,10 @@ PHLLS CLayerSurface::create(SP resource) { pLS->szNamespace = resource->layerNamespace; - pLS->layer = resource->current.layer; - pLS->popupHead = makeUnique(pLS); - pLS->monitor = pMonitor; + pLS->layer = resource->current.layer; + pLS->popupHead = makeUnique(pLS); + pLS->popupHead->m_pSelf = pLS->popupHead; + pLS->monitor = pMonitor; pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS); pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace); @@ -331,7 +332,7 @@ void CLayerSurface::onCommit() { nullptr); if (!WASLASTFOCUS && popupHead) { popupHead->breadthfirst( - [&WASLASTFOCUS](CPopup* popup, void* data) { + [&WASLASTFOCUS](WP popup, void* data) { WASLASTFOCUS = WASLASTFOCUS || (popup->m_pWLSurface && g_pSeatManager->state.keyboardFocus == popup->m_pWLSurface->resource()); }, nullptr); @@ -576,7 +577,7 @@ int CLayerSurface::popupsCount() { return 0; int no = -1; // we have one dummy - popupHead->breadthfirst([](CPopup* p, void* data) { *(int*)data += 1; }, &no); + popupHead->breadthfirst([](WP p, void* data) { *(int*)data += 1; }, &no); return no; } diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 831619a5..0c7c72a4 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -20,7 +20,8 @@ CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) { initAllSignals(); } -CPopup::CPopup(SP popup, CPopup* pOwner) : m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) { +CPopup::CPopup(SP popup, WP pOwner) : + m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) { m_pWLSurface = CWLSurface::create(); m_pWLSurface->assign(popup->surface->surface.lock(), this); @@ -58,7 +59,8 @@ void CPopup::initAllSignals() { } void CPopup::onNewPopup(SP popup) { - const auto POPUP = m_vChildren.emplace_back(makeShared(popup, this)).get(); + const auto& POPUP = m_vChildren.emplace_back(makeShared(popup, m_pSelf)); + POPUP->m_pSelf = POPUP; Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP); } @@ -89,7 +91,8 @@ void CPopup::onMap() { g_pInputManager->simulateMouseMovement(); - m_pSubsurfaceHead = makeUnique(this); + m_pSubsurfaceHead = makeUnique(m_pSelf); + m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead; //unconstrain(); sendScale(); @@ -126,7 +129,7 @@ void CPopup::onUnmap() { // damage all children breadthfirst( - [](CPopup* p, void* data) { + [](WP p, void* data) { if (!p->m_pResource) return; @@ -223,7 +226,7 @@ Vector2D CPopup::coordsRelativeToParent() { if (!m_pResource) return {}; - CPopup* current = this; + WP current = m_pSelf; offset -= current->m_pResource->surface->current.geometry.pos(); while (current->m_pParent && current->m_pResource) { @@ -256,7 +259,7 @@ Vector2D CPopup::t1ParentCoords() { } void CPopup::recheckTree() { - CPopup* curr = this; + WP curr = m_pSelf; while (curr->m_pParent) { curr = curr->m_pParent; } @@ -296,17 +299,17 @@ bool CPopup::visible() { return false; } -void CPopup::bfHelper(std::vector const& nodes, std::function fn, void* data) { +void CPopup::bfHelper(std::vector> const& nodes, std::function, void*)> fn, void* data) { for (auto const& n : nodes) { fn(n, data); } - std::vector nodes2; + std::vector> nodes2; nodes2.reserve(nodes.size() * 2); for (auto const& n : nodes) { for (auto const& c : n->m_vChildren) { - nodes2.push_back(c.get()); + nodes2.push_back(c->m_pSelf); } } @@ -314,15 +317,15 @@ void CPopup::bfHelper(std::vector const& nodes, std::function fn, void* data) { - std::vector popups; - popups.push_back(this); +void CPopup::breadthfirst(std::function, void*)> fn, void* data) { + std::vector> popups; + popups.push_back(m_pSelf); bfHelper(popups, fn, data); } -CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) { - std::vector popups; - breadthfirst([](CPopup* popup, void* data) { ((std::vector*)data)->push_back(popup); }, &popups); +WP CPopup::at(const Vector2D& globalCoords, bool allowsInput) { + std::vector> popups; + breadthfirst([](WP popup, void* data) { ((std::vector>*)data)->push_back(popup); }, &popups); for (auto const& p : popups | std::views::reverse) { if (!p->m_pResource || !p->m_bMapped) @@ -344,5 +347,5 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) { } } - return nullptr; + return {}; } diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 2b7b4e82..6051f7eb 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -14,7 +14,7 @@ class CPopup { CPopup(PHLLS pOwner); // real nodes - CPopup(SP popup, CPopup* pOwner); + CPopup(SP popup, WP pOwner); ~CPopup(); @@ -36,11 +36,12 @@ class CPopup { bool visible(); // will also loop over this node - void breadthfirst(std::function fn, void* data); - CPopup* at(const Vector2D& globalCoords, bool allowsInput = false); + void breadthfirst(std::function, void*)> fn, void* data); + WP at(const Vector2D& globalCoords, bool allowsInput = false); // SP m_pWLSurface; + WP m_pSelf; bool m_bMapped = false; private: @@ -49,7 +50,7 @@ class CPopup { PHLLSREF m_pLayerOwner; // T2 owners - CPopup* m_pParent = nullptr; + WP m_pParent; WP m_pResource; @@ -81,5 +82,5 @@ class CPopup { Vector2D localToGlobal(const Vector2D& rel); Vector2D t1ParentCoords(); - static void bfHelper(std::vector const& nodes, std::function fn, void* data); + static void bfHelper(std::vector> const& nodes, std::function, void*)> fn, void* data); }; diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index eb18ee39..5657cb39 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -12,7 +12,7 @@ CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) { initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); } -CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) { +CSubsurface::CSubsurface(WP pOwner) : m_pPopupParent(pOwner) { initSignals(); initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); } @@ -24,7 +24,7 @@ CSubsurface::CSubsurface(SP pSubsurface, PHLWINDOW pOwner initExistingSubsurfaces(pSubsurface->surface.lock()); } -CSubsurface::CSubsurface(SP pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) { +CSubsurface::CSubsurface(SP pSubsurface, WP pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) { m_pWLSurface = CWLSurface::create(); m_pWLSurface->assign(pSubsurface->surface.lock(), this); initSignals(); @@ -132,16 +132,18 @@ void CSubsurface::onDestroy() { } void CSubsurface::onNewSubsurface(SP pSubsurface) { - CSubsurface* PSUBSURFACE = nullptr; + WP PSUBSURFACE; if (!m_pWindowParent.expired()) - PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pWindowParent.lock())).get(); + PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pWindowParent.lock())); else if (m_pPopupParent) - PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pPopupParent)).get(); + PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pPopupParent)); + + PSUBSURFACE->m_pSelf = PSUBSURFACE; ASSERT(PSUBSURFACE); - PSUBSURFACE->m_pParent = this; + PSUBSURFACE->m_pParent = PSUBSURFACE; } void CSubsurface::onMap() { diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index aacbad91..f16a11ea 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -11,28 +11,30 @@ class CSubsurface { public: // root dummy nodes CSubsurface(PHLWINDOW pOwner); - CSubsurface(CPopup* pOwner); + CSubsurface(WP pOwner); // real nodes CSubsurface(SP pSubsurface, PHLWINDOW pOwner); - CSubsurface(SP pSubsurface, CPopup* pOwner); + CSubsurface(SP pSubsurface, WP pOwner); ~CSubsurface(); - Vector2D coordsRelativeToParent(); - Vector2D coordsGlobal(); + Vector2D coordsRelativeToParent(); + Vector2D coordsGlobal(); - Vector2D size(); + Vector2D size(); - void onCommit(); - void onDestroy(); - void onNewSubsurface(SP pSubsurface); - void onMap(); - void onUnmap(); + void onCommit(); + void onDestroy(); + void onNewSubsurface(SP pSubsurface); + void onMap(); + void onUnmap(); - bool visible(); + bool visible(); - void recheckDamageForSubsurfaces(); + void recheckDamageForSubsurfaces(); + + WP m_pSelf; private: struct { @@ -48,10 +50,10 @@ class CSubsurface { Vector2D m_vLastSize = {}; // if nullptr, means it's a dummy node - CSubsurface* m_pParent = nullptr; + WP m_pParent; PHLWINDOWREF m_pWindowParent; - CPopup* m_pPopupParent = nullptr; + WP m_pPopupParent; std::vector> m_vChildren; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index b1b3c66c..9dcdb385 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -154,7 +154,7 @@ SBoxExtents CWindow::getFullWindowExtents() { CBox surfaceExtents = {0, 0, 0, 0}; // TODO: this could be better, perhaps make a getFullWindowRegion? m_pPopupHead->breadthfirst( - [](CPopup* popup, void* data) { + [](WP popup, void* data) { if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource()) return; @@ -569,8 +569,10 @@ void CWindow::onMap() { if (m_bIsX11) return; - m_pSubsurfaceHead = makeUnique(m_pSelf.lock()); - m_pPopupHead = makeUnique(m_pSelf.lock()); + m_pSubsurfaceHead = makeUnique(m_pSelf.lock()); + m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead; + m_pPopupHead = makeUnique(m_pSelf.lock()); + m_pPopupHead->m_pSelf = m_pPopupHead; } void CWindow::onBorderAngleAnimEnd(WP pav) { @@ -847,7 +849,7 @@ bool CWindow::hasPopupAt(const Vector2D& pos) { if (m_bIsX11) return false; - CPopup* popup = m_pPopupHead->at(pos); + auto popup = m_pPopupHead->at(pos); return popup && popup->m_pWLSurface->resource(); } @@ -1289,7 +1291,7 @@ int CWindow::popupsCount() { return 0; int no = -1; - m_pPopupHead->breadthfirst([](CPopup* p, void* d) { *((int*)d) += 1; }, &no); + m_pPopupHead->breadthfirst([](WP p, void* d) { *((int*)d) += 1; }, &no); return no; } diff --git a/src/main.cpp b/src/main.cpp index d244f10f..464ed978 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -181,6 +181,8 @@ int main(int argc, char** argv) { g_pCompositor->cleanup(); + g_pCompositor.reset(); + Debug::log(LOG, "Hyprland has reached the end."); return EXIT_SUCCESS; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index d82d79d1..f897379a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -615,7 +615,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe renderdata.surfaceCounter = 0; pWindow->m_pPopupHead->breadthfirst( - [this, &renderdata](CPopup* popup, void* data) { + [this, &renderdata](WP popup, void* data) { if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource() || !popup->m_bMapped) return; const auto pos = popup->coordsRelativeToParent(); @@ -718,7 +718,7 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim renderdata.surfaceCounter = 0; if (popups) { pLayer->popupHead->breadthfirst( - [this, &renderdata](CPopup* popup, void* data) { + [this, &renderdata](WP popup, void* data) { if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource() || !popup->m_bMapped) return; From 4abf9155ee67ee09116948b1d9efef58c08697d9 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:00:52 +0000 Subject: [PATCH 0178/1444] window: only set m_iMonitorMovedFrom when the workspace is visible (#9178) --- src/desktop/Window.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 9dcdb385..e59a8d4e 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -422,10 +422,12 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { const auto OLDWORKSPACE = m_pWorkspace; - m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F); - *m_fMovingToWorkspaceAlpha = 0.F; - m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); - m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; + if (OLDWORKSPACE->isVisible()) { + m_fMovingToWorkspaceAlpha->setValueAndWarp(1.F); + *m_fMovingToWorkspaceAlpha = 0.F; + m_fMovingToWorkspaceAlpha->setCallbackOnEnd([this](auto) { m_iMonitorMovedFrom = -1; }); + m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->monitorID() : -1; + } m_pWorkspace = pWorkspace; From 74d0f34cf396f4fc41ee98b000e7d0a4e277c066 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 14:25:49 +0000 Subject: [PATCH 0179/1444] pointer: always scale the cpu cursor to the right size fixes #9003 --- src/managers/PointerManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index df145f6d..5fdfa553 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -507,6 +507,10 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->transform; + // we need to scale the cursor to the right size, because it might not be (esp with XCursor) + const auto SCALE = texture->m_vSize / (currentCursorImage.size / currentCursorImage.scale * state->monitor->scale); + cairo_matrix_scale(&matrixPre, SCALE.x, SCALE.y); + if (TR) { cairo_matrix_rotate(&matrixPre, M_PI_2 * (double)TR); From 16aeb24bc1395b46d675ec3522ed452e487f5b69 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 14:40:42 +0000 Subject: [PATCH 0180/1444] core: make persistent workspaces always follow the config instead of just staying after open, they will now be enforced on their respective monitors fixes #8769 --- src/Compositor.cpp | 43 ++++++++++++++++++++++++++++++++++++ src/Compositor.hpp | 2 ++ src/config/ConfigManager.cpp | 8 +++++++ src/config/ConfigManager.hpp | 1 + src/helpers/Monitor.cpp | 2 ++ 5 files changed, 56 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 43efdac1..3421c314 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -3024,3 +3024,46 @@ bool CCompositor::shouldChangePreferredImageDescription() { Debug::log(WARN, "FIXME: color management protocol is enabled and outputs changed, check preferred image description changes"); return false; } + +void CCompositor::ensurePersistentWorkspacesPresent(const std::vector& rules) { + for (const auto& rule : rules) { + if (!rule.isPersistent) + continue; + + const auto PMONITOR = getMonitorFromString(rule.monitor); + + if (!PMONITOR) { + Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve monitor for {}, skipping", rule.monitor); + continue; + } + + WORKSPACEID id = rule.workspaceId; + std::string wsname = rule.workspaceName; + if (id == WORKSPACE_INVALID) { + const auto R = getWorkspaceIDNameFromString(rule.workspaceString); + id = R.id; + wsname = R.name; + } + + if (id == WORKSPACE_INVALID) { + Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve id for workspace {}", rule.workspaceString); + continue; + } + + if (const auto PWORKSPACE = getWorkspaceByID(id); PWORKSPACE) { + if (PWORKSPACE->m_pMonitor == PMONITOR) { + Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} already on {}", rule.workspaceString, PMONITOR->szName); + continue; + } + + Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} not on {}, moving", rule.workspaceString, PMONITOR->szName); + moveWorkspaceToMonitor(PWORKSPACE, PMONITOR); + continue; + } + + createNewWorkspace(id, PMONITOR ? PMONITOR : m_pLastMonitor.lock(), wsname, false); + } + + // cleanup old + sanityCheckWorkspaces(); +} diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 295878df..e55d7e1e 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -15,6 +15,7 @@ #include class CWLSurfaceResource; +struct SWorkspaceRule; enum eManagersInitStage : uint8_t { STAGE_PRIORITY = 0, @@ -151,6 +152,7 @@ class CCompositor { void setPreferredTransformForSurface(SP pSurface, wl_output_transform transform); void updateSuspendedStates(); void onNewMonitor(SP output); + void ensurePersistentWorkspacesPresent(const std::vector& rules); SImageDescription getPreferredImageDescription(); bool shouldChangePreferredImageDescription(); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index fd4783da..93289bf7 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1034,6 +1034,10 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { // update plugins handlePluginLoads(); + // update persistent workspaces + if (!isFirstLaunch) + ensurePersistentWorkspacesPresent(); + EMIT_HOOK_EVENT("configReloaded", nullptr); if (g_pEventManager) g_pEventManager->postEvent(SHyprIPCEvent{"configreloaded", ""}); @@ -2830,3 +2834,7 @@ std::string SConfigOptionDescription::jsonify() const { return json; } + +void CConfigManager::ensurePersistentWorkspacesPresent() { + g_pCompositor->ensurePersistentWorkspacesPresent(m_vWorkspaceRules); +} diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 564c1ebf..ae0ba759 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -169,6 +169,7 @@ class CConfigManager { std::vector> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false); std::vector> getMatchingRules(PHLLS); + void ensurePersistentWorkspacesPresent(); const std::vector& getAllDescriptions(); diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 1f00e4ad..6fcaeeee 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -51,6 +51,8 @@ void CMonitor::onConnect(bool noRule) { EMIT_HOOK_EVENT("preMonitorAdded", self.lock()); CScopeGuard x = {[]() { g_pCompositor->arrangeMonitors(); }}; + g_pEventLoopManager->doLater([] { g_pConfigManager->ensurePersistentWorkspacesPresent(); }); + if (output->supportsExplicit) { inTimeline = CSyncTimeline::create(output->getBackend()->drmFD()); outTimeline = CSyncTimeline::create(output->getBackend()->drmFD()); From e9510115039e7ae9fcf2778e8455e7beed3424ea Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 15:05:34 +0000 Subject: [PATCH 0181/1444] renderer/internal: stop using box pointers in favor of const refs --- src/debug/HyprDebugOverlay.cpp | 4 +- src/debug/HyprNotificationOverlay.cpp | 6 +- src/desktop/LayerSurface.cpp | 10 +- src/desktop/Popup.cpp | 10 +- src/desktop/Subsurface.cpp | 10 +- src/events/Windows.cpp | 5 +- src/helpers/Monitor.cpp | 8 +- src/helpers/Monitor.hpp | 4 +- src/hyprerror/HyprError.cpp | 4 +- src/layout/IHyprLayout.cpp | 8 +- src/managers/AnimationManager.cpp | 8 +- src/managers/PointerManager.cpp | 6 +- src/managers/XWaylandManager.cpp | 24 ++- src/managers/XWaylandManager.hpp | 2 +- src/managers/input/InputMethodPopup.cpp | 2 +- src/protocols/AlphaModifier.cpp | 2 +- src/protocols/HyprlandSurface.cpp | 2 +- src/protocols/Screencopy.cpp | 4 +- src/protocols/core/DataDevice.cpp | 2 +- src/render/OpenGL.cpp | 182 ++++++++---------- src/render/OpenGL.hpp | 130 ++++++------- src/render/Renderer.cpp | 25 ++- src/render/Renderer.hpp | 2 +- .../decorations/CHyprDropShadowDecoration.cpp | 16 +- .../decorations/CHyprDropShadowDecoration.hpp | 2 +- .../decorations/CHyprGroupBarDecoration.cpp | 2 +- src/render/pass/BorderPassElement.cpp | 4 +- src/render/pass/Pass.cpp | 14 +- src/render/pass/RectPassElement.cpp | 4 +- src/render/pass/SurfacePassElement.cpp | 8 +- src/render/pass/TexPassElement.cpp | 2 +- src/render/pass/TextureMatteElement.cpp | 4 +- 32 files changed, 252 insertions(+), 264 deletions(-) diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp index 6e7a0407..9ea7f1bc 100644 --- a/src/debug/HyprDebugOverlay.cpp +++ b/src/debug/HyprDebugOverlay.cpp @@ -198,10 +198,10 @@ int CHyprMonitorDebugOverlay::draw(int offset) { double posX = 0, posY = 0; cairo_get_current_point(cr, &posX, &posY); - g_pHyprRenderer->damageBox(&m_wbLastDrawnBox); + g_pHyprRenderer->damageBox(m_wbLastDrawnBox); m_wbLastDrawnBox = {(int)g_pCompositor->m_vMonitors.front()->vecPosition.x + MARGIN_LEFT - 1, (int)g_pCompositor->m_vMonitors.front()->vecPosition.y + offset + MARGIN_TOP - 1, (int)maxTextW + 2, posY - offset - MARGIN_TOP + 2}; - g_pHyprRenderer->damageBox(&m_wbLastDrawnBox); + g_pHyprRenderer->damageBox(m_wbLastDrawnBox); return posY - offset; } diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp index 66c68d08..4081af84 100644 --- a/src/debug/HyprNotificationOverlay.cpp +++ b/src/debug/HyprNotificationOverlay.cpp @@ -26,7 +26,7 @@ CHyprNotificationOverlay::CHyprNotificationOverlay() { if (m_vNotifications.size() == 0) return; - g_pHyprRenderer->damageBox(&m_bLastDamage); + g_pHyprRenderer->damageBox(m_bLastDamage); }); m_pTexture = makeShared(); @@ -225,8 +225,8 @@ void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) { CBox damage = drawNotifications(pMonitor); - g_pHyprRenderer->damageBox(&damage); - g_pHyprRenderer->damageBox(&m_bLastDamage); + g_pHyprRenderer->damageBox(damage); + g_pHyprRenderer->damageBox(m_bLastDamage); g_pCompositor->scheduleFrameForMonitor(pMonitor); diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index c2b07c5d..e2d0177b 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -115,7 +115,7 @@ void CLayerSurface::onDestroy() { // and damage CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); + g_pHyprRenderer->damageBox(geomFixed); } readyToDelete = true; @@ -179,7 +179,7 @@ void CLayerSurface::onMap() { position = Vector2D(geometry.x, geometry.y); CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); + g_pHyprRenderer->damageBox(geomFixed); const bool FULLSCREEN = PMONITOR->activeWorkspace && PMONITOR->activeWorkspace->m_bHasFullscreenWindow && PMONITOR->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN; startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS)); @@ -240,11 +240,11 @@ void CLayerSurface::onUnmap() { g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock()); CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); + g_pHyprRenderer->damageBox(geomFixed); geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.size.x, (int)layerSurface->surface->current.size.y}; - g_pHyprRenderer->damageBox(&geomFixed); + g_pHyprRenderer->damageBox(geomFixed); g_pInputManager->simulateMouseMovement(); @@ -275,7 +275,7 @@ void CLayerSurface::onCommit() { g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd CBox geomFixed = {geometry.x, geometry.y, geometry.width, geometry.height}; - g_pHyprRenderer->damageBox(&geomFixed); + g_pHyprRenderer->damageBox(geomFixed); if (layerSurface->current.committed != 0) { if (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_LAYER) { diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 0c7c72a4..93a810ff 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -85,7 +85,7 @@ void CPopup::onMap() { CBox box = m_pWLSurface->resource()->extends(); box.translate(COORDS).expand(4); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); m_vLastPos = coordsRelativeToParent(); @@ -120,7 +120,7 @@ void CPopup::onUnmap() { CBox box = m_pWLSurface->resource()->extends(); box.translate(COORDS).expand(4); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); m_pSubsurfaceHead.reset(); @@ -134,7 +134,7 @@ void CPopup::onUnmap() { return; auto box = CBox{p->coordsGlobal(), p->size()}; - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); }, nullptr); @@ -173,10 +173,10 @@ void CPopup::onCommit(bool ignoreSiblings) { if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) { CBox box = {localToGlobal(m_vLastPos), m_vLastSize}; - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); m_vLastSize = m_pResource->surface->surface->current.size; box = {COORDS, m_vLastSize}; - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); m_vLastPos = COORDSLOCAL; } diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 5657cb39..a68cf8f3 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -103,10 +103,10 @@ void CSubsurface::onCommit() { if (m_vLastSize != m_pWLSurface->resource()->current.size) { // TODO: fix this // CBox box{COORDS, m_vLastSize}; - // g_pHyprRenderer->damageBox(&box); + // g_pHyprRenderer->damageBox(box); // m_vLastSize = m_pWLSurface->resource()->current.size; // box = {COORDS, m_vLastSize}; - // g_pHyprRenderer->damageBox(&box); + // g_pHyprRenderer->damageBox(box); CBox box; if (m_pPopupParent) @@ -114,7 +114,7 @@ void CSubsurface::onCommit() { else if (m_pWindowParent) box = m_pWindowParent->getWindowMainSurfaceBox(); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); } } @@ -152,7 +152,7 @@ void CSubsurface::onMap() { const auto COORDS = coordsGlobal(); CBox box{COORDS, m_vLastSize}; box.expand(4); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); if (!m_pWindowParent.expired()) m_pWindowParent->updateSurfaceScaleTransformDetails(); @@ -162,7 +162,7 @@ void CSubsurface::onUnmap() { const auto COORDS = coordsGlobal(); CBox box{COORDS, m_vLastSize}; box.expand(4); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus) g_pInputManager->releaseAllMouseButtons(); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 9ecf3652..f6ef9ced 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -376,9 +376,8 @@ void Events::listener_mapWindow(void* owner, void* data) { if (PWORKSPACE->m_bDefaultPseudo) { PWINDOW->m_bIsPseudotiled = true; - CBox desiredGeometry = {0}; - g_pXWaylandManager->getGeometryForWindow(PWINDOW, &desiredGeometry); - PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height); + CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(PWINDOW); + PWINDOW->m_vPseudoSize = Vector2D(desiredGeometry.width, desiredGeometry.height); } PWINDOW->updateWindowData(); diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 6fcaeeee..19d68a56 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -766,18 +766,18 @@ void CMonitor::addDamage(const pixman_region32_t* rg) { g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE); } -void CMonitor::addDamage(const CRegion* rg) { - addDamage(const_cast(rg)->pixman()); +void CMonitor::addDamage(const CRegion& rg) { + addDamage(const_cast(&rg)->pixman()); } -void CMonitor::addDamage(const CBox* box) { +void CMonitor::addDamage(const CBox& box) { static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == self) { damage.damageEntire(); g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE); } - if (damage.damage(*box)) + if (damage.damage(box)) g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE); } diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index e07d62c6..7c19b57c 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -166,8 +166,8 @@ class CMonitor { void onDisconnect(bool destroy = false); bool applyMonitorRule(SMonitorRule* pMonitorRule, bool force = false); void addDamage(const pixman_region32_t* rg); - void addDamage(const CRegion* rg); - void addDamage(const CBox* box); + void addDamage(const CRegion& rg); + void addDamage(const CBox& box); bool shouldSkipScheduleFrameOnMouseEvent(); void setMirror(const std::string&); bool isMirror(); diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index d14173bf..4076ed3a 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -26,7 +26,7 @@ CHyprError::CHyprError() { return; if (m_fFadeOpacity->isBeingAnimated() || m_bMonitorChanged) - g_pHyprRenderer->damageBox(&m_bDamageBox); + g_pHyprRenderer->damageBox(m_bDamageBox); }); m_pTexture = makeShared(); @@ -203,7 +203,7 @@ void CHyprError::draw() { m_bDamageBox.y = (int)PMONITOR->vecPosition.y; if (m_fFadeOpacity->isBeingAnimated() || m_bMonitorChanged) - g_pHyprRenderer->damageBox(&m_bDamageBox); + g_pHyprRenderer->damageBox(m_bDamageBox); m_bMonitorChanged = false; diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 81392be9..5e5669b8 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -14,8 +14,7 @@ #include "../managers/HookSystemManager.hpp" void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) { - CBox desiredGeometry = {}; - g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry); + CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow); if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) { const auto PMONITOR = pWindow->m_pMonitor.lock(); @@ -91,9 +90,8 @@ void IHyprLayout::onWindowRemovedFloating(PHLWINDOW pWindow) { void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) { - CBox desiredGeometry = {0}; - g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry); - const auto PMONITOR = pWindow->m_pMonitor.lock(); + CBox desiredGeometry = g_pXWaylandManager->getGeometryForWindow(pWindow); + const auto PMONITOR = pWindow->m_pMonitor.lock(); if (pWindow->m_bIsX11) { Vector2D xy = {desiredGeometry.x, desiredGeometry.y}; diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 964f7cfa..5be7aa33 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -41,7 +41,7 @@ CHyprAnimationManager::CHyprAnimationManager() { } template -void updateVariable(CAnimatedVariable& av, const float POINTY, bool warp = false) { +static void updateVariable(CAnimatedVariable& av, const float POINTY, bool warp = false) { if (warp || av.value() == av.goal()) { av.warp(); return; @@ -51,7 +51,7 @@ void updateVariable(CAnimatedVariable& av, const float POINTY, bool war av.value() = av.begun() + DELTA * POINTY; } -void updateColorVariable(CAnimatedVariable& av, const float POINTY, bool warp) { +static void updateColorVariable(CAnimatedVariable& av, const float POINTY, bool warp) { if (warp || av.value() == av.goal()) { av.warp(); return; @@ -137,7 +137,7 @@ static void handleUpdate(CAnimatedVariable& av, bool warp) { // "some fucking layers miss 1 pixel???" -- vaxry CBox expandBox = CBox{PLAYER->realPosition->value(), PLAYER->realSize->value()}; expandBox.expand(5); - g_pHyprRenderer->damageBox(&expandBox); + g_pHyprRenderer->damageBox(expandBox); PMONITOR = g_pCompositor->getMonitorFromVector(PLAYER->realPosition->goal() + PLAYER->realSize->goal() / 2.F); if (!PMONITOR) @@ -180,7 +180,7 @@ static void handleUpdate(CAnimatedVariable& av, bool warp) { // some fucking layers miss 1 pixel??? CBox expandBox = CBox{PLAYER->realPosition->value(), PLAYER->realSize->value()}; expandBox.expand(5); - g_pHyprRenderer->damageBox(&expandBox); + g_pHyprRenderer->damageBox(expandBox); } break; } diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 5fdfa553..48ef5e16 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -566,7 +566,7 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->szName, currentCursorImage.size, cursorSize, currentCursorImage.scale, state->monitor->scale, xbox.size()); - g_pHyprOpenGL->renderTexture(texture, &xbox, 1.F); + g_pHyprOpenGL->renderTexture(texture, xbox, 1.F); g_pHyprOpenGL->end(); glFlush(); @@ -730,7 +730,7 @@ void CPointerManager::damageIfSoftware() { continue; if ((mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors()) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) { - g_pHyprRenderer->damageBox(&b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent()); + g_pHyprRenderer->damageBox(b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent()); break; } } @@ -1143,7 +1143,7 @@ void CPointerManager::damageCursor(PHLMONITOR pMonitor) { if (b.empty()) return; - g_pHyprRenderer->damageBox(&b); + g_pHyprRenderer->damageBox(b); return; } diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index ea2a47ea..f103266d 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -76,9 +76,11 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { pWindow->m_pWorkspace->m_pLastFocusedWindow = pWindow; } -void CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow, CBox* pbox) { +CBox CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow) { if (!pWindow) - return; + return {}; + + CBox box; if (pWindow->m_bIsX11) { const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get(); @@ -86,24 +88,26 @@ void CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow, CBox* pbox) { if (SIZEHINTS && !pWindow->isX11OverrideRedirect()) { // WM_SIZE_HINTS' x,y,w,h is deprecated it seems. // Source: https://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#wm_normal_hints_property - pbox->x = pWindow->m_pXWaylandSurface->geometry.x; - pbox->y = pWindow->m_pXWaylandSurface->geometry.y; + box.x = pWindow->m_pXWaylandSurface->geometry.x; + box.y = pWindow->m_pXWaylandSurface->geometry.y; constexpr int ICCCM_USSize = 0x2; constexpr int ICCCM_PSize = 0x8; if ((SIZEHINTS->flags & ICCCM_USSize) || (SIZEHINTS->flags & ICCCM_PSize)) { - pbox->w = SIZEHINTS->base_width; - pbox->h = SIZEHINTS->base_height; + box.w = SIZEHINTS->base_width; + box.h = SIZEHINTS->base_height; } else { - pbox->w = pWindow->m_pXWaylandSurface->geometry.w; - pbox->h = pWindow->m_pXWaylandSurface->geometry.h; + box.w = pWindow->m_pXWaylandSurface->geometry.w; + box.h = pWindow->m_pXWaylandSurface->geometry.h; } } else - *pbox = pWindow->m_pXWaylandSurface->geometry; + box = pWindow->m_pXWaylandSurface->geometry; } else if (pWindow->m_pXDGSurface) - *pbox = pWindow->m_pXDGSurface->current.geometry; + box = pWindow->m_pXDGSurface->current.geometry; + + return box; } void CHyprXWaylandManager::sendCloseWindow(PHLWINDOW pWindow) { diff --git a/src/managers/XWaylandManager.hpp b/src/managers/XWaylandManager.hpp index edbdd243..e4f1e17a 100644 --- a/src/managers/XWaylandManager.hpp +++ b/src/managers/XWaylandManager.hpp @@ -15,7 +15,7 @@ class CHyprXWaylandManager { SP getWindowSurface(PHLWINDOW); void activateSurface(SP, bool); void activateWindow(PHLWINDOW, bool); - void getGeometryForWindow(PHLWINDOW, CBox*); + CBox getGeometryForWindow(PHLWINDOW); void sendCloseWindow(PHLWINDOW); void setWindowFullscreen(PHLWINDOW, bool); bool shouldBeFloated(PHLWINDOW, bool pending = false); diff --git a/src/managers/input/InputMethodPopup.cpp b/src/managers/input/InputMethodPopup.cpp index 8c55416b..db08c026 100644 --- a/src/managers/input/InputMethodPopup.cpp +++ b/src/managers/input/InputMethodPopup.cpp @@ -61,7 +61,7 @@ void CInputPopup::damageEntire() { return; } CBox box = globalBox(); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); } void CInputPopup::damageSurface() { diff --git a/src/protocols/AlphaModifier.cpp b/src/protocols/AlphaModifier.cpp index e8766405..60037632 100644 --- a/src/protocols/AlphaModifier.cpp +++ b/src/protocols/AlphaModifier.cpp @@ -38,7 +38,7 @@ void CAlphaModifier::setResource(SP resource) { auto box = surface->getSurfaceBoxGlobal(); if (box.has_value()) - g_pHyprRenderer->damageBox(&*box); + g_pHyprRenderer->damageBox(*box); if (!m_pResource) PROTO::alphaModifier->destroyAlphaModifier(this); diff --git a/src/protocols/HyprlandSurface.cpp b/src/protocols/HyprlandSurface.cpp index e3716f10..8b65f0fa 100644 --- a/src/protocols/HyprlandSurface.cpp +++ b/src/protocols/HyprlandSurface.cpp @@ -60,7 +60,7 @@ void CHyprlandSurface::setResource(SP resource) { auto box = surface->getSurfaceBoxGlobal(); if (box.has_value()) - g_pHyprRenderer->damageBox(&*box); + g_pHyprRenderer->damageBox(*box); if (!m_pResource) PROTO::hyprlandSurface->destroySurface(this); diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index e0e3a559..e086cc76 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -214,7 +214,7 @@ bool CScreencopyFrame::copyDmabuf() { .transform(wlTransformToHyprutils(invertTransform(pMonitor->transform)), pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(false); - g_pHyprOpenGL->renderTexture(TEXTURE, &monbox, 1); + g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1); g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); @@ -247,7 +247,7 @@ bool CScreencopyFrame::copyShm() { CBox monbox = CBox{0, 0, pMonitor->vecTransformedSize.x, pMonitor->vecTransformedSize.y}.translate({-box.x, -box.y}); g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(false); - g_pHyprOpenGL->renderTexture(TEXTURE, &monbox, 1); + g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1); g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 36437dd4..e17b5612 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -806,7 +806,7 @@ void CWLDataDeviceProtocol::renderDND(PHLMONITOR pMonitor, timespec* when) { g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); box = CBox{POS, dnd.dndSurface->current.size}.translate(g_pPointerManager->cursorSizeLogical() / 2.F).expand(5); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); dnd.dndSurface->frame(when); } diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 0fe9565f..f0b2f447 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -935,15 +935,15 @@ void CHyprOpenGLImpl::end() { // copy the damaged areas into the mirror buffer // we can't use the offloadFB for mirroring, as it contains artifacts from blurring if (!m_RenderData.pMonitor->mirrors.empty() && !m_bFakeFrame) - saveBufferForMirror(&monbox); + saveBufferForMirror(monbox); m_RenderData.outFB->bind(); blend(false); if (m_sFinalScreenShader.program < 1 && !g_pHyprRenderer->m_bCrashingInProgress) - renderTexturePrimitive(m_RenderData.pCurrentMonData->offloadFB.getTexture(), &monbox); + renderTexturePrimitive(m_RenderData.pCurrentMonData->offloadFB.getTexture(), monbox); else - renderTexture(m_RenderData.pCurrentMonData->offloadFB.getTexture(), &monbox, 1.f); + renderTexture(m_RenderData.pCurrentMonData->offloadFB.getTexture(), monbox, 1.f); blend(true); @@ -1214,7 +1214,7 @@ void CHyprOpenGLImpl::clear(const CHyprColor& color) { } } - scissor((CBox*)nullptr); + scissor(nullptr); } void CHyprOpenGLImpl::blend(bool enabled) { @@ -1227,22 +1227,19 @@ void CHyprOpenGLImpl::blend(bool enabled) { m_bBlend = enabled; } -void CHyprOpenGLImpl::scissor(const CBox* pBox, bool transform) { +void CHyprOpenGLImpl::scissor(const CBox& originalBox, bool transform) { RASSERT(m_RenderData.pMonitor, "Tried to scissor without begin()!"); - if (!pBox) { - glDisable(GL_SCISSOR_TEST); + if (transform) { + CBox box = originalBox; + const auto TR = wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)); + box.transform(TR, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); + glScissor(box.x, box.y, box.width, box.height); + glEnable(GL_SCISSOR_TEST); return; } - CBox newBox = *pBox; - - if (transform) { - const auto TR = wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)); - newBox.transform(TR, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); - } - - glScissor(newBox.x, newBox.y, newBox.width, newBox.height); + glScissor(originalBox.x, originalBox.y, originalBox.width, originalBox.height); glEnable(GL_SCISSOR_TEST); } @@ -1256,32 +1253,32 @@ void CHyprOpenGLImpl::scissor(const pixman_box32* pBox, bool transform) { CBox newBox = {pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1}; - scissor(&newBox, transform); + scissor(newBox, transform); } void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h, bool transform) { CBox box = {x, y, w, h}; - scissor(&box, transform); + scissor(box, transform); } -void CHyprOpenGLImpl::renderRect(CBox* box, const CHyprColor& col, int round, float roundingPower) { +void CHyprOpenGLImpl::renderRect(const CBox& box, const CHyprColor& col, int round, float roundingPower) { if (!m_RenderData.damage.empty()) renderRectWithDamage(box, col, m_RenderData.damage, round, roundingPower); } -void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int round, float roundingPower, float blurA, bool xray) { +void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col, int round, float roundingPower, float blurA, bool xray) { if (m_RenderData.damage.empty()) return; CRegion damage{m_RenderData.damage}; - damage.intersect(*box); + damage.intersect(box); CFramebuffer* POUTFB = xray ? &m_RenderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(blurA, &damage); m_RenderData.currentFB->bind(); // make a stencil for rounded corners to work with blur - scissor((CBox*)nullptr); // allow the entire window and stencil to render + scissor(nullptr); // allow the entire window and stencil to render glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); @@ -1302,7 +1299,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r m_bEndFrame = true; // fix transformed const auto SAVEDRENDERMODIF = m_RenderData.renderModif; m_RenderData.renderModif = {}; // fix shit - renderTextureInternalWithDamage(POUTFB->getTexture(), &MONITORBOX, blurA, damage, 0, 2.0f, false, false, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), MONITORBOX, blurA, damage, 0, 2.0f, false, false, false); m_bEndFrame = false; m_RenderData.renderModif = SAVEDRENDERMODIF; @@ -1311,22 +1308,20 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CHyprColor& col, int r glDisable(GL_STENCIL_TEST); glStencilMask(0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF); - scissor((CBox*)nullptr); + scissor(nullptr); renderRectWithDamage(box, col, m_RenderData.damage, round, roundingPower); } -void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, const CRegion& damage, int round, float roundingPower) { - RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); +void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& col, const CRegion& damage, int round, float roundingPower) { + 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()!"); TRACY_GPU_ZONE("RenderRectWithDamage"); - CBox newBox = *box; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); - box = &newBox; - Mat3x3 matrix = m_RenderData.monitorProjection.projectBox( newBox, wlTransformToHyprutils(invertTransform(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform)), newBox.rot); Mat3x3 glMatrix = m_RenderData.projection.copy().multiply(matrix); @@ -1343,7 +1338,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, con // premultiply the color as well as we don't work with straight alpha glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.color, col.r * col.a, col.g * col.a, col.b * col.a, col.a); - CBox transformedBox = *box; + CBox transformedBox = box; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); @@ -1379,27 +1374,27 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CHyprColor& col, con glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib); - scissor((CBox*)nullptr); + scissor(nullptr); } -void CHyprOpenGLImpl::renderTexture(SP tex, CBox* pBox, float alpha, int round, float roundingPower, bool discardActive, bool allowCustomUV) { +void CHyprOpenGLImpl::renderTexture(SP tex, const CBox& box, float alpha, int round, float roundingPower, bool discardActive, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.damage, round, roundingPower, discardActive, false, allowCustomUV, true); + renderTextureInternalWithDamage(tex, box, alpha, m_RenderData.damage, round, roundingPower, discardActive, false, allowCustomUV, true); - scissor((CBox*)nullptr); + scissor(nullptr); } -void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, CBox* pBox, const CRegion& damage, float alpha, int round, float roundingPower, bool discardActive, +void CHyprOpenGLImpl::renderTextureWithDamage(SP tex, const CBox& box, const CRegion& damage, float alpha, int round, float roundingPower, bool discardActive, bool allowCustomUV, SP waitTimeline, uint64_t waitPoint) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, damage, round, roundingPower, discardActive, false, allowCustomUV, true, waitTimeline, waitPoint); + renderTextureInternalWithDamage(tex, box, alpha, damage, round, roundingPower, discardActive, false, allowCustomUV, true, waitTimeline, waitPoint); - scissor((CBox*)nullptr); + scissor(nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pBox, float alpha, const CRegion& damage, int round, float roundingPower, bool discardActive, +void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, const CBox& box, float alpha, const CRegion& damage, int round, float roundingPower, bool discardActive, bool noAA, bool allowCustomUV, bool allowDim, SP waitTimeline, uint64_t waitPoint) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex->m_iTexID > 0), "Attempted to draw nullptr texture!"); @@ -1411,7 +1406,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB if (damage.empty()) return; - CBox newBox = *pBox; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); static auto PDT = CConfigValue("debug:damage_tracking"); @@ -1584,7 +1579,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, CBox* pB glBindTexture(tex->m_iTarget, 0); } -void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, CBox* pBox) { +void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, const CBox& box) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex->m_iTexID > 0), "Attempted to draw nullptr texture!"); @@ -1593,7 +1588,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, CBox* pBox) { if (m_RenderData.damage.empty()) return; - CBox newBox = *pBox; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); // get transform @@ -1627,7 +1622,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, CBox* pBox) { glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - scissor((CBox*)nullptr); + scissor(nullptr); glDisableVertexAttribArray(shader->posAttrib); glDisableVertexAttribArray(shader->texAttrib); @@ -1635,7 +1630,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, CBox* pBox) { glBindTexture(tex->m_iTarget, 0); } -void CHyprOpenGLImpl::renderTextureMatte(SP tex, CBox* pBox, CFramebuffer& matte) { +void CHyprOpenGLImpl::renderTextureMatte(SP tex, const CBox& box, CFramebuffer& matte) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex->m_iTexID > 0), "Attempted to draw nullptr texture!"); @@ -1644,7 +1639,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP tex, CBox* pBox, CFramebuf if (m_RenderData.damage.empty()) return; - CBox newBox = *pBox; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); // get transform @@ -1683,7 +1678,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP tex, CBox* pBox, CFramebuf glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - scissor((CBox*)nullptr); + scissor(nullptr); glDisableVertexAttribArray(shader->posAttrib); glDisableVertexAttribArray(shader->texAttrib); @@ -2013,8 +2008,7 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() { // make the fake dmg CRegion fakeDamage{0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - CBox wholeMonitor = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - const auto POUTFB = blurMainFramebufferWithDamage(1, &fakeDamage); + const auto POUTFB = blurMainFramebufferWithDamage(1, &fakeDamage); // render onto blurFB m_RenderData.pCurrentMonData->blurFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y, @@ -2024,7 +2018,8 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() { clear(CHyprColor(0, 0, 0, 0)); m_bEndFrame = true; // fix transformed - renderTextureInternalWithDamage(POUTFB->getTexture(), &wholeMonitor, 1, fakeDamage, 0, 2.0f, false, true, false); + renderTextureInternalWithDamage(POUTFB->getTexture(), CBox{0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}, 1, fakeDamage, 0, + 2.0f, false, true, false); m_bEndFrame = false; m_RenderData.currentFB->bind(); @@ -2072,7 +2067,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWin return false; } -void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float a, SP pSurface, int round, float roundingPower, bool blockBlurOptimization, +void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, const CBox& box, float a, SP pSurface, int round, float roundingPower, bool blockBlurOptimization, float blurA, float overallA) { RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); @@ -2082,7 +2077,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float // make a damage region for this window CRegion texDamage{m_RenderData.damage}; - texDamage.intersect(pBox->x, pBox->y, pBox->width, pBox->height); + texDamage.intersect(box.x, box.y, box.width, box.height); // While renderTextureInternalWithDamage will clip the blur as well, // clipping texDamage here allows blur generation to be optimized. @@ -2095,24 +2090,23 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float m_RenderData.renderModif.applyToRegion(texDamage); if (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) { - renderTexture(tex, pBox, a, round, roundingPower, false, true); + renderTexture(tex, box, a, round, roundingPower, false, true); return; } // amazing hack: the surface has an opaque region! CRegion inverseOpaque; - if (a >= 1.f && std::round(pSurface->current.size.x * m_RenderData.pMonitor->scale) == pBox->w && - std::round(pSurface->current.size.y * m_RenderData.pMonitor->scale) == pBox->h) { + if (a >= 1.f && std::round(pSurface->current.size.x * m_RenderData.pMonitor->scale) == box.w && std::round(pSurface->current.size.y * m_RenderData.pMonitor->scale) == box.h) { pixman_box32_t surfbox = {0, 0, pSurface->current.size.x * pSurface->current.scale, pSurface->current.size.y * pSurface->current.scale}; inverseOpaque = pSurface->current.opaque; inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->current.size.x * pSurface->current.scale, pSurface->current.size.y * pSurface->current.scale); if (inverseOpaque.empty()) { - renderTexture(tex, pBox, a, round, roundingPower, false, true); + renderTexture(tex, box, a, round, roundingPower, false, true); return; } } else { - inverseOpaque = {0, 0, pBox->width, pBox->height}; + inverseOpaque = {0, 0, box.width, box.height}; } inverseOpaque.scale(m_RenderData.pMonitor->scale); @@ -2122,7 +2116,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float CFramebuffer* POUTFB = nullptr; if (!USENEWOPTIMIZE) { - inverseOpaque.translate({pBox->x, pBox->y}); + inverseOpaque.translate(box.pos()); m_RenderData.renderModif.applyToRegion(inverseOpaque); inverseOpaque.intersect(texDamage); @@ -2133,7 +2127,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float m_RenderData.currentFB->bind(); // make a stencil for rounded corners to work with blur - scissor((CBox*)nullptr); // allow the entire window and stencil to render + scissor(nullptr); // allow the entire window and stencil to render glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); @@ -2144,9 +2138,9 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); if (USENEWOPTIMIZE && !(m_RenderData.discardMode & DISCARD_ALPHA)) - renderRect(pBox, CHyprColor(0, 0, 0, 0), round, roundingPower); + renderRect(box, CHyprColor(0, 0, 0, 0), round, roundingPower); else - renderTexture(tex, pBox, a, round, roundingPower, true, true); // discard opaque + renderTexture(tex, box, a, round, roundingPower, true, true); // discard opaque glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilFunc(GL_EQUAL, 1, 0xFF); @@ -2159,14 +2153,14 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float const auto LASTTL = m_RenderData.primarySurfaceUVTopLeft; const auto LASTBR = m_RenderData.primarySurfaceUVBottomRight; - m_RenderData.primarySurfaceUVTopLeft = pBox->pos() / MONITORBOX.size(); - m_RenderData.primarySurfaceUVBottomRight = (pBox->pos() + pBox->size()) / MONITORBOX.size(); + m_RenderData.primarySurfaceUVTopLeft = box.pos() / MONITORBOX.size(); + m_RenderData.primarySurfaceUVBottomRight = (box.pos() + box.size()) / MONITORBOX.size(); static auto PBLURIGNOREOPACITY = CConfigValue("decoration:blur:ignore_opacity"); setMonitorTransformEnabled(true); if (!USENEWOPTIMIZE) setRenderModifEnabled(false); - renderTextureInternalWithDamage(POUTFB->getTexture(), pBox, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, round, roundingPower, false, false, true); + renderTextureInternalWithDamage(POUTFB->getTexture(), box, (*PBLURIGNOREOPACITY ? blurA : a * blurA) * overallA, texDamage, round, roundingPower, false, false, true); if (!USENEWOPTIMIZE) setRenderModifEnabled(true); setMonitorTransformEnabled(false); @@ -2180,15 +2174,15 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, CBox* pBox, float // draw window glDisable(GL_STENCIL_TEST); - renderTextureInternalWithDamage(tex, pBox, a * overallA, texDamage, round, roundingPower, false, false, true, true); + renderTextureInternalWithDamage(tex, box, a * overallA, texDamage, round, roundingPower, false, false, true, true); glStencilMask(0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF); - scissor((CBox*)nullptr); + scissor(nullptr); } -void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, int round, float roundingPower, int borderSize, float a, int outerRound) { - RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); +void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& grad, int round, float roundingPower, int borderSize, float a, int outerRound) { + 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()!"); TRACY_GPU_ZONE("RenderBorder"); @@ -2196,11 +2190,9 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in if (m_RenderData.damage.empty() || (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.noBorder.valueOrDefault())) return; - CBox newBox = *box; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); - box = &newBox; - if (borderSize < 1) return; @@ -2208,10 +2200,10 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in scaledBorderSize = std::round(scaledBorderSize * m_RenderData.renderModif.combinedScale()); // adjust box - box->x -= scaledBorderSize; - box->y -= scaledBorderSize; - box->width += 2 * scaledBorderSize; - box->height += 2 * scaledBorderSize; + newBox.x -= scaledBorderSize; + newBox.y -= scaledBorderSize; + newBox.width += 2 * scaledBorderSize; + newBox.height += 2 * scaledBorderSize; round += round == 0 ? 0 : scaledBorderSize; @@ -2237,7 +2229,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.alpha, a); glUniform1i(m_RenderData.pCurrentMonData->m_shBORDER1.gradient2Length, 0); - CBox transformedBox = *box; + CBox transformedBox = box; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); @@ -2246,7 +2238,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box->width, (float)box->height); + glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box.width, (float)box.height); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower, roundingPower); @@ -2281,9 +2273,9 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in blend(BLEND); } -void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, const CGradientValueData& grad2, float lerp, int round, float roundingPower, int borderSize, float a, - int outerRound) { - RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); +void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& grad1, const CGradientValueData& grad2, float lerp, int round, float roundingPower, int borderSize, + float a, int outerRound) { + 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()!"); TRACY_GPU_ZONE("RenderBorder2"); @@ -2291,11 +2283,9 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c if (m_RenderData.damage.empty() || (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.noBorder.valueOrDefault())) return; - CBox newBox = *box; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); - box = &newBox; - if (borderSize < 1) return; @@ -2303,10 +2293,10 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c scaledBorderSize = std::round(scaledBorderSize * m_RenderData.renderModif.combinedScale()); // adjust box - box->x -= scaledBorderSize; - box->y -= scaledBorderSize; - box->width += 2 * scaledBorderSize; - box->height += 2 * scaledBorderSize; + newBox.x -= scaledBorderSize; + newBox.y -= scaledBorderSize; + newBox.width += 2 * scaledBorderSize; + newBox.height += 2 * scaledBorderSize; round += round == 0 ? 0 : scaledBorderSize; @@ -2336,7 +2326,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.alpha, a); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.gradientLerp, lerp); - CBox transformedBox = *box; + CBox transformedBox = box; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); @@ -2345,7 +2335,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box->width, (float)box->height); + glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box.width, (float)box.height); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower, roundingPower); @@ -2380,9 +2370,9 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad1, c blend(BLEND); } -void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, float roundingPower, int range, const CHyprColor& color, float a) { +void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roundingPower, int range, const CHyprColor& color, float a) { RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!"); - RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!"); + RASSERT((box.width > 0 && box.height > 0), "Tried to render shadow with width/height < 0!"); RASSERT(m_RenderData.currentWindow, "Tried to render shadow without a window!"); if (m_RenderData.damage.empty()) @@ -2390,11 +2380,9 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, float roundingPo TRACY_GPU_ZONE("RenderShadow"); - CBox newBox = *box; + CBox newBox = box; m_RenderData.renderModif.applyToBox(newBox); - box = &newBox; - static auto PSHADOWPOWER = CConfigValue("decoration:shadow:render_power"); const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4); @@ -2418,8 +2406,8 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, float roundingPo glUniform4f(m_RenderData.pCurrentMonData->m_shSHADOW.color, col.r, col.g, col.b, col.a * a); const auto TOPLEFT = Vector2D(range + round, range + round); - const auto BOTTOMRIGHT = Vector2D(box->width - (range + round), box->height - (range + round)); - const auto FULLSIZE = Vector2D(box->width, box->height); + const auto BOTTOMRIGHT = Vector2D(newBox.width - (range + round), newBox.height - (range + round)); + const auto FULLSIZE = Vector2D(newBox.width, newBox.height); // Rounded corners glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); @@ -2457,7 +2445,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, float roundingPo glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib); } -void CHyprOpenGLImpl::saveBufferForMirror(CBox* box) { +void CHyprOpenGLImpl::saveBufferForMirror(const CBox& box) { if (!m_RenderData.pCurrentMonData->monitorMirrorFB.isAllocated()) m_RenderData.pCurrentMonData->monitorMirrorFB.alloc(m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y, @@ -2850,11 +2838,11 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) { } CBox texbox = CBox{origin, m_pBackgroundTexture->m_vSize * scale}; - renderTextureInternalWithDamage(m_pBackgroundTexture, &texbox, 1.0, fakeDamage); + renderTextureInternalWithDamage(m_pBackgroundTexture, texbox, 1.0, fakeDamage); } CBox monbox = {{}, pMonitor->vecPixelSize}; - renderTextureInternalWithDamage(tex, &monbox, 1.0, fakeDamage); + renderTextureInternalWithDamage(tex, monbox, 1.0, fakeDamage); // bind back if (m_RenderData.currentFB) @@ -2936,7 +2924,7 @@ void CHyprOpenGLImpl::bindOffMain() { void CHyprOpenGLImpl::renderOffToMain(CFramebuffer* off) { CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - renderTexturePrimitive(off->getTexture(), &monbox); + renderTexturePrimitive(off->getTexture(), monbox); } void CHyprOpenGLImpl::bindBackOnMain() { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index fd84d478..1ebb0162 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -166,86 +166,86 @@ class CHyprOpenGLImpl { CHyprOpenGLImpl(); ~CHyprOpenGLImpl(); - void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); - void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); - void end(); + void begin(PHLMONITOR, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); + void beginSimple(PHLMONITOR, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); + void end(); - void renderRect(CBox*, const CHyprColor&, int round = 0, float roundingPower = 2.0f); - void renderRectWithBlur(CBox*, const CHyprColor&, int round = 0, float roundingPower = 2.0f, float blurA = 1.f, bool xray = false); - void renderRectWithDamage(CBox*, const CHyprColor&, const CRegion& damage, int round = 0, float roundingPower = 2.0f); - void renderTexture(SP, CBox*, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, bool allowCustomUV = false); - void renderTextureWithDamage(SP, CBox*, const CRegion& damage, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, - bool allowCustomUV = false, SP waitTimeline = nullptr, uint64_t waitPoint = 0); - void renderTextureWithBlur(SP, CBox*, float a, SP pSurface, int round = 0, float roundingPower = 2.0f, bool blockBlurOptimization = false, - float blurA = 1.f, float overallA = 1.f); - void renderRoundedShadow(CBox*, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0); - void renderBorder(CBox*, const CGradientValueData&, int round, float roundingPower, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); - void renderBorder(CBox*, const CGradientValueData&, const CGradientValueData&, float lerp, int round, float roundingPower, int borderSize, float a = 1.0, - int outerRound = -1 /* use round */); - void renderTextureMatte(SP tex, CBox* pBox, CFramebuffer& matte); + void renderRect(const CBox&, const CHyprColor&, int round = 0, float roundingPower = 2.0f); + void renderRectWithBlur(const CBox&, const CHyprColor&, int round = 0, float roundingPower = 2.0f, float blurA = 1.f, bool xray = false); + void renderRectWithDamage(const CBox&, const CHyprColor&, const CRegion& damage, int round = 0, float roundingPower = 2.0f); + void renderTexture(SP, const CBox&, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, bool allowCustomUV = false); + void renderTextureWithDamage(SP, const CBox&, const CRegion& damage, float a, int round = 0, float roundingPower = 2.0f, bool discardActive = false, + bool allowCustomUV = false, SP waitTimeline = nullptr, uint64_t waitPoint = 0); + void renderTextureWithBlur(SP, const CBox&, float a, SP pSurface, int round = 0, float roundingPower = 2.0f, bool blockBlurOptimization = false, + float blurA = 1.f, float overallA = 1.f); + void renderRoundedShadow(const CBox&, int round, float roundingPower, int range, const CHyprColor& color, float a = 1.0); + void renderBorder(const CBox&, const CGradientValueData&, int round, float roundingPower, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); + void renderBorder(const CBox&, const CGradientValueData&, const CGradientValueData&, float lerp, int round, float roundingPower, int borderSize, float a = 1.0, + int outerRound = -1 /* use round */); + void renderTextureMatte(SP tex, const CBox& pBox, CFramebuffer& matte); - void setMonitorTransformEnabled(bool enabled); - void setRenderModifEnabled(bool enabled); + void setMonitorTransformEnabled(bool enabled); + void setRenderModifEnabled(bool enabled); - void saveMatrix(); - void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); - void restoreMatrix(); + void saveMatrix(); + void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); + void restoreMatrix(); - void blend(bool enabled); + void blend(bool enabled); - bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); + bool shouldUseNewBlurOptimizations(PHLLS pLayer, PHLWINDOW pWindow); - void clear(const CHyprColor&); - void clearWithTex(); - void scissor(const CBox*, bool transform = true); - void scissor(const pixman_box32*, bool transform = true); - void scissor(const int x, const int y, const int w, const int h, bool transform = true); + void clear(const CHyprColor&); + void clearWithTex(); + void scissor(const CBox&, bool transform = true); + void scissor(const pixman_box32*, bool transform = true); + void scissor(const int x, const int y, const int w, const int h, bool transform = true); - void destroyMonitorResources(PHLMONITOR); + void destroyMonitorResources(PHLMONITOR); - void markBlurDirtyForMonitor(PHLMONITOR); + void markBlurDirtyForMonitor(PHLMONITOR); - void preWindowPass(); - bool preBlurQueued(); - void preRender(PHLMONITOR); + void preWindowPass(); + bool preBlurQueued(); + void preRender(PHLMONITOR); - void saveBufferForMirror(CBox*); - void renderMirrored(); + void saveBufferForMirror(const CBox&); + void renderMirrored(); - void applyScreenShader(const std::string& path); + void applyScreenShader(const std::string& path); - void bindOffMain(); - void renderOffToMain(CFramebuffer* off); - void bindBackOnMain(); + void bindOffMain(); + void renderOffToMain(CFramebuffer* off); + void bindBackOnMain(); - SP loadAsset(const std::string& file); - SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0); + SP loadAsset(const std::string& file); + SP renderText(const std::string& text, CHyprColor col, int pt, bool italic = false, const std::string& fontFamily = "", int maxWidth = 0); - void setDamage(const CRegion& damage, std::optional finalDamage = {}); + void setDamage(const CRegion& damage, std::optional finalDamage = {}); - void ensureBackgroundTexturePresence(); + void ensureBackgroundTexturePresence(); - uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); - std::vector getDRMFormats(); - EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); - SP createEGLSync(int fenceFD); - bool waitForTimelinePoint(SP timeline, uint64_t point); + uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); + std::vector getDRMFormats(); + EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); + SP createEGLSync(int fenceFD); + bool waitForTimelinePoint(SP timeline, uint64_t point); - SCurrentRenderData m_RenderData; + SCurrentRenderData m_RenderData; - GLint m_iCurrentOutputFb = 0; + GLint m_iCurrentOutputFb = 0; - int m_iGBMFD = -1; - gbm_device* m_pGbmDevice = nullptr; - EGLContext m_pEglContext = nullptr; - EGLDisplay m_pEglDisplay = nullptr; - EGLDeviceEXT m_pEglDevice = nullptr; - uint failedAssetsNo = 0; + int m_iGBMFD = -1; + gbm_device* m_pGbmDevice = nullptr; + EGLContext m_pEglContext = nullptr; + EGLDisplay m_pEglDisplay = nullptr; + EGLDeviceEXT m_pEglDevice = nullptr; + uint failedAssetsNo = 0; - bool m_bReloadScreenShader = true; // at launch it can be set + bool m_bReloadScreenShader = true; // at launch it can be set - std::map m_mWindowFramebuffers; - std::map m_mLayerFramebuffers; + std::map m_mWindowFramebuffers; + std::map m_mLayerFramebuffers; std::map m_mMonitorRenderResources; std::map m_mMonitorBGFBs; @@ -314,14 +314,14 @@ class CHyprOpenGLImpl { // returns the out FB, can be either Mirror or MirrorSwap CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage); - void renderTextureInternalWithDamage(SP, CBox* pBox, float a, const CRegion& damage, int round = 0, float roundingPower = 2.0f, bool discardOpaque = false, - bool noAA = false, bool allowCustomUV = false, bool allowDim = false, SP = nullptr, uint64_t waitPoint = 0); - void renderTexturePrimitive(SP tex, CBox* pBox); - void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size); + void renderTextureInternalWithDamage(SP, const CBox& box, float a, const CRegion& damage, int round = 0, float roundingPower = 2.0f, bool discardOpaque = false, + bool noAA = false, bool allowCustomUV = false, bool allowDim = false, SP = nullptr, uint64_t waitPoint = 0); + void renderTexturePrimitive(SP tex, const CBox& box); + void renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size); - void preBlurForCurrentMonitor(); + void preBlurForCurrentMonitor(); - bool passRequiresIntrospection(PHLMONITOR pMonitor); + bool passRequiresIntrospection(PHLMONITOR pMonitor); friend class CHyprRenderer; friend class CTexPassElement; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f897379a..41ab0b37 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -978,15 +978,15 @@ void CHyprRenderer::renderSessionLockMissing(PHLMONITOR pMonitor) { if (ANY_PRESENT) { // render image2, without instructions. Lock still "alive", unless texture dead - g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pLockDead2Texture, &monbox, ALPHA); + g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pLockDead2Texture, monbox, ALPHA); } else { // render image, with instructions. Lock is gone. - g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pLockDeadTexture, &monbox, ALPHA); + g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pLockDeadTexture, monbox, ALPHA); // also render text for the tty number if (g_pHyprOpenGL->m_pLockTtyTextTexture) { CBox texbox = {{}, g_pHyprOpenGL->m_pLockTtyTextTexture->m_vSize}; - g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pLockTtyTextTexture, &texbox, 1.F); + g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pLockTtyTextTexture, texbox, 1.F); } } @@ -1836,7 +1836,7 @@ void CHyprRenderer::damageSurface(SP pSurface, double x, dou damageBoxForEach.set(damageBox); damageBoxForEach.translate({-m->vecPosition.x, -m->vecPosition.y}).scale(m->scale); - m->addDamage(&damageBoxForEach); + m->addDamage(damageBoxForEach); } static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); @@ -1860,7 +1860,7 @@ void CHyprRenderer::damageWindow(PHLWINDOW pWindow, bool forceFull) { if (forceFull || shouldRenderWindow(pWindow, m)) { // only damage if window is rendered on monitor CBox fixedDamageBox = {windowBox.x - m->vecPosition.x, windowBox.y - m->vecPosition.y, windowBox.width, windowBox.height}; fixedDamageBox.scale(m->scale); - m->addDamage(&fixedDamageBox); + m->addDamage(fixedDamageBox); } } @@ -1878,7 +1878,7 @@ void CHyprRenderer::damageMonitor(PHLMONITOR pMonitor) { return; CBox damageBox = {0, 0, INT16_MAX, INT16_MAX}; - pMonitor->addDamage(&damageBox); + pMonitor->addDamage(damageBox); static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); @@ -1886,7 +1886,7 @@ void CHyprRenderer::damageMonitor(PHLMONITOR pMonitor) { Debug::log(LOG, "Damage: Monitor {}", pMonitor->szName); } -void CHyprRenderer::damageBox(CBox* pBox, bool skipFrameSchedule) { +void CHyprRenderer::damageBox(const CBox& box, bool skipFrameSchedule) { if (g_pCompositor->m_bUnsafeState) return; @@ -1895,21 +1895,20 @@ void CHyprRenderer::damageBox(CBox* pBox, bool skipFrameSchedule) { continue; // don't damage mirrors traditionally if (!skipFrameSchedule) { - CBox damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height}; - damageBox.scale(m->scale); - m->addDamage(&damageBox); + CBox damageBox = box.copy().translate(-m->vecPosition).scale(m->scale); + m->addDamage(damageBox); } } static auto PLOGDAMAGE = CConfigValue("debug:log_damage"); if (*PLOGDAMAGE) - Debug::log(LOG, "Damage: Box: xy: {}, {} wh: {}, {}", pBox->x, pBox->y, pBox->width, pBox->height); + Debug::log(LOG, "Damage: Box: xy: {}, {} wh: {}, {}", box.x, box.y, box.w, box.h); } void CHyprRenderer::damageBox(const int& x, const int& y, const int& w, const int& h) { CBox box = {x, y, w, h}; - damageBox(&box); + damageBox(box); } void CHyprRenderer::damageRegion(const CRegion& rg) { @@ -1936,7 +1935,7 @@ void CHyprRenderer::damageMirrorsWith(PHLMONITOR pMonitor, const CRegion& pRegio transformed.transform(wlTransformToHyprutils(pMonitor->transform), pMonitor->vecPixelSize.x * scale, pMonitor->vecPixelSize.y * scale); transformed.translate(Vector2D(monbox.x, monbox.y)); - mirror->addDamage(&transformed); + mirror->addDamage(transformed); g_pCompositor->scheduleFrameForMonitor(mirror.lock(), Aquamarine::IOutput::AQ_SCHEDULE_DAMAGE); } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 30fba3ca..e64d41c1 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -53,7 +53,7 @@ class CHyprRenderer { void arrangeLayersForMonitor(const MONITORID&); void damageSurface(SP, double, double, double scale = 1.0); void damageWindow(PHLWINDOW, bool forceFull = false); - void damageBox(CBox*, bool skipFrameSchedule = false); + void damageBox(const CBox&, bool skipFrameSchedule = false); void damageBox(const int& x, const int& y, const int& w, const int& h); void damageRegion(const CRegion&); void damageMonitor(PHLMONITOR); diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index c576b966..8a934086 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -149,7 +149,7 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { if (fullBox.width < 1 || fullBox.height < 1) return; // don't draw invisible shadows - g_pHyprOpenGL->scissor((CBox*)nullptr); + g_pHyprOpenGL->scissor(nullptr); g_pHyprOpenGL->m_RenderData.currentWindow = m_pWindow; // we'll take the liberty of using this as it should not be used rn @@ -191,18 +191,18 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { // build the matte // 10-bit formats have dogshit alpha channels, so we have to use the matte to its fullest. // first, clear region of interest with black (fully transparent) - g_pHyprOpenGL->renderRect(&fullBox, CHyprColor(0, 0, 0, 1), 0); + g_pHyprOpenGL->renderRect(fullBox, CHyprColor(0, 0, 0, 1), 0); // render white shadow with the alpha of the shadow color (otherwise we clear with alpha later and shit it to 2 bit) - drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, CHyprColor(1, 1, 1, PWINDOW->m_cRealShadowColor->value().a), a); + drawShadowInternal(fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, CHyprColor(1, 1, 1, PWINDOW->m_cRealShadowColor->value().a), a); // render black window box ("clip") - g_pHyprOpenGL->renderRect(&windowBox, CHyprColor(0, 0, 0, 1.0), (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->scale, ROUNDINGPOWER); + g_pHyprOpenGL->renderRect(windowBox, CHyprColor(0, 0, 0, 1.0), (ROUNDING + 1 /* This fixes small pixel gaps. */) * pMonitor->scale, ROUNDINGPOWER); alphaSwapFB.bind(); // alpha swap just has the shadow color. It will be the "texture" to render. - g_pHyprOpenGL->renderRect(&fullBox, PWINDOW->m_cRealShadowColor->value().stripA(), 0); + g_pHyprOpenGL->renderRect(fullBox, PWINDOW->m_cRealShadowColor->value().stripA(), 0); LASTFB->bind(); @@ -210,13 +210,13 @@ void CHyprDropShadowDecoration::render(PHLMONITOR pMonitor, float const& a) { g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(false); - g_pHyprOpenGL->renderTextureMatte(alphaSwapFB.getTexture(), &monbox, alphaFB); + g_pHyprOpenGL->renderTextureMatte(alphaSwapFB.getTexture(), monbox, alphaFB); g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); g_pHyprOpenGL->m_RenderData.damage = saveDamage; } else - drawShadowInternal(&fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, PWINDOW->m_cRealShadowColor->value(), a); + drawShadowInternal(fullBox, ROUNDING * pMonitor->scale, ROUNDINGPOWER, *PSHADOWSIZE * pMonitor->scale, PWINDOW->m_cRealShadowColor->value(), a); if (m_seExtents != m_seReportedExtents) g_pDecorationPositioner->repositionDeco(this); @@ -228,7 +228,7 @@ eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() { return DECORATION_LAYER_BOTTOM; } -void CHyprDropShadowDecoration::drawShadowInternal(CBox* box, int round, float roundingPower, int range, CHyprColor color, float a) { +void CHyprDropShadowDecoration::drawShadowInternal(const CBox& box, int round, float roundingPower, int range, CHyprColor color, float a) { static auto PSHADOWSHARP = CConfigValue("decoration:shadow:sharp"); g_pHyprOpenGL->blend(true); diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index 93fa3d1a..3b1c67c5 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -36,7 +36,7 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { Vector2D m_vLastWindowPos; Vector2D m_vLastWindowSize; - void drawShadowInternal(CBox* box, int round, float roundingPower, int range, CHyprColor color, float a); + void drawShadowInternal(const CBox& box, int round, float roundingPower, int range, CHyprColor color, float a); CBox m_bLastWindowBox = {0}; CBox m_bLastWindowBoxWithDecos = {0}; diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 7cef21b8..4e7c3cbc 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -94,7 +94,7 @@ void CHyprGroupBarDecoration::updateWindow(PHLWINDOW pWindow) { void CHyprGroupBarDecoration::damageEntire() { auto box = assignedBoxGlobal(); box.translate(m_pWindow->m_vFloatingOffset); - g_pHyprRenderer->damageBox(&box); + g_pHyprRenderer->damageBox(box); } void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { diff --git a/src/render/pass/BorderPassElement.cpp b/src/render/pass/BorderPassElement.cpp index ceeec6f3..31042c28 100644 --- a/src/render/pass/BorderPassElement.cpp +++ b/src/render/pass/BorderPassElement.cpp @@ -7,9 +7,9 @@ CBorderPassElement::CBorderPassElement(const CBorderPassElement::SBorderData& da void CBorderPassElement::draw(const CRegion& damage) { if (data.hasGrad2) - g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.grad2, data.lerp, data.round, data.roundingPower, data.borderSize, data.a, data.outerRound); + g_pHyprOpenGL->renderBorder(data.box, data.grad1, data.grad2, data.lerp, data.round, data.roundingPower, data.borderSize, data.a, data.outerRound); else - g_pHyprOpenGL->renderBorder(&data.box, data.grad1, data.round, data.roundingPower, data.borderSize, data.a, data.outerRound); + g_pHyprOpenGL->renderBorder(data.box, data.grad1, data.round, data.roundingPower, data.borderSize, data.a, data.outerRound); } bool CBorderPassElement::needsLiveBlur() { diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 5b133b7d..81b918ac 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -202,9 +202,9 @@ CRegion CRenderPass::render(const CRegion& damage_) { void CRenderPass::renderDebugData() { CBox box = {{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize}; for (const auto& rg : occludedRegions) { - g_pHyprOpenGL->renderRectWithDamage(&box, Colors::RED.modifyA(0.1F), rg); + g_pHyprOpenGL->renderRectWithDamage(box, Colors::RED.modifyA(0.1F), rg); } - g_pHyprOpenGL->renderRectWithDamage(&box, Colors::GREEN.modifyA(0.1F), totalLiveBlurRegion); + g_pHyprOpenGL->renderRectWithDamage(box, Colors::GREEN.modifyA(0.1F), totalLiveBlurRegion); std::unordered_map offsets; @@ -227,7 +227,7 @@ void CRenderPass::renderDebugData() { if (box.intersection(CBox{{}, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize}).empty()) return; - g_pHyprOpenGL->renderRectWithDamage(&box, color, CRegion{0, 0, INT32_MAX, INT32_MAX}); + g_pHyprOpenGL->renderRectWithDamage(box, color, CRegion{0, 0, INT32_MAX, INT32_MAX}); if (offsets.contains(surface.get())) box.translate(Vector2D{0.F, offsets[surface.get()]}); @@ -235,8 +235,8 @@ void CRenderPass::renderDebugData() { offsets[surface.get()] = 0; box = {box.pos(), texture->m_vSize}; - g_pHyprOpenGL->renderRectWithDamage(&box, CHyprColor{0.F, 0.F, 0.F, 0.2F}, CRegion{0, 0, INT32_MAX, INT32_MAX}, std::min(5.0, box.size().y)); - g_pHyprOpenGL->renderTexture(texture, &box, 1.F); + g_pHyprOpenGL->renderRectWithDamage(box, CHyprColor{0.F, 0.F, 0.F, 0.2F}, CRegion{0, 0, INT32_MAX, INT32_MAX}, std::min(5.0, box.size().y)); + g_pHyprOpenGL->renderTexture(texture, box, 1.F); offsets[surface.get()] += texture->m_vSize.y; }; @@ -253,7 +253,7 @@ void CRenderPass::renderDebugData() { if (tex) { box = CBox{{0.F, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.y - tex->m_vSize.y}, tex->m_vSize}.scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale); - g_pHyprOpenGL->renderTexture(tex, &box, 1.F); + g_pHyprOpenGL->renderTexture(tex, box, 1.F); } std::string passStructure; @@ -271,7 +271,7 @@ void CRenderPass::renderDebugData() { if (tex) { box = CBox{{g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.x - tex->m_vSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.y - tex->m_vSize.y}, tex->m_vSize}.scale( g_pHyprOpenGL->m_RenderData.pMonitor->scale); - g_pHyprOpenGL->renderTexture(tex, &box, 1.F); + g_pHyprOpenGL->renderTexture(tex, box, 1.F); } } diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index 55471e78..a9ab737d 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -10,9 +10,9 @@ void CRectPassElement::draw(const CRegion& damage) { return; if (data.color.a == 1.F || !data.blur) - g_pHyprOpenGL->renderRectWithDamage(&data.box, data.color, damage, data.round, data.roundingPower); + g_pHyprOpenGL->renderRectWithDamage(data.box, data.color, damage, data.round, data.roundingPower); else - g_pHyprOpenGL->renderRectWithBlur(&data.box, data.color, data.round, data.roundingPower, data.blurA, data.xray); + g_pHyprOpenGL->renderRectWithBlur(data.box, data.color, data.round, data.roundingPower, data.blurA, data.xray); } bool CRectPassElement::needsLiveBlur() { diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index b79407c8..a5d3d7c0 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -122,14 +122,14 @@ void CSurfacePassElement::draw(const CRegion& damage) { // to what we do for misaligned surfaces (blur the entire thing and then render shit without blur) if (data.surfaceCounter == 0 && !data.popup) { if (BLUR) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, roundingPower, data.blockBlurOptimization, data.fadeAlpha, OVERALL_ALPHA); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, windowBox, ALPHA, data.surface, rounding, roundingPower, data.blockBlurOptimization, data.fadeAlpha, OVERALL_ALPHA); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true); + g_pHyprOpenGL->renderTexture(TEXTURE, windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true); } else { if (BLUR && data.popup) - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, ALPHA, data.surface, rounding, roundingPower, true, data.fadeAlpha, OVERALL_ALPHA); + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, windowBox, ALPHA, data.surface, rounding, roundingPower, true, data.fadeAlpha, OVERALL_ALPHA); else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true); + g_pHyprOpenGL->renderTexture(TEXTURE, windowBox, ALPHA * OVERALL_ALPHA, rounding, roundingPower, false, true); } if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) diff --git a/src/render/pass/TexPassElement.cpp b/src/render/pass/TexPassElement.cpp index 0624a786..c7eab292 100644 --- a/src/render/pass/TexPassElement.cpp +++ b/src/render/pass/TexPassElement.cpp @@ -18,7 +18,7 @@ void CTexPassElement::draw(const CRegion& damage) { if (data.replaceProjection) g_pHyprOpenGL->m_RenderData.monitorProjection = *data.replaceProjection; - g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, &data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.roundingPower, data.syncTimeline, + g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.roundingPower, data.syncTimeline, data.syncPoint); if (data.replaceProjection) g_pHyprOpenGL->m_RenderData.monitorProjection = g_pHyprOpenGL->m_RenderData.pMonitor->projMatrix; diff --git a/src/render/pass/TextureMatteElement.cpp b/src/render/pass/TextureMatteElement.cpp index 5aed1c9a..3d927357 100644 --- a/src/render/pass/TextureMatteElement.cpp +++ b/src/render/pass/TextureMatteElement.cpp @@ -9,11 +9,11 @@ void CTextureMatteElement::draw(const CRegion& damage) { if (data.disableTransformAndModify) { g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(false); - g_pHyprOpenGL->renderTextureMatte(data.tex, &data.box, *data.fb); + g_pHyprOpenGL->renderTextureMatte(data.tex, data.box, *data.fb); g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(false); } else - g_pHyprOpenGL->renderTextureMatte(data.tex, &data.box, *data.fb); + g_pHyprOpenGL->renderTextureMatte(data.tex, data.box, *data.fb); } bool CTextureMatteElement::needsLiveBlur() { From efe29a24616d4de41dd8f2f70e1493ed6b581e33 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 15:15:54 +0000 Subject: [PATCH 0182/1444] shadow: avoid drawing empty shadows --- src/render/decorations/CHyprDropShadowDecoration.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 8a934086..0b2a96d9 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -231,6 +231,9 @@ eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() { void CHyprDropShadowDecoration::drawShadowInternal(const CBox& box, int round, float roundingPower, int range, CHyprColor color, float a) { static auto PSHADOWSHARP = CConfigValue("decoration:shadow:sharp"); + if (box.w < 1 || box.h < 1) + return; + g_pHyprOpenGL->blend(true); color.a *= a; From bb5b09def0645838456eb7eb1f52b471441acba1 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 15:19:42 +0000 Subject: [PATCH 0183/1444] renderer: fix funky corners oopsie --- src/render/OpenGL.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index f0b2f447..ee5d9a86 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2229,7 +2229,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.alpha, a); glUniform1i(m_RenderData.pCurrentMonData->m_shBORDER1.gradient2Length, 0); - CBox transformedBox = box; + CBox transformedBox = newBox; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); @@ -2238,7 +2238,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box.width, (float)box.height); + glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)newBox.width, (float)newBox.height); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower, roundingPower); @@ -2326,7 +2326,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.alpha, a); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.gradientLerp, lerp); - CBox transformedBox = box; + CBox transformedBox = newBox; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); @@ -2335,7 +2335,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box.width, (float)box.height); + glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)newBox.width, (float)newBox.height); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.roundingPower, roundingPower); From 6bd6c5512e1e413013044257e54581c237ca6fa0 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 18:35:35 +0000 Subject: [PATCH 0184/1444] hooksystem: avoid huge include for HANDLE --- src/managers/HookSystemManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/HookSystemManager.hpp b/src/managers/HookSystemManager.hpp index 6d72a02d..c679c380 100644 --- a/src/managers/HookSystemManager.hpp +++ b/src/managers/HookSystemManager.hpp @@ -9,7 +9,7 @@ #include -#include "../plugins/PluginAPI.hpp" +#define HANDLE void* // global typedef for hooked functions. Passes itself as a ptr when called, and `data` additionally. From 3b207d29bdaf4c718a8878456bb17f2a67f2d9f4 Mon Sep 17 00:00:00 2001 From: user111111111111111111111111111111111 <192911676+user111111111111111111111111111111111@users.noreply.github.com> Date: Sun, 26 Jan 2025 19:06:50 +0000 Subject: [PATCH 0185/1444] core: update groups on movewindow (#9183) --- src/layout/DwindleLayout.cpp | 9 +++++++++ src/layout/MasterLayout.cpp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index df6c3bde..8aaafaa3 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -847,6 +847,15 @@ void CHyprDwindleLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir, pWindow->m_pMonitor = PMONITORFOCAL; } + pWindow->updateGroupOutputs(); + if (!pWindow->m_sGroupData.pNextWindow.expired()) { + PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock(); + while (next != pWindow) { + next->updateToplevel(); + next = next->m_sGroupData.pNextWindow.lock(); + } + } + onWindowCreatedTiling(pWindow); m_vOverrideFocalPoint.reset(); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 8aa15e42..4773147f 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -945,6 +945,15 @@ void CHyprMasterLayout::moveWindowTo(PHLWINDOW pWindow, const std::string& dir, if (silent) g_pCompositor->focusWindow(PWINDOW2); } + + pWindow->updateGroupOutputs(); + if (!pWindow->m_sGroupData.pNextWindow.expired()) { + PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock(); + while (next != pWindow) { + next->updateToplevel(); + next = next->m_sGroupData.pNextWindow.lock(); + } + } } void CHyprMasterLayout::switchWindows(PHLWINDOW pWindow, PHLWINDOW pWindow2) { From 2f55806d6f11a1e81e3e821cb0327779d5cc50e6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 26 Jan 2025 21:06:19 +0000 Subject: [PATCH 0186/1444] renderer: fix rare case when a tiled window would be rendered over fs --- src/render/Renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 41ab0b37..3f6448d5 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -337,7 +337,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR // then render windows over fullscreen. for (auto const& w : g_pCompositor->m_vWindows) { - if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || w->isFullscreen()) + if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || !w->m_bIsFloating || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || w->isFullscreen()) continue; if (w->m_pMonitor == pWorkspace->m_pMonitor && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) From 04ac46c54357278fc68f0a95d26347ea0db99496 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 27 Jan 2025 11:43:43 +0000 Subject: [PATCH 0187/1444] version: bump to 0.47.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 30109231..421ab545 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.46.0 +0.47.0 From 2a478c30cab89c8c608936ca966155da5b16728d Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 27 Jan 2025 13:41:38 +0000 Subject: [PATCH 0188/1444] core: fix clang-format --- src/render/Renderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 3f6448d5..67d8b58b 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -337,7 +337,8 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR // then render windows over fullscreen. for (auto const& w : g_pCompositor->m_vWindows) { - if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || !w->m_bIsFloating || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || w->isFullscreen()) + if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || !w->m_bIsFloating || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || + w->isFullscreen()) continue; if (w->m_pMonitor == pWorkspace->m_pMonitor && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) From cb7ed4f62b195ab7d5f21fa393218170cfbb95c8 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Tue, 28 Jan 2025 00:41:26 +0800 Subject: [PATCH 0189/1444] ci: clang-format fix (#9145) * move * revert, comment via peter-evans/commit-comment@v3 * remove --- .github/workflows/ci.yaml | 24 --------------- .github/workflows/clang-format.yml | 48 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/clang-format.yml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 34c45d6b..416ea93b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -127,27 +127,3 @@ jobs: - name: clang-format check run: ninja -C build clang-format-check - - - name: clang-format apply - if: ${{ failure() && github.event_name == 'pull_request' }} - run: ninja -C build clang-format - - - name: Create patch - if: ${{ failure() && github.event_name == 'pull_request' }} - run: | - echo 'Please fix the formatting issues by running [`clang-format`](https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/#code-style), or directly apply this patch:' > clang-format.patch - echo '
' >> clang-format.patch - echo 'clang-format.patch' >> clang-format.patch - echo >> clang-format.patch - echo '```diff' >> clang-format.patch - git diff >> clang-format.patch - echo '```' >> clang-format.patch - echo >> clang-format.patch - echo '
' >> clang-format.patch - - - name: Comment patch - if: ${{ failure() && github.event_name == 'pull_request' }} - uses: mshick/add-pr-comment@v2 - with: - message-path: | - clang-format.patch diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 00000000..e935a605 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,48 @@ +name: clang-format +on: pull_request_target +jobs: + clang-format: + permissions: write-all + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork + name: "Code Style (Arch)" + runs-on: ubuntu-latest + container: + image: archlinux + steps: + - name: Checkout repository actions + uses: actions/checkout@v4 + with: + sparse-checkout: .github/actions + + - name: Setup base + uses: ./.github/actions/setup_base + + - name: Configure + run: meson setup build -Ddefault_library=static + + - name: clang-format check + run: ninja -C build clang-format-check + + - name: clang-format apply + if: ${{ failure() && github.event_name == 'pull_request' }} + run: ninja -C build clang-format + + - name: Create patch + if: ${{ failure() && github.event_name == 'pull_request' }} + run: | + echo 'Please fix the formatting issues by running [`clang-format`](https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/#code-style), or directly apply this patch:' > clang-format.patch + echo '
' >> clang-format.patch + echo 'clang-format.patch' >> clang-format.patch + echo >> clang-format.patch + echo '```diff' >> clang-format.patch + git diff >> clang-format.patch + echo '```' >> clang-format.patch + echo >> clang-format.patch + echo '
' >> clang-format.patch + + - name: Comment patch + if: ${{ failure() && github.event_name == 'pull_request' }} + uses: mshick/add-pr-comment@v2 + with: + message-path: | + clang-format.patch From e7a72de9b5550784ea804c7bb4e84a28a74326a8 Mon Sep 17 00:00:00 2001 From: DDoSolitary Date: Tue, 28 Jan 2025 00:45:15 +0800 Subject: [PATCH 0190/1444] xwayland: send synthetic configure events (#9193) --- src/xwayland/XSurface.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/xwayland/XSurface.cpp b/src/xwayland/XSurface.cpp index b5ee75f6..91f20be5 100644 --- a/src/xwayland/XSurface.cpp +++ b/src/xwayland/XSurface.cpp @@ -169,6 +169,22 @@ void CXWaylandSurface::configure(const CBox& box) { uint32_t values[] = {box.x, box.y, box.width, box.height, 0}; xcb_configure_window(g_pXWayland->pWM->connection, xID, mask, values); + if (geometry.width == box.width && geometry.height == box.height) { + // ICCCM requires a synthetic event when window size is not changed + xcb_configure_notify_event_t e; + e.response_type = XCB_CONFIGURE_NOTIFY; + e.event = xID; + e.window = xID; + e.x = box.x; + e.y = box.y; + e.width = box.width; + e.height = box.height; + e.border_width = 0; + e.above_sibling = XCB_NONE; + e.override_redirect = overrideRedirect; + xcb_send_event(g_pXWayland->pWM->connection, false, xID, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char*)&e); + } + g_pXWayland->pWM->updateClientList(); xcb_flush(g_pXWayland->pWM->connection); From 25d5ce4833a481325a2a948f51cabb6f4a6e1896 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 27 Jan 2025 22:25:27 +0200 Subject: [PATCH 0191/1444] CI/setup_base: add libspng --- .github/actions/setup_base/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/setup_base/action.yml b/.github/actions/setup_base/action.yml index 6df442b3..b4c9cf78 100644 --- a/.github/actions/setup_base/action.yml +++ b/.github/actions/setup_base/action.yml @@ -35,6 +35,7 @@ runs: libinput \ libjxl \ libliftoff \ + libspng \ libwebp \ libxcursor \ libxcvt \ From 5fd90548dc99d79dd2677e027a620c8ada9f4869 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Mon, 27 Jan 2025 14:19:47 -0500 Subject: [PATCH 0192/1444] nix: fix duplicate inputs and update flake.lock --- flake.lock | 95 +++++++++++++----------------------------------------- flake.nix | 2 +- 2 files changed, 24 insertions(+), 73 deletions(-) diff --git a/flake.lock b/flake.lock index 34249b0a..ac73e5f7 100644 --- a/flake.lock +++ b/flake.lock @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1737634889, - "narHash": "sha256-9JZE3KxcXOqZH9zs3UeadngDiK/yIACTiAR8HSA/TNI=", + "lastModified": 1737985436, + "narHash": "sha256-zx8FdI4zr2GhNyD1YGAqa2ymodAObTSAdwuWwVucewo=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "0d77b4895ad5f1bb3b0ee43103a5246c58b65591", + "rev": "23783b96036f5506fdaf8b2250a1ef849d57f0d3", "type": "github" }, "original": { @@ -143,7 +143,10 @@ }, "hyprland-qt-support": { "inputs": { - "hyprlang": "hyprlang", + "hyprlang": [ + "hyprland-qtutils", + "hyprlang" + ], "nixpkgs": [ "hyprland-qtutils", "nixpkgs" @@ -170,7 +173,12 @@ "hyprland-qtutils": { "inputs": { "hyprland-qt-support": "hyprland-qt-support", + "hyprlang": [ + "hyprlang" + ], "hyprutils": [ + "hyprland-qtutils", + "hyprlang", "hyprutils" ], "nixpkgs": [ @@ -181,11 +189,11 @@ ] }, "locked": { - "lastModified": 1737811848, - "narHash": "sha256-WZ7LeiKHk5Y94MU5gHIWn0r8asWxYOvie4LqfCjVIZU=", + "lastModified": 1737981711, + "narHash": "sha256-lh6cL5D8nPplB3WovCQjLUZ7k7MViiBrMlpkfm4R7/c=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "9c0831ff98856c0f312fcb8b57553fbe3dd34d5b", + "rev": "96bf0677fa9cd13508294e3d4559dfbbc8beff73", "type": "github" }, "original": { @@ -195,34 +203,6 @@ } }, "hyprlang": { - "inputs": { - "hyprutils": "hyprutils", - "nixpkgs": [ - "hyprland-qtutils", - "hyprland-qt-support", - "nixpkgs" - ], - "systems": [ - "hyprland-qtutils", - "hyprland-qt-support", - "systems" - ] - }, - "locked": { - "lastModified": 1737634606, - "narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=", - "owner": "hyprwm", - "repo": "hyprlang", - "rev": "f41271d35cc0f370d300413d756c2677f386af9d", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprlang", - "type": "github" - } - }, - "hyprlang_2": { "inputs": { "hyprutils": [ "hyprutils" @@ -249,35 +229,6 @@ } }, "hyprutils": { - "inputs": { - "nixpkgs": [ - "hyprland-qtutils", - "hyprland-qt-support", - "hyprlang", - "nixpkgs" - ], - "systems": [ - "hyprland-qtutils", - "hyprland-qt-support", - "hyprlang", - "systems" - ] - }, - "locked": { - "lastModified": 1737632363, - "narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=", - "owner": "hyprwm", - "repo": "hyprutils", - "rev": "006620eb29d54ea9086538891404c78563d1bae1", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprutils", - "type": "github" - } - }, - "hyprutils_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -287,11 +238,11 @@ ] }, "locked": { - "lastModified": 1737725508, - "narHash": "sha256-jGmcPc6y/prg/4A8KGYqJ27nSPaProCMiFadaxNAKvA=", + "lastModified": 1737978343, + "narHash": "sha256-TfFS0HCEJh63Kahrkp1h9hVDMdLU8a37Zz+IFucxyfA=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "fb0c2d1de3d1ef7396d19c18ac09e12bd956929e", + "rev": "6a8bc9d2a4451df12f5179dc0b1d2d46518a90ab", "type": "github" }, "original": { @@ -325,11 +276,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1737632463, - "narHash": "sha256-38J9QfeGSej341ouwzqf77WIHAScihAKCt8PQJ+NH28=", + "lastModified": 1737885589, + "narHash": "sha256-Zf0hSrtzaM1DEz8//+Xs51k/wdSajticVrATqDrfQjg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0aa475546ed21629c4f5bbf90e38c846a99ec9e9", + "rev": "852ff1d9e153d8875a83602e03fdef8a63f0ecf8", "type": "github" }, "original": { @@ -368,8 +319,8 @@ "hyprgraphics": "hyprgraphics", "hyprland-protocols": "hyprland-protocols", "hyprland-qtutils": "hyprland-qtutils", - "hyprlang": "hyprlang_2", - "hyprutils": "hyprutils_2", + "hyprlang": "hyprlang", + "hyprutils": "hyprutils", "hyprwayland-scanner": "hyprwayland-scanner", "nixpkgs": "nixpkgs", "pre-commit-hooks": "pre-commit-hooks", diff --git a/flake.nix b/flake.nix index 821a5f90..c1c580ae 100644 --- a/flake.nix +++ b/flake.nix @@ -39,7 +39,7 @@ url = "github:hyprwm/hyprland-qtutils"; inputs.nixpkgs.follows = "nixpkgs"; inputs.systems.follows = "systems"; - inputs.hyprutils.follows = "hyprutils"; + inputs.hyprlang.follows = "hyprlang"; }; hyprlang = { From d2773d7a4ecde7111af4ec71b51b1996ec1d96bf Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Mon, 27 Jan 2025 22:06:48 +0000 Subject: [PATCH 0193/1444] deps: add libinotify-kqueue on BSDs after 8dd2cd41fb4c (#9197) src/config/ConfigWatcher.cpp:2:10: fatal error: 'sys/inotify.h' file not found 2 | #include | ^~~~~~~~~~~~~~~ --- CMakeLists.txt | 6 ++++++ meson.build | 1 + src/meson.build | 1 + 3 files changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cfb8688..a34d677c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,6 +197,12 @@ if(NOT HAS_TIMERFD AND epoll_FOUND) target_link_libraries(Hyprland PkgConfig::epoll) endif() +check_include_file("sys/inotify.h" HAS_INOTIFY) +pkg_check_modules(inotify IMPORTED_TARGET libinotify) +if(NOT HAS_INOTIFY AND inotify_FOUND) + target_link_libraries(Hyprland PkgConfig::inotify) +endif() + if(LEGACY_RENDERER) message(STATUS "Using the legacy GLES2 renderer!") add_compile_definitions(LEGACY_RENDERER) diff --git a/meson.build b/meson.build index 6b50ff2d..ae6e3940 100644 --- a/meson.build +++ b/meson.build @@ -58,6 +58,7 @@ endif backtrace_dep = cpp_compiler.find_library('execinfo', required: false) epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs +inotify_dep = dependency('libinotify', required: false) # inotify on BSDs re2 = dependency('re2', required: true) diff --git a/src/meson.build b/src/meson.build index 7054d8e4..3973dc4c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -32,6 +32,7 @@ executable( xcb_xfixes_dep, backtrace_dep, epoll_dep, + inotify_dep, gio_dep, tracy, From d3042e5358a91287d6ff9d8c745dc70af1ebdc90 Mon Sep 17 00:00:00 2001 From: DDoSolitary Date: Tue, 28 Jan 2025 18:04:57 +0800 Subject: [PATCH 0194/1444] xwayland: respect window size set by configure requests (#9190) --- src/managers/XWaylandManager.cpp | 26 +++----------------------- src/xwayland/XWM.cpp | 4 ++-- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index f103266d..a5506329 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -82,29 +82,9 @@ CBox CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow) { CBox box; - if (pWindow->m_bIsX11) { - const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get(); - - if (SIZEHINTS && !pWindow->isX11OverrideRedirect()) { - // WM_SIZE_HINTS' x,y,w,h is deprecated it seems. - // Source: https://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#wm_normal_hints_property - box.x = pWindow->m_pXWaylandSurface->geometry.x; - box.y = pWindow->m_pXWaylandSurface->geometry.y; - - constexpr int ICCCM_USSize = 0x2; - constexpr int ICCCM_PSize = 0x8; - - if ((SIZEHINTS->flags & ICCCM_USSize) || (SIZEHINTS->flags & ICCCM_PSize)) { - box.w = SIZEHINTS->base_width; - box.h = SIZEHINTS->base_height; - } else { - box.w = pWindow->m_pXWaylandSurface->geometry.w; - box.h = pWindow->m_pXWaylandSurface->geometry.h; - } - } else - box = pWindow->m_pXWaylandSurface->geometry; - - } else if (pWindow->m_pXDGSurface) + if (pWindow->m_bIsX11) + box = pWindow->m_pXWaylandSurface->geometry; + else if (pWindow->m_pXDGSurface) box = pWindow->m_pXDGSurface->current.geometry; return box; diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index ef139b38..6673105e 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -102,8 +102,8 @@ void CXWM::handleMapRequest(xcb_map_request_event_t* e) { const bool HAS_HINTS = XSURF->sizeHints && Vector2D{XSURF->sizeHints->base_width, XSURF->sizeHints->base_height} > Vector2D{5, 5}; const auto DESIREDSIZE = HAS_HINTS ? Vector2D{XSURF->sizeHints->base_width, XSURF->sizeHints->base_height} : Vector2D{800, 800}; - // if it's too small, or its base size is set, configure it. - if ((SMALL || HAS_HINTS) && !XSURF->overrideRedirect) // default to 800 x 800 + // if it's too small, configure it. + if (SMALL && !XSURF->overrideRedirect) // default to 800 x 800 XSURF->configure({XSURF->geometry.pos(), DESIREDSIZE}); Debug::log(LOG, "[xwm] Mapping window {} in X (geometry {}x{} at {}x{}))", e->window, XSURF->geometry.width, XSURF->geometry.height, XSURF->geometry.x, XSURF->geometry.y); From 529ad4eaf450e558998e7417db5db6602e7fb497 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Tue, 28 Jan 2025 10:15:08 +0100 Subject: [PATCH 0195/1444] ikeyboard: free xkbSymState in clearManuallyAllocd asan reported a leak on xkbSymState on destruction, because it wasnt beeing unrefed, was only being unrefed on calls to updateXKBTranslationState. --- src/devices/IKeyboard.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp index d1119772..4623fe84 100644 --- a/src/devices/IKeyboard.cpp +++ b/src/devices/IKeyboard.cpp @@ -44,6 +44,10 @@ void IKeyboard::clearManuallyAllocd() { if (xkbKeymapFD >= 0) close(xkbKeymapFD); + if (xkbSymState) + xkb_state_unref(xkbSymState); + + xkbSymState = nullptr; xkbKeymap = nullptr; xkbState = nullptr; xkbStaticState = nullptr; From 1d3904c3e7a8b74ea83669f73ee408bd38390b11 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Tue, 28 Jan 2025 10:20:54 +0100 Subject: [PATCH 0196/1444] configmgr: properly free glob memory globfree is only freeing internally allocated resources, so also call free the on glob_t memory we allocated. --- src/config/ConfigManager.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 93289bf7..daff9285 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -2690,8 +2690,14 @@ std::optional CConfigManager::handleSource(const std::string& comma Debug::log(ERR, "source= path garbage"); return "source= path " + rawpath + " bogus!"; } - std::unique_ptr glob_buf{new glob_t, [](glob_t* g) { globfree(g); }}; - memset(glob_buf.get(), 0, sizeof(glob_t)); + + std::unique_ptr glob_buf{static_cast(calloc(1, sizeof(glob_t))), // allocate and zero-initialize + [](glob_t* g) { + if (g) { + globfree(g); // free internal resources allocated by glob() + free(g); // free the memory for the glob_t structure + } + }}; if (auto r = glob(absolutePath(rawpath, configCurrentPath).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) { std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory"); From 3d1dd6b5c7b90e513e86c1ad27c6c01a5c69e4f8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 28 Jan 2025 23:43:26 +0000 Subject: [PATCH 0197/1444] presentation: log a fixme when there is a feedback leak ref #8087 --- src/protocols/PresentationTime.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/protocols/PresentationTime.cpp b/src/protocols/PresentationTime.cpp index a9139ac0..05fda8ea 100644 --- a/src/protocols/PresentationTime.cpp +++ b/src/protocols/PresentationTime.cpp @@ -130,6 +130,11 @@ void CPresentationProtocol::onPresented(PHLMONITOR pMonitor, timespec* when, uin } } + if (m_vFeedbacks.size() > 10000 /* arbitrary number I chose as fitting */) { + LOGM(ERR, "FIXME: presentation has a feedback leak, and has grown to {} pending entries!!! Dropping!!!!!", m_vFeedbacks.size()); + m_vFeedbacks = {m_vFeedbacks.begin() + 9000, m_vFeedbacks.end()}; + } + std::erase_if(m_vFeedbacks, [](const auto& other) { return !other->surface || other->done; }); std::erase_if(m_vQueue, [pMonitor](const auto& other) { return !other->surface || other->pMonitor == pMonitor || !other->pMonitor || other->done; }); } From b884f1f7c88b798ba5d1b6a794615bf046ff1f14 Mon Sep 17 00:00:00 2001 From: nyx Date: Wed, 29 Jan 2025 03:41:56 -0500 Subject: [PATCH 0198/1444] renderer: calculate UV using both pixel and monitor dimensions (#9210) --- src/render/OpenGL.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index ee5d9a86..78b53c9b 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2147,14 +2147,20 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP tex, const CBox& box, f glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // stencil done. Render everything. - CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; - // render our great blurred FB - // calculate the uv for it const auto LASTTL = m_RenderData.primarySurfaceUVTopLeft; const auto LASTBR = m_RenderData.primarySurfaceUVBottomRight; - m_RenderData.primarySurfaceUVTopLeft = box.pos() / MONITORBOX.size(); - m_RenderData.primarySurfaceUVBottomRight = (box.pos() + box.size()) / MONITORBOX.size(); + CBox transformedBox = box; + transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, + m_RenderData.pMonitor->vecTransformedSize.y); + + CBox monitorSpaceBox = {transformedBox.pos().x / m_RenderData.pMonitor->vecPixelSize.x * m_RenderData.pMonitor->vecTransformedSize.x, + transformedBox.pos().y / m_RenderData.pMonitor->vecPixelSize.y * m_RenderData.pMonitor->vecTransformedSize.y, + transformedBox.width / m_RenderData.pMonitor->vecPixelSize.x * m_RenderData.pMonitor->vecTransformedSize.x, + transformedBox.height / m_RenderData.pMonitor->vecPixelSize.y * m_RenderData.pMonitor->vecTransformedSize.y}; + + m_RenderData.primarySurfaceUVTopLeft = monitorSpaceBox.pos() / m_RenderData.pMonitor->vecTransformedSize; + m_RenderData.primarySurfaceUVBottomRight = (monitorSpaceBox.pos() + monitorSpaceBox.size()) / m_RenderData.pMonitor->vecTransformedSize; static auto PBLURIGNOREOPACITY = CConfigValue("decoration:blur:ignore_opacity"); setMonitorTransformEnabled(true); From d41135d07c15f122d1ca2a03ace9ed3e080b2e28 Mon Sep 17 00:00:00 2001 From: "Owen L." <32573897+mageowl@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:27:34 -0800 Subject: [PATCH 0199/1444] input: change window grab cursor to closed hand (#9196) --- src/layout/IHyprLayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 5e5669b8..57ae5f40 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -307,7 +307,7 @@ void IHyprLayout::onBeginDragWindow() { } if (g_pInputManager->dragMode != MBIND_RESIZE && g_pInputManager->dragMode != MBIND_RESIZE_FORCE_RATIO && g_pInputManager->dragMode != MBIND_RESIZE_BLOCK_RATIO) - g_pInputManager->setCursorImageUntilUnset("grab"); + g_pInputManager->setCursorImageUntilUnset("grabbing"); g_pHyprRenderer->damageWindow(DRAGGINGWINDOW); From 344e32d71bf115a32434da3fa72b2b6238706625 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 29 Jan 2025 10:42:46 +0000 Subject: [PATCH 0200/1444] pass/rect: fix bounding / opaque regions fixes #9212 --- src/render/pass/PassElement.hpp | 4 ++-- src/render/pass/RectPassElement.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/render/pass/PassElement.hpp b/src/render/pass/PassElement.hpp index b45970aa..a006ce9e 100644 --- a/src/render/pass/PassElement.hpp +++ b/src/render/pass/PassElement.hpp @@ -13,7 +13,7 @@ class IPassElement { virtual const char* passName() = 0; virtual void discard(); virtual bool undiscardable(); - virtual std::optional boundingBox(); - virtual CRegion opaqueRegion(); + virtual std::optional boundingBox(); // in monitor-local logical coordinates + virtual CRegion opaqueRegion(); // in monitor-local logical coordinates virtual bool disableSimplification(); }; diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index a9ab737d..fba06286 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -24,7 +24,7 @@ bool CRectPassElement::needsPrecomputeBlur() { } std::optional CRectPassElement::boundingBox() { - return data.box; + return data.box.copy().scale(1.F / g_pHyprOpenGL->m_RenderData.pMonitor->scale).round(); } CRegion CRectPassElement::opaqueRegion() { From aaa5573c73636a76dd3ae4758bfd89ae4d5eeb8a Mon Sep 17 00:00:00 2001 From: vaxerski Date: Wed, 29 Jan 2025 10:50:39 +0000 Subject: [PATCH 0201/1444] config/hyprctl: fix keyword not updating autoreload ref #9139 --- src/config/ConfigManager.cpp | 8 ++++++-- src/config/ConfigManager.hpp | 1 + src/debug/HyprCtl.cpp | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index daff9285..047c58d9 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -912,12 +912,16 @@ std::optional CConfigManager::resetHLConfig() { return RET; } +void CConfigManager::updateWatcher() { + static const auto PDISABLEAUTORELOAD = CConfigValue("misc:disable_autoreload"); + g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector{} : m_configPaths); +} + void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); - static const auto PDISABLEAUTORELOAD = CConfigValue("misc:disable_autoreload"); static int prevEnabledExplicit = *PENABLEEXPLICIT; - g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector{} : m_configPaths); + updateWatcher(); for (auto const& w : g_pCompositor->m_vWindows) { w->uncacheWindowDecos(); diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index ae0ba759..f0696882 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -190,6 +190,7 @@ class CConfigManager { void ensureVRR(PHLMONITOR pMonitor = nullptr); bool shouldUseSoftwareCursors(); + void updateWatcher(); std::string parseKeyword(const std::string&, const std::string&); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index cfdba100..359428b1 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1100,6 +1100,9 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) } } + if (COMMAND.contains("misc:disable_autoreload")) + g_pConfigManager->updateWatcher(); + // decorations will probably need a repaint if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source" || COMMAND.starts_with("windowrule")) { From 61319197155cbcb3b8d5f004f46c2249029ec1f3 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 29 Jan 2025 13:16:50 +0000 Subject: [PATCH 0202/1444] monitor: round refresh rates in sorting modes fixes #9209 --- src/helpers/Monitor.cpp | 7 ++++--- src/helpers/Monitor.hpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 19d68a56..9ea85bca 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -456,9 +456,9 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { // sort prioritizing refresh rate 1st and resolution 2nd, then add best 3 addBest3Modes([](auto const& a, auto const& b) { - if (a->refreshRate > b->refreshRate) + if (std::round(a->refreshRate) > std::round(b->refreshRate)) return true; - else if (DELTALESSTHAN((float)a->refreshRate, (float)b->refreshRate, 1000) && a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) + else if (DELTALESSTHAN((float)a->refreshRate, (float)b->refreshRate, 1.F) && a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) return true; return false; }); @@ -469,7 +469,8 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { addBest3Modes([](auto const& a, auto const& b) { if (a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) return true; - else if (DELTALESSTHAN(a->pixelSize.x, b->pixelSize.x, 1) && DELTALESSTHAN(a->pixelSize.y, b->pixelSize.y, 1) && a->refreshRate > b->refreshRate) + else if (DELTALESSTHAN(a->pixelSize.x, b->pixelSize.x, 1) && DELTALESSTHAN(a->pixelSize.y, b->pixelSize.y, 1) && + std::round(a->refreshRate) > std::round(b->refreshRate)) return true; return false; }); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 7c19b57c..1b207f7d 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -33,7 +33,7 @@ struct SMonitorRule { Vector2D resolution = Vector2D(1280, 720); Vector2D offset = Vector2D(0, 0); float scale = 1; - float refreshRate = 60; + float refreshRate = 60; // Hz bool disabled = false; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; std::string mirrorOf = ""; @@ -92,7 +92,7 @@ class CMonitor { CDamageRing damage; SP output; - float refreshRate = 60; + float refreshRate = 60; // Hz int forceFullFrames = 0; bool scheduledRecalc = false; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; From 6fc9c8e4797a272c688fc74b872db5d828c21f02 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Wed, 29 Jan 2025 22:45:38 +0200 Subject: [PATCH 0203/1444] flake.lock: update --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index ac73e5f7..dfdd8c5b 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1737636397, - "narHash": "sha256-F5MbBj3QVorycVSFE9qjuOTLtIQBqt2VWbXa0uwzm98=", + "lastModified": 1738183445, + "narHash": "sha256-C1He3N1SA8D2u+TSlldbA9wiYwDvXI4GxX3zKaeD7qU=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "7fe006981fae53e931f513026fc754e322f13145", + "rev": "48a000cf35dd10bfeb231152735aebbe875f4b74", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1737634937, - "narHash": "sha256-Ffw4ujFpi++6pPHe+gCBOfDgAoNlzVPZN6MReC1beu8=", + "lastModified": 1738178255, + "narHash": "sha256-+D6Nu2ewXbMTFzx/Q4jDOo+LAOUPr0cxQJg5k33daIE=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "9c5dd1f7c825ee47f72727ad0a4e16ca46a2688e", + "rev": "dcadd3398abe146d60c67e0d9ee6e27b301cae82", "type": "github" }, "original": { @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1737985436, - "narHash": "sha256-zx8FdI4zr2GhNyD1YGAqa2ymodAObTSAdwuWwVucewo=", + "lastModified": 1738018829, + "narHash": "sha256-5Ol5iahMlELx3lWuChyZsqqLk6sP6aqaJCJFw92OZGo=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "23783b96036f5506fdaf8b2250a1ef849d57f0d3", + "rev": "12cd7034e441a5ebfdef1a090c0788413b4a635b", "type": "github" }, "original": { From 09ec1cca51e1880dfc855c168a0dd810ff1ddcd6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 29 Jan 2025 23:05:54 +0000 Subject: [PATCH 0204/1444] popup: stop refocusing at unmap fixes #9018 --- src/desktop/Popup.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 93a810ff..dea94f55 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -138,10 +138,11 @@ void CPopup::onUnmap() { }, nullptr); - const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource(); + // TODO: probably refocus, but without a motion event? + // const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource(); - if (WASLASTFOCUS) - g_pInputManager->simulateMouseMovement(); + // if (WASLASTFOCUS) + // g_pInputManager->simulateMouseMovement(); } void CPopup::onCommit(bool ignoreSiblings) { From d462cc7fa166e1e6a6f14b58a2dd1e8b92e15426 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 29 Jan 2025 23:16:25 +0000 Subject: [PATCH 0205/1444] subsurface: fix invalid parent typo fixes #9224 --- src/desktop/Subsurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index a68cf8f3..d7a53954 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -143,7 +143,7 @@ void CSubsurface::onNewSubsurface(SP pSubsurface) { ASSERT(PSUBSURFACE); - PSUBSURFACE->m_pParent = PSUBSURFACE; + PSUBSURFACE->m_pParent = m_pSelf; } void CSubsurface::onMap() { From 7d1c78f4a3720b693fedeb5d4f2d3f4da37f7fd3 Mon Sep 17 00:00:00 2001 From: Honkazel <169346573+Honkazel@users.noreply.github.com> Date: Thu, 30 Jan 2025 16:07:06 +0500 Subject: [PATCH 0206/1444] core,hyprctl: clang, clang-tidy, typo fixes and dtors changes (#9233) * declare dtor once + DMABBUF typo fix * dup include + clang moment * linux-dmabuf: last minute nit change --- hyprctl/main.cpp | 3 --- src/Compositor.cpp | 1 - src/config/ConfigDataValues.hpp | 2 +- src/config/ConfigManager.cpp | 4 ---- src/desktop/Subsurface.cpp | 4 ---- src/desktop/Subsurface.hpp | 4 ++-- src/helpers/Monitor.cpp | 4 ---- src/helpers/Monitor.hpp | 3 +-- src/hyprerror/HyprError.cpp | 2 -- src/hyprerror/HyprError.hpp | 2 +- src/layout/IHyprLayout.cpp | 2 -- src/layout/IHyprLayout.hpp | 2 +- src/layout/MasterLayout.hpp | 1 - src/managers/EventManager.hpp | 1 - src/managers/XCursorManager.hpp | 8 +++---- src/protocols/FocusGrab.cpp | 4 ---- src/protocols/FocusGrab.hpp | 2 +- src/protocols/LinuxDMABUF.cpp | 22 ++++++------------- src/protocols/LinuxDMABUF.hpp | 16 +++++++------- src/protocols/SinglePixel.cpp | 8 ------- src/protocols/SinglePixel.hpp | 6 ++--- src/protocols/core/Shm.cpp | 4 ---- src/protocols/core/Shm.hpp | 2 +- .../decorations/CHyprBorderDecoration.cpp | 4 ---- .../decorations/CHyprBorderDecoration.hpp | 2 +- .../decorations/CHyprDropShadowDecoration.cpp | 2 -- .../decorations/CHyprDropShadowDecoration.hpp | 2 +- .../decorations/CHyprGroupBarDecoration.cpp | 4 ---- .../decorations/CHyprGroupBarDecoration.hpp | 4 ++-- .../decorations/IHyprWindowDecoration.cpp | 2 -- .../decorations/IHyprWindowDecoration.hpp | 2 +- 31 files changed, 35 insertions(+), 94 deletions(-) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index 16d66223..4cc73bdf 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -21,13 +21,10 @@ #include #include #include -#include #include #include #include -#include #include -#include using namespace Hyprutils::String; #include "Strings.hpp" diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 3421c314..1daccbfd 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "debug/HyprCtl.hpp" #include "debug/CrashReporter.hpp" diff --git a/src/config/ConfigDataValues.hpp b/src/config/ConfigDataValues.hpp index 80e45a05..901fb317 100644 --- a/src/config/ConfigDataValues.hpp +++ b/src/config/ConfigDataValues.hpp @@ -11,7 +11,7 @@ enum eConfigValueDataTypes : int8_t { class ICustomConfigValueData { public: - virtual ~ICustomConfigValueData() = 0; + virtual ~ICustomConfigValueData() = default; virtual eConfigValueDataTypes getDataType() = 0; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 047c58d9..86581b10 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1709,10 +1709,6 @@ void CConfigManager::handlePluginLoads() { } } -ICustomConfigValueData::~ICustomConfigValueData() { - ; // empty -} - const std::unordered_map>& CConfigManager::getAnimationConfig() { return m_AnimationTree.getFullConfig(); } diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index d7a53954..1d938f39 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -31,10 +31,6 @@ CSubsurface::CSubsurface(SP pSubsurface, WP pOwne initExistingSubsurfaces(pSubsurface->surface.lock()); } -CSubsurface::~CSubsurface() { - ; -} - void CSubsurface::initSignals() { if (m_pSubsurface) { listeners.commitSubsurface = m_pSubsurface->surface->events.commit.registerListener([this](std::any d) { onCommit(); }); diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index f16a11ea..41958671 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -17,7 +17,7 @@ class CSubsurface { CSubsurface(SP pSubsurface, PHLWINDOW pOwner); CSubsurface(SP pSubsurface, WP pOwner); - ~CSubsurface(); + ~CSubsurface() = default; Vector2D coordsRelativeToParent(); Vector2D coordsGlobal(); @@ -62,4 +62,4 @@ class CSubsurface { void initSignals(); void initExistingSubsurfaces(SP pSurface); void checkSiblingDamage(); -}; \ No newline at end of file +}; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 9ea85bca..42acf485 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1434,10 +1434,6 @@ CMonitorState::CMonitorState(CMonitor* owner) : m_pOwner(owner) { ; } -CMonitorState::~CMonitorState() { - ; -} - void CMonitorState::ensureBufferPresent() { const auto STATE = m_pOwner->output->state->state(); if (!STATE.enabled) { diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 1b207f7d..2b02c30a 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -6,7 +6,6 @@ #include "../SharedDefs.hpp" #include "MiscFunctions.hpp" #include "WLClasses.hpp" -#include #include #include @@ -48,7 +47,7 @@ class CSyncTimeline; class CMonitorState { public: CMonitorState(CMonitor* owner); - ~CMonitorState(); + ~CMonitorState() = default; bool commit(); bool test(); diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 4076ed3a..9f889fdf 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -32,8 +32,6 @@ CHyprError::CHyprError() { m_pTexture = makeShared(); } -CHyprError::~CHyprError() = default; - void CHyprError::queueCreate(std::string message, const CHyprColor& color) { m_szQueued = message; m_cQueued = color; diff --git a/src/hyprerror/HyprError.hpp b/src/hyprerror/HyprError.hpp index 771e50f0..12de0c81 100644 --- a/src/hyprerror/HyprError.hpp +++ b/src/hyprerror/HyprError.hpp @@ -9,7 +9,7 @@ class CHyprError { public: CHyprError(); - ~CHyprError(); + ~CHyprError() = default; void queueCreate(std::string message, const CHyprColor& color); void draw(); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 57ae5f40..9a0ba6ee 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -950,5 +950,3 @@ Vector2D IHyprLayout::predictSizeForNewWindow(PHLWINDOW pWindow) { return sizePredicted; } - -IHyprLayout::~IHyprLayout() = default; diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index ab188b9b..e31bb63e 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -43,7 +43,7 @@ enum eDirection : int8_t { class IHyprLayout { public: - virtual ~IHyprLayout() = 0; + virtual ~IHyprLayout() = default; virtual void onEnable() = 0; virtual void onDisable() = 0; diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index 381ccc9d..f658fdaa 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -5,7 +5,6 @@ #include "../helpers/varlist/VarList.hpp" #include #include -#include #include enum eFullscreenMode : int8_t; diff --git a/src/managers/EventManager.hpp b/src/managers/EventManager.hpp index 5a88963e..6b506d33 100644 --- a/src/managers/EventManager.hpp +++ b/src/managers/EventManager.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include #include "../defines.hpp" #include "../helpers/memory/Memory.hpp" diff --git a/src/managers/XCursorManager.hpp b/src/managers/XCursorManager.hpp index 2517e85e..3052206f 100644 --- a/src/managers/XCursorManager.hpp +++ b/src/managers/XCursorManager.hpp @@ -13,10 +13,10 @@ extern "C" { // gangsta bootleg XCursor impl. adidas balkanized struct SXCursorImage { - Vector2D size; - Vector2D hotspot; - std::vector pixels; // XPixel is a u32 - uint32_t delay; // animation delay to next frame (ms) + Hyprutils::Math::Vector2D size; + Hyprutils::Math::Vector2D hotspot; + std::vector pixels; // XPixel is a u32 + uint32_t delay; // animation delay to next frame (ms) }; struct SXCursors { diff --git a/src/protocols/FocusGrab.cpp b/src/protocols/FocusGrab.cpp index ab9d22ef..bef69f62 100644 --- a/src/protocols/FocusGrab.cpp +++ b/src/protocols/FocusGrab.cpp @@ -11,10 +11,6 @@ CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, SPevents.destroy.registerListener([=](std::any d) { grab->eraseSurface(surface); }); } -CFocusGrabSurfaceState::~CFocusGrabSurfaceState() { - ; -} - CFocusGrab::CFocusGrab(SP resource_) : resource(resource_) { if UNLIKELY (!resource->resource()) return; diff --git a/src/protocols/FocusGrab.hpp b/src/protocols/FocusGrab.hpp index 3c907ed0..1445a24c 100644 --- a/src/protocols/FocusGrab.hpp +++ b/src/protocols/FocusGrab.hpp @@ -15,7 +15,7 @@ class CWLSurfaceResource; class CFocusGrabSurfaceState { public: CFocusGrabSurfaceState(CFocusGrab* grab, SP surface); - ~CFocusGrabSurfaceState(); + ~CFocusGrabSurfaceState() = default; enum State { PendingAddition, diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index 82d31c84..d3135da0 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -125,7 +125,7 @@ bool CLinuxDMABuffer::good() { return buffer && buffer->good(); } -CLinuxDMABBUFParamsResource::CLinuxDMABBUFParamsResource(SP resource_) : resource(resource_) { +CLinuxDMABUFParamsResource::CLinuxDMABUFParamsResource(SP resource_) : resource(resource_) { if UNLIKELY (!good()) return; @@ -197,15 +197,11 @@ CLinuxDMABBUFParamsResource::CLinuxDMABBUFParamsResource(SPresource(); } -void CLinuxDMABBUFParamsResource::create(uint32_t id) { +void CLinuxDMABUFParamsResource::create(uint32_t id) { used = true; if UNLIKELY (!verify()) { @@ -237,7 +233,7 @@ void CLinuxDMABBUFParamsResource::create(uint32_t id) { createdBuffer = buf; } -bool CLinuxDMABBUFParamsResource::commence() { +bool CLinuxDMABUFParamsResource::commence() { if (PROTO::linuxDma->mainDeviceFD < 0) return true; @@ -258,7 +254,7 @@ bool CLinuxDMABBUFParamsResource::commence() { return true; } -bool CLinuxDMABBUFParamsResource::verify() { +bool CLinuxDMABUFParamsResource::verify() { if UNLIKELY (attrs->planes <= 0) { resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "No planes added"); return false; @@ -311,10 +307,6 @@ CLinuxDMABUFFeedbackResource::CLinuxDMABUFFeedbackResource(SPresource(); } @@ -384,7 +376,7 @@ CLinuxDMABUFResource::CLinuxDMABUFResource(SP resource_) : re }); resource->setCreateParams([](CZwpLinuxDmabufV1* r, uint32_t id) { - const auto RESOURCE = PROTO::linuxDma->m_vParams.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); + const auto RESOURCE = PROTO::linuxDma->m_vParams.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); if UNLIKELY (!RESOURCE->good()) { r->noMemory(); @@ -550,7 +542,7 @@ void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABUFFeedbackResource* resou std::erase_if(m_vFeedbacks, [&](const auto& other) { return other.get() == resource; }); } -void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABBUFParamsResource* resource) { +void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABUFParamsResource* resource) { std::erase_if(m_vParams, [&](const auto& other) { return other.get() == resource; }); } diff --git a/src/protocols/LinuxDMABUF.hpp b/src/protocols/LinuxDMABUF.hpp index 8c574dbc..91cf3283 100644 --- a/src/protocols/LinuxDMABUF.hpp +++ b/src/protocols/LinuxDMABUF.hpp @@ -27,7 +27,7 @@ class CLinuxDMABuffer { CHyprSignalListener bufferResourceDestroy; } listeners; - friend class CLinuxDMABBUFParamsResource; + friend class CLinuxDMABUFParamsResource; }; #pragma pack(push, 1) @@ -56,10 +56,10 @@ class CDMABUFFormatTable { std::vector> monitorTranches; }; -class CLinuxDMABBUFParamsResource { +class CLinuxDMABUFParamsResource { public: - CLinuxDMABBUFParamsResource(SP resource_); - ~CLinuxDMABBUFParamsResource(); + CLinuxDMABUFParamsResource(SP resource_); + ~CLinuxDMABUFParamsResource() = default; bool good(); void create(uint32_t id); // 0 means not immed @@ -78,7 +78,7 @@ class CLinuxDMABBUFParamsResource { class CLinuxDMABUFFeedbackResource { public: CLinuxDMABUFFeedbackResource(SP resource_, SP surface_); - ~CLinuxDMABUFFeedbackResource(); + ~CLinuxDMABUFFeedbackResource() = default; bool good(); void sendDefaultFeedback(); @@ -115,7 +115,7 @@ class CLinuxDMABufV1Protocol : public IWaylandProtocol { private: void destroyResource(CLinuxDMABUFResource* resource); void destroyResource(CLinuxDMABUFFeedbackResource* resource); - void destroyResource(CLinuxDMABBUFParamsResource* resource); + void destroyResource(CLinuxDMABUFParamsResource* resource); void destroyResource(CLinuxDMABuffer* resource); void resetFormatTable(); @@ -123,7 +123,7 @@ class CLinuxDMABufV1Protocol : public IWaylandProtocol { // std::vector> m_vManagers; std::vector> m_vFeedbacks; - std::vector> m_vParams; + std::vector> m_vParams; std::vector> m_vBuffers; UP formatTable; @@ -132,7 +132,7 @@ class CLinuxDMABufV1Protocol : public IWaylandProtocol { friend class CLinuxDMABUFResource; friend class CLinuxDMABUFFeedbackResource; - friend class CLinuxDMABBUFParamsResource; + friend class CLinuxDMABUFParamsResource; friend class CLinuxDMABuffer; }; diff --git a/src/protocols/SinglePixel.cpp b/src/protocols/SinglePixel.cpp index 2fbfc93d..4d643a53 100644 --- a/src/protocols/SinglePixel.cpp +++ b/src/protocols/SinglePixel.cpp @@ -24,10 +24,6 @@ CSinglePixelBuffer::CSinglePixelBuffer(uint32_t id, wl_client* client, CHyprColo Debug::log(ERR, "Failed creating a single pixel texture: null texture id"); } -CSinglePixelBuffer::~CSinglePixelBuffer() { - ; -} - Aquamarine::eBufferCapability CSinglePixelBuffer::caps() { return Aquamarine::eBufferCapability::BUFFER_CAPABILITY_DATAPTR; } @@ -74,10 +70,6 @@ CSinglePixelBufferResource::CSinglePixelBufferResource(uint32_t id, wl_client* c }); } -CSinglePixelBufferResource::~CSinglePixelBufferResource() { - ; -} - bool CSinglePixelBufferResource::good() { return buffer->good(); } diff --git a/src/protocols/SinglePixel.hpp b/src/protocols/SinglePixel.hpp index 2a86d050..bd0607d6 100644 --- a/src/protocols/SinglePixel.hpp +++ b/src/protocols/SinglePixel.hpp @@ -9,7 +9,7 @@ class CSinglePixelBuffer : public IHLBuffer { public: CSinglePixelBuffer(uint32_t id, wl_client* client, CHyprColor col); - virtual ~CSinglePixelBuffer(); + virtual ~CSinglePixelBuffer() = default; virtual Aquamarine::eBufferCapability caps(); virtual Aquamarine::eBufferType type(); @@ -33,7 +33,7 @@ class CSinglePixelBuffer : public IHLBuffer { class CSinglePixelBufferResource { public: CSinglePixelBufferResource(uint32_t id, wl_client* client, CHyprColor color); - ~CSinglePixelBufferResource(); + ~CSinglePixelBufferResource() = default; bool good(); @@ -75,4 +75,4 @@ class CSinglePixelProtocol : public IWaylandProtocol { namespace PROTO { inline UP singlePixel; -}; \ No newline at end of file +}; diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp index 28585aeb..1649f82f 100644 --- a/src/protocols/core/Shm.cpp +++ b/src/protocols/core/Shm.cpp @@ -36,10 +36,6 @@ CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t of Debug::log(ERR, "Failed creating a shm texture: null texture id"); } -CWLSHMBuffer::~CWLSHMBuffer() { - ; -} - Aquamarine::eBufferCapability CWLSHMBuffer::caps() { return Aquamarine::eBufferCapability::BUFFER_CAPABILITY_DATAPTR; } diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index 23a465fb..d7e81367 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -31,7 +31,7 @@ class CSHMPool { class CWLSHMBuffer : public IHLBuffer { public: CWLSHMBuffer(SP pool, uint32_t id, int32_t offset, const Vector2D& size, int32_t stride, uint32_t fmt); - virtual ~CWLSHMBuffer(); + virtual ~CWLSHMBuffer() = default; virtual Aquamarine::eBufferCapability caps(); virtual Aquamarine::eBufferType type(); diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 6fb0ff88..5f2fdbda 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -10,10 +10,6 @@ CHyprBorderDecoration::CHyprBorderDecoration(PHLWINDOW pWindow) : IHyprWindowDec ; } -CHyprBorderDecoration::~CHyprBorderDecoration() { - ; -} - SDecorationPositioningInfo CHyprBorderDecoration::getPositioningInfo() { const auto BORDERSIZE = m_pWindow->getRealBorderSize(); m_seExtents = {{BORDERSIZE, BORDERSIZE}, {BORDERSIZE, BORDERSIZE}}; diff --git a/src/render/decorations/CHyprBorderDecoration.hpp b/src/render/decorations/CHyprBorderDecoration.hpp index bc9d7836..332c08b7 100644 --- a/src/render/decorations/CHyprBorderDecoration.hpp +++ b/src/render/decorations/CHyprBorderDecoration.hpp @@ -5,7 +5,7 @@ class CHyprBorderDecoration : public IHyprWindowDecoration { public: CHyprBorderDecoration(PHLWINDOW); - virtual ~CHyprBorderDecoration(); + virtual ~CHyprBorderDecoration() = default; virtual SDecorationPositioningInfo getPositioningInfo(); diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp index 0b2a96d9..60b1b33a 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.cpp +++ b/src/render/decorations/CHyprDropShadowDecoration.cpp @@ -9,8 +9,6 @@ CHyprDropShadowDecoration::CHyprDropShadowDecoration(PHLWINDOW pWindow) : IHyprW ; } -CHyprDropShadowDecoration::~CHyprDropShadowDecoration() = default; - eDecorationType CHyprDropShadowDecoration::getDecorationType() { return DECORATION_SHADOW; } diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp index 3b1c67c5..b5ee7276 100644 --- a/src/render/decorations/CHyprDropShadowDecoration.hpp +++ b/src/render/decorations/CHyprDropShadowDecoration.hpp @@ -5,7 +5,7 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration { public: CHyprDropShadowDecoration(PHLWINDOW); - virtual ~CHyprDropShadowDecoration(); + virtual ~CHyprDropShadowDecoration() = default; virtual SDecorationPositioningInfo getPositioningInfo(); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 4e7c3cbc..88501d74 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -29,8 +29,6 @@ CHyprGroupBarDecoration::CHyprGroupBarDecoration(PHLWINDOW pWindow) : IHyprWindo refreshGroupBarGradients(); } -CHyprGroupBarDecoration::~CHyprGroupBarDecoration() = default; - SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() { static auto PHEIGHT = CConfigValue("group:groupbar:height"); static auto PENABLED = CConfigValue("group:groupbar:enabled"); @@ -231,8 +229,6 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float texSize = tex->m_vSize; } -CTitleTex::~CTitleTex() = default; - void renderGradientTo(SP tex, CGradientValueData* grad) { if (!g_pCompositor->m_pLastMonitor) diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp index 7277955d..0cdf8a6b 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.hpp +++ b/src/render/decorations/CHyprGroupBarDecoration.hpp @@ -10,7 +10,7 @@ class CTitleTex { public: CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float monitorScale); - ~CTitleTex(); + ~CTitleTex() = default; SP tex; std::string szContent; @@ -24,7 +24,7 @@ void refreshGroupBarGradients(); class CHyprGroupBarDecoration : public IHyprWindowDecoration { public: CHyprGroupBarDecoration(PHLWINDOW); - virtual ~CHyprGroupBarDecoration(); + virtual ~CHyprGroupBarDecoration() = default; virtual SDecorationPositioningInfo getPositioningInfo(); diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp index cb9e166b..c71ee186 100644 --- a/src/render/decorations/IHyprWindowDecoration.cpp +++ b/src/render/decorations/IHyprWindowDecoration.cpp @@ -6,8 +6,6 @@ IHyprWindowDecoration::IHyprWindowDecoration(PHLWINDOW pWindow) : m_pWindow(pWin ; } -IHyprWindowDecoration::~IHyprWindowDecoration() = default; - bool IHyprWindowDecoration::onInputOnDeco(const eInputType, const Vector2D&, std::any) { return false; } diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp index 10145f40..2703eb61 100644 --- a/src/render/decorations/IHyprWindowDecoration.hpp +++ b/src/render/decorations/IHyprWindowDecoration.hpp @@ -33,7 +33,7 @@ class CDecorationPositioner; class IHyprWindowDecoration { public: IHyprWindowDecoration(PHLWINDOW); - virtual ~IHyprWindowDecoration() = 0; + virtual ~IHyprWindowDecoration() = default; virtual SDecorationPositioningInfo getPositioningInfo() = 0; From 32c0fa2f2fe02254d5887b38cf2cffa72ddfd769 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Thu, 30 Jan 2025 12:30:12 +0100 Subject: [PATCH 0207/1444] core: begin using CFileDescriptor from hyprutils (#9122) * config: make fd use CFileDescriptor make use of the new hyprutils CFileDescriptor instead of manual FD handling. * hyprctl: make fd use CFileDescriptor make use of the new hyprutils CFileDescriptor instead of manual FD handling. * ikeyboard: make fd use CFileDescriptor make use of the new CFileDescriptor instead of manual FD handling, also in sendKeymap remove dead code, it already early returns if keyboard isnt valid, and dont try to close the FD that ikeyboard owns. * core: make SHMFile functions use CFileDescriptor make SHMFile misc functions use CFileDescriptor and its associated usage in dmabuf and keyboard. * core: make explicit sync use CFileDescriptor begin using CFileDescriptor in explicit sync and its timelines and eglsync usage in opengl, there is still a bit left with manual handling that requires future aquamarine change aswell. * eventmgr: make fd and sockets use CFileDescriptor make use of the hyprutils CFileDescriptor instead of manual FD and socket handling and closing. * eventloopmgr: make timerfd use CFileDescriptor make the timerfd use CFileDescriptor instead of manual fd handling * opengl: make gbm fd use CFileDescriptor make the gbm rendernode fd use CFileDescriptor instead of manual fd handling * core: make selection source/offer use CFileDescriptor make data selection source and offers use CFileDescriptor and its associated use in xwm and protocols * protocols: convert protocols fd to CFileDescriptor make most fd handling use CFileDescriptor in protocols * shm: make SHMPool use CfileDescriptor make SHMPool use CFileDescriptor instead of manual fd handling. * opengl: duplicate fd with CFileDescriptor duplicate fenceFD with CFileDescriptor duplicate instead. * xwayland: make sockets and fds use CFileDescriptor instead of manual opening/closing make sockets and fds use CFileDescriptor * keybindmgr: make sockets and fds use CFileDescriptor make sockets and fds use CFileDescriptor instead of manual handling. --- src/config/ConfigWatcher.cpp | 25 ++- src/config/ConfigWatcher.hpp | 15 +- src/debug/HyprCtl.cpp | 18 +- src/debug/HyprCtl.hpp | 11 +- src/devices/IKeyboard.cpp | 26 ++- src/devices/IKeyboard.hpp | 3 +- src/helpers/MiscFunctions.cpp | 44 +++-- src/helpers/MiscFunctions.hpp | 5 +- src/helpers/Monitor.cpp | 17 +- src/helpers/Monitor.hpp | 1 + src/helpers/sync/SyncTimeline.cpp | 26 ++- src/helpers/sync/SyncTimeline.hpp | 28 ++-- src/managers/EventManager.cpp | 44 +++-- src/managers/EventManager.hpp | 14 +- src/managers/KeybindManager.cpp | 29 ++-- src/managers/eventLoop/EventLoopManager.cpp | 13 +- src/managers/eventLoop/EventLoopManager.hpp | 3 +- src/protocols/DRMLease.cpp | 17 +- src/protocols/DRMLease.hpp | 1 + src/protocols/DRMSyncobj.cpp | 12 +- src/protocols/DRMSyncobj.hpp | 7 +- src/protocols/DataDeviceWlr.cpp | 12 +- src/protocols/DataDeviceWlr.hpp | 3 +- src/protocols/GammaControl.cpp | 15 +- src/protocols/InputMethodV2.cpp | 11 +- src/protocols/LinuxDMABUF.cpp | 37 ++--- src/protocols/LinuxDMABUF.hpp | 9 +- src/protocols/PrimarySelection.cpp | 12 +- src/protocols/PrimarySelection.hpp | 3 +- src/protocols/SecurityContext.cpp | 21 ++- src/protocols/SecurityContext.hpp | 19 ++- src/protocols/VirtualKeyboard.cpp | 10 +- src/protocols/VirtualKeyboard.hpp | 1 + src/protocols/core/DataDevice.cpp | 12 +- src/protocols/core/DataDevice.hpp | 3 +- src/protocols/core/Seat.cpp | 29 +--- src/protocols/core/Shm.cpp | 23 +-- src/protocols/core/Shm.hpp | 14 +- src/protocols/types/DataDevice.hpp | 9 +- src/render/OpenGL.cpp | 41 ++--- src/render/OpenGL.hpp | 13 +- src/render/Renderer.cpp | 20 +-- src/xwayland/Dnd.cpp | 4 +- src/xwayland/Dnd.hpp | 3 +- src/xwayland/Server.cpp | 173 +++++++------------- src/xwayland/Server.hpp | 27 +-- src/xwayland/XDataSource.cpp | 13 +- src/xwayland/XDataSource.hpp | 5 +- src/xwayland/XWM.cpp | 20 +-- src/xwayland/XWM.hpp | 27 +-- 50 files changed, 422 insertions(+), 526 deletions(-) diff --git a/src/config/ConfigWatcher.cpp b/src/config/ConfigWatcher.cpp index c0a9c591..8d086bac 100644 --- a/src/config/ConfigWatcher.cpp +++ b/src/config/ConfigWatcher.cpp @@ -5,27 +5,24 @@ #include #include +using namespace Hyprutils::OS; + CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) { - if (m_inotifyFd < 0) { + if (!m_inotifyFd.isValid()) { Debug::log(ERR, "CConfigWatcher couldn't open an inotify node. Config will not be automatically reloaded"); return; } - const int FLAGS = fcntl(m_inotifyFd, F_GETFL, 0); - if (fcntl(m_inotifyFd, F_SETFL, FLAGS | O_NONBLOCK) < 0) { + // TODO: make CFileDescriptor take F_GETFL, F_SETFL + const int FLAGS = fcntl(m_inotifyFd.get(), F_GETFL, 0); + if (fcntl(m_inotifyFd.get(), F_SETFL, FLAGS | O_NONBLOCK) < 0) { Debug::log(ERR, "CConfigWatcher couldn't non-block inotify node. Config will not be automatically reloaded"); - close(m_inotifyFd); - m_inotifyFd = -1; + m_inotifyFd.reset(); return; } } -CConfigWatcher::~CConfigWatcher() { - if (m_inotifyFd >= 0) - close(m_inotifyFd); -} - -int CConfigWatcher::getInotifyFD() { +CFileDescriptor& CConfigWatcher::getInotifyFD() { return m_inotifyFd; } @@ -38,7 +35,7 @@ void CConfigWatcher::setWatchList(const std::vector& paths) { // cleanup old paths for (auto& watch : m_watches) { - inotify_rm_watch(m_inotifyFd, watch.wd); + inotify_rm_watch(m_inotifyFd.get(), watch.wd); } m_watches.clear(); @@ -46,7 +43,7 @@ void CConfigWatcher::setWatchList(const std::vector& paths) { // add new paths for (const auto& path : paths) { m_watches.emplace_back(SInotifyWatch{ - .wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY), + .wd = inotify_add_watch(m_inotifyFd.get(), path.c_str(), IN_MODIFY), .file = path, }); } @@ -58,7 +55,7 @@ void CConfigWatcher::setOnChange(const std::function 0) { + while (read(m_inotifyFd.get(), &ev, sizeof(ev)) > 0) { const auto WD = std::ranges::find_if(m_watches.begin(), m_watches.end(), [wd = ev.wd](const auto& e) { return e.wd == wd; }); if (WD == m_watches.end()) { diff --git a/src/config/ConfigWatcher.hpp b/src/config/ConfigWatcher.hpp index c36ecd17..97945689 100644 --- a/src/config/ConfigWatcher.hpp +++ b/src/config/ConfigWatcher.hpp @@ -3,20 +3,21 @@ #include #include #include +#include class CConfigWatcher { public: CConfigWatcher(); - ~CConfigWatcher(); + ~CConfigWatcher() = default; struct SConfigWatchEvent { std::string file; }; - int getInotifyFD(); - void setWatchList(const std::vector& paths); - void setOnChange(const std::function& fn); - void onInotifyEvent(); + Hyprutils::OS::CFileDescriptor& getInotifyFD(); + void setWatchList(const std::vector& paths); + void setOnChange(const std::function& fn); + void onInotifyEvent(); private: struct SInotifyWatch { @@ -26,7 +27,7 @@ class CConfigWatcher { std::function m_watchCallback; std::vector m_watches; - int m_inotifyFd = -1; + Hyprutils::OS::CFileDescriptor m_inotifyFd; }; -inline UP g_pConfigWatcher = makeUnique(); \ No newline at end of file +inline UP g_pConfigWatcher = makeUnique(); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 359428b1..cd6451e2 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -25,6 +25,7 @@ #include using namespace Hyprutils::String; +using namespace Hyprutils::OS; #include #include "../config/ConfigDataValues.hpp" @@ -1680,8 +1681,6 @@ CHyprCtl::CHyprCtl() { CHyprCtl::~CHyprCtl() { if (m_eventSource) wl_event_source_remove(m_eventSource); - if (m_iSocketFD >= 0) - close(m_iSocketFD); if (!m_socketPath.empty()) unlink(m_socketPath.c_str()); } @@ -1840,10 +1839,13 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) { if (mask & WL_EVENT_ERROR || mask & WL_EVENT_HANGUP) return 0; + if (!g_pHyprCtl->m_iSocketFD.isValid()) + return 0; + sockaddr_in clientAddress; socklen_t clientSize = sizeof(clientAddress); - const auto ACCEPTEDCONNECTION = accept4(g_pHyprCtl->m_iSocketFD, (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC); + const auto ACCEPTEDCONNECTION = accept4(g_pHyprCtl->m_iSocketFD.get(), (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC); std::array readBuffer; @@ -1900,9 +1902,9 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) { } void CHyprCtl::startHyprCtlSocket() { - m_iSocketFD = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + m_iSocketFD = CFileDescriptor{socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)}; - if (m_iSocketFD < 0) { + if (!m_iSocketFD.isValid()) { Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work."); return; } @@ -1913,15 +1915,15 @@ void CHyprCtl::startHyprCtlSocket() { strcpy(SERVERADDRESS.sun_path, m_socketPath.c_str()); - if (bind(m_iSocketFD, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) { + if (bind(m_iSocketFD.get(), (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) { Debug::log(ERR, "Couldn't start the Hyprland Socket. (2) IPC will not work."); return; } // 10 max queued. - listen(m_iSocketFD, 10); + listen(m_iSocketFD.get(), 10); Debug::log(LOG, "Hypr socket started at {}", m_socketPath); - m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD, WL_EVENT_READABLE, hyprCtlFDTick, nullptr); + m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD.get(), WL_EVENT_READABLE, hyprCtlFDTick, nullptr); } diff --git a/src/debug/HyprCtl.hpp b/src/debug/HyprCtl.hpp index eed8265c..a95a5f93 100644 --- a/src/debug/HyprCtl.hpp +++ b/src/debug/HyprCtl.hpp @@ -4,6 +4,7 @@ #include "../helpers/MiscFunctions.hpp" #include "../desktop/Window.hpp" #include +#include // exposed for main.cpp std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request); @@ -14,12 +15,12 @@ class CHyprCtl { CHyprCtl(); ~CHyprCtl(); - std::string makeDynamicCall(const std::string& input); - SP registerCommand(SHyprCtlCommand cmd); - void unregisterCommand(const SP& cmd); - std::string getReply(std::string); + std::string makeDynamicCall(const std::string& input); + SP registerCommand(SHyprCtlCommand cmd); + void unregisterCommand(const SP& cmd); + std::string getReply(std::string); - int m_iSocketFD = -1; + Hyprutils::OS::CFileDescriptor m_iSocketFD; struct { bool all = false; diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp index 4623fe84..307d840b 100644 --- a/src/devices/IKeyboard.cpp +++ b/src/devices/IKeyboard.cpp @@ -8,6 +8,8 @@ #include #include +using namespace Hyprutils::OS; + #define LED_COUNT 3 constexpr static std::array MODNAMES = { @@ -41,9 +43,6 @@ void IKeyboard::clearManuallyAllocd() { if (xkbKeymap) xkb_keymap_unref(xkbKeymap); - if (xkbKeymapFD >= 0) - close(xkbKeymapFD); - if (xkbSymState) xkb_state_unref(xkbSymState); @@ -51,7 +50,7 @@ void IKeyboard::clearManuallyAllocd() { xkbKeymap = nullptr; xkbState = nullptr; xkbStaticState = nullptr; - xkbKeymapFD = -1; + xkbKeymapFD.reset(); } void IKeyboard::setKeymap(const SStringRuleNames& rules) { @@ -147,31 +146,30 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) { void IKeyboard::updateKeymapFD() { Debug::log(LOG, "Updating keymap fd for keyboard {}", deviceName); - if (xkbKeymapFD >= 0) - close(xkbKeymapFD); - xkbKeymapFD = -1; + if (xkbKeymapFD.isValid()) + xkbKeymapFD.reset(); auto cKeymapStr = xkb_keymap_get_as_string(xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1); xkbKeymapString = cKeymapStr; free(cKeymapStr); - int rw, ro; - if (!allocateSHMFilePair(xkbKeymapString.length() + 1, &rw, &ro)) + CFileDescriptor rw, ro; + if (!allocateSHMFilePair(xkbKeymapString.length() + 1, rw, ro)) Debug::log(ERR, "IKeyboard: failed to allocate shm pair for the keymap"); else { - auto keymapFDDest = mmap(nullptr, xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw, 0); - close(rw); + auto keymapFDDest = mmap(nullptr, xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw.get(), 0); + rw.reset(); if (keymapFDDest == MAP_FAILED) { Debug::log(ERR, "IKeyboard: failed to mmap a shm pair for the keymap"); - close(ro); + ro.reset(); } else { memcpy(keymapFDDest, xkbKeymapString.c_str(), xkbKeymapString.length()); munmap(keymapFDDest, xkbKeymapString.length() + 1); - xkbKeymapFD = ro; + xkbKeymapFD = std::move(ro); } } - Debug::log(LOG, "Updated keymap fd to {}", xkbKeymapFD); + Debug::log(LOG, "Updated keymap fd to {}", xkbKeymapFD.get()); } void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) { diff --git a/src/devices/IKeyboard.hpp b/src/devices/IKeyboard.hpp index dce2127a..aabf4cc2 100644 --- a/src/devices/IKeyboard.hpp +++ b/src/devices/IKeyboard.hpp @@ -6,6 +6,7 @@ #include #include +#include AQUAMARINE_FORWARD(IKeyboard); @@ -96,7 +97,7 @@ class IKeyboard : public IHID { std::string xkbFilePath = ""; std::string xkbKeymapString = ""; - int xkbKeymapFD = -1; + Hyprutils::OS::CFileDescriptor xkbKeymapFD; SStringRuleNames currentRules; int repeatRate = 0; diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 5ebb0842..f532617c 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -836,50 +836,48 @@ bool envEnabled(const std::string& env) { return std::string(ENV) == "1"; } -std::pair openExclusiveShm() { +std::pair openExclusiveShm() { // Only absolute paths can be shared across different shm_open() calls std::string name = "/" + g_pTokenManager->getRandomUUID(); for (size_t i = 0; i < 69; ++i) { - int fd = shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd >= 0) - return {fd, name}; + CFileDescriptor fd{shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600)}; + if (fd.isValid()) + return {std::move(fd), name}; } - return {-1, ""}; + return {{}, ""}; } -int allocateSHMFile(size_t len) { +CFileDescriptor allocateSHMFile(size_t len) { auto [fd, name] = openExclusiveShm(); - if (fd < 0) - return -1; + if (!fd.isValid()) + return {}; shm_unlink(name.c_str()); int ret; do { - ret = ftruncate(fd, len); + ret = ftruncate(fd.get(), len); } while (ret < 0 && errno == EINTR); if (ret < 0) { - close(fd); - return -1; + return {}; } - return fd; + return std::move(fd); } -bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) { +bool allocateSHMFilePair(size_t size, CFileDescriptor& rw_fd_ptr, CFileDescriptor& ro_fd_ptr) { auto [fd, name] = openExclusiveShm(); - if (fd < 0) { + if (!fd.isValid()) { return false; } // CLOEXEC is guaranteed to be set by shm_open - int ro_fd = shm_open(name.c_str(), O_RDONLY, 0); - if (ro_fd < 0) { + CFileDescriptor ro_fd{shm_open(name.c_str(), O_RDONLY, 0)}; + if (!ro_fd.isValid()) { shm_unlink(name.c_str()); - close(fd); return false; } @@ -887,24 +885,20 @@ bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) { // Make sure the file cannot be re-opened in read-write mode (e.g. via // "/proc/self/fd/" on Linux) - if (fchmod(fd, 0) != 0) { - close(fd); - close(ro_fd); + if (fchmod(fd.get(), 0) != 0) { return false; } int ret; do { - ret = ftruncate(fd, size); + ret = ftruncate(fd.get(), size); } while (ret < 0 && errno == EINTR); if (ret < 0) { - close(fd); - close(ro_fd); return false; } - *rw_fd_ptr = fd; - *ro_fd_ptr = ro_fd; + rw_fd_ptr = std::move(fd); + ro_fd_ptr = std::move(ro_fd); return true; } diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index d0824284..bd288638 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../SharedDefs.hpp" #include "../macros.hpp" @@ -35,8 +36,8 @@ double normalizeAngleRad(double ang); std::vector getBacktrace(); void throwError(const std::string& err); bool envEnabled(const std::string& env); -int allocateSHMFile(size_t len); -bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr); +Hyprutils::OS::CFileDescriptor allocateSHMFile(size_t len); +bool allocateSHMFilePair(size_t size, Hyprutils::OS::CFileDescriptor& rw_fd_ptr, Hyprutils::OS::CFileDescriptor& ro_fd_ptr); float stringToPercentage(const std::string& VALUE, const float REL); template diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 42acf485..fc3de3aa 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -32,6 +32,7 @@ #include using namespace Hyprutils::String; using namespace Hyprutils::Utils; +using namespace Hyprutils::OS; static int ratHandler(void* data) { g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock()); @@ -1301,19 +1302,15 @@ bool CMonitor::attemptDirectScanout() { // wait for the explicit fence if present, and if kms explicit is allowed bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->syncobj->current.acquireTimeline && PSURFACE->syncobj->current.acquireTimeline->timeline && explicitOptions.explicitKMSEnabled; - int explicitWaitFD = -1; + CFileDescriptor explicitWaitFD; if (DOEXPLICIT) { explicitWaitFD = PSURFACE->syncobj->current.acquireTimeline->timeline->exportAsSyncFileFD(PSURFACE->syncobj->current.acquirePoint); - if (explicitWaitFD < 0) + if (!explicitWaitFD.isValid()) Debug::log(TRACE, "attemptDirectScanout: failed to acquire an explicit wait fd"); } - DOEXPLICIT = DOEXPLICIT && explicitWaitFD >= 0; + DOEXPLICIT = DOEXPLICIT && explicitWaitFD.isValid(); - auto cleanup = CScopeGuard([explicitWaitFD, this]() { - output->state->resetExplicitFences(); - if (explicitWaitFD >= 0) - close(explicitWaitFD); - }); + auto cleanup = CScopeGuard([this]() { output->state->resetExplicitFences(); }); timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -1323,8 +1320,8 @@ bool CMonitor::attemptDirectScanout() { output->state->resetExplicitFences(); if (DOEXPLICIT) { - Debug::log(TRACE, "attemptDirectScanout: setting IN_FENCE for aq to {}", explicitWaitFD); - output->state->setExplicitInFence(explicitWaitFD); + Debug::log(TRACE, "attemptDirectScanout: setting IN_FENCE for aq to {}", explicitWaitFD.get()); + output->state->setExplicitInFence(explicitWaitFD.get()); } bool ok = output->commit(); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 2b02c30a..c67bccc5 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -16,6 +16,7 @@ #include "DamageRing.hpp" #include #include +#include // Enum for the different types of auto directions, e.g. auto-left, auto-up. enum eAutoDirs : uint8_t { diff --git a/src/helpers/sync/SyncTimeline.cpp b/src/helpers/sync/SyncTimeline.cpp index 16b5bd92..46b617bc 100644 --- a/src/helpers/sync/SyncTimeline.cpp +++ b/src/helpers/sync/SyncTimeline.cpp @@ -4,6 +4,7 @@ #include #include +using namespace Hyprutils::OS; SP CSyncTimeline::create(int drmFD_) { auto timeline = SP(new CSyncTimeline); @@ -85,10 +86,9 @@ bool CSyncTimeline::addWaiter(const std::function& waiter, uint64_t poin auto w = makeShared(); w->fn = waiter; w->timeline = self; + w->eventFd = CFileDescriptor{eventfd(0, EFD_CLOEXEC)}; - int eventFD = eventfd(0, EFD_CLOEXEC); - - if (eventFD < 0) { + if (!w->eventFd.isValid()) { Debug::log(ERR, "CSyncTimeline::addWaiter: failed to acquire an eventfd"); return false; } @@ -97,19 +97,17 @@ bool CSyncTimeline::addWaiter(const std::function& waiter, uint64_t poin .handle = handle, .flags = flags, .point = point, - .fd = eventFD, + .fd = w->eventFd.get(), }; if (drmIoctl(drmFD, DRM_IOCTL_SYNCOBJ_EVENTFD, &syncobjEventFD) != 0) { Debug::log(ERR, "CSyncTimeline::addWaiter: drmIoctl failed"); - close(eventFD); return false; } - w->source = wl_event_loop_add_fd(g_pEventLoopManager->m_sWayland.loop, eventFD, WL_EVENT_READABLE, ::handleWaiterFD, w.get()); + w->source = wl_event_loop_add_fd(g_pEventLoopManager->m_sWayland.loop, w->eventFd.get(), WL_EVENT_READABLE, ::handleWaiterFD, w.get()); if (!w->source) { Debug::log(ERR, "CSyncTimeline::addWaiter: wl_event_loop_add_fd failed"); - close(eventFD); return false; } @@ -126,32 +124,32 @@ void CSyncTimeline::removeWaiter(SWaiter* w) { std::erase_if(waiters, [w](const auto& e) { return e.get() == w; }); } -int CSyncTimeline::exportAsSyncFileFD(uint64_t src) { +CFileDescriptor CSyncTimeline::exportAsSyncFileFD(uint64_t src) { int sync = -1; uint32_t syncHandle = 0; if (drmSyncobjCreate(drmFD, 0, &syncHandle)) { Debug::log(ERR, "exportAsSyncFileFD: drmSyncobjCreate failed"); - return -1; + return {}; } if (drmSyncobjTransfer(drmFD, syncHandle, 0, handle, src, 0)) { Debug::log(ERR, "exportAsSyncFileFD: drmSyncobjTransfer failed"); drmSyncobjDestroy(drmFD, syncHandle); - return -1; + return {}; } if (drmSyncobjExportSyncFile(drmFD, syncHandle, &sync)) { Debug::log(ERR, "exportAsSyncFileFD: drmSyncobjExportSyncFile failed"); drmSyncobjDestroy(drmFD, syncHandle); - return -1; + return {}; } drmSyncobjDestroy(drmFD, syncHandle); - return sync; + return CFileDescriptor{sync}; } -bool CSyncTimeline::importFromSyncFileFD(uint64_t dst, int fd) { +bool CSyncTimeline::importFromSyncFileFD(uint64_t dst, CFileDescriptor& fd) { uint32_t syncHandle = 0; if (drmSyncobjCreate(drmFD, 0, &syncHandle)) { @@ -159,7 +157,7 @@ bool CSyncTimeline::importFromSyncFileFD(uint64_t dst, int fd) { return false; } - if (drmSyncobjImportSyncFile(drmFD, syncHandle, fd)) { + if (drmSyncobjImportSyncFile(drmFD, syncHandle, fd.get())) { Debug::log(ERR, "importFromSyncFileFD: drmSyncobjImportSyncFile failed"); drmSyncobjDestroy(drmFD, syncHandle); return false; diff --git a/src/helpers/sync/SyncTimeline.hpp b/src/helpers/sync/SyncTimeline.hpp index 88ad4921..ba65e004 100644 --- a/src/helpers/sync/SyncTimeline.hpp +++ b/src/helpers/sync/SyncTimeline.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "../memory/Memory.hpp" /* @@ -20,26 +21,27 @@ class CSyncTimeline { ~CSyncTimeline(); struct SWaiter { - std::function fn; - wl_event_source* source = nullptr; - WP timeline; + std::function fn; + wl_event_source* source = nullptr; + WP timeline; + Hyprutils::OS::CFileDescriptor eventFd; }; // check if the timeline point has been signaled // flags: DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT or DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE // std::nullopt on fail - std::optional check(uint64_t point, uint32_t flags); + std::optional check(uint64_t point, uint32_t flags); - bool addWaiter(const std::function& waiter, uint64_t point, uint32_t flags); - void removeWaiter(SWaiter*); - int exportAsSyncFileFD(uint64_t src); - bool importFromSyncFileFD(uint64_t dst, int fd); - bool transfer(SP from, uint64_t fromPoint, uint64_t toPoint); - void signal(uint64_t point); + bool addWaiter(const std::function& waiter, uint64_t point, uint32_t flags); + void removeWaiter(SWaiter*); + Hyprutils::OS::CFileDescriptor exportAsSyncFileFD(uint64_t src); + bool importFromSyncFileFD(uint64_t dst, Hyprutils::OS::CFileDescriptor& fd); + bool transfer(SP from, uint64_t fromPoint, uint64_t toPoint); + void signal(uint64_t point); - int drmFD = -1; - uint32_t handle = 0; - WP self; + int drmFD = -1; + uint32_t handle = 0; + WP self; private: CSyncTimeline() = default; diff --git a/src/managers/EventManager.cpp b/src/managers/EventManager.cpp index fc55b472..6231f0bc 100644 --- a/src/managers/EventManager.cpp +++ b/src/managers/EventManager.cpp @@ -9,9 +9,10 @@ #include #include #include +using namespace Hyprutils::OS; CEventManager::CEventManager() : m_iSocketFD(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) { - if (m_iSocketFD < 0) { + if (!m_iSocketFD.isValid()) { Debug::log(ERR, "Couldn't start the Hyprland Socket 2. (1) IPC will not work."); return; } @@ -25,31 +26,27 @@ CEventManager::CEventManager() : m_iSocketFD(socket(AF_UNIX, SOCK_STREAM | SOCK_ strncpy(SERVERADDRESS.sun_path, PATH.c_str(), sizeof(SERVERADDRESS.sun_path) - 1); - if (bind(m_iSocketFD, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) { + if (bind(m_iSocketFD.get(), (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) { Debug::log(ERR, "Couldn't bind the Hyprland Socket 2. (3) IPC will not work."); return; } // 10 max queued. - if (listen(m_iSocketFD, 10) < 0) { + if (listen(m_iSocketFD.get(), 10) < 0) { Debug::log(ERR, "Couldn't listen on the Hyprland Socket 2. (4) IPC will not work."); return; } - m_pEventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD, WL_EVENT_READABLE, onClientEvent, nullptr); + m_pEventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, m_iSocketFD.get(), WL_EVENT_READABLE, onClientEvent, nullptr); } CEventManager::~CEventManager() { for (const auto& client : m_vClients) { wl_event_source_remove(client.eventSource); - close(client.fd); } if (m_pEventSource != nullptr) wl_event_source_remove(m_pEventSource); - - if (m_iSocketFD >= 0) - close(m_iSocketFD); } int CEventManager::onServerEvent(int fd, uint32_t mask, void* data) { @@ -66,33 +63,31 @@ int CEventManager::onServerEvent(int fd, uint32_t mask) { wl_event_source_remove(m_pEventSource); m_pEventSource = nullptr; - close(fd); - m_iSocketFD = -1; + m_iSocketFD.reset(); return 0; } - sockaddr_in clientAddress; - socklen_t clientSize = sizeof(clientAddress); - const auto ACCEPTEDCONNECTION = accept4(m_iSocketFD, (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC | SOCK_NONBLOCK); - if (ACCEPTEDCONNECTION < 0) { + sockaddr_in clientAddress; + socklen_t clientSize = sizeof(clientAddress); + CFileDescriptor ACCEPTEDCONNECTION{accept4(m_iSocketFD.get(), (sockaddr*)&clientAddress, &clientSize, SOCK_CLOEXEC | SOCK_NONBLOCK)}; + if (!ACCEPTEDCONNECTION.isValid()) { if (errno != EAGAIN) { Debug::log(ERR, "Socket2 failed receiving connection, errno: {}", errno); wl_event_source_remove(m_pEventSource); m_pEventSource = nullptr; - close(fd); - m_iSocketFD = -1; + m_iSocketFD.reset(); } return 0; } - Debug::log(LOG, "Socket2 accepted a new client at FD {}", ACCEPTEDCONNECTION); + Debug::log(LOG, "Socket2 accepted a new client at FD {}", ACCEPTEDCONNECTION.get()); // add to event loop so we can close it when we need to - auto* eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, ACCEPTEDCONNECTION, 0, onServerEvent, nullptr); + auto* eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, ACCEPTEDCONNECTION.get(), 0, onServerEvent, nullptr); m_vClients.emplace_back(SClient{ - ACCEPTEDCONNECTION, + std::move(ACCEPTEDCONNECTION), {}, eventSource, }); @@ -113,7 +108,7 @@ int CEventManager::onClientEvent(int fd, uint32_t mask) { // send all queued events while (!CLIENTIT->events.empty()) { const auto& event = CLIENTIT->events.front(); - if (write(CLIENTIT->fd, event->c_str(), event->length()) < 0) + if (write(CLIENTIT->fd.get(), event->c_str(), event->length()) < 0) break; CLIENTIT->events.erase(CLIENTIT->events.begin()); @@ -128,13 +123,12 @@ int CEventManager::onClientEvent(int fd, uint32_t mask) { } std::vector::iterator CEventManager::findClientByFD(int fd) { - return std::find_if(m_vClients.begin(), m_vClients.end(), [fd](const auto& client) { return client.fd == fd; }); + return std::find_if(m_vClients.begin(), m_vClients.end(), [fd](const auto& client) { return client.fd.get() == fd; }); } std::vector::iterator CEventManager::removeClientByFD(int fd) { const auto CLIENTIT = findClientByFD(fd); wl_event_source_remove(CLIENTIT->eventSource); - close(fd); return m_vClients.erase(CLIENTIT); } @@ -157,11 +151,11 @@ void CEventManager::postEvent(const SHyprIPCEvent& event) { for (auto it = m_vClients.begin(); it != m_vClients.end();) { // try to send the event immediately if the queue is empty const auto QUEUESIZE = it->events.size(); - if (QUEUESIZE > 0 || write(it->fd, sharedEvent->c_str(), sharedEvent->length()) < 0) { + if (QUEUESIZE > 0 || write(it->fd.get(), sharedEvent->c_str(), sharedEvent->length()) < 0) { if (QUEUESIZE >= MAX_QUEUED_EVENTS) { // too many events queued, remove the client - Debug::log(ERR, "Socket2 fd {} overflowed event queue, removing", it->fd); - it = removeClientByFD(it->fd); + Debug::log(ERR, "Socket2 fd {} overflowed event queue, removing", it->fd.get()); + it = removeClientByFD(it->fd.get()); continue; } diff --git a/src/managers/EventManager.hpp b/src/managers/EventManager.hpp index 6b506d33..c8335d20 100644 --- a/src/managers/EventManager.hpp +++ b/src/managers/EventManager.hpp @@ -1,6 +1,6 @@ #pragma once #include - +#include #include "../defines.hpp" #include "../helpers/memory/Memory.hpp" @@ -26,19 +26,19 @@ class CEventManager { int onClientEvent(int fd, uint32_t mask); struct SClient { - int fd = -1; - std::vector> events; - wl_event_source* eventSource = nullptr; + Hyprutils::OS::CFileDescriptor fd; + std::vector> events; + wl_event_source* eventSource = nullptr; }; std::vector::iterator findClientByFD(int fd); std::vector::iterator removeClientByFD(int fd); private: - int m_iSocketFD = -1; - wl_event_source* m_pEventSource = nullptr; + Hyprutils::OS::CFileDescriptor m_iSocketFD; + wl_event_source* m_pEventSource = nullptr; - std::vector m_vClients; + std::vector m_vClients; }; inline UP g_pEventManager; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 2cb77d21..247550ae 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -28,7 +28,9 @@ #include #include +#include using namespace Hyprutils::String; +using namespace Hyprutils::OS; #include #include @@ -853,19 +855,18 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) { const unsigned int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1; // vtnr is bugged for some reason. - unsigned int ttynum = 0; - int fd; - if ((fd = open("/dev/tty", O_RDONLY | O_NOCTTY)) >= 0) { + unsigned int ttynum = 0; + Hyprutils::OS::CFileDescriptor fd{open("/dev/tty", O_RDONLY | O_NOCTTY)}; + if (fd.isValid()) { #if defined(VT_GETSTATE) struct vt_stat st; - if (!ioctl(fd, VT_GETSTATE, &st)) + if (!ioctl(fd.get(), VT_GETSTATE, &st)) ttynum = st.v_active; #elif defined(VT_GETACTIVE) int vt; - if (!ioctl(fd, VT_GETACTIVE, &vt)) + if (!ioctl(fd.get(), VT_GETACTIVE, &vt)) ttynum = vt; #endif - close(fd); } if (ttynum == TTY) @@ -944,11 +945,11 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo Debug::log(LOG, "Unable to create pipe for fork"); } - pid_t child, grandchild; + CFileDescriptor pipeSock[2] = {CFileDescriptor{socket[0]}, CFileDescriptor{socket[1]}}; + + pid_t child, grandchild; child = fork(); if (child < 0) { - close(socket[0]); - close(socket[1]); Debug::log(LOG, "Fail to create the first fork"); return 0; } @@ -967,22 +968,16 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo setenv(e.first.c_str(), e.second.c_str(), 1); } setenv("WAYLAND_DISPLAY", g_pCompositor->m_szWLDisplaySocket.c_str(), 1); - close(socket[0]); - close(socket[1]); execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr); // exit grandchild _exit(0); } - close(socket[0]); - write(socket[1], &grandchild, sizeof(grandchild)); - close(socket[1]); + write(pipeSock[1].get(), &grandchild, sizeof(grandchild)); // exit child _exit(0); } // run in parent - close(socket[1]); - read(socket[0], &grandchild, sizeof(grandchild)); - close(socket[0]); + read(pipeSock[0].get(), &grandchild, sizeof(grandchild)); // clear child and leave grandchild to init waitpid(child, nullptr, 0); if (grandchild < 0) { diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index 4021c171..83bdf4a0 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -11,11 +11,12 @@ #include #include +using namespace Hyprutils::OS; #define TIMESPEC_NSEC_PER_SEC 1000000000L CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEventLoop) { - m_sTimers.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + m_sTimers.timerfd = CFileDescriptor{timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC)}; m_sWayland.loop = wlEventLoop; m_sWayland.display = display; } @@ -31,8 +32,6 @@ CEventLoopManager::~CEventLoopManager() { wl_event_source_remove(m_sIdle.eventSource); if (m_configWatcherInotifySource) wl_event_source_remove(m_configWatcherInotifySource); - if (m_sTimers.timerfd >= 0) - close(m_sTimers.timerfd); } static int timerWrite(int fd, uint32_t mask, void* data) { @@ -52,10 +51,10 @@ static int configWatcherWrite(int fd, uint32_t mask, void* data) { } void CEventLoopManager::enterLoop() { - m_sWayland.eventSource = wl_event_loop_add_fd(m_sWayland.loop, m_sTimers.timerfd, WL_EVENT_READABLE, timerWrite, nullptr); + m_sWayland.eventSource = wl_event_loop_add_fd(m_sWayland.loop, m_sTimers.timerfd.get(), WL_EVENT_READABLE, timerWrite, nullptr); - if (const auto FD = g_pConfigWatcher->getInotifyFD(); FD >= 0) - m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD, WL_EVENT_READABLE, configWatcherWrite, nullptr); + if (const auto& FD = g_pConfigWatcher->getInotifyFD(); FD.isValid()) + m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD.get(), WL_EVENT_READABLE, configWatcherWrite, nullptr); syncPollFDs(); m_sListeners.pollFDsChanged = g_pCompositor->m_pAqBackend->events.pollFDsChanged.registerListener([this](std::any d) { syncPollFDs(); }); @@ -120,7 +119,7 @@ void CEventLoopManager::nudgeTimers() { itimerspec ts = {.it_value = now}; - timerfd_settime(m_sTimers.timerfd, TFD_TIMER_ABSTIME, &ts, nullptr); + timerfd_settime(m_sTimers.timerfd.get(), TFD_TIMER_ABSTIME, &ts, nullptr); } void CEventLoopManager::doLater(const std::function& fn) { diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp index 95cc6109..ebeb2160 100644 --- a/src/managers/eventLoop/EventLoopManager.hpp +++ b/src/managers/eventLoop/EventLoopManager.hpp @@ -6,6 +6,7 @@ #include #include #include "helpers/signal/Signal.hpp" +#include #include "EventLoopTimer.hpp" @@ -54,7 +55,7 @@ class CEventLoopManager { struct { std::vector> timers; - int timerfd = -1; + Hyprutils::OS::CFileDescriptor timerfd; } m_sTimers; SIdleData m_sIdle; diff --git a/src/protocols/DRMLease.cpp b/src/protocols/DRMLease.cpp index 6fdbaf4b..e70f0441 100644 --- a/src/protocols/DRMLease.cpp +++ b/src/protocols/DRMLease.cpp @@ -4,6 +4,7 @@ #include "managers/eventLoop/EventLoopManager.hpp" #include #include +using namespace Hyprutils::OS; CDRMLeaseResource::CDRMLeaseResource(SP resource_, SP request) : resource(resource_) { if UNLIKELY (!good()) @@ -185,15 +186,14 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP resourc RESOURCE->parent = self; }); - int fd = ((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD(); - if (fd < 0) { + CFileDescriptor fd{((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD()}; + if (!fd.isValid()) { LOGM(ERR, "Failed to dup fd in lease"); return; } - LOGM(LOG, "Sending DRMFD {} to new lease device", fd); - resource->sendDrmFd(fd); - close(fd); + LOGM(LOG, "Sending DRMFD {} to new lease device", fd.get()); + resource->sendDrmFd(fd.get()); for (auto const& m : PROTO::lease->primaryDevice->offeredOutputs) { if (m) @@ -231,16 +231,15 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) { } CDRMLeaseDevice::CDRMLeaseDevice(SP drmBackend) : backend(drmBackend) { - auto drm = (Aquamarine::CDRMBackend*)drmBackend.get(); + auto drm = (Aquamarine::CDRMBackend*)drmBackend.get(); - auto fd = drm->getNonMasterFD(); + CFileDescriptor fd{drm->getNonMasterFD()}; - if (fd < 0) { + if (!fd.isValid()) { LOGM(ERR, "Failed to dup fd for drm node {}", drm->gpuName); return; } - close(fd); success = true; name = drm->gpuName; } diff --git a/src/protocols/DRMLease.hpp b/src/protocols/DRMLease.hpp index ec1e73f2..c7849149 100644 --- a/src/protocols/DRMLease.hpp +++ b/src/protocols/DRMLease.hpp @@ -5,6 +5,7 @@ #include "WaylandProtocol.hpp" #include "drm-lease-v1.hpp" #include "../helpers/signal/Signal.hpp" +#include /* TODO: this protocol is not made for systems with multiple DRM nodes (e.g. multigpu) diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp index ce598385..23dafbca 100644 --- a/src/protocols/DRMSyncobj.cpp +++ b/src/protocols/DRMSyncobj.cpp @@ -6,6 +6,7 @@ #include "../Compositor.hpp" #include +using namespace Hyprutils::OS; CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { if UNLIKELY (!good()) @@ -103,7 +104,7 @@ bool CDRMSyncobjSurfaceResource::good() { return resource->resource(); } -CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP resource_, int fd_) : fd(fd_), resource(resource_) { +CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP resource_, CFileDescriptor fd_) : fd(std::move(fd_)), resource(resource_) { if UNLIKELY (!good()) return; @@ -112,7 +113,7 @@ CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SPsetOnDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); }); resource->setDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); }); - timeline = CSyncTimeline::create(PROTO::sync->drmFD, fd); + timeline = CSyncTimeline::create(PROTO::sync->drmFD, fd.get()); if (!timeline) { resource->error(WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_INVALID_TIMELINE, "Timeline failed importing"); @@ -120,11 +121,6 @@ CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP= 0) - close(fd); -} - SP CDRMSyncobjTimelineResource::fromResource(wl_resource* res) { auto data = (CDRMSyncobjTimelineResource*)(((CWpLinuxDrmSyncobjTimelineV1*)wl_resource_get_user_data(res))->data()); return data ? data->self.lock() : nullptr; @@ -171,7 +167,7 @@ CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(SPsetImportTimeline([this](CWpLinuxDrmSyncobjManagerV1* r, uint32_t id, int32_t fd) { - auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id), fd); + auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id), CFileDescriptor{fd}); if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); return; diff --git a/src/protocols/DRMSyncobj.hpp b/src/protocols/DRMSyncobj.hpp index 42ecdb3e..8677576f 100644 --- a/src/protocols/DRMSyncobj.hpp +++ b/src/protocols/DRMSyncobj.hpp @@ -4,6 +4,7 @@ #include "WaylandProtocol.hpp" #include "linux-drm-syncobj-v1.hpp" #include "../helpers/signal/Signal.hpp" +#include class CWLSurfaceResource; class CDRMSyncobjTimelineResource; @@ -32,14 +33,14 @@ class CDRMSyncobjSurfaceResource { class CDRMSyncobjTimelineResource { public: - CDRMSyncobjTimelineResource(SP resource_, int fd_); - ~CDRMSyncobjTimelineResource(); + CDRMSyncobjTimelineResource(SP resource_, Hyprutils::OS::CFileDescriptor fd_); + ~CDRMSyncobjTimelineResource() = default; static SP fromResource(wl_resource*); bool good(); WP self; - int fd = -1; + Hyprutils::OS::CFileDescriptor fd; SP timeline; private: diff --git a/src/protocols/DataDeviceWlr.cpp b/src/protocols/DataDeviceWlr.cpp index 71ee1c4a..3da5afd6 100644 --- a/src/protocols/DataDeviceWlr.cpp +++ b/src/protocols/DataDeviceWlr.cpp @@ -2,6 +2,7 @@ #include #include "../managers/SeatManager.hpp" #include "core/Seat.hpp" +using namespace Hyprutils::OS; CWLRDataOffer::CWLRDataOffer(SP resource_, SP source_) : source(source_), resource(resource_) { if UNLIKELY (!good()) @@ -11,21 +12,20 @@ CWLRDataOffer::CWLRDataOffer(SP resource_, SPsetOnDestroy([this](CZwlrDataControlOfferV1* r) { PROTO::dataWlr->destroyResource(this); }); resource->setReceive([this](CZwlrDataControlOfferV1* r, const char* mime, int32_t fd) { + CFileDescriptor sendFd{fd}; if (!source) { LOGM(WARN, "Possible bug: Receive on an offer w/o a source"); - close(fd); return; } if (dead) { LOGM(WARN, "Possible bug: Receive on an offer that's dead"); - close(fd); return; } LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get()); - source->send(mime, fd); + source->send(mime, std::move(sendFd)); }); } @@ -77,15 +77,13 @@ std::vector CWLRDataSource::mimes() { return mimeTypes; } -void CWLRDataSource::send(const std::string& mime, uint32_t fd) { +void CWLRDataSource::send(const std::string& mime, CFileDescriptor fd) { if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) { LOGM(ERR, "Compositor/App bug: CWLRDataSource::sendAskSend with non-existent mime"); - close(fd); return; } - resource->sendSend(mime.c_str(), fd); - close(fd); + resource->sendSend(mime.c_str(), fd.get()); } void CWLRDataSource::accepted(const std::string& mime) { diff --git a/src/protocols/DataDeviceWlr.hpp b/src/protocols/DataDeviceWlr.hpp index 5eef163c..7f14b320 100644 --- a/src/protocols/DataDeviceWlr.hpp +++ b/src/protocols/DataDeviceWlr.hpp @@ -5,6 +5,7 @@ #include "WaylandProtocol.hpp" #include "wlr-data-control-unstable-v1.hpp" #include "types/DataDevice.hpp" +#include class CWLRDataControlManagerResource; class CWLRDataSource; @@ -38,7 +39,7 @@ class CWLRDataSource : public IDataSource { bool good(); virtual std::vector mimes(); - virtual void send(const std::string& mime, uint32_t fd); + virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd); virtual void accepted(const std::string& mime); virtual void cancelled(); virtual void error(uint32_t code, const std::string& msg); diff --git a/src/protocols/GammaControl.cpp b/src/protocols/GammaControl.cpp index 43ba9d41..0a383e2e 100644 --- a/src/protocols/GammaControl.cpp +++ b/src/protocols/GammaControl.cpp @@ -4,6 +4,7 @@ #include "../helpers/Monitor.hpp" #include "../protocols/core/Output.hpp" #include "../render/Renderer.hpp" +using namespace Hyprutils::OS; CGammaControl::CGammaControl(SP resource_, wl_resource* output) : resource(resource_) { if UNLIKELY (!resource_->resource()) @@ -46,34 +47,33 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out resource->setOnDestroy([this](CZwlrGammaControlV1* gamma) { PROTO::gamma->destroyGammaControl(this); }); resource->setSetGamma([this](CZwlrGammaControlV1* gamma, int32_t fd) { + CFileDescriptor gammaFd{fd}; if UNLIKELY (!pMonitor) { LOGM(ERR, "setGamma for a dead monitor"); resource->sendFailed(); - close(fd); return; } LOGM(LOG, "setGamma for {}", pMonitor->szName); - int fdFlags = fcntl(fd, F_GETFL, 0); + // TODO: make CFileDescriptor getflags use F_GETFL + int fdFlags = fcntl(gammaFd.get(), F_GETFL, 0); if UNLIKELY (fdFlags < 0) { LOGM(ERR, "Failed to get fd flags"); resource->sendFailed(); - close(fd); return; } - if UNLIKELY (fcntl(fd, F_SETFL, fdFlags | O_NONBLOCK) < 0) { + // TODO: make CFileDescriptor setflags use F_SETFL + if UNLIKELY (fcntl(gammaFd.get(), F_SETFL, fdFlags | O_NONBLOCK) < 0) { LOGM(ERR, "Failed to set fd flags"); resource->sendFailed(); - close(fd); return; } - ssize_t readBytes = pread(fd, gammaTable.data(), gammaTable.size() * sizeof(uint16_t), 0); + ssize_t readBytes = pread(gammaFd.get(), gammaTable.data(), gammaTable.size() * sizeof(uint16_t), 0); if (readBytes < 0 || (size_t)readBytes != gammaTable.size() * sizeof(uint16_t)) { LOGM(ERR, "Failed to read bytes"); - close(fd); if ((size_t)readBytes != gammaTable.size() * sizeof(uint16_t)) { gamma->error(ZWLR_GAMMA_CONTROL_V1_ERROR_INVALID_GAMMA, "Gamma ramps size mismatch"); @@ -85,7 +85,6 @@ CGammaControl::CGammaControl(SP resource_, wl_resource* out } gammaTableSet = true; - close(fd); // translate the table to AQ format std::vector red, green, blue; diff --git a/src/protocols/InputMethodV2.cpp b/src/protocols/InputMethodV2.cpp index 796cec06..33121ecd 100644 --- a/src/protocols/InputMethodV2.cpp +++ b/src/protocols/InputMethodV2.cpp @@ -33,25 +33,22 @@ void CInputMethodKeyboardGrabV2::sendKeyboardData(SP keyboard) { pLastKeyboard = keyboard; - int keymapFD = allocateSHMFile(keyboard->xkbKeymapString.length() + 1); - if UNLIKELY (keymapFD < 0) { + auto keymapFD = allocateSHMFile(keyboard->xkbKeymapString.length() + 1); + if UNLIKELY (!keymapFD.isValid()) { LOGM(ERR, "Failed to create a keymap file for keyboard grab"); return; } - void* data = mmap(nullptr, keyboard->xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD, 0); + void* data = mmap(nullptr, keyboard->xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, keymapFD.get(), 0); if UNLIKELY (data == MAP_FAILED) { LOGM(ERR, "Failed to mmap a keymap file for keyboard grab"); - close(keymapFD); return; } memcpy(data, keyboard->xkbKeymapString.c_str(), keyboard->xkbKeymapString.length()); munmap(data, keyboard->xkbKeymapString.length() + 1); - resource->sendKeymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymapFD, keyboard->xkbKeymapString.length() + 1); - - close(keymapFD); + resource->sendKeymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymapFD.get(), keyboard->xkbKeymapString.length() + 1); sendMods(keyboard->modifiersState.depressed, keyboard->modifiersState.latched, keyboard->modifiersState.locked, keyboard->modifiersState.group); diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp index d3135da0..b7b91594 100644 --- a/src/protocols/LinuxDMABUF.cpp +++ b/src/protocols/LinuxDMABUF.cpp @@ -14,6 +14,8 @@ #include "../render/OpenGL.hpp" #include "../Compositor.hpp" +using namespace Hyprutils::OS; + static std::optional devIDFromFD(int fd) { struct stat stat; if (fstat(fd, &stat) != 0) @@ -77,29 +79,21 @@ CDMABUFFormatTable::CDMABUFFormatTable(SDMABUFTranche _rendererTranche, std::vec tableSize = formatsVec.size() * sizeof(SDMABUFFormatTableEntry); - int fds[2] = {0}; - allocateSHMFilePair(tableSize, &fds[0], &fds[1]); + CFileDescriptor fds[2]; + allocateSHMFilePair(tableSize, fds[0], fds[1]); - auto arr = (SDMABUFFormatTableEntry*)mmap(nullptr, tableSize, PROT_READ | PROT_WRITE, MAP_SHARED, fds[0], 0); + auto arr = (SDMABUFFormatTableEntry*)mmap(nullptr, tableSize, PROT_READ | PROT_WRITE, MAP_SHARED, fds[0].get(), 0); if (arr == MAP_FAILED) { LOGM(ERR, "mmap failed"); - close(fds[0]); - close(fds[1]); return; } - close(fds[0]); - std::copy(formatsVec.begin(), formatsVec.end(), arr); munmap(arr, tableSize); - tableFD = fds[1]; -} - -CDMABUFFormatTable::~CDMABUFFormatTable() { - close(tableFD); + tableFD = std::move(fds[1]); } CLinuxDMABuffer::CLinuxDMABuffer(uint32_t id, wl_client* client, Aquamarine::SDMABUFAttrs attrs) { @@ -234,18 +228,18 @@ void CLinuxDMABUFParamsResource::create(uint32_t id) { } bool CLinuxDMABUFParamsResource::commence() { - if (PROTO::linuxDma->mainDeviceFD < 0) + if (!PROTO::linuxDma->mainDeviceFD.isValid()) return true; for (int i = 0; i < attrs->planes; i++) { uint32_t handle = 0; - if (drmPrimeFDToHandle(PROTO::linuxDma->mainDeviceFD, attrs->fds.at(i), &handle)) { + if (drmPrimeFDToHandle(PROTO::linuxDma->mainDeviceFD.get(), attrs->fds.at(i), &handle)) { LOGM(ERR, "Failed to import dmabuf fd"); return false; } - if (drmCloseBufferHandle(PROTO::linuxDma->mainDeviceFD, handle)) { + if (drmCloseBufferHandle(PROTO::linuxDma->mainDeviceFD.get(), handle)) { LOGM(ERR, "Failed to close dmabuf handle"); return false; } @@ -303,7 +297,7 @@ CLinuxDMABUFFeedbackResource::CLinuxDMABUFFeedbackResource(SPsetDestroy([this](CZwpLinuxDmabufFeedbackV1* r) { PROTO::linuxDma->destroyResource(this); }); auto& formatTable = PROTO::linuxDma->formatTable; - resource->sendFormatTable(formatTable->tableFD, formatTable->tableSize); + resource->sendFormatTable(formatTable->tableFD.get(), formatTable->tableSize); sendDefaultFeedback(); } @@ -472,9 +466,9 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const if (device->available_nodes & (1 << DRM_NODE_RENDER)) { const char* name = device->nodes[DRM_NODE_RENDER]; - mainDeviceFD = open(name, O_RDWR | O_CLOEXEC); + mainDeviceFD = CFileDescriptor{open(name, O_RDWR | O_CLOEXEC)}; drmFreeDevice(&device); - if (mainDeviceFD < 0) { + if (!mainDeviceFD.isValid()) { LOGM(ERR, "failed to open drm dev, disabling linux dmabuf"); removeGlobal(); return; @@ -496,7 +490,7 @@ void CLinuxDMABufV1Protocol::resetFormatTable() { auto newFormatTable = makeUnique(formatTable->rendererTranche, formatTable->monitorTranches); for (auto const& feedback : m_vFeedbacks) { - feedback->resource->sendFormatTable(newFormatTable->tableFD, newFormatTable->tableSize); + feedback->resource->sendFormatTable(newFormatTable->tableFD.get(), newFormatTable->tableSize); if (feedback->lastFeedbackWasScanout) { PHLMONITOR mon; auto HLSurface = CWLSurface::fromResource(feedback->surface); @@ -519,11 +513,6 @@ void CLinuxDMABufV1Protocol::resetFormatTable() { formatTable = std::move(newFormatTable); } -CLinuxDMABufV1Protocol::~CLinuxDMABufV1Protocol() { - if (mainDeviceFD >= 0) - close(mainDeviceFD); -} - void CLinuxDMABufV1Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); diff --git a/src/protocols/LinuxDMABUF.hpp b/src/protocols/LinuxDMABUF.hpp index 91cf3283..6c967878 100644 --- a/src/protocols/LinuxDMABUF.hpp +++ b/src/protocols/LinuxDMABUF.hpp @@ -9,6 +9,7 @@ #include "../helpers/Format.hpp" #include "../helpers/Monitor.hpp" #include +#include class CDMABuffer; class CWLSurfaceResource; @@ -48,9 +49,9 @@ struct SDMABUFTranche { class CDMABUFFormatTable { public: CDMABUFFormatTable(SDMABUFTranche rendererTranche, std::vector> tranches); - ~CDMABUFFormatTable(); + ~CDMABUFFormatTable() = default; - int tableFD = -1; + Hyprutils::OS::CFileDescriptor tableFD; size_t tableSize = 0; SDMABUFTranche rendererTranche; std::vector> monitorTranches; @@ -107,7 +108,7 @@ class CLinuxDMABUFResource { class CLinuxDMABufV1Protocol : public IWaylandProtocol { public: CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name); - ~CLinuxDMABufV1Protocol(); + ~CLinuxDMABufV1Protocol() = default; virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); void updateScanoutTranche(SP surface, PHLMONITOR pMonitor); @@ -128,7 +129,7 @@ class CLinuxDMABufV1Protocol : public IWaylandProtocol { UP formatTable; dev_t mainDevice; - int mainDeviceFD = -1; + Hyprutils::OS::CFileDescriptor mainDeviceFD; friend class CLinuxDMABUFResource; friend class CLinuxDMABUFFeedbackResource; diff --git a/src/protocols/PrimarySelection.cpp b/src/protocols/PrimarySelection.cpp index 567bfdd2..620f262e 100644 --- a/src/protocols/PrimarySelection.cpp +++ b/src/protocols/PrimarySelection.cpp @@ -3,6 +3,7 @@ #include "../managers/SeatManager.hpp" #include "core/Seat.hpp" #include "../config/ConfigValue.hpp" +using namespace Hyprutils::OS; CPrimarySelectionOffer::CPrimarySelectionOffer(SP resource_, SP source_) : source(source_), resource(resource_) { if UNLIKELY (!good()) @@ -12,21 +13,20 @@ CPrimarySelectionOffer::CPrimarySelectionOffer(SP r resource->setOnDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); }); resource->setReceive([this](CZwpPrimarySelectionOfferV1* r, const char* mime, int32_t fd) { + CFileDescriptor sendFd{fd}; if (!source) { LOGM(WARN, "Possible bug: Receive on an offer w/o a source"); - close(fd); return; } if (dead) { LOGM(WARN, "Possible bug: Receive on an offer that's dead"); - close(fd); return; } LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get()); - source->send(mime, fd); + source->send(mime, std::move(sendFd)); }); } @@ -78,15 +78,13 @@ std::vector CPrimarySelectionSource::mimes() { return mimeTypes; } -void CPrimarySelectionSource::send(const std::string& mime, uint32_t fd) { +void CPrimarySelectionSource::send(const std::string& mime, CFileDescriptor fd) { if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) { LOGM(ERR, "Compositor/App bug: CPrimarySelectionSource::sendAskSend with non-existent mime"); - close(fd); return; } - resource->sendSend(mime.c_str(), fd); - close(fd); + resource->sendSend(mime.c_str(), fd.get()); } void CPrimarySelectionSource::accepted(const std::string& mime) { diff --git a/src/protocols/PrimarySelection.hpp b/src/protocols/PrimarySelection.hpp index aeebe03c..0ecc962b 100644 --- a/src/protocols/PrimarySelection.hpp +++ b/src/protocols/PrimarySelection.hpp @@ -5,6 +5,7 @@ #include "WaylandProtocol.hpp" #include "primary-selection-unstable-v1.hpp" #include "types/DataDevice.hpp" +#include class CPrimarySelectionOffer; class CPrimarySelectionSource; @@ -38,7 +39,7 @@ class CPrimarySelectionSource : public IDataSource { bool good(); virtual std::vector mimes(); - virtual void send(const std::string& mime, uint32_t fd); + virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd); virtual void accepted(const std::string& mime); virtual void cancelled(); virtual void error(uint32_t code, const std::string& msg); diff --git a/src/protocols/SecurityContext.cpp b/src/protocols/SecurityContext.cpp index e5b3cf2a..30fca260 100644 --- a/src/protocols/SecurityContext.cpp +++ b/src/protocols/SecurityContext.cpp @@ -1,6 +1,7 @@ #include "SecurityContext.hpp" #include "../Compositor.hpp" #include +using namespace Hyprutils::OS; static int onListenFdEvent(int fd, uint32_t mask, void* data) { auto sc = (CSecurityContext*)data; @@ -14,8 +15,8 @@ static int onCloseFdEvent(int fd, uint32_t mask, void* data) { return 0; } -SP CSecurityContextSandboxedClient::create(int clientFD_) { - auto p = SP(new CSecurityContextSandboxedClient(clientFD_)); +SP CSecurityContextSandboxedClient::create(CFileDescriptor clientFD_) { + auto p = SP(new CSecurityContextSandboxedClient(std::move(clientFD_))); if (!p->client) return nullptr; return p; @@ -27,8 +28,8 @@ static void onSecurityContextClientDestroy(wl_listener* l, void* d) { client->onDestroy(); } -CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(int clientFD_) : clientFD(clientFD_) { - client = wl_client_create(g_pCompositor->m_sWLDisplay, clientFD); +CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(CFileDescriptor clientFD_) : clientFD(std::move(clientFD_)) { + client = wl_client_create(g_pCompositor->m_sWLDisplay, clientFD.get()); if (!client) return; @@ -41,7 +42,6 @@ CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(int clientFD_) CSecurityContextSandboxedClient::~CSecurityContextSandboxedClient() { wl_list_remove(&destroyListener.listener.link); wl_list_init(&destroyListener.listener.link); - close(clientFD); } void CSecurityContextSandboxedClient::onDestroy() { @@ -113,8 +113,8 @@ CSecurityContext::CSecurityContext(SP resource_, int liste LOGM(LOG, "security_context at 0x{:x} commits", (uintptr_t)this); - listenSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, listenFD, WL_EVENT_READABLE, ::onListenFdEvent, this); - closeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, closeFD, 0, ::onCloseFdEvent, this); + listenSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, listenFD.get(), WL_EVENT_READABLE, ::onListenFdEvent, this); + closeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, closeFD.get(), 0, ::onCloseFdEvent, this); if (!listenSource || !closeSource) { r->noMemory(); @@ -144,16 +144,15 @@ void CSecurityContext::onListen(uint32_t mask) { if (!(mask & WL_EVENT_READABLE)) return; - int clientFD = accept(listenFD, nullptr, nullptr); - if UNLIKELY (clientFD < 0) { + CFileDescriptor clientFD{accept(listenFD.get(), nullptr, nullptr)}; + if UNLIKELY (!clientFD.isValid()) { LOGM(ERR, "security_context at 0x{:x} couldn't accept", (uintptr_t)this); return; } - auto newClient = CSecurityContextSandboxedClient::create(clientFD); + auto newClient = CSecurityContextSandboxedClient::create(std::move(clientFD)); if UNLIKELY (!newClient) { LOGM(ERR, "security_context at 0x{:x} couldn't create a client", (uintptr_t)this); - close(clientFD); return; } diff --git a/src/protocols/SecurityContext.hpp b/src/protocols/SecurityContext.hpp index 2bec08d4..56d4f7b4 100644 --- a/src/protocols/SecurityContext.hpp +++ b/src/protocols/SecurityContext.hpp @@ -4,19 +4,20 @@ #include #include "WaylandProtocol.hpp" #include "security-context-v1.hpp" +#include class CSecurityContext { public: CSecurityContext(SP resource_, int listenFD_, int closeFD_); ~CSecurityContext(); - bool good(); + bool good(); - std::string sandboxEngine, appID, instanceID; - int listenFD = -1, closeFD = -1; + std::string sandboxEngine, appID, instanceID; + Hyprutils::OS::CFileDescriptor listenFD, closeFD; - void onListen(uint32_t mask); - void onClose(uint32_t mask); + void onListen(uint32_t mask); + void onClose(uint32_t mask); private: SP resource; @@ -44,7 +45,7 @@ struct SCSecurityContextSandboxedClientDestroyWrapper { class CSecurityContextSandboxedClient { public: - static SP create(int clientFD); + static SP create(Hyprutils::OS::CFileDescriptor clientFD); ~CSecurityContextSandboxedClient(); void onDestroy(); @@ -52,10 +53,10 @@ class CSecurityContextSandboxedClient { SCSecurityContextSandboxedClientDestroyWrapper destroyListener; private: - CSecurityContextSandboxedClient(int clientFD_); + CSecurityContextSandboxedClient(Hyprutils::OS::CFileDescriptor clientFD_); - wl_client* client = nullptr; - int clientFD = -1; + wl_client* client = nullptr; + Hyprutils::OS::CFileDescriptor clientFD; friend class CSecurityContextProtocol; friend class CSecurityContext; diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp index 4fec57c0..00aca041 100644 --- a/src/protocols/VirtualKeyboard.cpp +++ b/src/protocols/VirtualKeyboard.cpp @@ -1,6 +1,7 @@ #include "VirtualKeyboard.hpp" #include #include "../devices/IKeyboard.hpp" +using namespace Hyprutils::OS; CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP resource_) : resource(resource_) { if UNLIKELY (!good()) @@ -51,20 +52,19 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP }); resource->setKeymap([this](CZwpVirtualKeyboardV1* r, uint32_t fmt, int32_t fd, uint32_t len) { - auto xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + auto xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + CFileDescriptor keymapFd{fd}; if UNLIKELY (!xkbContext) { LOGM(ERR, "xkbContext creation failed"); r->noMemory(); - close(fd); return; } - auto keymapData = mmap(nullptr, len, PROT_READ, MAP_PRIVATE, fd, 0); + auto keymapData = mmap(nullptr, len, PROT_READ, MAP_PRIVATE, keymapFd.get(), 0); if UNLIKELY (keymapData == MAP_FAILED) { LOGM(ERR, "keymapData alloc failed"); xkb_context_unref(xkbContext); r->noMemory(); - close(fd); return; } @@ -75,7 +75,6 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP LOGM(ERR, "xkbKeymap creation failed"); xkb_context_unref(xkbContext); r->noMemory(); - close(fd); return; } @@ -86,7 +85,6 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP xkb_keymap_unref(xkbKeymap); xkb_context_unref(xkbContext); - close(fd); }); name = "hl-virtual-keyboard"; diff --git a/src/protocols/VirtualKeyboard.hpp b/src/protocols/VirtualKeyboard.hpp index 8157b276..0a13003b 100644 --- a/src/protocols/VirtualKeyboard.hpp +++ b/src/protocols/VirtualKeyboard.hpp @@ -5,6 +5,7 @@ #include "WaylandProtocol.hpp" #include "virtual-keyboard-unstable-v1.hpp" #include "../helpers/signal/Signal.hpp" +#include class CVirtualKeyboardV1Resource { public: diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index e17b5612..0931608a 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -13,6 +13,7 @@ #include "../../managers/HookSystemManager.hpp" #include "../../helpers/Monitor.hpp" #include "../../render/Renderer.hpp" +using namespace Hyprutils::OS; CWLDataOfferResource::CWLDataOfferResource(SP resource_, SP source_) : source(source_), resource(resource_) { if UNLIKELY (!good()) @@ -39,15 +40,14 @@ CWLDataOfferResource::CWLDataOfferResource(SP resource_, SPsetReceive([this](CWlDataOffer* r, const char* mime, uint32_t fd) { + CFileDescriptor sendFd{fd}; if (!source) { LOGM(WARN, "Possible bug: Receive on an offer w/o a source"); - close(fd); return; } if (dead) { LOGM(WARN, "Possible bug: Receive on an offer that's dead"); - close(fd); return; } @@ -58,7 +58,7 @@ CWLDataOfferResource::CWLDataOfferResource(SP resource_, SPaccepted(mime ? mime : ""); } - source->send(mime ? mime : "", fd); + source->send(mime ? mime : "", std::move(sendFd)); recvd = true; @@ -182,15 +182,13 @@ std::vector CWLDataSourceResource::mimes() { return mimeTypes; } -void CWLDataSourceResource::send(const std::string& mime, uint32_t fd) { +void CWLDataSourceResource::send(const std::string& mime, CFileDescriptor fd) { if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) { LOGM(ERR, "Compositor/App bug: CWLDataSourceResource::sendAskSend with non-existent mime"); - close(fd); return; } - resource->sendSend(mime.c_str(), fd); - close(fd); + resource->sendSend(mime.c_str(), fd.get()); } void CWLDataSourceResource::cancelled() { diff --git a/src/protocols/core/DataDevice.hpp b/src/protocols/core/DataDevice.hpp index d8bc2b9c..dfea4a71 100644 --- a/src/protocols/core/DataDevice.hpp +++ b/src/protocols/core/DataDevice.hpp @@ -16,6 +16,7 @@ #include "../../helpers/signal/Signal.hpp" #include "../../helpers/math/Math.hpp" #include "../types/DataDevice.hpp" +#include class CWLDataDeviceResource; class CWLDataDeviceManagerResource; @@ -63,7 +64,7 @@ class CWLDataSourceResource : public IDataSource { bool good(); virtual std::vector mimes(); - virtual void send(const std::string& mime, uint32_t fd); + virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd); virtual void accepted(const std::string& mime); virtual void cancelled(); virtual bool hasDnd(); diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index c6b2de05..1f07a15e 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -321,35 +321,18 @@ void CWLKeyboardResource::sendKeymap(SP keyboard) { if (!(PROTO::seat->currentCaps & eHIDCapabilityType::HID_INPUT_CAPABILITY_KEYBOARD)) return; - std::string_view keymap; - int fd; - uint32_t size; - if (keyboard) { - keymap = keyboard->xkbKeymapString; - fd = keyboard->xkbKeymapFD; - size = keyboard->xkbKeymapString.length() + 1; - } else { - fd = open("/dev/null", O_RDONLY | O_CLOEXEC); - if (fd < 0) { - LOGM(ERR, "Failed to open /dev/null"); - return; - } - size = 0; - } + std::string_view keymap = keyboard->xkbKeymapString; + Hyprutils::OS::CFileDescriptor& fd = keyboard->xkbKeymapFD; + uint32_t size = keyboard->xkbKeymapString.length() + 1; - if (keymap == lastKeymap) { - if (!keyboard) - close(fd); + if (keymap == lastKeymap) return; - } + lastKeymap = keymap; const wl_keyboard_keymap_format format = keyboard ? WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 : WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP; - resource->sendKeymap(format, fd, size); - - if (!keyboard) - close(fd); + resource->sendKeymap(format, fd.get(), size); } void CWLKeyboardResource::sendEnter(SP surface) { diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp index 1649f82f..e0e62560 100644 --- a/src/protocols/core/Shm.cpp +++ b/src/protocols/core/Shm.cpp @@ -7,6 +7,7 @@ #include "../types/WLBuffer.hpp" #include "../../helpers/Format.hpp" #include "../../render/Renderer.hpp" +using namespace Hyprutils::OS; CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t offset_, const Vector2D& size_, int32_t stride_, uint32_t fmt_) { if UNLIKELY (!pool_->pool->data) @@ -51,7 +52,7 @@ bool CWLSHMBuffer::isSynchronous() { Aquamarine::SSHMAttrs CWLSHMBuffer::shm() { Aquamarine::SSHMAttrs attrs; attrs.success = true; - attrs.fd = pool->fd; + attrs.fd = pool->fd.get(); attrs.format = NFormatUtils::shmToDRM(fmt); attrs.size = size; attrs.stride = stride; @@ -75,13 +76,12 @@ void CWLSHMBuffer::update(const CRegion& damage) { texture->update(NFormatUtils::shmToDRM(fmt), (uint8_t*)pool->data + offset, stride, damage); } -CSHMPool::CSHMPool(int fd_, size_t size_) : fd(fd_), size(size_), data(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) { +CSHMPool::CSHMPool(CFileDescriptor fd_, size_t size_) : fd(std::move(fd_)), size(size_), data(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0)) { ; } CSHMPool::~CSHMPool() { munmap(data, size); - close(fd); } void CSHMPool::resize(size_t size_) { @@ -90,23 +90,23 @@ void CSHMPool::resize(size_t size_) { if (data) munmap(data, size); size = size_; - data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0); if UNLIKELY (data == MAP_FAILED) - LOGM(ERR, "Couldn't mmap {} bytes from fd {} of shm client", size, fd); + LOGM(ERR, "Couldn't mmap {} bytes from fd {} of shm client", size, fd.get()); } -static int shmIsSizeValid(int fd, size_t size) { +static int shmIsSizeValid(CFileDescriptor& fd, size_t size) { struct stat st; - if UNLIKELY (fstat(fd, &st) == -1) { - LOGM(ERR, "Couldn't get stat for fd {} of shm client", fd); + if UNLIKELY (fstat(fd.get(), &st) == -1) { + LOGM(ERR, "Couldn't get stat for fd {} of shm client", fd.get()); return 0; } return (size_t)st.st_size >= size; } -CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, int fd_, size_t size_) : resource(resource_) { +CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, CFileDescriptor fd_, size_t size_) : resource(resource_) { if UNLIKELY (!good()) return; @@ -115,7 +115,7 @@ CWLSHMPoolResource::CWLSHMPoolResource(SP resource_, int fd_, size_t return; } - pool = makeShared(fd_, size_); + pool = makeShared(std::move(fd_), size_); resource->setDestroy([this](CWlShmPool* r) { PROTO::shm->destroyResource(this); }); resource->setOnDestroy([this](CWlShmPool* r) { PROTO::shm->destroyResource(this); }); @@ -176,7 +176,8 @@ CWLSHMResource::CWLSHMResource(SP resource_) : resource(resource_) { resource->setOnDestroy([this](CWlShm* r) { PROTO::shm->destroyResource(this); }); resource->setCreatePool([](CWlShm* r, uint32_t id, int32_t fd, int32_t size) { - const auto RESOURCE = PROTO::shm->m_vPools.emplace_back(makeShared(makeShared(r->client(), r->version(), id), fd, size)); + CFileDescriptor poolFd{fd}; + const auto RESOURCE = PROTO::shm->m_vPools.emplace_back(makeShared(makeShared(r->client(), r->version(), id), std::move(poolFd), size)); if UNLIKELY (!RESOURCE->good()) { r->noMemory(); diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index d7e81367..fef821cb 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -7,6 +7,8 @@ - wl_buffer with shm */ +#include +#include #include #include #include "../WaylandProtocol.hpp" @@ -18,14 +20,14 @@ class CWLSHMPoolResource; class CSHMPool { public: - CSHMPool(int fd, size_t size); + CSHMPool(Hyprutils::OS::CFileDescriptor fd, size_t size); ~CSHMPool(); - int fd = 0; - size_t size = 0; - void* data = nullptr; + Hyprutils::OS::CFileDescriptor fd; + size_t size = 0; + void* data = nullptr; - void resize(size_t size); + void resize(size_t size); }; class CWLSHMBuffer : public IHLBuffer { @@ -57,7 +59,7 @@ class CWLSHMBuffer : public IHLBuffer { class CWLSHMPoolResource { public: - CWLSHMPoolResource(SP resource_, int fd, size_t size); + CWLSHMPoolResource(SP resource_, Hyprutils::OS::CFileDescriptor fd, size_t size); bool good(); diff --git a/src/protocols/types/DataDevice.hpp b/src/protocols/types/DataDevice.hpp index 62f10de2..cbb4b271 100644 --- a/src/protocols/types/DataDevice.hpp +++ b/src/protocols/types/DataDevice.hpp @@ -7,6 +7,7 @@ #include #include "../../helpers/memory/Memory.hpp" #include "../../helpers/math/Math.hpp" +#include class CWLDataOfferResource; class CX11DataOffer; @@ -24,10 +25,10 @@ class IDataSource { IDataSource() = default; virtual ~IDataSource() = default; - virtual std::vector mimes() = 0; - virtual void send(const std::string& mime, uint32_t fd) = 0; - virtual void accepted(const std::string& mime) = 0; - virtual void cancelled() = 0; + virtual std::vector mimes() = 0; + virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) = 0; + virtual void accepted(const std::string& mime) = 0; + virtual void cancelled() = 0; virtual bool hasDnd(); virtual bool dndDone(); virtual void sendDndFinished(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 78b53c9b..e4aadd63 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -19,6 +19,7 @@ #include #include #include +using namespace Hyprutils::OS; const std::vector ASSET_PATHS = { #ifdef DATAROOTDIR @@ -301,11 +302,11 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() : m_iDRMFD(g_pCompositor->m_iDRMFD) { Debug::log(WARN, "EGL: EXT_platform_device or EGL_EXT_device_query not supported, using gbm"); if (EGLEXTENSIONS.contains("KHR_platform_gbm")) { success = true; - m_iGBMFD = openRenderNode(m_iDRMFD); - if (m_iGBMFD < 0) + m_iGBMFD = CFileDescriptor{openRenderNode(m_iDRMFD)}; + if (!m_iGBMFD.isValid()) RASSERT(false, "Couldn't open a gbm fd"); - m_pGbmDevice = gbm_create_device(m_iGBMFD); + m_pGbmDevice = gbm_create_device(m_iGBMFD.get()); if (!m_pGbmDevice) RASSERT(false, "Couldn't open a gbm device"); @@ -371,9 +372,6 @@ CHyprOpenGLImpl::~CHyprOpenGLImpl() { if (m_pGbmDevice) gbm_device_destroy(m_pGbmDevice); - - if (m_iGBMFD >= 0) - close(m_iGBMFD); } std::optional> CHyprOpenGLImpl::getModsForFormat(EGLint format) { @@ -2954,29 +2952,28 @@ std::vector CHyprOpenGLImpl::getDRMFormats() { return drmFormats; } -SP CHyprOpenGLImpl::createEGLSync(int fenceFD) { +SP CHyprOpenGLImpl::createEGLSync(CFileDescriptor fenceFD) { std::vector attribs; - int dupFd = -1; - if (fenceFD > 0) { - dupFd = fcntl(fenceFD, F_DUPFD_CLOEXEC, 0); - if (dupFd < 0) { + CFileDescriptor dupFd; + if (fenceFD.isValid()) { + dupFd = fenceFD.duplicate(); + if (!dupFd.isValid()) { Debug::log(ERR, "createEGLSync: dup failed"); return nullptr; } // reserve number of elements to avoid reallocations attribs.reserve(3); attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID); - attribs.push_back(dupFd); + attribs.push_back(dupFd.get()); attribs.push_back(EGL_NONE); } EGLSyncKHR sync = m_sProc.eglCreateSyncKHR(m_pEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs.data()); if (sync == EGL_NO_SYNC_KHR) { Debug::log(ERR, "eglCreateSyncKHR failed"); - if (dupFd >= 0) - close(dupFd); return nullptr; - } + } else + dupFd.take(); // eglCreateSyncKHR only takes ownership on success // we need to flush otherwise we might not get a valid fd glFlush(); @@ -2989,19 +2986,18 @@ SP CHyprOpenGLImpl::createEGLSync(int fenceFD) { auto eglsync = SP(new CEGLSync); eglsync->sync = sync; - eglsync->m_iFd = fd; + eglsync->m_iFd = CFileDescriptor{fd}; return eglsync; } bool CHyprOpenGLImpl::waitForTimelinePoint(SP timeline, uint64_t point) { - int fd = timeline->exportAsSyncFileFD(point); - if (fd < 0) { + auto fd = timeline->exportAsSyncFileFD(point); + if (!fd.isValid()) { Debug::log(ERR, "waitForTimelinePoint: failed to get a fd from explicit timeline"); return false; } - auto sync = g_pHyprOpenGL->createEGLSync(fd); - close(fd); + auto sync = g_pHyprOpenGL->createEGLSync(std::move(fd)); if (!sync) { Debug::log(ERR, "waitForTimelinePoint: failed to get an eglsync from explicit timeline"); return false; @@ -3082,12 +3078,9 @@ CEGLSync::~CEGLSync() { if (g_pHyprOpenGL->m_sProc.eglDestroySyncKHR(g_pHyprOpenGL->m_pEglDisplay, sync) != EGL_TRUE) Debug::log(ERR, "eglDestroySyncKHR failed"); - - if (m_iFd >= 0) - close(m_iFd); } -int CEGLSync::fd() { +CFileDescriptor& CEGLSync::fd() { return m_iFd; } diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 1ebb0162..d7abdf63 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "../debug/TracyDefines.hpp" @@ -146,15 +147,15 @@ class CEGLSync { public: ~CEGLSync(); - EGLSyncKHR sync = nullptr; + EGLSyncKHR sync = nullptr; - int fd(); - bool wait(); + Hyprutils::OS::CFileDescriptor& fd(); + bool wait(); private: CEGLSync() = default; - int m_iFd = -1; + Hyprutils::OS::CFileDescriptor m_iFd; friend class CHyprOpenGLImpl; }; @@ -228,14 +229,14 @@ class CHyprOpenGLImpl { uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); std::vector getDRMFormats(); EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); - SP createEGLSync(int fenceFD); + SP createEGLSync(Hyprutils::OS::CFileDescriptor fenceFD); bool waitForTimelinePoint(SP timeline, uint64_t point); SCurrentRenderData m_RenderData; GLint m_iCurrentOutputFb = 0; - int m_iGBMFD = -1; + Hyprutils::OS::CFileDescriptor m_iGBMFD; gbm_device* m_pGbmDevice = nullptr; EGLContext m_pEglContext = nullptr; EGLDisplay m_pEglDisplay = nullptr; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 67d8b58b..42445728 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -36,6 +36,7 @@ #include using namespace Hyprutils::Utils; +using namespace Hyprutils::OS; extern "C" { #include @@ -1462,10 +1463,10 @@ static hdr_output_metadata createHDRMetadata(SImageDescription settings, Aquamar bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { // apply timelines for explicit sync // save inFD otherwise reset will reset it - auto inFD = pMonitor->output->state->state().explicitInFence; + CFileDescriptor inFD{pMonitor->output->state->state().explicitInFence}; pMonitor->output->state->resetExplicitFences(); - if (inFD >= 0) - pMonitor->output->state->setExplicitInFence(inFD); + if (inFD.isValid()) + pMonitor->output->state->setExplicitInFence(inFD.get()); static auto PHDR = CConfigValue("experimental:hdr"); @@ -1515,7 +1516,7 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { bool ok = pMonitor->state.commit(); if (!ok) { - if (inFD >= 0) { + if (inFD.isValid()) { Debug::log(TRACE, "Monitor state commit failed, retrying without a fence"); pMonitor->output->state->resetExplicitFences(); ok = pMonitor->state.commit(); @@ -1534,11 +1535,8 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { if (!explicitOptions.explicitEnabled) return ok; - if (inFD >= 0) - close(inFD); - Debug::log(TRACE, "Explicit: {} presented", explicitPresented.size()); - auto sync = g_pHyprOpenGL->createEGLSync(-1); + auto sync = g_pHyprOpenGL->createEGLSync({}); if (!sync) Debug::log(TRACE, "Explicit: can't add sync, EGLSync failed"); @@ -2272,7 +2270,7 @@ void CHyprRenderer::endRender() { auto explicitOptions = getExplicitSyncSettings(); if (PMONITOR->inTimeline && explicitOptions.explicitEnabled && explicitOptions.explicitKMSEnabled) { - auto sync = g_pHyprOpenGL->createEGLSync(-1); + auto sync = g_pHyprOpenGL->createEGLSync({}); if (!sync) { Debug::log(ERR, "renderer: couldn't create an EGLSync for out in endRender"); return; @@ -2285,12 +2283,12 @@ void CHyprRenderer::endRender() { } auto fd = PMONITOR->inTimeline->exportAsSyncFileFD(PMONITOR->commitSeq); - if (fd <= 0) { + if (!fd.isValid()) { Debug::log(ERR, "renderer: couldn't export from sync timeline in endRender"); return; } - PMONITOR->output->state->setExplicitInFence(fd); + PMONITOR->output->state->setExplicitInFence(fd.take()); } else { if (isNvidia() && *PNVIDIAANTIFLICKER) glFinish(); diff --git a/src/xwayland/Dnd.cpp b/src/xwayland/Dnd.cpp index d4ae3780..16d166ce 100644 --- a/src/xwayland/Dnd.cpp +++ b/src/xwayland/Dnd.cpp @@ -7,6 +7,8 @@ #include "../managers/XWaylandManager.hpp" #include "../desktop/WLSurface.hpp" +using namespace Hyprutils::OS; + #ifndef NO_XWAYLAND static xcb_atom_t dndActionToAtom(uint32_t actions) { if (actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) @@ -172,7 +174,7 @@ std::vector CX11DataSource::mimes() { return mimeTypes; } -void CX11DataSource::send(const std::string& mime, uint32_t fd) { +void CX11DataSource::send(const std::string& mime, CFileDescriptor fd) { ; } diff --git a/src/xwayland/Dnd.hpp b/src/xwayland/Dnd.hpp index 8da60ddd..fb030796 100644 --- a/src/xwayland/Dnd.hpp +++ b/src/xwayland/Dnd.hpp @@ -2,6 +2,7 @@ #include "../protocols/types/DataDevice.hpp" #include +#include #define XDND_VERSION 5 @@ -35,7 +36,7 @@ class CX11DataSource : public IDataSource { ~CX11DataSource() = default; virtual std::vector mimes(); - virtual void send(const std::string& mime, uint32_t fd); + virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd); virtual void accepted(const std::string& mime); virtual void cancelled(); virtual bool hasDnd(); diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index d5dce333..99bcdf62 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -24,70 +24,41 @@ #include "../defines.hpp" #include "../Compositor.hpp" #include "../managers/CursorManager.hpp" +using namespace Hyprutils::OS; // Constants -constexpr int SOCKET_DIR_PERMISSIONS = 0755; -constexpr int SOCKET_BACKLOG = 1; -constexpr int MAX_SOCKET_RETRIES = 32; -constexpr int LOCK_FILE_MODE = 0444; +constexpr int SOCKET_DIR_PERMISSIONS = 0755; +constexpr int SOCKET_BACKLOG = 1; +constexpr int MAX_SOCKET_RETRIES = 32; +constexpr int LOCK_FILE_MODE = 0444; -static bool setCloseOnExec(int fd, bool cloexec) { - int flags = fcntl(fd, F_GETFD); - if (flags == -1) { - Debug::log(ERR, "fcntl failed"); - return false; - } - - if (cloexec) - flags = flags | FD_CLOEXEC; - else - flags = flags & ~FD_CLOEXEC; - - if (fcntl(fd, F_SETFD, flags) == -1) { - Debug::log(ERR, "fcntl failed"); - return false; - } - - return true; -} - -static void cleanUpSocket(int fd, const char* path) { - close(fd); - if (path[0]) - unlink(path); -} - -static inline void closeSocketSafely(int& fd) { - if (fd >= 0) - close(fd); -} - -static int createSocket(struct sockaddr_un* addr, size_t path_size) { - socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1; - int fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { +static CFileDescriptor createSocket(struct sockaddr_un* addr, size_t path_size) { + socklen_t size = offsetof(struct sockaddr_un, sun_path) + path_size + 1; + CFileDescriptor fd{socket(AF_UNIX, SOCK_STREAM, 0)}; + if (!fd.isValid()) { Debug::log(ERR, "Failed to create socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1); - return -1; + return {}; } - if (!setCloseOnExec(fd, true)) { - close(fd); - return -1; + if (!fd.setFlags(fd.getFlags() | FD_CLOEXEC)) { + return {}; } if (addr->sun_path[0]) unlink(addr->sun_path); - if (bind(fd, (struct sockaddr*)addr, size) < 0) { + if (bind(fd.get(), (struct sockaddr*)addr, size) < 0) { Debug::log(ERR, "Failed to bind socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1); - cleanUpSocket(fd, addr->sun_path); - return -1; + if (addr->sun_path[0]) + unlink(addr->sun_path); + return {}; } - if (listen(fd, SOCKET_BACKLOG) < 0) { + if (listen(fd.get(), SOCKET_BACKLOG) < 0) { Debug::log(ERR, "Failed to listen to socket {}{}", addr->sun_path[0] ? addr->sun_path[0] : '@', addr->sun_path + 1); - cleanUpSocket(fd, addr->sun_path); - return -1; + if (addr->sun_path[0]) + unlink(addr->sun_path); + return {}; } return fd; @@ -141,7 +112,7 @@ static std::string getSocketPath(int display, bool isLinux) { return std::format("/tmp/.X11-unix/X{}_", display); } -static bool openSockets(std::array& sockets, int display) { +static bool openSockets(std::array& sockets, int display) { if (!ensureSocketDirExists()) return false; @@ -151,17 +122,16 @@ static bool openSockets(std::array& sockets, int display) { path = getSocketPath(display, false); strncpy(addr.sun_path, path.c_str(), path.length() + 1); - sockets[0] = createSocket(&addr, path.length()); - if (sockets[0] < 0) + sockets[0] = CFileDescriptor{createSocket(&addr, path.length())}; + if (!sockets[0].isValid()) return false; path = getSocketPath(display, true); strncpy(addr.sun_path, path.c_str(), path.length() + 1); - sockets[1] = createSocket(&addr, path.length()); - if (sockets[1] < 0) { - close(sockets[0]); - sockets[0] = -1; + sockets[1] = CFileDescriptor{createSocket(&addr, path.length())}; + if (!sockets[1].isValid()) { + sockets[0].reset(); return false; } @@ -174,7 +144,8 @@ static void startServer(void* data) { } static int xwaylandReady(int fd, uint32_t mask, void* data) { - return g_pXWayland->pServer->ready(fd, mask); + CFileDescriptor xwlFd{fd}; + return g_pXWayland->pServer->ready(std::move(xwlFd), mask); } static bool safeRemove(const std::string& path) { @@ -186,38 +157,34 @@ static bool safeRemove(const std::string& path) { bool CXWaylandServer::tryOpenSockets() { for (size_t i = 0; i <= MAX_SOCKET_RETRIES; ++i) { - std::string lockPath = std::format("/tmp/.X{}-lock", i); + std::string lockPath = std::format("/tmp/.X{}-lock", i); - int fd = open(lockPath.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, LOCK_FILE_MODE); - if (fd >= 0) { + CFileDescriptor fd{open(lockPath.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, LOCK_FILE_MODE)}; + if (fd.isValid()) { // we managed to open the lock if (!openSockets(xFDs, i)) { safeRemove(lockPath); - close(fd); continue; } const std::string pidStr = std::to_string(getpid()); - if (write(fd, pidStr.c_str(), pidStr.length()) != (long)pidStr.length()) { + if (write(fd.get(), pidStr.c_str(), pidStr.length()) != (long)pidStr.length()) { safeRemove(lockPath); - close(fd); continue; } - close(fd); display = i; displayName = std::format(":{}", display); break; } - fd = open(lockPath.c_str(), O_RDONLY | O_CLOEXEC); + fd = CFileDescriptor{open(lockPath.c_str(), O_RDONLY | O_CLOEXEC)}; - if (fd < 0) + if (!fd.isValid()) continue; char pidstr[12] = {0}; - read(fd, pidstr, sizeof(pidstr) - 1); - close(fd); + read(fd.get(), pidstr, sizeof(pidstr) - 1); int32_t pid = 0; try { @@ -249,9 +216,6 @@ CXWaylandServer::~CXWaylandServer() { if (display < 0) return; - closeSocketSafely(xFDs[0]); - closeSocketSafely(xFDs[1]); - std::string lockPath = std::format("/tmp/.X{}-lock", display); safeRemove(lockPath); @@ -277,21 +241,11 @@ void CXWaylandServer::die() { if (pipeSource) wl_event_source_remove(pipeSource); - if (pipeFd >= 0) - close(pipeFd); - - closeSocketSafely(waylandFDs[0]); - closeSocketSafely(waylandFDs[1]); - closeSocketSafely(xwmFDs[0]); - closeSocketSafely(xwmFDs[1]); - // possible crash. Better to leak a bit. //if (xwaylandClient) // wl_client_destroy(xwaylandClient); xwaylandClient = nullptr; - waylandFDs = {-1, -1}; - xwmFDs = {-1, -1}; } bool CXWaylandServer::create() { @@ -307,15 +261,17 @@ bool CXWaylandServer::create() { return true; } -void CXWaylandServer::runXWayland(int notifyFD) { - if (!setCloseOnExec(xFDs[0], false) || !setCloseOnExec(xFDs[1], false) || !setCloseOnExec(waylandFDs[1], false) || !setCloseOnExec(xwmFDs[1], false)) { +void CXWaylandServer::runXWayland(CFileDescriptor& notifyFD) { + if (!xFDs[0].setFlags(xFDs[0].getFlags() & ~FD_CLOEXEC) || !xFDs[1].setFlags(xFDs[1].getFlags() & ~FD_CLOEXEC) || + !waylandFDs[1].setFlags(waylandFDs[1].getFlags() & ~FD_CLOEXEC) || !xwmFDs[1].setFlags(xwmFDs[1].getFlags() & ~FD_CLOEXEC)) { Debug::log(ERR, "Failed to unset cloexec on fds"); _exit(EXIT_FAILURE); } - auto cmd = std::format("Xwayland {} -rootless -core -listenfd {} -listenfd {} -displayfd {} -wm {}", displayName, xFDs[0], xFDs[1], notifyFD, xwmFDs[1]); + auto cmd = + std::format("Xwayland {} -rootless -core -listenfd {} -listenfd {} -displayfd {} -wm {}", displayName, xFDs[0].get(), xFDs[1].get(), notifyFD.get(), xwmFDs[1].get()); - auto waylandSocket = std::format("{}", waylandFDs[1]); + auto waylandSocket = std::format("{}", waylandFDs[1].get()); setenv("WAYLAND_SOCKET", waylandSocket.c_str(), true); Debug::log(LOG, "Starting XWayland with \"{}\", bon voyage!", cmd); @@ -327,40 +283,46 @@ void CXWaylandServer::runXWayland(int notifyFD) { } bool CXWaylandServer::start() { - idleSource = nullptr; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, waylandFDs.data()) != 0) { + idleSource = nullptr; + int wlPair[2] = {-1, -1}; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, wlPair) != 0) { Debug::log(ERR, "socketpair failed (1)"); die(); return false; } + waylandFDs[0] = CFileDescriptor{wlPair[0]}; + waylandFDs[1] = CFileDescriptor{wlPair[1]}; - if (!setCloseOnExec(waylandFDs[0], true) || !setCloseOnExec(waylandFDs[1], true)) { + if (!waylandFDs[0].setFlags(waylandFDs[0].getFlags() | FD_CLOEXEC) || !waylandFDs[1].setFlags(waylandFDs[1].getFlags() | FD_CLOEXEC)) { Debug::log(ERR, "set_cloexec failed (1)"); die(); return false; } - if (socketpair(AF_UNIX, SOCK_STREAM, 0, xwmFDs.data()) != 0) { + int xwmPair[2] = {-1, -1}; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, xwmPair) != 0) { Debug::log(ERR, "socketpair failed (2)"); die(); return false; } - if (!setCloseOnExec(xwmFDs[0], true) || !setCloseOnExec(xwmFDs[1], true)) { + xwmFDs[0] = CFileDescriptor{xwmPair[0]}; + xwmFDs[1] = CFileDescriptor{xwmPair[1]}; + + if (!xwmFDs[0].setFlags(xwmFDs[0].getFlags() | FD_CLOEXEC) || !xwmFDs[1].setFlags(xwmFDs[1].getFlags() | FD_CLOEXEC)) { Debug::log(ERR, "set_cloexec failed (2)"); die(); return false; } - xwaylandClient = wl_client_create(g_pCompositor->m_sWLDisplay, waylandFDs[0]); + xwaylandClient = wl_client_create(g_pCompositor->m_sWLDisplay, waylandFDs[0].get()); if (!xwaylandClient) { Debug::log(ERR, "wl_client_create failed"); die(); return false; } - waylandFDs[0] = -1; + waylandFDs[0].take(); // does this leak? int notify[2] = {-1, -1}; if (pipe(notify) < 0) { @@ -369,22 +331,20 @@ bool CXWaylandServer::start() { return false; } - if (!setCloseOnExec(notify[0], true)) { + CFileDescriptor notifyFds[2] = {CFileDescriptor{notify[0]}, CFileDescriptor{notify[1]}}; + + if (!notifyFds[0].setFlags(notifyFds[0].getFlags() | FD_CLOEXEC)) { Debug::log(ERR, "set_cloexec failed (3)"); - close(notify[0]); - close(notify[1]); die(); return false; } - pipeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, notify[0], WL_EVENT_READABLE, ::xwaylandReady, nullptr); - pipeFd = notify[0]; + pipeSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, notifyFds[0].get(), WL_EVENT_READABLE, ::xwaylandReady, nullptr); + pipeFd = std::move(notifyFds[0]); serverPID = fork(); if (serverPID < 0) { Debug::log(ERR, "fork failed"); - close(notify[0]); - close(notify[1]); die(); return false; } else if (serverPID == 0) { @@ -393,25 +353,19 @@ bool CXWaylandServer::start() { Debug::log(ERR, "second fork failed"); _exit(1); } else if (pid == 0) - runXWayland(notify[1]); + runXWayland(notifyFds[1]); _exit(0); } - close(notify[1]); - close(waylandFDs[1]); - closeSocketSafely(xwmFDs[1]); - waylandFDs[1] = -1; - xwmFDs[1] = -1; - return true; } -int CXWaylandServer::ready(int fd, uint32_t mask) { +int CXWaylandServer::ready(CFileDescriptor fd, uint32_t mask) { if (mask & WL_EVENT_READABLE) { // xwayland writes twice char buf[64]; - ssize_t n = read(fd, buf, sizeof(buf)); + ssize_t n = read(fd.get(), buf, sizeof(buf)); if (n < 0 && errno != EINTR) { Debug::log(ERR, "Xwayland: read from displayFd failed"); mask = 0; @@ -436,7 +390,6 @@ int CXWaylandServer::ready(int fd, uint32_t mask) { Debug::log(LOG, "XWayland is ready"); - close(fd); wl_event_source_remove(pipeSource); pipeSource = nullptr; diff --git a/src/xwayland/Server.hpp b/src/xwayland/Server.hpp index 7a36a965..ccbcf6ea 100644 --- a/src/xwayland/Server.hpp +++ b/src/xwayland/Server.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "../helpers/signal/Signal.hpp" struct wl_event_source; @@ -19,7 +20,7 @@ class CXWaylandServer { bool start(); // called on ready - int ready(int fd, uint32_t mask); + int ready(Hyprutils::OS::CFileDescriptor fd, uint32_t mask); void die(); @@ -30,20 +31,20 @@ class CXWaylandServer { wl_client* xwaylandClient = nullptr; private: - bool tryOpenSockets(); - void runXWayland(int notifyFD); + bool tryOpenSockets(); + void runXWayland(Hyprutils::OS::CFileDescriptor& notifyFD); - pid_t serverPID = 0; + pid_t serverPID = 0; - std::string displayName; - int display = -1; - std::array xFDs = {-1, -1}; - std::array xFDReadEvents = {nullptr, nullptr}; - wl_event_source* idleSource = nullptr; - wl_event_source* pipeSource = nullptr; - int pipeFd = -1; - std::array xwmFDs = {-1, -1}; - std::array waylandFDs = {-1, -1}; + std::string displayName; + int display = -1; + std::array xFDs; + std::array xFDReadEvents = {nullptr, nullptr}; + wl_event_source* idleSource = nullptr; + wl_event_source* pipeSource = nullptr; + Hyprutils::OS::CFileDescriptor pipeFd; + std::array xwmFDs; + std::array waylandFDs; friend class CXWM; }; diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp index 4b0c5a29..e6282dcb 100644 --- a/src/xwayland/XDataSource.cpp +++ b/src/xwayland/XDataSource.cpp @@ -5,6 +5,7 @@ #include "XDataSource.hpp" #include +using namespace Hyprutils::OS; CXDataSource::CXDataSource(SXSelection& sel_) : selection(sel_) { xcb_get_property_cookie_t cookie = xcb_get_property(g_pXWayland->pWM->connection, @@ -47,7 +48,7 @@ std::vector CXDataSource::mimes() { return mimeTypes; } -void CXDataSource::send(const std::string& mime, uint32_t fd) { +void CXDataSource::send(const std::string& mime, CFileDescriptor fd) { xcb_atom_t mimeAtom = 0; if (mime == "text/plain") @@ -65,11 +66,10 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) { if (!mimeAtom) { Debug::log(ERR, "[XDataSource] mime atom not found"); - close(fd); return; } - Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd); + Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get()); selection.transfer = makeUnique(selection); selection.transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection); @@ -81,8 +81,9 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) { xcb_flush(g_pXWayland->pWM->connection); - fcntl(fd, F_SETFL, O_WRONLY | O_NONBLOCK); - selection.transfer->wlFD = fd; + //TODO: make CFileDescriptor setflags take SETFL aswell + fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK); + selection.transfer->wlFD = std::move(fd); } void CXDataSource::accepted(const std::string& mime) { @@ -101,4 +102,4 @@ eDataSourceType CXDataSource::type() { return DATA_SOURCE_TYPE_X11; } -#endif \ No newline at end of file +#endif diff --git a/src/xwayland/XDataSource.hpp b/src/xwayland/XDataSource.hpp index c629aa2a..a61ffcc9 100644 --- a/src/xwayland/XDataSource.hpp +++ b/src/xwayland/XDataSource.hpp @@ -1,6 +1,7 @@ #pragma once #include "../protocols/types/DataDevice.hpp" +#include struct SXSelection; @@ -9,7 +10,7 @@ class CXDataSource : public IDataSource { CXDataSource(SXSelection&); virtual std::vector mimes(); - virtual void send(const std::string& mime, uint32_t fd); + virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd); virtual void accepted(const std::string& mime); virtual void cancelled(); virtual void error(uint32_t code, const std::string& msg); @@ -19,4 +20,4 @@ class CXDataSource : public IDataSource { SXSelection& selection; std::vector mimeTypes; // these two have shared idx std::vector mimeAtoms; // -}; \ No newline at end of file +}; diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 6673105e..81900c7b 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -17,6 +17,7 @@ #include "../managers/SeatManager.hpp" #include "../protocols/XWaylandShell.hpp" #include "../protocols/core/Compositor.hpp" +using namespace Hyprutils::OS; #define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f #define INCR_CHUNK_SIZE (64 * 1024) @@ -883,7 +884,7 @@ void CXWM::getRenderFormat() { free(reply); } -CXWM::CXWM() : connection(g_pXWayland->pServer->xwmFDs[0]) { +CXWM::CXWM() : connection(g_pXWayland->pServer->xwmFDs[0].get()) { if (connection.hasError()) { Debug::log(ERR, "[xwm] Couldn't start, error {}", connection.hasError()); @@ -901,7 +902,7 @@ CXWM::CXWM() : connection(g_pXWayland->pServer->xwmFDs[0]) { xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(connection)); screen = screen_iterator.data; - eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, g_pXWayland->pServer->xwmFDs[0], WL_EVENT_READABLE, ::onX11Event, nullptr); + eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, g_pXWayland->pServer->xwmFDs[0].get(), WL_EVENT_READABLE, ::onX11Event, nullptr); wl_event_source_check(eventSource); gatherResources(); @@ -1180,13 +1181,12 @@ void CXWM::getTransferData(SXSelection& sel) { if (sel.transfer->propertyReply->type == HYPRATOMS["INCR"]) { Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :("); - close(sel.transfer->wlFD); sel.transfer.reset(); return; } else { sel.onWrite(); if (sel.transfer) - sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD, WL_EVENT_WRITABLE, ::writeDataSource, &sel); + sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD.get(), WL_EVENT_WRITABLE, ::writeDataSource, &sel); } } @@ -1361,13 +1361,13 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) { // the wayland client might not expect a non-blocking fd // fcntl(p[1], F_SETFL, O_NONBLOCK); - transfer->wlFD = p[0]; + transfer->wlFD = CFileDescriptor{p[0]}; Debug::log(LOG, "[xwm] sending wayland selection to xwayland with mime {}, target {}, fds {} {}", mime, e->target, p[0], p[1]); - selection->send(mime, p[1]); + selection->send(mime, CFileDescriptor{p[1]}); - transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD, WL_EVENT_READABLE, ::readDataSource, this); + transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD.get(), WL_EVENT_READABLE, ::readDataSource, this); return true; } @@ -1376,10 +1376,9 @@ int SXSelection::onWrite() { char* property = (char*)xcb_get_property_value(transfer->propertyReply); int remainder = xcb_get_property_value_length(transfer->propertyReply) - transfer->propertyStart; - ssize_t len = write(transfer->wlFD, property + transfer->propertyStart, remainder); + ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder); if (len == -1) { Debug::log(ERR, "[xwm] write died in transfer get"); - close(transfer->wlFD); transfer.reset(); return 0; } @@ -1389,7 +1388,6 @@ int SXSelection::onWrite() { Debug::log(LOG, "[xwm] wl client read partially: len {}", len); } else { Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len); - close(transfer->wlFD); transfer.reset(); } @@ -1397,8 +1395,6 @@ int SXSelection::onWrite() { } SXTransfer::~SXTransfer() { - if (wlFD) - close(wlFD); if (eventSource) wl_event_source_remove(eventSource); if (incomingWindow) diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index dfaf33b9..73a02a86 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -10,6 +10,7 @@ #include #include #include +#include struct wl_event_source; class CXWaylandSurfaceResource; @@ -18,25 +19,25 @@ struct SXSelection; struct SXTransfer { ~SXTransfer(); - SXSelection& selection; - bool out = true; + SXSelection& selection; + bool out = true; - bool incremental = false; - bool flushOnDelete = false; - bool propertySet = false; + bool incremental = false; + bool flushOnDelete = false; + bool propertySet = false; - int wlFD = -1; - wl_event_source* eventSource = nullptr; + Hyprutils::OS::CFileDescriptor wlFD; + wl_event_source* eventSource = nullptr; - std::vector data; + std::vector data; - xcb_selection_request_event_t request; + xcb_selection_request_event_t request; - int propertyStart; - xcb_get_property_reply_t* propertyReply; - xcb_window_t incomingWindow; + int propertyStart; + xcb_get_property_reply_t* propertyReply; + xcb_window_t incomingWindow; - bool getIncomingSelectionProp(bool erase); + bool getIncomingSelectionProp(bool erase); }; struct SXSelection { From ef03f6911694413b1b06aba727ad9ab089a511f7 Mon Sep 17 00:00:00 2001 From: nyx Date: Thu, 30 Jan 2025 16:36:42 -0500 Subject: [PATCH 0208/1444] xwayland: handle window coords correctly (#9238) --- src/desktop/Window.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index e59a8d4e..09037cbd 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1706,9 +1706,15 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional // TODO: this should be decoupled from setWindowSize IMO Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal()); - if (m_bIsX11) { - if (const auto XWAYLANDPOS = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); XWAYLANDPOS != Vector2D{}) - windowPos = XWAYLANDPOS; + if (m_bIsX11 && PMONITOR) { + windowPos -= PMONITOR->vecPosition; + + if (*PXWLFORCESCALEZERO) { + windowPos *= PMONITOR->scale; + size *= PMONITOR->scale; + } + + windowPos += PMONITOR->vecXWaylandPosition; } if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11)) @@ -1716,13 +1722,10 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional m_vReportedPosition = windowPos; m_vPendingReportedSize = size; + m_fX11SurfaceScaledBy = 1.0f; - m_fX11SurfaceScaledBy = 1.0f; - - if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR) { - size *= PMONITOR->scale; + if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR) m_fX11SurfaceScaledBy = PMONITOR->scale; - } if (m_bIsX11 && m_pXWaylandSurface) m_pXWaylandSurface->configure({windowPos, size}); From e6a9cfab9199788ee0dcefd8b1bda46f93e6a001 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Fri, 31 Jan 2025 06:23:32 -0600 Subject: [PATCH 0209/1444] monitor: preferred mode now tries first 3 modes if preferred fails before erroring (#9246) --- src/helpers/Monitor.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index fc3de3aa..9aa6efce 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -435,7 +435,7 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { // accumulate requested modes in reverse order (cause inesrting at front is inefficient) std::vector> requestedModes; - std::string requestedStr = "preferred"; + std::string requestedStr = "unknown"; // use sortFunc, add best 3 to requestedModes in reverse, since we test in reverse auto addBest3Modes = [&](auto const& sortFunc) { @@ -446,13 +446,24 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) { requestedModes.insert(requestedModes.end(), sortedModes.rbegin(), sortedModes.rend()); }; - // last fallback is preferred mode, btw this covers resolution == Vector2D() + // last fallback is always preferred mode if (!output->preferredMode()) Debug::log(ERR, "Monitor {} has NO PREFERRED MODE", output->name); else requestedModes.push_back(output->preferredMode()); - if (RULE->resolution == Vector2D(-1, -1)) { + if (RULE->resolution == Vector2D()) { + requestedStr = "preferred"; + + // fallback to first 3 modes if preferred fails/doesn't exist + requestedModes = output->modes; + if (requestedModes.size() > 3) + requestedModes.erase(requestedModes.begin() + 3, requestedModes.end()); + std::ranges::reverse(requestedModes.begin(), requestedModes.end()); + + if (output->preferredMode()) + requestedModes.push_back(output->preferredMode()); + } else if (RULE->resolution == Vector2D(-1, -1)) { requestedStr = "highrr"; // sort prioritizing refresh rate 1st and resolution 2nd, then add best 3 From ea16b64ec169afcd21020dfb819a73c37428c7f2 Mon Sep 17 00:00:00 2001 From: nyx Date: Fri, 31 Jan 2025 07:26:08 -0500 Subject: [PATCH 0210/1444] xwayland: prevent invalid window configurations for X11 apps (#9253) * fix(xwayland): prevent invalid window configurations for X11 apps * refact(xwayland): remove unneeded line --- src/desktop/Window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 09037cbd..91c76e7c 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1700,7 +1700,7 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional const auto PMONITOR = m_pMonitor.lock(); - size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + size = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); // calculate pos // TODO: this should be decoupled from setWindowSize IMO From 7d51dee103e22742d425d14faebb0273a64ac8c1 Mon Sep 17 00:00:00 2001 From: Aaron Tulino <13600347+aaronjamt@users.noreply.github.com> Date: Fri, 31 Jan 2025 05:33:36 -0700 Subject: [PATCH 0211/1444] hyprctl: Extract IPC code to separate method (#9223) This makes it possible to use the same IPC code for more projects in the future --- hyprctl/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hyprctl/main.cpp b/hyprctl/main.cpp index 4cc73bdf..ac88f1da 100644 --- a/hyprctl/main.cpp +++ b/hyprctl/main.cpp @@ -225,7 +225,7 @@ int request(std::string arg, int minArgs = 0, bool needRoll = false) { return 0; } -int requestHyprpaper(std::string arg) { +int requestIPC(std::string filename, std::string arg) { const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0); if (SERVERSOCKET < 0) { @@ -243,7 +243,7 @@ int requestHyprpaper(std::string arg) { const std::string USERID = std::to_string(getUID()); - std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/.hyprpaper.sock"; + std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/" + filename; strncpy(serverAddress.sun_path, socketPath.c_str(), sizeof(serverAddress.sun_path) - 1); @@ -278,6 +278,10 @@ int requestHyprpaper(std::string arg) { return 0; } +int requestHyprpaper(std::string arg) { + return requestIPC(".hyprpaper.sock", arg); +} + void batchRequest(std::string arg, bool json) { std::string commands = arg.substr(arg.find_first_of(' ') + 1); From ac5668192ed56c50b5612c7670e397a2128eeba6 Mon Sep 17 00:00:00 2001 From: Brayden Zee Date: Fri, 31 Jan 2025 07:33:51 -0500 Subject: [PATCH 0212/1444] desktop: fix segfault when destroying a partially create layer surface (#9247) --- src/desktop/LayerSurface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index e2d0177b..78dae0a9 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -98,7 +98,8 @@ void CLayerSurface::onDestroy() { onUnmap(); } else { Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); - alpha->setValueAndWarp(0.f); + if (alpha) + alpha->setValueAndWarp(0.f); fadingOut = true; g_pCompositor->addToFadingOutSafe(self.lock()); } From 9c38287410b305503f921e411eb39686b23ccc42 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 31 Jan 2025 13:32:36 +0000 Subject: [PATCH 0213/1444] groupbar: various visual improvements added rounding, round at edges, and indicator height --- src/config/ConfigDescriptions.hpp | 32 ++++++- src/config/ConfigManager.cpp | 7 +- .../decorations/CHyprGroupBarDecoration.cpp | 91 +++++++++++++++---- src/render/pass/RectPassElement.cpp | 5 + src/render/pass/RectPassElement.hpp | 1 + src/render/pass/TexPassElement.cpp | 6 +- src/render/pass/TexPassElement.hpp | 1 + 7 files changed, 121 insertions(+), 22 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 483f1f1f..01ef392e 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -883,7 +883,7 @@ inline static const std::vector CONFIG_OPTIONS = { .value = "group:groupbar:gradients", .description = "enables gradients", .type = CONFIG_OPTION_BOOL, - .data = SConfigOptionDescription::SBoolData{true}, + .data = SConfigOptionDescription::SBoolData{false}, }, SConfigOptionDescription{ .value = "group:groupbar:height", @@ -891,6 +891,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{14, 1, 64}, }, + SConfigOptionDescription{ + .value = "group:groupbar:indicator_height", + .description = "height of the groupbar indicator", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{3, 1, 64}, + }, SConfigOptionDescription{ .value = "group:groupbar:stacked", .description = "render the groupbar as a vertical stack", @@ -915,6 +921,30 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{true}, }, + SConfigOptionDescription{ + .value = "group:groupbar:rounding", + .description = "how much to round the groupbar", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{1, 0, 20}, + }, + SConfigOptionDescription{ + .value = "group:groupbar:gradient_rounding", + .description = "how much to round the groupbar gradient", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{1, 0, 20}, + }, + SConfigOptionDescription{ + .value = "group:groupbar:round_only_edges", + .description = "if yes, will only round at the groupbar edges", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, + SConfigOptionDescription{ + .value = "group:groupbar:groupbar_round_only_edges", + .description = "if yes, will only round at the groupbar gradient edges", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, SConfigOptionDescription{ .value = "group:groupbar:text_color", .description = "controls the group bar text color", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 86581b10..e36a2914 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -441,13 +441,18 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY}); m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8}); - m_pConfig->addConfigValue("group:groupbar:gradients", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:groupbar:gradients", Hyprlang::INT{0}); m_pConfig->addConfigValue("group:groupbar:height", Hyprlang::INT{14}); + m_pConfig->addConfigValue("group:groupbar:indicator_height", Hyprlang::INT{3}); m_pConfig->addConfigValue("group:groupbar:priority", Hyprlang::INT{3}); m_pConfig->addConfigValue("group:groupbar:render_titles", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:scrolling", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:text_color", Hyprlang::INT{0xffffffff}); m_pConfig->addConfigValue("group:groupbar:stacked", Hyprlang::INT{0}); + m_pConfig->addConfigValue("group:groupbar:rounding", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:groupbar:gradient_rounding", Hyprlang::INT{2}); + m_pConfig->addConfigValue("group:groupbar:round_only_edges", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:groupbar:gradient_round_only_edges", Hyprlang::INT{1}); m_pConfig->addConfigValue("debug:int", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:log_damage", Hyprlang::INT{0}); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 88501d74..1a64b024 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -15,7 +15,6 @@ static SP m_tGradientInactive = makeShared(); static SP m_tGradientLockedActive = makeShared(); static SP m_tGradientLockedInactive = makeShared(); -constexpr int BAR_INDICATOR_HEIGHT = 3; constexpr int BAR_PADDING_OUTER_VERT = 2; constexpr int BAR_PADDING_OUTER_HORZ = 2; constexpr int BAR_TEXT_PAD = 2; @@ -30,12 +29,13 @@ CHyprGroupBarDecoration::CHyprGroupBarDecoration(PHLWINDOW pWindow) : IHyprWindo } SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() { - static auto PHEIGHT = CConfigValue("group:groupbar:height"); - static auto PENABLED = CConfigValue("group:groupbar:enabled"); - static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); - static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); - static auto PPRIORITY = CConfigValue("group:groupbar:priority"); - static auto PSTACKED = CConfigValue("group:groupbar:stacked"); + static auto PHEIGHT = CConfigValue("group:groupbar:height"); + static auto PINDICATORHEIGHT = CConfigValue("group:groupbar:indicator_height"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); + static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); + static auto PPRIORITY = CConfigValue("group:groupbar:priority"); + static auto PSTACKED = CConfigValue("group:groupbar:stacked"); SDecorationPositioningInfo info; info.policy = DECORATION_POSITION_STICKY; @@ -45,10 +45,10 @@ SDecorationPositioningInfo CHyprGroupBarDecoration::getPositioningInfo() { if (*PENABLED && m_pWindow->m_sWindowData.decorate.valueOrDefault()) { if (*PSTACKED) { - const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); + const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); info.desiredExtents = {{0, (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT}, {0, 0}}; } else - info.desiredExtents = {{0, BAR_PADDING_OUTER_VERT * 2 + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2}, {0, 0}}; + info.desiredExtents = {{0, BAR_PADDING_OUTER_VERT * 2 + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0) + 2}, {0, 0}}; } else info.desiredExtents = {{0, 0}, {0, 0}}; return info; @@ -99,19 +99,24 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { // get how many bars we will draw int barsToDraw = m_dwGroupMembers.size(); - static auto PENABLED = CConfigValue("group:groupbar:enabled"); - static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); - static auto PTITLEFONTSIZE = CConfigValue("group:groupbar:font_size"); - static auto PHEIGHT = CConfigValue("group:groupbar:height"); - static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); - static auto PSTACKED = CConfigValue("group:groupbar:stacked"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); + static auto PTITLEFONTSIZE = CConfigValue("group:groupbar:font_size"); + static auto PHEIGHT = CConfigValue("group:groupbar:height"); + static auto PINDICATORHEIGHT = CConfigValue("group:groupbar:indicator_height"); + static auto PGRADIENTS = CConfigValue("group:groupbar:gradients"); + static auto PSTACKED = CConfigValue("group:groupbar:stacked"); + static auto PROUNDING = CConfigValue("group:groupbar:rounding"); + static auto PGRADIENTROUNDING = CConfigValue("group:groupbar:gradient_rounding"); + static auto PGRADIENTROUNDINGONLYEDGES = CConfigValue("group:groupbar:gradient_round_only_edges"); + static auto PROUNDONLYEDGES = CConfigValue("group:groupbar:round_only_edges"); if (!*PENABLED || !m_pWindow->m_sWindowData.decorate.valueOrDefault()) return; const auto ASSIGNEDBOX = assignedBoxGlobal(); - const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + BAR_INDICATOR_HEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); + const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); m_fBarWidth = *PSTACKED ? ASSIGNEDBOX.w : (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw; m_fBarHeight = *PSTACKED ? ((ASSIGNEDBOX.h - 2 - BAR_PADDING_OUTER_VERT) - BAR_PADDING_OUTER_VERT * (barsToDraw)) / barsToDraw : ASSIGNEDBOX.h - BAR_PADDING_OUTER_VERT; @@ -126,8 +131,8 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { const auto WINDOWINDEX = *PSTACKED ? m_dwGroupMembers.size() - i - 1 : i; CBox rect = {ASSIGNEDBOX.x + floor(xoff) - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, - ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - BAR_INDICATOR_HEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, - m_fBarWidth, BAR_INDICATOR_HEIGHT}; + ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - *PINDICATORHEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, + m_fBarWidth, *PINDICATORHEIGHT}; if (rect.width <= 0 || rect.height <= 0) break; @@ -152,6 +157,30 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { CRectPassElement::SRectData rectdata; rectdata.color = color; rectdata.box = rect; + if (*PROUNDING) { + if (*PROUNDONLYEDGES) { + static constexpr double PADDING = 20; + + if (i == 0 && barsToDraw == 1) + rectdata.round = *PROUNDING; + else if (i == 0) { + double first = rect.w - (*PROUNDING * 2); + rectdata.round = *PROUNDING; + rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); + rectdata.round = 0; + rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } else if (i == barsToDraw - 1) { + double first = *PROUNDING * 2; + rectdata.round = 0; + rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); + rectdata.round = *PROUNDING; + rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } + } else + rectdata.round = *PROUNDING; + } g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); rect = {ASSIGNEDBOX.x + floor(xoff) - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, @@ -166,6 +195,30 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { CTexPassElement::SRenderData data; data.tex = GRADIENTTEX; data.box = rect; + if (*PGRADIENTROUNDING) { + if (*PGRADIENTROUNDINGONLYEDGES) { + static constexpr double PADDING = 20; + + if (i == 0 && barsToDraw == 1) + data.round = *PGRADIENTROUNDING; + else if (i == 0) { + double first = rect.w - (*PGRADIENTROUNDING * 2); + data.round = *PGRADIENTROUNDING; + data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + data.round = 0; + data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } else if (i == barsToDraw - 1) { + double first = *PGRADIENTROUNDING * 2; + data.round = 0; + data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + data.round = *PGRADIENTROUNDING; + data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } + } else + rectdata.round = *PGRADIENTROUNDING; + } g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } } @@ -229,7 +282,7 @@ CTitleTex::CTitleTex(PHLWINDOW pWindow, const Vector2D& bufferSize, const float texSize = tex->m_vSize; } -void renderGradientTo(SP tex, CGradientValueData* grad) { +static void renderGradientTo(SP tex, CGradientValueData* grad) { if (!g_pCompositor->m_pLastMonitor) return; diff --git a/src/render/pass/RectPassElement.cpp b/src/render/pass/RectPassElement.cpp index fba06286..aa024577 100644 --- a/src/render/pass/RectPassElement.cpp +++ b/src/render/pass/RectPassElement.cpp @@ -9,10 +9,15 @@ void CRectPassElement::draw(const CRegion& damage) { if (data.box.w <= 0 || data.box.h <= 0) return; + if (!data.clipBox.empty()) + g_pHyprOpenGL->m_RenderData.clipBox = data.clipBox; + if (data.color.a == 1.F || !data.blur) g_pHyprOpenGL->renderRectWithDamage(data.box, data.color, damage, data.round, data.roundingPower); else g_pHyprOpenGL->renderRectWithBlur(data.box, data.color, data.round, data.roundingPower, data.blurA, data.xray); + + g_pHyprOpenGL->m_RenderData.clipBox = {}; } bool CRectPassElement::needsLiveBlur() { diff --git a/src/render/pass/RectPassElement.hpp b/src/render/pass/RectPassElement.hpp index d27abdcc..f798dbf9 100644 --- a/src/render/pass/RectPassElement.hpp +++ b/src/render/pass/RectPassElement.hpp @@ -10,6 +10,7 @@ class CRectPassElement : public IPassElement { float roundingPower = 2.0f; bool blur = false, xray = false; float blurA = 1.F; + CBox clipBox; }; CRectPassElement(const SRectData& data); diff --git a/src/render/pass/TexPassElement.cpp b/src/render/pass/TexPassElement.cpp index c7eab292..8b577373 100644 --- a/src/render/pass/TexPassElement.cpp +++ b/src/render/pass/TexPassElement.cpp @@ -13,9 +13,13 @@ void CTexPassElement::draw(const CRegion& damage) { CScopeGuard x = {[]() { // - g_pHyprOpenGL->m_bEndFrame = false; + g_pHyprOpenGL->m_bEndFrame = false; + g_pHyprOpenGL->m_RenderData.clipBox = {}; }}; + if (!data.clipBox.empty()) + g_pHyprOpenGL->m_RenderData.clipBox = data.clipBox; + if (data.replaceProjection) g_pHyprOpenGL->m_RenderData.monitorProjection = *data.replaceProjection; g_pHyprOpenGL->renderTextureInternalWithDamage(data.tex, data.box, data.a, data.damage.empty() ? damage : data.damage, data.round, data.roundingPower, data.syncTimeline, diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp index 036b89fe..6faa0872 100644 --- a/src/render/pass/TexPassElement.hpp +++ b/src/render/pass/TexPassElement.hpp @@ -19,6 +19,7 @@ class CTexPassElement : public IPassElement { SP syncTimeline; int64_t syncPoint = 0; std::optional replaceProjection; + CBox clipBox; }; CTexPassElement(const SRenderData& data); From 12b5034c99f28025e6c6be29c33bde9f4a24ac9f Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Fri, 31 Jan 2025 15:36:22 +0200 Subject: [PATCH 0214/1444] configWatcher: watch both symlinks and canonical paths (#9219) --- src/config/ConfigWatcher.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/config/ConfigWatcher.cpp b/src/config/ConfigWatcher.cpp index 8d086bac..e5db1e86 100644 --- a/src/config/ConfigWatcher.cpp +++ b/src/config/ConfigWatcher.cpp @@ -4,6 +4,7 @@ #include #include #include +#include using namespace Hyprutils::OS; @@ -43,9 +44,19 @@ void CConfigWatcher::setWatchList(const std::vector& paths) { // add new paths for (const auto& path : paths) { m_watches.emplace_back(SInotifyWatch{ - .wd = inotify_add_watch(m_inotifyFd.get(), path.c_str(), IN_MODIFY), + .wd = inotify_add_watch(m_inotifyFd.get(), path.c_str(), IN_MODIFY | IN_DONT_FOLLOW), .file = path, }); + + std::error_code ec, ec2; + const auto CANONICAL = std::filesystem::canonical(path, ec); + const auto IS_SYMLINK = std::filesystem::is_symlink(path, ec2); + if (!ec && !ec2 && IS_SYMLINK) { + m_watches.emplace_back(SInotifyWatch{ + .wd = inotify_add_watch(m_inotifyFd.get(), CANONICAL.c_str(), IN_MODIFY), + .file = path, + }); + } } } From a4b7d1c2d7538068ab4832a66f86801f5f75cc65 Mon Sep 17 00:00:00 2001 From: nyx Date: Fri, 31 Jan 2025 08:36:56 -0500 Subject: [PATCH 0215/1444] xwayland: correct pointer coordinate mismatch in X11 windows (#9259) refactor(xwayland): add back comments --- src/desktop/Window.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 91c76e7c..0f6bac99 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1697,8 +1697,7 @@ Vector2D CWindow::requestedMaxSize() { void CWindow::sendWindowSize(Vector2D size, bool force, std::optional overridePos) { static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); - - const auto PMONITOR = m_pMonitor.lock(); + const auto PMONITOR = m_pMonitor.lock(); size = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); @@ -1707,14 +1706,9 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal()); if (m_bIsX11 && PMONITOR) { - windowPos -= PMONITOR->vecPosition; - - if (*PXWLFORCESCALEZERO) { - windowPos *= PMONITOR->scale; + windowPos = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); + if (*PXWLFORCESCALEZERO) size *= PMONITOR->scale; - } - - windowPos += PMONITOR->vecXWaylandPosition; } if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11)) From ddf180fa304e71b1d6eaa9f2b250a907131b05d9 Mon Sep 17 00:00:00 2001 From: nyx Date: Fri, 31 Jan 2025 11:08:43 -0500 Subject: [PATCH 0216/1444] render: enforce framebuffer offloading and remove introspection toggle (#9217) --- src/config/ConfigDescriptions.hpp | 7 -- src/config/ConfigManager.cpp | 1 - src/render/OpenGL.cpp | 147 ++---------------------------- src/render/OpenGL.hpp | 3 - src/render/pass/Pass.cpp | 4 - src/render/pass/Pass.hpp | 1 - 6 files changed, 10 insertions(+), 153 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 01ef392e..2fa86817 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1294,13 +1294,6 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{true}, }, - SConfigOptionDescription{ - .value = "opengl:force_introspection", - .description = "forces introspection at all times. Introspection is aimed at reducing GPU usage in certain cases, but might cause graphical glitches on nvidia. 0 - " - "nothing, 1 - force always on, 2 - force always on if nvidia", - .type = CONFIG_OPTION_INT, - .data = SConfigOptionDescription::SRangeData{2, 0, 2}, - }, /* * render: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index e36a2914..8bb6d157 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -619,7 +619,6 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0}); m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1}); - m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{1}); // TODO: remove this. I don't think it does us any good to disable intro. m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0}); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index e4aadd63..75a5eadb 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -650,112 +650,6 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool return shader; } -bool CHyprOpenGLImpl::passRequiresIntrospection(PHLMONITOR pMonitor) { - // passes requiring introspection are the ones that need to render blur, - // or when we are rendering to a multigpu target - - static auto PBLUR = CConfigValue("decoration:blur:enabled"); - static auto PXRAY = CConfigValue("decoration:blur:xray"); - static auto POPTIM = CConfigValue("decoration:blur:new_optimizations"); - static auto PBLURSPECIAL = CConfigValue("decoration:blur:special"); - static auto PBLURPOPUPS = CConfigValue("decoration:blur:popups"); - - if (m_RenderData.mouseZoomFactor != 1.0 || g_pHyprRenderer->m_bCrashingInProgress) - return true; - - // mirrors should not be offloaded (as we then would basically copy the same data twice) - // yes, this breaks mirrors of mirrors - if (pMonitor->isMirror()) - return false; - - // monitors that are mirrored however must be offloaded because we cannot copy from output FBs - if (!pMonitor->mirrors.empty()) - return true; - - if (*PBLUR == 0) - return false; - - if (preBlurQueued()) - return true; - - if (!pMonitor->solitaryClient.expired()) - return false; - - for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) { - const auto XRAYMODE = ls->xray == -1 ? *PXRAY : ls->xray; - if (ls->forceBlur && !XRAYMODE) - return true; - - if (ls->popupsCount() > 0 && ls->forceBlurPopups) - return true; - } - - for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { - const auto XRAYMODE = ls->xray == -1 ? *PXRAY : ls->xray; - if (ls->forceBlur && !XRAYMODE) - return true; - - if (ls->popupsCount() > 0 && ls->forceBlurPopups) - return true; - } - - // these two block optimization - for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { - if (ls->forceBlur) - return true; - - if (ls->popupsCount() > 0 && ls->forceBlurPopups) - return true; - } - - for (auto const& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) { - if (ls->forceBlur) - return true; - - if (ls->popupsCount() > 0 && ls->forceBlurPopups) - return true; - } - - if (*PBLURSPECIAL) { - for (auto const& ws : g_pCompositor->m_vWorkspaces) { - if (!ws->m_bIsSpecialWorkspace || ws->m_pMonitor != pMonitor) - continue; - - if (ws->m_fAlpha->value() == 0) - continue; - - return true; - } - } - - if (*PXRAY) - return false; - - for (auto const& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || w->isHidden()) - continue; - - if (!g_pHyprRenderer->shouldRenderWindow(w)) - continue; - - if (w->popupsCount() > 0 && *PBLURPOPUPS) - return true; - - if (!w->m_bIsFloating && *POPTIM && !w->onSpecialWorkspace()) - continue; - - if (w->m_sWindowData.noBlur.valueOrDefault() || w->m_sWindowData.xray.valueOrDefault()) - continue; - - if (w->opaque()) - continue; - - return true; - } - - return false; -} - void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP rb, CFramebuffer* fb) { m_RenderData.pMonitor = pMonitor; @@ -811,8 +705,6 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFramebuffer* fb, std::optional finalDamage) { m_RenderData.pMonitor = pMonitor; - static auto PFORCEINTROSPECTION = CConfigValue("opengl:force_introspection"); - #ifndef GLES2 const GLenum RESETSTATUS = glGetGraphicsResetStatus(); if (RESETSTATUS != GL_NO_ERROR) { @@ -871,30 +763,12 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb applyScreenShader(*PSHADER); } - const auto PRBO = g_pHyprRenderer->getCurrentRBO(); - const bool FBPROPERSIZE = !fb || fb->m_vSize == pMonitor->vecPixelSize; - const bool USERFORCEDINTROSPECTION = *PFORCEINTROSPECTION == 1 ? true : (*PFORCEINTROSPECTION == 2 ? g_pHyprRenderer->isNvidia() : false); // 0 - no, 1 - yes, 2 - nvidia only - - if (USERFORCEDINTROSPECTION || m_RenderData.forceIntrospection || !FBPROPERSIZE || m_sFinalScreenShader.program > 0 || - (PRBO && pMonitor->vecPixelSize != PRBO->getFB()->m_vSize) || passRequiresIntrospection(pMonitor)) { - // we have to offload - // bind the offload Hypr Framebuffer - m_RenderData.pCurrentMonData->offloadFB.bind(); - m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offloadFB; - m_bOffloadedFramebuffer = true; - } else { - // we can render to the rbo / fbo (fake) directly - const auto PFBO = fb ? fb : PRBO->getFB(); - m_RenderData.currentFB = PFBO; - if (PFBO->getStencilTex() != m_RenderData.pCurrentMonData->stencilTex) - PFBO->addStencil(m_RenderData.pCurrentMonData->stencilTex); - - PFBO->bind(); - m_bOffloadedFramebuffer = false; - } + m_RenderData.pCurrentMonData->offloadFB.bind(); + m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offloadFB; + m_bOffloadedFramebuffer = true; m_RenderData.mainFB = m_RenderData.currentFB; - m_RenderData.outFB = fb ? fb : PRBO->getFB(); + m_RenderData.outFB = fb ? fb : g_pHyprRenderer->getCurrentRBO()->getFB(); } void CHyprOpenGLImpl::end() { @@ -952,13 +826,12 @@ void CHyprOpenGLImpl::end() { // reset our data m_RenderData.pMonitor.reset(); - m_RenderData.mouseZoomFactor = 1.f; - m_RenderData.mouseZoomUseMouse = true; - m_RenderData.forceIntrospection = false; - m_RenderData.blockScreenShader = false; - m_RenderData.currentFB = nullptr; - m_RenderData.mainFB = nullptr; - m_RenderData.outFB = nullptr; + m_RenderData.mouseZoomFactor = 1.f; + m_RenderData.mouseZoomUseMouse = true; + m_RenderData.blockScreenShader = false; + m_RenderData.currentFB = nullptr; + m_RenderData.mainFB = nullptr; + m_RenderData.outFB = nullptr; // if we dropped to offMain, release it now. // if there is a plugin constantly using it, this might be a bit slow, diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index d7abdf63..7b7b7e6f 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -126,7 +126,6 @@ struct SCurrentRenderData { float mouseZoomFactor = 1.f; bool mouseZoomUseMouse = true; // true by default bool useNearestNeighbor = false; - bool forceIntrospection = false; // cleaned in ::end() bool blockScreenShader = false; bool simplePass = false; @@ -322,8 +321,6 @@ class CHyprOpenGLImpl { void preBlurForCurrentMonitor(); - bool passRequiresIntrospection(PHLMONITOR pMonitor); - friend class CHyprRenderer; friend class CTexPassElement; friend class CPreBlurElement; diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 81b918ac..5068cbbc 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -17,10 +17,6 @@ bool CRenderPass::single() const { return m_vPassElements.size() == 1; } -bool CRenderPass::needsIntrospection() const { - return true; -} - void CRenderPass::add(SP el) { m_vPassElements.emplace_back(makeShared(CRegion{}, el)); } diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp index a0810155..bbc55d2c 100644 --- a/src/render/pass/Pass.hpp +++ b/src/render/pass/Pass.hpp @@ -10,7 +10,6 @@ class CRenderPass { public: bool empty() const; bool single() const; - bool needsIntrospection() const; void add(SP elem); void clear(); From d11d0697155e0896c4ab76406e6d5dcf35abff05 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Sat, 1 Feb 2025 09:29:06 +0200 Subject: [PATCH 0217/1444] CI/Nix: remove deprecated magic-nix-cache-action --- .github/workflows/nix-build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/nix-build.yml b/.github/workflows/nix-build.yml index a98468ac..5b2e81cf 100644 --- a/.github/workflows/nix-build.yml +++ b/.github/workflows/nix-build.yml @@ -19,7 +19,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - uses: cachix/cachix-action@v15 with: From 5b43c106bd1cde9ac0b5626130890cde4de0b245 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sat, 1 Feb 2025 14:44:20 +0000 Subject: [PATCH 0218/1444] animation: don't immediately disconnect active vars during tick (#9272) --- CMakeLists.txt | 2 +- src/managers/AnimationManager.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a34d677c..9c286831 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION}) pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5) pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2) pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) -pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.4.0) +pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.0) pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1) add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}") diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 5be7aa33..29f669dc 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -43,7 +43,7 @@ CHyprAnimationManager::CHyprAnimationManager() { template static void updateVariable(CAnimatedVariable& av, const float POINTY, bool warp = false) { if (warp || av.value() == av.goal()) { - av.warp(); + av.warp(true, false); return; } @@ -53,7 +53,7 @@ static void updateVariable(CAnimatedVariable& av, const float POINTY, b static void updateColorVariable(CAnimatedVariable& av, const float POINTY, bool warp) { if (warp || av.value() == av.goal()) { - av.warp(); + av.warp(true, false); return; } From c6f672257bd2ae98f4fd7a6a273b2d1d3e944baa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 1 Feb 2025 15:08:30 +0000 Subject: [PATCH 0219/1444] desktop: move popup and subsurface ctors to factories makes sure m_pSelf is set before we do anything like possibly adding children fixes #9275 supersedes #9276 --- src/desktop/LayerSurface.cpp | 7 ++--- src/desktop/LayerSurface.hpp | 2 +- src/desktop/Popup.cpp | 41 ++++++++++++++++++---------- src/desktop/Popup.hpp | 8 ++++-- src/desktop/Subsurface.cpp | 53 ++++++++++++++++++++++++------------ src/desktop/Subsurface.hpp | 10 ++++--- src/desktop/Window.cpp | 6 ++-- src/desktop/Window.hpp | 2 +- 8 files changed, 80 insertions(+), 49 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 78dae0a9..f4ffaedf 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -31,10 +31,9 @@ PHLLS CLayerSurface::create(SP resource) { pLS->szNamespace = resource->layerNamespace; - pLS->layer = resource->current.layer; - pLS->popupHead = makeUnique(pLS); - pLS->popupHead->m_pSelf = pLS->popupHead; - pLS->monitor = pMonitor; + pLS->layer = resource->current.layer; + pLS->popupHead = CPopup::create(pLS); + pLS->monitor = pMonitor; pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS); pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace); diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index ab259733..f2be7459 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -59,7 +59,7 @@ class CLayerSurface { CBox geometry = {0, 0, 0, 0}; Vector2D position; std::string szNamespace = ""; - UP popupHead; + SP popupHead; void onDestroy(); void onMap(); diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index dea94f55..20ff49d7 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -12,23 +12,37 @@ #include "../render/OpenGL.hpp" #include -CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) { - initAllSignals(); +SP CPopup::create(PHLWINDOW pOwner) { + auto popup = SP(new CPopup()); + popup->m_pWindowOwner = pOwner; + popup->m_pSelf = popup; + popup->initAllSignals(); + return popup; } -CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) { - initAllSignals(); +SP CPopup::create(PHLLS pOwner) { + auto popup = SP(new CPopup()); + popup->m_pLayerOwner = pOwner; + popup->m_pSelf = popup; + popup->initAllSignals(); + return popup; } -CPopup::CPopup(SP popup, WP pOwner) : - m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) { - m_pWLSurface = CWLSurface::create(); - m_pWLSurface->assign(popup->surface->surface.lock(), this); +SP CPopup::create(SP resource, WP pOwner) { + auto popup = SP(new CPopup()); + popup->m_pResource = resource; + popup->m_pWindowOwner = pOwner->m_pWindowOwner; + popup->m_pLayerOwner = pOwner->m_pLayerOwner; + popup->m_pParent = pOwner; + popup->m_pSelf = popup; + popup->m_pWLSurface = CWLSurface::create(); + popup->m_pWLSurface->assign(resource->surface->surface.lock(), popup.get()); - m_vLastSize = popup->surface->current.geometry.size(); - reposition(); + popup->m_vLastSize = resource->surface->current.geometry.size(); + popup->reposition(); - initAllSignals(); + popup->initAllSignals(); + return popup; } CPopup::~CPopup() { @@ -59,7 +73,7 @@ void CPopup::initAllSignals() { } void CPopup::onNewPopup(SP popup) { - const auto& POPUP = m_vChildren.emplace_back(makeShared(popup, m_pSelf)); + const auto& POPUP = m_vChildren.emplace_back(CPopup::create(popup, m_pSelf)); POPUP->m_pSelf = POPUP; Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP); } @@ -91,8 +105,7 @@ void CPopup::onMap() { g_pInputManager->simulateMouseMovement(); - m_pSubsurfaceHead = makeUnique(m_pSelf); - m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead; + m_pSubsurfaceHead = CSubsurface::create(m_pSelf); //unconstrain(); sendScale(); diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 6051f7eb..a64af7eb 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -10,11 +10,11 @@ class CXDGPopupResource; class CPopup { public: // dummy head nodes - CPopup(PHLWINDOW pOwner); - CPopup(PHLLS pOwner); + static SP create(PHLWINDOW pOwner); + static SP create(PHLLS pOwner); // real nodes - CPopup(SP popup, WP pOwner); + static SP create(SP popup, WP pOwner); ~CPopup(); @@ -45,6 +45,8 @@ class CPopup { bool m_bMapped = false; private: + CPopup() = default; + // T1 owners, each popup has to have one of these PHLWINDOWREF m_pWindowOwner; PHLLSREF m_pLayerOwner; diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 1d938f39..33ee3553 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -7,28 +7,45 @@ #include "../render/Renderer.hpp" #include "../managers/input/InputManager.hpp" -CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) { - initSignals(); - initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); +UP CSubsurface::create(PHLWINDOW pOwner) { + auto subsurface = UP(new CSubsurface()); + subsurface->m_pWindowParent = pOwner; + subsurface->m_pSelf = subsurface; + + subsurface->initSignals(); + subsurface->initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); + return subsurface; } -CSubsurface::CSubsurface(WP pOwner) : m_pPopupParent(pOwner) { - initSignals(); - initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); +UP CSubsurface::create(WP pOwner) { + auto subsurface = UP(new CSubsurface()); + subsurface->m_pPopupParent = pOwner; + subsurface->m_pSelf = subsurface; + subsurface->initSignals(); + subsurface->initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); + return subsurface; } -CSubsurface::CSubsurface(SP pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) { - m_pWLSurface = CWLSurface::create(); - m_pWLSurface->assign(pSubsurface->surface.lock(), this); - initSignals(); - initExistingSubsurfaces(pSubsurface->surface.lock()); +UP CSubsurface::create(SP pSubsurface, PHLWINDOW pOwner) { + auto subsurface = UP(new CSubsurface()); + subsurface->m_pWindowParent = pOwner; + subsurface->m_pSelf = subsurface; + subsurface->m_pWLSurface = CWLSurface::create(); + subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get()); + subsurface->initSignals(); + subsurface->initExistingSubsurfaces(pSubsurface->surface.lock()); + return subsurface; } -CSubsurface::CSubsurface(SP pSubsurface, WP pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) { - m_pWLSurface = CWLSurface::create(); - m_pWLSurface->assign(pSubsurface->surface.lock(), this); - initSignals(); - initExistingSubsurfaces(pSubsurface->surface.lock()); +UP CSubsurface::create(SP pSubsurface, WP pOwner) { + auto subsurface = UP(new CSubsurface()); + subsurface->m_pPopupParent = pOwner; + subsurface->m_pSelf = subsurface; + subsurface->m_pWLSurface = CWLSurface::create(); + subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get()); + subsurface->initSignals(); + subsurface->initExistingSubsurfaces(pSubsurface->surface.lock()); + return subsurface; } void CSubsurface::initSignals() { @@ -131,9 +148,9 @@ void CSubsurface::onNewSubsurface(SP pSubsurface) { WP PSUBSURFACE; if (!m_pWindowParent.expired()) - PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pWindowParent.lock())); + PSUBSURFACE = m_vChildren.emplace_back(CSubsurface::create(pSubsurface, m_pWindowParent.lock())); else if (m_pPopupParent) - PSUBSURFACE = m_vChildren.emplace_back(makeUnique(pSubsurface, m_pPopupParent)); + PSUBSURFACE = m_vChildren.emplace_back(CSubsurface::create(pSubsurface, m_pPopupParent)); PSUBSURFACE->m_pSelf = PSUBSURFACE; diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp index 41958671..2983c7c1 100644 --- a/src/desktop/Subsurface.hpp +++ b/src/desktop/Subsurface.hpp @@ -10,12 +10,12 @@ class CWLSubsurfaceResource; class CSubsurface { public: // root dummy nodes - CSubsurface(PHLWINDOW pOwner); - CSubsurface(WP pOwner); + static UP create(PHLWINDOW pOwner); + static UP create(WP pOwner); // real nodes - CSubsurface(SP pSubsurface, PHLWINDOW pOwner); - CSubsurface(SP pSubsurface, WP pOwner); + static UP create(SP pSubsurface, PHLWINDOW pOwner); + static UP create(SP pSubsurface, WP pOwner); ~CSubsurface() = default; @@ -37,6 +37,8 @@ class CSubsurface { WP m_pSelf; private: + CSubsurface() = default; + struct { CHyprSignalListener destroySubsurface; CHyprSignalListener commitSubsurface; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 0f6bac99..6e580e49 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -571,10 +571,8 @@ void CWindow::onMap() { if (m_bIsX11) return; - m_pSubsurfaceHead = makeUnique(m_pSelf.lock()); - m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead; - m_pPopupHead = makeUnique(m_pSelf.lock()); - m_pPopupHead->m_pSelf = m_pPopupHead; + m_pSubsurfaceHead = CSubsurface::create(m_pSelf.lock()); + m_pPopupHead = CPopup::create(m_pSelf.lock()); } void CWindow::onBorderAngleAnimEnd(WP pav) { diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index ce2f8eb2..3573d7ab 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -298,7 +298,7 @@ class CWindow { // desktop components UP m_pSubsurfaceHead; - UP m_pPopupHead; + SP m_pPopupHead; // Animated border CGradientValueData m_cRealBorderColor = {0}; From 88adae73ba3b57490fdef1041f58fcc6a15a54c8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 1 Feb 2025 15:31:31 +0000 Subject: [PATCH 0220/1444] pass: add input region debug --- src/render/pass/Pass.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index 5068cbbc..60c1bc30 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -8,6 +8,7 @@ #include "../../managers/eventLoop/EventLoopManager.hpp" #include "../../render/Renderer.hpp" #include "../../Compositor.hpp" +#include "../../protocols/core/Compositor.hpp" bool CRenderPass::empty() const { return false; @@ -242,6 +243,22 @@ void CRenderPass::renderDebugData() { if (g_pCompositor->m_pLastWindow) renderHLSurface(debugData.lastWindowText, g_pCompositor->m_pLastWindow->m_pWLSurface->resource(), Colors::LIGHT_BLUE.modifyA(0.1F)); + if (g_pSeatManager->state.pointerFocus) { + if (g_pSeatManager->state.pointerFocus->current.input.intersect(CBox{{}, g_pSeatManager->state.pointerFocus->current.size}).getExtents().size() != + g_pSeatManager->state.pointerFocus->current.size) { + auto hlSurface = CWLSurface::fromResource(g_pSeatManager->state.pointerFocus.lock()); + if (hlSurface) { + auto BOX = hlSurface->getSurfaceBoxGlobal(); + if (BOX) { + auto region = g_pSeatManager->state.pointerFocus->current.input.copy() + .scale(g_pHyprOpenGL->m_RenderData.pMonitor->scale) + .translate(BOX->pos() - g_pHyprOpenGL->m_RenderData.pMonitor->vecPosition); + g_pHyprOpenGL->renderRectWithDamage(box, CHyprColor{0.8F, 0.8F, 0.2F, 0.4F}, region); + } + } + } + } + const auto DISCARDED_ELEMENTS = std::count_if(m_vPassElements.begin(), m_vPassElements.end(), [](const auto& e) { return e->discard; }); auto tex = g_pHyprOpenGL->renderText(std::format("occlusion layers: {}\npass elements: {} ({} discarded)\nviewport: {:X0}", occludedRegions.size(), m_vPassElements.size(), DISCARDED_ELEMENTS, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize), From e380b6ed66aceeae8fde84b4baed0d91550e9f4c Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 1 Feb 2025 15:49:10 +0000 Subject: [PATCH 0221/1444] popup: take xdg geometry into account in input calcs fixes #9023 --- src/desktop/Popup.cpp | 12 +++++++----- src/protocols/core/Compositor.cpp | 4 +--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 20ff49d7..e66cebcd 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -339,22 +339,24 @@ void CPopup::breadthfirst(std::function, void*)> fn, void* data) WP CPopup::at(const Vector2D& globalCoords, bool allowsInput) { std::vector> popups; - breadthfirst([](WP popup, void* data) { ((std::vector>*)data)->push_back(popup); }, &popups); + breadthfirst([&popups](WP popup, void* data) { popups.push_back(popup); }, &popups); for (auto const& p : popups | std::views::reverse) { if (!p->m_pResource || !p->m_bMapped) continue; if (!allowsInput) { - const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{}; - const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size(); + const Vector2D offset = + p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{}; + const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size(); const auto BOX = CBox{p->coordsGlobal() + offset, size}; if (BOX.containsPoint(globalCoords)) return p; } else { - const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{}; - const auto REGION = + const Vector2D offset = + p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{}; + const auto REGION = CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset); if (REGION.containsPoint(globalCoords)) return p; diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 93683993..92c3c425 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -308,9 +308,7 @@ void CWLSurfaceResource::breadthfirst(std::function, std::pair, Vector2D> CWLSurfaceResource::at(const Vector2D& localCoords, bool allowsInput) { std::vector, Vector2D>> surfs; - breadthfirst([](SP surf, const Vector2D& offset, - void* data) { ((std::vector, Vector2D>>*)data)->emplace_back(std::make_pair<>(surf, offset)); }, - &surfs); + breadthfirst([&surfs](SP surf, const Vector2D& offset, void* data) { surfs.emplace_back(std::make_pair<>(surf, offset)); }, &surfs); for (auto const& [surf, pos] : surfs | std::views::reverse) { if (!allowsInput) { From 64fefa3749868e6170b6275963c6528456a7d9f2 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 1 Feb 2025 19:10:19 +0000 Subject: [PATCH 0222/1444] desktop: move popups to UPs and fix missing subsurface resource fixes #9283 --- src/desktop/LayerSurface.hpp | 2 +- src/desktop/Popup.cpp | 15 ++++++++------- src/desktop/Popup.hpp | 8 ++++---- src/desktop/Subsurface.cpp | 2 ++ src/desktop/Window.hpp | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index f2be7459..ab259733 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -59,7 +59,7 @@ class CLayerSurface { CBox geometry = {0, 0, 0, 0}; Vector2D position; std::string szNamespace = ""; - SP popupHead; + UP popupHead; void onDestroy(); void onMap(); diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index e66cebcd..4accb58f 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -12,24 +12,24 @@ #include "../render/OpenGL.hpp" #include -SP CPopup::create(PHLWINDOW pOwner) { - auto popup = SP(new CPopup()); +UP CPopup::create(PHLWINDOW pOwner) { + auto popup = UP(new CPopup()); popup->m_pWindowOwner = pOwner; popup->m_pSelf = popup; popup->initAllSignals(); return popup; } -SP CPopup::create(PHLLS pOwner) { - auto popup = SP(new CPopup()); +UP CPopup::create(PHLLS pOwner) { + auto popup = UP(new CPopup()); popup->m_pLayerOwner = pOwner; popup->m_pSelf = popup; popup->initAllSignals(); return popup; } -SP CPopup::create(SP resource, WP pOwner) { - auto popup = SP(new CPopup()); +UP CPopup::create(SP resource, WP pOwner) { + auto popup = UP(new CPopup()); popup->m_pResource = resource; popup->m_pWindowOwner = pOwner->m_pWindowOwner; popup->m_pLayerOwner = pOwner->m_pLayerOwner; @@ -282,7 +282,8 @@ void CPopup::recheckTree() { } void CPopup::recheckChildrenRecursive() { - auto cpy = m_vChildren; + std::vector> cpy; + std::ranges::for_each(m_vChildren, [&cpy](const auto& el) { cpy.emplace_back(el); }); for (auto const& c : cpy) { c->onCommit(true); c->recheckChildrenRecursive(); diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index a64af7eb..0bca436c 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -10,11 +10,11 @@ class CXDGPopupResource; class CPopup { public: // dummy head nodes - static SP create(PHLWINDOW pOwner); - static SP create(PHLLS pOwner); + static UP create(PHLWINDOW pOwner); + static UP create(PHLLS pOwner); // real nodes - static SP create(SP popup, WP pOwner); + static UP create(SP popup, WP pOwner); ~CPopup(); @@ -64,7 +64,7 @@ class CPopup { bool m_bInert = false; // - std::vector> m_vChildren; + std::vector> m_vChildren; UP m_pSubsurfaceHead; struct { diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index 33ee3553..db106a09 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -29,6 +29,7 @@ UP CSubsurface::create(WP pOwner) { UP CSubsurface::create(SP pSubsurface, PHLWINDOW pOwner) { auto subsurface = UP(new CSubsurface()); subsurface->m_pWindowParent = pOwner; + subsurface->m_pSubsurface = pSubsurface; subsurface->m_pSelf = subsurface; subsurface->m_pWLSurface = CWLSurface::create(); subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get()); @@ -40,6 +41,7 @@ UP CSubsurface::create(SP pSubsurface, PHLWI UP CSubsurface::create(SP pSubsurface, WP pOwner) { auto subsurface = UP(new CSubsurface()); subsurface->m_pPopupParent = pOwner; + subsurface->m_pSubsurface = pSubsurface; subsurface->m_pSelf = subsurface; subsurface->m_pWLSurface = CWLSurface::create(); subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get()); diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 3573d7ab..ce2f8eb2 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -298,7 +298,7 @@ class CWindow { // desktop components UP m_pSubsurfaceHead; - SP m_pPopupHead; + UP m_pPopupHead; // Animated border CGradientValueData m_cRealBorderColor = {0}; From 97a24ec6f3abd2b2ce4c2e00627679a2713848dd Mon Sep 17 00:00:00 2001 From: micha4w Date: Sun, 2 Feb 2025 12:39:32 +0100 Subject: [PATCH 0223/1444] Nix: change meson buildtype from debugoptimized to debug --- nix/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/default.nix b/nix/default.nix index a4ddc63b..6a703713 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -155,7 +155,7 @@ in mesonBuildType = if debug - then "debugoptimized" + then "debug" else "release"; mesonFlags = flatten [ From 373108102c85f9568a8f28b7a85c5500634ca9a4 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 2 Feb 2025 09:31:04 -0800 Subject: [PATCH 0224/1444] protocols: implement hyprland-ctm-control rev 2 (#9267) * protocols: implement hyprland-ctm-control v2 * bump h-p and nix --- CMakeLists.txt | 2 +- flake.lock | 24 ++++++++++++------------ protocols/meson.build | 2 +- src/managers/ProtocolManager.cpp | 2 +- src/protocols/CTMControl.cpp | 22 +++++++++++++++++++++- src/protocols/CTMControl.hpp | 5 ++++- subprojects/hyprland-protocols | 2 +- 7 files changed, 41 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c286831..34e9a8ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -304,7 +304,7 @@ endfunction() target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads) -pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.0) +pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.2) if(hyprland_protocols_dep_FOUND) pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir) message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}") diff --git a/flake.lock b/flake.lock index dfdd8c5b..7637a2c7 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1738183445, - "narHash": "sha256-C1He3N1SA8D2u+TSlldbA9wiYwDvXI4GxX3zKaeD7qU=", + "lastModified": 1738456976, + "narHash": "sha256-cufyHbOMnSt9V4w4OVSzNcpJ+8DwzRZRJaca2Q89KVI=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "48a000cf35dd10bfeb231152735aebbe875f4b74", + "rev": "257b2050790ab3b1eb389e0f8bdc400eb9510139", "type": "github" }, "original": { @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1738018829, - "narHash": "sha256-5Ol5iahMlELx3lWuChyZsqqLk6sP6aqaJCJFw92OZGo=", + "lastModified": 1738437059, + "narHash": "sha256-J+8ecqaP3zD9GHeN8Y4hUapoELSoggp0IZI8laTFt/0=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "12cd7034e441a5ebfdef1a090c0788413b4a635b", + "rev": "5ac80e3686a4dfa55d2bd15c81a266b89594a295", "type": "github" }, "original": { @@ -128,11 +128,11 @@ ] }, "locked": { - "lastModified": 1737556638, - "narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=", + "lastModified": 1738422629, + "narHash": "sha256-5v+bv75wJWvahyM2xcMTSNNxmV8a7hb01Eey5zYnBJw=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5", + "rev": "755aef8dab49d0fc4663c715fa4ad221b2aedaed", "type": "github" }, "original": { @@ -276,11 +276,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1737885589, - "narHash": "sha256-Zf0hSrtzaM1DEz8//+Xs51k/wdSajticVrATqDrfQjg=", + "lastModified": 1738410390, + "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "852ff1d9e153d8875a83602e03fdef8a63f0ecf8", + "rev": "3a228057f5b619feb3186e986dbe76278d707b6e", "type": "github" }, "original": { diff --git a/protocols/meson.build b/protocols/meson.build index aa20940d..6ed1b11a 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -7,7 +7,7 @@ wayland_protos = dependency( hyprland_protos = dependency( 'hyprland-protocols', - version: '>=0.6', + version: '>=0.6.2', fallback: 'hyprland-protocols', ) diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index d3270fe2..62736ae5 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -167,7 +167,7 @@ CProtocolManager::CProtocolManager() { PROTO::xdgDialog = makeUnique(&xdg_dialog_v1_interface, 1, "XDGDialog"); PROTO::singlePixel = makeUnique(&wp_single_pixel_buffer_manager_v1_interface, 1, "SinglePixel"); PROTO::securityContext = makeUnique(&wp_security_context_manager_v1_interface, 1, "SecurityContext"); - PROTO::ctm = makeUnique(&hyprland_ctm_control_manager_v1_interface, 1, "CTMControl"); + PROTO::ctm = makeUnique(&hyprland_ctm_control_manager_v1_interface, 2, "CTMControl"); PROTO::hyprlandSurface = makeUnique(&hyprland_surface_manager_v1_interface, 2, "HyprlandSurface"); if (*PENABLEXXCM) { diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index 5560271f..322f95e2 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -15,6 +15,9 @@ CHyprlandCTMControlResource::CHyprlandCTMControlResource(SPsetSetCtmForOutput([this](CHyprlandCtmControlManagerV1* r, wl_resource* output, wl_fixed_t mat0, wl_fixed_t mat1, wl_fixed_t mat2, wl_fixed_t mat3, wl_fixed_t mat4, wl_fixed_t mat5, wl_fixed_t mat6, wl_fixed_t mat7, wl_fixed_t mat8) { + if (blocked) + return; + const auto OUTPUTRESOURCE = CWLOutputResource::fromResource(output); if UNLIKELY (!OUTPUTRESOURCE) @@ -41,6 +44,9 @@ CHyprlandCTMControlResource::CHyprlandCTMControlResource(SPsetCommit([this](CHyprlandCtmControlManagerV1* r) { + if (blocked) + return; + LOGM(LOG, "Committing ctms to outputs"); for (auto& m : g_pCompositor->m_vMonitors) { @@ -54,7 +60,17 @@ CHyprlandCTMControlResource::CHyprlandCTMControlResource(SPversion() >= 2) + resource->sendBlocked(); +} + CHyprlandCTMControlResource::~CHyprlandCTMControlResource() { + if (blocked) + return; + for (auto& m : g_pCompositor->m_vMonitors) { PROTO::ctm->setCTM(m, Mat3x3::identity()); } @@ -69,7 +85,6 @@ CHyprlandCTMControlProtocol::CHyprlandCTMControlProtocol(const wl_interface* ifa } void CHyprlandCTMControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); if UNLIKELY (!RESOURCE->good()) { @@ -78,6 +93,11 @@ void CHyprlandCTMControlProtocol::bindManager(wl_client* client, void* data, uin return; } + if (m_pManager) + RESOURCE->block(); + else + m_pManager = RESOURCE; + LOGM(LOG, "New CTM Manager at 0x{:x}", (uintptr_t)RESOURCE.get()); } diff --git a/src/protocols/CTMControl.hpp b/src/protocols/CTMControl.hpp index 2c168acd..eb54a3aa 100644 --- a/src/protocols/CTMControl.hpp +++ b/src/protocols/CTMControl.hpp @@ -16,11 +16,13 @@ class CHyprlandCTMControlResource { ~CHyprlandCTMControlResource(); bool good(); + void block(); private: SP resource; std::unordered_map ctms; + bool blocked = false; }; class CHyprlandCTMControlProtocol : public IWaylandProtocol { @@ -37,6 +39,7 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { // std::vector> m_vManagers; + WP m_pManager; // struct SCTMData { @@ -51,4 +54,4 @@ class CHyprlandCTMControlProtocol : public IWaylandProtocol { namespace PROTO { inline UP ctm; -}; \ No newline at end of file +}; diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index 4c75dd5c..755aef8d 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit 4c75dd5c015c8a0e5a34c6d02a018a650f57feb5 +Subproject commit 755aef8dab49d0fc4663c715fa4ad221b2aedaed From 70d94fec134c4b91916812901310e7765acf8405 Mon Sep 17 00:00:00 2001 From: Alexander <51529891+Truenya@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:34:26 +0300 Subject: [PATCH 0225/1444] refactor: clang-tidy in compositor (#9241) Co-authored-by: Alexandr Krylov --- src/Compositor.cpp | 90 ++++++++++++++------------------- src/Compositor.hpp | 5 +- src/macros.hpp | 3 +- src/managers/KeybindManager.cpp | 2 - 4 files changed, 40 insertions(+), 60 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 1daccbfd..6a241472 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1,3 +1,4 @@ +#include #include #include "Compositor.hpp" @@ -21,14 +22,12 @@ #include #include #include -#include #include #include "debug/HyprCtl.hpp" #include "debug/CrashReporter.hpp" #ifdef USES_SYSTEMD #include // for SdNotify #endif -#include "helpers/varlist/VarList.hpp" #include "helpers/fs/FsUtils.hpp" #include "protocols/FractionalScale.hpp" #include "protocols/PointerConstraints.hpp" @@ -264,7 +263,6 @@ static bool filterGlobals(const wl_client* client, const wl_global* global, void // void CCompositor::initServer(std::string socketName, int socketFd) { - if (m_bOnlyConfigVerification) { g_pHookSystem = makeUnique(); g_pKeybindManager = makeUnique(); @@ -500,7 +498,7 @@ void CCompositor::cleanEnvironment() { "dbus-update-activation-environment 2>/dev/null && " #endif "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS"; - g_pKeybindManager->spawn(CMD); + CKeybindManager::spawn(CMD); } } @@ -738,7 +736,7 @@ void CCompositor::startCompositor() { "dbus-update-activation-environment 2>/dev/null && " #endif "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS"; - g_pKeybindManager->spawn(CMD); + CKeybindManager::spawn(CMD); } Debug::log(LOG, "Running on WAYLAND_DISPLAY: {}", m_szWLDisplaySocket); @@ -839,12 +837,7 @@ void CCompositor::removeWindowFromVectorSafe(PHLWINDOW pWindow) { } bool CCompositor::monitorExists(PHLMONITOR pMonitor) { - for (auto const& m : m_vRealMonitors) { - if (m == pMonitor) - return true; - } - - return false; + return std::ranges::any_of(m_vRealMonitors, [&](const PHLMONITOR& m) { return m == pMonitor; }); } PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t properties, PHLWINDOW pIgnoreWindow) { @@ -1175,8 +1168,8 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface pWindow->m_bIsUrgent = false; // Send an event - g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", pWindow->m_szClass + "," + pWindow->m_szTitle}); - g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", std::format("{:x}", (uintptr_t)pWindow.get())}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = pWindow->m_szClass + "," + pWindow->m_szTitle}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = std::format("{:x}", (uintptr_t)pWindow.get())}); EMIT_HOOK_EVENT("activeWindow", pWindow); @@ -1217,8 +1210,8 @@ void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindo if (!pSurface) { g_pSeatManager->setKeyboardFocus(nullptr); - g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused - g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindow", .data = ","}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "activewindowv2", .data = ""}); EMIT_HOOK_EVENT("keyboardFocus", (SP)nullptr); m_pLastFocus.reset(); return; @@ -1395,7 +1388,7 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) { toMove.insert(toMove.begin(), pw); for (auto const& w : m_vWindows) { - if (w->m_bIsMapped && !w->isHidden() && w->m_bIsX11 && w->x11TransientFor() == pw && w != pw && std::find(toMove.begin(), toMove.end(), w) == toMove.end()) { + if (w->m_bIsMapped && !w->isHidden() && w->m_bIsX11 && w->x11TransientFor() == pw && w != pw && std::ranges::find(toMove, w) == toMove.end()) { x11Stack(w, top, x11Stack); } } @@ -1454,7 +1447,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) { if (ls->fadingOut && ls->readyToDelete && ls->isFadedOut()) { for (auto const& m : m_vMonitors) { for (auto& lsl : m->m_aLayerSurfaceLayers) { - if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](auto& other) { return other == ls; }) != lsl.end()) { + if (!lsl.empty() && std::ranges::find_if(lsl, [&](auto& other) { return other == ls; }) != lsl.end()) { std::erase_if(lsl, [&](auto& other) { return other == ls || !other; }); } } @@ -1477,7 +1470,7 @@ void CCompositor::cleanupFadingOut(const MONITORID& monid) { } void CCompositor::addToFadingOutSafe(PHLLS pLS) { - const auto FOUND = std::find_if(m_vSurfacesFadingOut.begin(), m_vSurfacesFadingOut.end(), [&](auto& other) { return other.lock() == pLS; }); + const auto FOUND = std::ranges::find_if(m_vSurfacesFadingOut, [&](auto& other) { return other.lock() == pLS; }); if (FOUND != m_vSurfacesFadingOut.end()) return; // if it's already added, don't add it. @@ -1490,7 +1483,7 @@ void CCompositor::removeFromFadingOutSafe(PHLLS ls) { } void CCompositor::addToFadingOutSafe(PHLWINDOW pWindow) { - const auto FOUND = std::find_if(m_vWindowsFadingOut.begin(), m_vWindowsFadingOut.end(), [&](PHLWINDOWREF& other) { return other.lock() == pWindow; }); + const auto FOUND = std::ranges::find_if(m_vWindowsFadingOut, [&](PHLWINDOWREF& other) { return other.lock() == pWindow; }); if (FOUND != m_vWindowsFadingOut.end()) return; // if it's already added, don't add it. @@ -1609,7 +1602,7 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks // auto vectorAngles = [](const Vector2D& a, const Vector2D& b) -> double { - double dot = a.x * b.x + a.y * b.y; + double dot = (a.x * b.x) + (a.y * b.y); double ang = std::acos(dot / (a.size() * b.size())); return ang; }; @@ -1728,7 +1721,7 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const PHLMONITOR const auto XY1 = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; const auto XY2 = PMONITOR->vecPosition + PMONITOR->vecSize - PMONITOR->vecReservedBottomRight; - return !VECINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y); + return VECNOTINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y); } PHLMONITOR CCompositor::getMonitorInDirection(const char& dir) { @@ -1902,7 +1895,7 @@ void CCompositor::updateWindowAnimatedDecorationValues(PHLWINDOW pWindow) { MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { // reuse ID if it's already in the map, and the monitor with that ID is not being used by another monitor - if (m_mMonitorIDMap.contains(name) && !std::any_of(m_vRealMonitors.begin(), m_vRealMonitors.end(), [&](auto m) { return m->ID == m_mMonitorIDMap[name]; })) + if (m_mMonitorIDMap.contains(name) && !std::ranges::any_of(m_vRealMonitors, [&](auto m) { return m->ID == m_mMonitorIDMap[name]; })) return m_mMonitorIDMap[name]; // otherwise, find minimum available ID that is not in the map @@ -1912,7 +1905,7 @@ MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { } MONITORID nextID = 0; - while (usedIDs.count(nextID) > 0) { + while (usedIDs.contains(nextID)) { nextID++; } m_mMonitorIDMap[name] = nextID; @@ -1920,7 +1913,6 @@ MONITORID CCompositor::getNextAvailableMonitorID(std::string const& name) { } void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitorB) { - const auto PWORKSPACEA = pMonitorA->activeWorkspace; const auto PWORKSPACEB = pMonitorB->activeWorkspace; @@ -1992,17 +1984,18 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING))); const auto PNEWWORKSPACE = pMonitorA->ID == g_pCompositor->m_pLastMonitor->ID ? PWORKSPACEB : PWORKSPACEA; - g_pEventManager->postEvent(SHyprIPCEvent{"workspace", PNEWWORKSPACE->m_szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"workspacev2", std::format("{},{}", PNEWWORKSPACE->m_iID, PNEWWORKSPACE->m_szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspace", .data = PNEWWORKSPACE->m_szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "workspacev2", .data = std::format("{},{}", PNEWWORKSPACE->m_iID, PNEWWORKSPACE->m_szName)}); EMIT_HOOK_EVENT("workspace", PNEWWORKSPACE); } // event - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEA->m_iID, PWORKSPACEA->m_szName, pMonitorB->szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspace", .data = PWORKSPACEA->m_szName + "," + pMonitorB->szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspacev2", .data = std::format("{},{},{}", PWORKSPACEA->m_iID, PWORKSPACEA->m_szName, pMonitorB->szName)}); EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEA, pMonitorB})); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEB->m_iID, PWORKSPACEB->m_szName, pMonitorA->szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspace", .data = PWORKSPACEB->m_szName + "," + pMonitorA->szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspacev2", .data = std::format("{},{},{}", PWORKSPACEB->m_iID, PWORKSPACEB->m_szName, pMonitorA->szName)}); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEB, pMonitorA})); } @@ -2081,7 +2074,6 @@ PHLMONITOR CCompositor::getMonitorFromString(const std::string& name) { } void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMonitor, bool noWarpCursor) { - if (!pWorkspace || !pMonitor) return; @@ -2188,8 +2180,8 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo updateSuspendedStates(); // event - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName}); - g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", pWorkspace->m_iID, pWorkspace->m_szName, pMonitor->szName)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspace", .data = pWorkspace->m_szName + "," + pMonitor->szName}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "moveworkspacev2", .data = std::format("{},{},{}", pWorkspace->m_iID, pWorkspace->m_szName, pMonitor->szName)}); EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); } @@ -2200,12 +2192,8 @@ bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) { for (auto const& w : m_vWorkspaces) { if (w->m_bIsSpecialWorkspace) continue; - - if (w->m_iID < lowestID) - lowestID = w->m_iID; - - if (w->m_iID > highestID) - highestID = w->m_iID; + lowestID = std::min(w->m_iID, lowestID); + highestID = std::max(w->m_iID, highestID); } return std::clamp(id, lowestID, highestID) != id; @@ -2281,7 +2269,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->isFullscreen()) setWindowFullscreenInternal(PWORKSPACE->getFullscreenWindow(), FSMODE_NONE); - const bool CHANGEINTERNAL = !(PWINDOW->m_bPinned || CURRENT_EFFECTIVE_MODE == EFFECTIVE_MODE); + const bool CHANGEINTERNAL = !PWINDOW->m_bPinned && CURRENT_EFFECTIVE_MODE != EFFECTIVE_MODE; if (*PALLOWPINFULLSCREEN && PWINDOW->m_bPinFullscreened && PWINDOW->isFullscreen() && !PWINDOW->m_bPinned && state.internal == FSMODE_NONE) { PWINDOW->m_bPinned = true; @@ -2308,7 +2296,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS PWORKSPACE->m_efFullscreenMode = EFFECTIVE_MODE; PWORKSPACE->m_bHasFullscreenWindow = EFFECTIVE_MODE != FSMODE_NONE; - g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)EFFECTIVE_MODE != FSMODE_NONE)}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "fullscreen", .data = std::to_string((int)EFFECTIVE_MODE != FSMODE_NONE)}); EMIT_HOOK_EVENT("fullscreen", PWINDOW); PWINDOW->updateDynamicRules(); @@ -2575,8 +2563,8 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con X = xIsPercent ? std::stof(x) * 0.01 * PMONITOR->vecSize.x : std::stoi(x); Y = yIsPercent ? std::stof(y) * 0.01 * PMONITOR->vecSize.y : std::stoi(y); } else { - X = xIsPercent ? std::stof(x) * 0.01 * relativeTo.x + relativeTo.x : std::stoi(x) + relativeTo.x; - Y = yIsPercent ? std::stof(y) * 0.01 * relativeTo.y + relativeTo.y : std::stoi(y) + relativeTo.y; + X = xIsPercent ? (std::stof(x) * 0.01 * relativeTo.x) + relativeTo.x : std::stoi(x) + relativeTo.x; + Y = yIsPercent ? (std::stof(y) * 0.01 * relativeTo.y) + relativeTo.y : std::stoi(y) + relativeTo.y; } return Vector2D(X, Y); @@ -2613,8 +2601,8 @@ void CCompositor::setActiveMonitor(PHLMONITOR pMonitor) { const auto WORKSPACE_ID = PWORKSPACE ? std::to_string(PWORKSPACE->m_iID) : std::to_string(WORKSPACE_INVALID); const auto WORKSPACE_NAME = PWORKSPACE ? PWORKSPACE->m_szName : "?"; - g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + WORKSPACE_NAME}); - g_pEventManager->postEvent(SHyprIPCEvent{"focusedmonv2", pMonitor->szName + "," + WORKSPACE_ID}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmon", .data = pMonitor->szName + "," + WORKSPACE_NAME}); + g_pEventManager->postEvent(SHyprIPCEvent{.event = "focusedmonv2", .data = pMonitor->szName + "," + WORKSPACE_ID}); EMIT_HOOK_EVENT("focusedMon", pMonitor); m_pLastMonitor = pMonitor->self; @@ -2804,14 +2792,10 @@ void CCompositor::arrangeMonitors() { // Finds the max and min values of explicitely placed monitors. for (auto const& m : arranged) { - if (m->vecPosition.x + m->vecSize.x > maxXOffsetRight) - maxXOffsetRight = m->vecPosition.x + m->vecSize.x; - if (m->vecPosition.x < maxXOffsetLeft) - maxXOffsetLeft = m->vecPosition.x; - if (m->vecPosition.y + m->vecSize.y > maxYOffsetDown) - maxYOffsetDown = m->vecPosition.y + m->vecSize.y; - if (m->vecPosition.y < maxYOffsetUp) - maxYOffsetUp = m->vecPosition.y; + maxXOffsetRight = std::max(m->vecPosition.x + m->vecSize.x, maxXOffsetRight); + maxXOffsetLeft = std::min(m->vecPosition.x, maxXOffsetLeft); + maxYOffsetDown = std::max(m->vecPosition.y + m->vecSize.y, maxYOffsetDown); + maxYOffsetUp = std::min(m->vecPosition.y, maxYOffsetUp); } }; diff --git a/src/Compositor.hpp b/src/Compositor.hpp index e55d7e1e..787ead08 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -1,15 +1,12 @@ #pragma once -#include #include -#include "defines.hpp" #include "managers/XWaylandManager.hpp" #include "managers/KeybindManager.hpp" #include "managers/SessionLockManager.hpp" #include "desktop/Window.hpp" #include "protocols/types/ColorManagement.hpp" -#include "helpers/memory/Memory.hpp" #include #include @@ -170,7 +167,7 @@ class CCompositor { uint64_t m_iHyprlandPID = 0; wl_event_source* m_critSigSource = nullptr; - rlimit m_sOriginalNofile = {0}; + rlimit m_sOriginalNofile = {}; }; inline UP g_pCompositor; diff --git a/src/macros.hpp b/src/macros.hpp index 0a3be8bc..a5176675 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -38,7 +38,8 @@ #define DYNLISTENER(name) CHyprWLListener hyprListener_##name #define DYNMULTILISTENER(name) wl_listener listen_##name -#define VECINRECT(vec, x1, y1, x2, y2) ((vec).x >= (x1) && (vec).x < (x2) && (vec).y >= (y1) && (vec).y < (y2)) +#define VECINRECT(vec, x1, y1, x2, y2) ((vec).x >= (x1) && (vec).x < (x2) && (vec).y >= (y1) && (vec).y < (y2)) +#define VECNOTINRECT(vec, x1, y1, x2, y2) ((vec).x < (x1) || (vec).x >= (x2) || (vec).y < (y1) || (vec).y >= (y2)) #define DELTALESSTHAN(a, b, delta) (abs((a) - (b)) < (delta)) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 247550ae..bc5d36c8 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -12,8 +12,6 @@ #include "TokenManager.hpp" #include "eventLoop/EventLoopManager.hpp" #include "debug/Log.hpp" -#include "helpers/varlist/VarList.hpp" -#include "../helpers/signal/Signal.hpp" #include "../managers/HookSystemManager.hpp" #include "../managers/input/InputManager.hpp" #include "../managers/LayoutManager.hpp" From 31431a92714ab7f53c25d2ececb26c5b7264b7e3 Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:25:29 +0300 Subject: [PATCH 0226/1444] protocols: Support content-type-v1 proto (#9226) --- CMakeLists.txt | 9 ++ meson.build | 4 + protocols/meson.build | 1 + src/Compositor.cpp | 3 +- src/config/ConfigDescriptions.hpp | 13 +-- src/config/ConfigManager.cpp | 24 ++++- src/desktop/Window.cpp | 15 +++ src/desktop/Window.hpp | 159 ++++++++++++++-------------- src/desktop/WindowRule.cpp | 7 +- src/desktop/WindowRule.hpp | 2 + src/events/Windows.cpp | 9 +- src/helpers/Monitor.cpp | 5 +- src/macros.hpp | 1 + src/managers/ProtocolManager.cpp | 3 + src/protocols/ContentType.cpp | 95 +++++++++++++++++ src/protocols/ContentType.hpp | 59 +++++++++++ src/protocols/core/Compositor.hpp | 2 + src/protocols/types/ContentType.cpp | 37 +++++++ src/protocols/types/ContentType.hpp | 18 ++++ src/render/Renderer.cpp | 14 ++- 20 files changed, 386 insertions(+), 94 deletions(-) create mode 100644 src/protocols/ContentType.cpp create mode 100644 src/protocols/ContentType.hpp create mode 100644 src/protocols/types/ContentType.cpp create mode 100644 src/protocols/types/ContentType.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 34e9a8ed..a98f697d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,15 @@ pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.0) pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1) +string(REPLACE "." ";" AQ_VERSION_LIST ${aquamarine_dep_VERSION}) +list(GET AQ_VERSION_LIST 0 AQ_VERSION_MAJOR) +list(GET AQ_VERSION_LIST 1 AQ_VERSION_MINOR) +list(GET AQ_VERSION_LIST 2 AQ_VERSION_PATCH) + add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}") +add_compile_definitions(AQUAMARINE_VERSION_MAJOR=${AQ_VERSION_MAJOR}) +add_compile_definitions(AQUAMARINE_VERSION_MINOR=${AQ_VERSION_MINOR}) +add_compile_definitions(AQUAMARINE_VERSION_PATCH=${AQ_VERSION_PATCH}) add_compile_definitions(HYPRLANG_VERSION="${hyprlang_dep_VERSION}") add_compile_definitions(HYPRUTILS_VERSION="${hyprutils_dep_VERSION}") add_compile_definitions(HYPRCURSOR_VERSION="${hyprcursor_dep_VERSION}") @@ -368,6 +376,7 @@ protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false) protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false) protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false) protocolnew("staging/security-context" "security-context-v1" false) +protocolnew("staging/content-type" "content-type-v1" false) protocolwayland() diff --git a/meson.build b/meson.build index ae6e3940..a367b166 100644 --- a/meson.build +++ b/meson.build @@ -36,7 +36,11 @@ hyprcursor = dependency('hyprcursor', version: '>=0.1.7') hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1') hyprlang = dependency('hyprlang', version: '>= 0.3.2') hyprutils = dependency('hyprutils', version: '>= 0.2.3') +aquamarine_version_list = aquamarine.version().split('.') add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp') +add_project_arguments(['-DAQUAMARINE_VERSION_MAJOR=@0@'.format(aquamarine_version_list.get(0))], language: 'cpp') +add_project_arguments(['-DAQUAMARINE_VERSION_MINOR=@0@'.format(aquamarine_version_list.get(1))], language: 'cpp') +add_project_arguments(['-DAQUAMARINE_VERSION_PATCH=@0@'.format(aquamarine_version_list.get(2))], language: 'cpp') add_project_arguments(['-DHYPRCURSOR_VERSION="@0@"'.format(hyprcursor.version())], language: 'cpp') add_project_arguments(['-DHYPRGRAPHICS_VERSION="@0@"'.format(hyprgraphics.version())], language: 'cpp') add_project_arguments(['-DHYPRLANG_VERSION="@0@"'.format(hyprlang.version())], language: 'cpp') diff --git a/protocols/meson.build b/protocols/meson.build index 6ed1b11a..7c57470b 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -70,6 +70,7 @@ protocols = [ wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml', wayland_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml', wayland_protocol_dir / 'staging/security-context/security-context-v1.xml', + wayland_protocol_dir / 'staging/content-type/content-type-v1.xml', ] wl_protocols = [] diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 6a241472..0aa0f13d 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -72,6 +72,7 @@ using namespace Hyprutils::String; using namespace Aquamarine; +using enum NContentType::eContentType; static int handleCritSignal(int signo, void* data) { Debug::log(LOG, "Hyprland received signal {}", signo); @@ -2323,7 +2324,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS // send a scanout tranche if we are entering fullscreen, and send a regular one if we aren't. // ignore if DS is disabled. - if (*PDIRECTSCANOUT) + if (*PDIRECTSCANOUT == 1 || (*PDIRECTSCANOUT == 2 && PWINDOW->getContentType() == CONTENT_TYPE_GAME)) g_pHyprRenderer->setSurfaceScanoutMode(PWINDOW->m_pWLSurface->resource(), EFFECTIVE_MODE != FSMODE_NONE ? PMONITOR->self.lock() : nullptr); g_pConfigManager->ensureVRR(PMONITOR); diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 2fa86817..28cd29c4 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1314,9 +1314,9 @@ inline static const std::vector CONFIG_OPTIONS = { SConfigOptionDescription{ .value = "render:direct_scanout", .description = "Enables direct scanout. Direct scanout attempts to reduce lag when there is only one fullscreen application on a screen (e.g. game). It is also " - "recommended to set this to false if the fullscreen application shows graphical glitches.", - .type = CONFIG_OPTION_BOOL, - .data = SConfigOptionDescription::SBoolData{false}, + "recommended to set this to false if the fullscreen application shows graphical glitches. 0 - off, 1 - on, 2 - auto (on with content type 'game')", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{.value = 0, .min = 0, .max = 2}, }, SConfigOptionDescription{ .value = "render:expand_undersized_textures", @@ -1362,9 +1362,10 @@ inline static const std::vector CONFIG_OPTIONS = { }, SConfigOptionDescription{ .value = "cursor:no_break_fs_vrr", - .description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (requires no_hardware_cursors = true)", - .type = CONFIG_OPTION_BOOL, - .data = SConfigOptionDescription::SBoolData{false}, + .description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (may require no_hardware_cursors = true) " + "0 - off, 1 - on, 2 - auto (on with content type 'game')", + .type = CONFIG_OPTION_INT, + .data = SConfigOptionDescription::SRangeData{.value = 2, .min = 0, .max = 2}, }, SConfigOptionDescription{ .value = "cursor:min_refresh_rate", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 8bb6d157..42a1a91c 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -26,6 +26,7 @@ #include "../plugins/PluginSystem.hpp" #include "managers/HookSystemManager.hpp" +#include "protocols/types/ContentType.hpp" #include #include #include @@ -621,7 +622,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1}); m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0}); - m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{2}); m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24}); m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0}); m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f}); @@ -1347,6 +1348,14 @@ std::vector> CConfigManager::getMatchingRules(PHLWINDOW pWindow, continue; } + if (!rule->szContentType.empty()) { + try { + const auto contentType = NContentType::fromString(rule->szContentType); + if (pWindow->getContentType() != contentType) + continue; + } catch (std::exception& e) { Debug::log(ERR, "Rule \"content:{}\" failed with: {}", rule->szContentType, e.what()); } + } + if (!rule->szWorkspace.empty()) { const auto PWORKSPACE = pWindow->m_pWorkspace; @@ -2361,6 +2370,7 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& const auto FOCUSPOS = VALUE.find("focus:"); const auto FULLSCREENSTATEPOS = VALUE.find("fullscreenstate:"); const auto ONWORKSPACEPOS = VALUE.find("onworkspace:"); + const auto CONTENTTYPEPOS = VALUE.find("content:"); // find workspacepos that isn't onworkspacepos size_t WORKSPACEPOS = std::string::npos; @@ -2373,8 +2383,8 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& currentPos = VALUE.find("workspace:", currentPos + 1); } - const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS, - FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS}; + const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS, + FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS, CONTENTTYPEPOS}; if (checkPos.size() == 1 && checkPos.contains(std::string::npos)) { Debug::log(ERR, "Invalid rulev2 syntax: {}", VALUE); return "Invalid rulev2 syntax: " + VALUE; @@ -2411,6 +2421,8 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& min = WORKSPACEPOS; if (FOCUSPOS > pos && FOCUSPOS < min) min = FOCUSPOS; + if (CONTENTTYPEPOS > pos && CONTENTTYPEPOS < min) + min = CONTENTTYPEPOS; result = result.substr(0, min - pos); @@ -2469,6 +2481,9 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& if (ONWORKSPACEPOS != std::string::npos) rule->szOnWorkspace = extract(ONWORKSPACEPOS + 12); + if (CONTENTTYPEPOS != std::string::npos) + rule->szContentType = extract(CONTENTTYPEPOS + 8); + if (RULE == "unset") { std::erase_if(m_vWindowRules, [&](const auto& other) { if (!other->v2) @@ -2513,6 +2528,9 @@ std::optional CConfigManager::handleWindowRuleV2(const std::string& if (!rule->szOnWorkspace.empty() && rule->szOnWorkspace != other->szOnWorkspace) return false; + if (!rule->szContentType.empty() && rule->szContentType != other->szContentType) + return false; + return true; } }); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 6e580e49..6a523eec 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -15,6 +15,7 @@ #include "../managers/AnimationManager.hpp" #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" +#include "../protocols/ContentType.hpp" #include "../xwayland/XWayland.hpp" #include "../helpers/Color.hpp" #include "../events/Events.hpp" @@ -29,6 +30,7 @@ using namespace Hyprutils::String; using namespace Hyprutils::Animation; +using enum NContentType::eContentType; PHLWINDOW CWindow::create(SP surface) { PHLWINDOW pWindow = SP(new CWindow(surface)); @@ -1724,3 +1726,16 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional else if (m_pXDGSurface && m_pXDGSurface->toplevel) m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor()); } + +NContentType::eContentType CWindow::getContentType() { + return m_pWLSurface->resource()->contentType.valid() ? m_pWLSurface->resource()->contentType->value : CONTENT_TYPE_NONE; +} + +void CWindow::setContentType(NContentType::eContentType contentType) { + if (!m_pWLSurface->resource()->contentType.valid()) + m_pWLSurface->resource()->contentType = PROTO::contentType->getContentType(m_pWLSurface->resource()); + // else disallow content type change if proto is used? + + Debug::log(INFO, "ContentType for window {}", (int)contentType); + m_pWLSurface->resource()->contentType->value = contentType; +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index ce2f8eb2..b3c3d84f 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -19,6 +19,7 @@ #include "WLSurface.hpp" #include "Workspace.hpp" #include "WindowRule.hpp" +#include "protocols/types/ContentType.hpp" class CXDGSurfaceResource; class CXWaylandSurface; @@ -393,85 +394,87 @@ class CWindow { } // methods - CBox getFullWindowBoundingBox(); - SBoxExtents getFullWindowExtents(); - CBox getWindowBoxUnified(uint64_t props); - CBox getWindowIdealBoundingBoxIgnoreReserved(); - void addWindowDeco(UP deco); - void updateWindowDecos(); - void removeWindowDeco(IHyprWindowDecoration* deco); - void uncacheWindowDecos(); - bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {}); - pid_t getPID(); - IHyprWindowDecoration* getDecorationByType(eDecorationType); - void updateToplevel(); - void updateSurfaceScaleTransformDetails(bool force = false); - void moveToWorkspace(PHLWORKSPACE); - PHLWINDOW x11TransientFor(); - void onUnmap(); - void onMap(); - void setHidden(bool hidden); - bool isHidden(); - void applyDynamicRule(const SP& r); - void updateDynamicRules(); - SBoxExtents getFullWindowReservedArea(); - Vector2D middle(); - bool opaque(); - float rounding(); - float roundingPower(); - bool canBeTorn(); - void setSuspended(bool suspend); - bool visibleOnMonitor(PHLMONITOR pMonitor); - WORKSPACEID workspaceID(); - MONITORID monitorID(); - bool onSpecialWorkspace(); - void activate(bool force = false); - int surfacesCount(); - void clampWindowSize(const std::optional minSize, const std::optional maxSize); - bool isFullscreen(); - bool isEffectiveInternalFSMode(const eFullscreenMode); - int getRealBorderSize(); - float getScrollMouse(); - float getScrollTouchpad(); - void updateWindowData(); - void updateWindowData(const struct SWorkspaceRule&); - void onBorderAngleAnimEnd(WP pav); - bool isInCurvedCorner(double x, double y); - bool hasPopupAt(const Vector2D& pos); - int popupsCount(); - void applyGroupRules(); - void createGroup(); - void destroyGroup(); - PHLWINDOW getGroupHead(); - PHLWINDOW getGroupTail(); - PHLWINDOW getGroupCurrent(); - PHLWINDOW getGroupPrevious(); - PHLWINDOW getGroupWindowByIndex(int); - int getGroupSize(); - bool canBeGroupedInto(PHLWINDOW pWindow); - void setGroupCurrent(PHLWINDOW pWindow); - void insertWindowToGroup(PHLWINDOW pWindow); - void updateGroupOutputs(); - void switchWithWindowInGroup(PHLWINDOW pWindow); - void setAnimationsToMove(); - void onWorkspaceAnimUpdate(); - void onFocusAnimUpdate(); - void onUpdateState(); - void onUpdateMeta(); - void onX11Configure(CBox box); - void onResourceChangeX11(); - std::string fetchTitle(); - std::string fetchClass(); - void warpCursor(bool force = false); - PHLWINDOW getSwallower(); - void unsetWindowData(eOverridePriority priority); - bool isX11OverrideRedirect(); - bool isModal(); - Vector2D requestedMinSize(); - Vector2D requestedMaxSize(); - void sendWindowSize(Vector2D size, bool force = false, std::optional overridePos = std::nullopt); + CBox getFullWindowBoundingBox(); + SBoxExtents getFullWindowExtents(); + CBox getWindowBoxUnified(uint64_t props); + CBox getWindowIdealBoundingBoxIgnoreReserved(); + void addWindowDeco(UP deco); + void updateWindowDecos(); + void removeWindowDeco(IHyprWindowDecoration* deco); + void uncacheWindowDecos(); + bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {}); + pid_t getPID(); + IHyprWindowDecoration* getDecorationByType(eDecorationType); + void updateToplevel(); + void updateSurfaceScaleTransformDetails(bool force = false); + void moveToWorkspace(PHLWORKSPACE); + PHLWINDOW x11TransientFor(); + void onUnmap(); + void onMap(); + void setHidden(bool hidden); + bool isHidden(); + void applyDynamicRule(const SP& r); + void updateDynamicRules(); + SBoxExtents getFullWindowReservedArea(); + Vector2D middle(); + bool opaque(); + float rounding(); + float roundingPower(); + bool canBeTorn(); + void setSuspended(bool suspend); + bool visibleOnMonitor(PHLMONITOR pMonitor); + WORKSPACEID workspaceID(); + MONITORID monitorID(); + bool onSpecialWorkspace(); + void activate(bool force = false); + int surfacesCount(); + void clampWindowSize(const std::optional minSize, const std::optional maxSize); + bool isFullscreen(); + bool isEffectiveInternalFSMode(const eFullscreenMode); + int getRealBorderSize(); + float getScrollMouse(); + float getScrollTouchpad(); + void updateWindowData(); + void updateWindowData(const struct SWorkspaceRule&); + void onBorderAngleAnimEnd(WP pav); + bool isInCurvedCorner(double x, double y); + bool hasPopupAt(const Vector2D& pos); + int popupsCount(); + void applyGroupRules(); + void createGroup(); + void destroyGroup(); + PHLWINDOW getGroupHead(); + PHLWINDOW getGroupTail(); + PHLWINDOW getGroupCurrent(); + PHLWINDOW getGroupPrevious(); + PHLWINDOW getGroupWindowByIndex(int); + int getGroupSize(); + bool canBeGroupedInto(PHLWINDOW pWindow); + void setGroupCurrent(PHLWINDOW pWindow); + void insertWindowToGroup(PHLWINDOW pWindow); + void updateGroupOutputs(); + void switchWithWindowInGroup(PHLWINDOW pWindow); + void setAnimationsToMove(); + void onWorkspaceAnimUpdate(); + void onFocusAnimUpdate(); + void onUpdateState(); + void onUpdateMeta(); + void onX11Configure(CBox box); + void onResourceChangeX11(); + std::string fetchTitle(); + std::string fetchClass(); + void warpCursor(bool force = false); + PHLWINDOW getSwallower(); + void unsetWindowData(eOverridePriority priority); + bool isX11OverrideRedirect(); + bool isModal(); + Vector2D requestedMinSize(); + Vector2D requestedMaxSize(); + void sendWindowSize(Vector2D size, bool force = false, std::optional overridePos = std::nullopt); + NContentType::eContentType getContentType(); + void setContentType(NContentType::eContentType contentType); - CBox getWindowMainSurfaceBox() const { + CBox getWindowMainSurfaceBox() const { return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y}; } diff --git a/src/desktop/WindowRule.cpp b/src/desktop/WindowRule.cpp index 306a25ce..fea2d43b 100644 --- a/src/desktop/WindowRule.cpp +++ b/src/desktop/WindowRule.cpp @@ -8,8 +8,9 @@ static const auto RULES = std::unordered_set{ "float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused", }; static const auto RULES_PREFIX = std::unordered_set{ - "animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor", "move", "opacity", - "plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray", + "animation", "bordercolor", "bordersize", "center", "content", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", + "monitor", "move", "opacity", "plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", + "size", "suppressevent", "tag", "workspace", "xray", }; CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) { @@ -74,6 +75,8 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool ruleType = RULE_WORKSPACE; else if (rule.starts_with("prop")) ruleType = RULE_PROP; + else if (rule.starts_with("content")) + ruleType = RULE_CONTENT; else { // check if this is a prop. const CVarList VARS(rule, 0, 's', true); diff --git a/src/desktop/WindowRule.hpp b/src/desktop/WindowRule.hpp index be9c2d9c..50e221f3 100644 --- a/src/desktop/WindowRule.hpp +++ b/src/desktop/WindowRule.hpp @@ -36,6 +36,7 @@ class CWindowRule { RULE_TAG, RULE_WORKSPACE, RULE_PROP, + RULE_CONTENT, }; eRuleType ruleType = RULE_INVALID; @@ -58,6 +59,7 @@ class CWindowRule { std::string szFullscreenState = ""; // empty means any std::string szOnWorkspace = ""; // empty means any std::string szWorkspace = ""; // empty means any + std::string szContentType = ""; // empty means any // precompiled regexes CRuleRegexContainer rTitle; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index f6ef9ced..8eaabd29 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -11,11 +11,11 @@ #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../protocols/ToplevelExport.hpp" +#include "protocols/types/ContentType.hpp" #include "../xwayland/XSurface.hpp" #include "managers/AnimationManager.hpp" #include "managers/PointerManager.hpp" #include "../desktop/LayerSurface.hpp" -#include "../managers/input/InputManager.hpp" #include "../managers/LayoutManager.hpp" #include "../managers/EventManager.hpp" #include "../managers/AnimationManager.hpp" @@ -307,6 +307,13 @@ void Events::listener_mapWindow(void* owner, void* data) { } break; } + case CWindowRule::RULE_CONTENT: { + const CVarList VARS(r->szRule, 0, ' '); + try { + PWINDOW->setContentType(NContentType::fromString(VARS[1])); + } catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->szRule, e.what()); } + break; + } default: break; } diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 9aa6efce..3ea6d49b 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -33,6 +33,7 @@ using namespace Hyprutils::String; using namespace Hyprutils::Utils; using namespace Hyprutils::OS; +using enum NContentType::eContentType; static int ratHandler(void* data) { g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock()); @@ -799,8 +800,8 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() { static auto PMINRR = CConfigValue("cursor:min_refresh_rate"); // skip scheduling extra frames for fullsreen apps with vrr - bool shouldSkip = - *PNOBREAK && output->state->state().adaptiveSync && activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN; + const bool shouldSkip = activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN && + (*PNOBREAK == 1 || (*PNOBREAK == 2 && activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && output->state->state().adaptiveSync; // keep requested minimum refresh rate if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) { diff --git a/src/macros.hpp b/src/macros.hpp index a5176675..d2cad6b7 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -111,6 +111,7 @@ } \ } +#define AQUAMARINE_VERSION_NUMBER (AQUAMARINE_VERSION_MAJOR * 10000 + AQUAMARINE_VERSION_MINOR * 100 + AQUAMARINE_VERSION_PATCH) #define AQUAMARINE_FORWARD(name) \ namespace Aquamarine { \ class name; \ diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 62736ae5..6cd3a608 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -58,10 +58,12 @@ #include "../protocols/core/Shm.hpp" #include "../protocols/ColorManagement.hpp" #include "../protocols/FrogColorManagement.hpp" +#include "../protocols/ContentType.hpp" #include "../helpers/Monitor.hpp" #include "../render/Renderer.hpp" #include "../Compositor.hpp" +#include "content-type-v1.hpp" #include #include @@ -169,6 +171,7 @@ CProtocolManager::CProtocolManager() { PROTO::securityContext = makeUnique(&wp_security_context_manager_v1_interface, 1, "SecurityContext"); PROTO::ctm = makeUnique(&hyprland_ctm_control_manager_v1_interface, 2, "CTMControl"); PROTO::hyprlandSurface = makeUnique(&hyprland_surface_manager_v1_interface, 2, "HyprlandSurface"); + PROTO::contentType = makeUnique(&wp_content_type_manager_v1_interface, 1, "ContentType"); if (*PENABLEXXCM) { PROTO::colorManagement = makeUnique(&xx_color_manager_v4_interface, 1, "ColorManagement"); diff --git a/src/protocols/ContentType.cpp b/src/protocols/ContentType.cpp new file mode 100644 index 00000000..0dd5481a --- /dev/null +++ b/src/protocols/ContentType.cpp @@ -0,0 +1,95 @@ +#include "ContentType.hpp" +#include "content-type-v1.hpp" +#include "protocols/types/ContentType.hpp" + +CContentTypeManager::CContentTypeManager(SP resource) : m_resource(resource) { + if UNLIKELY (!good()) + return; + + resource->setDestroy([](CWpContentTypeManagerV1* r) {}); + resource->setOnDestroy([this](CWpContentTypeManagerV1* r) { PROTO::contentType->destroyResource(this); }); + + resource->setGetSurfaceContentType([](CWpContentTypeManagerV1* r, uint32_t id, wl_resource* surface) { + LOGM(TRACE, "Get surface for id={}, surface={}", id, (uintptr_t)surface); + auto SURF = CWLSurfaceResource::fromResource(surface); + + if (!SURF) { + LOGM(ERR, "No surface for resource {}", (uintptr_t)surface); + r->error(-1, "Invalid surface (2)"); + return; + } + + if (SURF->colorManagement) { + r->error(WP_CONTENT_TYPE_MANAGER_V1_ERROR_ALREADY_CONSTRUCTED, "CT manager already exists"); + return; + } + + const auto RESOURCE = PROTO::contentType->m_vContentTypes.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); + if UNLIKELY (!RESOURCE->good()) { + r->noMemory(); + PROTO::contentType->m_vContentTypes.pop_back(); + return; + } + + RESOURCE->self = RESOURCE; + + SURF->contentType = RESOURCE; + }); +} + +bool CContentTypeManager::good() { + return m_resource->resource(); +} + +CContentType::CContentType(WP surface) { + destroy = surface->events.destroy.registerListener([this](std::any d) { PROTO::contentType->destroyResource(this); }); +} + +CContentType::CContentType(SP resource) : m_resource(resource) { + if UNLIKELY (!good()) + return; + + m_pClient = resource->client(); + + resource->setDestroy([this](CWpContentTypeV1* r) { PROTO::contentType->destroyResource(this); }); + resource->setOnDestroy([this](CWpContentTypeV1* r) { PROTO::contentType->destroyResource(this); }); + + resource->setSetContentType([this](CWpContentTypeV1* r, wpContentTypeV1Type type) { value = NContentType::fromWP(type); }); +} + +bool CContentType::good() { + return m_resource && m_resource->resource(); +} + +wl_client* CContentType::client() { + return m_pClient; +} + +CContentTypeProtocol::CContentTypeProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CContentTypeProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); + + if UNLIKELY (!RESOURCE->good()) { + wl_client_post_no_memory(client); + m_vManagers.pop_back(); + return; + } +} + +SP CContentTypeProtocol::getContentType(WP surface) { + if (surface->contentType.valid()) + return surface->contentType.lock(); + + return m_vContentTypes.emplace_back(makeShared(surface)); +} + +void CContentTypeProtocol::destroyResource(CContentTypeManager* resource) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; }); +} + +void CContentTypeProtocol::destroyResource(CContentType* resource) { + std::erase_if(m_vContentTypes, [&](const auto& other) { return other.get() == resource; }); +} diff --git a/src/protocols/ContentType.hpp b/src/protocols/ContentType.hpp new file mode 100644 index 00000000..c0359bf1 --- /dev/null +++ b/src/protocols/ContentType.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include "WaylandProtocol.hpp" +#include "core/Compositor.hpp" +#include "content-type-v1.hpp" +#include "protocols/types/ContentType.hpp" + +class CContentTypeManager { + public: + CContentTypeManager(SP resource); + + bool good(); + + private: + SP m_resource; +}; + +class CContentType { + public: + CContentType(SP resource); + CContentType(WP surface); + + bool good(); + wl_client* client(); + NContentType::eContentType value = NContentType::CONTENT_TYPE_NONE; + + WP self; + + private: + SP m_resource; + wl_client* m_pClient = nullptr; + + CHyprSignalListener destroy; + + friend class CContentTypeProtocol; +}; + +class CContentTypeProtocol : public IWaylandProtocol { + public: + CContentTypeProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + SP getContentType(WP surface); + + private: + void destroyResource(CContentTypeManager* resource); + void destroyResource(CContentType* resource); + + std::vector> m_vManagers; + std::vector> m_vContentTypes; + + friend class CContentTypeManager; + friend class CContentType; +}; + +namespace PROTO { + inline UP contentType; +}; diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index 20614813..aaaf9b1a 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -26,6 +26,7 @@ class CViewportResource; class CDRMSyncobjSurfaceResource; class CColorManagementSurface; class CFrogColorManagementSurface; +class CContentType; class CWLCallbackResource { public: @@ -123,6 +124,7 @@ class CWLSurfaceResource { WP viewportResource; WP syncobj; // may not be present WP colorManagement; + WP contentType; void breadthfirst(std::function, const Vector2D&, void*)> fn, void* data); CRegion accumulateCurrentBufferDamage(); diff --git a/src/protocols/types/ContentType.cpp b/src/protocols/types/ContentType.cpp new file mode 100644 index 00000000..c0a3d30f --- /dev/null +++ b/src/protocols/types/ContentType.cpp @@ -0,0 +1,37 @@ +#include "ContentType.hpp" +#include +#include +#include + +namespace NContentType { + static std::unordered_map const table = { + {"none", CONTENT_TYPE_NONE}, {"photo", CONTENT_TYPE_PHOTO}, {"video", CONTENT_TYPE_VIDEO}, {"game", CONTENT_TYPE_GAME}}; + + eContentType fromString(const std::string name) { + auto it = table.find(name); + if (it != table.end()) + return it->second; + else + throw std::invalid_argument(std::format("Unknown content type {}", name)); + } + + eContentType fromWP(wpContentTypeV1Type contentType) { + switch (contentType) { + case WP_CONTENT_TYPE_V1_TYPE_NONE: return CONTENT_TYPE_NONE; + case WP_CONTENT_TYPE_V1_TYPE_PHOTO: return CONTENT_TYPE_PHOTO; + case WP_CONTENT_TYPE_V1_TYPE_VIDEO: return CONTENT_TYPE_VIDEO; + case WP_CONTENT_TYPE_V1_TYPE_GAME: return CONTENT_TYPE_GAME; + default: return CONTENT_TYPE_NONE; + } + } + + uint16_t toDRM(eContentType contentType) { + switch (contentType) { + case CONTENT_TYPE_NONE: return DRM_MODE_CONTENT_TYPE_GRAPHICS; + case CONTENT_TYPE_PHOTO: return DRM_MODE_CONTENT_TYPE_PHOTO; + case CONTENT_TYPE_VIDEO: return DRM_MODE_CONTENT_TYPE_CINEMA; + case CONTENT_TYPE_GAME: return DRM_MODE_CONTENT_TYPE_GAME; + default: return DRM_MODE_CONTENT_TYPE_NO_DATA; + } + } +} \ No newline at end of file diff --git a/src/protocols/types/ContentType.hpp b/src/protocols/types/ContentType.hpp new file mode 100644 index 00000000..66fcbca7 --- /dev/null +++ b/src/protocols/types/ContentType.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "content-type-v1.hpp" +#include + +namespace NContentType { + + enum eContentType : uint8_t { + CONTENT_TYPE_NONE = 0, + CONTENT_TYPE_PHOTO = 1, + CONTENT_TYPE_VIDEO = 2, + CONTENT_TYPE_GAME = 3, + }; + + eContentType fromString(const std::string name); + eContentType fromWP(wpContentTypeV1Type contentType); + uint16_t toDRM(eContentType contentType); +} \ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 42445728..6d7b409c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -33,10 +33,14 @@ #include "pass/SurfacePassElement.hpp" #include "debug/Log.hpp" #include "protocols/ColorManagement.hpp" +#if AQUAMARINE_VERSION_NUMBER > 702 // >0.7.2 +#include "protocols/types/ContentType.hpp" +#endif #include using namespace Hyprutils::Utils; using namespace Hyprutils::OS; +using enum NContentType::eContentType; extern "C" { #include @@ -1192,7 +1196,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { pMonitor->tearingState.activelyTearing = shouldTear; - if (*PDIRECTSCANOUT && !shouldTear) { + if ((*PDIRECTSCANOUT == 1 || (*PDIRECTSCANOUT == 2 && pMonitor->activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && !shouldTear) { if (pMonitor->attemptDirectScanout()) { return; } else if (!pMonitor->lastScanout.expired()) { @@ -1509,6 +1513,14 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { } } +#if AQUAMARINE_VERSION_NUMBER > 702 // >0.7.2 + if (pMonitor->activeWorkspace && pMonitor->activeWorkspace->m_bHasFullscreenWindow && pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) { + const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow(); + pMonitor->output->state->setContentType(NContentType::toDRM(WINDOW->getContentType())); + } else + pMonitor->output->state->setContentType(NContentType::toDRM(CONTENT_TYPE_NONE)); +#endif + if (pMonitor->ctmUpdated) { pMonitor->ctmUpdated = false; pMonitor->output->state->setCTM(pMonitor->ctm); From 44004abc0189b9ba49444431e2a39d2df7e930bb Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 2 Feb 2025 22:16:00 +0000 Subject: [PATCH 0227/1444] config: fix includes --- src/config/ConfigManager.cpp | 4 ++-- src/desktop/Window.hpp | 2 +- src/events/Windows.cpp | 2 +- src/protocols/ContentType.hpp | 2 +- subprojects/hyprland-protocols | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 42a1a91c..3f45ddfe 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -25,8 +25,8 @@ #include "../debug/HyprNotificationOverlay.hpp" #include "../plugins/PluginSystem.hpp" -#include "managers/HookSystemManager.hpp" -#include "protocols/types/ContentType.hpp" +#include "../managers/HookSystemManager.hpp" +#include "../protocols/types/ContentType.hpp" #include #include #include diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index b3c3d84f..2d004855 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -19,7 +19,7 @@ #include "WLSurface.hpp" #include "Workspace.hpp" #include "WindowRule.hpp" -#include "protocols/types/ContentType.hpp" +#include "../protocols/types/ContentType.hpp" class CXDGSurfaceResource; class CXWaylandSurface; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 8eaabd29..a068ba07 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -11,7 +11,7 @@ #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../protocols/ToplevelExport.hpp" -#include "protocols/types/ContentType.hpp" +#include "../protocols/types/ContentType.hpp" #include "../xwayland/XSurface.hpp" #include "managers/AnimationManager.hpp" #include "managers/PointerManager.hpp" diff --git a/src/protocols/ContentType.hpp b/src/protocols/ContentType.hpp index c0359bf1..4c0c445f 100644 --- a/src/protocols/ContentType.hpp +++ b/src/protocols/ContentType.hpp @@ -3,7 +3,7 @@ #include "WaylandProtocol.hpp" #include "core/Compositor.hpp" #include "content-type-v1.hpp" -#include "protocols/types/ContentType.hpp" +#include "types/ContentType.hpp" class CContentTypeManager { public: diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index 755aef8d..4c75dd5c 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit 755aef8dab49d0fc4663c715fa4ad221b2aedaed +Subproject commit 4c75dd5c015c8a0e5a34c6d02a018a650f57feb5 From 708d16636047c6a311c4e44424cf7d2090219a47 Mon Sep 17 00:00:00 2001 From: Alexander <51529891+Truenya@users.noreply.github.com> Date: Mon, 3 Feb 2025 04:34:30 +0300 Subject: [PATCH 0228/1444] dispatchers: add cyclenext hist option (#9055) --- src/Compositor.cpp | 83 +++++++++++++++++++-------------- src/Compositor.hpp | 7 ++- src/managers/KeybindManager.cpp | 32 ++++++------- src/managers/KeybindManager.hpp | 2 +- 4 files changed, 67 insertions(+), 57 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 0aa0f13d..95a57e03 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1058,7 +1058,7 @@ PHLMONITOR CCompositor::getRealMonitorFromOutput(SP out) { return nullptr; } -void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface) { +void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface, bool preserveFocusHistory) { static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); static auto PSPECIALFALLTHROUGH = CConfigValue("input:special_fallthrough"); @@ -1178,12 +1178,13 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface g_pInputManager->recheckIdleInhibitorStatus(); - // move to front of the window history - const auto HISTORYPIVOT = std::find_if(m_vWindowFocusHistory.begin(), m_vWindowFocusHistory.end(), [&](const auto& other) { return other.lock() == pWindow; }); - if (HISTORYPIVOT == m_vWindowFocusHistory.end()) { - Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow); - } else { - std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1); + if (!preserveFocusHistory) { + // move to front of the window history + const auto HISTORYPIVOT = std::ranges::find_if(m_vWindowFocusHistory, [&](const auto& other) { return other.lock() == pWindow; }); + if (HISTORYPIVOT == m_vWindowFocusHistory.end()) + Debug::log(ERR, "BUG THIS: {} has no pivot in history", pWindow); + else + std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1); } if (*PFOLLOWMOUSE == 0) @@ -1396,7 +1397,6 @@ void CCompositor::changeWindowZOrder(PHLWINDOW pWindow, bool top) { }; x11Stack(pWindow, top, x11Stack); - for (const auto& it : toMove) { moveToZ(it, top); } @@ -1647,37 +1647,52 @@ PHLWINDOW CCompositor::getWindowInDirection(const CBox& box, PHLWORKSPACE pWorks return nullptr; } -PHLWINDOW CCompositor::getNextWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating, bool visible) { - auto it = std::ranges::find(m_vWindows, pWindow); - const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); }; - const auto IN_RIGHT = std::find_if(it, m_vWindows.end(), FINDER); - if (IN_RIGHT != m_vWindows.end()) - return *IN_RIGHT; - const auto IN_LEFT = std::find_if(m_vWindows.begin(), it, FINDER); - return *IN_LEFT; -} - -PHLWINDOW CCompositor::getPrevWindowOnWorkspace(PHLWINDOW pWindow, bool focusableOnly, std::optional floating, bool visible) { - auto it = std::ranges::find(std::ranges::reverse_view(m_vWindows), pWindow); - const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(pWindow, w, focusableOnly, floating, visible); }; - const auto IN_LEFT = std::find_if(it, m_vWindows.rend(), FINDER); - if (IN_LEFT != m_vWindows.rend()) - return *IN_LEFT; - const auto IN_RIGHT = std::find_if(m_vWindows.rbegin(), it, FINDER); - return *IN_RIGHT; -} - -inline static bool isWorkspaceMatches(PHLWINDOW pWindow, const PHLWINDOW w, bool anyWorkspace) { +template +static bool isWorkspaceMatches(WINDOWPTR pWindow, const WINDOWPTR w, bool anyWorkspace) { return anyWorkspace ? w->m_pWorkspace && w->m_pWorkspace->isVisible() : w->m_pWorkspace == pWindow->m_pWorkspace; } -inline static bool isFloatingMatches(PHLWINDOW w, std::optional floating) { +template +static bool isFloatingMatches(WINDOWPTR w, std::optional floating) { return !floating.has_value() || w->m_bIsFloating == floating.value(); -}; +} -bool CCompositor::isWindowAvailableForCycle(PHLWINDOW pWindow, const PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace) { - return isFloatingMatches(w, floating) && w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && - (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault()); +template +static bool isWindowAvailableForCycle(WINDOWPTR pWindow, WINDOWPTR w, bool focusableOnly, std::optional floating, bool anyWorkspace = false) { + return isFloatingMatches(w, floating) && + (w != pWindow && isWorkspaceMatches(pWindow, w, anyWorkspace) && w->m_bIsMapped && !w->isHidden() && (!focusableOnly || !w->m_sWindowData.noFocus.valueOrDefault())); +} + +template +static PHLWINDOW getWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function PRED) { + const auto IN_ONE_SIDE = std::find_if(cur, end, PRED); + if (IN_ONE_SIDE != end) + return *IN_ONE_SIDE; + const auto IN_OTHER_SIDE = std::find_if(begin, cur, PRED); + return *IN_OTHER_SIDE; +} + +template +static PHLWINDOW getWeakWindowPred(Iterator cur, Iterator end, Iterator begin, const std::function PRED) { + const auto IN_ONE_SIDE = std::find_if(cur, end, PRED); + if (IN_ONE_SIDE != end) + return IN_ONE_SIDE->lock(); + const auto IN_OTHER_SIDE = std::find_if(begin, cur, PRED); + return IN_OTHER_SIDE->lock(); +} + +PHLWINDOW CCompositor::getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly, std::optional floating, bool visible, bool next) { + const auto FINDER = [&](const PHLWINDOWREF& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + // also m_vWindowFocusHistory has reverse order, so when it is next - we need to reverse again + return next ? + getWeakWindowPred(std::ranges::find(std::ranges::reverse_view(m_vWindowFocusHistory), cur), m_vWindowFocusHistory.rend(), m_vWindowFocusHistory.rbegin(), FINDER) : + getWeakWindowPred(std::ranges::find(m_vWindowFocusHistory, cur), m_vWindowFocusHistory.end(), m_vWindowFocusHistory.begin(), FINDER); +} + +PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::optional floating, bool visible, bool prev) { + const auto FINDER = [&](const PHLWINDOW& w) { return isWindowAvailableForCycle(cur, w, focusableOnly, floating, visible); }; + return prev ? getWindowPred(std::ranges::find(std::ranges::reverse_view(m_vWindows), cur), m_vWindows.rend(), m_vWindows.rbegin(), FINDER) : + getWindowPred(std::ranges::find(m_vWindows, cur), m_vWindows.end(), m_vWindows.begin(), FINDER); } WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() { diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 787ead08..a57095a3 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -83,7 +83,7 @@ class CCompositor { PHLMONITOR getMonitorFromCursor(); PHLMONITOR getMonitorFromVector(const Vector2D&); void removeWindowFromVectorSafe(PHLWINDOW); - void focusWindow(PHLWINDOW, SP pSurface = nullptr); + void focusWindow(PHLWINDOW, SP pSurface = nullptr, bool preserveFocusHistory = false); void focusSurface(SP, PHLWINDOW pWindowOwner = nullptr); bool monitorExists(PHLMONITOR); PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr); @@ -105,8 +105,8 @@ class CCompositor { void cleanupFadingOut(const MONITORID& monid); PHLWINDOW getWindowInDirection(PHLWINDOW, char); PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false); - PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); - PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {}, bool visible = false); + PHLWINDOW getWindowCycle(PHLWINDOW cur, bool focusableOnly = false, std::optional floating = std::nullopt, bool visible = false, bool prev = false); + PHLWINDOW getWindowCycleHist(PHLWINDOWREF cur, bool focusableOnly = false, std::optional floating = std::nullopt, bool visible = false, bool next = false); WORKSPACEID getNextAvailableNamedWorkspace(); bool isPointOnAnyMonitor(const Vector2D&); bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr); @@ -163,7 +163,6 @@ class CCompositor { void setRandomSplash(); void initManagers(eManagersInitStage stage); void prepareFallbackOutput(); - bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional floating, bool anyWorkspace = false); uint64_t m_iHyprlandPID = 0; wl_event_source* m_critSigSource = nullptr; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index bc5d36c8..47cc4f67 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -367,7 +367,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(PHLMONITOR monitor) { return true; } -void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { +void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory) { static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); static auto PNOWARPS = CConfigValue("cursor:no_warps"); @@ -386,7 +386,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { if (!PWINDOWTOCHANGETO->m_bPinned) g_pCompositor->setWindowFullscreenInternal(PLASTWINDOW, FSMODE_NONE); - g_pCompositor->focusWindow(PWINDOWTOCHANGETO); + g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory); if (!PWINDOWTOCHANGETO->m_bPinned) g_pCompositor->setWindowFullscreenInternal(PWINDOWTOCHANGETO, MODE); @@ -396,7 +396,7 @@ void CKeybindManager::switchToWindow(PHLWINDOW PWINDOWTOCHANGETO) { PWINDOWTOCHANGETO->m_vRealSize->warp(); } else { updateRelativeCursorCoords(); - g_pCompositor->focusWindow(PWINDOWTOCHANGETO); + g_pCompositor->focusWindow(PWINDOWTOCHANGETO, nullptr, preserveFocusHistory); PWINDOWTOCHANGETO->warpCursor(); // Move mouse focus to the new window if required by current follow_mouse and warp modes @@ -1473,7 +1473,7 @@ SDispatchResult CKeybindManager::moveFocusTo(std::string args) { } const auto PWINDOWTOCHANGETO = *PFULLCYCLE && PLASTWINDOW->isFullscreen() ? - (arg == 'd' || arg == 'b' || arg == 'r' ? g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true) : g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true)) : + g_pCompositor->getWindowCycle(PLASTWINDOW, true, {}, false, arg != 'd' && arg != 'b' && arg != 'r') : g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); // Prioritize focus change within groups if the window is a part of it. @@ -2221,11 +2221,13 @@ SDispatchResult CKeybindManager::circleNext(std::string arg) { floatStatus = true; const auto VISIBLE = args.contains("visible") || args.contains("v"); - const auto& w = (args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l")) ? - g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE) : - g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE); + const auto PREV = args.contains("prev") || args.contains("p") || args.contains("last") || args.contains("l"); + const auto NEXT = args.contains("next") || args.contains("n"); // prev is default in classic alt+tab + const auto HIST = args.contains("hist") || args.contains("h"); + const auto& w = HIST ? g_pCompositor->getWindowCycleHist(g_pCompositor->m_pLastWindow, true, floatStatus, VISIBLE, NEXT) : + g_pCompositor->getWindowCycle(g_pCompositor->m_pLastWindow.lock(), true, floatStatus, VISIBLE, PREV); - switchToWindow(w); + switchToWindow(w, HIST); return {}; } @@ -2620,18 +2622,12 @@ SDispatchResult CKeybindManager::swapnext(std::string arg) { g_pCompositor->m_pLastWindow->m_pLastCycledWindow.lock() : nullptr; - if (arg == "last" || arg == "l" || arg == "prev" || arg == "p") - toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true); - else - toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true); + const bool NEED_PREV = arg == "last" || arg == "l" || arg == "prev" || arg == "p"; + toSwap = g_pCompositor->getWindowCycle(PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW, true, std::nullopt, false, NEED_PREV); // sometimes we may come back to ourselves. - if (toSwap == PLASTWINDOW) { - if (arg == "last" || arg == "l" || arg == "prev" || arg == "p") - toSwap = g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true); - else - toSwap = g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true); - } + if (toSwap == PLASTWINDOW) + toSwap = g_pCompositor->getWindowCycle(PLASTWINDOW, true, std::nullopt, false, NEED_PREV); g_pLayoutManager->getCurrentLayout()->switchWindows(PLASTWINDOW, toSwap); diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 1848ca78..cea3e3cf 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -148,7 +148,7 @@ class CKeybindManager { static bool tryMoveFocusToMonitor(PHLMONITOR monitor); static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = ""); static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection); - static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO); + static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false); static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace); static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace); From 1da0b2c02e99d3bd35f4d1a6f9a55dc403715913 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 3 Feb 2025 19:45:26 +0000 Subject: [PATCH 0229/1444] subprojects: update h-p fixes #9309 --- subprojects/hyprland-protocols | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index 4c75dd5c..755aef8d 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit 4c75dd5c015c8a0e5a34c6d02a018a650f57feb5 +Subproject commit 755aef8dab49d0fc4663c715fa4ad221b2aedaed From 70cfc7cc9c4ecadbb9dd9a75f096fc70177a8ca5 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 3 Feb 2025 19:53:14 +0000 Subject: [PATCH 0230/1444] cmonitor: guard old workspace --- src/helpers/Monitor.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 3ea6d49b..e4843211 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1019,15 +1019,17 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo if (pWorkspace == activeWorkspace) return; - const auto POLDWORKSPACE = activeWorkspace; - POLDWORKSPACE->m_bVisible = false; - pWorkspace->m_bVisible = true; + const auto POLDWORKSPACE = activeWorkspace; + if (POLDWORKSPACE) + POLDWORKSPACE->m_bVisible = false; + pWorkspace->m_bVisible = true; activeWorkspace = pWorkspace; if (!internal) { - const auto ANIMTOLEFT = pWorkspace->m_iID > POLDWORKSPACE->m_iID; - POLDWORKSPACE->startAnim(false, ANIMTOLEFT); + const auto ANIMTOLEFT = POLDWORKSPACE && pWorkspace->m_iID > POLDWORKSPACE->m_iID; + if (POLDWORKSPACE) + POLDWORKSPACE->startAnim(false, ANIMTOLEFT); pWorkspace->startAnim(true, ANIMTOLEFT); // move pinned windows From 5e7292434a9189d0550187f8a6fb687848194a41 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 3 Feb 2025 22:36:10 +0000 Subject: [PATCH 0231/1444] compositor: guard null ws in updating fade --- src/Compositor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 95a57e03..22cb70fb 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2217,6 +2217,9 @@ bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) { void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) { + if (!pWorkspace) + return; + const auto FULLSCREEN = pWorkspace->m_bHasFullscreenWindow; for (auto const& w : g_pCompositor->m_vWindows) { From 3b99e906df8b439d65e740301940e57efc057012 Mon Sep 17 00:00:00 2001 From: vaxerski Date: Tue, 4 Feb 2025 10:18:08 +0000 Subject: [PATCH 0232/1444] compositor: don't iterate over unmapped ls-es in vectorToLS fixes #9312 --- src/Compositor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 22cb70fb..a8cbae3a 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1245,7 +1245,7 @@ void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindo SP CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, PHLMONITOR monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { for (auto const& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) { for (auto const& ls : lsl | std::views::reverse) { - if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha->value() == 0.f) + if (!ls->mapped || ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha->value() == 0.f) continue; auto SURFACEAT = ls->popupHead->at(pos, true); @@ -1263,7 +1263,7 @@ SP CCompositor::vectorToLayerPopupSurface(const Vector2D& po SP CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { for (auto const& ls : *layerSurfaces | std::views::reverse) { - if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha->value() == 0.f) + if (!ls->mapped || ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha->value() == 0.f) continue; auto [surf, local] = ls->layerSurface->surface->at(pos - ls->geometry.pos(), true); From 84c9baecc6b73f6321b2739061e3c232710f73bf Mon Sep 17 00:00:00 2001 From: Tom Benham <38216488+tomben13@users.noreply.github.com> Date: Wed, 5 Feb 2025 10:56:41 +0100 Subject: [PATCH 0233/1444] keybinds: Added `toggleswallow` dispatcher (#5548) * Added `toggleswallow` dispatcher * clang-format * Removed brackets for 1-line if --- src/desktop/Window.cpp | 6 ++++-- src/desktop/Window.hpp | 3 ++- src/events/Windows.cpp | 13 +++++++++---- src/managers/KeybindManager.cpp | 22 ++++++++++++++++++++++ src/managers/KeybindManager.hpp | 1 + 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 6a523eec..c71fe652 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -452,8 +452,10 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { } if (const auto SWALLOWED = m_pSwallowed.lock()) { - SWALLOWED->moveToWorkspace(pWorkspace); - SWALLOWED->m_pMonitor = m_pMonitor; + if (SWALLOWED->m_bCurrentlySwallowed) { + SWALLOWED->moveToWorkspace(pWorkspace); + SWALLOWED->m_pMonitor = m_pMonitor; + } } // update xwayland coords diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 2d004855..8444a113 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -355,7 +355,8 @@ class CWindow { // swallowing PHLWINDOWREF m_pSwallowed; - bool m_bGroupSwallowed = false; + bool m_bCurrentlySwallowed = false; + bool m_bGroupSwallowed = false; // focus stuff bool m_bStayFocused = false; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index a068ba07..d96bb332 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -392,6 +392,8 @@ void Events::listener_mapWindow(void* owner, void* data) { // Verify window swallowing. Get the swallower before calling onWindowCreated(PWINDOW) because getSwallower() wouldn't get it after if PWINDOW gets auto grouped. const auto SWALLOWER = PWINDOW->getSwallower(); PWINDOW->m_pSwallowed = SWALLOWER; + if (PWINDOW->m_pSwallowed) + PWINDOW->m_pSwallowed->m_bCurrentlySwallowed = true; if (PWINDOW->m_bIsFloating) { g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); @@ -731,12 +733,15 @@ void Events::listener_unmapWindow(void* owner, void* data) { // swallowing if (valid(PWINDOW->m_pSwallowed)) { - PWINDOW->m_pSwallowed->setHidden(false); + if (PWINDOW->m_pSwallowed->m_bCurrentlySwallowed) { + PWINDOW->m_pSwallowed->m_bCurrentlySwallowed = false; + PWINDOW->m_pSwallowed->setHidden(false); - if (PWINDOW->m_sGroupData.pNextWindow.lock()) - PWINDOW->m_pSwallowed->m_bGroupSwallowed = true; // flag for the swallowed window to be created into the group where it belongs when auto_group = false. + if (PWINDOW->m_sGroupData.pNextWindow.lock()) + PWINDOW->m_pSwallowed->m_bGroupSwallowed = true; // flag for the swallowed window to be created into the group where it belongs when auto_group = false. - g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed.lock()); + g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW->m_pSwallowed.lock()); + } PWINDOW->m_pSwallowed->m_bGroupSwallowed = false; PWINDOW->m_pSwallowed.reset(); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 47cc4f67..2d6b2cb8 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -113,6 +113,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["focuswindowbyclass"] = focusWindow; m_mDispatchers["focuswindow"] = focusWindow; m_mDispatchers["tagwindow"] = tagWindow; + m_mDispatchers["toggleswallow"] = toggleSwallow; m_mDispatchers["submap"] = setSubmap; m_mDispatchers["pass"] = pass; m_mDispatchers["sendshortcut"] = sendshortcut; @@ -2306,6 +2307,27 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) { return {}; } +SDispatchResult CKeybindManager::toggleSwallow(std::string args) { + PHLWINDOWREF pWindow = g_pCompositor->m_pLastWindow; + + if (!valid(pWindow) || !valid(pWindow->m_pSwallowed)) + return {}; + + if (pWindow->m_pSwallowed->m_bCurrentlySwallowed) { + // Unswallow + pWindow->m_pSwallowed->m_bCurrentlySwallowed = false; + pWindow->m_pSwallowed->setHidden(false); + g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow->m_pSwallowed.lock()); + } else { + // Reswallow + pWindow->m_pSwallowed->m_bCurrentlySwallowed = true; + pWindow->m_pSwallowed->setHidden(true); + g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow->m_pSwallowed.lock()); + } + + return {}; +} + SDispatchResult CKeybindManager::setSubmap(std::string submap) { if (submap == "reset" || submap == "") { m_szCurrentSelectedSubmap = ""; diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index cea3e3cf..712fd58d 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -199,6 +199,7 @@ class CKeybindManager { static SDispatchResult circleNext(std::string); static SDispatchResult focusWindow(std::string); static SDispatchResult tagWindow(std::string); + static SDispatchResult toggleSwallow(std::string); static SDispatchResult setSubmap(std::string); static SDispatchResult pass(std::string); static SDispatchResult sendshortcut(std::string); From 873bff390e56fb379754221d9652d0c3b850eaad Mon Sep 17 00:00:00 2001 From: nyx Date: Wed, 5 Feb 2025 09:53:09 -0500 Subject: [PATCH 0234/1444] renderer: fix missing null checks to prevent crashes (#9332) --- src/render/Renderer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 6d7b409c..0fcda827 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1196,7 +1196,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) { pMonitor->tearingState.activelyTearing = shouldTear; - if ((*PDIRECTSCANOUT == 1 || (*PDIRECTSCANOUT == 2 && pMonitor->activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && !shouldTear) { + if ((*PDIRECTSCANOUT == 1 || + (*PDIRECTSCANOUT == 2 && pMonitor->activeWorkspace->getFullscreenWindow() && pMonitor->activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && + !shouldTear) { if (pMonitor->attemptDirectScanout()) { return; } else if (!pMonitor->lastScanout.expired()) { From 64591c85aa212fe06fab90ea2deaccbec529c0c0 Mon Sep 17 00:00:00 2001 From: raf Date: Wed, 5 Feb 2025 14:55:33 +0000 Subject: [PATCH 0235/1444] nix: add hydraJobs output for aggregating Hyprland build jobs --- flake.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flake.nix b/flake.nix index c1c580ae..801d96ec 100644 --- a/flake.nix +++ b/flake.nix @@ -157,5 +157,11 @@ nixosModules.default = import ./nix/module.nix inputs; homeManagerModules.default = import ./nix/hm-module.nix self; + + # Hydra build jobs + # Recent versions of Hydra can aggregate jobsets from 'hydraJobs' intead of a release.nix + # or similar. Remember to filter large or incompatible attributes here. More eval jobs can + # be added by merging, e.g., self.packages // self.devShells. + hydraJobs = self.packages; }; } From 8a6778f0a087cdfc4bc1d3751b0be2c2bf3322aa Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 5 Feb 2025 15:41:54 +0000 Subject: [PATCH 0236/1444] scripts: don't overwrite generated version if we're not in a git repo --- scripts/generateVersion.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/generateVersion.sh b/scripts/generateVersion.sh index fdcc4712..e88cef3f 100755 --- a/scripts/generateVersion.sh +++ b/scripts/generateVersion.sh @@ -1,4 +1,13 @@ #!/bin/sh + +# if the git directory doesn't exist, don't gather data to avoid overwriting, unless +# the version file is missing altogether (otherwise compiling will fail) +if [[ ! -d ./.git ]]; then + if [[ -f ./src/version.h ]]; then + exit 0 + fi +fi + cp -fr ./src/version.h.in ./src/version.h HASH=${HASH-$(git rev-parse HEAD)} From 868b2b544abb61764089b0e4e9b0fd153a9db26f Mon Sep 17 00:00:00 2001 From: nyx Date: Thu, 6 Feb 2025 06:16:47 -0500 Subject: [PATCH 0237/1444] window: fix missing surface null checks to prevent crashes (#9350) --- src/desktop/Window.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index c71fe652..b5126b67 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1730,7 +1730,10 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional } NContentType::eContentType CWindow::getContentType() { - return m_pWLSurface->resource()->contentType.valid() ? m_pWLSurface->resource()->contentType->value : CONTENT_TYPE_NONE; + if (!m_pWLSurface || !m_pWLSurface->resource() || !m_pWLSurface->resource()->contentType.valid()) + return CONTENT_TYPE_NONE; + + return m_pWLSurface->resource()->contentType->value; } void CWindow::setContentType(NContentType::eContentType contentType) { From f1e32cd122ad64ba7119ee7fe65f7c1074a65b91 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Thu, 6 Feb 2025 12:18:04 +0100 Subject: [PATCH 0238/1444] core: avoid .at() and use [] operator (#9347) avoid .at() where it makes sense and use [] operator in loops. --- src/desktop/Window.cpp | 8 ++++---- src/devices/IKeyboard.cpp | 20 ++++++++++---------- src/layout/MasterLayout.cpp | 2 +- src/managers/PointerManager.cpp | 2 +- src/managers/XCursorManager.cpp | 2 +- src/render/OpenGL.cpp | 8 ++++---- src/xwayland/XDataSource.cpp | 4 ++-- src/xwayland/XWM.cpp | 4 ++-- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index b5126b67..8f6d2cb5 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1626,17 +1626,17 @@ PHLWINDOW CWindow::getSwallower() { if (!(*PSWALLOWREGEX).empty()) std::erase_if(candidates, [&](const auto& other) { return !RE2::FullMatch(other->m_szClass, *PSWALLOWREGEX); }); - if (candidates.size() <= 0) + if (candidates.size() == 0) return nullptr; if (!(*PSWALLOWEXREGEX).empty()) std::erase_if(candidates, [&](const auto& other) { return RE2::FullMatch(other->m_szTitle, *PSWALLOWEXREGEX); }); - if (candidates.size() <= 0) + if (candidates.size() == 0) return nullptr; if (candidates.size() == 1) - return candidates.at(0); + return candidates[0]; // walk up the focus history and find the last focused for (auto const& w : g_pCompositor->m_vWindowFocusHistory) { @@ -1648,7 +1648,7 @@ PHLWINDOW CWindow::getSwallower() { } // if none are found (??) then just return the first one - return candidates.at(0); + return candidates[0]; } void CWindow::unsetWindowData(eOverridePriority priority) { diff --git a/src/devices/IKeyboard.cpp b/src/devices/IKeyboard.cpp index 307d840b..89891ebd 100644 --- a/src/devices/IKeyboard.cpp +++ b/src/devices/IKeyboard.cpp @@ -126,14 +126,14 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) { updateModifiers(0, 0, modifiersState.locked, modifiersState.group); } - for (size_t i = 0; i < LEDNAMES.size(); ++i) { - ledIndexes.at(i) = xkb_map_led_get_index(xkbKeymap, LEDNAMES.at(i)); - Debug::log(LOG, "xkb: LED index {} (name {}) got index {}", i, LEDNAMES.at(i), ledIndexes.at(i)); + for (size_t i = 0; i < std::min(LEDNAMES.size(), ledIndexes.size()); ++i) { + ledIndexes[i] = xkb_map_led_get_index(xkbKeymap, LEDNAMES[i]); + Debug::log(LOG, "xkb: LED index {} (name {}) got index {}", i, LEDNAMES[i], ledIndexes[i]); } - for (size_t i = 0; i < MODNAMES.size(); ++i) { - modIndexes.at(i) = xkb_map_mod_get_index(xkbKeymap, MODNAMES.at(i)); - Debug::log(LOG, "xkb: Mod index {} (name {}) got index {}", i, MODNAMES.at(i), modIndexes.at(i)); + for (size_t i = 0; i < std::min(MODNAMES.size(), modIndexes.size()); ++i) { + modIndexes[i] = xkb_map_mod_get_index(xkbKeymap, MODNAMES[i]); + Debug::log(LOG, "xkb: Mod index {} (name {}) got index {}", i, MODNAMES[i], modIndexes[i]); } updateKeymapFD(); @@ -289,8 +289,8 @@ std::optional IKeyboard::getLEDs() { return {}; uint32_t leds = 0; - for (uint32_t i = 0; i < LED_COUNT; ++i) { - if (xkb_state_led_index_is_active(xkbState, ledIndexes.at(i))) + for (uint32_t i = 0; i < std::min((size_t)LED_COUNT, ledIndexes.size()); ++i) { + if (xkb_state_led_index_is_active(xkbState, ledIndexes[i])) leds |= (1 << i); } @@ -323,10 +323,10 @@ uint32_t IKeyboard::getModifiers() { uint32_t modMask = modifiersState.depressed | modifiersState.latched; uint32_t mods = 0; for (size_t i = 0; i < modIndexes.size(); ++i) { - if (modIndexes.at(i) == XKB_MOD_INVALID) + if (modIndexes[i] == XKB_MOD_INVALID) continue; - if (!(modMask & (1 << modIndexes.at(i)))) + if (!(modMask & (1 << modIndexes[i]))) continue; mods |= (1 << i); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 4773147f..dc301bfa 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -1357,7 +1357,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi int nextOrPrev = 0; for (size_t i = 0; i < cycle.size(); ++i) { - if (PWORKSPACEDATA->orientation == cycle.at(i)) { + if (PWORKSPACEDATA->orientation == cycle[i]) { nextOrPrev = i + direction; break; } diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 48ef5e16..1c8e9976 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -475,7 +475,7 @@ SP CPointerManager::renderHWCursorBuffer(SP> CXCursorManager::loadStandardCursors(std::string cons // load the default xcursor shapes that exist in the theme for (size_t i = 0; i < XCURSOR_STANDARD_NAMES.size(); ++i) { - std::string shape{XCURSOR_STANDARD_NAMES.at(i)}; + std::string shape{XCURSOR_STANDARD_NAMES[i]}; auto xImages = XcursorShapeLoadImages(i << 1 /* wtf xcursor? */, name.c_str(), size); if (!xImages) { diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 75a5eadb..3b641c36 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -402,14 +402,14 @@ std::optional> CHyprOpenGLImpl::getModsForFormat(EGLint fo result.reserve(mods.size()); bool linearIsExternal = false; - for (size_t i = 0; i < mods.size(); ++i) { - if (external.at(i)) { - if (mods.at(i) == DRM_FORMAT_MOD_LINEAR) + for (size_t i = 0; i < std::min(mods.size(), external.size()); ++i) { + if (external[i]) { + if (mods[i] == DRM_FORMAT_MOD_LINEAR) linearIsExternal = true; continue; } - result.push_back(mods.at(i)); + result.push_back(mods[i]); } // if the driver doesn't mark linear as external, add it. It's allowed unless the driver says otherwise. (e.g. nvidia) diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp index e6282dcb..9384db69 100644 --- a/src/xwayland/XDataSource.cpp +++ b/src/xwayland/XDataSource.cpp @@ -57,8 +57,8 @@ void CXDataSource::send(const std::string& mime, CFileDescriptor fd) { mimeAtom = HYPRATOMS["UTF8_STRING"]; else { for (size_t i = 0; i < mimeTypes.size(); ++i) { - if (mimeTypes.at(i) == mime) { - mimeAtom = mimeAtoms.at(i); + if (mimeTypes[i] == mime) { + mimeAtom = mimeAtoms[i]; break; } } diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 81900c7b..68552dd6 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -1051,13 +1051,13 @@ void CXWM::readWindowData(SP surf) { }; for (size_t i = 0; i < interestingProps.size(); i++) { - xcb_get_property_cookie_t cookie = xcb_get_property(connection, 0, surf->xID, interestingProps.at(i), XCB_ATOM_ANY, 0, 2048); + xcb_get_property_cookie_t cookie = xcb_get_property(connection, 0, surf->xID, interestingProps[i], XCB_ATOM_ANY, 0, 2048); xcb_get_property_reply_t* reply = xcb_get_property_reply(connection, cookie, nullptr); if (!reply) { Debug::log(ERR, "[xwm] Failed to get window property"); continue; } - readProp(surf, interestingProps.at(i), reply); + readProp(surf, interestingProps[i], reply); free(reply); } } From ff9e059de6dd30c813270ff5a74053339cc94765 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:21:04 +0000 Subject: [PATCH 0239/1444] window: move size reporting to animation begin callback (#9298) * window: fix resizes with an update callback * window: fixup sendWindowSize Remove the size argument from sendWindowSize, since it is now a member of the Window class and we don't want any mismatches between m_vRealSize and what we report. Remove sendWindowSize from mapWindow, since we shouldn't need it. * window: sendWindowSize on animation begin * window: move most calls to sendWindowSize to the animation begin callback * window: remove sendWindowSize in unmanaged if not fullscreen --- src/Compositor.cpp | 2 +- src/desktop/Window.cpp | 26 +++++++++++-------- src/desktop/Window.hpp | 2 +- src/desktop/Workspace.cpp | 2 +- src/events/Windows.cpp | 9 +------ src/layout/DwindleLayout.cpp | 4 --- src/layout/IHyprLayout.cpp | 18 +++++-------- src/layout/MasterLayout.cpp | 4 --- src/managers/KeybindManager.cpp | 1 - src/managers/XWaylandManager.cpp | 2 +- .../decorations/CHyprGroupBarDecoration.cpp | 3 --- 11 files changed, 26 insertions(+), 47 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index a8cbae3a..e460bbca 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2330,7 +2330,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS updateFullscreenFadeOnWorkspace(PWORKSPACE); - PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true); + PWINDOW->sendWindowSize(true); PWORKSPACE->forceReportSizesToWindows(); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 8f6d2cb5..b0d7b58c 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -458,9 +458,6 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { } } - // update xwayland coords - sendWindowSize(m_vRealSize->goal()); - if (OLDWORKSPACE && g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE->m_iID) && OLDWORKSPACE->getWindows() == 0 && *PCLOSEONLASTSPECIAL) { if (const auto PMONITOR = OLDWORKSPACE->m_pMonitor.lock(); PMONITOR) PMONITOR->setSpecialWorkspace(nullptr); @@ -563,6 +560,15 @@ void CWindow::onMap() { *m_fBorderAngleAnimationProgress = 1.f; } + m_vRealSize->setCallbackOnBegin( + [this](auto) { + if (!m_bIsMapped || isX11OverrideRedirect()) + return; + + sendWindowSize(); + }, + false); + m_fMovingFromWorkspaceAlpha->setValueAndWarp(1.F); g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf); @@ -1315,7 +1321,6 @@ void CWindow::clampWindowSize(const std::optional minSize, const std:: *m_vRealPosition = m_vRealPosition->goal() + DELTA / 2.0; *m_vRealSize = NEWSIZE; - sendWindowSize(NEWSIZE); } bool CWindow::isFullscreen() { @@ -1539,7 +1544,7 @@ void CWindow::onX11Configure(CBox box) { g_pHyprRenderer->damageWindow(m_pSelf.lock()); if (!m_bIsFloating || isFullscreen() || g_pInputManager->currentlyDraggedWindow == m_pSelf) { - sendWindowSize(m_vRealSize->goal(), true); + sendWindowSize(true); g_pInputManager->refocus(); g_pHyprRenderer->damageWindow(m_pSelf.lock()); return; @@ -1566,8 +1571,6 @@ void CWindow::onX11Configure(CBox box) { m_vPosition = m_vRealPosition->goal(); m_vSize = m_vRealSize->goal(); - sendWindowSize(box.size(), true); - m_vPendingReportedSize = box.size(); m_vReportedSize = box.size(); @@ -1697,15 +1700,16 @@ Vector2D CWindow::requestedMaxSize() { return maxSize; } -void CWindow::sendWindowSize(Vector2D size, bool force, std::optional overridePos) { +void CWindow::sendWindowSize(bool force) { static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); const auto PMONITOR = m_pMonitor.lock(); - size = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + Debug::log(TRACE, "sendWindowSize: window:{:x},title:{} with real pos {}, real size {} (force: {})", (uintptr_t)this, this->m_szTitle, m_vRealPosition->goal(), + m_vRealSize->goal(), force); - // calculate pos // TODO: this should be decoupled from setWindowSize IMO - Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal()); + Vector2D windowPos = m_vRealPosition->goal(); + Vector2D size = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); if (m_bIsX11 && PMONITOR) { windowPos = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 8444a113..9a4a36c2 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -471,7 +471,7 @@ class CWindow { bool isModal(); Vector2D requestedMinSize(); Vector2D requestedMaxSize(); - void sendWindowSize(Vector2D size, bool force = false, std::optional overridePos = std::nullopt); + void sendWindowSize(bool force = false); NContentType::eContentType getContentType(); void setContentType(NContentType::eContentType contentType); diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 8dbf30b7..7f8e7fc9 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -624,7 +624,7 @@ void CWorkspace::forceReportSizesToWindows() { if (w->m_pWorkspace != m_pSelf || !w->m_bIsMapped || w->isHidden()) continue; - w->sendWindowSize(w->m_vRealSize->goal(), true); + w->sendWindowSize(true); } } diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index d96bb332..399894f9 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -688,13 +688,6 @@ void Events::listener_mapWindow(void* owner, void* data) { if (PMONITOR && PWINDOW->isX11OverrideRedirect()) PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale; - - // Fix some X11 popups being invisible / having incorrect size on open. - // What the ACTUAL FUCK is going on?????? I HATE X11 - if (!PWINDOW->isX11OverrideRedirect() && PWINDOW->m_bIsX11 && PWINDOW->m_bIsFloating) { - PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true, PWINDOW->m_vRealPosition->goal() - Vector2D{1, 1}); - PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true); - } } void Events::listener_unmapWindow(void* owner, void* data) { @@ -964,7 +957,7 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) { PWINDOW->setHidden(true); if (PWINDOW->isFullscreen() || !PWINDOW->m_bIsFloating) { - PWINDOW->sendWindowSize(PWINDOW->m_vRealSize->goal(), true); + PWINDOW->sendWindowSize(true); g_pHyprRenderer->damageWindow(PWINDOW); return; } diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 8aaafaa3..ecd7abea 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -198,16 +198,12 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for *PWINDOW->m_vRealPosition = wb.pos(); *PWINDOW->m_vRealSize = wb.size(); - - PWINDOW->sendWindowSize(wb.size()); } else { CBox wb = {calcPos, calcSize}; wb.round(); // avoid rounding mess *PWINDOW->m_vRealSize = wb.size(); *PWINDOW->m_vRealPosition = wb.pos(); - - PWINDOW->sendWindowSize(wb.size()); } if (force) { diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 9a0ba6ee..e84ffb21 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -176,11 +176,9 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) { pWindow->m_vRealSize->warp(); } - if (!pWindow->isX11OverrideRedirect()) { - pWindow->sendWindowSize(pWindow->m_vRealSize->goal()); - + if (!pWindow->isX11OverrideRedirect()) g_pCompositor->changeWindowZOrder(pWindow, true); - } else { + else { pWindow->m_vPendingReportedSize = pWindow->m_vRealSize->goal(); pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize; } @@ -362,9 +360,6 @@ void IHyprLayout::onEndDragWindow() { DRAGGINGWINDOW->m_vLastFloatingSize = m_vDraggingWindowOriginalFloatSize; DRAGGINGWINDOW->m_bDraggingTiled = false; - if (pWindow->m_bIsFloating) - DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); // match the size of the window - static auto USECURRPOS = CConfigValue("group:insert_after_current"); (*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW); pWindow->setGroupCurrent(DRAGGINGWINDOW); @@ -606,10 +601,11 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { if (*PANIMATEMOUSE) *DRAGGINGWINDOW->m_vRealPosition = wb.pos(); - else + else { DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos()); + DRAGGINGWINDOW->sendWindowSize(); + } - DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); } else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) { if (DRAGGINGWINDOW->m_bIsFloating) { @@ -679,9 +675,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) { } else { DRAGGINGWINDOW->m_vRealSize->setValueAndWarp(wb.size()); DRAGGINGWINDOW->m_vRealPosition->setValueAndWarp(wb.pos()); + DRAGGINGWINDOW->sendWindowSize(); } - - DRAGGINGWINDOW->sendWindowSize(DRAGGINGWINDOW->m_vRealSize->goal()); } else { resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW); } @@ -787,7 +782,6 @@ void IHyprLayout::changeWindowFloatingMode(PHLWINDOW pWindow) { g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); pWindow->updateToplevel(); - pWindow->sendWindowSize(pWindow->m_vRealSize->goal()); g_pHyprRenderer->damageWindow(pWindow); } diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index dc301bfa..a429843f 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -678,16 +678,12 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { *PWINDOW->m_vRealPosition = wb.pos(); *PWINDOW->m_vRealSize = wb.size(); - - PWINDOW->sendWindowSize(wb.size()); } else { CBox wb = {calcPos, calcSize}; wb.round(); // avoid rounding mess *PWINDOW->m_vRealPosition = wb.pos(); *PWINDOW->m_vRealSize = wb.size(); - - PWINDOW->sendWindowSize(wb.size()); } if (m_bForceWarps && !*PANIMATE) { diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 2d6b2cb8..8daa6838 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1908,7 +1908,6 @@ SDispatchResult CKeybindManager::workspaceOpt(std::string args) { if (PWORKSPACE->m_bDefaultFloating) { w->m_vRealPosition->setValueAndWarp(SAVEDPOS); w->m_vRealSize->setValueAndWarp(SAVEDSIZE); - w->sendWindowSize(SAVEDSIZE); *w->m_vRealSize = w->m_vRealSize->value() + Vector2D(4, 4); *w->m_vRealPosition = w->m_vRealPosition->value() - Vector2D(2, 2); } diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index a5506329..63b14962 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -55,7 +55,7 @@ void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { if (pWindow->m_bIsX11) { if (activate) { - pWindow->sendWindowSize(pWindow->m_vRealSize->value(), true); // update xwayland output pos + pWindow->sendWindowSize(true); // update xwayland output pos pWindow->m_pXWaylandSurface->setMinimized(false); if (!pWindow->isX11OverrideRedirect()) diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 1a64b024..32422e14 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -456,9 +456,6 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, PHLWIND pDraggedWindow->m_bIsFloating = pWindowInsertAfter->m_bIsFloating; // match the floating state of the window - if (pWindowInsertAfter->m_bIsFloating) - pDraggedWindow->sendWindowSize(pWindowInsertAfter->m_vRealSize->goal()); // match the size of the window - pWindowInsertAfter->insertWindowToGroup(pDraggedWindow); if (WINDOWINDEX == -1) From 30b49c75bf04ceffc9fb1652a4d02e4eebacc24c Mon Sep 17 00:00:00 2001 From: vaxerski Date: Thu, 6 Feb 2025 12:13:35 +0000 Subject: [PATCH 0240/1444] popup: improve ::at() behavior --- src/desktop/Popup.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 4accb58f..82767ead 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -347,18 +347,19 @@ WP CPopup::at(const Vector2D& globalCoords, bool allowsInput) { continue; if (!allowsInput) { - const Vector2D offset = - p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{}; - const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size(); + const bool HASSURFACE = p->m_pResource && p->m_pResource->surface; - const auto BOX = CBox{p->coordsGlobal() + offset, size}; + Vector2D offset = HASSURFACE ? p->m_pResource->surface->current.geometry.pos() : Vector2D{}; + Vector2D size = HASSURFACE ? p->m_pResource->surface->current.geometry.size() : p->size(); + + if (size == Vector2D{}) + size = p->size(); + + const auto BOX = CBox{p->coordsGlobal() + offset, size}; if (BOX.containsPoint(globalCoords)) return p; } else { - const Vector2D offset = - p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{}; - const auto REGION = - CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset); + const auto REGION = CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal()); if (REGION.containsPoint(globalCoords)) return p; } From acbcf0cf115d55ef80a75ded3223a9e098f77541 Mon Sep 17 00:00:00 2001 From: WhySoBad <49595640+WhySoBad@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:42:20 +0100 Subject: [PATCH 0241/1444] toplevelexport: fix transformed origin for shm buffers (#9343) * toplevelexport: fix transformed origin for shm buffers * toplevelexport: fix style nits --- src/protocols/ToplevelExport.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 8b835b50..a9009aa4 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -11,6 +11,7 @@ #include "../render/Renderer.hpp" #include +#include CToplevelExportClient::CToplevelExportClient(SP resource_) : resource(resource_) { if UNLIKELY (!good()) @@ -289,7 +290,29 @@ bool CToplevelExportFrame::copyShm(timespec* now) { glPixelStorei(GL_PACK_ALIGNMENT, 1); auto glFormat = PFORMAT->flipRB ? GL_BGRA_EXT : GL_RGBA; - glReadPixels(0, 0, box.width, box.height, glFormat, PFORMAT->glType, pixelData); + + auto origin = Vector2D(0, 0); + switch (PMONITOR->transform) { + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + case WL_OUTPUT_TRANSFORM_90: { + origin.y = PMONITOR->vecPixelSize.y - box.height; + break; + } + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + case WL_OUTPUT_TRANSFORM_180: { + origin.x = PMONITOR->vecPixelSize.x - box.width; + origin.y = PMONITOR->vecPixelSize.y - box.height; + break; + } + case WL_OUTPUT_TRANSFORM_FLIPPED: + case WL_OUTPUT_TRANSFORM_270: { + origin.x = PMONITOR->vecPixelSize.x - box.width; + break; + } + default: break; + } + + glReadPixels(origin.x, origin.y, box.width, box.height, glFormat, PFORMAT->glType, pixelData); if (overlayCursor) { g_pPointerManager->unlockSoftwareForMonitor(PMONITOR->self.lock()); From 54441e0c4e51dd182f78876c014446d5d0359ba8 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 6 Feb 2025 17:45:25 +0000 Subject: [PATCH 0242/1444] renderer: fix fade out on silent moves to special --- src/render/Renderer.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 0fcda827..6f0bbe44 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -379,7 +379,10 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo if (w->m_bIsFloating) continue; // floating are in the second pass - if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) + // some things may force us to ignore the special/not special disparity + const bool IGNORE_SPECIAL_CHECK = w->m_iMonitorMovedFrom != -1 && (w->m_pWorkspace && !w->m_pWorkspace->isVisible()); + + if (!IGNORE_SPECIAL_CHECK && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; // render active window after all others of this pass @@ -390,11 +393,14 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo // render the bad boy renderWindow(w.lock(), pMonitor, time, true, RENDER_PASS_MAIN); + w.reset(); } if (lastWindow) renderWindow(lastWindow, pMonitor, time, true, RENDER_PASS_MAIN); + lastWindow.reset(); + // Non-floating popup for (auto& w : windows) { if (!w) @@ -403,7 +409,10 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo if (w->m_bIsFloating) continue; // floating are in the second pass - if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) + // some things may force us to ignore the special/not special disparity + const bool IGNORE_SPECIAL_CHECK = w->m_iMonitorMovedFrom != -1 && (w->m_pWorkspace && !w->m_pWorkspace->isVisible()); + + if (!IGNORE_SPECIAL_CHECK && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; // render the bad boy @@ -419,7 +428,10 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo if (!w->m_bIsFloating || w->m_bPinned) continue; - if (pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) + // some things may force us to ignore the special/not special disparity + const bool IGNORE_SPECIAL_CHECK = w->m_iMonitorMovedFrom != -1 && (w->m_pWorkspace && !w->m_pWorkspace->isVisible()); + + if (!IGNORE_SPECIAL_CHECK && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) continue; if (pWorkspace->m_bIsSpecialWorkspace && w->m_pMonitor != pWorkspace->m_pMonitor) From a724332eb82c33308a8cb6127172f128e3afe14c Mon Sep 17 00:00:00 2001 From: Paul Cross <3613973+kreejzak@users.noreply.github.com> Date: Sat, 8 Feb 2025 01:45:13 +0100 Subject: [PATCH 0243/1444] desktop: add ability to target pinned windows in workspace rules (#9344) * desktop: add ability to target pinned windows in workspace rules * desktop: add ability to target pinned windows in workspace rules * fix formating --- src/desktop/Workspace.cpp | 21 +++++++++++++++++---- src/desktop/Workspace.hpp | 4 ++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index 7f8e7fc9..f2c22195 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -261,6 +261,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { // n - named: n[true] or n[s:string] or n[e:string] // m - monitor: m[monitor_selector] // w - windowCount: w[1-4] or w[1], optional flag t or f for tiled or floating and + // flag p to count only pinned windows, e.g. w[p1-2], w[pg4] // flag g to count groups instead of windows, e.g. w[t1-2], w[fg4] // flag v will count only visible windows // f - fullscreen state : f[-1], f[0], f[1], or f[2] for different fullscreen states @@ -370,6 +371,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { prop = prop.substr(2, prop.length() - 3); int wantsOnlyTiled = -1; + int wantsOnlyPinned = false; bool wantsCountGroup = false; bool wantsCountVisible = false; @@ -381,6 +383,9 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { } else if (flag == 'f' && wantsOnlyTiled == -1) { wantsOnlyTiled = 0; flagCount++; + } else if (flag == 'p' && !wantsOnlyPinned) { + wantsOnlyPinned = true; + flagCount++; } else if (flag == 'g' && !wantsCountGroup) { wantsCountGroup = true; flagCount++; @@ -411,9 +416,11 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { int count; if (wantsCountGroup) count = getGroups(wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), + wantsOnlyPinned ? std::optional(wantsOnlyPinned) : std::nullopt, wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); else count = getWindows(wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), + wantsOnlyPinned ? std::optional(wantsOnlyPinned) : std::nullopt, wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); if (count != from) @@ -444,10 +451,12 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { WORKSPACEID count; if (wantsCountGroup) - count = getGroups(wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), - wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); + count = + getGroups(wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), + wantsOnlyPinned ? std::optional(wantsOnlyPinned) : std::nullopt, wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); else count = getWindows(wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled), + wantsOnlyPinned ? std::optional(wantsOnlyPinned) : std::nullopt, wantsCountVisible ? std::optional(wantsCountVisible) : std::nullopt); if (std::clamp(count, from, to) != count) @@ -535,13 +544,15 @@ bool CWorkspace::isVisibleNotCovered() { return PMONITOR->activeWorkspace->m_iID == m_iID; } -int CWorkspace::getWindows(std::optional onlyTiled, std::optional onlyVisible) { +int CWorkspace::getWindows(std::optional onlyTiled, std::optional onlyPinned, std::optional onlyVisible) { int no = 0; for (auto const& w : g_pCompositor->m_vWindows) { if (w->workspaceID() != m_iID || !w->m_bIsMapped) continue; if (onlyTiled.has_value() && w->m_bIsFloating == onlyTiled.value()) continue; + if (onlyPinned.has_value() && w->m_bPinned != onlyPinned.value()) + continue; if (onlyVisible.has_value() && w->isHidden() == onlyVisible.value()) continue; no++; @@ -550,7 +561,7 @@ int CWorkspace::getWindows(std::optional onlyTiled, std::optional on return no; } -int CWorkspace::getGroups(std::optional onlyTiled, std::optional onlyVisible) { +int CWorkspace::getGroups(std::optional onlyTiled, std::optional onlyPinned, std::optional onlyVisible) { int no = 0; for (auto const& w : g_pCompositor->m_vWindows) { if (w->workspaceID() != m_iID || !w->m_bIsMapped) @@ -559,6 +570,8 @@ int CWorkspace::getGroups(std::optional onlyTiled, std::optional onl continue; if (onlyTiled.has_value() && w->m_bIsFloating == onlyTiled.value()) continue; + if (onlyPinned.has_value() && w->m_bPinned != onlyPinned.value()) + continue; if (onlyVisible.has_value() && w->isHidden() == onlyVisible.value()) continue; no++; diff --git a/src/desktop/Workspace.hpp b/src/desktop/Workspace.hpp index e9859d4f..12dbe328 100644 --- a/src/desktop/Workspace.hpp +++ b/src/desktop/Workspace.hpp @@ -72,8 +72,8 @@ class CWorkspace { SWorkspaceIDName getPrevWorkspaceIDName() const; void updateWindowDecos(); void updateWindowData(); - int getWindows(std::optional onlyTiled = {}, std::optional onlyVisible = {}); - int getGroups(std::optional onlyTiled = {}, std::optional onlyVisible = {}); + int getWindows(std::optional onlyTiled = {}, std::optional onlyPinned = {}, std::optional onlyVisible = {}); + int getGroups(std::optional onlyTiled = {}, std::optional onlyPinned = {}, std::optional onlyVisible = {}); bool hasUrgentWindow(); PHLWINDOW getFirstWindow(); PHLWINDOW getTopLeftWindow(); From f7fcbe32c9f66bcfc86853a5cda95edcf481f573 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 8 Feb 2025 01:46:26 +0100 Subject: [PATCH 0244/1444] renderer: various fixes towards improving gpu calls robustness (#9188) ensure framebuffer textures are detached and deleted, avoid leaving framebuffers bound when not needed * render: avoid calling glDeleteProgram on no program its safe to do so but it adds a bunch of unnecessery lines in apitrace when tracing. if guard it and return early. * opengl: ensure texture and buffers are unbound ensure bound buffers are unbound after use, also detach textures from framebuffer before deleting it otherwise it will become dangling and essentially leak. --- src/protocols/Screencopy.cpp | 6 ++++ src/protocols/ToplevelExport.cpp | 6 ++++ src/render/Framebuffer.cpp | 56 +++++++++++++++++--------------- src/render/Framebuffer.hpp | 3 +- src/render/OpenGL.hpp | 2 -- src/render/Renderbuffer.cpp | 8 ++--- src/render/Shader.cpp | 5 ++- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index e086cc76..aae5caf1 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -289,6 +289,12 @@ bool CScreencopyFrame::copyShm() { g_pHyprOpenGL->m_RenderData.pMonitor.reset(); +#ifndef GLES2 + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +#else + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif + LOGM(TRACE, "Copied frame via shm"); return true; diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index a9009aa4..fb0bd9c7 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -319,6 +319,12 @@ bool CToplevelExportFrame::copyShm(timespec* now) { g_pPointerManager->damageCursor(PMONITOR->self.lock()); } + outFB.unbind(); + +#ifndef GLES2 + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +#endif + return true; } diff --git a/src/render/Framebuffer.cpp b/src/render/Framebuffer.cpp index 93f8fe7f..6905eb36 100644 --- a/src/render/Framebuffer.cpp +++ b/src/render/Framebuffer.cpp @@ -12,29 +12,26 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) { uint32_t glFormat = NFormatUtils::drmFormatToGL(drmFormat); uint32_t glType = NFormatUtils::glFormatToType(glFormat); - if (!m_cTex) + if (!m_cTex) { m_cTex = makeShared(); - - if (!m_iFbAllocated) { - firstAlloc = true; - glGenFramebuffers(1, &m_iFb); - m_iFbAllocated = true; - } - - if (m_cTex->m_iTexID == 0) { - firstAlloc = true; m_cTex->allocate(); glBindTexture(GL_TEXTURE_2D, m_cTex->m_iTexID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + firstAlloc = true; + } + + if (!m_iFbAllocated) { + glGenFramebuffers(1, &m_iFb); + m_iFbAllocated = true; + firstAlloc = true; } if (firstAlloc || m_vSize != Vector2D(w, h)) { glBindTexture(GL_TEXTURE_2D, m_cTex->m_iTexID); glTexImage2D(GL_TEXTURE_2D, 0, glFormat, w, h, 0, GL_RGBA, glType, nullptr); - glBindFramebuffer(GL_FRAMEBUFFER, m_iFb); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_cTex->m_iTexID, 0); @@ -43,9 +40,6 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) { if (m_pStencilTex) { glBindTexture(GL_TEXTURE_2D, m_pStencilTex->m_iTexID); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); - - glBindFramebuffer(GL_FRAMEBUFFER, m_iFb); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_pStencilTex->m_iTexID, 0); } #endif @@ -57,8 +51,7 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) { } glBindTexture(GL_TEXTURE_2D, 0); - if (g_pHyprOpenGL) - glBindFramebuffer(GL_FRAMEBUFFER, g_pHyprOpenGL->m_iCurrentOutputFb); + glBindFramebuffer(GL_FRAMEBUFFER, 0); m_vSize = Vector2D(w, h); @@ -80,7 +73,7 @@ void CFramebuffer::addStencil(SP tex) { RASSERT((status == GL_FRAMEBUFFER_COMPLETE), "Failed adding a stencil to fbo!", status); glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_FRAMEBUFFER, g_pHyprOpenGL->m_iCurrentOutputFb); + glBindFramebuffer(GL_FRAMEBUFFER, 0); #endif } @@ -90,25 +83,36 @@ void CFramebuffer::bind() { #else glBindFramebuffer(GL_FRAMEBUFFER, m_iFb); #endif + if (g_pHyprOpenGL) glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y); else glViewport(0, 0, m_vSize.x, m_vSize.y); } +void CFramebuffer::unbind() { +#ifndef GLES2 + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +#else + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif +} + void CFramebuffer::release() { - if (!m_iFbAllocated && !m_cTex) - return; + if (m_iFbAllocated) { + glBindFramebuffer(GL_FRAMEBUFFER, m_iFb); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); - Debug::log(TRACE, "fb {} released", m_iFb); - - if (m_iFbAllocated) glDeleteFramebuffers(1, &m_iFb); + m_iFbAllocated = false; + m_iFb = 0; + } - m_cTex.reset(); - m_iFbAllocated = false; - m_vSize = Vector2D(); - m_iFb = 0; + if (m_cTex) + m_cTex.reset(); + + m_vSize = Vector2D(); } CFramebuffer::~CFramebuffer() { diff --git a/src/render/Framebuffer.hpp b/src/render/Framebuffer.hpp index 84dfeef1..092e548e 100644 --- a/src/render/Framebuffer.hpp +++ b/src/render/Framebuffer.hpp @@ -11,6 +11,7 @@ class CFramebuffer { bool alloc(int w, int h, uint32_t format = GL_RGBA); void addStencil(SP tex); void bind(); + void unbind(); void release(); void reset(); bool isAllocated(); @@ -28,4 +29,4 @@ class CFramebuffer { SP m_pStencilTex; friend class CRenderbuffer; -}; \ No newline at end of file +}; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 7b7b7e6f..cf1d2549 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -233,8 +233,6 @@ class CHyprOpenGLImpl { SCurrentRenderData m_RenderData; - GLint m_iCurrentOutputFb = 0; - Hyprutils::OS::CFileDescriptor m_iGBMFD; gbm_device* m_pGbmDevice = nullptr; EGLContext m_pEglContext = nullptr; diff --git a/src/render/Renderbuffer.cpp b/src/render/Renderbuffer.cpp index 887f31a9..1ea9f785 100644 --- a/src/render/Renderbuffer.cpp +++ b/src/render/Renderbuffer.cpp @@ -46,7 +46,7 @@ CRenderbuffer::CRenderbuffer(SP buffer, uint32_t format) : return; } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + m_sFramebuffer.unbind(); listeners.destroyBuffer = buffer->events.destroy.registerListener([this](std::any d) { g_pHyprRenderer->onRenderbufferDestroy(this); }); @@ -68,11 +68,7 @@ void CRenderbuffer::bindFB() { void CRenderbuffer::unbind() { glBindRenderbuffer(GL_RENDERBUFFER, 0); -#ifndef GLES2 - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -#else - glBindFramebuffer(GL_FRAMEBUFFER, 0); -#endif + m_sFramebuffer.unbind(); } CFramebuffer* CRenderbuffer::getFB() { diff --git a/src/render/Shader.cpp b/src/render/Shader.cpp index b494d79d..984d8ce3 100644 --- a/src/render/Shader.cpp +++ b/src/render/Shader.cpp @@ -17,7 +17,10 @@ CShader::~CShader() { } void CShader::destroy() { + if (program == 0) + return; + glDeleteProgram(program); program = 0; -} \ No newline at end of file +} From feb8ad48f0153a15b96356f280dbd04849db0e04 Mon Sep 17 00:00:00 2001 From: nyx Date: Sat, 8 Feb 2025 09:05:44 -0500 Subject: [PATCH 0245/1444] groups: deactivate unfocused windows in groups (#9354) --- src/Compositor.cpp | 3 +++ src/desktop/Window.cpp | 16 ++++++++++++++++ src/desktop/Window.hpp | 1 + 3 files changed, 20 insertions(+) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index e460bbca..aebb0ac1 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1189,6 +1189,9 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface if (*PFOLLOWMOUSE == 0) g_pInputManager->sendMotionEventsToFocused(); + + if (pWindow->m_sGroupData.pNextWindow) + pWindow->deactivateGroupMembers(); } void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindowOwner) { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index b0d7b58c..7c0cb741 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1748,3 +1748,19 @@ void CWindow::setContentType(NContentType::eContentType contentType) { Debug::log(INFO, "ContentType for window {}", (int)contentType); m_pWLSurface->resource()->contentType->value = contentType; } + +void CWindow::deactivateGroupMembers() { + auto curr = getGroupHead(); + while (curr) { + if (curr != m_pSelf.lock()) { + if (curr->m_bIsX11) + curr->m_pXWaylandSurface->activate(false); + else if (curr->m_pXDGSurface && curr->m_pXDGSurface->toplevel) + curr->m_pXDGSurface->toplevel->setActive(false); + } + + curr = curr->m_sGroupData.pNextWindow.lock(); + if (curr == getGroupHead()) + break; + } +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 9a4a36c2..171a15f4 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -474,6 +474,7 @@ class CWindow { void sendWindowSize(bool force = false); NContentType::eContentType getContentType(); void setContentType(NContentType::eContentType contentType); + void deactivateGroupMembers(); CBox getWindowMainSurfaceBox() const { return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y}; From 8e10ddb592977ef2e1836e75b0e5550ba8fb56f0 Mon Sep 17 00:00:00 2001 From: Honkazel <169346573+Honkazel@users.noreply.github.com> Date: Sun, 9 Feb 2025 02:00:55 +0500 Subject: [PATCH 0246/1444] datadevice: fix wrong param (#9370) Reason: look at the setReceive parameters and also at the next line(tries to narrow) --- src/protocols/core/DataDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocols/core/DataDevice.cpp b/src/protocols/core/DataDevice.cpp index 0931608a..25117265 100644 --- a/src/protocols/core/DataDevice.cpp +++ b/src/protocols/core/DataDevice.cpp @@ -39,7 +39,7 @@ CWLDataOfferResource::CWLDataOfferResource(SP resource_, SPsetReceive([this](CWlDataOffer* r, const char* mime, uint32_t fd) { + resource->setReceive([this](CWlDataOffer* r, const char* mime, int fd) { CFileDescriptor sendFd{fd}; if (!source) { LOGM(WARN, "Possible bug: Receive on an offer w/o a source"); From 56f6f61596a547cdcdfb7aa7c3550e380b487ee3 Mon Sep 17 00:00:00 2001 From: clamydo <13063485+clamydo@users.noreply.github.com> Date: Sun, 9 Feb 2025 15:30:30 +0100 Subject: [PATCH 0247/1444] tablet: take `active_area_size` into account when sending tip event (#9325) * fixes #9322, take `active_area_size` into account when sending tip event * check if `relative_input` is set As suggested by @y47s5s68tq870r7tc1xpp755pabopg * refactoring active area in own function to keep it DRY * coding style * making transformation static --------- Co-authored-by: clamydo --- src/managers/input/Tablets.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp index 0952a7d4..e1a2f2aa 100644 --- a/src/managers/input/Tablets.cpp +++ b/src/managers/input/Tablets.cpp @@ -88,6 +88,20 @@ static void refocusTablet(SP tab, SP tool, bool motion = f PROTO::tablet->motion(tool, local); } +static Vector2D transformToActiveRegion(const Vector2D pos, const CBox activeArea) { + auto newPos = pos; + + //Calculate transformations if active area is set + if (!activeArea.empty()) { + if (!std::isnan(pos.x)) + newPos.x = (pos.x - activeArea.x) / (activeArea.w - activeArea.x); + if (!std::isnan(pos.y)) + newPos.y = (pos.y - activeArea.y) / (activeArea.h - activeArea.y); + } + + return newPos; +} + void CInputManager::onTabletAxis(CTablet::SAxisEvent e) { const auto PTAB = e.tablet; const auto PTOOL = ensureTabletToolPresent(e.tool); @@ -113,16 +127,9 @@ void CInputManager::onTabletAxis(CTablet::SAxisEvent e) { if (PTAB->relativeInput) g_pPointerManager->move(delta); - else { - //Calculate transformations if active area is set - if (!PTAB->activeArea.empty()) { - if (!std::isnan(x)) - x = (x - PTAB->activeArea.x) / (PTAB->activeArea.w - PTAB->activeArea.x); - if (!std::isnan(y)) - y = (y - PTAB->activeArea.y) / (PTAB->activeArea.h - PTAB->activeArea.y); - } - g_pPointerManager->warpAbsolute({x, y}, PTAB); - } + else + g_pPointerManager->warpAbsolute(transformToActiveRegion({x, y}, PTAB->activeArea), PTAB); + break; } } @@ -160,7 +167,12 @@ void CInputManager::onTabletTip(CTablet::STipEvent e) { const auto PTAB = e.tablet; const auto PTOOL = ensureTabletToolPresent(e.tool); const auto POS = e.tip; - g_pPointerManager->warpAbsolute(POS, PTAB); + + if (PTAB->relativeInput) + g_pPointerManager->move({0, 0}); + else + g_pPointerManager->warpAbsolute(transformToActiveRegion(POS, PTAB->activeArea), PTAB); + refocusTablet(PTAB, PTOOL, true); if (e.in) From 1f97643e830d513cafc2057860bbefa5cc01a0ee Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 9 Feb 2025 17:38:20 +0000 Subject: [PATCH 0248/1444] core: add mallopt to modify trim threshold --- src/Compositor.cpp | 14 ++++++++++++++ src/Compositor.hpp | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index aebb0ac1..88a2530b 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -69,6 +69,8 @@ #include #include #include +#include +#include using namespace Hyprutils::String; using namespace Aquamarine; @@ -162,10 +164,22 @@ void CCompositor::restoreNofile() { Debug::log(ERR, "Failed restoring NOFILE limits"); } +void CCompositor::setMallocThreshold() { +#ifdef M_TRIM_THRESHOLD + // The default is 128 pages, + // which is very large and can lead to a lot of memory used for no reason + // because trimming hasn't happened + static const int PAGESIZE = sysconf(_SC_PAGESIZE); + mallopt(M_TRIM_THRESHOLD, 6 * PAGESIZE); +#endif +} + CCompositor::CCompositor(bool onlyConfig) : m_bOnlyConfigVerification(onlyConfig), m_iHyprlandPID(getpid()) { if (onlyConfig) return; + setMallocThreshold(); + m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr"; if (m_szHyprTempDataRoot.starts_with("/hypr")) { diff --git a/src/Compositor.hpp b/src/Compositor.hpp index a57095a3..893ffadd 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -52,8 +52,6 @@ class CCompositor { void startCompositor(); void stopCompositor(); void cleanup(); - void createLockFile(); - void removeLockFile(); void bumpNofile(); void restoreNofile(); @@ -163,6 +161,9 @@ class CCompositor { void setRandomSplash(); void initManagers(eManagersInitStage stage); void prepareFallbackOutput(); + void createLockFile(); + void removeLockFile(); + void setMallocThreshold(); uint64_t m_iHyprlandPID = 0; wl_event_source* m_critSigSource = nullptr; From 3a43e7bb9a787755639838d7cb005a9d33f8c6f2 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 9 Feb 2025 17:50:54 +0000 Subject: [PATCH 0249/1444] config: default movefocus_cycles_fullscreen to false less confusing --- src/config/ConfigDescriptions.hpp | 2 +- src/config/ConfigManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 28cd29c4..8d1b73c4 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1234,7 +1234,7 @@ inline static const std::vector CONFIG_OPTIONS = { .value = "binds:movefocus_cycles_fullscreen", .description = "If enabled, when on a fullscreen window, movefocus will cycle fullscreen, if not, it will move the focus in a direction.", .type = CONFIG_OPTION_BOOL, - .data = SConfigOptionDescription::SBoolData{true}, + .data = SConfigOptionDescription::SBoolData{false}, }, SConfigOptionDescription{ .value = "binds:movefocus_cycles_groupfirst", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 3f45ddfe..f87a5e6b 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -594,7 +594,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("binds:workspace_center_on", Hyprlang::INT{1}); m_pConfig->addConfigValue("binds:focus_preferred_method", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:ignore_group_lock", Hyprlang::INT{0}); - m_pConfig->addConfigValue("binds:movefocus_cycles_fullscreen", Hyprlang::INT{1}); + m_pConfig->addConfigValue("binds:movefocus_cycles_fullscreen", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:movefocus_cycles_groupfirst", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:disable_keybind_grabbing", Hyprlang::INT{0}); m_pConfig->addConfigValue("binds:window_direction_monitor_fallback", Hyprlang::INT{1}); From f261fb6fe028a1427cfd672eee6e7d5705cd696f Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 9 Feb 2025 17:58:09 +0000 Subject: [PATCH 0250/1444] groupbar: fix groupbar missing when indicator_height is <= 0 ref #9291 #9372 --- .../decorations/CHyprGroupBarDecoration.cpp | 188 +++++++++--------- 1 file changed, 95 insertions(+), 93 deletions(-) diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index 32422e14..4e430bef 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -99,7 +99,11 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { // get how many bars we will draw int barsToDraw = m_dwGroupMembers.size(); - static auto PENABLED = CConfigValue("group:groupbar:enabled"); + static auto PENABLED = CConfigValue("group:groupbar:enabled"); + + if (!*PENABLED || !m_pWindow->m_sWindowData.decorate.valueOrDefault()) + return; + static auto PRENDERTITLES = CConfigValue("group:groupbar:render_titles"); static auto PTITLEFONTSIZE = CConfigValue("group:groupbar:font_size"); static auto PHEIGHT = CConfigValue("group:groupbar:height"); @@ -110,14 +114,19 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { static auto PGRADIENTROUNDING = CConfigValue("group:groupbar:gradient_rounding"); static auto PGRADIENTROUNDINGONLYEDGES = CConfigValue("group:groupbar:gradient_round_only_edges"); static auto PROUNDONLYEDGES = CConfigValue("group:groupbar:round_only_edges"); + static auto PGROUPCOLACTIVE = CConfigValue("group:groupbar:col.active"); + static auto PGROUPCOLINACTIVE = CConfigValue("group:groupbar:col.inactive"); + static auto PGROUPCOLACTIVELOCKED = CConfigValue("group:groupbar:col.locked_active"); + static auto PGROUPCOLINACTIVELOCKED = CConfigValue("group:groupbar:col.locked_inactive"); + auto* const GROUPCOLACTIVE = (CGradientValueData*)(PGROUPCOLACTIVE.ptr())->getData(); + auto* const GROUPCOLINACTIVE = (CGradientValueData*)(PGROUPCOLINACTIVE.ptr())->getData(); + auto* const GROUPCOLACTIVELOCKED = (CGradientValueData*)(PGROUPCOLACTIVELOCKED.ptr())->getData(); + auto* const GROUPCOLINACTIVELOCKED = (CGradientValueData*)(PGROUPCOLINACTIVELOCKED.ptr())->getData(); - if (!*PENABLED || !m_pWindow->m_sWindowData.decorate.valueOrDefault()) - return; + const auto ASSIGNEDBOX = assignedBoxGlobal(); - const auto ASSIGNEDBOX = assignedBoxGlobal(); - - const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); - m_fBarWidth = *PSTACKED ? ASSIGNEDBOX.w : (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw; + const auto ONEBARHEIGHT = BAR_PADDING_OUTER_VERT + *PINDICATORHEIGHT + (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0); + m_fBarWidth = *PSTACKED ? ASSIGNEDBOX.w : (ASSIGNEDBOX.w - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw; m_fBarHeight = *PSTACKED ? ((ASSIGNEDBOX.h - 2 - BAR_PADDING_OUTER_VERT) - BAR_PADDING_OUTER_VERT * (barsToDraw)) / barsToDraw : ASSIGNEDBOX.h - BAR_PADDING_OUTER_VERT; const auto DESIREDHEIGHT = *PSTACKED ? (ONEBARHEIGHT * m_dwGroupMembers.size()) + 2 + BAR_PADDING_OUTER_VERT : BAR_PADDING_OUTER_VERT * 2L + ONEBARHEIGHT; @@ -134,116 +143,109 @@ void CHyprGroupBarDecoration::draw(PHLMONITOR pMonitor, float const& a) { ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - *PINDICATORHEIGHT - BAR_PADDING_OUTER_VERT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth, *PINDICATORHEIGHT}; - if (rect.width <= 0 || rect.height <= 0) - break; - rect.scale(pMonitor->scale); - static auto PGROUPCOLACTIVE = CConfigValue("group:groupbar:col.active"); - static auto PGROUPCOLINACTIVE = CConfigValue("group:groupbar:col.inactive"); - static auto PGROUPCOLACTIVELOCKED = CConfigValue("group:groupbar:col.locked_active"); - static auto PGROUPCOLINACTIVELOCKED = CConfigValue("group:groupbar:col.locked_inactive"); - auto* const GROUPCOLACTIVE = (CGradientValueData*)(PGROUPCOLACTIVE.ptr())->getData(); - auto* const GROUPCOLINACTIVE = (CGradientValueData*)(PGROUPCOLINACTIVE.ptr())->getData(); - auto* const GROUPCOLACTIVELOCKED = (CGradientValueData*)(PGROUPCOLACTIVELOCKED.ptr())->getData(); - auto* const GROUPCOLINACTIVELOCKED = (CGradientValueData*)(PGROUPCOLINACTIVELOCKED.ptr())->getData(); - const bool GROUPLOCKED = m_pWindow->getGroupHead()->m_sGroupData.locked || g_pKeybindManager->m_bGroupsLocked; const auto* const PCOLACTIVE = GROUPLOCKED ? GROUPCOLACTIVELOCKED : GROUPCOLACTIVE; const auto* const PCOLINACTIVE = GROUPLOCKED ? GROUPCOLINACTIVELOCKED : GROUPCOLINACTIVE; CHyprColor color = m_dwGroupMembers[WINDOWINDEX].lock() == g_pCompositor->m_pLastWindow.lock() ? PCOLACTIVE->m_vColors[0] : PCOLINACTIVE->m_vColors[0]; color.a *= a; - CRectPassElement::SRectData rectdata; - rectdata.color = color; - rectdata.box = rect; - if (*PROUNDING) { - if (*PROUNDONLYEDGES) { - static constexpr double PADDING = 20; - if (i == 0 && barsToDraw == 1) + if (!rect.empty()) { + CRectPassElement::SRectData rectdata; + rectdata.color = color; + rectdata.box = rect; + if (*PROUNDING) { + if (*PROUNDONLYEDGES) { + static constexpr double PADDING = 20; + + if (i == 0 && barsToDraw == 1) + rectdata.round = *PROUNDING; + else if (i == 0) { + double first = rect.w - (*PROUNDING * 2); + rectdata.round = *PROUNDING; + rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); + rectdata.round = 0; + rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } else if (i == barsToDraw - 1) { + double first = *PROUNDING * 2; + rectdata.round = 0; + rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); + rectdata.round = *PROUNDING; + rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } + } else rectdata.round = *PROUNDING; - else if (i == 0) { - double first = rect.w - (*PROUNDING * 2); - rectdata.round = *PROUNDING; - rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; - g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); - rectdata.round = 0; - rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; - } else if (i == barsToDraw - 1) { - double first = *PROUNDING * 2; - rectdata.round = 0; - rectdata.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; - g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); - rectdata.round = *PROUNDING; - rectdata.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; - } - } else - rectdata.round = *PROUNDING; + } + g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); } - g_pHyprRenderer->m_sRenderPass.add(makeShared(rectdata)); rect = {ASSIGNEDBOX.x + floor(xoff) - pMonitor->vecPosition.x + m_pWindow->m_vFloatingOffset.x, ASSIGNEDBOX.y + ASSIGNEDBOX.h - floor(yoff) - ONEBARHEIGHT - pMonitor->vecPosition.y + m_pWindow->m_vFloatingOffset.y, m_fBarWidth, (*PGRADIENTS || *PRENDERTITLES ? *PHEIGHT : 0)}; rect.scale(pMonitor->scale); - if (*PGRADIENTS) { - const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_pLastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) : - (GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive)); - if (GRADIENTTEX->m_iTexID) { - CTexPassElement::SRenderData data; - data.tex = GRADIENTTEX; - data.box = rect; - if (*PGRADIENTROUNDING) { - if (*PGRADIENTROUNDINGONLYEDGES) { - static constexpr double PADDING = 20; + if (!rect.empty()) { + if (*PGRADIENTS) { + const auto GRADIENTTEX = (m_dwGroupMembers[WINDOWINDEX] == g_pCompositor->m_pLastWindow ? (GROUPLOCKED ? m_tGradientLockedActive : m_tGradientActive) : + (GROUPLOCKED ? m_tGradientLockedInactive : m_tGradientInactive)); + if (GRADIENTTEX->m_iTexID) { + CTexPassElement::SRenderData data; + data.tex = GRADIENTTEX; + data.box = rect; + if (*PGRADIENTROUNDING) { + if (*PGRADIENTROUNDINGONLYEDGES) { + static constexpr double PADDING = 20; - if (i == 0 && barsToDraw == 1) + if (i == 0 && barsToDraw == 1) + data.round = *PGRADIENTROUNDING; + else if (i == 0) { + double first = rect.w - (*PGRADIENTROUNDING * 2); + data.round = *PGRADIENTROUNDING; + data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + data.round = 0; + data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } else if (i == barsToDraw - 1) { + double first = *PGRADIENTROUNDING * 2; + data.round = 0; + data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); + data.round = *PGRADIENTROUNDING; + data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; + } + } else data.round = *PGRADIENTROUNDING; - else if (i == 0) { - double first = rect.w - (*PGRADIENTROUNDING * 2); - data.round = *PGRADIENTROUNDING; - data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; - g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); - data.round = 0; - data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; - } else if (i == barsToDraw - 1) { - double first = *PGRADIENTROUNDING * 2; - data.round = 0; - data.clipBox = CBox{rect.pos() - Vector2D{PADDING, 0.F}, Vector2D{first + PADDING, rect.h}}; - g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); - data.round = *PGRADIENTROUNDING; - data.clipBox = CBox{rect.pos() + Vector2D{first, 0.F}, Vector2D{rect.w - first + PADDING, rect.h}}; - } - } else - rectdata.round = *PGRADIENTROUNDING; + } + g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } + } + + if (*PRENDERTITLES) { + CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[WINDOWINDEX]->m_szTitle); + + if (!pTitleTex) + pTitleTex = + m_sTitleTexs.titleTexs + .emplace_back(makeUnique(m_dwGroupMembers[WINDOWINDEX].lock(), + Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2L * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale)) + .get(); + rect.y += std::ceil((rect.height - pTitleTex->texSize.y) / 2.0); + rect.height = pTitleTex->texSize.y; + rect.width = pTitleTex->texSize.x; + rect.x += std::round(((m_fBarWidth * pMonitor->scale) / 2.0) - (pTitleTex->texSize.x / 2.0)); + rect.round(); + + CTexPassElement::SRenderData data; + data.tex = pTitleTex->tex; + data.box = rect; g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); } } - if (*PRENDERTITLES) { - CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[WINDOWINDEX]->m_szTitle); - - if (!pTitleTex) - pTitleTex = - m_sTitleTexs.titleTexs - .emplace_back(makeUnique(m_dwGroupMembers[WINDOWINDEX].lock(), - Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2L * BAR_TEXT_PAD) * pMonitor->scale}, pMonitor->scale)) - .get(); - rect.y += std::ceil((rect.height - pTitleTex->texSize.y) / 2.0); - rect.height = pTitleTex->texSize.y; - rect.width = pTitleTex->texSize.x; - rect.x += std::round((m_fBarWidth * pMonitor->scale) / 2.0 - (pTitleTex->texSize.x / 2.0)); - rect.round(); - - CTexPassElement::SRenderData data; - data.tex = pTitleTex->tex; - data.box = rect; - g_pHyprRenderer->m_sRenderPass.add(makeShared(data)); - } - if (*PSTACKED) yoff += ONEBARHEIGHT; else From e1179b665b307e46a57367493a85ac80f34f2ce4 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 10 Feb 2025 20:11:35 +0200 Subject: [PATCH 0251/1444] flake.lock: update --- flake.lock | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/flake.lock b/flake.lock index 7637a2c7..38f48983 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1738456976, - "narHash": "sha256-cufyHbOMnSt9V4w4OVSzNcpJ+8DwzRZRJaca2Q89KVI=", + "lastModified": 1739103745, + "narHash": "sha256-c53dcRaw0F4Os9WD05HwIRs9kTDZw4Mxe1XK4edEALo=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "257b2050790ab3b1eb389e0f8bdc400eb9510139", + "rev": "a3dda0d10ce9aa1d1dfb7a6c139ea8c2872c74bd", "type": "github" }, "original": { @@ -79,11 +79,11 @@ ] }, "locked": { - "lastModified": 1738178255, - "narHash": "sha256-+D6Nu2ewXbMTFzx/Q4jDOo+LAOUPr0cxQJg5k33daIE=", + "lastModified": 1738664950, + "narHash": "sha256-xIeGNM+iivwVHkv9tHwOqoUP5dDrtees34bbFKKMZYs=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "dcadd3398abe146d60c67e0d9ee6e27b301cae82", + "rev": "7c6d165e1eb9045a996551eb9f121b6d1b30adc3", "type": "github" }, "original": { @@ -105,11 +105,11 @@ ] }, "locked": { - "lastModified": 1738437059, - "narHash": "sha256-J+8ecqaP3zD9GHeN8Y4hUapoELSoggp0IZI8laTFt/0=", + "lastModified": 1739049071, + "narHash": "sha256-3+7TpXMrbsUXSwgr5VAKAnmkzMb6JO+Rvc9XRb5NMg4=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "5ac80e3686a4dfa55d2bd15c81a266b89594a295", + "rev": "175c6b29b6ff82100539e7c4363a35a02c74dd73", "type": "github" }, "original": { @@ -189,11 +189,11 @@ ] }, "locked": { - "lastModified": 1737981711, - "narHash": "sha256-lh6cL5D8nPplB3WovCQjLUZ7k7MViiBrMlpkfm4R7/c=", + "lastModified": 1739048983, + "narHash": "sha256-REhTcXq4qs3B3cCDtLlYDz0GZvmsBSh947Ub6pQWGTQ=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "96bf0677fa9cd13508294e3d4559dfbbc8beff73", + "rev": "3504a293c8f8db4127cb0f7cfc1a318ffb4316f8", "type": "github" }, "original": { @@ -215,11 +215,11 @@ ] }, "locked": { - "lastModified": 1737634606, - "narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=", + "lastModified": 1739048914, + "narHash": "sha256-vd5rJBTmp2w7SDgfv23Zcd84ktI5eDA7e5UBzx+pKrU=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "f41271d35cc0f370d300413d756c2677f386af9d", + "rev": "a7334904d591f38757c46fbe2ab68651877d9099", "type": "github" }, "original": { @@ -238,11 +238,11 @@ ] }, "locked": { - "lastModified": 1737978343, - "narHash": "sha256-TfFS0HCEJh63Kahrkp1h9hVDMdLU8a37Zz+IFucxyfA=", + "lastModified": 1739048933, + "narHash": "sha256-ck6MaoYvISBQKqZR+HcxXnx0wOhyCauxfVMaV5zhJxQ=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "6a8bc9d2a4451df12f5179dc0b1d2d46518a90ab", + "rev": "e4e018a2ca6f5a9c33511973454199e1c7c85499", "type": "github" }, "original": { @@ -261,11 +261,11 @@ ] }, "locked": { - "lastModified": 1735493474, - "narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=", + "lastModified": 1739049028, + "narHash": "sha256-RleJp7LYbr6s+M1xgbmhtBs+fYa3ZdIiF7+QalJ4D1g=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b", + "rev": "04146df74a8d5ec0b579657307be01f1e241125f", "type": "github" }, "original": { @@ -276,11 +276,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1738410390, - "narHash": "sha256-xvTo0Aw0+veek7hvEVLzErmJyQkEcRk6PSR4zsRQFEc=", + "lastModified": 1739020877, + "narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3a228057f5b619feb3186e986dbe76278d707b6e", + "rev": "a79cfe0ebd24952b580b1cf08cd906354996d547", "type": "github" }, "original": { From f2d43e5f2180adb81b3b7b51a7d0f39dace70b05 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Mon, 10 Feb 2025 20:17:29 +0200 Subject: [PATCH 0252/1444] nix/overlays: add wayland-protocols overlay --- nix/overlays.nix | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nix/overlays.nix b/nix/overlays.nix index b632d0b4..c5dd1bee 100644 --- a/nix/overlays.nix +++ b/nix/overlays.nix @@ -28,6 +28,7 @@ in { inputs.hyprlang.overlays.default inputs.hyprutils.overlays.default inputs.hyprwayland-scanner.overlays.default + self.overlays.wayland-protocols-bump self.overlays.udis86 # Hyprland packages themselves @@ -89,4 +90,17 @@ in { patches = []; }); }; + + # Temporary bump until https://nixpk.gs/pr-tracker.html?pr=367753 is merged. + # Expect to build the universe. + wayland-protocols-bump = final: prev: { + wayland-protocols = prev.wayland-protocols.overrideAttrs (self: super: { + version = "1.40"; + + src = prev.fetchurl { + url = "https://gitlab.freedesktop.org/wayland/${super.pname}/-/releases/${self.version}/downloads/${super.pname}-${self.version}.tar.xz"; + hash = "sha256-shcReTJHwsQnY5FDkt+p/LnjcoyktKoRCtuNkV/ABok="; + }; + }); + }; } From f83fe9986b34c53c67b113a015d54fe8c084e9bd Mon Sep 17 00:00:00 2001 From: "J. J. Ramsey" Date: Tue, 11 Feb 2025 09:58:43 -0500 Subject: [PATCH 0253/1444] protocols: add version 2 of ext-idle-notify-v1 protocol (#8959) Signed-off-by: James Ramsey Co-authored-by: James Ramsey --- protocols/meson.build | 2 +- src/managers/ProtocolManager.cpp | 2 +- src/protocols/IdleNotify.cpp | 26 ++++++++++++++++++-------- src/protocols/IdleNotify.hpp | 9 ++++++--- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/protocols/meson.build b/protocols/meson.build index 7c57470b..f0a6a7e6 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -1,6 +1,6 @@ wayland_protos = dependency( 'wayland-protocols', - version: '>=1.32', + version: '>=1.40', fallback: 'wayland-protocols', default_options: ['tests=false'], ) diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 6cd3a608..6474d661 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -147,7 +147,7 @@ CProtocolManager::CProtocolManager() { PROTO::constraints = makeUnique(&zwp_pointer_constraints_v1_interface, 1, "PointerConstraints"); PROTO::outputPower = makeUnique(&zwlr_output_power_manager_v1_interface, 1, "OutputPower"); PROTO::activation = makeUnique(&xdg_activation_v1_interface, 1, "XDGActivation"); - PROTO::idle = makeUnique(&ext_idle_notifier_v1_interface, 1, "IdleNotify"); + PROTO::idle = makeUnique(&ext_idle_notifier_v1_interface, 2, "IdleNotify"); PROTO::lockNotify = makeUnique(&hyprland_lock_notifier_v1_interface, 1, "IdleNotify"); PROTO::sessionLock = makeUnique(&ext_session_lock_manager_v1_interface, 1, "SessionLock"); PROTO::ime = makeUnique(&zwp_input_method_manager_v2_interface, 1, "IMEv2"); diff --git a/src/protocols/IdleNotify.cpp b/src/protocols/IdleNotify.cpp index bc5aabb1..14a5f3e1 100644 --- a/src/protocols/IdleNotify.cpp +++ b/src/protocols/IdleNotify.cpp @@ -10,7 +10,8 @@ static int onTimer(SP self, void* data) { return 0; } -CExtIdleNotification::CExtIdleNotification(SP resource_, uint32_t timeoutMs_) : resource(resource_), timeoutMs(timeoutMs_) { +CExtIdleNotification::CExtIdleNotification(SP resource_, uint32_t timeoutMs_, bool obeyInhibitors_) : + resource(resource_), timeoutMs(timeoutMs_), obeyInhibitors(obeyInhibitors_) { if UNLIKELY (!resource_->resource()) return; @@ -35,7 +36,7 @@ bool CExtIdleNotification::good() { } void CExtIdleNotification::updateTimer() { - if (PROTO::idle->isInhibited) + if (PROTO::idle->isInhibited && obeyInhibitors) timer->updateTimeout(std::nullopt); else timer->updateTimeout(std::chrono::milliseconds(timeoutMs)); @@ -54,6 +55,10 @@ void CExtIdleNotification::onActivity() { updateTimer(); } +bool CExtIdleNotification::inhibitorsAreObeyed() const { + return obeyInhibitors; +} + CIdleNotifyProtocol::CIdleNotifyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { ; } @@ -63,7 +68,10 @@ void CIdleNotifyProtocol::bindManager(wl_client* client, void* data, uint32_t ve RESOURCE->setOnDestroy([this](CExtIdleNotifierV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setDestroy([this](CExtIdleNotifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); - RESOURCE->setGetIdleNotification([this](CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat) { this->onGetNotification(pMgr, id, timeout, seat); }); + RESOURCE->setGetIdleNotification( + [this](CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat) { this->onGetNotification(pMgr, id, timeout, seat, true); }); + RESOURCE->setGetInputIdleNotification( + [this](CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat) { this->onGetNotification(pMgr, id, timeout, seat, false); }); } void CIdleNotifyProtocol::onManagerResourceDestroy(wl_resource* res) { @@ -74,9 +82,10 @@ void CIdleNotifyProtocol::destroyNotification(CExtIdleNotification* notif) { std::erase_if(m_vNotifications, [&](const auto& other) { return other.get() == notif; }); } -void CIdleNotifyProtocol::onGetNotification(CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat) { - const auto CLIENT = pMgr->client(); - const auto RESOURCE = m_vNotifications.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id), timeout)).get(); +void CIdleNotifyProtocol::onGetNotification(CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat, bool obeyInhibitors) { + const auto CLIENT = pMgr->client(); + const auto RESOURCE = + m_vNotifications.emplace_back(makeShared(makeShared(CLIENT, pMgr->version(), id), timeout, obeyInhibitors)).get(); if UNLIKELY (!RESOURCE->good()) { pMgr->noMemory(); @@ -94,6 +103,7 @@ void CIdleNotifyProtocol::onActivity() { void CIdleNotifyProtocol::setInhibit(bool inhibited) { isInhibited = inhibited; for (auto const& n : m_vNotifications) { - n->onActivity(); + if (n->inhibitorsAreObeyed()) + n->onActivity(); } -} \ No newline at end of file +} diff --git a/src/protocols/IdleNotify.hpp b/src/protocols/IdleNotify.hpp index e3dcdc98..efc3accc 100644 --- a/src/protocols/IdleNotify.hpp +++ b/src/protocols/IdleNotify.hpp @@ -9,19 +9,22 @@ class CEventLoopTimer; class CExtIdleNotification { public: - CExtIdleNotification(SP resource_, uint32_t timeoutMs); + CExtIdleNotification(SP resource_, uint32_t timeoutMs, bool obeyInhibitors); ~CExtIdleNotification(); bool good(); void onTimerFired(); void onActivity(); + bool inhibitorsAreObeyed() const; + private: SP resource; uint32_t timeoutMs = 0; SP timer; - bool idled = false; + bool idled = false; + bool obeyInhibitors = false; void updateTimer(); }; @@ -38,7 +41,7 @@ class CIdleNotifyProtocol : public IWaylandProtocol { private: void onManagerResourceDestroy(wl_resource* res); void destroyNotification(CExtIdleNotification* notif); - void onGetNotification(CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat); + void onGetNotification(CExtIdleNotifierV1* pMgr, uint32_t id, uint32_t timeout, wl_resource* seat, bool obeyInhibitors); bool isInhibited = false; From 68bb3e7f0a1d528a8b2da1f92d2005889587561d Mon Sep 17 00:00:00 2001 From: nyx Date: Wed, 12 Feb 2025 08:54:42 -0500 Subject: [PATCH 0254/1444] env: move XDG_SESSION_TYPE to before backend init (#9390) --- src/Compositor.cpp | 1 - src/main.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 88a2530b..6d9e8d7e 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -386,7 +386,6 @@ void CCompositor::initServer(std::string socketName, int socketFd) { } setenv("WAYLAND_DISPLAY", m_szWLDisplaySocket.c_str(), 1); - setenv("XDG_SESSION_TYPE", "wayland", 1); if (!getenv("XDG_CURRENT_DESKTOP")) { setenv("XDG_CURRENT_DESKTOP", "Hyprland", 1); m_bDesktopEnvSet = true; diff --git a/src/main.cpp b/src/main.cpp index 464ed978..397d7463 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ int main(int argc, char** argv) { setenv("HYPRLAND_CMD", cmd.c_str(), 1); setenv("XDG_BACKEND", "wayland", 1); + setenv("XDG_SESSION_TYPE", "wayland", 1); setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 1); setenv("MOZ_ENABLE_WAYLAND", "1", 1); From 17894051634716ab80c6502abdbb90ae2bc68f25 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:06:36 +0000 Subject: [PATCH 0255/1444] session-lock: send locked when in unsafe state (#9399) --- src/managers/SessionLockManager.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp index 996860a1..40611199 100644 --- a/src/managers/SessionLockManager.cpp +++ b/src/managers/SessionLockManager.cpp @@ -89,6 +89,13 @@ void CSessionLockManager::onNewSessionLock(SP pLock) { g_pCompositor->focusSurface(nullptr); g_pSeatManager->setGrab(nullptr); + + // Normally the locked event is sent after each output rendered a lock screen frame. + // When there are no outputs, send it right away. + if (g_pCompositor->m_bUnsafeState) { + m_pSessionLock->lock->sendLocked(); + m_pSessionLock->m_hasSentLocked = true; + } } bool CSessionLockManager::isSessionLocked() { @@ -131,8 +138,7 @@ void CSessionLockManager::onLockscreenRenderedOnMonitor(uint64_t id) { if (!m_pSessionLock || m_pSessionLock->m_hasSentLocked) return; m_pSessionLock->m_lockedMonitors.emplace(id); - const auto MONITORS = g_pCompositor->m_vMonitors; - const bool LOCKED = std::all_of(MONITORS.begin(), MONITORS.end(), [this](auto m) { return m_pSessionLock->m_lockedMonitors.contains(m->ID); }); + const bool LOCKED = std::ranges::all_of(g_pCompositor->m_vMonitors, [this](auto m) { return m_pSessionLock->m_lockedMonitors.contains(m->ID); }); if (LOCKED && m_pSessionLock->lock->good()) { m_pSessionLock->lock->sendLocked(); m_pSessionLock->m_hasSentLocked = true; From 208f94fe12a30474d6805262524da3da492a0990 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:08:03 +0000 Subject: [PATCH 0256/1444] animations: sync inactive/active border angles when using borderangle animations (#9401) --- src/render/decorations/CHyprBorderDecoration.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/render/decorations/CHyprBorderDecoration.cpp b/src/render/decorations/CHyprBorderDecoration.cpp index 5f2fdbda..0df3acde 100644 --- a/src/render/decorations/CHyprBorderDecoration.cpp +++ b/src/render/decorations/CHyprBorderDecoration.cpp @@ -63,6 +63,11 @@ void CHyprBorderDecoration::draw(PHLMONITOR pMonitor, float const& a) { if (m_pWindow->m_fBorderAngleAnimationProgress->enabled()) { grad.m_fAngle += m_pWindow->m_fBorderAngleAnimationProgress->value() * M_PI * 2; grad.m_fAngle = normalizeAngleRad(grad.m_fAngle); + + // When borderangle is animated, it is counterintuitive to fade between inactive/active gradient angles. + // Instead we sync the angles to avoid fading between them and additionally rotating the border angle. + if (ANIMATED) + m_pWindow->m_cRealBorderColorPrevious.m_fAngle = grad.m_fAngle; } int borderSize = m_pWindow->getRealBorderSize(); From 5d2b00829484684b619a8c0de6b1d2b1d18d31a9 Mon Sep 17 00:00:00 2001 From: Anthony Ruhier Date: Thu, 13 Feb 2025 12:09:25 +0100 Subject: [PATCH 0257/1444] renderer: disable explicit if aquamarine output doesn't support it (#9396) (#9398) The explicit settings ignore the aquamarine output.supportsExplicit attribute, which creates glitches on drivers not supporting explicit sync (example: freedreno). If the output has been set as not supporting explicit, disable the explicit settings. --- src/helpers/Monitor.cpp | 2 +- src/render/Renderer.cpp | 14 +++++++++++--- src/render/Renderer.hpp | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index e4843211..fead5db9 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1312,7 +1312,7 @@ bool CMonitor::attemptDirectScanout() { return false; } - auto explicitOptions = g_pHyprRenderer->getExplicitSyncSettings(); + auto explicitOptions = g_pHyprRenderer->getExplicitSyncSettings(output); // wait for the explicit fence if present, and if kms explicit is allowed bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->syncobj->current.acquireTimeline && PSURFACE->syncobj->current.acquireTimeline->timeline && explicitOptions.explicitKMSEnabled; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 6f0bbe44..531ceb33 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1557,7 +1557,7 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) { } } - auto explicitOptions = getExplicitSyncSettings(); + auto explicitOptions = getExplicitSyncSettings(pMonitor->output); if (!explicitOptions.explicitEnabled) return ok; @@ -2293,7 +2293,7 @@ void CHyprRenderer::endRender() { if (m_eRenderMode == RENDER_MODE_NORMAL) { PMONITOR->output->state->setBuffer(m_pCurrentBuffer); - auto explicitOptions = getExplicitSyncSettings(); + auto explicitOptions = getExplicitSyncSettings(PMONITOR->output); if (PMONITOR->inTimeline && explicitOptions.explicitEnabled && explicitOptions.explicitKMSEnabled) { auto sync = g_pHyprOpenGL->createEGLSync({}); @@ -2336,7 +2336,7 @@ bool CHyprRenderer::isNvidia() { return m_bNvidia; } -SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings() { +SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings(SP output) { static auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); static auto PENABLEEXPLICITKMS = CConfigValue("render:explicit_sync_kms"); @@ -2344,6 +2344,14 @@ SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings() { settings.explicitEnabled = *PENABLEEXPLICIT; settings.explicitKMSEnabled = *PENABLEEXPLICITKMS; + if (!output->supportsExplicit) { + Debug::log(LOG, "Renderer: the aquamarine output does not support explicit, explicit settings are disabled."); + settings.explicitEnabled = false; + settings.explicitKMSEnabled = false; + + return settings; + } + if (*PENABLEEXPLICIT == 2 /* auto */) settings.explicitEnabled = true; if (*PENABLEEXPLICITKMS == 2 /* auto */) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index e64d41c1..731ed926 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -75,7 +75,7 @@ class CHyprRenderer { bool isNvidia(); void makeEGLCurrent(); void unsetEGL(); - SExplicitSyncSettings getExplicitSyncSettings(); + SExplicitSyncSettings getExplicitSyncSettings(SP output); void addWindowToRenderUnfocused(PHLWINDOW window); void makeWindowSnapshot(PHLWINDOW); void makeRawWindowSnapshot(PHLWINDOW, CFramebuffer*); From 40adb3dfb4b6f8cf0c5093f095954e3ef162a8eb Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:37:59 +0000 Subject: [PATCH 0258/1444] config: actually set initial beziers (#9400) --- src/config/ConfigManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index f87a5e6b..43abcb1f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -885,9 +885,9 @@ void CConfigManager::setDefaultAnimationVars() { m_AnimationTree.createNode("specialWorkspaceOut", "specialWorkspace"); // init the root nodes - m_AnimationTree.setConfigForNode("global", 1, 8.f, "", "default"); - m_AnimationTree.setConfigForNode("__internal_fadeCTM", 1, 5.f, "", "linear"); - m_AnimationTree.setConfigForNode("borderangle", 0, 0.f, "", "default"); + m_AnimationTree.setConfigForNode("global", 1, 8.f, "default"); + m_AnimationTree.setConfigForNode("__internal_fadeCTM", 1, 5.f, "linear"); + m_AnimationTree.setConfigForNode("borderangle", 0, 1, "default"); } std::optional CConfigManager::resetHLConfig() { From df3fba157279de53c582344b59699a21ac5d62b5 Mon Sep 17 00:00:00 2001 From: Honkazel <169346573+Honkazel@users.noreply.github.com> Date: Fri, 14 Feb 2025 20:31:03 +0500 Subject: [PATCH 0259/1444] internal: remove unused variable (#9402) --- src/helpers/MiscFunctions.cpp | 91 ----------------------------------- 1 file changed, 91 deletions(-) diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index f532617c..9e398fd9 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -49,97 +49,6 @@ using namespace Hyprutils::OS; #endif #endif -static const float transforms[][9] = { - { - 1.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - 0.0f, - 1.0f, - 0.0f, - -1.0f, - 0.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - -1.0f, - 0.0f, - 0.0f, - 0.0f, - -1.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - 0.0f, - -1.0f, - 0.0f, - 1.0f, - 0.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - -1.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - 0.0f, - 1.0f, - 0.0f, - 1.0f, - 0.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - 1.0f, - 0.0f, - 0.0f, - 0.0f, - -1.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, - { - 0.0f, - -1.0f, - 0.0f, - -1.0f, - 0.0f, - 0.0f, - 0.0f, - 0.0f, - 1.0f, - }, -}; - std::string absolutePath(const std::string& rawpath, const std::string& currentPath) { auto value = rawpath; From fb36815b0146d7b494cd648be0dfaa67a14d164a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 14 Feb 2025 22:51:36 +0000 Subject: [PATCH 0260/1444] renderer: remove spammy log --- src/render/Renderer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 531ceb33..b61f1c3e 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -2345,7 +2345,6 @@ SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings(SPsupportsExplicit) { - Debug::log(LOG, "Renderer: the aquamarine output does not support explicit, explicit settings are disabled."); settings.explicitEnabled = false; settings.explicitKMSEnabled = false; From 1309b59f2cb5179a4c59c111c35c7feede535eb6 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 15 Feb 2025 00:18:43 +0000 Subject: [PATCH 0261/1444] monitor: report a scheduled frame when tearing on cursor move --- src/helpers/Monitor.cpp | 18 ++++++++++++++++++ src/helpers/Monitor.hpp | 1 + src/managers/PointerManager.cpp | 10 +++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index fead5db9..24db3ea4 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1441,6 +1441,24 @@ void CMonitor::onMonitorFrame() { g_pHyprRenderer->renderMonitor(self.lock()); } +void CMonitor::onCursorMovedOnMonitor() { + if (!tearingState.activelyTearing || !solitaryClient || !g_pHyprRenderer->shouldRenderCursor()) + return; + + // submit a frame immediately. This will only update the cursor pos. + // output->state->setBuffer(output->state->state().buffer); + // output->state->addDamage(CRegion{}); + // output->state->setPresentationMode(Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE); + // if (!output->commit()) + // Debug::log(ERR, "onCursorMovedOnMonitor: tearing and wanted to update cursor, failed."); + + // FIXME: try to do the above. We currently can't just render because drm is a fucking bitch + // and throws a "nO pRoP cAn Be ChAnGeD dUrInG AsYnC fLiP" on crtc_x + // this will throw too but fix it if we use sw cursors + + tearingState.frameScheduledWhileBusy = true; +} + CMonitorState::CMonitorState(CMonitor* owner) : m_pOwner(owner) { ; } diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index c67bccc5..690b8c4a 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -186,6 +186,7 @@ class CMonitor { void scheduleDone(); bool attemptDirectScanout(); void setCTM(const Mat3x3& ctm); + void onCursorMovedOnMonitor(); void debugLastPresentation(const std::string& message); void onMonitorFrame(); diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 1c8e9976..24f2b35d 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -17,6 +17,9 @@ #include #include #include +#include + +using namespace Hyprutils::Utils; CPointerManager::CPointerManager() { hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) { @@ -310,7 +313,12 @@ void CPointerManager::onCursorMoved() { recalc = true; } - if (state->hardwareFailed || !state->entered) + if (!state->entered) + continue; + + CScopeGuard x([m] { m->onCursorMovedOnMonitor(); }); + + if (state->hardwareFailed) continue; const auto CURSORPOS = getCursorPosForMonitor(m); From 2f967037aa00c4aecce62222e5e21c1790148eb0 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 15 Feb 2025 00:21:50 +0000 Subject: [PATCH 0262/1444] config: set no_hw_cursors to auto by default and disable on tearing when tearing, updates to the overlay plane may be ignored by the kernel. To avoid the cursor being a slideshow, disable hw cursors --- src/config/ConfigDescriptions.hpp | 2 +- src/config/ConfigManager.cpp | 5 +++-- src/config/ConfigManager.hpp | 2 +- src/managers/PointerManager.cpp | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 8d1b73c4..23635760 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1356,7 +1356,7 @@ inline static const std::vector CONFIG_OPTIONS = { }, SConfigOptionDescription{ .value = "cursor:no_hardware_cursors", - .description = "disables hardware cursors", + .description = "disables hardware cursors. Auto = disable when tearing", .type = CONFIG_OPTION_CHOICE, .data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Auto"}, }, diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 43abcb1f..00dba200 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -621,7 +621,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1}); - m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0}); + m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{2}); m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{2}); m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24}); m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0}); @@ -2798,12 +2798,13 @@ const std::vector& CConfigManager::getAllDescriptions( return CONFIG_OPTIONS; } -bool CConfigManager::shouldUseSoftwareCursors() { +bool CConfigManager::shouldUseSoftwareCursors(PHLMONITOR pMonitor) { static auto PNOHW = CConfigValue("cursor:no_hardware_cursors"); switch (*PNOHW) { case 0: return false; case 1: return true; + case 2: return pMonitor->tearingState.activelyTearing; default: break; } diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index f0696882..b914a3a3 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -189,7 +189,7 @@ class CConfigManager { void ensureMonitorStatus(); void ensureVRR(PHLMONITOR pMonitor = nullptr); - bool shouldUseSoftwareCursors(); + bool shouldUseSoftwareCursors(PHLMONITOR pMonitor); void updateWatcher(); std::string parseKeyword(const std::string&, const std::string&); diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 24f2b35d..048719b8 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -274,7 +274,7 @@ void CPointerManager::updateCursorBackend() { continue; } - if (state->softwareLocks > 0 || g_pConfigManager->shouldUseSoftwareCursors() || !attemptHardwareCursor(state)) { + if (state->softwareLocks > 0 || g_pConfigManager->shouldUseSoftwareCursors(m) || !attemptHardwareCursor(state)) { Debug::log(TRACE, "Output {} rejected hardware cursors, falling back to sw", m->szName); state->box = getCursorBoxLogicalForMonitor(state->monitor.lock()); state->hardwareFailed = true; @@ -737,7 +737,8 @@ void CPointerManager::damageIfSoftware() { if (mw->monitor.expired() || !mw->monitor->output) continue; - if ((mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors()) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) { + if ((mw->softwareLocks > 0 || mw->hardwareFailed || g_pConfigManager->shouldUseSoftwareCursors(mw->monitor.lock())) && + b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) { g_pHyprRenderer->damageBox(b, mw->monitor->shouldSkipScheduleFrameOnMouseEvent()); break; } From 3eb6cb1875bd2f0850d19b1ad1b554c61b06bcec Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 15 Feb 2025 14:48:52 +0100 Subject: [PATCH 0263/1444] syncobj: ensure we only add waiters on succesful checks (#9412) timeline check only returns nullopt on ETIME_ERR , meaning the if check later on returns true if drmSyncobjTimelineWait returns anything else like EINVAL/EPERM/EACCESS etc, so actually check the returned .value() of the std::optional. also move the fd to rvalue references. --- src/protocols/DRMSyncobj.cpp | 4 ++-- src/protocols/DRMSyncobj.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp index 23dafbca..38aab305 100644 --- a/src/protocols/DRMSyncobj.cpp +++ b/src/protocols/DRMSyncobj.cpp @@ -75,7 +75,7 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SPlockPendingState(); @@ -104,7 +104,7 @@ bool CDRMSyncobjSurfaceResource::good() { return resource->resource(); } -CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP resource_, CFileDescriptor fd_) : fd(std::move(fd_)), resource(resource_) { +CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP resource_, CFileDescriptor&& fd_) : fd(std::move(fd_)), resource(resource_) { if UNLIKELY (!good()) return; diff --git a/src/protocols/DRMSyncobj.hpp b/src/protocols/DRMSyncobj.hpp index 8677576f..9895dff1 100644 --- a/src/protocols/DRMSyncobj.hpp +++ b/src/protocols/DRMSyncobj.hpp @@ -33,7 +33,7 @@ class CDRMSyncobjSurfaceResource { class CDRMSyncobjTimelineResource { public: - CDRMSyncobjTimelineResource(SP resource_, Hyprutils::OS::CFileDescriptor fd_); + CDRMSyncobjTimelineResource(SP resource_, Hyprutils::OS::CFileDescriptor&& fd_); ~CDRMSyncobjTimelineResource() = default; static SP fromResource(wl_resource*); From 7a6fde8414ae200759ac41569f189ac5e1ba0fbb Mon Sep 17 00:00:00 2001 From: nyx Date: Sat, 15 Feb 2025 08:51:17 -0500 Subject: [PATCH 0264/1444] internal: redirect exec'd app output to /dev/null (#9411) --- src/managers/KeybindManager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 8daa6838..4bfd1454 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -967,6 +967,14 @@ uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWo setenv(e.first.c_str(), e.second.c_str(), 1); } setenv("WAYLAND_DISPLAY", g_pCompositor->m_szWLDisplaySocket.c_str(), 1); + + int devnull = open("/dev/null", O_WRONLY | O_CLOEXEC); + if (devnull != -1) { + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); + } + execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr); // exit grandchild _exit(0); From 410da2e46fc44d93196cd902a070391a416cff01 Mon Sep 17 00:00:00 2001 From: Roberto Previdi Date: Sat, 15 Feb 2025 15:01:52 +0100 Subject: [PATCH 0265/1444] workspaces: update persistence on workspace rename (#9368) --- src/Compositor.cpp | 51 ++++++++++++++++++++++++++------------- src/Compositor.hpp | 2 +- src/debug/HyprCtl.cpp | 14 ++++++----- src/desktop/Workspace.cpp | 6 +++++ 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 6d9e8d7e..5389844f 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -3043,34 +3043,53 @@ bool CCompositor::shouldChangePreferredImageDescription() { return false; } -void CCompositor::ensurePersistentWorkspacesPresent(const std::vector& rules) { +void CCompositor::ensurePersistentWorkspacesPresent(const std::vector& rules, PHLWORKSPACE pWorkspace) { + for (const auto& rule : rules) { if (!rule.isPersistent) continue; + PHLWORKSPACE PWORKSPACE = nullptr; + if (pWorkspace) { + if (pWorkspace->matchesStaticSelector(rule.workspaceString)) + PWORKSPACE = pWorkspace; + else + continue; + } + const auto PMONITOR = getMonitorFromString(rule.monitor); + if (!PWORKSPACE) { + WORKSPACEID id = rule.workspaceId; + std::string wsname = rule.workspaceName; + + if (id == WORKSPACE_INVALID) { + const auto R = getWorkspaceIDNameFromString(rule.workspaceString); + id = R.id; + wsname = R.name; + } + + if (id == WORKSPACE_INVALID) { + Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve id for workspace {}", rule.workspaceString); + continue; + } + PWORKSPACE = getWorkspaceByID(id); + if (!PWORKSPACE) + createNewWorkspace(id, PMONITOR ? PMONITOR : m_pLastMonitor.lock(), wsname, false); + } + + if (PWORKSPACE) + PWORKSPACE->m_bPersistent = true; + if (!PMONITOR) { Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve monitor for {}, skipping", rule.monitor); continue; } - WORKSPACEID id = rule.workspaceId; - std::string wsname = rule.workspaceName; - if (id == WORKSPACE_INVALID) { - const auto R = getWorkspaceIDNameFromString(rule.workspaceString); - id = R.id; - wsname = R.name; - } - - if (id == WORKSPACE_INVALID) { - Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve id for workspace {}", rule.workspaceString); - continue; - } - - if (const auto PWORKSPACE = getWorkspaceByID(id); PWORKSPACE) { + if (PWORKSPACE) { if (PWORKSPACE->m_pMonitor == PMONITOR) { Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} already on {}", rule.workspaceString, PMONITOR->szName); + continue; } @@ -3078,8 +3097,6 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector pSurface, wl_output_transform transform); void updateSuspendedStates(); void onNewMonitor(SP output); - void ensurePersistentWorkspacesPresent(const std::vector& rules); + void ensurePersistentWorkspacesPresent(const std::vector& rules, PHLWORKSPACE pWorkspace = nullptr); SImageDescription getPreferredImageDescription(); bool shouldChangePreferredImageDescription(); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index cd6451e2..a155474d 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -319,15 +319,17 @@ std::string CHyprCtl::getWorkspaceData(PHLWORKSPACE w, eHyprCtlOutputFormat form "windows": {}, "hasfullscreen": {}, "lastwindow": "0x{:x}", - "lastwindowtitle": "{}" + "lastwindowtitle": "{}", + "ispersistent": {} }})#", w->m_iID, escapeJSONStrings(w->m_szName), escapeJSONStrings(PMONITOR ? PMONITOR->szName : "?"), - escapeJSONStrings(PMONITOR ? std::to_string(PMONITOR->ID) : "null"), w->getWindows(), ((int)w->m_bHasFullscreenWindow == 1 ? "true" : "false"), - (uintptr_t)PLASTW.get(), PLASTW ? escapeJSONStrings(PLASTW->m_szTitle) : ""); + escapeJSONStrings(PMONITOR ? std::to_string(PMONITOR->ID) : "null"), w->getWindows(), w->m_bHasFullscreenWindow ? "true" : "false", + (uintptr_t)PLASTW.get(), PLASTW ? escapeJSONStrings(PLASTW->m_szTitle) : "", w->m_bPersistent ? "true" : "false"); } else { - return std::format("workspace ID {} ({}) on monitor {}:\n\tmonitorID: {}\n\twindows: {}\n\thasfullscreen: {}\n\tlastwindow: 0x{:x}\n\tlastwindowtitle: {}\n\n", w->m_iID, - w->m_szName, PMONITOR ? PMONITOR->szName : "?", PMONITOR ? std::to_string(PMONITOR->ID) : "null", w->getWindows(), (int)w->m_bHasFullscreenWindow, - (uintptr_t)PLASTW.get(), PLASTW ? PLASTW->m_szTitle : ""); + return std::format( + "workspace ID {} ({}) on monitor {}:\n\tmonitorID: {}\n\twindows: {}\n\thasfullscreen: {}\n\tlastwindow: 0x{:x}\n\tlastwindowtitle: {}\n\tispersistent: {}\n\n", + w->m_iID, w->m_szName, PMONITOR ? PMONITOR->szName : "?", PMONITOR ? std::to_string(PMONITOR->ID) : "null", w->getWindows(), (int)w->m_bHasFullscreenWindow, + (uintptr_t)PLASTW.get(), PLASTW ? PLASTW->m_szTitle : "", (int)w->m_bPersistent); } } diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index f2c22195..322c4e33 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -648,6 +648,12 @@ void CWorkspace::rename(const std::string& name) { Debug::log(LOG, "CWorkspace::rename: Renaming workspace {} to '{}'", m_iID, name); m_szName = name; + const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(m_pSelf.lock()); + m_bPersistent = WORKSPACERULE.isPersistent; + + if (WORKSPACERULE.isPersistent) + g_pCompositor->ensurePersistentWorkspacesPresent(std::vector{WORKSPACERULE}, m_pSelf.lock()); + g_pEventManager->postEvent({"renameworkspace", std::to_string(m_iID) + "," + m_szName}); } From 9228116c9aa682477aae1a52d2d7d023bb075352 Mon Sep 17 00:00:00 2001 From: nyx Date: Sat, 15 Feb 2025 14:03:37 -0500 Subject: [PATCH 0266/1444] xwayland: fix a possible clipboard race condition (#9394) --- src/xwayland/XDataSource.cpp | 15 ++++--- src/xwayland/XWM.cpp | 85 ++++++++++++++++++++++++++++-------- src/xwayland/XWM.hpp | 2 +- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/xwayland/XDataSource.cpp b/src/xwayland/XDataSource.cpp index 9384db69..003f6c9f 100644 --- a/src/xwayland/XDataSource.cpp +++ b/src/xwayland/XDataSource.cpp @@ -71,19 +71,20 @@ void CXDataSource::send(const std::string& mime, CFileDescriptor fd) { Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get()); - selection.transfer = makeUnique(selection); - selection.transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection); - const uint32_t MASK = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE; - xcb_create_window(g_pXWayland->pWM->connection, XCB_COPY_FROM_PARENT, selection.transfer->incomingWindow, g_pXWayland->pWM->screen->root, 0, 0, 10, 10, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, g_pXWayland->pWM->screen->root_visual, XCB_CW_EVENT_MASK, &MASK); + auto transfer = makeUnique(selection); + transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection); + const uint32_t MASK = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE; + xcb_create_window(g_pXWayland->pWM->connection, XCB_COPY_FROM_PARENT, transfer->incomingWindow, g_pXWayland->pWM->screen->root, 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, + g_pXWayland->pWM->screen->root_visual, XCB_CW_EVENT_MASK, &MASK); - xcb_convert_selection(g_pXWayland->pWM->connection, selection.transfer->incomingWindow, HYPRATOMS["CLIPBOARD"], mimeAtom, HYPRATOMS["_WL_SELECTION"], XCB_TIME_CURRENT_TIME); + xcb_convert_selection(g_pXWayland->pWM->connection, transfer->incomingWindow, HYPRATOMS["CLIPBOARD"], mimeAtom, HYPRATOMS["_WL_SELECTION"], XCB_TIME_CURRENT_TIME); xcb_flush(g_pXWayland->pWM->connection); //TODO: make CFileDescriptor setflags take SETFL aswell fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK); - selection.transfer->wlFD = std::move(fd); + transfer->wlFD = std::move(fd); + selection.transfers.emplace_back(std::move(transfer)); } void CXDataSource::accepted(const std::string& mime) { diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 68552dd6..f2a9b794 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -571,9 +571,10 @@ void CXWM::handleSelectionNotify(xcb_selection_notify_event_t* e) { SXSelection* sel = getSelection(e->selection); if (e->property == XCB_ATOM_NONE) { - if (sel->transfer) { + auto it = std::ranges::find_if(sel->transfers, [](const auto& t) { return !t->propertyReply; }); + if (it != sel->transfers.end()) { Debug::log(TRACE, "[xwm] converting selection failed"); - sel->transfer.reset(); + sel->transfers.erase(it); } } else if (e->target == HYPRATOMS["TARGETS"] && sel == &clipboard) { if (!focusedSurface) { @@ -582,7 +583,7 @@ void CXWM::handleSelectionNotify(xcb_selection_notify_event_t* e) { } setClipboardToWayland(*sel); - } else if (sel->transfer) + } else if (!sel->transfers.empty()) getTransferData(*sel); } @@ -1177,17 +1178,50 @@ static int writeDataSource(int fd, uint32_t mask, void* data) { void CXWM::getTransferData(SXSelection& sel) { Debug::log(LOG, "[xwm] getTransferData"); - sel.transfer->getIncomingSelectionProp(true); - - if (sel.transfer->propertyReply->type == HYPRATOMS["INCR"]) { - Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :("); - sel.transfer.reset(); + auto it = std::ranges::find_if(sel.transfers, [](const auto& t) { return !t->propertyReply; }); + if (it == sel.transfers.end()) { + Debug::log(ERR, "[xwm] No pending transfer found"); return; - } else { - sel.onWrite(); - if (sel.transfer) - sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD.get(), WL_EVENT_WRITABLE, ::writeDataSource, &sel); } + + auto& transfer = *it; + if (!transfer || !transfer->incomingWindow) { + Debug::log(ERR, "[xwm] Invalid transfer state"); + sel.transfers.erase(it); + return; + } + + if (!transfer->getIncomingSelectionProp(true)) { + Debug::log(ERR, "[xwm] Failed to get property data"); + sel.transfers.erase(it); + return; + } + + if (!transfer->propertyReply) { + Debug::log(ERR, "[xwm] No property reply"); + sel.transfers.erase(it); + return; + } + + if (transfer->propertyReply->type == HYPRATOMS["INCR"]) { + Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :("); + sel.transfers.erase(it); + return; + } + + const size_t pos = std::distance(sel.transfers.begin(), it); + sel.onWrite(); + + if (pos >= sel.transfers.size()) + return; + + auto newIt = sel.transfers.begin() + pos; + if (newIt == sel.transfers.end() || !(*newIt)) + return; + + auto& updatedTransfer = *newIt; + if (updatedTransfer->eventSource && updatedTransfer->wlFD.get() != -1) + updatedTransfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, updatedTransfer->wlFD.get(), WL_EVENT_WRITABLE, ::writeDataSource, &sel); } void CXWM::setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot) { @@ -1290,16 +1324,21 @@ void SXSelection::onKeyboardFocus() { } int SXSelection::onRead(int fd, uint32_t mask) { - // TODO: support INCR + auto it = std::ranges::find_if(transfers, [fd](const auto& t) { return t->wlFD.get() == fd; }); + if (it == transfers.end()) { + Debug::log(ERR, "[xwm] No transfer found for fd {}", fd); + return 0; + } - size_t pre = transfer->data.size(); + auto& transfer = *it; + size_t pre = transfer->data.size(); transfer->data.resize(INCR_CHUNK_SIZE + pre); auto len = read(fd, transfer->data.data() + pre, INCR_CHUNK_SIZE - 1); if (len < 0) { Debug::log(ERR, "[xwm] readDataSource died"); g_pXWayland->pWM->selectionSendNotify(&transfer->request, false); - transfer.reset(); + transfers.erase(it); return 0; } @@ -1311,7 +1350,7 @@ int SXSelection::onRead(int fd, uint32_t mask) { transfer->data.size(), transfer->data.data()); xcb_flush(g_pXWayland->pWM->connection); g_pXWayland->pWM->selectionSendNotify(&transfer->request, true); - transfer.reset(); + transfers.erase(it); } else Debug::log(LOG, "[xwm] Received {} bytes, waiting...", len); @@ -1346,7 +1385,7 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) { mime = *MIMES.begin(); } - transfer = makeUnique(*this); + auto transfer = makeUnique(*this); transfer->request = *e; int p[2]; @@ -1368,18 +1407,26 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) { selection->send(mime, CFileDescriptor{p[1]}); transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD.get(), WL_EVENT_READABLE, ::readDataSource, this); + transfers.emplace_back(std::move(transfer)); return true; } int SXSelection::onWrite() { + auto it = std::ranges::find_if(transfers, [](const auto& t) { return t->propertyReply; }); + if (it == transfers.end()) { + Debug::log(ERR, "[xwm] No transfer with property data found"); + return 0; + } + + auto& transfer = *it; char* property = (char*)xcb_get_property_value(transfer->propertyReply); int remainder = xcb_get_property_value_length(transfer->propertyReply) - transfer->propertyStart; ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder); if (len == -1) { Debug::log(ERR, "[xwm] write died in transfer get"); - transfer.reset(); + transfers.erase(it); return 0; } @@ -1388,7 +1435,7 @@ int SXSelection::onWrite() { Debug::log(LOG, "[xwm] wl client read partially: len {}", len); } else { Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len); - transfer.reset(); + transfers.erase(it); } return 1; diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index 73a02a86..f6dcee54 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -58,7 +58,7 @@ struct SXSelection { CHyprSignalListener keyboardFocusChange; } listeners; - UP transfer; + std::vector> transfers; }; class CXCBConnection { From 94a30889a78fa7c7f87fe8134c18357855824c35 Mon Sep 17 00:00:00 2001 From: andrewandreii <63286820+andrewandreii@users.noreply.github.com> Date: Sat, 15 Feb 2025 21:04:02 +0200 Subject: [PATCH 0267/1444] keybinds: fix some errors not returning a failure (#9416) --- src/managers/KeybindManager.cpp | 65 ++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 4bfd1454..4e63e6dc 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1723,7 +1723,7 @@ SDispatchResult CKeybindManager::changeGroupActive(std::string args) { // index starts from '1'; '0' means last window const int INDEX = std::stoi(args); if (INDEX > PWINDOW->getGroupSize()) - return {}; + return {.success = false, .error = "Index too big, there aren't that many windows in this group"}; if (INDEX == 0) PWINDOW->setGroupCurrent(PWINDOW->getGroupTail()); else @@ -1986,7 +1986,7 @@ SDispatchResult CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) SDispatchResult CKeybindManager::moveWorkspaceToMonitor(std::string args) { if (!args.contains(' ')) - return {}; + return {.success = false, .error = "Invalid arguments, expected: workspace monitor"}; std::string workspace = args.substr(0, args.find_first_of(' ')); std::string monitor = args.substr(args.find_first_of(' ') + 1); @@ -2129,13 +2129,16 @@ SDispatchResult CKeybindManager::forceRendererReload(std::string args) { SDispatchResult CKeybindManager::resizeActive(std::string args) { const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); - if (!PLASTWINDOW || PLASTWINDOW->isFullscreen()) - return {}; + if (!PLASTWINDOW) + return {.success = false, .error = "No window found"}; + + if (PLASTWINDOW->isFullscreen()) + return {.success = false, .error = "Window is fullscreen"}; const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_vRealSize->goal()); if (SIZ.x < 1 || SIZ.y < 1) - return {}; + return {.success = false, .error = "Invalid size provided"}; g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PLASTWINDOW->m_vRealSize->goal()); @@ -2148,8 +2151,11 @@ SDispatchResult CKeybindManager::resizeActive(std::string args) { SDispatchResult CKeybindManager::moveActive(std::string args) { const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); - if (!PLASTWINDOW || PLASTWINDOW->isFullscreen()) - return {}; + if (!PLASTWINDOW) + return {.success = false, .error = "No window found"}; + + if (PLASTWINDOW->isFullscreen()) + return {.success = false, .error = "Window is fullscreen"}; const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, PLASTWINDOW->m_vRealPosition->goal()); @@ -2171,7 +2177,7 @@ SDispatchResult CKeybindManager::moveWindow(std::string args) { } if (PWINDOW->isFullscreen()) - return {}; + return {.success = false, .error = "Window is fullscreen"}; const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition->goal()); @@ -2193,12 +2199,12 @@ SDispatchResult CKeybindManager::resizeWindow(std::string args) { } if (PWINDOW->isFullscreen()) - return {}; + return {.success = false, .error = "Window is fullscreen"}; const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize->goal()); if (SIZ.x < 1 || SIZ.y < 1) - return {}; + return {.success = false, .error = "Invalid size provided"}; g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize->goal(), CORNER_NONE, PWINDOW); @@ -2244,7 +2250,7 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) { const auto PWINDOW = g_pCompositor->getWindowByRegex(regexp); if (!PWINDOW) - return {}; + return {.success = false, .error = "No such window found"}; Debug::log(LOG, "Focusing to window name: {}", PWINDOW->m_szTitle); @@ -2304,7 +2310,7 @@ SDispatchResult CKeybindManager::tagWindow(std::string args) { else if (vars.size() == 2) PWINDOW = g_pCompositor->getWindowByRegex(vars[1]); else - return {}; + return {.success = false, .error = "Invalid number of arguments, expected 1 or 2 arguments"}; if (PWINDOW && PWINDOW->m_tags.applyTag(vars[0])) { PWINDOW->updateDynamicRules(); @@ -2674,7 +2680,10 @@ SDispatchResult CKeybindManager::swapActiveWorkspaces(std::string args) { const auto PMON1 = g_pCompositor->getMonitorFromString(MON1); const auto PMON2 = g_pCompositor->getMonitorFromString(MON2); - if (!PMON1 || !PMON2 || PMON1 == PMON2) + if (!PMON1 || !PMON2) + return {.success = false, .error = "No such monitor found"}; + + if (PMON1 == PMON2) return {}; g_pCompositor->swapActiveWorkspaces(PMON1, PMON2); @@ -2697,7 +2706,7 @@ SDispatchResult CKeybindManager::pinActive(std::string args) { } if (!PWINDOW->m_bIsFloating || PWINDOW->isFullscreen()) - return {}; + return {.success = false, .error = "Window does not qualify to be pinned"}; PWINDOW->m_bPinned = !PWINDOW->m_bPinned; @@ -2825,8 +2834,11 @@ SDispatchResult CKeybindManager::lockGroups(std::string args) { SDispatchResult CKeybindManager::lockActiveGroup(std::string args) { const auto PWINDOW = g_pCompositor->m_pLastWindow.lock(); - if (!PWINDOW || !PWINDOW->m_sGroupData.pNextWindow.lock()) - return {}; + if (!PWINDOW) + return {.success = false, .error = "No window found"}; + + if (!PWINDOW->m_sGroupData.pNextWindow.lock()) + return {.success = false, .error = "Not a group"}; const auto PHEAD = PWINDOW->getGroupHead(); @@ -2947,7 +2959,7 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) { static auto PIGNOREGROUPLOCK = CConfigValue("binds:ignore_group_lock"); if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked) - return {}; + return {.success = false, .error = "Groups locked"}; PHLWINDOW PWINDOW = nullptr; @@ -2956,8 +2968,11 @@ SDispatchResult CKeybindManager::moveOutOfGroup(std::string args) { else PWINDOW = g_pCompositor->m_pLastWindow.lock(); - if (!PWINDOW || !PWINDOW->m_sGroupData.pNextWindow.lock()) - return {}; + if (!PWINDOW) + return {.success = false, .error = "No window found"}; + + if (!PWINDOW->m_sGroupData.pNextWindow.lock()) + return {.success = false, .error = "Window not in a group"}; moveWindowOutOfGroup(PWINDOW); @@ -2975,7 +2990,10 @@ SDispatchResult CKeybindManager::moveWindowOrGroup(std::string args) { } const auto PWINDOW = g_pCompositor->m_pLastWindow.lock(); - if (!PWINDOW || PWINDOW->isFullscreen()) + if (!PWINDOW) + return {.success = false, .error = "No window found"}; + + if (PWINDOW->isFullscreen()) return {}; if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked) { @@ -3064,8 +3082,11 @@ SDispatchResult CKeybindManager::moveGroupWindow(std::string args) { const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); - if (!PLASTWINDOW || !PLASTWINDOW->m_sGroupData.pNextWindow.lock()) - return {}; + if (!PLASTWINDOW) + return {.success = false, .error = "No window found"}; + + if (!PLASTWINDOW->m_sGroupData.pNextWindow.lock()) + return {.success = false, .error = "Window not in a group"}; if ((!BACK && PLASTWINDOW->m_sGroupData.pNextWindow->m_sGroupData.head) || (BACK && PLASTWINDOW->m_sGroupData.head)) { std::swap(PLASTWINDOW->m_sGroupData.head, PLASTWINDOW->m_sGroupData.pNextWindow->m_sGroupData.head); From 897ee276dc0a8a6b11a8102b225a9e969faac0bf Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Sun, 16 Feb 2025 00:20:42 +0000 Subject: [PATCH 0268/1444] xwayland: configure on a configure request and cleanup geometry conversion (#9375) * xwayland: configure the window on a configure request * xwayland: move coordinate conversion handling to their own functions * xwayland: rename configure to configureRequest --- src/desktop/Window.cpp | 120 ++++++++++++++++++++++++-------------- src/desktop/Window.hpp | 9 ++- src/xwayland/XSurface.hpp | 4 +- src/xwayland/XWM.cpp | 9 +-- src/xwayland/XWM.hpp | 2 +- 5 files changed, 91 insertions(+), 53 deletions(-) diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 7c0cb741..7b7f954d 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -95,15 +95,15 @@ CWindow::CWindow(SP resource) : m_pXDGSurface(resource) { CWindow::CWindow(SP surface) : m_pXWaylandSurface(surface) { m_pWLSurface = CWLSurface::create(); - listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); }); - listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); }); - listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); }); - listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); }); - listeners.configure = m_pXWaylandSurface->events.configure.registerListener([this](std::any d) { onX11Configure(std::any_cast(d)); }); - listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); }); - listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); }); - listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); }); - listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); }); + listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); }); + listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); }); + listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); }); + listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); }); + listeners.configureRequest = m_pXWaylandSurface->events.configureRequest.registerListener([this](std::any d) { onX11ConfigureRequest(std::any_cast(d)); }); + listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); }); + listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); }); + listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); }); + listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); }); if (m_pXWaylandSurface->overrideRedirect) listeners.setGeometry = m_pXWaylandSurface->events.setGeometry.registerListener([this](std::any d) { Events::listener_unmanagedSetGeometry(this, nullptr); }); @@ -1530,14 +1530,14 @@ void CWindow::onResourceChangeX11() { Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface->resource().get()); } -void CWindow::onX11Configure(CBox box) { +void CWindow::onX11ConfigureRequest(CBox box) { if (!m_pXWaylandSurface->surface || !m_pXWaylandSurface->mapped || !m_bIsMapped) { m_pXWaylandSurface->configure(box); m_vPendingReportedSize = box.size(); m_vReportedSize = box.size(); - if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) - m_fX11SurfaceScaledBy = PMONITOR->scale; + m_vReportedPosition = box.pos(); + updateX11SurfaceScale(); return; } @@ -1555,25 +1555,20 @@ void CWindow::onX11Configure(CBox box) { else setHidden(true); - const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(box.pos()); - - m_vRealPosition->setValueAndWarp(LOGICALPOS); - m_vRealSize->setValueAndWarp(box.size()); - - static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); - if (*PXWLFORCESCALEZERO) { - if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) { - m_vRealSize->setValueAndWarp(m_vRealSize->goal() / PMONITOR->scale); - m_fX11SurfaceScaledBy = PMONITOR->scale; - } - } + m_vRealPosition->setValueAndWarp(xwaylandPositionToReal(box.pos())); + m_vRealSize->setValueAndWarp(xwaylandSizeToReal(box.size())); m_vPosition = m_vRealPosition->goal(); m_vSize = m_vRealSize->goal(); - m_vPendingReportedSize = box.size(); - m_vReportedSize = box.size(); + if (m_vPendingReportedSize != box.size() || m_vReportedPosition != box.pos()) { + m_pXWaylandSurface->configure(box); + m_vReportedSize = box.size(); + m_vPendingReportedSize = box.size(); + m_vReportedPosition = box.pos(); + } + updateX11SurfaceScale(); updateWindowDecos(); if (!m_pWorkspace || !m_pWorkspace->isVisible()) @@ -1700,37 +1695,74 @@ Vector2D CWindow::requestedMaxSize() { return maxSize; } -void CWindow::sendWindowSize(bool force) { +Vector2D CWindow::realToReportSize() { + if (!m_bIsX11) + return m_vRealSize->goal().clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); - const auto PMONITOR = m_pMonitor.lock(); + + const auto REPORTSIZE = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + const auto PMONITOR = m_pMonitor.lock(); + + if (*PXWLFORCESCALEZERO && PMONITOR) + return REPORTSIZE * PMONITOR->scale; + + return REPORTSIZE; +} + +Vector2D CWindow::realToReportPosition() { + if (!m_bIsX11) + return m_vRealPosition->goal(); + + return g_pXWaylandManager->waylandToXWaylandCoords(m_vRealPosition->goal()); +} + +Vector2D CWindow::xwaylandSizeToReal(Vector2D size) { + static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); + + const auto PMONITOR = m_pMonitor.lock(); + const auto SIZE = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + const auto SCALE = *PXWLFORCESCALEZERO ? PMONITOR->scale : 1.0f; + + return SIZE / SCALE; +} + +Vector2D CWindow::xwaylandPositionToReal(Vector2D pos) { + return g_pXWaylandManager->xwaylandToWaylandCoords(pos); +} + +void CWindow::updateX11SurfaceScale() { + static auto PXWLFORCESCALEZERO = CConfigValue("xwayland:force_zero_scaling"); + + m_fX11SurfaceScaledBy = 1.0f; + if (m_bIsX11 && *PXWLFORCESCALEZERO) { + if (const auto PMONITOR = m_pMonitor.lock(); PMONITOR) + m_fX11SurfaceScaledBy = PMONITOR->scale; + } +} + +void CWindow::sendWindowSize(bool force) { + const auto PMONITOR = m_pMonitor.lock(); Debug::log(TRACE, "sendWindowSize: window:{:x},title:{} with real pos {}, real size {} (force: {})", (uintptr_t)this, this->m_szTitle, m_vRealPosition->goal(), m_vRealSize->goal(), force); // TODO: this should be decoupled from setWindowSize IMO - Vector2D windowPos = m_vRealPosition->goal(); - Vector2D size = m_vRealSize->goal().clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits::infinity(), std::numeric_limits::infinity()}); + const auto REPORTPOS = realToReportPosition(); - if (m_bIsX11 && PMONITOR) { - windowPos = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); - if (*PXWLFORCESCALEZERO) - size *= PMONITOR->scale; - } + const auto REPORTSIZE = realToReportSize(); - if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11)) + if (!force && m_vPendingReportedSize == REPORTSIZE && (m_vReportedPosition == REPORTPOS || !m_bIsX11)) return; - m_vReportedPosition = windowPos; - m_vPendingReportedSize = size; - m_fX11SurfaceScaledBy = 1.0f; - - if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR) - m_fX11SurfaceScaledBy = PMONITOR->scale; + m_vReportedPosition = REPORTPOS; + m_vPendingReportedSize = REPORTSIZE; + updateX11SurfaceScale(); if (m_bIsX11 && m_pXWaylandSurface) - m_pXWaylandSurface->configure({windowPos, size}); + m_pXWaylandSurface->configure({REPORTPOS, REPORTSIZE}); else if (m_pXDGSurface && m_pXDGSurface->toplevel) - m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor()); + m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(REPORTSIZE), REPORTPOS.floor()); } NContentType::eContentType CWindow::getContentType() { diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index 171a15f4..bc32bab4 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -460,7 +460,7 @@ class CWindow { void onFocusAnimUpdate(); void onUpdateState(); void onUpdateMeta(); - void onX11Configure(CBox box); + void onX11ConfigureRequest(CBox box); void onResourceChangeX11(); std::string fetchTitle(); std::string fetchClass(); @@ -471,6 +471,11 @@ class CWindow { bool isModal(); Vector2D requestedMinSize(); Vector2D requestedMaxSize(); + Vector2D realToReportSize(); + Vector2D realToReportPosition(); + Vector2D xwaylandSizeToReal(Vector2D size); + Vector2D xwaylandPositionToReal(Vector2D size); + void updateX11SurfaceScale(); void sendWindowSize(bool force = false); NContentType::eContentType getContentType(); void setContentType(NContentType::eContentType contentType); @@ -497,7 +502,7 @@ class CWindow { CHyprSignalListener commit; CHyprSignalListener destroy; CHyprSignalListener activate; - CHyprSignalListener configure; + CHyprSignalListener configureRequest; CHyprSignalListener setGeometry; CHyprSignalListener updateState; CHyprSignalListener updateMetadata; diff --git a/src/xwayland/XSurface.hpp b/src/xwayland/XSurface.hpp index 7584354e..55e96078 100644 --- a/src/xwayland/XSurface.hpp +++ b/src/xwayland/XSurface.hpp @@ -50,7 +50,7 @@ class CXWaylandSurface { CSignal resourceChange; // associated / dissociated CSignal setGeometry; - CSignal configure; // CBox + CSignal configureRequest; // CBox CSignal map; CSignal unmap; @@ -116,4 +116,4 @@ class CXWaylandSurface { } listeners; friend class CXWM; -}; \ No newline at end of file +}; diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index f2a9b794..a4e3289b 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -59,7 +59,7 @@ void CXWM::handleDestroy(xcb_destroy_notify_event_t* e) { std::erase_if(surfaces, [XSURF](const auto& other) { return XSURF == other; }); } -void CXWM::handleConfigure(xcb_configure_request_event_t* e) { +void CXWM::handleConfigureRequest(xcb_configure_request_event_t* e) { const auto XSURF = windowForXID(e->window); if (!XSURF) @@ -70,8 +70,9 @@ void CXWM::handleConfigure(xcb_configure_request_event_t* e) { if (!(MASK & GEOMETRY)) return; - XSURF->events.configure.emit(CBox{MASK & XCB_CONFIG_WINDOW_X ? e->x : XSURF->geometry.x, MASK & XCB_CONFIG_WINDOW_Y ? e->y : XSURF->geometry.y, - MASK & XCB_CONFIG_WINDOW_WIDTH ? e->width : XSURF->geometry.width, MASK & XCB_CONFIG_WINDOW_HEIGHT ? e->height : XSURF->geometry.height}); + XSURF->events.configureRequest.emit(CBox{MASK & XCB_CONFIG_WINDOW_X ? e->x : XSURF->geometry.x, MASK & XCB_CONFIG_WINDOW_Y ? e->y : XSURF->geometry.y, + MASK & XCB_CONFIG_WINDOW_WIDTH ? e->width : XSURF->geometry.width, + MASK & XCB_CONFIG_WINDOW_HEIGHT ? e->height : XSURF->geometry.height}); } void CXWM::handleConfigureNotify(xcb_configure_notify_event_t* e) { @@ -758,7 +759,7 @@ int CXWM::onEvent(int fd, uint32_t mask) { switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { case XCB_CREATE_NOTIFY: handleCreate((xcb_create_notify_event_t*)event); break; case XCB_DESTROY_NOTIFY: handleDestroy((xcb_destroy_notify_event_t*)event); break; - case XCB_CONFIGURE_REQUEST: handleConfigure((xcb_configure_request_event_t*)event); break; + case XCB_CONFIGURE_REQUEST: handleConfigureRequest((xcb_configure_request_event_t*)event); break; case XCB_CONFIGURE_NOTIFY: handleConfigureNotify((xcb_configure_notify_event_t*)event); break; case XCB_MAP_REQUEST: handleMapRequest((xcb_map_request_event_t*)event); break; case XCB_MAP_NOTIFY: handleMapNotify((xcb_map_notify_event_t*)event); break; diff --git a/src/xwayland/XWM.hpp b/src/xwayland/XWM.hpp index f6dcee54..4326c77b 100644 --- a/src/xwayland/XWM.hpp +++ b/src/xwayland/XWM.hpp @@ -148,7 +148,7 @@ class CXWM { // event handlers void handleCreate(xcb_create_notify_event_t* e); void handleDestroy(xcb_destroy_notify_event_t* e); - void handleConfigure(xcb_configure_request_event_t* e); + void handleConfigureRequest(xcb_configure_request_event_t* e); void handleConfigureNotify(xcb_configure_notify_event_t* e); void handleMapRequest(xcb_map_request_event_t* e); void handleMapNotify(xcb_map_notify_event_t* e); From e2a9271150f9f1a2cba825f6f21bb130effc6b11 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sun, 16 Feb 2025 20:53:49 +0000 Subject: [PATCH 0269/1444] animations: add the gnomed animation style for windows --- src/managers/AnimationManager.cpp | 23 +++++++++++++++++++++-- src/managers/AnimationManager.hpp | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 29f669dc..18dae2a4 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -357,6 +357,21 @@ void CHyprAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, *pWindow->m_vRealPosition = posOffset; } +void CHyprAnimationManager::animationGnomed(PHLWINDOW pWindow, bool close) { + const auto GOALPOS = pWindow->m_vRealPosition->goal(); + const auto GOALSIZE = pWindow->m_vRealSize->goal(); + + if (close) { + *pWindow->m_vRealPosition = GOALPOS + Vector2D{0.F, GOALSIZE.y / 2.F}; + *pWindow->m_vRealSize = Vector2D{GOALSIZE.x, 0.F}; + } else { + pWindow->m_vRealPosition->setValueAndWarp(GOALPOS + Vector2D{0.F, GOALSIZE.y / 2.F}); + pWindow->m_vRealSize->setValueAndWarp(Vector2D{GOALSIZE.x, 0.F}); + *pWindow->m_vRealPosition = GOALPOS; + *pWindow->m_vRealSize = GOALSIZE; + } +} + void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) { if (!close) { pWindow->m_vRealPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn")); @@ -387,7 +402,9 @@ void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool clos if (STYLE.starts_with("slide")) { CVarList animList2(STYLE, 0, 's'); animationSlide(pWindow, animList2[1], close); - } else { + } else if (STYLE == "gnomed" || STYLE == "gnome") + animationGnomed(pWindow, close); + else { // anim popin, fallback float minPerc = 0.f; @@ -405,6 +422,8 @@ void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool clos } else { if (animList[0] == "slide") animationSlide(pWindow, animList[1], close); + else if (animList[0] == "gnomed" || animList[0] == "gnome") + animationGnomed(pWindow, close); else { // anim popin, fallback @@ -425,7 +444,7 @@ void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool clos std::string CHyprAnimationManager::styleValidInConfigVar(const std::string& config, const std::string& style) { if (config.starts_with("window")) { - if (style.starts_with("slide")) + if (style.starts_with("slide") || style == "gnome" || style == "gnomed") return ""; else if (style.starts_with("popin")) { // try parsing diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index 067fa676..833087d7 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -59,6 +59,7 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager { // Anim stuff void animationPopin(PHLWINDOW, bool close = false, float minPerc = 0.f); void animationSlide(PHLWINDOW, std::string force = "", bool close = false); + void animationGnomed(PHLWINDOW, bool close = false); }; inline UP g_pAnimationManager; From 59c615c321c45302491de3b1c003844c86aefca7 Mon Sep 17 00:00:00 2001 From: andrewandreii <63286820+andrewandreii@users.noreply.github.com> Date: Mon, 17 Feb 2025 04:03:27 +0200 Subject: [PATCH 0270/1444] input: add follow_mouse_threshold (#9392) --- src/config/ConfigDescriptions.hpp | 6 ++++++ src/config/ConfigManager.cpp | 1 + src/managers/input/InputManager.cpp | 29 ++++++++++++++++++----------- src/managers/input/InputManager.hpp | 1 + 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 23635760..1283050d 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -501,6 +501,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{1, 0, 3}, }, + SConfigOptionDescription{ + .value = "input:follow_mouse_threshold", + .description = "The smallest distance in logical pixels the mouse needs to travel for the window under it to get focused. Works only with follow_mouse = 1.", + .type = CONFIG_OPTION_FLOAT, + .data = SConfigOptionDescription::SFloatData{}, + }, SConfigOptionDescription{ .value = "input:focus_on_close", .description = "Controls the window focus behavior when a window is closed. When set to 0, focus will shift to the next window candidate. When set to 1, focus will shift " diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 00dba200..dc56d73f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -539,6 +539,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("animations:first_launch_animation", Hyprlang::INT{1}); m_pConfig->addConfigValue("input:follow_mouse", Hyprlang::INT{1}); + m_pConfig->addConfigValue("input:follow_mouse_threshold", Hyprlang::FLOAT{0}); m_pConfig->addConfigValue("input:focus_on_close", Hyprlang::INT{0}); m_pConfig->addConfigValue("input:mouse_refocus", Hyprlang::INT{1}); m_pConfig->addConfigValue("input:special_fallthrough", Hyprlang::INT{0}); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 3d8c6de8..1d16f915 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -161,17 +161,23 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored && !refocus) return; - static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); - static auto PMOUSEREFOCUS = CConfigValue("input:mouse_refocus"); - static auto PFOLLOWONDND = CConfigValue("misc:always_follow_on_dnd"); - static auto PFLOATBEHAVIOR = CConfigValue("input:float_switch_override_focus"); - static auto PMOUSEFOCUSMON = CConfigValue("misc:mouse_move_focuses_monitor"); - static auto PRESIZEONBORDER = CConfigValue("general:resize_on_border"); - static auto PRESIZECURSORICON = CConfigValue("general:hover_icon_on_border"); - static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); + static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); + static auto PFOLLOWMOUSETHRESHOLD = CConfigValue("input:follow_mouse_threshold"); + static auto PMOUSEREFOCUS = CConfigValue("input:mouse_refocus"); + static auto PFOLLOWONDND = CConfigValue("misc:always_follow_on_dnd"); + static auto PFLOATBEHAVIOR = CConfigValue("input:float_switch_override_focus"); + static auto PMOUSEFOCUSMON = CConfigValue("misc:mouse_move_focuses_monitor"); + static auto PRESIZEONBORDER = CConfigValue("general:resize_on_border"); + static auto PRESIZECURSORICON = CConfigValue("general:hover_icon_on_border"); + static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); const auto FOLLOWMOUSE = *PFOLLOWONDND && PROTO::data->dndActive() ? 1 : *PFOLLOWMOUSE; + if (FOLLOWMOUSE == 1 && m_tmrLastCursorMovement.getSeconds() < 0.5) + m_fMousePosDelta += MOUSECOORDSFLOORED.distance(m_vLastCursorPosFloored); + else + m_fMousePosDelta = 0; + m_pFoundSurfaceToFocus.reset(); m_pFoundLSToFocus.reset(); m_pFoundWindowToFocus.reset(); @@ -513,9 +519,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { // TODO: this looks wrong. When over a popup, it constantly is switching. // Temp fix until that's figured out. Otherwise spams windowrule lookups and other shit. - if (m_pLastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_pLastWindow.lock() != pFoundWindow) - g_pCompositor->focusWindow(pFoundWindow, foundSurface); - else + if (m_pLastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_pLastWindow.lock() != pFoundWindow) { + if (m_fMousePosDelta > *PFOLLOWMOUSETHRESHOLD || refocus) + g_pCompositor->focusWindow(pFoundWindow, foundSurface); + } else g_pCompositor->focusSurface(foundSurface, pFoundWindow); } } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 3afb1b88..7774a6db 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -255,6 +255,7 @@ class CInputManager { // used for warping back after non-mouse input Vector2D m_vLastMousePos = {}; + double m_fMousePosDelta = 0; bool m_bLastInputMouse = true; // for holding focus on buttons held From d01f9943e1d401b09fc53be3c161279ab4f2c5ba Mon Sep 17 00:00:00 2001 From: nyx Date: Mon, 17 Feb 2025 13:02:32 -0500 Subject: [PATCH 0271/1444] subsurfaces: dont try to access popup surfaces when handling subsurface updates (#9421) --- src/desktop/Popup.cpp | 7 +++++++ src/desktop/Popup.hpp | 1 + src/desktop/Subsurface.cpp | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp index 82767ead..912069e7 100644 --- a/src/desktop/Popup.cpp +++ b/src/desktop/Popup.cpp @@ -282,6 +282,9 @@ void CPopup::recheckTree() { } void CPopup::recheckChildrenRecursive() { + if (m_bInert || !m_pWLSurface) + return; + std::vector> cpy; std::ranges::for_each(m_vChildren, [&cpy](const auto& el) { cpy.emplace_back(el); }); for (auto const& c : cpy) { @@ -367,3 +370,7 @@ WP CPopup::at(const Vector2D& globalCoords, bool allowsInput) { return {}; } + +bool CPopup::inert() const { + return m_bInert; +} diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp index 0bca436c..f6ca65da 100644 --- a/src/desktop/Popup.hpp +++ b/src/desktop/Popup.hpp @@ -34,6 +34,7 @@ class CPopup { void recheckTree(); bool visible(); + bool inert() const; // will also loop over this node void breadthfirst(std::function, void*)> fn, void* data); diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp index db106a09..9846764c 100644 --- a/src/desktop/Subsurface.cpp +++ b/src/desktop/Subsurface.cpp @@ -107,7 +107,7 @@ void CSubsurface::onCommit() { g_pHyprRenderer->damageSurface(m_pWLSurface->resource(), COORDS.x, COORDS.y); - if (m_pPopupParent) + if (m_pPopupParent && !m_pPopupParent->inert() && m_pPopupParent->m_pWLSurface) m_pPopupParent->recheckTree(); if (!m_pWindowParent.expired()) // I hate you firefox why are you doing this m_pWindowParent->m_pPopupHead->recheckTree(); @@ -124,7 +124,7 @@ void CSubsurface::onCommit() { // g_pHyprRenderer->damageBox(box); CBox box; - if (m_pPopupParent) + if (m_pPopupParent && !m_pPopupParent->inert() && m_pPopupParent->m_pWLSurface) box = m_pPopupParent->m_pWLSurface->getSurfaceBoxGlobal().value_or(CBox{}); else if (m_pWindowParent) box = m_pWindowParent->getWindowMainSurfaceBox(); From e59623d1d564089543cddb496fbed30fbd6ab247 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 18 Feb 2025 00:33:27 +0000 Subject: [PATCH 0272/1444] hyprctl: don't return empty str if there are no global shortcuts fixes #6043 --- src/debug/HyprCtl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index a155474d..174eb932 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -811,8 +811,11 @@ static std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::stri std::string ret = ""; const auto SHORTCUTS = PROTO::globalShortcuts->getAllShortcuts(); if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) { - for (auto const& sh : SHORTCUTS) + for (auto const& sh : SHORTCUTS) { ret += std::format("{}:{} -> {}\n", sh.appid, sh.id, sh.description); + } + if (ret.empty()) + ret = "none"; } else { ret += "["; for (auto const& sh : SHORTCUTS) { From 3352317ca827dfb2dfd222274dfaf5941c78c086 Mon Sep 17 00:00:00 2001 From: nyx Date: Tue, 18 Feb 2025 09:18:22 -0500 Subject: [PATCH 0273/1444] scripts/generateVersion.sh: convert to posix (#9433) --- scripts/generateVersion.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/generateVersion.sh b/scripts/generateVersion.sh index e88cef3f..9313815d 100755 --- a/scripts/generateVersion.sh +++ b/scripts/generateVersion.sh @@ -2,8 +2,8 @@ # if the git directory doesn't exist, don't gather data to avoid overwriting, unless # the version file is missing altogether (otherwise compiling will fail) -if [[ ! -d ./.git ]]; then - if [[ -f ./src/version.h ]]; then +if [ ! -d ./.git ]; then + if [ -f ./src/version.h ]; then exit 0 fi fi From fb8eaba83f2d114fb346730e789a559ccc366887 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 18 Feb 2025 15:10:40 +0000 Subject: [PATCH 0274/1444] core: add an ANR dialog for xdg-shell, we can ping the wm_base, and thus render an ANR dialog if an app dies for XWayland, there probably is a similar method, but I don't know about it and don't care. --- CMakeLists.txt | 2 +- src/Compositor.cpp | 5 + src/config/ConfigManager.cpp | 1 + src/desktop/Window.cpp | 10 ++ src/desktop/Window.hpp | 4 + src/managers/ANRManager.cpp | 173 +++++++++++++++++++++++++++++++++++ src/managers/ANRManager.hpp | 46 ++++++++++ src/protocols/XDGShell.cpp | 10 ++ src/protocols/XDGShell.hpp | 5 + src/render/OpenGL.cpp | 16 +++- src/render/Renderer.cpp | 6 ++ 11 files changed, 272 insertions(+), 6 deletions(-) create mode 100644 src/managers/ANRManager.cpp create mode 100644 src/managers/ANRManager.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a98f697d..22bc7498 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION}) pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5) pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2) pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) -pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.0) +pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.1) pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1) string(REPLACE "." ";" AQ_VERSION_LIST ${aquamarine_dep_VERSION}) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 5389844f..a35e4216 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -13,6 +13,7 @@ #include "managers/SeatManager.hpp" #include "managers/VersionKeeperManager.hpp" #include "managers/DonationNagManager.hpp" +#include "managers/ANRManager.hpp" #include "managers/eventLoop/EventLoopManager.hpp" #include #include @@ -592,6 +593,7 @@ void CCompositor::cleanup() { g_pEventLoopManager.reset(); g_pVersionKeeperMgr.reset(); g_pDonationNagManager.reset(); + g_pANRManager.reset(); g_pConfigWatcher.reset(); if (m_pAqBackend) @@ -694,6 +696,9 @@ void CCompositor::initManagers(eManagersInitStage stage) { Debug::log(LOG, "Creating the DonationNag!"); g_pDonationNagManager = makeUnique(); + Debug::log(LOG, "Creating the ANRManager!"); + g_pANRManager = makeUnique(); + Debug::log(LOG, "Starting XWayland"); g_pXWayland = makeUnique(g_pCompositor->m_bWantsXwayland); } break; diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index dc56d73f..9b547ffb 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -430,6 +430,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("misc:disable_xdg_env_checks", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:disable_hyprland_qtutils_check", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:lockdead_screen_delay", Hyprlang::INT{1000}); + m_pConfig->addConfigValue("misc:enable_anr_dialog", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1}); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 7b7f954d..7c0693bf 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -13,6 +13,7 @@ #include "../config/ConfigValue.hpp" #include "../managers/TokenManager.hpp" #include "../managers/AnimationManager.hpp" +#include "../managers/ANRManager.hpp" #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../protocols/ContentType.hpp" @@ -48,6 +49,7 @@ PHLWINDOW CWindow::create(SP surface) { g_pAnimationManager->createAnimation(0.f, pWindow->m_fDimPercent, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_notRespondingTint, g_pConfigManager->getAnimationPropertyConfig("fade"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(makeUnique(pWindow)); pWindow->addWindowDeco(makeUnique(pWindow)); @@ -71,6 +73,7 @@ PHLWINDOW CWindow::create(SP resource) { g_pAnimationManager->createAnimation(0.f, pWindow->m_fDimPercent, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE); g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingToWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE); g_pAnimationManager->createAnimation(0.f, pWindow->m_fMovingFromWorkspaceAlpha, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), pWindow, AVARDAMAGE_ENTIRE); + g_pAnimationManager->createAnimation(0.f, pWindow->m_notRespondingTint, g_pConfigManager->getAnimationPropertyConfig("fade"), pWindow, AVARDAMAGE_ENTIRE); pWindow->addWindowDeco(makeUnique(pWindow)); pWindow->addWindowDeco(makeUnique(pWindow)); @@ -1796,3 +1799,10 @@ void CWindow::deactivateGroupMembers() { break; } } + +bool CWindow::isNotResponding() { + if (!m_pXDGSurface) + return false; + + return g_pANRManager->isNotResponding(m_pXDGSurface->owner.lock()); +} diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index bc32bab4..50b61050 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -388,6 +388,9 @@ class CWindow { // window tags CTagKeeper m_tags; + // ANR + PHLANIMVAR m_notRespondingTint; + // For the list lookup bool operator==(const CWindow& rhs) const { return m_pXDGSurface == rhs.m_pXDGSurface && m_pXWaylandSurface == rhs.m_pXWaylandSurface && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && @@ -480,6 +483,7 @@ class CWindow { NContentType::eContentType getContentType(); void setContentType(NContentType::eContentType contentType); void deactivateGroupMembers(); + bool isNotResponding(); CBox getWindowMainSurfaceBox() const { return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y}; diff --git a/src/managers/ANRManager.cpp b/src/managers/ANRManager.cpp new file mode 100644 index 00000000..e2b276ee --- /dev/null +++ b/src/managers/ANRManager.cpp @@ -0,0 +1,173 @@ +#include "ANRManager.hpp" +#include "../helpers/fs/FsUtils.hpp" +#include "../debug/Log.hpp" +#include "../macros.hpp" +#include "HookSystemManager.hpp" +#include "../Compositor.hpp" +#include "../protocols/XDGShell.hpp" +#include "./eventLoop/EventLoopManager.hpp" +#include "../config/ConfigValue.hpp" + +using namespace Hyprutils::OS; + +static constexpr auto TIMER_TIMEOUT = std::chrono::milliseconds(1500); + +CANRManager::CANRManager() { + if (!NFsUtils::executableExistsInPath("hyprland-dialog")) { + Debug::log(ERR, "hyprland-dialog missing from PATH, cannot start ANRManager"); + return; + } + + m_timer = makeShared(TIMER_TIMEOUT, [this](SP self, void* data) { onTick(); }, this); + g_pEventLoopManager->addTimer(m_timer); + + m_active = true; + + static auto P = g_pHookSystem->hookDynamic("openWindow", [this](void* self, SCallbackInfo& info, std::any data) { + auto window = std::any_cast(data); + + if (window->m_bIsX11) + return; + + for (const auto& w : g_pCompositor->m_vWindows) { + if (w->m_bIsX11 || w == window || !w->m_pXDGSurface) + continue; + + if (w->m_pXDGSurface->owner == window->m_pXDGSurface->owner) + return; + } + + m_data[window->m_pXDGSurface->owner] = makeShared(); + }); + + m_timer->updateTimeout(TIMER_TIMEOUT); +} + +void CANRManager::onTick() { + std::erase_if(m_data, [](const auto& e) { return e.first.expired(); }); + + static auto PENABLEANR = CConfigValue("misc:enable_anr_dialog"); + + if (!*PENABLEANR) { + m_timer->updateTimeout(TIMER_TIMEOUT * 10); + return; + } + + for (auto& [wmBase, data] : m_data) { + PHLWINDOW firstWindow; + int count = 0; + for (const auto& w : g_pCompositor->m_vWindows) { + if (!w->m_bIsMapped || w->m_bIsX11 || !w->m_pXDGSurface) + continue; + + if (w->m_pXDGSurface->owner != wmBase) + continue; + + count++; + if (!firstWindow) + firstWindow = w; + } + + if (count == 0) + continue; + + if (data->missedResponses > 0) { + if (!data->isThreadRunning() && !data->dialogThreadSaidWait) { + pid_t pid = 0; + wl_client_get_credentials(wmBase->client(), &pid, nullptr, nullptr); + data->runDialog("Application Not Responding", firstWindow->m_szTitle, firstWindow->m_szClass, pid); + + for (const auto& w : g_pCompositor->m_vWindows) { + if (!w->m_bIsMapped || w->m_bIsX11 || !w->m_pXDGSurface) + continue; + + if (w->m_pXDGSurface->owner != wmBase) + continue; + + *w->m_notRespondingTint = 0.2F; + } + } + } else if (data->isThreadRunning()) + data->killDialog(); + + if (data->missedResponses == 0) + data->dialogThreadSaidWait = false; + + data->missedResponses++; + + wmBase->ping(); + } + + m_timer->updateTimeout(TIMER_TIMEOUT); +} + +void CANRManager::onResponse(SP wmBase) { + if (!m_data.contains(wmBase)) + return; + + auto& data = m_data.at(wmBase); + data->missedResponses = 0; + if (data->isThreadRunning()) + data->killDialog(); +} + +void CANRManager::SANRData::runDialog(const std::string& title, const std::string& appName, const std::string appClass, pid_t dialogWmPID) { + if (!dialogThreadExited) + killDialog(); + + // dangerous: might lock if the above failed!! + if (dialogThread.joinable()) + dialogThread.join(); + + dialogThreadExited = false; + dialogThreadSaidWait = false; + dialogThread = std::thread([title, appName, appClass, dialogWmPID, this]() { + SP proc = + makeShared("hyprland-dialog", + std::vector{"--title", title, "--text", + std::format("Application {} with class of {} is not responding.\nWhat do you want to do with it?", appName, appClass), + "--buttons", "terminate;wait"}); + + dialogProc = proc; + proc->runSync(); + + dialogThreadExited = true; + + if (proc->stdOut().empty()) + return; + + if (proc->stdOut().starts_with("terminate")) + kill(dialogWmPID, SIGKILL); + if (proc->stdOut().starts_with("wait")) + dialogThreadSaidWait = true; + }); +} + +bool CANRManager::SANRData::isThreadRunning() { + if (dialogThread.native_handle() == 0) + return false; + if (dialogThreadExited) + return false; + return pthread_kill(dialogThread.native_handle(), 0) != ESRCH; +} + +void CANRManager::SANRData::killDialog() const { + if (!dialogProc) + return; + + kill(dialogProc->pid(), SIGKILL); +} + +CANRManager::SANRData::~SANRData() { + if (dialogThread.joinable()) { + killDialog(); + // dangerous: might lock if the above failed!! + dialogThread.join(); + } +} + +bool CANRManager::isNotResponding(SP wmBase) { + if (!m_data.contains(wmBase)) + return false; + return m_data[wmBase]->missedResponses > 1; +} diff --git a/src/managers/ANRManager.hpp b/src/managers/ANRManager.hpp new file mode 100644 index 00000000..7d67e872 --- /dev/null +++ b/src/managers/ANRManager.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "../helpers/memory/Memory.hpp" +#include "../desktop/DesktopTypes.hpp" +#include +#include +#include +#include +#include "./eventLoop/EventLoopTimer.hpp" +#include "../helpers/signal/Signal.hpp" +#include +#include + +class CXDGWMBase; + +class CANRManager { + public: + CANRManager(); + + void onResponse(SP wmBase); + bool isNotResponding(SP wmBase); + + private: + bool m_active = false; + SP m_timer; + + void onTick(); + + struct SANRData { + ~SANRData(); + + int missedResponses = 0; + std::thread dialogThread; + SP dialogProc; + std::atomic dialogThreadExited = false; + std::atomic dialogThreadSaidWait = false; + + void runDialog(const std::string& title, const std::string& appName, const std::string appClass, pid_t dialogWmPID); + bool isThreadRunning(); + void killDialog() const; + }; + + std::map, SP> m_data; +}; + +inline UP g_pANRManager; \ No newline at end of file diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index f5d1a8fa..9424a9d6 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -3,6 +3,7 @@ #include #include "../Compositor.hpp" #include "../managers/SeatManager.hpp" +#include "../managers/ANRManager.hpp" #include "../helpers/Monitor.hpp" #include "core/Seat.hpp" #include "core/Compositor.hpp" @@ -740,6 +741,11 @@ CXDGWMBase::CXDGWMBase(SP resource_) : resource(resource_) { LOGM(LOG, "New xdg_surface at {:x}", (uintptr_t)RESOURCE.get()); }); + + resource->setPong([this](CXdgWmBase* r, uint32_t serial) { + g_pANRManager->onResponse(self.lock()); + events.pong.emit(); + }); } bool CXDGWMBase::good() { @@ -750,6 +756,10 @@ wl_client* CXDGWMBase::client() { return pClient; } +void CXDGWMBase::ping() { + resource->sendPing(1337); +} + CXDGShellProtocol::CXDGShellProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { grab = makeShared(); grab->keyboard = true; diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp index 4c2b8100..b46e0236 100644 --- a/src/protocols/XDGShell.hpp +++ b/src/protocols/XDGShell.hpp @@ -241,12 +241,17 @@ class CXDGWMBase { bool good(); wl_client* client(); + void ping(); std::vector> positioners; std::vector> surfaces; WP self; + struct { + CSignal pong; + } events; + private: SP resource; wl_client* pClient = nullptr; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 3b641c36..1a296b65 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -1396,12 +1396,18 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP tex, const CB glUniform1f(shader->roundingPower, roundingPower); if (allowDim && m_RenderData.currentWindow) { - glUniform1i(shader->applyTint, 1); - const auto DIM = m_RenderData.currentWindow->m_fDimPercent->value(); - glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); - } else { + if (m_RenderData.currentWindow->m_notRespondingTint->value() > 0) { + const auto DIM = m_RenderData.currentWindow->m_notRespondingTint->value(); + glUniform1i(shader->applyTint, 1); + glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); + } else if (m_RenderData.currentWindow->m_fDimPercent->value() > 0) { + glUniform1i(shader->applyTint, 1); + const auto DIM = m_RenderData.currentWindow->m_fDimPercent->value(); + glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); + } else + glUniform1i(shader->applyTint, 0); + } else glUniform1i(shader->applyTint, 0); - } } const float verts[] = { diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b61f1c3e..f01a0d12 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -473,6 +473,12 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe if (ignorePosition) { renderdata.pos.x = pMonitor->vecPosition.x; renderdata.pos.y = pMonitor->vecPosition.y; + } else { + const bool ANR = pWindow->isNotResponding(); + if (ANR && pWindow->m_notRespondingTint->goal() != 0.2F) + *pWindow->m_notRespondingTint = 0.2F; + else if (!ANR && pWindow->m_notRespondingTint->goal() != 0.F) + *pWindow->m_notRespondingTint = 0.F; } if (standalone) From 3c1a2e9fcae6575e1f17627047c93d6e9fcc8634 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 18 Feb 2025 15:18:34 +0000 Subject: [PATCH 0275/1444] config/descriptions: add enable_anr_dialog --- src/config/ConfigDescriptions.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 1283050d..4e591fa8 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1187,6 +1187,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{1000, 0, 5000}, }, + SConfigOptionDescription{ + .value = "misc:enable_anr_dialog", + .description = "whether to enable the ANR (app not responding) dialog when your apps hang", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, /* * binds: From 0137a5f6cdd24d5a10f813572791f1e641221a5b Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 18 Feb 2025 15:20:00 +0000 Subject: [PATCH 0276/1444] anr: capitalize options --- src/managers/ANRManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/managers/ANRManager.cpp b/src/managers/ANRManager.cpp index e2b276ee..af1cb93a 100644 --- a/src/managers/ANRManager.cpp +++ b/src/managers/ANRManager.cpp @@ -126,7 +126,7 @@ void CANRManager::SANRData::runDialog(const std::string& title, const std::strin makeShared("hyprland-dialog", std::vector{"--title", title, "--text", std::format("Application {} with class of {} is not responding.\nWhat do you want to do with it?", appName, appClass), - "--buttons", "terminate;wait"}); + "--buttons", "Terminate;Wait"}); dialogProc = proc; proc->runSync(); @@ -136,9 +136,9 @@ void CANRManager::SANRData::runDialog(const std::string& title, const std::strin if (proc->stdOut().empty()) return; - if (proc->stdOut().starts_with("terminate")) + if (proc->stdOut().starts_with("Terminate")) kill(dialogWmPID, SIGKILL); - if (proc->stdOut().starts_with("wait")) + if (proc->stdOut().starts_with("Wait")) dialogThreadSaidWait = true; }); } From 6d25ef09cd6a33bcd589bd0f1e88e86fcff2dc67 Mon Sep 17 00:00:00 2001 From: nyx Date: Wed, 19 Feb 2025 10:29:39 -0500 Subject: [PATCH 0277/1444] xwayland: add INCR support for clipboard transfers (#9434) add INCR protocol support for large transfers fix write handling for partial transfers fix an issue where wayland windows could die from a paste from an xwayland window --- src/xwayland/XWM.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index a4e3289b..0899261a 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -589,9 +589,18 @@ void CXWM::handleSelectionNotify(xcb_selection_notify_event_t* e) { } bool CXWM::handleSelectionPropertyNotify(xcb_property_notify_event_t* e) { - // Debug::log(LOG, "[xwm] Selection property notify for {} target {}", e->atom, e->window); + if (e->state != XCB_PROPERTY_DELETE) + return false; - // Debug::log(ERR, "[xwm] FIXME: CXWM::handleSelectionPropertyNotify stub"); + auto it = std::ranges::find_if(clipboard.transfers, [e](const auto& t) { return t->incomingWindow == e->window; }); + if (it != clipboard.transfers.end()) { + if (!(*it)->getIncomingSelectionProp(true)) { + clipboard.transfers.erase(it); + return false; + } + getTransferData(clipboard); + return true; + } return false; } @@ -1205,8 +1214,10 @@ void CXWM::getTransferData(SXSelection& sel) { } if (transfer->propertyReply->type == HYPRATOMS["INCR"]) { - Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :("); - sel.transfers.erase(it); + transfer->incremental = true; + transfer->propertyStart = 0; + free(transfer->propertyReply); + transfer->propertyReply = nullptr; return; } @@ -1426,6 +1437,8 @@ int SXSelection::onWrite() { ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder); if (len == -1) { + if (errno == EAGAIN) + return 1; Debug::log(ERR, "[xwm] write died in transfer get"); transfers.erase(it); return 0; @@ -1436,7 +1449,13 @@ int SXSelection::onWrite() { Debug::log(LOG, "[xwm] wl client read partially: len {}", len); } else { Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len); - transfers.erase(it); + if (!transfer->incremental) { + transfers.erase(it); + } else { + free(transfer->propertyReply); + transfer->propertyReply = nullptr; + transfer->propertyStart = 0; + } } return 1; From fa246cb6ed5f486aad27c11dd46b3a26768a15d1 Mon Sep 17 00:00:00 2001 From: Mihai Fufezan Date: Thu, 20 Feb 2025 14:56:17 +0200 Subject: [PATCH 0278/1444] flake.lock: update hyprutils and aquamarine --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 38f48983..76eee761 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1739103745, - "narHash": "sha256-c53dcRaw0F4Os9WD05HwIRs9kTDZw4Mxe1XK4edEALo=", + "lastModified": 1739298463, + "narHash": "sha256-oAFv9jKwwA7d7384d2LeywDSgwhvb3ZnrwbfoWPhXsI=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "a3dda0d10ce9aa1d1dfb7a6c139ea8c2872c74bd", + "rev": "f239e5aadd6d23c48e085c2de3397e2058e54d16", "type": "github" }, "original": { @@ -238,11 +238,11 @@ ] }, "locked": { - "lastModified": 1739048933, - "narHash": "sha256-ck6MaoYvISBQKqZR+HcxXnx0wOhyCauxfVMaV5zhJxQ=", + "lastModified": 1739891528, + "narHash": "sha256-h8HOCZ/rw2Buzku+GKF77VXxrGjCSOQkLhptiEKMYg0=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "e4e018a2ca6f5a9c33511973454199e1c7c85499", + "rev": "61a5382f4b1ab578064d470b1b3d3f0df396b8ba", "type": "github" }, "original": { From 2cfa5d2408cd3e213aa0c87076ce9ada0dc08e20 Mon Sep 17 00:00:00 2001 From: Aaron Tulino <13600347+aaronjamt@users.noreply.github.com> Date: Fri, 21 Feb 2025 07:20:11 -0700 Subject: [PATCH 0279/1444] hyprctl: Add IPC support for Hyprsunset (#9315) * Add IPC support for Hyprsunset * clang-format * Add documentation --- hyprctl/Strings.hpp | 11 +++++++++++ hyprctl/main.cpp | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/hyprctl/Strings.hpp b/hyprctl/Strings.hpp index f77626a5..c70ca737 100644 --- a/hyprctl/Strings.hpp +++ b/hyprctl/Strings.hpp @@ -22,6 +22,7 @@ commands: getoption