11#include < hyprland/src/plugins/PluginSystem.hpp>
22#include < hyprland/src/plugins/PluginAPI.hpp>
33#include < hyprland/src/devices/IKeyboard.hpp>
4+ #include < hyprlang.hpp>
45#include " Overview.hpp"
56#include " Globals.hpp"
7+ #include " src/SharedDefs.hpp"
8+ #include " src/debug/Log.hpp"
69
710void * pMouseKeybind;
811void * pRenderWindow;
@@ -49,6 +52,9 @@ bool Config::showSpecialWorkspace = false;
4952bool Config::disableGestures = false ;
5053bool Config::reverseSwipe = false ;
5154
55+ bool Config::disableHyprgrassIntegration = false ;
56+ std::string Config::hyprgrassSwipeEdge = " r" ;
57+
5258bool Config::disableBlur = false ;
5359
5460float Config::overrideAnimSpeed = 0 ;
@@ -72,6 +78,9 @@ Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN> g_pSwipeEndHook;
7278Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN > g_pKeyPressHook;
7379Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN > g_pSwitchWorkspaceHook;
7480Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN > g_pAddMonitorHook;
81+ Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN > g_pHyprgrassEdgeBeginHook;
82+ Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN > g_pHyprgrassEdgeMoveHook;
83+ Hyprutils::Memory::CSharedPointer<HOOK_CALLBACK_FN > g_pHyprgrassEdgeEndHook;
7584
7685APICALL EXPORT std::string PLUGIN_API_VERSION () {
7786 return HYPRLAND_API_VERSION ;
@@ -252,6 +261,69 @@ void onSwipeEnd(void* thisptr, SCallbackInfo& info, std::any args) {
252261 widget->endSwipe (e);
253262}
254263
264+ Vector2D g_hyprgrassEdgePrevCoord;
265+
266+ // event hook for hyprgrass edge gestures
267+ void onHyprgrassEdgeBegin (void * thisptr, SCallbackInfo& info, std::any args) {
268+ if (Config::disableHyprgrassIntegration) return ;
269+
270+ const auto e = std::any_cast<std::pair<std::string, Vector2D>>(args);
271+ const auto swipe = IPointer::SSwipeBeginEvent{};
272+
273+ // event name is "edge:x:y"
274+ // where x is the origin edge and y is the swipe direction
275+ size_t a = e.first .find (' :' );
276+ size_t b = e.first .find (' :' , a+1 );
277+ if (e.first .compare (a+1 , b-a-1 , Config::hyprgrassSwipeEdge) != 0 ) {
278+ return ;
279+ }
280+
281+ info.cancelled = true ;
282+ g_hyprgrassEdgePrevCoord = e.second ;
283+ const auto widget = getWidgetForMonitor (g_pCompositor->getMonitorFromCursor ());
284+ if (widget!= nullptr )
285+ widget->beginSwipe (swipe);
286+
287+ // end other widget swipe
288+ for (auto & w : g_overviewWidgets) {
289+ if (w != widget && w->isSwiping ()) {
290+ IPointer::SSwipeEndEvent dummy;
291+ dummy.cancelled = true ;
292+ w->endSwipe (dummy);
293+ }
294+ }
295+ }
296+
297+ void onHyprgrassEdgeMove (void *thisptr, SCallbackInfo& info, std::any args) {
298+ if (Config::disableHyprgrassIntegration) return ;
299+
300+ int fingers = std::any_cast<Hyprlang::INT >(HyprlandAPI::getConfigValue (pHandle, " gestures:workspace_swipe_fingers" )->getValue ());
301+ int distance = std::any_cast<Hyprlang::INT >(HyprlandAPI::getConfigValue (pHandle, " gestures:workspace_swipe_distance" )->getValue ());
302+
303+ const auto e = std::any_cast<Vector2D>(args);
304+ const IPointer::SSwipeUpdateEvent swipe = {
305+ .fingers = static_cast <uint32_t >(fingers),
306+ // this means I need to swipe 1/4 of the screen to trigger I think?
307+ // I don't understand what "unit" distance is in
308+ .delta = (e - g_hyprgrassEdgePrevCoord) * distance * 4 ,
309+ };
310+ g_hyprgrassEdgePrevCoord = e;
311+
312+ const auto widget = getWidgetForMonitor (g_pCompositor->getMonitorFromCursor ());
313+ if (widget != nullptr )
314+ info.cancelled = !widget->updateSwipe (swipe);
315+ }
316+
317+ void onHyprgrassEdgeEnd (void * thisptr, SCallbackInfo& info, std::any args) {
318+ if (Config::disableHyprgrassIntegration) return ;
319+
320+ const IPointer::SSwipeEndEvent e = {.cancelled = false };
321+
322+ const auto widget = getWidgetForMonitor (g_pCompositor->getMonitorFromCursor ());
323+ if (widget != nullptr )
324+ widget->endSwipe (e);
325+ }
326+
255327// atm this is only for ESC to exit
256328void onKeyPress (void * thisptr, SCallbackInfo& info, std::any args) {
257329 const auto e = std::any_cast<IKeyboard::SKeyEvent>(std::any_cast<std::unordered_map<std::string, std::any>>(args)[" event" ]);
@@ -486,6 +558,9 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE inHandle) {
486558 HyprlandAPI::addConfigValue (pHandle, " plugin:overview:disableGestures" , Hyprlang::INT {0 });
487559 HyprlandAPI::addConfigValue (pHandle, " plugin:overview:reverseSwipe" , Hyprlang::INT {0 });
488560
561+ HyprlandAPI::addConfigValue (pHandle, " plugin:overview:disableHyprgrassIntegration" , Hyprlang::INT {0 });
562+ HyprlandAPI::addConfigValue (pHandle, " plugin:overview:hyprgrassSwipeEdge" , Hyprlang::STRING {" r" });
563+
489564 HyprlandAPI::addConfigValue (pHandle, " plugin:overview:disableBlur" , Hyprlang::INT {0 });
490565 HyprlandAPI::addConfigValue (pHandle, " plugin:overview:overrideAnimSpeed" , Hyprlang::FLOAT {0.0 });
491566 HyprlandAPI::addConfigValue (pHandle, " plugin:overview:dragAlpha" , Hyprlang::FLOAT {0.2 });
@@ -522,6 +597,10 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE inHandle) {
522597
523598 g_pSwitchWorkspaceHook = HyprlandAPI::registerCallbackDynamic (pHandle, " workspace" , onWorkspaceChange);
524599
600+ g_pHyprgrassEdgeBeginHook = HyprlandAPI::registerCallbackDynamic (pHandle, " hyprgrass:edgeBegin" , onHyprgrassEdgeBegin);
601+ g_pHyprgrassEdgeMoveHook = HyprlandAPI::registerCallbackDynamic (pHandle, " hyprgrass:edgeUpdate" , onHyprgrassEdgeMove);
602+ g_pHyprgrassEdgeEndHook = HyprlandAPI::registerCallbackDynamic (pHandle, " hyprgrass:edgeEnd" , onHyprgrassEdgeEnd);
603+
525604 // CHyprRenderer::renderWindow
526605 auto funcSearch = HyprlandAPI::findFunctionsByName (pHandle, " renderWindow" );
527606 pRenderWindow = funcSearch[0 ].address ;
0 commit comments