Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73bd4d6d authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge "Desks: Add keyboard shortcuts to switch active desks" into main

parents 0dd597d0 cd20d623
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -129,6 +129,8 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 74;
    public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 75;
    public static final int KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS = 76;
    public static final int KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK = 77;
    public static final int KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK = 78;

    public static final int FLAG_CANCELLED = 1;

@@ -219,6 +221,8 @@ public final class KeyGestureEvent {
            KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
            KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB,
            KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS,
            KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK,
            KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface KeyGestureType {
@@ -807,6 +811,10 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB";
            case KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
                return "KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS";
            case KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK:
                return "KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK";
            case KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK:
                return "KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK";
            default:
                return Integer.toHexString(value);
        }
+18 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ class DesktopModeKeyGestureHandler(
                    KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW,
                    KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW,
                    KeyGestureEvent.KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK,
                    KeyGestureEvent.KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK,
                )
            inputManager.registerKeyGestureEventHandler(supportedGestures, this)
        }
@@ -71,6 +73,22 @@ class DesktopModeKeyGestureHandler(
                    }
                }
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK -> {
                logV("Key gesture SWITCH_TO_PREVIOUS_DESK is handled")
                mainExecutor.execute {
                    desktopTasksController
                        .get()
                        .activatePreviousDesk(focusTransitionObserver.globallyFocusedDisplayId)
                }
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK -> {
                logV("Key gesture SWITCH_TO_NEXT_DESK is handled")
                mainExecutor.execute {
                    desktopTasksController
                        .get()
                        .activateNextDesk(focusTransitionObserver.globallyFocusedDisplayId)
                }
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW -> {
                logV("Key gesture SNAP_LEFT_FREEFORM_WINDOW is handled")
                getGloballyFocusedFreeformTask()?.let {
+33 −6
Original line number Diff line number Diff line
@@ -47,12 +47,11 @@ class DesktopRepository(
    val userId: Int,
) {
    /** A display that supports desktops. */
    private data class DesktopDisplay(
        val displayId: Int,
        val orderedDesks: MutableSet<Desk> = mutableSetOf(),
        // TODO: b/389960283 - update on desk activation / deactivation.
        var activeDeskId: Int? = null,
    )
    private class DesktopDisplay(val displayId: Int) {
        // The set implementation must preserve order.
        val orderedDesks: MutableSet<Desk> = mutableSetOf()
        var activeDeskId: Int? = null
    }

    /**
     * Task data tracked per desk.
@@ -236,6 +235,25 @@ class DesktopRepository(
    /** Returns the default desk in the given display. */
    private fun getDefaultDesk(displayId: Int): Desk? = desktopData.getDefaultDesk(displayId)

    /** Returns the id of the desk ordered previous to the given one, or null if there isn't one. */
    fun getPreviousDeskId(deskId: Int): Int? {
        val desks = desktopData.getOrderedDesks(getDisplayForDesk(deskId))
        val index = desks.indexOfFirst { it.deskId == deskId }
        if (index <= 0) return null
        return desks[index - 1].deskId
    }

    /** Returns the id of the desk ordered next to the given one, or null if there isn't one. */
    fun getNextDeskId(deskId: Int): Int? {
        val desks = desktopData.getOrderedDesks(getDisplayForDesk(deskId))
        val index = desks.indexOfFirst { it.deskId == deskId }
        return if (index >= 0 && index < desks.size - 1) {
            desks[index + 1].deskId
        } else {
            null
        }
    }

    /** Returns whether the given desk is active in its display. */
    fun isDeskActive(deskId: Int): Boolean =
        desktopData.getAllActiveDesks().any { desk -> desk.deskId == deskId }
@@ -1181,6 +1199,9 @@ class DesktopRepository(
        /** Returns the number of desks in the given display. */
        fun getNumberOfDesks(displayId: Int): Int

        /** Returns a list of ordered desks in a given display. */
        fun getOrderedDesks(displayId: Int): List<Desk>

        /** Applies a function to all desks. */
        fun forAllDesks(consumer: (Desk) -> Unit)

@@ -1256,6 +1277,9 @@ class DesktopRepository(

        override fun getNumberOfDesks(displayId: Int): Int = 1

        override fun getOrderedDesks(displayId: Int): List<Desk> =
            listOf(getDesk(deskId = displayId))

        override fun forAllDesks(consumer: (Desk) -> Unit) {
            deskByDisplayId.forEach { _, desk -> consumer(desk) }
        }
@@ -1332,6 +1356,9 @@ class DesktopRepository(
                ?: display.orderedDesks.firstOrNull()
        }

        override fun getOrderedDesks(displayId: Int): List<Desk> =
            desktopDisplays[displayId].orderedDesks.toList()

        override fun getAllActiveDesks(): Set<Desk> {
            return desktopDisplays
                .valueIterator()
+76 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.os.UserManager
import android.util.Slog
import android.view.Display
import android.view.Display.DEFAULT_DISPLAY
import android.view.Display.INVALID_DISPLAY
import android.view.DragEvent
import android.view.MotionEvent
import android.view.SurfaceControl
@@ -2992,8 +2993,83 @@ class DesktopTasksController(
        }
    }

    /** Activates the desk at the given index if it exists. */
    fun activatePreviousDesk(displayId: Int) {
        if (
            !DesktopExperienceFlags.ENABLE_KEYBOARD_SHORTCUTS_TO_SWITCH_DESKS.isTrue ||
                !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
        ) {
            return
        }
        val validDisplay =
            when {
                displayId != INVALID_DISPLAY -> displayId
                focusTransitionObserver.globallyFocusedDisplayId != INVALID_DISPLAY ->
                    focusTransitionObserver.globallyFocusedDisplayId
                else -> {
                    logW("activatePreviousDesk no valid display found")
                    return
                }
            }
        val activeDeskId = taskRepository.getActiveDeskId(validDisplay)
        if (activeDeskId == null) {
            logV("activatePreviousDesk no active desk in display=%d", validDisplay)
            return
        }
        val destinationDeskId = taskRepository.getPreviousDeskId(activeDeskId)
        if (destinationDeskId == null) {
            logV(
                "activatePreviousDesk no previous desk before deskId=%d in display=%d",
                activeDeskId,
                validDisplay,
            )
            // TODO: b/389957556 - add animation.
            return
        }
        logV("activatePreviousDesk from deskId=%d to deskId=%d", activeDeskId, destinationDeskId)
        activateDesk(destinationDeskId)
    }

    /** Activates the desk at the given index if it exists. */
    fun activateNextDesk(displayId: Int) {
        if (
            !DesktopExperienceFlags.ENABLE_KEYBOARD_SHORTCUTS_TO_SWITCH_DESKS.isTrue ||
                !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
        ) {
            return
        }
        val validDisplay =
            when {
                displayId != INVALID_DISPLAY -> displayId
                focusTransitionObserver.globallyFocusedDisplayId != INVALID_DISPLAY ->
                    focusTransitionObserver.globallyFocusedDisplayId
                else -> {
                    logW("activateNextDesk no valid display found")
                    return
                }
            }
        val activeDeskId = taskRepository.getActiveDeskId(validDisplay)
        if (activeDeskId == null) {
            logV("activateNextDesk no active desk in display=%d", validDisplay)
            return
        }
        val destinationDeskId = taskRepository.getNextDeskId(activeDeskId)
        if (destinationDeskId == null) {
            logV(
                "activateNextDesk no next desk before deskId=%d in display=%d",
                activeDeskId,
                validDisplay,
            )
            // TODO: b/389957556 - add animation.
            return
        }
        logV("activateNextDesk from deskId=%d to deskId=%d", activeDeskId, destinationDeskId)
        activateDesk(destinationDeskId)
    }

    /** Activates the given desk. */
    fun activateDesk(deskId: Int, remoteTransition: RemoteTransition? = null) {
        logV("activateDesk deskId=%d", deskId)
        val wct = WindowContainerTransaction()
        val runOnTransitStart = addDeskActivationChanges(deskId, wct)

+8 −0
Original line number Diff line number Diff line
@@ -218,6 +218,14 @@ public class FocusTransitionObserver {
        return focusedTaskOnDisplay != null && focusedTaskOnDisplay.taskId == task.taskId;
    }

    /** Returns the globally focused display id. */
    public int getGloballyFocusedDisplayId() {
        if (!enableDisplayFocusInShellTransitions() || mFocusedDisplayId == INVALID_DISPLAY) {
            return INVALID_DISPLAY;
        }
        return mFocusedDisplayId;
    }

    /**
     * Gets the globally focused task ID.
     */
Loading