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

Commit 5b0b0e2f authored by Wes Okuhara's avatar Wes Okuhara Committed by Android (Google) Code Review
Browse files

Merge "Screen capture: Esc keypress closes the window" into main

parents 3f2c33f1 111afe00
Loading
Loading
Loading
Loading
+28 −33
Original line number Diff line number Diff line
@@ -19,9 +19,6 @@ package com.android.systemui.screencapture.ui
import android.annotation.SuppressLint
import android.content.Context
import android.view.Display
import android.view.KeyEvent
import android.view.View
import android.view.View.OnKeyListener
import android.view.Window
import android.view.WindowManager
import android.window.OnBackInvokedCallback
@@ -32,6 +29,7 @@ import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.safeDrawing
@@ -45,6 +43,16 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.isAltPressed
import androidx.compose.ui.input.key.isCtrlPressed
import androidx.compose.ui.input.key.isMetaPressed
import androidx.compose.ui.input.key.isShiftPressed
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.platform.ComposeView
import com.android.compose.theme.PlatformTheme
import com.android.systemui.compose.ComposeInitializer
@@ -126,13 +134,11 @@ constructor(
                    // Wait until parameters are passed down to Compose
                    val parameters = parametersState ?: return@setContent

                    LaunchedEffect(viewModel) {
                        window.decorView.observeKeyUpEvents { keyCode: Int, event: KeyEvent ->
                            onKeyUp(viewModel = viewModel, keyCode = keyCode, event = event)
                        }
                    }
                    LaunchedEffect(viewModel) { window.observeBack { viewModel.dismiss() } }

                    // Focus the view on initial render so it can receive key events.
                    LaunchedEffect(Unit) { window.decorView.requestFocus() }

                    PlatformTheme {
                        val visibleState = remember { MutableTransitionState(false) }
                        visibleState.targetState = viewModel.state is ScreenCaptureUiState.Visible
@@ -160,7 +166,13 @@ constructor(
                                        .setWindow(window)
                                        .build()
                                }
                            Box(modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing)) {

                            Box(
                                modifier =
                                    Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
                                        .focusable()
                                        .onKeyEvent { event -> handleKeyEvent(event, viewModel) }
                            ) {
                                component.screenCaptureContent.Content()
                            }
                        }
@@ -176,18 +188,19 @@ constructor(
        composeRoot = null
    }

    private fun onKeyUp(
        viewModel: ScreenCaptureUiViewModel,
        keyCode: Int,
        event: KeyEvent,
    ): Boolean {
    private fun handleKeyEvent(event: KeyEvent, viewModel: ScreenCaptureUiViewModel): Boolean {
        if (event.type != KeyEventType.KeyUp) {
            return false
        }

        val noModifierKeys =
            !event.isShiftPressed &&
                !event.isCtrlPressed &&
                !event.isAltPressed &&
                !event.isMetaPressed

        return when {
            (keyCode == KeyEvent.KEYCODE_ESCAPE && noModifierKeys) -> {
            (event.key == Key.Escape && noModifierKeys) -> {
                viewModel.dismiss()
                true
            }
@@ -213,21 +226,3 @@ private suspend fun Window.observeBack(onBack: OnBackInvokedCallback) {
        onBackInvokedDispatcher.unregisterOnBackInvokedCallback(onBack)
    }
}

private suspend fun View.observeKeyUpEvents(onKeyUp: (keyCode: Int, event: KeyEvent) -> Boolean) {
    val listener =
        object : OnKeyListener {
            override fun onKey(v: View?, keyCode: Int, event: KeyEvent?): Boolean {
                if (event?.action == KeyEvent.ACTION_UP) {
                    return onKeyUp(keyCode, event)
                }
                return false
            }
        }
    setOnKeyListener(listener)
    try {
        awaitCancellation()
    } finally {
        setOnKeyListener(null)
    }
}