compose-floating-window icon indicating copy to clipboard operation
compose-floating-window copied to clipboard

unable to input

Open FunnySaltyFish opened this issue 8 months ago • 2 comments

浮窗内无法使用 TextField,点击无法唤起输入法

Unable to use TextField inside the float window, cause it's is not possible to launch soft input method.

FunnySaltyFish avatar Apr 06 '25 07:04 FunnySaltyFish

https://github.com/only52607/compose-floating-window/blob/148f5e9bd7cb0caa18f539a29ff7bf0fcf78831e/library/src/main/java/com/github/only52607/compose/window/ComposeFloatingWindow.kt#L52-L66

             flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
+                    ) 

You could probably try supplying your own windowParams with removing that flag. I don't have usecase for it so I haven't tried and don't know if it will work

ArthurKun21 avatar Apr 12 '25 12:04 ArthurKun21

The problem was solved through efforts. Now the text field can be focused when tapping and unfocused when IME is closing. I'll post my solution below as a reference, if someone needs it.

val interactionSource = remember { MutableInteractionSource() }
var focusIndication: FocusInteraction.Focus? by rememberStateOf(null)
val isFocused by rememberDerivedStateOf { focusIndication != null }
val focusManager = LocalFocusManager.current

LaunchedEffect(interactionSource){
    interactionSource.interactions.collect {
        when (it) {
            is FocusInteraction.Focus -> {
                focusIndication = it
                Log.d(TAG, "FocusInteraction.Focus")
            }
        }
    }
}
val scope = rememberCoroutineScope()

DisposableEffect (window.decorView) {
    ViewCompat.setOnApplyWindowInsetsListener(decorView) { v, insets ->
        val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
//                            Log.d("ComposeFloatingWindow", "Insets received by decorView: ime=$imeVisible, bottom=${insets.getInsets(
//                                WindowInsetsCompat.Type.ime()).bottom}")
        if (!imeVisible && isFocused && window.windowParams.flags and FLAG_NOT_FOCUSABLE == 0) {
            Log.d(TAG, "IME closed, restoring FLAG_NOT_FOCUSABLE")
            window.windowParams.flags =
                FLAG_NOT_TOUCH_MODAL or FLAG_NOT_FOCUSABLE or FLAG_LAYOUT_NO_LIMITS
            window.update()
            focusIndication?.let {
                Log.d(TAG, "Unfocusing window: $it")
                scope.launch {
                    focusManager.clearFocus()
                    focusIndication = null
                }
            }
        }
        insets
    }

    onDispose {
        // 清理工作
        ViewCompat.setOnApplyWindowInsetsListener(decorView, null)
    }
}

and as for text field:

// Input text field
OutlinedTextField(
    value = value,
    onValueChange = onValueChange,
    modifier = Modifier
        .onFocusChanged {
            Log.d("FloatingWindowInputField", "onFocusChanged: ${it.isFocused}")
            if (it.isFocused) {
                onTapInput()
            }
        },
    interactionSource = interactionSource
)

FunnySaltyFish avatar Apr 12 '25 15:04 FunnySaltyFish