mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 22:03:13 -06:00
fix(android): show soft keyboard for PIN/URL dialogs over immersive fullscreen (#191)
The hidden-settings PIN box (2x back) and the change-server URL dialog couldn't be typed into on kiosk devices: a plain AlertDialog shown over the player's SYSTEM_UI_FLAG_IMMERSIVE_STICKY activity never gains window focus, so the soft keyboard doesn't attach and the EditText gets no cursor. On a panel/Fire TV with no hardware keyboard that means the PIN can't be entered at all. Pre-existing (showPinDialog unchanged since it was added; immersive flags since the initial release) — surfaces on tier-0 kiosk devices where immersive is active. Fix: shared showImeDialog() applies the standard immersive-dialog IME workaround — mark the dialog NOT_FOCUSABLE before show() (so it doesn't steal focus and reset the activity's immersive flags), mirror the immersive systemUiVisibility onto the dialog, then clear NOT_FOCUSABLE after show() so the IME can attach, force SOFT_INPUT_STATE_ALWAYS_VISIBLE, and requestFocus the field. Routed both the PIN and change-server dialogs through it. Compiles (:app:compileDebugKotlin). IME behavior needs a real tier-0 device to confirm (can't be exercised headless). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
fa31eb9cc3
commit
77322c631a
|
|
@ -999,6 +999,26 @@ class MainActivity : AppCompatActivity() {
|
|||
handler.postDelayed(backTapRunnable!!, TAP_WINDOW_MS)
|
||||
}
|
||||
|
||||
// Show a dialog containing a text field over the IMMERSIVE_STICKY fullscreen so the soft
|
||||
// keyboard actually attaches. A dialog shown over an immersive activity otherwise doesn't gain
|
||||
// window focus -> its EditText gets no cursor/IME, so on a kiosk with no hardware keyboard the
|
||||
// PIN/URL can't be typed. Fix: mark the dialog NOT_FOCUSABLE *before* show() so it doesn't steal
|
||||
// focus and reset the activity's immersive flags; mirror those flags onto the dialog; then clear
|
||||
// NOT_FOCUSABLE *after* show() so the IME can attach to the focused field.
|
||||
@Suppress("DEPRECATION")
|
||||
private fun showImeDialog(dialog: AlertDialog, focus: android.view.View?) {
|
||||
val w = dialog.window
|
||||
w?.setFlags(
|
||||
android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||
android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
)
|
||||
w?.decorView?.systemUiVisibility = window.decorView.systemUiVisibility
|
||||
dialog.show()
|
||||
w?.clearFlags(android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
|
||||
w?.setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
||||
focus?.requestFocus()
|
||||
}
|
||||
|
||||
private fun showPinDialog() {
|
||||
val input = EditText(this).apply {
|
||||
inputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD
|
||||
|
|
@ -1011,7 +1031,7 @@ class MainActivity : AppCompatActivity() {
|
|||
addView(input)
|
||||
}
|
||||
|
||||
AlertDialog.Builder(this)
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.settings_pin_title))
|
||||
.setView(container)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
|
|
@ -1022,7 +1042,8 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
.create()
|
||||
showImeDialog(dialog, input)
|
||||
}
|
||||
|
||||
private fun showSettingsDialog() {
|
||||
|
|
@ -1115,7 +1136,7 @@ class MainActivity : AppCompatActivity() {
|
|||
addView(input)
|
||||
}
|
||||
|
||||
AlertDialog.Builder(this)
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.settings_change_server))
|
||||
.setView(container)
|
||||
.setPositiveButton(getString(R.string.settings_save)) { _, _ ->
|
||||
|
|
@ -1126,7 +1147,8 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
.create()
|
||||
showImeDialog(dialog, input)
|
||||
}
|
||||
|
||||
private fun showPermissionsDialog() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue