From 77322c631a43e6b03719371ef566b472f51dfade Mon Sep 17 00:00:00 2001 From: screentinker Date: Wed, 15 Jul 2026 10:00:26 -0500 Subject: [PATCH] fix(android): show soft keyboard for PIN/URL dialogs over immersive fullscreen (#191) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../com/remotedisplay/player/MainActivity.kt | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/java/com/remotedisplay/player/MainActivity.kt b/android/app/src/main/java/com/remotedisplay/player/MainActivity.kt index d439e86..2490451 100644 --- a/android/app/src/main/java/com/remotedisplay/player/MainActivity.kt +++ b/android/app/src/main/java/com/remotedisplay/player/MainActivity.kt @@ -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() {