From 1b56cc4e99c391a94fc05a24e1f71c8e425168f1 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sun, 19 Feb 2023 20:54:53 +0000 Subject: [PATCH] Added an Event Hook System (#1578) * added an eventHookSystem * Add all socket2 events to hooks --- src/Compositor.cpp | 17 ++++++++-- src/Compositor.hpp | 1 + src/Window.cpp | 1 + src/events/Layers.cpp | 2 ++ src/events/Monitors.cpp | 4 +-- src/events/Windows.cpp | 7 ++++ src/helpers/Monitor.cpp | 2 ++ src/helpers/Workspace.cpp | 2 ++ src/layout/DwindleLayout.cpp | 1 + src/layout/IHyprLayout.cpp | 1 + src/layout/MasterLayout.cpp | 3 +- src/managers/HookSystemManager.cpp | 44 +++++++++++++++++++++++++ src/managers/HookSystemManager.hpp | 36 ++++++++++++++++++++ src/managers/KeybindManager.cpp | 5 +++ src/managers/input/InputManager.cpp | 18 +++++++--- src/managers/input/InputMethodRelay.cpp | 4 ++- src/protocols/ToplevelExport.cpp | 2 ++ src/protocols/ToplevelExport.hpp | 4 +-- src/render/OpenGL.cpp | 2 ++ 19 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 src/managers/HookSystemManager.cpp create mode 100644 src/managers/HookSystemManager.hpp diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 0b4970c2..95366001 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -319,6 +319,9 @@ void CCompositor::startCompositor() { // properly and we dont get any bad mem reads. // + Debug::log(LOG, "Creating the HookSystem!"); + g_pHookSystem = std::make_unique(); + Debug::log(LOG, "Creating the KeybindManager!"); g_pKeybindManager = std::make_unique(); @@ -788,6 +791,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ","}); + EMIT_HOOK_EVENT("activeWindow", nullptr); + g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr); m_pLastFocus = nullptr; @@ -859,6 +864,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", getFormat("%x", pWindow)}); + EMIT_HOOK_EVENT("activeWindow", pWindow); + g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow); if (pWindow->m_phForeignToplevel) @@ -901,7 +908,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) { wlr_seat_keyboard_clear_focus(m_sSeat.seat); g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ","}); - g_pInputManager->m_sIMERelay.onKeyboardFocus(nullptr); + EMIT_HOOK_EVENT("keyboardFocus", nullptr); m_pLastFocus = nullptr; return; } @@ -913,8 +920,6 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) { wlr_seat_keyboard_notify_enter(m_sSeat.seat, pSurface, KEYBOARD->keycodes, KEYBOARD->num_keycodes, &KEYBOARD->modifiers); - g_pInputManager->m_sIMERelay.onKeyboardFocus(pSurface); - wlr_seat_keyboard_focus_change_event event = { .seat = m_sSeat.seat, .old_surface = m_pLastFocus, @@ -929,6 +934,8 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) { g_pXWaylandManager->activateSurface(pSurface, true); m_pLastFocus = pSurface; + + EMIT_HOOK_EVENT("keyboardFocus", pSurface); } bool CCompositor::windowValidMapped(CWindow* pWindow) { @@ -1719,7 +1726,9 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB) // event g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName}); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEA, pMonitorB})); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName}); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{PWORKSPACEB, pMonitorA})); } CMonitor* CCompositor::getMonitorFromString(const std::string& name) { @@ -1882,6 +1891,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni // event g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName}); + EMIT_HOOK_EVENT("moveWorkspace", (std::vector{pWorkspace, pMonitor})); } bool CCompositor::workspaceIDOutOfBounds(const int& id) { @@ -2210,6 +2220,7 @@ void CCompositor::setActiveMonitor(CMonitor* pMonitor) { const auto PWORKSPACE = getWorkspaceByID(pMonitor->activeWorkspace); g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + PWORKSPACE->m_szName}); + EMIT_HOOK_EVENT("focusedMon", pMonitor); m_pLastMonitor = pMonitor; } diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 24f8dd21..8008acc3 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -17,6 +17,7 @@ #include "managers/EventManager.hpp" #include "managers/ProtocolManager.hpp" #include "managers/SessionLockManager.hpp" +#include "managers/HookSystemManager.hpp" #include "debug/HyprDebugOverlay.hpp" #include "helpers/Monitor.hpp" #include "helpers/Workspace.hpp" diff --git a/src/Window.cpp b/src/Window.cpp index dd0f660c..e7d4a02a 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -219,6 +219,7 @@ void CWindow::moveToWorkspace(int workspaceID) { if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); PWORKSPACE) { g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())}); + EMIT_HOOK_EVENT("moveWindow", (std::vector{this, PWORKSPACE})); } if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR) diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index e72af5dd..65f679d5 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -166,6 +166,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) { layersurface->fadingOut = false; g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", std::string(layersurface->layerSurface->_namespace ? layersurface->layerSurface->_namespace : "")}); + EMIT_HOOK_EVENT("openLayer", layersurface); g_pProtocolManager->m_pFractionalScaleProtocolManager->setPreferredScaleForSurface(layersurface->layerSurface->surface, PMONITOR->scale); } @@ -176,6 +177,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) { Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface); g_pEventManager->postEvent(SHyprIPCEvent{"closelayer", std::string(layersurface->layerSurface->_namespace ? layersurface->layerSurface->_namespace : "")}); + EMIT_HOOK_EVENT("closeLayer", layersurface); if (!g_pCompositor->getMonitorFromID(layersurface->monitorID) || g_pCompositor->m_bUnsafeState) { Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring."); diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index bbc86bee..799669a1 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -177,7 +177,7 @@ void Events::listener_monitorFrame(void* owner, void* data) { } } - g_pProtocolManager->m_pToplevelExportProtocolManager->onMonitorRender(PMONITOR); // dispatch any toplevel sharing + EMIT_HOOK_EVENT("preRender", PMONITOR); timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -192,8 +192,6 @@ void Events::listener_monitorFrame(void* owner, void* data) { return; } - g_pHyprOpenGL->preRender(PMONITOR); - if (!wlr_output_damage_attach_render(PMONITOR->damage, &hasChanged, &damage)) { Debug::log(ERR, "Couldn't attach render to display %s ???", PMONITOR->szName.c_str()); return; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 6a7efc88..5c954f68 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -562,6 +562,7 @@ void Events::listener_mapWindow(void* owner, void* data) { auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName; g_pEventManager->postEvent( SHyprIPCEvent{"openwindow", getFormat("%x,%s,%s,%s", PWINDOW, workspaceID.c_str(), g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), PWINDOW->m_szTitle.c_str())}); + EMIT_HOOK_EVENT("openWindow", PWINDOW); // recalc the values for this window g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW); @@ -575,6 +576,7 @@ void Events::listener_unmapWindow(void* owner, void* data) { Debug::log(LOG, "Window %x unmapped (class %s)", PWINDOW, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str()); g_pEventManager->postEvent(SHyprIPCEvent{"closewindow", getFormat("%x", PWINDOW)}); + EMIT_HOOK_EVENT("closeWindow", PWINDOW); g_pProtocolManager->m_pToplevelExportProtocolManager->onWindowUnmap(PWINDOW); @@ -744,6 +746,7 @@ void Events::listener_setTitleWindow(void* owner, void* data) { if (PWINDOW == g_pCompositor->m_pLastWindow) { // if it's the active, let's post an event to update others g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", getFormat("%x", PWINDOW)}); + EMIT_HOOK_EVENT("activeWindow", PWINDOW); } PWINDOW->updateDynamicRules(); @@ -828,6 +831,7 @@ void Events::listener_activateXDG(wl_listener* listener, void* data) { return; g_pEventManager->postEvent(SHyprIPCEvent{"urgent", getFormat("%x", PWINDOW)}); + EMIT_HOOK_EVENT("urgent", PWINDOW); PWINDOW->m_bIsUrgent = true; @@ -869,6 +873,7 @@ void Events::listener_activateX11(void* owner, void* data) { return; g_pEventManager->postEvent(SHyprIPCEvent{"urgent", getFormat("%x", PWINDOW)}); + EMIT_HOOK_EVENT("urgent", PWINDOW); if (!*PFOCUSONACTIVATE) return; @@ -1044,11 +1049,13 @@ void Events::listener_requestMinimize(void* owner, void* data) { const auto E = (wlr_xwayland_minimize_event*)data; g_pEventManager->postEvent({"minimize", getFormat("%x,%i", PWINDOW, (int)E->minimize)}); + EMIT_HOOK_EVENT("minimize", (std::vector{PWINDOW, (void*)E->minimize})); wlr_xwayland_surface_set_minimized(PWINDOW->m_uSurface.xwayland, E->minimize && g_pCompositor->m_pLastWindow != PWINDOW); // fucking DXVK } else { const auto E = (wlr_foreign_toplevel_handle_v1_minimized_event*)data; g_pEventManager->postEvent({"minimize", getFormat("%x,%i", PWINDOW, E ? (int)E->minimized : 1)}); + EMIT_HOOK_EVENT("minimize", (std::vector{PWINDOW, (void*)(E ? (int)E->minimized : 1)})); } } diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index bf97a80c..3d00408d 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -132,6 +132,7 @@ void CMonitor::onConnect(bool noRule) { // g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName}); + EMIT_HOOK_EVENT("monitorAdded", this); if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet g_pCompositor->setActiveMonitor(this); @@ -203,6 +204,7 @@ void CMonitor::onDisconnect() { Debug::log(LOG, "Removed monitor %s!", szName.c_str()); g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName}); + EMIT_HOOK_EVENT("monitorRemoved", this); if (!BACKUPMON) { Debug::log(WARN, "Unplugged last monitor, entering an unsafe state. Good luck my friend."); diff --git a/src/helpers/Workspace.cpp b/src/helpers/Workspace.cpp index 06b3c766..e60c1ea4 100644 --- a/src/helpers/Workspace.cpp +++ b/src/helpers/Workspace.cpp @@ -37,6 +37,7 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) { m_fAlpha.registerVar(); g_pEventManager->postEvent({"createworkspace", m_szName}, true); + EMIT_HOOK_EVENT("createWorkspace", this); } CWorkspace::~CWorkspace() { @@ -51,6 +52,7 @@ CWorkspace::~CWorkspace() { } g_pEventManager->postEvent({"destroyworkspace", m_szName}, true); + EMIT_HOOK_EVENT("destroyWorkspace", this); } void CWorkspace::startAnim(bool in, bool left, bool instant) { diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 85993676..9e2a6012 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -741,6 +741,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow; g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)on)}); + EMIT_HOOK_EVENT("fullscreen", pWindow); if (!pWindow->m_bIsFullscreen) { // if it got its fullscreen disabled, set back its node if it had one diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index 24e76035..d62556d5 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -322,6 +322,7 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) { // event g_pEventManager->postEvent(SHyprIPCEvent{"changefloatingmode", getFormat("%x,%d", pWindow, (int)TILED)}); + EMIT_HOOK_EVENT("changeFloatingMode", pWindow); if (!TILED) { const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 94d26c29..e349d650 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -228,7 +228,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { if (getNodesOnWorkspace(PWORKSPACE->m_iID) < 2) { PMASTERNODE->position = PMONITOR->vecReservedTopLeft + PMONITOR->vecPosition; PMASTERNODE->size = Vector2D(PMONITOR->vecSize.x - PMONITOR->vecReservedTopLeft.x - PMONITOR->vecReservedBottomRight.x, - PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PMONITOR->vecReservedTopLeft.y); applyNodeDataToWindow(PMASTERNODE); return; } else if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT || PWORKSPACEDATA->orientation == ORIENTATION_RIGHT) { @@ -524,6 +524,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow; g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)on)}); + EMIT_HOOK_EVENT("fullscreen", pWindow); if (!pWindow->m_bIsFullscreen) { // if it got its fullscreen disabled, set back its node if it had one diff --git a/src/managers/HookSystemManager.cpp b/src/managers/HookSystemManager.cpp new file mode 100644 index 00000000..02775a24 --- /dev/null +++ b/src/managers/HookSystemManager.cpp @@ -0,0 +1,44 @@ +#include "HookSystemManager.hpp" + +CHookSystemManager::CHookSystemManager() { + ; // +} + +// returns the pointer to the function +HOOK_CALLBACK_FN* CHookSystemManager::hookDynamic(const std::string& event, HOOK_CALLBACK_FN fn) { + const auto PVEC = getVecForEvent(event); + const auto PFN = &m_lCallbackFunctions.emplace_back(fn); + PVEC->emplace_back(PFN); + return PFN; +} + +void CHookSystemManager::hookStatic(const std::string& event, HOOK_CALLBACK_FN* fn) { + const auto PVEC = getVecForEvent(event); + PVEC->emplace_back(fn); +} + +void CHookSystemManager::unhook(HOOK_CALLBACK_FN* fn) { + std::erase_if(m_lCallbackFunctions, [&](const auto& other) { return &other == fn; }); + for (auto& [k, v] : m_lpRegisteredHooks) { + std::erase_if(v, [&](const auto& other) { return other == fn; }); + } +} + +void CHookSystemManager::emit(const std::vector* callbacks, std::any data) { + if (callbacks->empty()) + return; + + for (auto& cb : *callbacks) + (*cb)(cb, data); +} + +std::vector* CHookSystemManager::getVecForEvent(const std::string& event) { + auto IT = std::find_if(m_lpRegisteredHooks.begin(), m_lpRegisteredHooks.end(), [&](const auto& other) { return other.first == event; }); + + if (IT != m_lpRegisteredHooks.end()) + return &IT->second; + + Debug::log(LOG, "[hookSystem] New hook event registered: %s", event.c_str()); + + return &m_lpRegisteredHooks.emplace_back(std::make_pair<>(event, std::vector{})).second; +} \ No newline at end of file diff --git a/src/managers/HookSystemManager.hpp b/src/managers/HookSystemManager.hpp new file mode 100644 index 00000000..57f1e58b --- /dev/null +++ b/src/managers/HookSystemManager.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "../defines.hpp" + +#include +#include +#include + +// global typedef for hooked functions. Passes itself as a ptr when called, and `data` additionally. +typedef std::function HOOK_CALLBACK_FN; + +#define EMIT_HOOK_EVENT(name, param) \ + { \ + static auto* const PEVENTVEC = g_pHookSystem->getVecForEvent(name); \ + g_pHookSystem->emit(PEVENTVEC, param); \ + } + +class CHookSystemManager { + public: + CHookSystemManager(); + + // returns the pointer to the function + HOOK_CALLBACK_FN* hookDynamic(const std::string& event, HOOK_CALLBACK_FN fn); + void hookStatic(const std::string& event, HOOK_CALLBACK_FN* fn); + void unhook(HOOK_CALLBACK_FN* fn); + + void emit(const std::vector* callbacks, std::any data = 0); + std::vector* getVecForEvent(const std::string& event); + + private: + // todo: this is slow. Maybe static ptrs should be somehow allowed. unique ptr for vec? + std::list>> m_lpRegisteredHooks; + std::list m_lCallbackFunctions; +}; + +inline std::unique_ptr g_pHookSystem; \ No newline at end of file diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index ef988c32..76c08611 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -792,6 +792,7 @@ void CKeybindManager::changeworkspace(std::string args) { PWORKSPACETOCHANGETO->startAnim(true, ANIMTOLEFT); g_pEventManager->postEvent(SHyprIPCEvent{"workspace", PWORKSPACETOCHANGETO->m_szName}); + EMIT_HOOK_EVENT("workspace", PWORKSPACETOCHANGETO); } // If the monitor is not the one our cursor's at, warp to it. @@ -885,6 +886,7 @@ void CKeybindManager::changeworkspace(std::string args) { g_pCompositor->warpCursorTo(PMONITOR->vecPosition + PMONITOR->vecSize / 2.f); g_pEventManager->postEvent(SHyprIPCEvent{"workspace", PWORKSPACE->m_szName}); + EMIT_HOOK_EVENT("workspace", PWORKSPACE); g_pCompositor->setActiveMonitor(PMONITOR); @@ -1066,6 +1068,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) { // manually post event cuz it got ignored above g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", PWINDOW, PWORKSPACE->m_szName.c_str())}); + EMIT_HOOK_EVENT("moveWindow", (std::vector{PWINDOW, PWORKSPACE})); PWINDOW->m_iWorkspaceID = OLDWORKSPACEIDRETURN; const auto PNEXTCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW); @@ -1702,6 +1705,7 @@ void CKeybindManager::setSubmap(std::string submap) { m_szCurrentSelectedSubmap = ""; Debug::log(LOG, "Reset active submap to the default one."); g_pEventManager->postEvent(SHyprIPCEvent{"submap", ""}); + EMIT_HOOK_EVENT("submap", m_szCurrentSelectedSubmap); return; } @@ -1710,6 +1714,7 @@ void CKeybindManager::setSubmap(std::string submap) { m_szCurrentSelectedSubmap = submap; Debug::log(LOG, "Changed keybind submap to %s", submap.c_str()); g_pEventManager->postEvent(SHyprIPCEvent{"submap", submap}); + EMIT_HOOK_EVENT("submap", m_szCurrentSelectedSubmap); return; } } diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 6aa3b73b..0c6a2420 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -531,8 +531,10 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) { &wlr_keyboard_from_input_device(keyboard)->events.keymap, [&](void* owner, void* data) { const auto PKEYBOARD = (SKeyboard*)owner; + const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD); - g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + getActiveLayoutForKeyboard(PKEYBOARD)}, true); // force as this should ALWAYS be sent + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT}, true); // force as this should ALWAYS be sent + EMIT_HOOK_EVENT("activeLayout", (std::vector{PKEYBOARD, (void*)&LAYOUT})); }, PNEWKEYBOARD, "Keyboard"); @@ -568,8 +570,10 @@ void CInputManager::newVirtualKeyboard(wlr_input_device* keyboard) { &wlr_keyboard_from_input_device(keyboard)->events.keymap, [&](void* owner, void* data) { const auto PKEYBOARD = (SKeyboard*)owner; + const auto LAYOUT = getActiveLayoutForKeyboard(PKEYBOARD); - g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + getActiveLayoutForKeyboard(PKEYBOARD)}, true); // force as this should ALWAYS be sent + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEYBOARD->name + "," + LAYOUT}, true); // force as this should ALWAYS be sent + EMIT_HOOK_EVENT("activeLayout", (std::vector{PKEYBOARD, (void*)&LAYOUT})); }, PNEWKEYBOARD, "Keyboard"); @@ -710,7 +714,10 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) { xkb_keymap_unref(KEYMAP); xkb_context_unref(CONTEXT); - g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + getActiveLayoutForKeyboard(pKeyboard)}, true); // force as this should ALWAYS be sent + const auto LAYOUTSTR = getActiveLayoutForKeyboard(pKeyboard); + + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUTSTR}, true); // force as this should ALWAYS be sent + EMIT_HOOK_EVENT("activeLayout", (std::vector{pKeyboard, (void*)&LAYOUTSTR})); Debug::log(LOG, "Set the keyboard layout to %s and variant to %s for keyboard \"%s\"", rules.layout, rules.variant, pKeyboard->keyboard->name); } @@ -974,7 +981,10 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) { if (PWLRKB->modifiers.group != pKeyboard->activeLayout) { pKeyboard->activeLayout = PWLRKB->modifiers.group; - g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + getActiveLayoutForKeyboard(pKeyboard)}, true); // force as this should ALWAYS be sent + const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard); + + g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT}, true); // force as this should ALWAYS be sent + EMIT_HOOK_EVENT("activeLayout", (std::vector{pKeyboard, (void*)&LAYOUT})); } } diff --git a/src/managers/input/InputMethodRelay.cpp b/src/managers/input/InputMethodRelay.cpp index 20057a6a..95f0b6fb 100644 --- a/src/managers/input/InputMethodRelay.cpp +++ b/src/managers/input/InputMethodRelay.cpp @@ -2,7 +2,9 @@ #include "InputManager.hpp" #include "../../Compositor.hpp" -CInputMethodRelay::CInputMethodRelay() {} +CInputMethodRelay::CInputMethodRelay() { + g_pHookSystem->hookDynamic("keyboardFocus", [&](void* self, std::any param) { onKeyboardFocus(std::any_cast(param)); }); +} void CInputMethodRelay::onNewIME(wlr_input_method_v2* pIME) { if (m_pWLRIME) { diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 4d7f881a..bee1deb6 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -37,6 +37,8 @@ CToplevelExportProtocolManager::CToplevelExportProtocolManager() { m_liDisplayDestroy.notify = handleDisplayDestroy; wl_display_add_destroy_listener(g_pCompositor->m_sWLDisplay, &m_liDisplayDestroy); + g_pHookSystem->hookDynamic("preRender", [&](void* self, std::any data) { onMonitorRender(std::any_cast(data)); }); + Debug::log(LOG, "ToplevelExportManager started successfully!"); } diff --git a/src/protocols/ToplevelExport.hpp b/src/protocols/ToplevelExport.hpp index d3bbc362..e9042e66 100644 --- a/src/protocols/ToplevelExport.hpp +++ b/src/protocols/ToplevelExport.hpp @@ -50,8 +50,6 @@ class CToplevelExportProtocolManager { void removeClient(SToplevelClient* client, bool force = false); void removeFrame(SToplevelFrame* frame, bool force = false); void copyFrame(wl_client* client, wl_resource* resource, wl_resource* buffer, int32_t ignore_damage); - - void onMonitorRender(CMonitor* pMonitor); void displayDestroy(); void onWindowUnmap(CWindow* pWindow); @@ -67,4 +65,6 @@ class CToplevelExportProtocolManager { void shareFrame(SToplevelFrame* frame); bool copyFrameDmabuf(SToplevelFrame* frame); bool copyFrameShm(SToplevelFrame* frame, timespec* now); + + void onMonitorRender(CMonitor* pMonitor); }; \ No newline at end of file diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index e427e4c2..0d2327a0 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -26,6 +26,8 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { Debug::log(WARN, "!RENDERER: Using the legacy GLES2 renderer!"); #endif + g_pHookSystem->hookDynamic("preRender", [&](void* self, std::any data) { preRender(std::any_cast(data)); }); + pixman_region32_init(&m_rOriginalDamageRegion); RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), "Couldn't unset current EGL!");