From 3c21f5e07b853b1b37a7aa38a5084a114f0c1983 Mon Sep 17 00:00:00 2001 From: Zach DeCook Date: Sun, 17 Mar 2024 11:43:59 -0400 Subject: swipe: Touchscreen workspace swipe (#4489) * Workspace Swipe: Refactor update and end functions * Touch: Implement workspace swipe better ignoring additional fingers and new touches allow gaps-right and gaps-left to be different --- src/managers/input/Touch.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'src/managers/input/Touch.cpp') diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index 3247a229..92f8316d 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); -- cgit v1.2.3