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" <sp1...@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};

Reply via email to