Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package hyprutils for openSUSE:Factory checked in at 2024-08-09 16:14:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hyprutils (Old) and /work/SRC/openSUSE:Factory/.hyprutils.new.7232 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "hyprutils" Fri Aug 9 16:14:27 2024 rev:3 rq:1192542 version:0.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/hyprutils/hyprutils.changes 2024-06-27 16:03:20.122684154 +0200 +++ /work/SRC/openSUSE:Factory/.hyprutils.new.7232/hyprutils.changes 2024-08-09 16:14:56.115610925 +0200 @@ -1,0 +2,21 @@ +Thu Aug 8 07:39:55 UTC 2024 - Florian "sp1rit" <sp1rit@disroot.org> + +- Update to version 0.2.1: + + A small, ABI-compatible update to add Edges. + + Other: + - Add Edges type and Box::extent() for its bottom right corner + +- Changes from version 0.2.0: + + A major release which also breaks ABI compat, as such bumping the + sover. + + Fixes: + - math: avoid assert fail in std::clamp in closestPoint + - math/region: add expand + - memory: do not release pointers after emitting a signal + - adjust right and bottom box edges when getting closest point + + Other: + - avoid undefined behaviour from downcasting ptr implentation + - string: respect removeEmpty when VarList input is empty + - path: add findConfig and dir utils + +------------------------------------------------------------------- Old: ---- hyprutils-0.1.5.tar.xz New: ---- hyprutils-0.2.1.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hyprutils.spec ++++++ --- /var/tmp/diff_new_pack.v1tQsR/_old 2024-08-09 16:14:57.411665022 +0200 +++ /var/tmp/diff_new_pack.v1tQsR/_new 2024-08-09 16:14:57.411665022 +0200 @@ -17,10 +17,10 @@ # -%define sover 0 +%define sover 1 Name: hyprutils -Version: 0.1.5 +Version: 0.2.1 Release: 0 Summary: Utilities used across the Hypr* ecosystem License: BSD-3-Clause ++++++ hyprutils-0.1.5.tar.xz -> hyprutils-0.2.1.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/CMakeLists.txt new/hyprutils-0.2.1/CMakeLists.txt --- old/hyprutils-0.1.5/CMakeLists.txt 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/CMakeLists.txt 2024-07-27 18:47:29.000000000 +0200 @@ -1,12 +1,13 @@ cmake_minimum_required(VERSION 3.19) -set(HYPRUTILS_VERSION "0.1.5") +file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW) +string(STRIP ${VER_RAW} HYPRUTILS_VERSION) add_compile_definitions(HYPRUTILS_VERSION="${HYPRUTILS_VERSION}") -project(hyprutils - VERSION ${HYPRUTILS_VERSION} - DESCRIPTION "Small C++ library for utilities used across the Hypr* ecosystem" -) +project( + hyprutils + VERSION ${HYPRUTILS_VERSION} + DESCRIPTION "Small C++ library for utilities used across the Hypr* ecosystem") include(CTest) include(GNUInstallDirs) @@ -20,11 +21,11 @@ set(CMAKE_CXX_STANDARD 23) if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) - message(STATUS "Configuring hyprutils in Debug") - add_compile_definitions(HYPRLAND_DEBUG) + message(STATUS "Configuring hyprutils in Debug") + add_compile_definitions(HYPRLAND_DEBUG) else() - add_compile_options(-O3) - message(STATUS "Configuring hyprutils in Release") + add_compile_options(-O3) + message(STATUS "Configuring hyprutils in Release") endif() file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/*.hpp") @@ -34,14 +35,12 @@ pkg_check_modules(deps REQUIRED IMPORTED_TARGET pixman-1) add_library(hyprutils SHARED ${SRCFILES}) -target_include_directories( hyprutils - PUBLIC "./include" - PRIVATE "./src" -) -set_target_properties(hyprutils PROPERTIES - VERSION ${hyprutils_VERSION} - SOVERSION 0 -) +target_include_directories( + hyprutils + PUBLIC "./include" + PRIVATE "./src") +set_target_properties(hyprutils PROPERTIES VERSION ${hyprutils_VERSION} + SOVERSION 1) target_link_libraries(hyprutils PkgConfig::deps) # tests @@ -49,25 +48,38 @@ add_executable(hyprutils_memory "tests/memory.cpp") target_link_libraries(hyprutils_memory PRIVATE hyprutils PkgConfig::deps) -add_test(NAME "Memory" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests COMMAND hyprutils_memory "memory") +add_test( + NAME "Memory" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests + COMMAND hyprutils_memory "memory") add_dependencies(tests hyprutils_memory) add_executable(hyprutils_string "tests/string.cpp") target_link_libraries(hyprutils_string PRIVATE hyprutils PkgConfig::deps) -add_test(NAME "String" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests COMMAND hyprutils_string "string") +add_test( + NAME "String" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests + COMMAND hyprutils_string "string") add_dependencies(tests hyprutils_string) add_executable(hyprutils_signal "tests/signal.cpp") target_link_libraries(hyprutils_signal PRIVATE hyprutils PkgConfig::deps) -add_test(NAME "Signal" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests COMMAND hyprutils_signal "signal") +add_test( + NAME "Signal" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests + COMMAND hyprutils_signal "signal") add_dependencies(tests hyprutils_signal) add_executable(hyprutils_math "tests/math.cpp") target_link_libraries(hyprutils_math PRIVATE hyprutils PkgConfig::deps) -add_test(NAME "Math" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests COMMAND hyprutils_math "math") +add_test( + NAME "Math" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests + COMMAND hyprutils_math "math") add_dependencies(tests hyprutils_math) # Installation install(TARGETS hyprutils) install(DIRECTORY "include/hyprutils" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(FILES ${CMAKE_BINARY_DIR}/hyprutils.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(FILES ${CMAKE_BINARY_DIR}/hyprutils.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/VERSION new/hyprutils-0.2.1/VERSION --- old/hyprutils-0.1.5/VERSION 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprutils-0.2.1/VERSION 2024-07-27 18:47:29.000000000 +0200 @@ -0,0 +1 @@ +0.2.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/flake.lock new/hyprutils-0.2.1/flake.lock --- old/hyprutils-0.1.5/flake.lock 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/flake.lock 2024-07-27 18:47:29.000000000 +0200 @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1717602782, - "narHash": "sha256-pL9jeus5QpX5R+9rsp3hhZ+uplVHscNJh8n8VpqscM0=", + "lastModified": 1721138476, + "narHash": "sha256-+W5eZOhhemLQxelojLxETfbFbc19NWawsXBlapYpqIA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e8057b67ebf307f01bdcc8fba94d94f75039d1f6", + "rev": "ad0b5eed1b6031efaed382844806550c3dcb4206", "type": "github" }, "original": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/flake.nix new/hyprutils-0.2.1/flake.nix --- old/hyprutils-0.1.5/flake.nix 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/flake.nix 2024-07-27 18:47:29.000000000 +0200 @@ -23,13 +23,15 @@ (builtins.substring 4 2 longDate) (builtins.substring 6 2 longDate) ]); + + version = lib.removeSuffix "\n" (builtins.readFile ./VERSION); in { overlays = { default = self.overlays.hyprutils; hyprutils = final: prev: { hyprutils = final.callPackage ./nix/default.nix { stdenv = final.gcc13Stdenv; - version = "0.pre" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty"); + version = version + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty"); }; hyprutils-with-tests = final.hyprutils.override {doCheck = true;}; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/math/Box.hpp new/hyprutils-0.2.1/include/hyprutils/math/Box.hpp --- old/hyprutils-0.1.5/include/hyprutils/math/Box.hpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/include/hyprutils/math/Box.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -136,6 +136,12 @@ Vector2D size() const; /** + * @brief Retrieves the size of the box offset by its position. + * @return Vector2D representing the bottom right extent of the box. + */ + Vector2D extent() const; + + /** * @brief Finds the closest point within the box to a given vector. * @param vec Vector from which to find the closest point. * @return Vector2D representing the closest point within the box. @@ -179,4 +185,4 @@ private: CBox roundInternal(); }; -} \ No newline at end of file +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/math/Edges.hpp new/hyprutils-0.2.1/include/hyprutils/math/Edges.hpp --- old/hyprutils-0.1.5/include/hyprutils/math/Edges.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprutils-0.2.1/include/hyprutils/math/Edges.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -0,0 +1,110 @@ +#pragma once +#include <cstdint> + +namespace Hyprutils::Math { + + /** + * @brief Flag set of box edges + */ + class CEdges { + public: + enum eEdges : uint8_t { + NONE = 0, + TOP = 1, + LEFT = 2, + BOTTOM = 4, + RIGHT = 8, + }; + + CEdges() = default; + CEdges(eEdges edges) : m_edges(edges) {} + CEdges(uint8_t edges) : m_edges(static_cast<eEdges>(edges)) {} + + bool operator==(const CEdges& other) { + return m_edges == other.m_edges; + } + + CEdges operator|(const CEdges& other) { + return m_edges | other.m_edges; + } + + CEdges operator&(const CEdges& other) { + return m_edges & other.m_edges; + } + + CEdges operator^(const CEdges& other) { + return m_edges ^ other.m_edges; + } + + void operator|=(const CEdges& other) { + m_edges = (*this | other).m_edges; + } + + void operator&=(const CEdges& other) { + m_edges = (*this & other).m_edges; + } + + void operator^=(const CEdges& other) { + m_edges = (*this ^ other).m_edges; + } + + /** + * @return if the edge set contains the top edge. + */ + bool top() { + return m_edges & TOP; + } + + /** + * @return if the edge set contains the left edge. + */ + bool left() { + return m_edges & LEFT; + } + + /** + * @return if the edge set contains the bottom edge. + */ + bool bottom() { + return m_edges & BOTTOM; + } + + /** + * @return if the edge set contains the right edge. + */ + bool right() { + return m_edges & RIGHT; + } + + /** + * @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)); + } + + /** + * @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)); + } + + /** + * @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)); + } + + /** + * @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)); + } + + eEdges m_edges = NONE; + }; + +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/math/Region.hpp new/hyprutils-0.2.1/include/hyprutils/math/Region.hpp --- old/hyprutils-0.1.5/include/hyprutils/math/Region.hpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/include/hyprutils/math/Region.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -49,6 +49,7 @@ CRegion& invert(const CBox& box); CRegion& scale(float scale); CRegion& scale(const Vector2D& scale); + CRegion& expand(double units); CRegion& rationalize(); CBox getExtents(); bool containsPoint(const Vector2D& vec) const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/memory/SharedPtr.hpp new/hyprutils-0.2.1/include/hyprutils/memory/SharedPtr.hpp --- old/hyprutils-0.1.5/include/hyprutils/memory/SharedPtr.hpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/include/hyprutils/memory/SharedPtr.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -20,7 +20,7 @@ namespace CSharedPointer_ { class impl_base { public: - virtual ~impl_base(){}; + virtual ~impl_base() {}; virtual void inc() noexcept = 0; virtual void dec() noexcept = 0; @@ -31,6 +31,7 @@ virtual void destroy() noexcept = 0; virtual bool destroying() noexcept = 0; virtual bool dataNonNull() noexcept = 0; + virtual void* getData() noexcept = 0; }; template <typename T> @@ -107,6 +108,10 @@ } virtual bool dataNonNull() noexcept { + return _data != nullptr; + } + + virtual void* getData() noexcept { return _data; } @@ -213,11 +218,11 @@ } bool operator()(const CSharedPointer& lhs, const CSharedPointer& rhs) const { - return (uintptr_t)lhs.impl_ < (uintptr_t)rhs.impl_; + return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); } bool operator<(const CSharedPointer& rhs) const { - return (uintptr_t)impl_ < (uintptr_t)rhs.impl_; + return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); } T* operator->() const { @@ -234,7 +239,7 @@ } T* get() const { - return (T*)(impl_ ? static_cast<CSharedPointer_::impl<T>*>(impl_)->_data : nullptr); + return impl_ ? static_cast<T*>(impl_->getData()) : nullptr; } unsigned int strongRef() const { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/memory/WeakPtr.hpp new/hyprutils-0.2.1/include/hyprutils/memory/WeakPtr.hpp --- old/hyprutils-0.1.5/include/hyprutils/memory/WeakPtr.hpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/include/hyprutils/memory/WeakPtr.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -80,7 +80,7 @@ /* create a weak ptr from a shared ptr with assignment */ template <typename U> validHierarchy<const CWeakPointer<U>&> operator=(const CSharedPointer<U>& rhs) { - if ((uintptr_t)impl_ == (uintptr_t)rhs.impl_) + if (reinterpret_cast<uintptr_t>(impl_) == reinterpret_cast<uintptr_t>(rhs.impl_)) return *this; decrementWeak(); @@ -139,15 +139,15 @@ } bool operator()(const CWeakPointer& lhs, const CWeakPointer& rhs) const { - return (uintptr_t)lhs.impl_ < (uintptr_t)rhs.impl_; + return reinterpret_cast<uintptr_t>(lhs.impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); } bool operator<(const CWeakPointer& rhs) const { - return (uintptr_t)impl_ < (uintptr_t)rhs.impl_; + return reinterpret_cast<uintptr_t>(impl_) < reinterpret_cast<uintptr_t>(rhs.impl_); } T* get() const { - return (T*)(impl_ ? static_cast<CSharedPointer_::impl<T>*>(impl_)->_data : nullptr); + return impl_ ? static_cast<T*>(impl_->getData()) : nullptr; } T* operator->() const { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/path/Path.hpp new/hyprutils-0.2.1/include/hyprutils/path/Path.hpp --- old/hyprutils-0.1.5/include/hyprutils/path/Path.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprutils-0.2.1/include/hyprutils/path/Path.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -0,0 +1,42 @@ +#pragma once +#include "../string/VarList.hpp" +#include <string> +#include <optional> +#include <utility> + +namespace Hyprutils { + namespace Path { + /** Check whether a config in the form basePath/hypr/programName.conf exists. + @param basePath the path where the config will be searched + @param programName name of the program (and config file) to search for + */ + bool checkConfigExists(const std::string basePath, const std::string programName); + + /** Constructs a full config path given the basePath and programName. + @param basePath the path where the config hypr/programName.conf is located + @param programName name of the program (and config file) + */ + std::string fullConfigPath(const std::string basePath, const std::string programName); + + /** Retrieves the absolute path of the $HOME env variable. + */ + std::optional<std::string> getHome(); + + /** Retrieves a CVarList of paths from the $XDG_CONFIG_DIRS env variable. + */ + std::optional<String::CVarList> getXdgConfigDirs(); + + /** Retrieves the absolute path of the $XDG_CONFIG_HOME env variable. + */ + std::optional<std::string> getXdgConfigHome(); + + /** Searches for a config according to the XDG Base Directory specification. + Returns a pair of the full path to a config and the base path. + Returns std::nullopt in case of a non-existent value. + @param programName name of the program (and config file) + */ + + using T = std::optional<std::string>; + std::pair<T, T> findConfig(const std::string programName); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/include/hyprutils/string/VarList.hpp new/hyprutils-0.2.1/include/hyprutils/string/VarList.hpp --- old/hyprutils-0.1.5/include/hyprutils/string/VarList.hpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/include/hyprutils/string/VarList.hpp 2024-07-27 18:47:29.000000000 +0200 @@ -12,7 +12,7 @@ @param delim if delimiter is 's', use std::isspace @param removeEmpty remove empty args from argv */ - CVarList(const std::string& in, const size_t maxSize = 0, const char delim = ',', const bool removeEmpty = false); + CVarList(const std::string& in, const size_t lastArgNo = 0, const char delim = ',', const bool removeEmpty = false); ~CVarList() = default; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/src/math/Box.cpp new/hyprutils-0.2.1/src/math/Box.cpp --- old/hyprutils-0.1.5/src/math/Box.cpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/src/math/Box.cpp 2024-07-27 18:47:29.000000000 +0200 @@ -199,23 +199,35 @@ return {w, h}; } +Vector2D Hyprutils::Math::CBox::extent() const { + return pos() + size(); +} + Vector2D Hyprutils::Math::CBox::closestPoint(const Vector2D& vec) const { if (containsPoint(vec)) return vec; - Vector2D nv = vec; - nv.x = std::clamp(nv.x, x, x + w); - nv.y = std::clamp(nv.y, y, y + h); + Vector2D nv = vec; + Vector2D maxPoint = {x + w - EPSILON, y + h - EPSILON}; + + if (x < maxPoint.x) + nv.x = std::clamp(nv.x, x, maxPoint.x); + else + nv.x = x; + if (y < maxPoint.y) + nv.y = std::clamp(nv.y, y, maxPoint.y); + else + nv.y = y; if (std::fabs(nv.x - x) < EPSILON) nv.x = x; - else if (std::fabs(nv.x - (x + w)) < EPSILON) - nv.x = x + w; + else if (std::fabs(nv.x - (maxPoint.x)) < EPSILON) + nv.x = maxPoint.x; if (std::fabs(nv.y - y) < EPSILON) nv.y = y; - else if (std::fabs(nv.y - (y + h)) < EPSILON) - nv.y = y + h; + else if (std::fabs(nv.y - (maxPoint.y)) < EPSILON) + nv.y = maxPoint.y; return nv; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/src/math/Region.cpp new/hyprutils-0.2.1/src/math/Region.cpp --- old/hyprutils-0.1.5/src/math/Region.cpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/src/math/Region.cpp 2024-07-27 18:47:29.000000000 +0200 @@ -112,6 +112,19 @@ return *this; } +CRegion& Hyprutils::Math::CRegion::expand(double units) { + auto rects = getRects(); + + 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}; + add(b); + } + + return *this; +} + CRegion& Hyprutils::Math::CRegion::rationalize() { intersect(CBox{-MAX_REGION_SIDE, -MAX_REGION_SIDE, MAX_REGION_SIDE * 2, MAX_REGION_SIDE * 2}); return *this; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/src/path/Path.cpp new/hyprutils-0.2.1/src/path/Path.cpp --- old/hyprutils-0.1.5/src/path/Path.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprutils-0.2.1/src/path/Path.cpp 2024-07-27 18:47:29.000000000 +0200 @@ -0,0 +1,81 @@ +#include <hyprutils/path/Path.hpp> +#include <hyprutils/string/VarList.hpp> +#include <filesystem> + +using namespace Hyprutils; + +namespace Hyprutils::Path { + std::string fullConfigPath(std::string basePath, std::string programName) { + return basePath + "/hypr/" + programName + ".conf"; + } + + bool checkConfigExists(std::string basePath, std::string programName) { + return std::filesystem::exists(fullConfigPath(basePath, programName)); + } + + std::optional<std::string> getHome() { + static const auto homeDir = getenv("HOME"); + + if (!homeDir || !std::filesystem::path(homeDir).is_absolute()) + return std::nullopt; + + return std::string(homeDir).append("/.config"); + } + + std::optional<String::CVarList> getXdgConfigDirs() { + static const auto xdgConfigDirs = getenv("XDG_CONFIG_DIRS"); + + if (!xdgConfigDirs) + return std::nullopt; + + static const auto xdgConfigDirsList = String::CVarList(xdgConfigDirs, 0, ':'); + + return xdgConfigDirsList; + } + + std::optional<std::string> getXdgConfigHome() { + static const auto xdgConfigHome = getenv("XDG_CONFIG_HOME"); + + if (!xdgConfigHome || !std::filesystem::path(xdgConfigHome).is_absolute()) + return std::nullopt; + + return xdgConfigHome; + } + + using T = std::optional<std::string>; + std::pair<T, T> findConfig(std::string programName) { + bool xdgConfigHomeExists = false; + static const auto xdgConfigHome = getXdgConfigHome(); + if (xdgConfigHome.has_value()) { + xdgConfigHomeExists = true; + if (checkConfigExists(xdgConfigHome.value(), programName)) + return std::make_pair(fullConfigPath(xdgConfigHome.value(), programName), xdgConfigHome); + } + + bool homeExists = false; + static const auto home = getHome(); + if (home.has_value()) { + homeExists = true; + if (checkConfigExists(home.value(), programName)) + return std::make_pair(fullConfigPath(home.value(), programName), home); + } + + static const auto xdgConfigDirs = getXdgConfigDirs(); + if (xdgConfigDirs.has_value()) { + for (auto dir : xdgConfigDirs.value()) { + if (checkConfigExists(dir, programName)) + return std::make_pair(fullConfigPath(dir, programName), std::nullopt); + } + } + + if (checkConfigExists("/etc/xdg", programName)) + return std::make_pair(fullConfigPath("/etc/xdg", programName), std::nullopt); + + if (xdgConfigHomeExists) + return std::make_pair(std::nullopt, xdgConfigHome); + else if (homeExists) + return std::make_pair(std::nullopt, home); + + return std::make_pair(std::nullopt, std::nullopt); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/src/signal/Signal.cpp new/hyprutils-0.2.1/src/signal/Signal.cpp --- old/hyprutils-0.1.5/src/signal/Signal.cpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/src/signal/Signal.cpp 2024-07-27 18:47:29.000000000 +0200 @@ -9,14 +9,10 @@ #define WP CWeakPointer void Hyprutils::Signal::CSignal::emit(std::any data) { - bool dirty = false; - std::vector<SP<CSignalListener>> listeners; for (auto& l : m_vListeners) { - if (l.expired()) { - dirty = true; + if (l.expired()) continue; - } listeners.emplace_back(l.lock()); } @@ -29,10 +25,9 @@ for (auto& l : listeners) { // if there is only one lock, it means the event is only held by the listeners // vector and was removed during our iteration - if (l.strongRef() == 1) { - dirty = true; + if (l.strongRef() == 1) continue; - } + l->emit(data); } @@ -43,13 +38,17 @@ // release SPs listeners.clear(); - if (dirty) - std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); }); + // we cannot release any expired refs here as one of the listeners could've removed this object and + // as such we'd be doing a UAF } CHyprSignalListener Hyprutils::Signal::CSignal::registerListener(std::function<void(std::any)> handler) { CHyprSignalListener listener = makeShared<CSignalListener>(handler); m_vListeners.emplace_back(listener); + + // housekeeping: remove any stale listeners + std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); }); + return listener; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprutils-0.1.5/src/string/VarList.cpp new/hyprutils-0.2.1/src/string/VarList.cpp --- old/hyprutils-0.1.5/src/string/VarList.cpp 2024-06-25 13:48:22.000000000 +0200 +++ new/hyprutils-0.2.1/src/string/VarList.cpp 2024-07-27 18:47:29.000000000 +0200 @@ -6,7 +6,7 @@ using namespace Hyprutils::String; Hyprutils::String::CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) { - if (in.empty()) + if (!removeEmpty && in.empty()) m_vArgs.emplace_back(""); std::string args{in};