New upstream version 0.2.2
This commit is contained in:
parent
d322427bc5
commit
aa8b6130dd
|
|
@ -34,3 +34,13 @@
|
||||||
build/
|
build/
|
||||||
.vscode/
|
.vscode/
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
|
.cmake/
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles/
|
||||||
|
CTestTestfile.cmake
|
||||||
|
DartConfiguration.tcl
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
compile_commands.json
|
||||||
|
hyprutils.pc
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
cmake_minimum_required(VERSION 3.19)
|
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}")
|
add_compile_definitions(HYPRUTILS_VERSION="${HYPRUTILS_VERSION}")
|
||||||
|
|
||||||
project(hyprutils
|
project(
|
||||||
VERSION ${HYPRUTILS_VERSION}
|
hyprutils
|
||||||
DESCRIPTION "Small C++ library for utilities used across the Hypr* ecosystem"
|
VERSION ${HYPRUTILS_VERSION}
|
||||||
)
|
DESCRIPTION "Small C++ library for utilities used across the Hypr* ecosystem")
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
@ -20,11 +21,11 @@ configure_file(hyprutils.pc.in hyprutils.pc @ONLY)
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
message(STATUS "Configuring hyprutils in Debug")
|
message(STATUS "Configuring hyprutils in Debug")
|
||||||
add_compile_definitions(HYPRLAND_DEBUG)
|
add_compile_definitions(HYPRLAND_DEBUG)
|
||||||
else()
|
else()
|
||||||
add_compile_options(-O3)
|
add_compile_options(-O3)
|
||||||
message(STATUS "Configuring hyprutils in Release")
|
message(STATUS "Configuring hyprutils in Release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/*.hpp")
|
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/*.hpp")
|
||||||
|
|
@ -34,14 +35,12 @@ find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET pixman-1)
|
pkg_check_modules(deps REQUIRED IMPORTED_TARGET pixman-1)
|
||||||
|
|
||||||
add_library(hyprutils SHARED ${SRCFILES})
|
add_library(hyprutils SHARED ${SRCFILES})
|
||||||
target_include_directories( hyprutils
|
target_include_directories(
|
||||||
PUBLIC "./include"
|
hyprutils
|
||||||
PRIVATE "./src"
|
PUBLIC "./include"
|
||||||
)
|
PRIVATE "./src")
|
||||||
set_target_properties(hyprutils PROPERTIES
|
set_target_properties(hyprutils PROPERTIES VERSION ${hyprutils_VERSION}
|
||||||
VERSION ${hyprutils_VERSION}
|
SOVERSION 1)
|
||||||
SOVERSION 0
|
|
||||||
)
|
|
||||||
target_link_libraries(hyprutils PkgConfig::deps)
|
target_link_libraries(hyprutils PkgConfig::deps)
|
||||||
|
|
||||||
# tests
|
# tests
|
||||||
|
|
@ -49,25 +48,38 @@ add_custom_target(tests)
|
||||||
|
|
||||||
add_executable(hyprutils_memory "tests/memory.cpp")
|
add_executable(hyprutils_memory "tests/memory.cpp")
|
||||||
target_link_libraries(hyprutils_memory PRIVATE hyprutils PkgConfig::deps)
|
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_dependencies(tests hyprutils_memory)
|
||||||
|
|
||||||
add_executable(hyprutils_string "tests/string.cpp")
|
add_executable(hyprutils_string "tests/string.cpp")
|
||||||
target_link_libraries(hyprutils_string PRIVATE hyprutils PkgConfig::deps)
|
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_dependencies(tests hyprutils_string)
|
||||||
|
|
||||||
add_executable(hyprutils_signal "tests/signal.cpp")
|
add_executable(hyprutils_signal "tests/signal.cpp")
|
||||||
target_link_libraries(hyprutils_signal PRIVATE hyprutils PkgConfig::deps)
|
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_dependencies(tests hyprutils_signal)
|
||||||
|
|
||||||
add_executable(hyprutils_math "tests/math.cpp")
|
add_executable(hyprutils_math "tests/math.cpp")
|
||||||
target_link_libraries(hyprutils_math PRIVATE hyprutils PkgConfig::deps)
|
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)
|
add_dependencies(tests hyprutils_math)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
install(TARGETS hyprutils)
|
install(TARGETS hyprutils)
|
||||||
install(DIRECTORY "include/hyprutils" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
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)
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1717602782,
|
"lastModified": 1721138476,
|
||||||
"narHash": "sha256-pL9jeus5QpX5R+9rsp3hhZ+uplVHscNJh8n8VpqscM0=",
|
"narHash": "sha256-+W5eZOhhemLQxelojLxETfbFbc19NWawsXBlapYpqIA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e8057b67ebf307f01bdcc8fba94d94f75039d1f6",
|
"rev": "ad0b5eed1b6031efaed382844806550c3dcb4206",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,15 @@
|
||||||
(builtins.substring 4 2 longDate)
|
(builtins.substring 4 2 longDate)
|
||||||
(builtins.substring 6 2 longDate)
|
(builtins.substring 6 2 longDate)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
version = lib.removeSuffix "\n" (builtins.readFile ./VERSION);
|
||||||
in {
|
in {
|
||||||
overlays = {
|
overlays = {
|
||||||
default = self.overlays.hyprutils;
|
default = self.overlays.hyprutils;
|
||||||
hyprutils = final: prev: {
|
hyprutils = final: prev: {
|
||||||
hyprutils = final.callPackage ./nix/default.nix {
|
hyprutils = final.callPackage ./nix/default.nix {
|
||||||
stdenv = final.gcc13Stdenv;
|
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;};
|
hyprutils-with-tests = final.hyprutils.override {doCheck = true;};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,12 @@ namespace Hyprutils::Math {
|
||||||
*/
|
*/
|
||||||
Vector2D size() const;
|
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.
|
* @brief Finds the closest point within the box to a given vector.
|
||||||
* @param vec Vector from which to find the closest point.
|
* @param vec Vector from which to find the closest point.
|
||||||
|
|
@ -179,4 +185,4 @@ namespace Hyprutils::Math {
|
||||||
private:
|
private:
|
||||||
CBox roundInternal();
|
CBox roundInternal();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -49,6 +49,7 @@ namespace Hyprutils {
|
||||||
CRegion& invert(const CBox& box);
|
CRegion& invert(const CBox& box);
|
||||||
CRegion& scale(float scale);
|
CRegion& scale(float scale);
|
||||||
CRegion& scale(const Vector2D& scale);
|
CRegion& scale(const Vector2D& scale);
|
||||||
|
CRegion& expand(double units);
|
||||||
CRegion& rationalize();
|
CRegion& rationalize();
|
||||||
CBox getExtents();
|
CBox getExtents();
|
||||||
bool containsPoint(const Vector2D& vec) const;
|
bool containsPoint(const Vector2D& vec) const;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Hyprutils {
|
||||||
namespace CSharedPointer_ {
|
namespace CSharedPointer_ {
|
||||||
class impl_base {
|
class impl_base {
|
||||||
public:
|
public:
|
||||||
virtual ~impl_base(){};
|
virtual ~impl_base() {};
|
||||||
|
|
||||||
virtual void inc() noexcept = 0;
|
virtual void inc() noexcept = 0;
|
||||||
virtual void dec() noexcept = 0;
|
virtual void dec() noexcept = 0;
|
||||||
|
|
@ -31,6 +31,7 @@ namespace Hyprutils {
|
||||||
virtual void destroy() noexcept = 0;
|
virtual void destroy() noexcept = 0;
|
||||||
virtual bool destroying() noexcept = 0;
|
virtual bool destroying() noexcept = 0;
|
||||||
virtual bool dataNonNull() noexcept = 0;
|
virtual bool dataNonNull() noexcept = 0;
|
||||||
|
virtual void* getData() noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -107,6 +108,10 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool dataNonNull() noexcept {
|
virtual bool dataNonNull() noexcept {
|
||||||
|
return _data != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* getData() noexcept {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,11 +218,11 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const CSharedPointer& lhs, const CSharedPointer& rhs) const {
|
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 {
|
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 {
|
T* operator->() const {
|
||||||
|
|
@ -234,7 +239,7 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get() const {
|
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 {
|
unsigned int strongRef() const {
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ namespace Hyprutils {
|
||||||
/* create a weak ptr from a shared ptr with assignment */
|
/* create a weak ptr from a shared ptr with assignment */
|
||||||
template <typename U>
|
template <typename U>
|
||||||
validHierarchy<const CWeakPointer<U>&> operator=(const CSharedPointer<U>& rhs) {
|
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;
|
return *this;
|
||||||
|
|
||||||
decrementWeak();
|
decrementWeak();
|
||||||
|
|
@ -139,15 +139,15 @@ namespace Hyprutils {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const CWeakPointer& lhs, const CWeakPointer& rhs) const {
|
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 {
|
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 {
|
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 {
|
T* operator->() const {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Hyprutils {
|
||||||
@param delim if delimiter is 's', use std::isspace
|
@param delim if delimiter is 's', use std::isspace
|
||||||
@param removeEmpty remove empty args from argv
|
@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;
|
~CVarList() = default;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Hyprutils {
|
||||||
|
namespace Utils {
|
||||||
|
// calls a function when it goes out of scope
|
||||||
|
class CScopeGuard {
|
||||||
|
public:
|
||||||
|
CScopeGuard(const std::function<void()>& fn_);
|
||||||
|
~CScopeGuard();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void()> fn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -199,23 +199,35 @@ Vector2D Hyprutils::Math::CBox::size() const {
|
||||||
return {w, h};
|
return {w, h};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2D Hyprutils::Math::CBox::extent() const {
|
||||||
|
return pos() + size();
|
||||||
|
}
|
||||||
|
|
||||||
Vector2D Hyprutils::Math::CBox::closestPoint(const Vector2D& vec) const {
|
Vector2D Hyprutils::Math::CBox::closestPoint(const Vector2D& vec) const {
|
||||||
if (containsPoint(vec))
|
if (containsPoint(vec))
|
||||||
return vec;
|
return vec;
|
||||||
|
|
||||||
Vector2D nv = vec;
|
Vector2D nv = vec;
|
||||||
nv.x = std::clamp(nv.x, x, x + w);
|
Vector2D maxPoint = {x + w - EPSILON, y + h - EPSILON};
|
||||||
nv.y = std::clamp(nv.y, y, y + h);
|
|
||||||
|
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)
|
if (std::fabs(nv.x - x) < EPSILON)
|
||||||
nv.x = x;
|
nv.x = x;
|
||||||
else if (std::fabs(nv.x - (x + w)) < EPSILON)
|
else if (std::fabs(nv.x - (maxPoint.x)) < EPSILON)
|
||||||
nv.x = x + w;
|
nv.x = maxPoint.x;
|
||||||
|
|
||||||
if (std::fabs(nv.y - y) < EPSILON)
|
if (std::fabs(nv.y - y) < EPSILON)
|
||||||
nv.y = y;
|
nv.y = y;
|
||||||
else if (std::fabs(nv.y - (y + h)) < EPSILON)
|
else if (std::fabs(nv.y - (maxPoint.y)) < EPSILON)
|
||||||
nv.y = y + h;
|
nv.y = maxPoint.y;
|
||||||
|
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,19 @@ CRegion& Hyprutils::Math::CRegion::transform(const eTransform t, double w, doubl
|
||||||
return *this;
|
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() {
|
CRegion& Hyprutils::Math::CRegion::rationalize() {
|
||||||
intersect(CBox{-MAX_REGION_SIDE, -MAX_REGION_SIDE, MAX_REGION_SIDE * 2, MAX_REGION_SIDE * 2});
|
intersect(CBox{-MAX_REGION_SIDE, -MAX_REGION_SIDE, MAX_REGION_SIDE * 2, MAX_REGION_SIDE * 2});
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,14 +9,10 @@ using namespace Hyprutils::Memory;
|
||||||
#define WP CWeakPointer
|
#define WP CWeakPointer
|
||||||
|
|
||||||
void Hyprutils::Signal::CSignal::emit(std::any data) {
|
void Hyprutils::Signal::CSignal::emit(std::any data) {
|
||||||
bool dirty = false;
|
|
||||||
|
|
||||||
std::vector<SP<CSignalListener>> listeners;
|
std::vector<SP<CSignalListener>> listeners;
|
||||||
for (auto& l : m_vListeners) {
|
for (auto& l : m_vListeners) {
|
||||||
if (l.expired()) {
|
if (l.expired())
|
||||||
dirty = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
listeners.emplace_back(l.lock());
|
listeners.emplace_back(l.lock());
|
||||||
}
|
}
|
||||||
|
|
@ -29,10 +25,9 @@ void Hyprutils::Signal::CSignal::emit(std::any data) {
|
||||||
for (auto& l : listeners) {
|
for (auto& l : listeners) {
|
||||||
// if there is only one lock, it means the event is only held by the listeners
|
// if there is only one lock, it means the event is only held by the listeners
|
||||||
// vector and was removed during our iteration
|
// vector and was removed during our iteration
|
||||||
if (l.strongRef() == 1) {
|
if (l.strongRef() == 1)
|
||||||
dirty = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
l->emit(data);
|
l->emit(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,13 +38,17 @@ void Hyprutils::Signal::CSignal::emit(std::any data) {
|
||||||
// release SPs
|
// release SPs
|
||||||
listeners.clear();
|
listeners.clear();
|
||||||
|
|
||||||
if (dirty)
|
// we cannot release any expired refs here as one of the listeners could've removed this object and
|
||||||
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
|
// as such we'd be doing a UAF
|
||||||
}
|
}
|
||||||
|
|
||||||
CHyprSignalListener Hyprutils::Signal::CSignal::registerListener(std::function<void(std::any)> handler) {
|
CHyprSignalListener Hyprutils::Signal::CSignal::registerListener(std::function<void(std::any)> handler) {
|
||||||
CHyprSignalListener listener = makeShared<CSignalListener>(handler);
|
CHyprSignalListener listener = makeShared<CSignalListener>(handler);
|
||||||
m_vListeners.emplace_back(listener);
|
m_vListeners.emplace_back(listener);
|
||||||
|
|
||||||
|
// housekeeping: remove any stale listeners
|
||||||
|
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
|
||||||
|
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ bool Hyprutils::String::isNumber(const std::string& str, bool allowfloat) {
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool decimalParsed = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < str.length(); ++i) {
|
for (size_t i = 0; i < str.length(); ++i) {
|
||||||
const char& c = str.at(i);
|
const char& c = str.at(i);
|
||||||
|
|
||||||
|
|
@ -44,9 +46,11 @@ bool Hyprutils::String::isNumber(const std::string& str, bool allowfloat) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (str.at(0) == '-')
|
if (decimalParsed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
decimalParsed = true;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
|
|
||||||
Hyprutils::String::CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) {
|
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("");
|
m_vArgs.emplace_back("");
|
||||||
|
|
||||||
std::string args{in};
|
std::string args{in};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||||
|
|
||||||
|
using namespace Hyprutils::Utils;
|
||||||
|
|
||||||
|
Hyprutils::Utils::CScopeGuard::CScopeGuard(const std::function<void()>& fn_) : fn(fn_) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hyprutils::Utils::CScopeGuard::~CScopeGuard() {
|
||||||
|
if (fn)
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,9 @@ int main(int argc, char** argv, char** envp) {
|
||||||
EXPECT(isNumber("vvss", true), false);
|
EXPECT(isNumber("vvss", true), false);
|
||||||
EXPECT(isNumber("0.9999s", true), false);
|
EXPECT(isNumber("0.9999s", true), false);
|
||||||
EXPECT(isNumber("s0.9999", true), false);
|
EXPECT(isNumber("s0.9999", true), false);
|
||||||
|
EXPECT(isNumber("-1.0", true), true);
|
||||||
|
EXPECT(isNumber("-1..0", true), false);
|
||||||
|
EXPECT(isNumber("-10.0000000001", true), true);
|
||||||
|
|
||||||
CVarList list("hello world!", 0, 's', true);
|
CVarList list("hello world!", 0, 's', true);
|
||||||
EXPECT(list[0], "hello");
|
EXPECT(list[0], "hello");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue