diff --git a/kwin/mobiletaskswitcher/package/contents/ui/TaskList.qml b/kwin/mobiletaskswitcher/package/contents/ui/TaskList.qml index e0fab74a..4954d085 100644 --- a/kwin/mobiletaskswitcher/package/contents/ui/TaskList.qml +++ b/kwin/mobiletaskswitcher/package/contents/ui/TaskList.qml @@ -26,6 +26,7 @@ MouseArea { property int taskInteractingCount: 0 // account for system header and footer offset (center the preview image) + // if there's too little space space for the task scrub icons, shift it slightly above center to make space readonly property real taskYBase: { let headerHeight = shellTopMargin; let footerHeight = shellBottomMargin; @@ -41,7 +42,12 @@ MouseArea { trackFingerYOffsetClamped = taskSwitcherHelpers.trackFingerYOffset; } - return taskYBase - trackFingerYOffsetClamped; + let scrubModeOffset = 0; + if (taskSwitcherHelpers.isInTaskScrubMode && !taskSwitcherHelpers.currentlyBeingClosed) { + scrubModeOffset = taskSwitcherHelpers.scrubModeOverrun; + } + + return Math.round(taskYBase - trackFingerYOffsetClamped - scrubModeOffset); } function getTaskAt(index: int): Task { diff --git a/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml b/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml index a66ff923..bef2388c 100644 --- a/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml +++ b/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcher.qml @@ -97,6 +97,7 @@ FocusScope { taskSwitcherHelpers.reachedHeightThreshold = false; taskSwitcherHelpers.gestureState = TaskSwitcherHelpers.GestureStates.Undecided; taskSwitcherHelpers.isInTaskScrubMode = false; + taskSwitcherHelpers.inLastFrame = false; taskSwitcherHelpers.hasVibrated = false; @@ -375,7 +376,6 @@ FocusScope { root.taskSwitcherHelpers.close(); } if (root.taskSwitcherHelpers.isInTaskScrubMode) { // TODO! do we want to handle upwards flick to dismiss in task scrub mode? - // TODO do we want to show a list of thumbnails in task scrub mode? let unmodifiedYposition = Math.abs(root.state.touchYPosition) root.backgroundColorOpacity = 1; if (root.taskSwitcherHelpers.taskDrawerOpened || unmodifiedYposition > root.taskSwitcherHelpers.undoYThreshold) { @@ -641,7 +641,7 @@ FocusScope { anchors.bottom: container.bottom anchors.right: container.horizontalCenter - anchors.bottomMargin: root.taskSwitcherHelpers.openedYPosition * 5 / 8 + anchors.bottomMargin: root.taskSwitcherHelpers.scrubModeBottomMargin anchors.rightMargin: { let size = Kirigami.Units.iconSizes.large + Kirigami.Units.largeSpacing * 2; diff --git a/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcherHelpers.qml b/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcherHelpers.qml index 61d78d3b..665dac78 100644 --- a/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcherHelpers.qml +++ b/kwin/mobiletaskswitcher/package/contents/ui/TaskSwitcherHelpers.qml @@ -45,10 +45,22 @@ QtObject { readonly property bool gestureMovingUp: state.yVelocity < 0 readonly property bool currentlyBeingOpened: state.gestureInProgress || openAnim.running - readonly property bool currentlyBeingClosed: closeAnim.running || openAppAnim.running + readonly property bool currentlyBeingClosed: closeAnim.running || openAppAnim.running || inLastFrame + + // indicates whether taskswitcher is in last frame before dismissal. this happens after open app or close animation + // and is required because openApp/close animation isRunning is false in said last frame which can lead to visual + // glitches in said frame. + property bool inLastFrame: false // yPosition when the task switcher is completely open - readonly property real openedYPosition: (taskSwitcher.height - taskHeight) / 2 + readonly property real openedYPosition: Math.round((taskSwitcher.height - taskHeight) / 2) + readonly property real scrubModeOverrun: { + return Math.max(0, scrubModeBottomMargin + Kirigami.Units.iconSizes.huge + Kirigami.Units.smallSpacing - openedYPosition); + } + + readonly property real scrubModeBottomMargin: { + return Math.round(openedYPosition * 5 / 8); + } // yPosition threshold below which opening the task switcher should be undone and returned to the previously active task readonly property real undoYThreshold: openedYPosition / 2 @@ -329,6 +341,7 @@ QtObject { easing.type: Easing.InBack onFinished: { + root.inLastFrame = true; root.state.status = TaskSwitcherPlugin.MobileTaskSwitcherState.Inactive; root.taskSwitcher.instantHide(); } @@ -361,6 +374,7 @@ QtObject { duration: 300 easing.type: Easing.OutQuint onFinished: { + root.inLastFrame = true; root.state.status = TaskSwitcherPlugin.MobileTaskSwitcherState.Inactive; root.taskSwitcher.instantHide(); }