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

Commit d5f04ff3 authored by mattsziklay's avatar mattsziklay
Browse files

Forward click and hover inputs to caption handle.

Simplifies input handling for statusBarInputLayer by having click/hover
listener call the equivalent event on captionHandle view directly. This
fixes an issue with hover events not being passed correctly.

This CL also fixes press events by adding that handling to
statusBarInputLayer's onTouchListener.

Bug: 341997116
Test: manual
Flag: com.android.window.flags.enable_additional_windows_above_status_bar
Change-Id: I83fd7d2c607781b69c7742cfd9aae6d1f58c4fe7
parent ea743d22
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -669,12 +669,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                View v, MotionEvent e) {
            final int id = v.getId();
            if (id == R.id.caption_handle) {
                if (e.getActionMasked() == MotionEvent.ACTION_DOWN) {
                    // Caption handle is located within the status bar region, meaning the
                    // DisplayPolicy will attempt to transfer this input to status bar if it's
                    // a swipe down. Pilfer here to keep the gesture in handle alone.
                    mInputManager.pilferPointers(v.getViewRootImpl().getInputToken());
                }
                handleCaptionThroughStatusBar(e, decoration);
                final boolean wasDragging = mIsDragging;
                updateDragStatus(e.getActionMasked());
+4 −6
Original line number Diff line number Diff line
@@ -520,11 +520,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            return new AppHandleViewHolder(
                    mResult.mRootView,
                    mOnCaptionTouchListener,
                    mOnCaptionButtonClickListener,
                    (v, event) -> {
                        updateHoverAndPressStatus(event);
                        return true;
                    }
                    mOnCaptionButtonClickListener
            );
        } else if (mRelayoutParams.mLayoutResId
                == R.layout.desktop_mode_app_header) {
@@ -589,9 +585,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            controlsElement.mWidthResId = R.dimen.desktop_mode_customizable_caption_margin_end;
            controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
            relayoutParams.mOccludingCaptionElements.add(controlsElement);
        } else if (isAppHandle) {
        } else if (isAppHandle && !Flags.enableAdditionalWindowsAboveStatusBar()) {
            // The focused decor (fullscreen/split) does not need to handle input because input in
            // the App Handle is handled by the InputMonitor in DesktopModeWindowDecorViewModel.
            // Note: This does not apply with the above flag enabled as the status bar input layer
            // will forward events to the handle directly.
            relayoutParams.mInputFeatures
                    |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
        }
+18 −9
Original line number Diff line number Diff line
@@ -21,10 +21,11 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Point
import android.hardware.input.InputManager
import android.view.MotionEvent.ACTION_DOWN
import android.view.SurfaceControl
import android.view.View
import android.view.View.OnClickListener
import android.view.View.OnHoverListener
import android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
import android.view.WindowManager
import android.widget.ImageButton
@@ -39,9 +40,8 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystem
 */
internal class AppHandleViewHolder(
    rootView: View,
    private val onCaptionTouchListener: View.OnTouchListener,
    private val onCaptionButtonClickListener: OnClickListener,
    private val onCaptionHoverListener: OnHoverListener,
    onCaptionTouchListener: View.OnTouchListener,
    onCaptionButtonClickListener: OnClickListener
) : WindowDecorationViewHolder(rootView) {

    companion object {
@@ -51,6 +51,7 @@ internal class AppHandleViewHolder(
    private val windowManager = context.getSystemService(WindowManager::class.java)
    private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption)
    private val captionHandle: ImageButton = rootView.requireViewById(R.id.caption_handle)
    private val inputManager = context.getSystemService(InputManager::class.java)

    // An invisible View that takes up the same coordinates as captionHandle but is layered
    // above the status bar. The purpose of this View is to receive input intended for
@@ -61,7 +62,6 @@ internal class AppHandleViewHolder(
        captionView.setOnTouchListener(onCaptionTouchListener)
        captionHandle.setOnTouchListener(onCaptionTouchListener)
        captionHandle.setOnClickListener(onCaptionButtonClickListener)
        captionHandle.setOnHoverListener(onCaptionHoverListener)
    }

    override fun bindData(
@@ -106,10 +106,19 @@ internal class AppHandleViewHolder(
        // gesture listener that receives events before window. This is to prevent notification
        // shade gesture when we swipe down to enter desktop.
        lp.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
        view.id = R.id.caption_handle
        view.setOnClickListener(onCaptionButtonClickListener)
        view.setOnTouchListener(onCaptionTouchListener)
        view.setOnHoverListener(onCaptionHoverListener)
        view.setOnHoverListener { _, event ->
            captionHandle.onHoverEvent(event)
        }
        // Caption handle is located within the status bar region, meaning the
        // DisplayPolicy will attempt to transfer this input to status bar if it's
        // a swipe down. Pilfer here to keep the gesture in handle alone.
        view.setOnTouchListener { v, event ->
            if (event.actionMasked == ACTION_DOWN) {
                inputManager.pilferPointers(v.viewRootImpl.inputToken)
            }
            captionHandle.dispatchTouchEvent(event)
            true
        }
        windowManager.updateViewLayout(view, lp)
    }