diff --git a/kwin/mobiletaskswitcher/qml/TaskSwitcher.qml b/kwin/mobiletaskswitcher/qml/TaskSwitcher.qml index a9018c03..c44d5d9a 100644 --- a/kwin/mobiletaskswitcher/qml/TaskSwitcher.qml +++ b/kwin/mobiletaskswitcher/qml/TaskSwitcher.qml @@ -39,6 +39,10 @@ FocusScope { stateClass: TaskSwitcherData.TaskSwitcherState } + MobileShell.HapticsEffect { + id: haptics + } + property var tasksModel: TaskSwitcherData.TaskFilterModel { screenName: root.targetScreen.name windowModel: TaskSwitcherData.TaskModel @@ -102,6 +106,12 @@ FocusScope { taskSwitcherHelpers.isInTaskScrubMode = true; taskSwitcherHelpers.cancelAnimations(); taskSwitcherHelpers.open(); + if (!taskSwitcherHelpers.hasVibrated) { + // Haptic feedback when the task scrub mode engages + haptics.buttonVibrate(); + taskSwitcherHelpers.hasVibrated = true; + } + } let newTaskIndex = Math.max(0, Math.min(tasksCount - 1, Math.floor(state.touchXPosition / taskSwitcherHelpers.taskScrubDistance) + state.initialTaskIndex)); if (newTaskIndex != state.currentTaskIndex) { @@ -217,12 +227,33 @@ FocusScope { taskSwitcherHelpers.open(); } else { // no flick and not enough activation to go to task switcher - returnToApp(); + if (state.wasInActiveTask) { + returnToApp(); + } else { + // do open switcher in case we were on homescreen before + taskSwitcherHelpers.animateGoToTaskIndex(state.currentTaskIndex); + taskSwitcherHelpers.open(); + } + } } } } + function onVelocityChanged() { + if (!taskSwitcherHelpers.hasVibrated) { + if (!state.wasInActiveTask || + (state.wasInActiveTask && + state.yPosition > taskSwitcherHelpers.undoYThreshold && + state.totalSquaredVelocity < state.flickVelocityThreshold)) { + // Haptic feedback when conditions are met for the task switcher to open + haptics.buttonVibrate(); + taskSwitcherHelpers.hasVibrated = true; + } + + } + } + function onXPositionChanged() { taskSwitcherHelpers.updateTaskIndex(); } diff --git a/kwin/mobiletaskswitcher/qml/TaskSwitcherHelpers.qml b/kwin/mobiletaskswitcher/qml/TaskSwitcherHelpers.qml index 91b44328..3bf1c6d2 100644 --- a/kwin/mobiletaskswitcher/qml/TaskSwitcherHelpers.qml +++ b/kwin/mobiletaskswitcher/qml/TaskSwitcherHelpers.qml @@ -33,6 +33,10 @@ QtObject { // yPosition threshold below which opening the task switcher should be undone and returned to the previously active task readonly property real undoYThreshold: openedYPosition / 2 + // whether the switcher has already triggered haptic feedback or not + // we don't want to continuously send haptics, just once is enough + property bool hasVibrated: false + // ~~ measurement constants ~~ // dimensions of a real window on the screen