New upstream version 0.1.9

This commit is contained in:
alan (NyxTrail) 2024-06-13 06:59:57 +00:00
parent f6be58e58e
commit 7f4eaa029d
7 changed files with 85 additions and 45 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.19)
set(HYPRCURSOR_VERSION "0.1.7")
set(HYPRCURSOR_VERSION "0.1.9")
add_compile_definitions(HYPRCURSOR_VERSION="${HYPRCURSOR_VERSION}")
project(hyprcursor

View File

@ -57,7 +57,7 @@ Util:
### Build
```sh
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF`
```
Install with:

View File

@ -5,14 +5,16 @@
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1709914708,
"narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=",
"lastModified": 1713121246,
"narHash": "sha256-502X0Q0fhN6tJK7iEUA8CghONKSatW/Mqj4Wappd++0=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2",
"rev": "78fcaa27ae9e1d782faa3ff06c8ea55ddce63706",
"type": "github"
},
"original": {
@ -23,11 +25,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1708475490,
"narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=",
"lastModified": 1712963716,
"narHash": "sha256-WKm9CvgCldeIVvRz87iOMi8CFVB1apJlkUT4GGvA0iM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0e74ca98a74bc7270d28838369593635a5db3260",
"rev": "cfd6b5fc90b15709b780a5a1619695a88505a176",
"type": "github"
},
"original": {
@ -41,7 +43,7 @@
"inputs": {
"hyprlang": "hyprlang",
"nixpkgs": "nixpkgs",
"systems": "systems_2"
"systems": "systems"
}
},
"systems": {
@ -58,21 +60,6 @@
"repo": "default-linux",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
}
},
"root": "root",

View File

@ -5,11 +5,16 @@
#include <array>
#include <format>
#include <algorithm>
#include <regex>
#include <hyprlang.hpp>
#include "internalSharedTypes.hpp"
#include "manifest.hpp"
#include "meta.hpp"
#ifndef ZIP_LENGTH_TO_END
#define ZIP_LENGTH_TO_END -1
#endif
enum eOperation {
OPERATION_CREATE = 0,
OPERATION_EXTRACT = 1,
@ -87,7 +92,7 @@ static std::optional<std::string> createCursorThemeFromPath(const std::string& p
const std::string THEMENAME = manifest.parsedData.name;
std::string out = (out_.empty() ? path.substr(0, path.find_last_of('/') + 1) : out_) + "/theme_" + THEMENAME + "/";
std::string out = (out_.empty() ? path.substr(0, path.find_last_of('/')) : out_) + "/theme_" + THEMENAME;
const std::string CURSORSSUBDIR = manifest.parsedData.cursorsDirectory;
const std::string CURSORDIR = path + "/" + CURSORSSUBDIR;
@ -98,6 +103,9 @@ static std::optional<std::string> createCursorThemeFromPath(const std::string& p
// iterate over the directory and record all cursors
for (auto& dir : std::filesystem::directory_iterator(CURSORDIR)) {
if (!std::regex_match(dir.path().stem().string(), std::regex("^[A-Za-z0-9_\\-\\.]+$")))
return "Invalid cursor directory name at " + dir.path().string() + " : characters must be within [A-Za-z0-9_\\-\\.]";
const auto METAPATH = dir.path().string() + "/meta";
auto& SHAPE = currentTheme.shapes.emplace_back(std::make_unique<SCursorShape>());
@ -113,6 +121,8 @@ static std::optional<std::string> createCursorThemeFromPath(const std::string& p
SHAPE->images.push_back(SCursorImage{i.file, i.size, i.delayMs});
}
SHAPE->overrides = meta.parsedData.overrides;
// check if we have at least one image.
for (auto& i : SHAPE->images) {
@ -178,7 +188,7 @@ static std::optional<std::string> createCursorThemeFromPath(const std::string& p
// add meta.hl
const auto METADIR = std::filesystem::exists(CURRENTCURSORSDIR + "/meta.hl") ? (CURRENTCURSORSDIR + "/meta.hl") : (CURRENTCURSORSDIR + "/meta.toml");
zip_source_t* meta = zip_source_file(zip, METADIR.c_str(), 0, 0);
zip_source_t* meta = zip_source_file(zip, METADIR.c_str(), 0, ZIP_LENGTH_TO_END);
if (!meta)
return "(1) failed to add meta " + METADIR + " to hlc";
if (zip_file_add(zip, (std::string{"meta."} + (METADIR.ends_with(".hl") ? "hl" : "toml")).c_str(), meta, ZIP_FL_ENC_UTF_8) < 0)
@ -186,9 +196,9 @@ static std::optional<std::string> createCursorThemeFromPath(const std::string& p
meta = nullptr;
// add each cursor png
// add each cursor image
for (auto& i : shape->images) {
zip_source_t* image = zip_source_file(zip, (CURRENTCURSORSDIR + "/" + i.filename).c_str(), 0, 0);
zip_source_t* image = zip_source_file(zip, (CURRENTCURSORSDIR + "/" + i.filename).c_str(), 0, ZIP_LENGTH_TO_END);
if (!image)
return "(1) failed to add image " + (CURRENTCURSORSDIR + "/" + i.filename) + " to hlc";
if (zip_file_add(zip, (i.filename).c_str(), image, ZIP_FL_ENC_UTF_8) < 0)
@ -199,9 +209,8 @@ static std::optional<std::string> createCursorThemeFromPath(const std::string& p
// close zip and write
if (zip_close(zip) < 0) {
zip_error_t ziperror;
zip_error_init_with_code(&ziperror, errp);
return "Failed to write " + OUTPUTFILE + ": " + zip_error_strerror(&ziperror);
zip_error_t* ziperror = zip_get_error(zip);
return "Failed to write " + OUTPUTFILE + ": " + zip_error_strerror(ziperror);
}
std::cout << "Written " << OUTPUTFILE << "\n";

View File

@ -47,6 +47,22 @@ namespace Hyprcursor {
eHyprcursorDataType type = HC_DATA_PNG;
};
/*!
struct for cursor manager options
*/
struct SManagerOptions {
explicit SManagerOptions();
/*!
The function used for logging by the cursor manager
*/
PHYPRCURSORLOGFUNC logFn;
/*!
Allow fallback to env and first theme found
*/
bool allowDefaultFallback;
};
/*!
Basic Hyprcursor manager.
@ -58,6 +74,8 @@ namespace Hyprcursor {
If none found, bool valid() will be false.
If loading fails, bool valid() will be false.
If theme has no valid cursor shapes, bool valid() will be false.
*/
class CHyprcursorManager {
public:
@ -66,6 +84,7 @@ namespace Hyprcursor {
\since 0.1.6
*/
CHyprcursorManager(const char* themeName, PHYPRCURSORLOGFUNC fn);
CHyprcursorManager(const char* themeName, SManagerOptions options);
~CHyprcursorManager();
/*!
@ -170,9 +189,10 @@ namespace Hyprcursor {
private:
void init(const char* themeName_);
CHyprcursorImplementation* impl = nullptr;
bool finalizedAndValid = false;
PHYPRCURSORLOGFUNC logFn = nullptr;
CHyprcursorImplementation* impl = nullptr;
bool finalizedAndValid = false;
bool allowDefaultFallback = true;
PHYPRCURSORLOGFUNC logFn = nullptr;
friend class CHyprcursorImplementation;
};

View File

@ -108,7 +108,7 @@ static std::string getFirstTheme(PHYPRCURSORLOGFUNC logfn) {
return "";
}
static std::string getFullPathForThemeName(const std::string& name, PHYPRCURSORLOGFUNC logfn) {
static std::string getFullPathForThemeName(const std::string& name, PHYPRCURSORLOGFUNC logfn, bool allowDefaultFallback) {
const auto HOMEENV = getenv("HOME");
if (!HOMEENV)
return "";
@ -134,7 +134,7 @@ static std::string getFullPathForThemeName(const std::string& name, PHYPRCURSORL
const auto MANIFESTPATH = themeDir.path().string() + "/manifest";
if (name.empty()) {
if (allowDefaultFallback && name.empty()) {
if (std::filesystem::exists(MANIFESTPATH + ".hl") || std::filesystem::exists(MANIFESTPATH + ".toml")) {
Debug::log(HC_LOG_INFO, logfn, "getFullPathForThemeName: found {}", themeDir.path().string());
return std::filesystem::canonical(themeDir.path()).string();
@ -193,14 +193,19 @@ static std::string getFullPathForThemeName(const std::string& name, PHYPRCURSORL
}
}
if (!name.empty()) { // try without name
if (allowDefaultFallback && !name.empty()) { // try without name
Debug::log(HC_LOG_INFO, logfn, "getFullPathForThemeName: failed, trying without name of {}", name);
return getFullPathForThemeName("", logfn);
return getFullPathForThemeName("", logfn, allowDefaultFallback);
}
return "";
}
SManagerOptions::SManagerOptions() {
logFn = nullptr;
allowDefaultFallback = true;
}
CHyprcursorManager::CHyprcursorManager(const char* themeName_) {
init(themeName_);
}
@ -210,16 +215,22 @@ CHyprcursorManager::CHyprcursorManager(const char* themeName_, PHYPRCURSORLOGFUN
init(themeName_);
}
CHyprcursorManager::CHyprcursorManager(const char* themeName_, SManagerOptions options) {
logFn = options.logFn;
allowDefaultFallback = options.allowDefaultFallback;
init(themeName_);
}
void CHyprcursorManager::init(const char* themeName_) {
std::string themeName = themeName_ ? themeName_ : "";
if (themeName.empty()) {
if (allowDefaultFallback && themeName.empty()) {
// try reading from env
Debug::log(HC_LOG_INFO, logFn, "CHyprcursorManager: attempting to find theme from env");
themeName = themeNameFromEnv(logFn);
}
if (themeName.empty()) {
if (allowDefaultFallback && themeName.empty()) {
// try finding first, in the hierarchy
Debug::log(HC_LOG_INFO, logFn, "CHyprcursorManager: attempting to find any theme");
themeName = getFirstTheme(logFn);
@ -234,7 +245,7 @@ void CHyprcursorManager::init(const char* themeName_) {
// initialize theme
impl = new CHyprcursorImplementation(this, logFn);
impl->themeName = themeName;
impl->themeFullDir = getFullPathForThemeName(themeName, logFn);
impl->themeFullDir = getFullPathForThemeName(themeName, logFn, allowDefaultFallback);
if (impl->themeFullDir.empty())
return;
@ -248,6 +259,11 @@ void CHyprcursorManager::init(const char* themeName_) {
return;
}
if (impl->theme.shapes.empty()) {
Debug::log(HC_LOG_ERR, logFn, "Theme {} has no valid cursor shapes\n", impl->themeName);
return;
}
finalizedAndValid = true;
}
@ -301,7 +317,7 @@ SCursorImageData** CHyprcursorManager::getShapesC(int& outSize, const char* shap
// find nearest
int leader = 13371337;
for (auto& image : impl->loadedShapes[shape.get()].images) {
if (std::abs((int)(image->side - info.size)) > leader)
if (std::abs((int)(image->side - info.size)) > std::abs((int)(leader - info.size)))
continue;
leader = image->side;

View File

@ -3,6 +3,7 @@
#include <hyprlang.hpp>
#include <toml++/toml.hpp>
#include <filesystem>
#include <regex>
#include "VarList.hpp"
@ -95,6 +96,11 @@ static Hyprlang::CParseResult parseDefineSize(const char* C, const char* V) {
RHS = LL;
}
if (!std::regex_match(RHS, std::regex("^[A-Za-z0-9_\\-\\.]+$"))) {
result.setError("Invalid cursor file name, characters must be within [A-Za-z0-9_\\-\\.] (if this seems like a mistake, check for invisible characters)");
return result;
}
size.file = RHS;
if (!size.file.ends_with(".svg")) {
@ -132,7 +138,9 @@ std::optional<std::string> CMeta::parseHL() {
meta->registerHandler(::parseDefineSize, "define_size", {.allowFlags = false});
meta->registerHandler(::parseOverride, "define_override", {.allowFlags = false});
meta->commence();
meta->parse();
const auto RESULT = meta->parse();
if (RESULT.error)
return RESULT.getError();
} catch (const char* err) { return "failed parsing meta: " + std::string{err}; }
parsedData.hotspotX = std::any_cast<Hyprlang::FLOAT>(meta->getConfigValue("hotspot_x"));