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

Commit e8cc7be8 authored by Daniel Akinola's avatar Daniel Akinola
Browse files

Ensure talkback focus stays on maximize button after click

Fixing issue with clicking maximize button using Talkback. Often the talkback focus would go to the app chip instead of the maximize button. This seemed to be because of a race condition where the maximize button would be hidden, and talkback would foucs on the first focusable node of the app header instead. Now implementing a change utilizing the resize veil, to keep the focus and then manually giving it back to the maximize button after resizing.

Bug: 398975290
Flag: NONE bugfix
Test: manual (with talkback on)
Change-Id: I4a0b048c89be879f2c596ccfefef79522d3639eb
parent 869a9ac9
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@
  -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
              android:layout_height="match_parent">
    android:layout_height="match_parent"
    android:focusable="true">

    <ImageView
        android:id="@+id/veil_application_icon"
+8 −0
Original line number Diff line number Diff line
@@ -868,6 +868,14 @@ class DefaultWindowDecoration @JvmOverloads constructor(
        (captionController as? AppHeaderController)?.a11yAnnounceFocused()
    }

    /**
     * Request direct a11y focus on the maximize button. This is used after a maximize/restore to
     * ensure that focus always goes back to the button.
     */
    fun a11yFocusMaximizeButton() {
        (captionController as? AppHeaderController)?.a11yFocusMaximizeButton()
    }

    /** Closes the window decoration. */
    override fun close() {
        taskResourceLoader.onWindowDecorClosed(taskInfo)
+1 −0
Original line number Diff line number Diff line
@@ -2197,6 +2197,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            if (decoration == null) return;
            decoration.hideResizeVeil();
            decoration.setAnimatingTaskResizeOrReposition(false);
            decoration.requestFocusMaximizeButton();
        }
    }

+11 −4
Original line number Diff line number Diff line
@@ -1498,13 +1498,20 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mMaximizeMenu.close(() -> {
            // Request the accessibility service to refocus on the maximize button after closing
            // the menu.
            a11yFocusMaximizeButton();
            return Unit.INSTANCE;
        });
        mMaximizeMenu = null;
    }

    /**
     * Request direct a11y focus on the maximize button
     */
    void a11yFocusMaximizeButton() {
        final AppHeaderViewHolder appHeader = asAppHeader(mWindowDecorViewHolder);
        if (appHeader != null) {
            appHeader.requestAccessibilityFocus();
        }
            return Unit.INSTANCE;
        });
        mMaximizeMenu = null;
    }

    @Override
+9 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.view.Display
import android.view.LayoutInflater
import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
import android.view.View
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL
import android.view.WindowlessWindowManager
@@ -77,6 +78,7 @@ public class ResizeVeil @JvmOverloads constructor(

    @VisibleForTesting
    lateinit var iconView: ImageView
    lateinit var rootView: View
    private var iconSize = 0

    /** A container surface to host the veil background and icon child surfaces.  */
@@ -152,9 +154,9 @@ public class ResizeVeil @JvmOverloads constructor(
                .build()
        iconSize = context.resources
                .getDimensionPixelSize(R.dimen.desktop_mode_resize_veil_icon_size)
        val root = LayoutInflater.from(context)
        rootView = LayoutInflater.from(context)
                .inflate(R.layout.desktop_mode_resize_veil, null /* root */)
        iconView = root.requireViewById(R.id.veil_application_icon)
        iconView = rootView.requireViewById(R.id.veil_application_icon)
        val lp = WindowManager.LayoutParams(
                iconSize,
                iconSize,
@@ -167,7 +169,7 @@ public class ResizeVeil @JvmOverloads constructor(
        val wwm = WindowlessWindowManager(taskInfo.configuration,
                iconSurface, null /* hostInputToken */)
        viewHost = surfaceControlViewHostFactory.create(context, display, wwm, "ResizeVeil")
        viewHost?.setView(root, lp)
        viewHost?.setView(rootView, lp)
        loadAppInfoJob = mainScope.launch {
            if (!isActive) return@launch
            val icon = taskResourceLoader.getVeilIcon(taskInfo)
@@ -215,6 +217,10 @@ public class ResizeVeil @JvmOverloads constructor(
            taskInfo,
            fadeIn,
        )

        // Give a11y focus to the veil to "park" it, to keep it from being lost during resize
        rootView.post { rootView.requestAccessibilityFocus() }

        if (fadeIn) {
            cancelAnimation()
            val veilAnimT = surfaceControlTransactionSupplier.get()
Loading