diff --git a/flake.lock b/flake.lock index 7ca8097..0f96fc6 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ ] }, "locked": { - "lastModified": 1729527199, - "narHash": "sha256-D5/YksfRga8Akd04ZtIkuYSIOjXVrAzQIQBSeplokzU=", + "lastModified": 1739103745, + "narHash": "sha256-c53dcRaw0F4Os9WD05HwIRs9kTDZw4Mxe1XK4edEALo=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "8d732fa8aff8b12ef2b1e2f00fc8153e41312b72", + "rev": "a3dda0d10ce9aa1d1dfb7a6c139ea8c2872c74bd", "type": "github" }, "original": { @@ -87,11 +87,11 @@ ] }, "locked": { - "lastModified": 1728669738, - "narHash": "sha256-EDNAU9AYcx8OupUzbTbWE1d3HYdeG0wO6Msg3iL1muk=", + "lastModified": 1738664950, + "narHash": "sha256-xIeGNM+iivwVHkv9tHwOqoUP5dDrtees34bbFKKMZYs=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "0264e698149fcb857a66a53018157b41f8d97bb0", + "rev": "7c6d165e1eb9045a996551eb9f121b6d1b30adc3", "type": "github" }, "original": { @@ -100,11 +100,42 @@ "type": "github" } }, + "hyprgraphics": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1739049071, + "narHash": "sha256-3+7TpXMrbsUXSwgr5VAKAnmkzMb6JO+Rvc9XRb5NMg4=", + "owner": "hyprwm", + "repo": "hyprgraphics", + "rev": "175c6b29b6ff82100539e7c4363a35a02c74dd73", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprgraphics", + "type": "github" + } + }, "hyprland": { "inputs": { "aquamarine": "aquamarine", "hyprcursor": "hyprcursor", + "hyprgraphics": "hyprgraphics", "hyprland-protocols": "hyprland-protocols", + "hyprland-qtutils": "hyprland-qtutils", "hyprlang": "hyprlang", "hyprutils": "hyprutils", "hyprwayland-scanner": "hyprwayland-scanner", @@ -116,11 +147,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1729989895, - "narHash": "sha256-IFctdjt+v7zRDe24Y8+BdVDaKy0pmn60FWDzpYg4CT0=", + "lastModified": 1739815352, + "narHash": "sha256-JqMiCMkkOOq5380y7S/xgBG9yd2C7/KjDbXqu4vLe2A=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "a3d3b4fd64a51a8c1663b450bd2a408f1f0fa9b3", + "rev": "d01f9943e1d401b09fc53be3c161279ab4f2c5ba", "type": "github" }, "original": { @@ -141,11 +172,11 @@ ] }, "locked": { - "lastModified": 1728345020, - "narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=", + "lastModified": 1738422629, + "narHash": "sha256-5v+bv75wJWvahyM2xcMTSNNxmV8a7hb01Eey5zYnBJw=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "a7c183800e74f337753de186522b9017a07a8cee", + "rev": "755aef8dab49d0fc4663c715fa4ad221b2aedaed", "type": "github" }, "original": { @@ -154,6 +185,74 @@ "type": "github" } }, + "hyprland-qt-support": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprland-qtutils", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "hyprland-qtutils", + "nixpkgs" + ], + "systems": [ + "hyprland", + "hyprland-qtutils", + "systems" + ] + }, + "locked": { + "lastModified": 1737634706, + "narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=", + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "rev": "8810df502cdee755993cb803eba7b23f189db795", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "type": "github" + } + }, + "hyprland-qtutils": { + "inputs": { + "hyprland-qt-support": "hyprland-qt-support", + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprland-qtutils", + "hyprlang", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1739048983, + "narHash": "sha256-REhTcXq4qs3B3cCDtLlYDz0GZvmsBSh947Ub6pQWGTQ=", + "owner": "hyprwm", + "repo": "hyprland-qtutils", + "rev": "3504a293c8f8db4127cb0f7cfc1a318ffb4316f8", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qtutils", + "type": "github" + } + }, "hyprlang": { "inputs": { "hyprutils": [ @@ -170,11 +269,11 @@ ] }, "locked": { - "lastModified": 1728168612, - "narHash": "sha256-AnB1KfiXINmuiW7BALYrKqcjCnsLZPifhb/7BsfPbns=", + "lastModified": 1739048914, + "narHash": "sha256-vd5rJBTmp2w7SDgfv23Zcd84ktI5eDA7e5UBzx+pKrU=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "f054f2e44d6a0b74607a6bc0f52dba337a3db38e", + "rev": "a7334904d591f38757c46fbe2ab68651877d9099", "type": "github" }, "original": { @@ -195,11 +294,11 @@ ] }, "locked": { - "lastModified": 1728941256, - "narHash": "sha256-WRypmcZ2Bw94lLmcmxYokVOHPJSZ7T06V49QZ4tkZeQ=", + "lastModified": 1739048933, + "narHash": "sha256-ck6MaoYvISBQKqZR+HcxXnx0wOhyCauxfVMaV5zhJxQ=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "fd4be8b9ca932f7384e454bcd923c5451ef2aa85", + "rev": "e4e018a2ca6f5a9c33511973454199e1c7c85499", "type": "github" }, "original": { @@ -220,11 +319,11 @@ ] }, "locked": { - "lastModified": 1726874836, - "narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=", + "lastModified": 1739049028, + "narHash": "sha256-RleJp7LYbr6s+M1xgbmhtBs+fYa3ZdIiF7+QalJ4D1g=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "500c81a9e1a76760371049a8d99e008ea77aa59e", + "rev": "04146df74a8d5ec0b579657307be01f1e241125f", "type": "github" }, "original": { @@ -235,11 +334,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1729413321, - "narHash": "sha256-I4tuhRpZFa6Fu6dcH9Dlo5LlH17peT79vx1y1SpeKt0=", + "lastModified": 1739020877, + "narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1997e4aa514312c1af7e2bda7fad1644e778ff26", + "rev": "a79cfe0ebd24952b580b1cf08cd906354996d547", "type": "github" }, "original": { @@ -249,22 +348,6 @@ "type": "github" } }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1720386169, - "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.05", - "repo": "nixpkgs", - "type": "github" - } - }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", @@ -272,15 +355,14 @@ "nixpkgs": [ "hyprland", "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" + ] }, "locked": { - "lastModified": 1729104314, - "narHash": "sha256-pZRZsq5oCdJt3upZIU4aslS9XwFJ+/nVtALHIciX/BI=", + "lastModified": 1737465171, + "narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "3c3e88f0f544d6bb54329832616af7eb971b6be6", + "rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17", "type": "github" }, "original": { @@ -338,11 +420,11 @@ ] }, "locked": { - "lastModified": 1728166987, - "narHash": "sha256-w6dVTguAn9zJ+7aPOhBQgDz8bn6YZ7b56cY8Kg5HJRI=", + "lastModified": 1737634991, + "narHash": "sha256-dBAnb7Kbnier30cA7AgxVSxxARmxKZ1vHZT33THSIr8=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "fb9c8d665af0588bb087f97d0f673ddf0d501787", + "rev": "e09dfe2726c8008f983e45a0aa1a3b7416aaeb8a", "type": "github" }, "original": { diff --git a/src/Globals.hpp b/src/Globals.hpp index e1c956d..cba0af7 100644 --- a/src/Globals.hpp +++ b/src/Globals.hpp @@ -56,6 +56,9 @@ namespace Config { extern bool disableGestures; extern bool reverseSwipe; + extern bool disableHyprgrassIntegration; + extern std::string hyprgrassSwipeEdge; + extern bool disableBlur; extern float overrideAnimSpeed; extern float dragAlpha; diff --git a/src/main.cpp b/src/main.cpp index 62db994..0023831 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,11 @@ #include #include #include +#include #include "Overview.hpp" #include "Globals.hpp" +#include "src/SharedDefs.hpp" +#include "src/debug/Log.hpp" void* pMouseKeybind; void* pRenderWindow; @@ -49,6 +52,9 @@ bool Config::showSpecialWorkspace = false; bool Config::disableGestures = false; bool Config::reverseSwipe = false; +bool Config::disableHyprgrassIntegration = false; +std::string Config::hyprgrassSwipeEdge = "r"; + bool Config::disableBlur = false; float Config::overrideAnimSpeed = 0; @@ -64,6 +70,7 @@ Hyprutils::Memory::CSharedPointer g_pCloseLayerHook; Hyprutils::Memory::CSharedPointer g_pMouseButtonHook; Hyprutils::Memory::CSharedPointer g_pMouseAxisHook; Hyprutils::Memory::CSharedPointer g_pTouchDownHook; +Hyprutils::Memory::CSharedPointer g_pTouchMoveHook; Hyprutils::Memory::CSharedPointer g_pTouchUpHook; Hyprutils::Memory::CSharedPointer g_pSwipeBeginHook; Hyprutils::Memory::CSharedPointer g_pSwipeUpdateHook; @@ -71,6 +78,9 @@ Hyprutils::Memory::CSharedPointer g_pSwipeEndHook; Hyprutils::Memory::CSharedPointer g_pKeyPressHook; Hyprutils::Memory::CSharedPointer g_pSwitchWorkspaceHook; Hyprutils::Memory::CSharedPointer g_pAddMonitorHook; +Hyprutils::Memory::CSharedPointer g_pHyprgrassEdgeBeginHook; +Hyprutils::Memory::CSharedPointer g_pHyprgrassEdgeMoveHook; +Hyprutils::Memory::CSharedPointer g_pHyprgrassEdgeEndHook; APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; @@ -251,6 +261,69 @@ void onSwipeEnd(void* thisptr, SCallbackInfo& info, std::any args) { widget->endSwipe(e); } +Vector2D g_hyprgrassEdgePrevCoord; + +// event hook for hyprgrass edge gestures +void onHyprgrassEdgeBegin(void* thisptr, SCallbackInfo& info, std::any args) { + if (Config::disableHyprgrassIntegration) return; + + const auto e = std::any_cast>(args); + const auto swipe = IPointer::SSwipeBeginEvent{}; + + // event name is "edge:x:y" + // where x is the origin edge and y is the swipe direction + size_t a = e.first.find(':'); + size_t b = e.first.find(':', a+1); + if (e.first.compare(a+1, b-a-1, Config::hyprgrassSwipeEdge) != 0) { + return; + } + + info.cancelled = true; + g_hyprgrassEdgePrevCoord = e.second; + const auto widget = getWidgetForMonitor(g_pCompositor->getMonitorFromCursor()); + if (widget != nullptr && !widget->isActive()) + widget->beginSwipe(swipe); + + // end other widget swipe + for (auto& w : g_overviewWidgets) { + if (w != widget && w->isSwiping()) { + IPointer::SSwipeEndEvent dummy; + dummy.cancelled = true; + w->endSwipe(dummy); + } + } +} + +void onHyprgrassEdgeMove(void *thisptr, SCallbackInfo& info, std::any args) { + if (Config::disableHyprgrassIntegration) return; + + int fingers = std::any_cast(HyprlandAPI::getConfigValue(pHandle, "gestures:workspace_swipe_fingers")->getValue()); + int distance = std::any_cast(HyprlandAPI::getConfigValue(pHandle, "gestures:workspace_swipe_distance")->getValue()); + + const auto e = std::any_cast(args); + const IPointer::SSwipeUpdateEvent swipe = { + .fingers = static_cast(fingers), + // this means I need to swipe 1/4 of the screen to trigger I think? + // I don't understand what "unit" distance is in + .delta = (e - g_hyprgrassEdgePrevCoord) * distance * 4, + }; + g_hyprgrassEdgePrevCoord = e; + + const auto widget = getWidgetForMonitor(g_pCompositor->getMonitorFromCursor()); + if (widget != nullptr) + info.cancelled = !widget->updateSwipe(swipe); +} + +void onHyprgrassEdgeEnd(void* thisptr, SCallbackInfo& info, std::any args) { + if (Config::disableHyprgrassIntegration) return; + + const IPointer::SSwipeEndEvent e = {.cancelled = false}; + + const auto widget = getWidgetForMonitor(g_pCompositor->getMonitorFromCursor()); + if (widget != nullptr) + widget->endSwipe(e); +} + // atm this is only for ESC to exit void onKeyPress(void* thisptr, SCallbackInfo& info, std::any args) { const auto e = std::any_cast(std::any_cast>(args)["event"]); @@ -268,22 +341,42 @@ void onKeyPress(void* thisptr, SCallbackInfo& info, std::any args) { } } +PHLMONITOR g_pTouchedMonitor; + void onTouchDown(void* thisptr, SCallbackInfo& info, std::any args) { const auto e = std::any_cast(args); - const auto targetMonitor = g_pCompositor->getMonitorFromName(e.device ? e.device->deviceName : ""); + auto targetMonitor = g_pCompositor->getMonitorFromName(!e.device->boundOutput.empty() ? e.device->boundOutput : ""); + targetMonitor = targetMonitor ? targetMonitor : g_pCompositor->m_pLastMonitor.lock(); + const auto widget = getWidgetForMonitor(targetMonitor); - if (widget != nullptr && targetMonitor != nullptr) - if (widget->isActive()) - info.cancelled = !widget->buttonEvent(true, { targetMonitor->vecPosition.x + e.pos.x * targetMonitor->vecSize.x, targetMonitor->vecPosition.y + e.pos.y * targetMonitor->vecSize.y }); + if (widget != nullptr && targetMonitor != nullptr) { + if (widget->isActive()) { + Vector2D pos = targetMonitor->vecPosition + e.pos * targetMonitor->vecSize; + info.cancelled = !widget->buttonEvent(true, pos); + if (info.cancelled) { + g_pTouchedMonitor = targetMonitor; + g_pCompositor->warpCursorTo(pos); + g_pInputManager->refocus(); + } + } + } +} + +void onTouchMove(void* thisptr, SCallbackInfo& info, std::any args) { + if (g_pTouchedMonitor == nullptr) return; + + const auto e = std::any_cast(args); + g_pCompositor->warpCursorTo(g_pTouchedMonitor->vecPosition + g_pTouchedMonitor->vecSize * e.pos); + g_pInputManager->simulateMouseMovement(); } void onTouchUp(void* thisptr, SCallbackInfo& info, std::any args) { - const auto e = std::any_cast(args); - const auto targetMonitor = g_pCompositor->getMonitorFromID(e.touchID); - const auto widget = getWidgetForMonitor(targetMonitor); - if (widget != nullptr && targetMonitor != nullptr) + const auto widget = getWidgetForMonitor(g_pTouchedMonitor); + if (widget != nullptr && g_pTouchedMonitor != nullptr) if (widget->isActive()) info.cancelled = !widget->buttonEvent(false, g_pInputManager->getMouseCoordsInternal()); + + g_pTouchedMonitor = nullptr; } static SDispatchResult dispatchToggleOverview(std::string arg) { @@ -465,6 +558,9 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE inHandle) { HyprlandAPI::addConfigValue(pHandle, "plugin:overview:disableGestures", Hyprlang::INT{0}); HyprlandAPI::addConfigValue(pHandle, "plugin:overview:reverseSwipe", Hyprlang::INT{0}); + HyprlandAPI::addConfigValue(pHandle, "plugin:overview:disableHyprgrassIntegration", Hyprlang::INT{0}); + HyprlandAPI::addConfigValue(pHandle, "plugin:overview:hyprgrassSwipeEdge", Hyprlang::STRING{"r"}); + HyprlandAPI::addConfigValue(pHandle, "plugin:overview:disableBlur", Hyprlang::INT{0}); HyprlandAPI::addConfigValue(pHandle, "plugin:overview:overrideAnimSpeed", Hyprlang::FLOAT{0.0}); HyprlandAPI::addConfigValue(pHandle, "plugin:overview:dragAlpha", Hyprlang::FLOAT{0.2}); @@ -490,6 +586,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE inHandle) { g_pMouseAxisHook = HyprlandAPI::registerCallbackDynamic(pHandle, "mouseAxis", onMouseAxis); g_pTouchDownHook = HyprlandAPI::registerCallbackDynamic(pHandle, "touchDown", onTouchDown); + g_pTouchMoveHook = HyprlandAPI::registerCallbackDynamic(pHandle, "touchMove", onTouchMove); g_pTouchUpHook = HyprlandAPI::registerCallbackDynamic(pHandle, "touchUp", onTouchUp); g_pSwipeBeginHook = HyprlandAPI::registerCallbackDynamic(pHandle, "swipeBegin", onSwipeBegin); @@ -500,6 +597,10 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE inHandle) { g_pSwitchWorkspaceHook = HyprlandAPI::registerCallbackDynamic(pHandle, "workspace", onWorkspaceChange); + g_pHyprgrassEdgeBeginHook = HyprlandAPI::registerCallbackDynamic(pHandle, "hyprgrass:edgeBegin", onHyprgrassEdgeBegin); + g_pHyprgrassEdgeMoveHook = HyprlandAPI::registerCallbackDynamic(pHandle, "hyprgrass:edgeUpdate", onHyprgrassEdgeMove); + g_pHyprgrassEdgeEndHook = HyprlandAPI::registerCallbackDynamic(pHandle, "hyprgrass:edgeEnd", onHyprgrassEdgeEnd); + // CHyprRenderer::renderWindow auto funcSearch = HyprlandAPI::findFunctionsByName(pHandle, "renderWindow"); pRenderWindow = funcSearch[0].address;