mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-05-13 07:10:35 +01:00
plugins: refactor class member vars (#10257)
This commit is contained in:
parent
d9cad5e1b6
commit
2d6ca96e07
7 changed files with 128 additions and 129 deletions
|
@ -130,11 +130,11 @@ void NCrashReporter::createAndSaveCrash(int sig) {
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
auto p = plugins[i];
|
||||
finalCrashReport += '\t';
|
||||
finalCrashReport += p->name;
|
||||
finalCrashReport += p->m_name;
|
||||
finalCrashReport += " (";
|
||||
finalCrashReport += p->author;
|
||||
finalCrashReport += p->m_author;
|
||||
finalCrashReport += ") ";
|
||||
finalCrashReport += p->version;
|
||||
finalCrashReport += p->m_version;
|
||||
finalCrashReport += '\n';
|
||||
}
|
||||
|
||||
|
|
|
@ -1052,7 +1052,7 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request)
|
|||
result += "plugins:\n";
|
||||
if (g_pPluginSystem) {
|
||||
for (auto const& pl : g_pPluginSystem->getAllPlugins()) {
|
||||
result += std::format(" {} by {} ver {}\n", pl->name, pl->author, pl->version);
|
||||
result += std::format(" {} by {} ver {}\n", pl->m_name, pl->m_author, pl->m_version);
|
||||
}
|
||||
} else
|
||||
result += "\tunknown: not runtime\n";
|
||||
|
@ -1548,7 +1548,7 @@ static std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string reque
|
|||
"version": "{}",
|
||||
"description": "{}"
|
||||
}},)#",
|
||||
escapeJSONStrings(p->name), escapeJSONStrings(p->author), (uintptr_t)p->m_pHandle, escapeJSONStrings(p->version), escapeJSONStrings(p->description));
|
||||
escapeJSONStrings(p->m_name), escapeJSONStrings(p->m_author), (uintptr_t)p->m_handle, escapeJSONStrings(p->m_version), escapeJSONStrings(p->m_description));
|
||||
}
|
||||
trimTrailingComma(result);
|
||||
result += "]";
|
||||
|
@ -1557,8 +1557,8 @@ static std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string reque
|
|||
return "no plugins loaded";
|
||||
|
||||
for (auto const& p : PLUGINS) {
|
||||
result +=
|
||||
std::format("\nPlugin {} by {}:\n\tHandle: {:x}\n\tVersion: {}\n\tDescription: {}\n", p->name, p->author, (uintptr_t)p->m_pHandle, p->version, p->description);
|
||||
result += std::format("\nPlugin {} by {}:\n\tHandle: {:x}\n\tVersion: {}\n\tDescription: {}\n", p->m_name, p->m_author, (uintptr_t)p->m_handle, p->m_version,
|
||||
p->m_description);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
CFunctionHook::CFunctionHook(HANDLE owner, void* source, void* destination) : m_pSource(source), m_pDestination(destination), m_pOwner(owner) {
|
||||
CFunctionHook::CFunctionHook(HANDLE owner, void* source, void* destination) : m_source(source), m_destination(destination), m_owner(owner) {
|
||||
;
|
||||
}
|
||||
|
||||
CFunctionHook::~CFunctionHook() {
|
||||
if (m_bActive)
|
||||
if (m_active)
|
||||
unhook();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ CFunctionHook::SAssembly CFunctionHook::fixInstructionProbeRIPCalls(const SInstr
|
|||
SAssembly returns;
|
||||
|
||||
// analyze the code and fix what we know how to.
|
||||
uint64_t currentAddress = (uint64_t)m_pSource;
|
||||
uint64_t currentAddress = (uint64_t)m_source;
|
||||
// actually newline + 1
|
||||
size_t lastAsmNewline = 0;
|
||||
// needle for destination binary
|
||||
|
@ -106,7 +106,7 @@ CFunctionHook::SAssembly CFunctionHook::fixInstructionProbeRIPCalls(const SInstr
|
|||
if (ADDREND == std::string::npos || ADDRSTART == std::string::npos)
|
||||
return {};
|
||||
|
||||
const uint64_t PREDICTEDRIP = (uint64_t)m_pTrampolineAddr + currentDestinationOffset + len;
|
||||
const uint64_t PREDICTEDRIP = (uint64_t)m_trampolineAddr + currentDestinationOffset + len;
|
||||
const int32_t NEWRIPOFFSET = DESTINATION - PREDICTEDRIP;
|
||||
|
||||
size_t ripOffset = 0;
|
||||
|
@ -157,12 +157,12 @@ bool CFunctionHook::hook() {
|
|||
|
||||
// alloc trampoline
|
||||
const auto MAX_TRAMPOLINE_SIZE = HOOK_TRAMPOLINE_MAX_SIZE; // we will never need more.
|
||||
m_pTrampolineAddr = (void*)g_pFunctionHookSystem->getAddressForTrampo();
|
||||
m_trampolineAddr = (void*)g_pFunctionHookSystem->getAddressForTrampo();
|
||||
|
||||
// probe instructions to be trampolin'd
|
||||
SInstructionProbe probe;
|
||||
try {
|
||||
probe = probeMinimumJumpSize(m_pSource, sizeof(ABSOLUTE_JMP_ADDRESS) + sizeof(PUSH_RAX) + sizeof(POP_RAX));
|
||||
probe = probeMinimumJumpSize(m_source, sizeof(ABSOLUTE_JMP_ADDRESS) + sizeof(PUSH_RAX) + sizeof(POP_RAX));
|
||||
} catch (std::exception& e) { return false; }
|
||||
|
||||
const auto PROBEFIXEDASM = fixInstructionProbeRIPCalls(probe);
|
||||
|
@ -182,42 +182,42 @@ bool CFunctionHook::hook() {
|
|||
return false;
|
||||
}
|
||||
|
||||
m_pOriginalBytes = malloc(ORIGSIZE);
|
||||
memcpy(m_pOriginalBytes, m_pSource, ORIGSIZE);
|
||||
m_originalBytes = malloc(ORIGSIZE);
|
||||
memcpy(m_originalBytes, m_source, ORIGSIZE);
|
||||
|
||||
// populate trampoline
|
||||
memcpy(m_pTrampolineAddr, PROBEFIXEDASM.bytes.data(), HOOKSIZE); // first, original but fixed func bytes
|
||||
memcpy((uint8_t*)m_pTrampolineAddr + HOOKSIZE, PUSH_RAX, sizeof(PUSH_RAX)); // then, pushq %rax
|
||||
memcpy((uint8_t*)m_pTrampolineAddr + HOOKSIZE + sizeof(PUSH_RAX), ABSOLUTE_JMP_ADDRESS, sizeof(ABSOLUTE_JMP_ADDRESS)); // then, jump to source
|
||||
memcpy(m_trampolineAddr, PROBEFIXEDASM.bytes.data(), HOOKSIZE); // first, original but fixed func bytes
|
||||
memcpy((uint8_t*)m_trampolineAddr + HOOKSIZE, PUSH_RAX, sizeof(PUSH_RAX)); // then, pushq %rax
|
||||
memcpy((uint8_t*)m_trampolineAddr + HOOKSIZE + sizeof(PUSH_RAX), ABSOLUTE_JMP_ADDRESS, sizeof(ABSOLUTE_JMP_ADDRESS)); // then, jump to source
|
||||
|
||||
// fixup trampoline addr
|
||||
*(uint64_t*)((uint8_t*)m_pTrampolineAddr + TRAMPOLINE_SIZE - sizeof(ABSOLUTE_JMP_ADDRESS) + ABSOLUTE_JMP_ADDRESS_OFFSET) =
|
||||
(uint64_t)((uint8_t*)m_pSource + sizeof(ABSOLUTE_JMP_ADDRESS));
|
||||
*(uint64_t*)((uint8_t*)m_trampolineAddr + TRAMPOLINE_SIZE - sizeof(ABSOLUTE_JMP_ADDRESS) + ABSOLUTE_JMP_ADDRESS_OFFSET) =
|
||||
(uint64_t)((uint8_t*)m_source + sizeof(ABSOLUTE_JMP_ADDRESS));
|
||||
|
||||
// make jump to hk
|
||||
const auto PAGESIZE_VAR = sysconf(_SC_PAGE_SIZE);
|
||||
const uint8_t* PROTSTART = (uint8_t*)m_pSource - ((uint64_t)m_pSource % PAGESIZE_VAR);
|
||||
const size_t PROTLEN = std::ceil((float)(ORIGSIZE + ((uint64_t)m_pSource - (uint64_t)PROTSTART)) / (float)PAGESIZE_VAR) * PAGESIZE_VAR;
|
||||
const uint8_t* PROTSTART = (uint8_t*)m_source - ((uint64_t)m_source % PAGESIZE_VAR);
|
||||
const size_t PROTLEN = std::ceil((float)(ORIGSIZE + ((uint64_t)m_source - (uint64_t)PROTSTART)) / (float)PAGESIZE_VAR) * PAGESIZE_VAR;
|
||||
mprotect((uint8_t*)PROTSTART, PROTLEN, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
memcpy((uint8_t*)m_pSource, ABSOLUTE_JMP_ADDRESS, sizeof(ABSOLUTE_JMP_ADDRESS));
|
||||
memcpy((uint8_t*)m_source, ABSOLUTE_JMP_ADDRESS, sizeof(ABSOLUTE_JMP_ADDRESS));
|
||||
|
||||
// make popq %rax and NOP all remaining
|
||||
memcpy((uint8_t*)m_pSource + sizeof(ABSOLUTE_JMP_ADDRESS), POP_RAX, sizeof(POP_RAX));
|
||||
memcpy((uint8_t*)m_source + sizeof(ABSOLUTE_JMP_ADDRESS), POP_RAX, sizeof(POP_RAX));
|
||||
size_t currentOp = sizeof(ABSOLUTE_JMP_ADDRESS) + sizeof(POP_RAX);
|
||||
memset((uint8_t*)m_pSource + currentOp, NOP, ORIGSIZE - currentOp);
|
||||
memset((uint8_t*)m_source + currentOp, NOP, ORIGSIZE - currentOp);
|
||||
|
||||
// fixup jump addr
|
||||
*(uint64_t*)((uint8_t*)m_pSource + ABSOLUTE_JMP_ADDRESS_OFFSET) = (uint64_t)(m_pDestination);
|
||||
*(uint64_t*)((uint8_t*)m_source + ABSOLUTE_JMP_ADDRESS_OFFSET) = (uint64_t)(m_destination);
|
||||
|
||||
// revert mprot
|
||||
mprotect((uint8_t*)PROTSTART, PROTLEN, PROT_READ | PROT_EXEC);
|
||||
|
||||
// set original addr to trampo addr
|
||||
m_pOriginal = m_pTrampolineAddr;
|
||||
m_original = m_trampolineAddr;
|
||||
|
||||
m_bActive = true;
|
||||
m_iHookLen = ORIGSIZE;
|
||||
m_iTrampoLen = TRAMPOLINE_SIZE;
|
||||
m_active = true;
|
||||
m_hookLen = ORIGSIZE;
|
||||
m_trampoLen = TRAMPOLINE_SIZE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -228,41 +228,41 @@ bool CFunctionHook::unhook() {
|
|||
return false;
|
||||
#endif
|
||||
|
||||
if (!m_bActive)
|
||||
if (!m_active)
|
||||
return false;
|
||||
|
||||
// allow write to src
|
||||
mprotect((uint8_t*)m_pSource - ((uint64_t)m_pSource) % sysconf(_SC_PAGE_SIZE), sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
mprotect((uint8_t*)m_source - ((uint64_t)m_source) % sysconf(_SC_PAGE_SIZE), sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
|
||||
// write back original bytes
|
||||
memcpy(m_pSource, m_pOriginalBytes, m_iHookLen);
|
||||
memcpy(m_source, m_originalBytes, m_hookLen);
|
||||
|
||||
// revert mprot
|
||||
mprotect((uint8_t*)m_pSource - ((uint64_t)m_pSource) % sysconf(_SC_PAGE_SIZE), sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_EXEC);
|
||||
mprotect((uint8_t*)m_source - ((uint64_t)m_source) % sysconf(_SC_PAGE_SIZE), sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_EXEC);
|
||||
|
||||
// reset vars
|
||||
m_bActive = false;
|
||||
m_iHookLen = 0;
|
||||
m_iTrampoLen = 0;
|
||||
m_pTrampolineAddr = nullptr; // no unmapping, it's managed by the HookSystem
|
||||
m_pOriginalBytes = nullptr;
|
||||
m_active = false;
|
||||
m_hookLen = 0;
|
||||
m_trampoLen = 0;
|
||||
m_trampolineAddr = nullptr; // no unmapping, it's managed by the HookSystem
|
||||
m_originalBytes = nullptr;
|
||||
|
||||
free(m_pOriginalBytes);
|
||||
free(m_originalBytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CFunctionHook* CHookSystem::initHook(HANDLE owner, void* source, void* destination) {
|
||||
return m_vHooks.emplace_back(makeUnique<CFunctionHook>(owner, source, destination)).get();
|
||||
return m_hooks.emplace_back(makeUnique<CFunctionHook>(owner, source, destination)).get();
|
||||
}
|
||||
|
||||
bool CHookSystem::removeHook(CFunctionHook* hook) {
|
||||
std::erase_if(m_vHooks, [&](const auto& other) { return other.get() == hook; });
|
||||
std::erase_if(m_hooks, [&](const auto& other) { return other.get() == hook; });
|
||||
return true; // todo: make false if not found
|
||||
}
|
||||
|
||||
void CHookSystem::removeAllHooksFrom(HANDLE handle) {
|
||||
std::erase_if(m_vHooks, [&](const auto& other) { return other->m_pOwner == handle; });
|
||||
std::erase_if(m_hooks, [&](const auto& other) { return other->m_owner == handle; });
|
||||
}
|
||||
|
||||
static uintptr_t seekNewPageAddr() {
|
||||
|
@ -334,7 +334,7 @@ uint64_t CHookSystem::getAddressForTrampo() {
|
|||
// Nobody will hook 100k times, and even if, that's only 6.4 MB. Nothing.
|
||||
|
||||
SAllocatedPage* page = nullptr;
|
||||
for (auto& p : pages) {
|
||||
for (auto& p : m_pages) {
|
||||
if (p.used + HOOK_TRAMPOLINE_MAX_SIZE > p.len)
|
||||
continue;
|
||||
|
||||
|
@ -343,7 +343,7 @@ uint64_t CHookSystem::getAddressForTrampo() {
|
|||
}
|
||||
|
||||
if (!page)
|
||||
page = &pages.emplace_back();
|
||||
page = &m_pages.emplace_back();
|
||||
|
||||
if (!page->addr) {
|
||||
// allocate it
|
||||
|
|
|
@ -20,19 +20,18 @@ class CFunctionHook {
|
|||
CFunctionHook& operator=(const CFunctionHook&) = delete;
|
||||
CFunctionHook& operator=(CFunctionHook&&) = delete;
|
||||
|
||||
void* m_pOriginal = nullptr;
|
||||
void* m_original = nullptr;
|
||||
|
||||
private:
|
||||
void* m_pSource = nullptr;
|
||||
void* m_pFunctionAddr = nullptr;
|
||||
void* m_pTrampolineAddr = nullptr;
|
||||
void* m_pDestination = nullptr;
|
||||
size_t m_iHookLen = 0;
|
||||
size_t m_iTrampoLen = 0;
|
||||
HANDLE m_pOwner = nullptr;
|
||||
bool m_bActive = false;
|
||||
void* m_source = nullptr;
|
||||
void* m_trampolineAddr = nullptr;
|
||||
void* m_destination = nullptr;
|
||||
size_t m_hookLen = 0;
|
||||
size_t m_trampoLen = 0;
|
||||
HANDLE m_owner = nullptr;
|
||||
bool m_active = false;
|
||||
|
||||
void* m_pOriginalBytes = nullptr;
|
||||
void* m_originalBytes = nullptr;
|
||||
|
||||
struct SInstructionProbe {
|
||||
size_t len = 0;
|
||||
|
@ -60,7 +59,7 @@ class CHookSystem {
|
|||
void removeAllHooksFrom(HANDLE handle);
|
||||
|
||||
private:
|
||||
std::vector<UP<CFunctionHook>> m_vHooks;
|
||||
std::vector<UP<CFunctionHook>> m_hooks;
|
||||
|
||||
uint64_t getAddressForTrampo();
|
||||
|
||||
|
@ -70,7 +69,7 @@ class CHookSystem {
|
|||
uint64_t used = 0;
|
||||
};
|
||||
|
||||
std::vector<SAllocatedPage> pages;
|
||||
std::vector<SAllocatedPage> m_pages;
|
||||
|
||||
friend class CFunctionHook;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ APICALL SP<HOOK_CALLBACK_FN> HyprlandAPI::registerCallbackDynamic(HANDLE handle,
|
|||
return nullptr;
|
||||
|
||||
auto PFN = g_pHookSystem->hookDynamic(event, fn, handle);
|
||||
PLUGIN->registeredCallbacks.emplace_back(std::make_pair<>(event, WP<HOOK_CALLBACK_FN>(PFN)));
|
||||
PLUGIN->m_registeredCallbacks.emplace_back(std::make_pair<>(event, WP<HOOK_CALLBACK_FN>(PFN)));
|
||||
return PFN;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ APICALL bool HyprlandAPI::unregisterCallback(HANDLE handle, SP<HOOK_CALLBACK_FN>
|
|||
return false;
|
||||
|
||||
g_pHookSystem->unhook(fn);
|
||||
std::erase_if(PLUGIN->registeredCallbacks, [&](const auto& other) { return other.second.lock() == fn; });
|
||||
std::erase_if(PLUGIN->m_registeredCallbacks, [&](const auto& other) { return other.second.lock() == fn; });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ APICALL bool HyprlandAPI::addLayout(HANDLE handle, const std::string& name, IHyp
|
|||
if (!PLUGIN)
|
||||
return false;
|
||||
|
||||
PLUGIN->registeredLayouts.push_back(layout);
|
||||
PLUGIN->m_registeredLayouts.push_back(layout);
|
||||
|
||||
return g_pLayoutManager->addLayout(name, layout);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ APICALL bool HyprlandAPI::removeLayout(HANDLE handle, IHyprLayout* layout) {
|
|||
if (!PLUGIN)
|
||||
return false;
|
||||
|
||||
std::erase(PLUGIN->registeredLayouts, layout);
|
||||
std::erase(PLUGIN->m_registeredLayouts, layout);
|
||||
|
||||
return g_pLayoutManager->removeLayout(layout);
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ APICALL bool HyprlandAPI::addWindowDecoration(HANDLE handle, PHLWINDOW pWindow,
|
|||
if (!validMapped(pWindow))
|
||||
return false;
|
||||
|
||||
PLUGIN->registeredDecorations.push_back(pDecoration.get());
|
||||
PLUGIN->m_registeredDecorations.push_back(pDecoration.get());
|
||||
|
||||
pWindow->addWindowDeco(std::move(pDecoration));
|
||||
|
||||
|
@ -145,7 +145,7 @@ APICALL bool HyprlandAPI::removeWindowDecoration(HANDLE handle, IHyprWindowDecor
|
|||
APICALL bool HyprlandAPI::addConfigValue(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value) {
|
||||
auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle);
|
||||
|
||||
if (!g_pPluginSystem->m_bAllowConfigVars)
|
||||
if (!g_pPluginSystem->m_allowConfigVars)
|
||||
return false;
|
||||
|
||||
if (!PLUGIN)
|
||||
|
@ -161,7 +161,7 @@ APICALL bool HyprlandAPI::addConfigValue(HANDLE handle, const std::string& name,
|
|||
APICALL bool HyprlandAPI::addConfigKeyword(HANDLE handle, const std::string& name, Hyprlang::PCONFIGHANDLERFUNC fn, Hyprlang::SHandlerOptions opts) {
|
||||
auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle);
|
||||
|
||||
if (!g_pPluginSystem->m_bAllowConfigVars)
|
||||
if (!g_pPluginSystem->m_allowConfigVars)
|
||||
return false;
|
||||
|
||||
if (!PLUGIN)
|
||||
|
@ -198,7 +198,7 @@ APICALL bool HyprlandAPI::addDispatcher(HANDLE handle, const std::string& name,
|
|||
if (!PLUGIN)
|
||||
return false;
|
||||
|
||||
PLUGIN->registeredDispatchers.push_back(name);
|
||||
PLUGIN->m_registeredDispatchers.push_back(name);
|
||||
|
||||
g_pKeybindManager->m_dispatchers[name] = [handler](std::string arg1) -> SDispatchResult {
|
||||
handler(arg1);
|
||||
|
@ -214,7 +214,7 @@ APICALL bool HyprlandAPI::addDispatcherV2(HANDLE handle, const std::string& name
|
|||
if (!PLUGIN)
|
||||
return false;
|
||||
|
||||
PLUGIN->registeredDispatchers.push_back(name);
|
||||
PLUGIN->m_registeredDispatchers.push_back(name);
|
||||
|
||||
g_pKeybindManager->m_dispatchers[name] = handler;
|
||||
|
||||
|
@ -228,7 +228,7 @@ APICALL bool HyprlandAPI::removeDispatcher(HANDLE handle, const std::string& nam
|
|||
return false;
|
||||
|
||||
std::erase_if(g_pKeybindManager->m_dispatchers, [&](const auto& other) { return other.first == name; });
|
||||
std::erase_if(PLUGIN->registeredDispatchers, [&](const auto& other) { return other == name; });
|
||||
std::erase_if(PLUGIN->m_registeredDispatchers, [&](const auto& other) { return other == name; });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ APICALL SP<SHyprCtlCommand> HyprlandAPI::registerHyprCtlCommand(HANDLE handle, S
|
|||
return nullptr;
|
||||
|
||||
auto PTR = g_pHyprCtl->registerCommand(cmd);
|
||||
PLUGIN->registeredHyprctlCommands.push_back(PTR);
|
||||
PLUGIN->m_registeredHyprctlCommands.push_back(PTR);
|
||||
return PTR;
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ APICALL bool HyprlandAPI::unregisterHyprCtlCommand(HANDLE handle, SP<SHyprCtlCom
|
|||
if (!PLUGIN)
|
||||
return false;
|
||||
|
||||
std::erase(PLUGIN->registeredHyprctlCommands, cmd);
|
||||
std::erase(PLUGIN->m_registeredHyprctlCommands, cmd);
|
||||
g_pHyprCtl->unregisterCommand(cmd);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -74,20 +74,20 @@ std::expected<CPlugin*, std::string> CPluginSystem::loadPluginInternal(const std
|
|||
return std::unexpected("Cannot load a plugin twice!");
|
||||
}
|
||||
|
||||
auto* const PLUGIN = m_vLoadedPlugins.emplace_back(makeUnique<CPlugin>()).get();
|
||||
auto* const PLUGIN = m_loadedPlugins.emplace_back(makeUnique<CPlugin>()).get();
|
||||
|
||||
PLUGIN->path = path;
|
||||
PLUGIN->m_path = path;
|
||||
|
||||
HANDLE MODULE = dlopen(path.c_str(), RTLD_LAZY);
|
||||
|
||||
if (!MODULE) {
|
||||
std::string strerr = dlerror();
|
||||
Debug::log(ERR, " [PluginSystem] Plugin {} could not be loaded: {}", path, strerr);
|
||||
m_vLoadedPlugins.pop_back();
|
||||
m_loadedPlugins.pop_back();
|
||||
return std::unexpected(std::format("Plugin {} could not be loaded: {}", path, strerr));
|
||||
}
|
||||
|
||||
PLUGIN->m_pHandle = MODULE;
|
||||
PLUGIN->m_handle = MODULE;
|
||||
|
||||
PPLUGIN_API_VERSION_FUNC apiVerFunc = (PPLUGIN_API_VERSION_FUNC)dlsym(MODULE, PLUGIN_API_VERSION_FUNC_STR);
|
||||
PPLUGIN_INIT_FUNC initFunc = (PPLUGIN_INIT_FUNC)dlsym(MODULE, PLUGIN_INIT_FUNC_STR);
|
||||
|
@ -95,7 +95,7 @@ std::expected<CPlugin*, std::string> CPluginSystem::loadPluginInternal(const std
|
|||
if (!apiVerFunc || !initFunc) {
|
||||
Debug::log(ERR, " [PluginSystem] Plugin {} could not be loaded. (No apiver/init func)", path);
|
||||
dlclose(MODULE);
|
||||
m_vLoadedPlugins.pop_back();
|
||||
m_loadedPlugins.pop_back();
|
||||
return std::unexpected(std::format("Plugin {} could not be loaded: {}", path, "missing apiver/init func"));
|
||||
}
|
||||
|
||||
|
@ -104,33 +104,33 @@ std::expected<CPlugin*, std::string> CPluginSystem::loadPluginInternal(const std
|
|||
if (PLUGINAPIVER != HYPRLAND_API_VERSION) {
|
||||
Debug::log(ERR, " [PluginSystem] Plugin {} could not be loaded. (API version mismatch)", path);
|
||||
dlclose(MODULE);
|
||||
m_vLoadedPlugins.pop_back();
|
||||
m_loadedPlugins.pop_back();
|
||||
return std::unexpected(std::format("Plugin {} could not be loaded: {}", path, "API version mismatch"));
|
||||
}
|
||||
|
||||
PLUGIN_DESCRIPTION_INFO PLUGINDATA;
|
||||
|
||||
try {
|
||||
if (!setjmp(m_jbPluginFaultJumpBuf)) {
|
||||
m_bAllowConfigVars = true;
|
||||
if (!setjmp(m_pluginFaultJumpBuf)) {
|
||||
m_allowConfigVars = true;
|
||||
PLUGINDATA = initFunc(MODULE);
|
||||
} else {
|
||||
// this module crashed.
|
||||
throw std::runtime_error("received a fatal signal");
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
m_bAllowConfigVars = false;
|
||||
m_allowConfigVars = false;
|
||||
Debug::log(ERR, " [PluginSystem] Plugin {} (Handle {:x}) crashed in init. Unloading.", path, (uintptr_t)MODULE);
|
||||
unloadPlugin(PLUGIN, true); // Plugin could've already hooked/done something
|
||||
return std::unexpected(std::format("Plugin {} could not be loaded: plugin crashed/threw in main: {}", path, e.what()));
|
||||
}
|
||||
|
||||
m_bAllowConfigVars = false;
|
||||
m_allowConfigVars = false;
|
||||
|
||||
PLUGIN->author = PLUGINDATA.author;
|
||||
PLUGIN->description = PLUGINDATA.description;
|
||||
PLUGIN->version = PLUGINDATA.version;
|
||||
PLUGIN->name = PLUGINDATA.name;
|
||||
PLUGIN->m_author = PLUGINDATA.author;
|
||||
PLUGIN->m_description = PLUGINDATA.description;
|
||||
PLUGIN->m_version = PLUGINDATA.version;
|
||||
PLUGIN->m_name = PLUGINDATA.name;
|
||||
|
||||
g_pEventLoopManager->doLater([] { g_pConfigManager->reload(); });
|
||||
|
||||
|
@ -145,42 +145,42 @@ void CPluginSystem::unloadPlugin(const CPlugin* plugin, bool eject) {
|
|||
return;
|
||||
|
||||
if (!eject) {
|
||||
PPLUGIN_EXIT_FUNC exitFunc = (PPLUGIN_EXIT_FUNC)dlsym(plugin->m_pHandle, PLUGIN_EXIT_FUNC_STR);
|
||||
PPLUGIN_EXIT_FUNC exitFunc = (PPLUGIN_EXIT_FUNC)dlsym(plugin->m_handle, PLUGIN_EXIT_FUNC_STR);
|
||||
if (exitFunc)
|
||||
exitFunc();
|
||||
}
|
||||
|
||||
for (auto const& [k, v] : plugin->registeredCallbacks) {
|
||||
for (auto const& [k, v] : plugin->m_registeredCallbacks) {
|
||||
if (const auto SHP = v.lock())
|
||||
g_pHookSystem->unhook(SHP);
|
||||
}
|
||||
|
||||
const auto ls = plugin->registeredLayouts;
|
||||
const auto ls = plugin->m_registeredLayouts;
|
||||
for (auto const& l : ls)
|
||||
g_pLayoutManager->removeLayout(l);
|
||||
|
||||
g_pFunctionHookSystem->removeAllHooksFrom(plugin->m_pHandle);
|
||||
g_pFunctionHookSystem->removeAllHooksFrom(plugin->m_handle);
|
||||
|
||||
const auto rd = plugin->registeredDecorations;
|
||||
const auto rd = plugin->m_registeredDecorations;
|
||||
for (auto const& d : rd)
|
||||
HyprlandAPI::removeWindowDecoration(plugin->m_pHandle, d);
|
||||
HyprlandAPI::removeWindowDecoration(plugin->m_handle, d);
|
||||
|
||||
const auto rdi = plugin->registeredDispatchers;
|
||||
const auto rdi = plugin->m_registeredDispatchers;
|
||||
for (auto const& d : rdi)
|
||||
HyprlandAPI::removeDispatcher(plugin->m_pHandle, d);
|
||||
HyprlandAPI::removeDispatcher(plugin->m_handle, d);
|
||||
|
||||
const auto rhc = plugin->registeredHyprctlCommands;
|
||||
const auto rhc = plugin->m_registeredHyprctlCommands;
|
||||
for (auto const& c : rhc)
|
||||
HyprlandAPI::unregisterHyprCtlCommand(plugin->m_pHandle, c);
|
||||
HyprlandAPI::unregisterHyprCtlCommand(plugin->m_handle, c);
|
||||
|
||||
g_pConfigManager->removePluginConfig(plugin->m_pHandle);
|
||||
g_pConfigManager->removePluginConfig(plugin->m_handle);
|
||||
|
||||
// save these two for dlclose and a log,
|
||||
// as erase_if will kill the pointer
|
||||
const auto PLNAME = plugin->name;
|
||||
const auto PLHANDLE = plugin->m_pHandle;
|
||||
const auto PLNAME = plugin->m_name;
|
||||
const auto PLHANDLE = plugin->m_handle;
|
||||
|
||||
std::erase_if(m_vLoadedPlugins, [&](const auto& other) { return other->m_pHandle == PLHANDLE; });
|
||||
std::erase_if(m_loadedPlugins, [&](const auto& other) { return other->m_handle == PLHANDLE; });
|
||||
|
||||
dlclose(PLHANDLE);
|
||||
|
||||
|
@ -191,24 +191,24 @@ void CPluginSystem::unloadPlugin(const CPlugin* plugin, bool eject) {
|
|||
}
|
||||
|
||||
void CPluginSystem::unloadAllPlugins() {
|
||||
for (auto const& p : m_vLoadedPlugins | std::views::reverse)
|
||||
for (auto const& p : m_loadedPlugins | std::views::reverse)
|
||||
unloadPlugin(p.get(), false); // Unload remaining plugins gracefully
|
||||
}
|
||||
|
||||
void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins, bool& changed) {
|
||||
// unload all plugins that are no longer present
|
||||
for (auto const& p : m_vLoadedPlugins | std::views::reverse) {
|
||||
if (!p->m_bLoadedWithConfig || std::ranges::find(plugins, p->path) != plugins.end())
|
||||
for (auto const& p : m_loadedPlugins | std::views::reverse) {
|
||||
if (!p->m_loadedWithConfig || std::ranges::find(plugins, p->m_path) != plugins.end())
|
||||
continue;
|
||||
|
||||
Debug::log(LOG, "Unloading plugin {} which is no longer present in config", p->path);
|
||||
Debug::log(LOG, "Unloading plugin {} which is no longer present in config", p->m_path);
|
||||
unloadPlugin(p.get(), false);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// load all new plugins
|
||||
for (auto const& path : plugins) {
|
||||
if (std::ranges::find_if(m_vLoadedPlugins, [&](const auto& other) { return other->path == path; }) != m_vLoadedPlugins.end())
|
||||
if (std::ranges::find_if(m_loadedPlugins, [&](const auto& other) { return other->m_path == path; }) != m_loadedPlugins.end())
|
||||
continue;
|
||||
|
||||
Debug::log(LOG, "Loading plugin {} which is now present in config", path);
|
||||
|
@ -223,7 +223,7 @@ void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins,
|
|||
return;
|
||||
}
|
||||
|
||||
result->result()->m_bLoadedWithConfig = true;
|
||||
result->result()->m_loadedWithConfig = true;
|
||||
|
||||
Debug::log(LOG, "CPluginSystem::updateConfigPlugins: loaded {}", path);
|
||||
});
|
||||
|
@ -231,8 +231,8 @@ void CPluginSystem::updateConfigPlugins(const std::vector<std::string>& plugins,
|
|||
}
|
||||
|
||||
CPlugin* CPluginSystem::getPluginByPath(const std::string& path) {
|
||||
for (auto const& p : m_vLoadedPlugins) {
|
||||
if (p->path == path)
|
||||
for (auto const& p : m_loadedPlugins) {
|
||||
if (p->m_path == path)
|
||||
return p.get();
|
||||
}
|
||||
|
||||
|
@ -240,8 +240,8 @@ CPlugin* CPluginSystem::getPluginByPath(const std::string& path) {
|
|||
}
|
||||
|
||||
CPlugin* CPluginSystem::getPluginByHandle(HANDLE handle) {
|
||||
for (auto const& p : m_vLoadedPlugins) {
|
||||
if (p->m_pHandle == handle)
|
||||
for (auto const& p : m_loadedPlugins) {
|
||||
if (p->m_handle == handle)
|
||||
return p.get();
|
||||
}
|
||||
|
||||
|
@ -249,18 +249,18 @@ CPlugin* CPluginSystem::getPluginByHandle(HANDLE handle) {
|
|||
}
|
||||
|
||||
std::vector<CPlugin*> CPluginSystem::getAllPlugins() {
|
||||
std::vector<CPlugin*> results(m_vLoadedPlugins.size());
|
||||
for (size_t i = 0; i < m_vLoadedPlugins.size(); ++i)
|
||||
results[i] = m_vLoadedPlugins[i].get();
|
||||
std::vector<CPlugin*> results(m_loadedPlugins.size());
|
||||
for (size_t i = 0; i < m_loadedPlugins.size(); ++i)
|
||||
results[i] = m_loadedPlugins[i].get();
|
||||
return results;
|
||||
}
|
||||
|
||||
size_t CPluginSystem::pluginCount() {
|
||||
return m_vLoadedPlugins.size();
|
||||
return m_loadedPlugins.size();
|
||||
}
|
||||
|
||||
void CPluginSystem::sigGetPlugins(CPlugin** data, size_t len) {
|
||||
for (size_t i = 0; i < std::min(m_vLoadedPlugins.size(), len); i++) {
|
||||
data[i] = m_vLoadedPlugins[i].get();
|
||||
for (size_t i = 0; i < std::min(m_loadedPlugins.size(), len); i++) {
|
||||
data[i] = m_loadedPlugins[i].get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,22 +10,22 @@ class IHyprWindowDecoration;
|
|||
|
||||
class CPlugin {
|
||||
public:
|
||||
std::string name = "";
|
||||
std::string description = "";
|
||||
std::string author = "";
|
||||
std::string version = "";
|
||||
std::string m_name = "";
|
||||
std::string m_description = "";
|
||||
std::string m_author = "";
|
||||
std::string m_version = "";
|
||||
|
||||
std::string path = "";
|
||||
std::string m_path = "";
|
||||
|
||||
bool m_bLoadedWithConfig = false;
|
||||
bool m_loadedWithConfig = false;
|
||||
|
||||
HANDLE m_pHandle = nullptr;
|
||||
HANDLE m_handle = nullptr;
|
||||
|
||||
std::vector<IHyprLayout*> registeredLayouts;
|
||||
std::vector<IHyprWindowDecoration*> registeredDecorations;
|
||||
std::vector<std::pair<std::string, WP<HOOK_CALLBACK_FN>>> registeredCallbacks;
|
||||
std::vector<std::string> registeredDispatchers;
|
||||
std::vector<SP<SHyprCtlCommand>> registeredHyprctlCommands;
|
||||
std::vector<IHyprLayout*> m_registeredLayouts;
|
||||
std::vector<IHyprWindowDecoration*> m_registeredDecorations;
|
||||
std::vector<std::pair<std::string, WP<HOOK_CALLBACK_FN>>> m_registeredCallbacks;
|
||||
std::vector<std::string> m_registeredDispatchers;
|
||||
std::vector<SP<SHyprCtlCommand>> m_registeredHyprctlCommands;
|
||||
};
|
||||
|
||||
class CPluginSystem {
|
||||
|
@ -42,12 +42,12 @@ class CPluginSystem {
|
|||
size_t pluginCount();
|
||||
void sigGetPlugins(CPlugin** data, size_t len);
|
||||
|
||||
bool m_bAllowConfigVars = false;
|
||||
bool m_allowConfigVars = false;
|
||||
|
||||
private:
|
||||
std::vector<UP<CPlugin>> m_vLoadedPlugins;
|
||||
std::vector<UP<CPlugin>> m_loadedPlugins;
|
||||
|
||||
jmp_buf m_jbPluginFaultJumpBuf;
|
||||
jmp_buf m_pluginFaultJumpBuf;
|
||||
|
||||
std::expected<CPlugin*, std::string> loadPluginInternal(const std::string& path);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue