Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hyprpm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0

find_package(glaze QUIET)
if (NOT glaze_FOUND)
set(GLAZE_VERSION v5.1.1)
set(GLAZE_VERSION v6.1.0)
message(STATUS "glaze dependency not found, retrieving ${GLAZE_VERSION} with FetchContent")
include(FetchContent)
FetchContent_Declare(
Expand Down
6 changes: 3 additions & 3 deletions hyprpm/src/core/DataState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void DataState::updateGlobalState(const SGlobalState& state) {
// clang-format off
auto DATA = toml::table{
{"state", toml::table{
{"hash", state.headersHashCompiled},
{"hash", state.headersAbiCompiled},
{"dont_warn_install", state.dontWarnInstall}
}}
};
Expand All @@ -206,8 +206,8 @@ SGlobalState DataState::getGlobalState() {
auto DATA = toml::parse_file(stateFile.c_str());

SGlobalState state;
state.headersHashCompiled = DATA["state"]["hash"].value_or("");
state.dontWarnInstall = DATA["state"]["dont_warn_install"].value_or(false);
state.headersAbiCompiled = DATA["state"]["hash"].value_or("");
state.dontWarnInstall = DATA["state"]["dont_warn_install"].value_or(false);

return state;
}
Expand Down
4 changes: 2 additions & 2 deletions hyprpm/src/core/DataState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include "Plugin.hpp"

struct SGlobalState {
std::string headersHashCompiled = "";
bool dontWarnInstall = false;
std::string headersAbiCompiled = "";
bool dontWarnInstall = false;
};

namespace DataState {
Expand Down
61 changes: 29 additions & 32 deletions hyprpm/src/core/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,40 +78,30 @@ SHyprlandVersion CPluginManager::getHyprlandVersion(bool running) {
else
onceInstalled = true;

const auto HLVERCALL = running ? NHyprlandSocket::send("/version") : execAndGet("Hyprland --version");
if (m_bVerbose)
std::println("{}", verboseString("{} version returned: {}", running ? "running" : "installed", HLVERCALL));
const auto HLVERCALL = running ? NHyprlandSocket::send("j/version") : execAndGet("Hyprland --version-json");

auto jsonQuery = glz::read_json<glz::generic>(HLVERCALL);

if (!HLVERCALL.contains("Tag:")) {
std::println(stderr, "\n{}", failureString("You don't seem to be running Hyprland."));
if (!jsonQuery) {
std::println("{}", failureString("failed to get the current hyprland version. Are you running hyprland?"));
return SHyprlandVersion{};
}

std::string hlcommit = HLVERCALL.substr(HLVERCALL.find("at commit") + 10);
hlcommit = hlcommit.substr(0, hlcommit.find_first_of(' '));

std::string hlbranch = HLVERCALL.substr(HLVERCALL.find("from branch") + 12);
hlbranch = hlbranch.substr(0, hlbranch.find(" at commit "));

std::string hldate = HLVERCALL.substr(HLVERCALL.find("Date: ") + 6);
hldate = hldate.substr(0, hldate.find('\n'));

std::string hlcommits;
auto hlbranch = (*jsonQuery)["branch"].get_string();
auto hlcommit = (*jsonQuery)["commit"].get_string();
auto abiHash = (*jsonQuery)["abiHash"].get_string();
auto hldate = (*jsonQuery)["commit_date"].get_string();
auto hlcommits = (*jsonQuery)["commits"].get_string();

if (HLVERCALL.contains("commits:")) {
hlcommits = HLVERCALL.substr(HLVERCALL.find("commits:") + 9);
hlcommits = hlcommits.substr(0, hlcommits.find(' '));
}

int commits = 0;
size_t commits = 0;
try {
commits = std::stoi(hlcommits);
commits = std::stoull(hlcommits);
} catch (...) { ; }

if (m_bVerbose)
std::println("{}", verboseString("parsed commit {} at branch {} on {}, commits {}", hlcommit, hlbranch, hldate, commits));

auto ver = SHyprlandVersion{hlbranch, hlcommit, hldate, commits};
auto ver = SHyprlandVersion{hlbranch, hlcommit, hldate, abiHash, commits};

if (running)
verRunning = ver;
Expand Down Expand Up @@ -161,7 +151,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
DataState::updateGlobalState(GLOBALSTATE);
}

if (GLOBALSTATE.headersHashCompiled.empty()) {
if (GLOBALSTATE.headersAbiCompiled.empty()) {
std::println("\n{}", failureString("Cannot find headers in the global state. Try running hyprpm update first."));
return false;
}
Expand Down Expand Up @@ -444,6 +434,12 @@ eHeadersErrors CPluginManager::headersValid() {
if (hash != HLVER.hash)
return HEADERS_MISMATCHED;

// check ABI hash too
const auto GLOBALSTATE = DataState::getGlobalState();

if (GLOBALSTATE.headersAbiCompiled != HLVER.abiHash)
return HEADERS_ABI_MISMATCH;

return HEADERS_OK;
}

Expand Down Expand Up @@ -589,14 +585,14 @@ bool CPluginManager::updateHeaders(bool force) {
std::filesystem::remove_all(WORKINGDIR);

auto HEADERSVALID = headersValid();
if (HEADERSVALID == HEADERS_OK) {
if (HEADERSVALID == HEADERS_OK || HEADERSVALID == HEADERS_MISMATCHED || HEADERSVALID == HEADERS_ABI_MISMATCH) {
progress.printMessageAbove(successString("installed headers"));
progress.m_iSteps = 5;
progress.m_szCurrentMessage = "Done!";
progress.print();

auto GLOBALSTATE = DataState::getGlobalState();
GLOBALSTATE.headersHashCompiled = HLVER.hash;
auto GLOBALSTATE = DataState::getGlobalState();
GLOBALSTATE.headersAbiCompiled = HLVER.abiHash;
DataState::updateGlobalState(GLOBALSTATE);

std::print("\n");
Expand Down Expand Up @@ -787,8 +783,8 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
progress.m_szCurrentMessage = "Updating global state...";
progress.print();

auto GLOBALSTATE = DataState::getGlobalState();
GLOBALSTATE.headersHashCompiled = HLVER.hash;
auto GLOBALSTATE = DataState::getGlobalState();
GLOBALSTATE.headersAbiCompiled = HLVER.abiHash;
DataState::updateGlobalState(GLOBALSTATE);

progress.m_iSteps++;
Expand Down Expand Up @@ -828,7 +824,7 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState(bool forceReload)
}
const auto HYPRPMPATH = DataState::getDataStatePath();

const auto json = glz::read_json<glz::json_t::array_t>(NHyprlandSocket::send("j/plugins list"));
const auto json = glz::read_json<glz::generic::array_t>(NHyprlandSocket::send("j/plugins list"));
if (!json) {
std::println(stderr, "PluginManager: couldn't parse plugin list output");
return LOADSTATE_FAIL;
Expand Down Expand Up @@ -913,9 +909,9 @@ bool CPluginManager::loadUnloadPlugin(const std::string& path, bool load) {
auto state = DataState::getGlobalState();
auto HLVER = getHyprlandVersion(true);

if (state.headersHashCompiled != HLVER.hash) {
if (state.headersAbiCompiled != HLVER.hash) {
if (load)
std::println("{}", infoString("Running Hyprland version ({}) differs from plugin state ({}), please restart Hyprland.", HLVER.hash, state.headersHashCompiled));
std::println("{}", infoString("Running Hyprland version ({}) differs from plugin state ({}), please restart Hyprland.", HLVER.hash, state.headersAbiCompiled));
return false;
}

Expand Down Expand Up @@ -956,6 +952,7 @@ std::string CPluginManager::headerError(const eHeadersErrors err) {
case HEADERS_MISMATCHED: return failureString("Headers version mismatch. Please run hyprpm update to fix those.\n");
case HEADERS_NOT_HYPRLAND: return failureString("It doesn't seem you are running on hyprland.\n");
case HEADERS_MISSING: return failureString("Headers missing. Please run hyprpm update to fix those.\n");
case HEADERS_ABI_MISMATCH: return failureString("ABI is mismatched. Please run hyprpm update to fix that.\n");
case HEADERS_DUPLICATED: {
return failureString("Headers duplicated!!! This is a very bad sign.\n"
"This could be due to e.g. installing hyprland manually while a system package of hyprland is also installed.\n"
Expand Down
2 changes: 2 additions & 0 deletions hyprpm/src/core/PluginManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum eHeadersErrors {
HEADERS_MISSING,
HEADERS_CORRUPTED,
HEADERS_MISMATCHED,
HEADERS_ABI_MISMATCH,
HEADERS_DUPLICATED
};

Expand All @@ -36,6 +37,7 @@ struct SHyprlandVersion {
std::string branch;
std::string hash;
std::string date;
std::string abiHash;
int commits = 0;
};

Expand Down
4 changes: 2 additions & 2 deletions hyprpm/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ int main(int argc, char** argv, char** envp) {
const auto HLVER = g_pPluginManager->getHyprlandVersion();
auto GLOBALSTATE = DataState::getGlobalState();

if (GLOBALSTATE.headersHashCompiled != HLVER.hash) {
if (GLOBALSTATE.headersAbiCompiled != HLVER.abiHash) {
std::println(stderr, "{}", failureString("Headers outdated, please run hyprpm update."));
return 1;
}
Expand Down Expand Up @@ -137,7 +137,7 @@ int main(int argc, char** argv, char** envp) {
if (headers) {
const auto HLVER = g_pPluginManager->getHyprlandVersion(false);
auto GLOBALSTATE = DataState::getGlobalState();
const auto COMPILEDOUTDATED = HLVER.hash != GLOBALSTATE.headersHashCompiled;
const auto COMPILEDOUTDATED = HLVER.abiHash != GLOBALSTATE.headersAbiCompiled;

bool ret1 = g_pPluginManager->updatePlugins(!headersValid || force || COMPILEDOUTDATED);

Expand Down
7 changes: 6 additions & 1 deletion src/debug/HyprCtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,9 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
result += "\n";
result += getBuiltSystemLibraryNames();
result += "\n";
result += "Version ABI string: ";
result += __hyprland_api_get_hash();
result += "\n";

#if (!ISDEBUG && !defined(NO_XWAYLAND))
result += "no flags were set\n";
Expand Down Expand Up @@ -1097,10 +1100,12 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
"systemHyprutils": "{}",
"systemHyprcursor": "{}",
"systemHyprgraphics": "{}",
"abiHash": "{}",
"flags": [)#",
GIT_BRANCH, GIT_COMMIT_HASH, HYPRLAND_VERSION, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG,
GIT_COMMITS, AQUAMARINE_VERSION, HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION, getSystemLibraryVersion("aquamarine"),
getSystemLibraryVersion("hyprlang"), getSystemLibraryVersion("hyprutils"), getSystemLibraryVersion("hyprcursor"), getSystemLibraryVersion("hyprgraphics"));
getSystemLibraryVersion("hyprlang"), getSystemLibraryVersion("hyprutils"), getSystemLibraryVersion("hyprcursor"), getSystemLibraryVersion("hyprgraphics"),
__hyprland_api_get_hash());

#if ISDEBUG
result += "\"debug\",";
Expand Down
8 changes: 6 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ using namespace Hyprutils::Memory;

static void help() {
std::println("usage: Hyprland [arg [...]].\n");
std::println(R"(Arguments:
std::println(R"#(Arguments:
--help -h - Show this message again
--config FILE -c FILE - Specify config file to use
--socket NAME - Sets the Wayland socket name (for Wayland socket handover)
--wayland-fd FD - Sets the Wayland socket fd (for Wayland socket handover)
--systeminfo - Prints system infos
--i-am-really-stupid - Omits root user privileges check (why would you do that?)
--verify-config - Do not run Hyprland, only print if the config has any errors
--version -v - Print this binary's version)");
--version -v - Print this binary's version
--version-json - Print this binary's version as json)#");
}

static void reapZombieChildrenAutomatically() {
Expand Down Expand Up @@ -142,6 +143,9 @@ int main(int argc, char** argv) {
} else if (value == "-v" || value == "--version") {
std::println("{}", versionRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
return 0;
} else if (value == "--version-json") {
std::println("{}", versionRequest(eHyprCtlOutputFormat::FORMAT_JSON, ""));
return 0;
} else if (value == "--systeminfo") {
std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
return 0;
Expand Down
Loading