diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 89195a277..ecb0937f7 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -498,6 +498,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("gestures:workspace_swipe_forever", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe_numbered", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe_use_r", Hyprlang::INT{0}); + m_pConfig->addConfigValue("gestures:workspace_swipe_touch", Hyprlang::INT{0}); m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", Hyprlang::INT{1}); m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0}); diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 5fc2692ac..d48fdff72 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -283,6 +283,7 @@ struct SSwipeGesture { int initialDirection = 0; float avgSpeed = 0; int speedPoints = 0; + int touch_id = 0; CMonitor* pMonitor = nullptr; }; diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index fd3aefe51..d63de6ef2 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -231,6 +231,8 @@ class CInputManager { // swipe void beginWorkspaceSwipe(); + void updateWorkspaceSwipe(double); + void endWorkspaceSwipe(); void setBorderCursorIcon(eBorderIconDirection); void setCursorIconOnBorder(CWindow* w); diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index 937266af6..68f7aa25d 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -44,7 +44,10 @@ void CInputManager::beginWorkspaceSwipe() { void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) { if (!m_sActiveSwipe.pWorkspaceBegin) return; // no valid swipe + endWorkspaceSwipe(); +} +void CInputManager::endWorkspaceSwipe() { static auto PSWIPEPERC = CConfigValue("gestures:workspace_swipe_cancel_ratio"); static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); static auto PSWIPEFORC = CConfigValue("gestures:workspace_swipe_min_speed_to_force"); @@ -192,11 +195,18 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) { } void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); + const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); if (!m_sActiveSwipe.pWorkspaceBegin) return; + const double delta = m_sActiveSwipe.delta + (VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx)); + updateWorkspaceSwipe(delta); +} + +void CInputManager::updateWorkspaceSwipe(double delta) { static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); - static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); static auto PSWIPENEW = CConfigValue("gestures:workspace_swipe_create_new"); static auto PSWIPEDIRLOCK = CConfigValue("gestures:workspace_swipe_direction_lock"); static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue("gestures:workspace_swipe_direction_lock_threshold"); @@ -209,10 +219,10 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) { const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP; const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + const double d = m_sActiveSwipe.delta - delta; + m_sActiveSwipe.delta = delta; - m_sActiveSwipe.delta += VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx); - - m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1); + m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(d)) / (m_sActiveSwipe.speedPoints + 1); m_sActiveSwipe.speedPoints++; std::string wsname = ""; diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 3247a2295..92f8316d0 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -1,7 +1,15 @@ #include "InputManager.hpp" #include "../../Compositor.hpp" +#include "../../config/ConfigValue.hpp" void CInputManager::onTouchDown(wlr_touch_down_event* e) { + static auto PSWIPETOUCH = CConfigValue("gestures:workspace_swipe_touch"); + static auto PGAPSOUTDATA = CConfigValue("general:gaps_out"); + auto* const PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData(); + // TODO: WORKSPACERULE.gapsOut.value_or() + auto gapsOut = *PGAPSOUT; + static auto PBORDERSIZE = CConfigValue("general:border_size"); + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); EMIT_HOOK_EVENT_CANCELLABLE("touchDown", e); auto PMONITOR = g_pCompositor->getMonitorFromName(e->touch->output_name ? e->touch->output_name : ""); @@ -24,6 +32,30 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { return; } + // Don't propagate new touches when a workspace swipe is in progress. + if (m_sActiveSwipe.pWorkspaceBegin) { + return; + // TODO: Don't swipe if you touched a floating window. + } else if (*PSWIPETOUCH && (!m_pFoundLSToFocus || m_pFoundLSToFocus->layer <= ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const bool VERTANIMS = PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || + PWORKSPACE->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + // TODO: support no_gaps_when_only? + const double TARGETLEFT = ((VERTANIMS ? gapsOut.top : gapsOut.left) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x); + const double TARGETRIGHT = 1 - (((VERTANIMS ? gapsOut.bottom : gapsOut.right) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->vecSize.y : PMONITOR->vecSize.x)); + const double POSITION = (VERTANIMS ? e->y : e->x); + if (POSITION < TARGETLEFT || POSITION > TARGETRIGHT) { + beginWorkspaceSwipe(); + m_sActiveSwipe.touch_id = e->touch_id; + // Set the initial direction based on which edge you started from + if (POSITION > 0.5) + m_sActiveSwipe.initialDirection = *PSWIPEINVR ? -1 : 1; + else + m_sActiveSwipe.initialDirection = *PSWIPEINVR ? 1 : -1; + return; + } + } + m_bLastInputTouch = true; m_sTouchData.touchFocusWindow = m_pFoundWindowToFocus; @@ -55,6 +87,13 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) { void CInputManager::onTouchUp(wlr_touch_up_event* e) { EMIT_HOOK_EVENT_CANCELLABLE("touchUp", e); + if (m_sActiveSwipe.pWorkspaceBegin) { + // If there was a swipe from this finger, end it. + if (e->touch_id == m_sActiveSwipe.touch_id) + endWorkspaceSwipe(); + return; + } + if (m_sTouchData.touchFocusSurface) { wlr_seat_touch_notify_up(g_pCompositor->m_sSeat.seat, e->time_msec, e->touch_id); } @@ -62,6 +101,30 @@ void CInputManager::onTouchUp(wlr_touch_up_event* e) { void CInputManager::onTouchMove(wlr_touch_motion_event* e) { EMIT_HOOK_EVENT_CANCELLABLE("touchMove", e); + if (m_sActiveSwipe.pWorkspaceBegin) { + // Do nothing if this is using a different finger. + if (e->touch_id != m_sActiveSwipe.touch_id) + return; + const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || + m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); + static auto PSWIPEINVR = CConfigValue("gestures:workspace_swipe_invert"); + static auto PSWIPEDIST = CConfigValue("gestures:workspace_swipe_distance"); + // Handle the workspace swipe if there is one + if (m_sActiveSwipe.initialDirection == -1) { + if (*PSWIPEINVR) + // go from 0 to -PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * ((VERTANIMS ? e->y : e->x) - 1)); + else + // go from 0 to -PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * (-1 * (VERTANIMS ? e->y : e->x))); + } else if (*PSWIPEINVR) + // go from 0 to PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * (VERTANIMS ? e->y : e->x)); + else + // go from 0 to PSWIPEDIST + updateWorkspaceSwipe(*PSWIPEDIST * (1 - (VERTANIMS ? e->y : e->x))); + return; + } if (m_sTouchData.touchFocusWindow && g_pCompositor->windowValidMapped(m_sTouchData.touchFocusWindow)) { const auto PMONITOR = g_pCompositor->getMonitorFromID(m_sTouchData.touchFocusWindow->m_iMonitorID);