Fix text input on kiosk: add keycodeToChar fallback for email/license pages

The kiosk lacks an input method framework, so SDL2 never generates
TextInputEvent. The WiFi password page already had a keycodeToChar
fallback but email and license key pages did not — characters were
never appended to inputText. Also removes excessive debug logging
from the previous commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
NeilClack
2026-03-13 19:27:28 -05:00
co-authored by Claude Opus 4.6
parent 8b0cf81e85
commit df5e64d38a
4 changed files with 52 additions and 87 deletions
+24 -25
View File
@@ -11,7 +11,6 @@ import (
"rhemawavetech.com/rhemawave/internal/colors"
"rhemawavetech.com/rhemawave/internal/db"
"rhemawavetech.com/rhemawave/internal/fontManager"
"rhemawavetech.com/rhemawave/internal/logger"
"rhemawavetech.com/rhemawave/internal/shaderManager"
)
@@ -43,6 +42,9 @@ type EmailAddressPage struct {
// isFirstTimeSetup tracks whether page was loaded empty (first-time setup)
isFirstTimeSetup bool
// Text input deduplication
textInputSupported bool
}
// isValidEmail checks if the given string is a valid email format
@@ -112,9 +114,7 @@ func (p *EmailAddressPage) Init(app ApplicationInterface) error {
p.isFirstTimeSetup = true
}
logger.Info("[EmailAddressPage.Init] Calling sdl.StartTextInput(), isFirstTimeSetup=%v", p.isFirstTimeSetup)
sdl.StartTextInput()
logger.Info("[EmailAddressPage.Init] After StartTextInput: IsTextInputActive=%v", sdl.IsTextInputActive())
return nil
}
@@ -122,34 +122,26 @@ func (p *EmailAddressPage) Init(app ApplicationInterface) error {
// HandleEvent processes SDL events and handles them appropriately for the EmailAddressPage.
func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error {
actualEvent := *event
logger.Info("[EmailAddressPage.HandleEvent] Event type: %T", actualEvent)
isActive := sdl.IsTextInputActive()
if !isActive {
logger.Info("[EmailAddressPage.HandleEvent] TextInput not active, calling StartTextInput()")
if !sdl.IsTextInputActive() {
sdl.StartTextInput()
logger.Info("[EmailAddressPage.HandleEvent] After StartTextInput: IsTextInputActive=%v", sdl.IsTextInputActive())
}
switch e := actualEvent.(type) {
case *sdl.TextInputEvent:
text := e.GetText()
p.inputText += text
logger.Info("[EmailAddressPage.HandleEvent] TextInputEvent: received=%q, inputText=%q", text, p.inputText)
// Clear error when user starts typing
p.errorMessage = ""
case *sdl.KeyboardEvent:
eventType := "KEYDOWN"
if e.Type == sdl.KEYUP {
eventType = "KEYUP"
if !p.textInputSupported {
// First TextInputEvent: the keyboard fallback already
// handled this character, so just record that text input
// is supported and skip the duplicate append.
p.textInputSupported = true
} else {
p.inputText += e.GetText()
// Clear error when user starts typing
p.errorMessage = ""
}
logger.Info("[EmailAddressPage.HandleEvent] KeyboardEvent: type=%s, sym=%d (%s), scancode=%d, mod=0x%04x",
eventType, e.Keysym.Sym, sdl.GetKeyName(e.Keysym.Sym), e.Keysym.Scancode, e.Keysym.Mod)
case *sdl.KeyboardEvent:
if e.Type == sdl.KEYDOWN {
switch e.Keysym.Sym {
case sdl.K_ESCAPE:
logger.Info("[EmailAddressPage.HandleEvent] ESCAPE pressed, isFirstTimeSetup=%v", p.isFirstTimeSetup)
// Block escape during first-time setup
if p.isFirstTimeSetup {
return nil
@@ -158,7 +150,6 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error {
sdl.StopTextInput()
p.App.UnwindToPage(&Settings{})
case sdl.K_RETURN:
logger.Info("[EmailAddressPage.HandleEvent] RETURN pressed, inputText=%q", p.inputText)
// Validate email - check empty first, then format
if p.inputText == "" {
p.errorMessage = "Email address cannot be empty"
@@ -186,10 +177,19 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error {
case sdl.K_BACKSPACE:
if len(p.inputText) > 0 {
p.inputText = p.inputText[:len(p.inputText)-1]
logger.Info("[EmailAddressPage.HandleEvent] BACKSPACE: inputText=%q", p.inputText)
// Clear error when user edits input
p.errorMessage = ""
}
default:
// Keyboard fallback: if TextInputEvent is not supported,
// convert printable keycodes to characters directly.
// This handles kiosk systems without an input method framework.
if !p.textInputSupported {
if ch := keycodeToChar(e.Keysym.Sym, e.Keysym.Mod); ch != 0 {
p.inputText += string(ch)
p.errorMessage = ""
}
}
}
}
}
@@ -410,7 +410,6 @@ func (p *EmailAddressPage) Destroy() error {
p.errorTextureID = 0
}
logger.Info("[EmailAddressPage.Destroy] Calling sdl.StopTextInput()")
sdl.StopTextInput()
return p.Base.Destroy()
}