Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package hyprutils for openSUSE:Factory checked in at 2025-09-11 14:39:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hyprutils (Old) and /work/SRC/openSUSE:Factory/.hyprutils.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hyprutils" Thu Sep 11 14:39:53 2025 rev:10 rq:1303722 version:0.8.4 Changes: -------- --- /work/SRC/openSUSE:Factory/hyprutils/hyprutils.changes 2025-07-17 17:19:57.114714184 +0200 +++ /work/SRC/openSUSE:Factory/.hyprutils.new.1977/hyprutils.changes 2025-09-11 14:43:25.118144175 +0200 @@ -1,0 +2,19 @@ +Wed Sep 10 19:44:04 UTC 2025 - Marcus Rueckert <[email protected]> + +- Update to version 0.8.4: + - add setStdinFD to CProcess by @ikalco in #74 +- Changes from version 0.8.3: + - Add C++ cast aliases; replace existing casts and remove + redundant casts by @Kam1k4dze in #71 + - smart pointer factories should not be static by @lukasx999 in + #72 +- Changes from version 0.8.2: + - introduce CRegion foreach and cleanup clangd warnings by + @gulafaran in #65 + - some minor optimisations by @gulafaran in #66 + - memory: fix CAtomicSharedPointer mutex unlock and lifetime + issues by @PaideiaDilemma in #68 + - memory: add missing lock by @PaideiaDilemma in #69 + - mat3x3: check for finite in toString by @gulafaran in #70 + +------------------------------------------------------------------- Old: ---- hyprutils-0.8.1.tar.xz New: ---- hyprutils-0.8.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hyprutils.spec ++++++ --- /var/tmp/diff_new_pack.95rTF8/_old 2025-09-11 14:43:25.646166487 +0200 +++ /var/tmp/diff_new_pack.95rTF8/_new 2025-09-11 14:43:25.646166487 +0200 @@ -1,7 +1,7 @@ # # spec file for package hyprutils # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # Copyright (c) 2024/25 Florian "sp1rit" <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -20,7 +20,7 @@ %define sover 7 Name: hyprutils -Version: 0.8.1 +Version: 0.8.4 Release: 0 Summary: Utilities used across the Hypr* ecosystem License: BSD-3-Clause ++++++ _service ++++++ --- /var/tmp/diff_new_pack.95rTF8/_old 2025-09-11 14:43:25.682168009 +0200 +++ /var/tmp/diff_new_pack.95rTF8/_new 2025-09-11 14:43:25.686168177 +0200 @@ -3,7 +3,7 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/hyprwm/hyprutils.git</param> <param name="scm">git</param> - <param name="revision">v0.8.1</param> + <param name="revision">v0.8.4</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> </service> ++++++ hyprutils-0.8.1.tar.xz -> hyprutils-0.8.4.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/VERSION new/hyprutils-0.8.4/VERSION --- old/hyprutils-0.8.1/VERSION 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/VERSION 2025-08-25 12:23:08.000000000 +0200 @@ -1 +1 @@ -0.8.1 +0.8.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/math/Edges.hpp new/hyprutils-0.8.4/include/hyprutils/math/Edges.hpp --- old/hyprutils-0.8.1/include/hyprutils/math/Edges.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/math/Edges.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,4 +1,6 @@ #pragma once +#include "hyprutils/memory/Casts.hpp" + #include <cstdint> namespace Hyprutils::Math { @@ -18,7 +20,7 @@ CEdges() = default; CEdges(eEdges edges) : m_edges(edges) {} - CEdges(uint8_t edges) : m_edges(static_cast<eEdges>(edges)) {} + CEdges(uint8_t edges) : m_edges(Memory::sc<eEdges>(edges)) {} bool operator==(const CEdges& other) { return m_edges == other.m_edges; @@ -80,28 +82,28 @@ * @param top The state the top edge should be set to. */ void setTop(bool top) { - m_edges = static_cast<eEdges>((m_edges & ~TOP) | (TOP * top)); + m_edges = Memory::sc<eEdges>((m_edges & ~TOP) | (TOP * top)); } /** * @param left The state the left edge should be set to. */ void setLeft(bool left) { - m_edges = static_cast<eEdges>((m_edges & ~LEFT) | (LEFT * left)); + m_edges = Memory::sc<eEdges>((m_edges & ~LEFT) | (LEFT * left)); } /** * @param bottom The state the bottom edge should be set to. */ void setBottom(bool bottom) { - m_edges = static_cast<eEdges>((m_edges & ~BOTTOM) | (BOTTOM * bottom)); + m_edges = Memory::sc<eEdges>((m_edges & ~BOTTOM) | (BOTTOM * bottom)); } /** * @param right The state the right edge should be set to. */ void setRight(bool right) { - m_edges = static_cast<eEdges>((m_edges & ~RIGHT) | (RIGHT * right)); + m_edges = Memory::sc<eEdges>((m_edges & ~RIGHT) | (RIGHT * right)); } eEdges m_edges = NONE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/math/Region.hpp new/hyprutils-0.8.4/include/hyprutils/math/Region.hpp --- old/hyprutils-0.8.1/include/hyprutils/math/Region.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/math/Region.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -21,17 +21,21 @@ CRegion(pixman_box32_t* box); CRegion(const CRegion&); - CRegion(CRegion&&); + CRegion(CRegion&&) noexcept; ~CRegion(); - CRegion& operator=(CRegion&& other) { - pixman_region32_copy(&m_rRegion, other.pixman()); + CRegion& operator=(CRegion&& other) noexcept { + if (this != &other) + pixman_region32_copy(&m_rRegion, other.pixman()); + return *this; } - CRegion& operator=(CRegion& other) { - pixman_region32_copy(&m_rRegion, other.pixman()); + CRegion& operator=(const CRegion& other) { + if (this != &other) + pixman_region32_copy(&m_rRegion, other.pixman()); + return *this; } @@ -58,12 +62,24 @@ CRegion copy() const; std::vector<pixman_box32_t> getRects() const; + template <typename T> + void forEachRect(T&& cb) const { + int rectsNum = 0; + const auto* rects = pixman_region32_rectangles(&m_rRegion, &rectsNum); + for (int i = 0; i < rectsNum; ++i) { + std::forward<T>(cb)(rects[i]); + } + } // pixman_region32_t* pixman() { return &m_rRegion; } + const pixman_region32_t* pixman() const { + return &m_rRegion; + } + private: pixman_region32_t m_rRegion; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/memory/Atomic.hpp new/hyprutils-0.8.4/include/hyprutils/memory/Atomic.hpp --- old/hyprutils-0.8.1/include/hyprutils/memory/Atomic.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/memory/Atomic.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -35,6 +35,11 @@ std::lock_guard<std::recursive_mutex> lockGuard() { return std::lock_guard<std::recursive_mutex>(m_mutex); } + + // Needed when unlock order or mutex lifetime matters. + std::recursive_mutex& getMutex() { + return m_mutex; + } }; } @@ -78,28 +83,19 @@ std::swap(m_ptr, ref.m_ptr); } - CAtomicSharedPointer() noexcept { - ; // empty - } + CAtomicSharedPointer() noexcept = default; CAtomicSharedPointer(std::nullptr_t) noexcept { ; // empty } ~CAtomicSharedPointer() { - if (!m_ptr.impl_) - return; - - auto lg = implLockGuard(); - m_ptr.reset(); + reset(); } template <typename U> validHierarchy<const CAtomicSharedPointer<U>&> operator=(const CAtomicSharedPointer<U>& rhs) { - if (m_ptr.impl_) { - auto lg = implLockGuard(); - m_ptr.reset(); - } + reset(); if (!rhs.m_ptr.impl_) return *this; @@ -113,10 +109,7 @@ if (this == &rhs) return *this; - if (m_ptr.impl_) { - auto lg = implLockGuard(); - m_ptr.reset(); - } + reset(); if (!rhs.m_ptr.impl_) return *this; @@ -144,8 +137,43 @@ if (!m_ptr.impl_) return; - auto lg = implLockGuard(); - m_ptr.reset(); + // last ref and last wref? + // -> must unlock BEFORE reset + // not last ref? + // -> must unlock AFTER reset + auto& mutex = sc<Atomic_::impl<T>*>(m_ptr.impl_)->getMutex(); + mutex.lock(); + + if (m_ptr.impl_->ref() > 1) { + m_ptr.reset(); + mutex.unlock(); + return; + } + + if (m_ptr.impl_->wref() == 0) { + mutex.unlock(); // Don't hold the mutex when destroying it + m_ptr.reset(); + // mutex invalid + return; + } else { + // When the control block gets destroyed, the mutex is destroyed with it. + // Thus we must avoid attempting an unlock after impl_ has been destroyed. + // Without the workaround is no safe way of checking whether it has been destroyed or not. + // + // To avoid this altogether, keep a weak pointer here. + // This guarantees that impl_ is still valid after the reset. + CWeakPointer<T> guard = m_ptr; + m_ptr.reset(); + + // Now we can safely check if guard is the last wref. + if (guard.impl_->wref() == 1) { + mutex.unlock(); + return; // ~guard destroys impl_ and mutex + } + + guard.reset(); + mutex.unlock(); + } } T& operator*() const { @@ -178,7 +206,7 @@ private: std::lock_guard<std::recursive_mutex> implLockGuard() const { - return ((Atomic_::impl<T>*)m_ptr.impl_)->lockGuard(); + return sc<Atomic_::impl<T>*>(m_ptr.impl_)->lockGuard(); } CSharedPointer<T> m_ptr; @@ -232,28 +260,19 @@ m_ptr = ref.m_ptr; } - CAtomicWeakPointer() noexcept { - ; // empty - } + CAtomicWeakPointer() noexcept = default; CAtomicWeakPointer(std::nullptr_t) noexcept { ; // empty } ~CAtomicWeakPointer() { - if (!m_ptr.impl_) - return; - - auto lg = implLockGuard(); - m_ptr.reset(); + reset(); } template <typename U> validHierarchy<const CAtomicWeakPointer<U>&> operator=(const CAtomicWeakPointer<U>& rhs) { - if (m_ptr.impl_) { - auto lg = implLockGuard(); - m_ptr.reset(); - } + reset(); auto lg = rhs.implLockGuard(); m_ptr = rhs.m_ptr; @@ -264,10 +283,7 @@ if (this == &rhs) return *this; - if (m_ptr.impl_) { - auto lg = implLockGuard(); - m_ptr.reset(); - } + reset(); auto lg = rhs.implLockGuard(); m_ptr = rhs.m_ptr; @@ -292,8 +308,21 @@ if (!m_ptr.impl_) return; - auto lg = implLockGuard(); + // last ref and last wref? + // -> must unlock BEFORE reset + // not last ref? + // -> must unlock AFTER reset + auto& mutex = sc<Atomic_::impl<T>*>(m_ptr.impl_)->getMutex(); + mutex.lock(); + if (m_ptr.impl_->ref() == 0 && m_ptr.impl_->wref() == 1) { + mutex.unlock(); + m_ptr.reset(); + // mutex invalid + return; + } + m_ptr.reset(); + mutex.unlock(); } T& operator*() const { @@ -346,7 +375,7 @@ private: std::lock_guard<std::recursive_mutex> implLockGuard() const { - return ((Atomic_::impl<T>*)m_ptr.impl_)->lockGuard(); + return sc<Atomic_::impl<T>*>(m_ptr.impl_)->lockGuard(); } CWeakPointer<T> m_ptr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/memory/Casts.hpp new/hyprutils-0.8.4/include/hyprutils/memory/Casts.hpp --- old/hyprutils-0.8.1/include/hyprutils/memory/Casts.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprutils-0.8.4/include/hyprutils/memory/Casts.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -0,0 +1,31 @@ +#pragma once +#include <bit> +#include <utility> +namespace Hyprutils::Memory { + template <typename To, typename From> + constexpr To sc(From&& from) noexcept { + return static_cast<To>(std::forward<From>(from)); + } + + template <typename To, typename From> + constexpr To cc(From&& from) noexcept { + return const_cast<To>(std::forward<From>(from)); + } + + template <typename To, typename From> + constexpr To rc(From&& from) noexcept { + return reinterpret_cast<To>(std::forward<From>(from)); + } + + template <typename To, typename From> + constexpr To dc(From&& from) { + return dynamic_cast<To>(std::forward<From>(from)); + } + + template <typename To, typename From> + constexpr To bc(const From& from) noexcept { + return std::bit_cast<To>(from); + } +} + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/memory/SharedPtr.hpp new/hyprutils-0.8.4/include/hyprutils/memory/SharedPtr.hpp --- old/hyprutils-0.8.1/include/hyprutils/memory/SharedPtr.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/memory/SharedPtr.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -2,6 +2,7 @@ #include <cstdint> #include "ImplBase.hpp" +#include "Casts.hpp" /* This is a custom impl of std::shared_ptr. @@ -60,9 +61,7 @@ } /* creates an empty shared pointer with no implementation */ - CSharedPointer() noexcept { - ; // empty - } + CSharedPointer() noexcept = default; /* creates an empty shared pointer with no implementation */ CSharedPointer(std::nullptr_t) noexcept { @@ -114,11 +113,11 @@ } bool operator()(const CSharedPointer& lhs, const CSharedPointer& rhs) const { - return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); + return rc<uintptr_t>(lhs.impl_) < rc<uintptr_t>(rhs.impl_); } bool operator<(const CSharedPointer& rhs) const { - return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); + return rc<uintptr_t>(impl_) < rc<uintptr_t>(rhs.impl_); } T* operator->() const { @@ -135,7 +134,7 @@ } T* get() const { - return impl_ ? static_cast<T*>(impl_->getData()) : nullptr; + return impl_ ? sc<T*>(impl_->getData()) : nullptr; } unsigned int strongRef() const { @@ -183,7 +182,7 @@ }; template <typename U, typename... Args> - static CSharedPointer<U> makeShared(Args&&... args) { + [[nodiscard]] inline CSharedPointer<U> makeShared(Args&&... args) { return CSharedPointer<U>(new U(std::forward<Args>(args)...)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/memory/UniquePtr.hpp new/hyprutils-0.8.4/include/hyprutils/memory/UniquePtr.hpp --- old/hyprutils-0.8.1/include/hyprutils/memory/UniquePtr.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/memory/UniquePtr.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,6 +1,7 @@ #pragma once #include "ImplBase.hpp" +#include "Casts.hpp" /* This is a custom impl of std::unique_ptr. @@ -41,9 +42,7 @@ } /* creates an empty unique pointer with no implementation */ - CUniquePointer() noexcept { - ; // empty - } + CUniquePointer() noexcept = default; /* creates an empty unique pointer with no implementation */ CUniquePointer(std::nullptr_t) noexcept { @@ -74,7 +73,7 @@ } bool operator()(const CUniquePointer& lhs, const CUniquePointer& rhs) const { - return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); + return rc<uintptr_t>(lhs.impl_) < rc<uintptr_t>(rhs.impl_); } T* operator->() const { @@ -91,7 +90,7 @@ } T* get() const { - return impl_ ? static_cast<T*>(impl_->getData()) : nullptr; + return impl_ ? sc<T*>(impl_->getData()) : nullptr; } Impl_::impl_base* impl_ = nullptr; @@ -135,7 +134,7 @@ }; template <typename U, typename... Args> - static CUniquePointer<U> makeUnique(Args&&... args) { + [[nodiscard]] inline CUniquePointer<U> makeUnique(Args&&... args) { return CUniquePointer<U>(new U(std::forward<Args>(args)...)); } } @@ -146,4 +145,4 @@ std::size_t operator()(const Hyprutils::Memory::CUniquePointer<T>& p) const noexcept { return std::hash<void*>{}(p.impl_); } -}; \ No newline at end of file +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/memory/WeakPtr.hpp new/hyprutils-0.8.4/include/hyprutils/memory/WeakPtr.hpp --- old/hyprutils-0.8.1/include/hyprutils/memory/WeakPtr.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/memory/WeakPtr.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -2,6 +2,7 @@ #include "./SharedPtr.hpp" #include "./UniquePtr.hpp" +#include "./Casts.hpp" /* This is a Hyprland implementation of std::weak_ptr. @@ -91,7 +92,7 @@ /* create a weak ptr from a shared ptr with assignment */ template <typename U> validHierarchy<const CWeakPointer<U>&> operator=(const CSharedPointer<U>& rhs) { - if (reinterpret_cast<uintptr_t>(impl_) == reinterpret_cast<uintptr_t>(rhs.impl_)) + if (rc<uintptr_t>(impl_) == rc<uintptr_t>(rhs.impl_)) return *this; decrementWeak(); @@ -101,9 +102,7 @@ } /* create an empty weak ptr */ - CWeakPointer() { - ; - } + CWeakPointer() noexcept = default; ~CWeakPointer() { decrementWeak(); @@ -162,15 +161,15 @@ } bool operator()(const CWeakPointer& lhs, const CWeakPointer& rhs) const { - return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); + return rc<uintptr_t>(lhs.impl_) < rc<uintptr_t>(rhs.impl_); } bool operator<(const CWeakPointer& rhs) const { - return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); + return rc<uintptr_t>(impl_) < rc<uintptr_t>(rhs.impl_); } T* get() const { - return impl_ ? static_cast<T*>(impl_->getData()) : nullptr; + return impl_ ? sc<T*>(impl_->getData()) : nullptr; } T* operator->() const { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/os/Process.hpp new/hyprutils-0.8.4/include/hyprutils/os/Process.hpp --- old/hyprutils-0.8.1/include/hyprutils/os/Process.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/os/Process.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -23,6 +23,8 @@ void addEnv(const std::string& name, const std::string& value); // only for async, sync doesn't make sense + void setStdinFD(int fd); + // only for async, sync doesn't make sense void setStdoutFD(int fd); // only for async, sync doesn't make sense void setStderrFD(int fd); @@ -47,4 +49,4 @@ impl* m_impl; }; } -} \ No newline at end of file +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/include/hyprutils/signal/Signal.hpp new/hyprutils-0.8.4/include/hyprutils/signal/Signal.hpp --- old/hyprutils-0.8.1/include/hyprutils/signal/Signal.hpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/include/hyprutils/signal/Signal.hpp 2025-08-25 12:23:08.000000000 +0200 @@ -37,7 +37,7 @@ if constexpr (sizeof...(Args) == 1) // NOLINTNEXTLINE: const is reapplied by handler invocation if required - emitInternal(const_cast<void*>(static_cast<const void*>(&std::get<0>(argsTuple)))); + emitInternal(Memory::cc<void*>(Memory::sc<const void*>(&std::get<0>(argsTuple)))); else emitInternal(&argsTuple); } @@ -94,9 +94,9 @@ if constexpr (sizeof...(Args) == 0) handler(); else if constexpr (sizeof...(Args) == 1) - handler(*static_cast<std::remove_reference_t<std::tuple_element_t<0, std::tuple<RefArg<Args>...>>>*>(args)); + handler(*Memory::sc<std::remove_reference_t<std::tuple_element_t<0, std::tuple<RefArg<Args>...>>>*>(args)); else - std::apply(handler, *static_cast<std::tuple<RefArg<Args>...>*>(args)); + std::apply(handler, *Memory::sc<std::tuple<RefArg<Args>...>*>(args)); }; } }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/nix/default.nix new/hyprutils-0.8.4/nix/default.nix --- old/hyprutils-0.8.1/nix/default.nix 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/nix/default.nix 2025-08-25 12:23:08.000000000 +0200 @@ -8,13 +8,16 @@ version ? "git", doCheck ? false, debug ? false, + # whether to use the mold linker + # disable this for older machines without SSE4_2 and AVX2 support + withMold ? true, }: let inherit (builtins) foldl'; inherit (lib.lists) flatten; inherit (lib.strings) optionalString; adapters = flatten [ - stdenvAdapters.useMoldLinker + (lib.optional withMold stdenvAdapters.useMoldLinker) (lib.optional debug stdenvAdapters.keepDebugInfo) ]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/animation/BezierCurve.cpp new/hyprutils-0.8.4/src/animation/BezierCurve.cpp --- old/hyprutils-0.8.1/src/animation/BezierCurve.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/animation/BezierCurve.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,10 +1,12 @@ #include <hyprutils/animation/BezierCurve.hpp> +#include <hyprutils/memory/Casts.hpp> #include <array> #include <cmath> using namespace Hyprutils::Animation; using namespace Hyprutils::Math; +using namespace Hyprutils::Memory; void CBezierCurve::setup(const std::array<Vector2D, 2>& pVec) { // Avoid reallocations by reserving enough memory upfront @@ -21,7 +23,7 @@ // bake BAKEDPOINTS points for faster lookups // T -> X ( / BAKEDPOINTS ) for (int i = 0; i < BAKEDPOINTS; ++i) { - float const t = (i + 1) / (float)BAKEDPOINTS; + float const t = (i + 1) / sc<float>(BAKEDPOINTS); m_aPointsBaked[i] = Vector2D(getXForT(t), getYForT(t)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/math/Mat3x3.cpp new/hyprutils-0.8.4/src/math/Mat3x3.cpp --- old/hyprutils-0.8.1/src/math/Mat3x3.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/math/Mat3x3.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,11 +1,13 @@ #include <hyprutils/math/Mat3x3.hpp> #include <hyprutils/math/Vector2D.hpp> #include <hyprutils/math/Box.hpp> +#include <hyprutils/memory/Casts.hpp> #include <cmath> #include <unordered_map> #include <format> using namespace Hyprutils::Math; +using namespace Hyprutils::Memory; static std::unordered_map<eTransform, Mat3x3> transforms = { {HYPRUTILS_TRANSFORM_NORMAL, std::array<float, 9>{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}}, @@ -93,12 +95,12 @@ } Mat3x3& Mat3x3::rotate(float rot) { - multiply(std::array<float, 9>{(float)cos(rot), (float)-sin(rot), 0.0f, (float)sin(rot), (float)cos(rot), 0.0f, 0.0f, 0.0f, 1.0f}); + multiply(std::array<float, 9>{cosf(rot), -sinf(rot), 0.0f, sinf(rot), cosf(rot), 0.0f, 0.0f, 0.0f, 1.0f}); return *this; } Mat3x3& Mat3x3::scale(const Vector2D& scale_) { - multiply(std::array<float, 9>{(float)scale_.x, 0.0f, 0.0f, 0.0f, (float)scale_.y, 0.0f, 0.0f, 0.0f, 1.0f}); + multiply(std::array<float, 9>{sc<float>(scale_.x), 0.0f, 0.0f, 0.0f, sc<float>(scale_.y), 0.0f, 0.0f, 0.0f, 1.0f}); return *this; } @@ -107,7 +109,7 @@ } Mat3x3& Mat3x3::translate(const Vector2D& offset) { - multiply(std::array<float, 9>{1.0f, 0.0f, (float)offset.x, 0.0f, 1.0f, (float)offset.y, 0.0f, 0.0f, 1.0f}); + multiply(std::array<float, 9>{1.0f, 0.0f, sc<float>(offset.x), 0.0f, 1.0f, sc<float>(offset.y), 0.0f, 0.0f, 1.0f}); return *this; } @@ -117,19 +119,22 @@ } Mat3x3& Mat3x3::multiply(const Mat3x3& other) { + const float* m1 = matrix.data(); // Pointer to current matrix + const float* m2 = other.matrix.data(); // Pointer to the other matrix + std::array<float, 9> product; - product[0] = matrix[0] * other.matrix[0] + matrix[1] * other.matrix[3] + matrix[2] * other.matrix[6]; - product[1] = matrix[0] * other.matrix[1] + matrix[1] * other.matrix[4] + matrix[2] * other.matrix[7]; - product[2] = matrix[0] * other.matrix[2] + matrix[1] * other.matrix[5] + matrix[2] * other.matrix[8]; - - product[3] = matrix[3] * other.matrix[0] + matrix[4] * other.matrix[3] + matrix[5] * other.matrix[6]; - product[4] = matrix[3] * other.matrix[1] + matrix[4] * other.matrix[4] + matrix[5] * other.matrix[7]; - product[5] = matrix[3] * other.matrix[2] + matrix[4] * other.matrix[5] + matrix[5] * other.matrix[8]; - - product[6] = matrix[6] * other.matrix[0] + matrix[7] * other.matrix[3] + matrix[8] * other.matrix[6]; - product[7] = matrix[6] * other.matrix[1] + matrix[7] * other.matrix[4] + matrix[8] * other.matrix[7]; - product[8] = matrix[6] * other.matrix[2] + matrix[7] * other.matrix[5] + matrix[8] * other.matrix[8]; + product[0] = m1[0] * m2[0] + m1[1] * m2[3] + m1[2] * m2[6]; + product[1] = m1[0] * m2[1] + m1[1] * m2[4] + m1[2] * m2[7]; + product[2] = m1[0] * m2[2] + m1[1] * m2[5] + m1[2] * m2[8]; + + product[3] = m1[3] * m2[0] + m1[4] * m2[3] + m1[5] * m2[6]; + product[4] = m1[3] * m2[1] + m1[4] * m2[4] + m1[5] * m2[7]; + product[5] = m1[3] * m2[2] + m1[4] * m2[5] + m1[5] * m2[8]; + + product[6] = m1[6] * m2[0] + m1[7] * m2[3] + m1[8] * m2[6]; + product[7] = m1[6] * m2[1] + m1[7] * m2[4] + m1[8] * m2[7]; + product[8] = m1[6] * m2[2] + m1[7] * m2[5] + m1[8] * m2[8]; matrix = product; return *this; @@ -140,6 +145,11 @@ } std::string Mat3x3::toString() const { + for (const auto& m : matrix) { + if (!std::isfinite(m)) + return "[mat3x3: invalid values]"; + } + return std::format("[mat3x3: {}, {}, {}, {}, {}, {}, {}, {}, {}]", matrix.at(0), matrix.at(1), matrix.at(2), matrix.at(3), matrix.at(4), matrix.at(5), matrix.at(6), matrix.at(7), matrix.at(8)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/math/Region.cpp new/hyprutils-0.8.4/src/math/Region.cpp --- old/hyprutils-0.8.1/src/math/Region.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/math/Region.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,7 +1,9 @@ +#include "hyprutils/memory/Casts.hpp" #include <hyprutils/math/Region.hpp> #include <cmath> using namespace Hyprutils::Math; +using namespace Hyprutils::Memory; constexpr const int64_t MAX_REGION_SIDE = 10000000; @@ -28,10 +30,10 @@ Hyprutils::Math::CRegion::CRegion(const CRegion& other) { pixman_region32_init(&m_rRegion); - pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman()); + pixman_region32_copy(&m_rRegion, other.pixman()); } -Hyprutils::Math::CRegion::CRegion(CRegion&& other) { +Hyprutils::Math::CRegion::CRegion(CRegion&& other) noexcept { pixman_region32_init(&m_rRegion); pixman_region32_copy(&m_rRegion, other.pixman()); } @@ -46,12 +48,12 @@ } CRegion& Hyprutils::Math::CRegion::set(const CRegion& other) { - pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman()); + pixman_region32_copy(&m_rRegion, other.pixman()); return *this; } CRegion& Hyprutils::Math::CRegion::add(const CRegion& other) { - pixman_region32_union(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman()); + pixman_region32_union(&m_rRegion, &m_rRegion, other.pixman()); return *this; } @@ -66,12 +68,12 @@ } CRegion& Hyprutils::Math::CRegion::subtract(const CRegion& other) { - pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman()); + pixman_region32_subtract(&m_rRegion, &m_rRegion, other.pixman()); return *this; } CRegion& Hyprutils::Math::CRegion::intersect(const CRegion& other) { - pixman_region32_intersect(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman()); + pixman_region32_intersect(&m_rRegion, &m_rRegion, other.pixman()); return *this; } @@ -86,7 +88,7 @@ } CRegion& Hyprutils::Math::CRegion::invert(const CBox& box) { - pixman_box32 pixmanBox = {.x1 = (int32_t)box.x, .y1 = (int32_t)box.y, .x2 = (int32_t)box.w + (int32_t)box.x, .y2 = (int32_t)box.h + (int32_t)box.y}; + pixman_box32 pixmanBox = {.x1 = sc<int32_t>(box.x), .y1 = sc<int32_t>(box.y), .x2 = sc<int32_t>(box.w) + sc<int32_t>(box.x), .y2 = sc<int32_t>(box.h) + sc<int32_t>(box.y)}; return this->invert(&pixmanBox); } @@ -104,7 +106,7 @@ clear(); for (auto& r : rects) { - CBox xfmd{(double)r.x1, (double)r.y1, (double)r.x2 - r.x1, (double)r.y2 - r.y1}; + CBox xfmd{r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1}; xfmd.transform(t, w, h); add(xfmd); } @@ -118,7 +120,7 @@ clear(); for (auto& r : rects) { - CBox b{(double)r.x1 - units, (double)r.y1 - units, (double)r.x2 - r.x1 + (units * 2), (double)r.y2 - r.y1 + (units * 2)}; + CBox b{sc<double>(r.x1) - units, sc<double>(r.y1) - units, sc<double>(r.x2) - r.x1 + (units * 2), sc<double>(r.y2) - r.y1 + (units * 2)}; add(b); } @@ -171,7 +173,7 @@ CBox Hyprutils::Math::CRegion::getExtents() { pixman_box32_t* box = pixman_region32_extents(&m_rRegion); - return {(double)box->x1, (double)box->y1, (double)box->x2 - box->x1, (double)box->y2 - box->y1}; + return {sc<double>(box->x1), sc<double>(box->y1), sc<double>(box->x2) - box->x1, sc<double>(box->y2) - box->y1}; } bool Hyprutils::Math::CRegion::containsPoint(const Vector2D& vec) const { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/math/Vector2D.cpp new/hyprutils-0.8.4/src/math/Vector2D.cpp --- old/hyprutils-0.8.1/src/math/Vector2D.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/math/Vector2D.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,15 +1,17 @@ #include <hyprutils/math/Vector2D.hpp> +#include <hyprutils/memory/Casts.hpp> #include <hyprutils/math/Misc.hpp> #include <algorithm> #include <cmath> using namespace Hyprutils::Math; +using namespace Hyprutils::Memory; Hyprutils::Math::Vector2D::Vector2D(double xx, double yy) : x(xx), y(yy) { ; } -Hyprutils::Math::Vector2D::Vector2D(int xx, int yy) : x((double)xx), y((double)yy) { +Hyprutils::Math::Vector2D::Vector2D(int xx, int yy) : x(sc<double>(xx)), y(sc<double>(yy)) { ; } @@ -59,23 +61,14 @@ Vector2D Hyprutils::Math::Vector2D::transform(eTransform transform, const Vector2D& monitorSize) const { switch (transform) { - case HYPRUTILS_TRANSFORM_NORMAL: - return *this; - case HYPRUTILS_TRANSFORM_90: - return Vector2D(y, monitorSize.y - x); - case HYPRUTILS_TRANSFORM_180: - return Vector2D(monitorSize.x - x, monitorSize.y - y); - case HYPRUTILS_TRANSFORM_270: - return Vector2D(monitorSize.x - y, x); - case HYPRUTILS_TRANSFORM_FLIPPED: - return Vector2D(monitorSize.x - x, y); - case HYPRUTILS_TRANSFORM_FLIPPED_90: - return Vector2D(y, x); - case HYPRUTILS_TRANSFORM_FLIPPED_180: - return Vector2D(x, monitorSize.y - y); - case HYPRUTILS_TRANSFORM_FLIPPED_270: - return Vector2D(monitorSize.x - y, monitorSize.y - x); - default: - return *this; + case HYPRUTILS_TRANSFORM_NORMAL: return *this; + case HYPRUTILS_TRANSFORM_90: return Vector2D(y, monitorSize.y - x); + case HYPRUTILS_TRANSFORM_180: return Vector2D(monitorSize.x - x, monitorSize.y - y); + case HYPRUTILS_TRANSFORM_270: return Vector2D(monitorSize.x - y, x); + case HYPRUTILS_TRANSFORM_FLIPPED: return Vector2D(monitorSize.x - x, y); + case HYPRUTILS_TRANSFORM_FLIPPED_90: return Vector2D(y, x); + case HYPRUTILS_TRANSFORM_FLIPPED_180: return Vector2D(x, monitorSize.y - y); + case HYPRUTILS_TRANSFORM_FLIPPED_270: return Vector2D(monitorSize.x - y, monitorSize.y - x); + default: return *this; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/os/Process.cpp new/hyprutils-0.8.4/src/os/Process.cpp --- old/hyprutils-0.8.1/src/os/Process.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/os/Process.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -1,5 +1,7 @@ #include <hyprutils/os/Process.hpp> +#include <hyprutils/memory/Casts.hpp> using namespace Hyprutils::OS; +using namespace Hyprutils::Memory; #include <csignal> #include <cstdio> @@ -17,7 +19,7 @@ std::vector<std::string> args; std::vector<std::pair<std::string, std::string>> env; pid_t grandchildPid = 0; - int stdoutFD = -1, stderrFD = -1, exitCode = 0; + int stdoutFD = -1, stderrFD = -1, exitCode = 0, stdinFD = -1; }; Hyprutils::OS::CProcess::CProcess(const std::string& binary, const std::vector<std::string>& args) : m_impl(new impl()) { @@ -61,7 +63,7 @@ dup2(errPipe[1], 2 /* stderr */); // build argv - std::vector<const char*> argsC; + std::vector<char*> argsC; argsC.emplace_back(strdup(m_impl->binary.c_str())); for (auto& arg : m_impl->args) { // TODO: does this leak? Can we just pipe c_str() as the strings won't be realloc'd? @@ -75,7 +77,7 @@ setenv(n.c_str(), v.c_str(), 1); } - execvp(m_impl->binary.c_str(), (char* const*)argsC.data()); + execvp(m_impl->binary.c_str(), argsC.data()); exit(1); } else { // parent @@ -129,7 +131,7 @@ if (pollfds[0].revents & POLLIN) { while ((ret = read(outPipe[0], buf.data(), 1023)) > 0) { - m_impl->out += std::string_view{(char*)buf.data(), (size_t)ret}; + m_impl->out += std::string_view{buf.data(), sc<size_t>(ret)}; } buf.fill(0); @@ -137,7 +139,7 @@ if (pollfds[1].revents & POLLIN) { while ((ret = read(errPipe[0], buf.data(), 1023)) > 0) { - m_impl->err += std::string_view{(char*)buf.data(), (size_t)ret}; + m_impl->err += std::string_view{buf.data(), sc<size_t>(ret)}; } buf.fill(0); @@ -146,13 +148,13 @@ // Final reads. Nonblock, so its ok. while ((ret = read(outPipe[0], buf.data(), 1023)) > 0) { - m_impl->out += std::string_view{(char*)buf.data(), (size_t)ret}; + m_impl->out += std::string_view{buf.data(), sc<size_t>(ret)}; } buf.fill(0); while ((ret = read(errPipe[0], buf.data(), 1023)) > 0) { - m_impl->err += std::string_view{(char*)buf.data(), (size_t)ret}; + m_impl->err += std::string_view{buf.data(), sc<size_t>(ret)}; } buf.fill(0); @@ -198,7 +200,7 @@ close(socket[0]); close(socket[1]); // build argv - std::vector<const char*> argsC; + std::vector<char*> argsC; argsC.emplace_back(strdup(m_impl->binary.c_str())); for (auto& arg : m_impl->args) { argsC.emplace_back(strdup(arg.c_str())); @@ -211,12 +213,20 @@ setenv(n.c_str(), v.c_str(), 1); } - if (m_impl->stdoutFD != -1) - dup2(m_impl->stdoutFD, 1); - if (m_impl->stderrFD != -1) - dup2(m_impl->stderrFD, 2); + if (m_impl->stdinFD != -1) { + dup2(m_impl->stdinFD, STDIN_FILENO); + close(m_impl->stdinFD); + } + if (m_impl->stdoutFD != -1) { + dup2(m_impl->stdoutFD, STDOUT_FILENO); + close(m_impl->stdoutFD); + } + if (m_impl->stderrFD != -1) { + dup2(m_impl->stderrFD, STDERR_FILENO); + close(m_impl->stderrFD); + } - execvp(m_impl->binary.c_str(), (char* const*)argsC.data()); + execvp(m_impl->binary.c_str(), argsC.data()); _exit(0); } close(socket[0]); @@ -262,6 +272,10 @@ return m_impl->exitCode; } +void Hyprutils::OS::CProcess::setStdinFD(int fd) { + m_impl->stdinFD = fd; +} + void Hyprutils::OS::CProcess::setStdoutFD(int fd) { m_impl->stdoutFD = fd; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/signal/Listener.cpp new/hyprutils-0.8.4/src/signal/Listener.cpp --- old/hyprutils-0.8.1/src/signal/Listener.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/signal/Listener.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -16,5 +16,5 @@ void Hyprutils::Signal::CSignalListener::emit(std::any data) { auto dataTuple = std::tuple<std::any>(data); - emitInternal(static_cast<void*>(&dataTuple)); + emitInternal(&dataTuple); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/src/signal/Signal.cpp new/hyprutils-0.8.4/src/signal/Signal.cpp --- old/hyprutils-0.8.1/src/signal/Signal.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/src/signal/Signal.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -11,6 +11,7 @@ void Hyprutils::Signal::CSignalBase::emitInternal(void* args) { std::vector<SP<CSignalListener>> listeners; + listeners.reserve(m_vListeners.size()); for (auto& l : m_vListeners) { if (l.expired()) continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.8.1/tests/animation.cpp new/hyprutils-0.8.4/tests/animation.cpp --- old/hyprutils-0.8.1/tests/animation.cpp 2025-07-07 13:34:25.000000000 +0200 +++ new/hyprutils-0.8.4/tests/animation.cpp 2025-08-25 12:23:08.000000000 +0200 @@ -62,7 +62,7 @@ switch (PAV->m_Type) { case eAVTypes::INT: { - auto avInt = dynamic_cast<CAnimatedVariable<int>*>(PAV.get()); + auto avInt = dc<CAnimatedVariable<int>*>(PAV.get()); if (!avInt) std::cout << Colors::RED << "Dynamic cast upcast failed" << Colors::RESET; @@ -70,7 +70,7 @@ avInt->value() = avInt->begun() + (DELTA * POINTY); } break; case eAVTypes::TEST: { - auto avCustom = dynamic_cast<CAnimatedVariable<SomeTestType>*>(PAV.get()); + auto avCustom = dc<CAnimatedVariable<SomeTestType>*>(PAV.get()); if (!avCustom) std::cout << Colors::RED << "Dynamic cast upcast failed" << Colors::RESET; @@ -93,7 +93,7 @@ constexpr const eAVTypes EAVTYPE = std::is_same_v<VarType, int> ? eAVTypes::INT : eAVTypes::TEST; const auto PAV = makeShared<CGenericAnimatedVariable<VarType, EmtpyContext>>(); - PAV->create(EAVTYPE, static_cast<CAnimationManager*>(this), PAV, v); + PAV->create(EAVTYPE, sc<CAnimationManager*>(this), PAV, v); PAV->setConfig(animationTree.getConfig(animationConfigName)); av = std::move(PAV); } @@ -348,7 +348,7 @@ *s.m_iA = 5; s.m_iA->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> v) { endCallbackRan++; - const auto PAV = dynamic_cast<CAnimatedVariable<int>*>(v.lock().get()); + const auto PAV = dc<CAnimatedVariable<int>*>(v.lock().get()); *PAV = 10; PAV->setCallbackOnEnd([&endCallbackRan](WP<CBaseAnimatedVariable> v) { endCallbackRan++; }); ++++++ hyprutils.obsinfo ++++++ --- /var/tmp/diff_new_pack.95rTF8/_old 2025-09-11 14:43:25.782172235 +0200 +++ /var/tmp/diff_new_pack.95rTF8/_new 2025-09-11 14:43:25.786172403 +0200 @@ -1,5 +1,5 @@ name: hyprutils -version: 0.8.1 -mtime: 1751888065 -commit: a8229739cf36d159001cfc203871917b83fdf917 +version: 0.8.4 +mtime: 1756117388 +commit: b2ae3204845f5f2f79b4703b441252d8ad2ecfd0
