Skip to content

refactor: extract KeyboardLayoutHandler from GeneralKeyboardIME (Part 15) - #426 - #692

Open
prince-0408 wants to merge 2 commits into
scribe-org:mainfrom
prince-0408:refactor/extract-keyboard-layout-handler-426
Open

prince-0408 wants to merge 2 commits into
scribe-org:mainfrom
prince-0408:refactor/extract-keyboard-layout-handler-426

Conversation

@prince-0408

Copy link
Copy Markdown
Collaborator

Description

This PR is Part 15 in modularizing GeneralKeyboardIME for #426.

It extracts keyboard layout XML resolution (getCurrentKeyboardLayoutXML, getPrimarySymbolKeyboardLayoutXML, getKeyboardLayoutForState), container width calculation (getKeyboardWidth), input-type keyboard layout matching (getKeyboardLayoutXMLForInputType, shouldUseNumericKeyboard), and keyboard view re-creation (recreateKeyboard) out of GeneralKeyboardIME.kt into a standalone helper class KeyboardLayoutHandler.

Detailed Changes Table

File / Component Changes Applied Detailed Impact
KeyboardLayoutHandler.kt Created standalone helper encapsulating layout XML resolution (getCurrentKeyboardLayoutXML, getPrimarySymbolKeyboardLayoutXML, getKeyboardLayoutForState), container width calculation (getKeyboardWidth), input-type layout matching (getKeyboardLayoutXMLForInputType, shouldUseNumericKeyboard), and view re-creation (recreateKeyboard). Centralizes all keyboard XML layout resolution and width calculation logic in a dedicated helper class.
GeneralKeyboardIME.kt Instantiated layoutHandler delegate and delegated layout methods (getCurrentKeyboardLayoutXML, getKeyboardWidth, recreateKeyboard, getKeyboardLayoutForState). Delegated companion input type layout helpers (getKeyboardLayoutXMLForInputType, shouldUseNumericKeyboard). Removed dead extension coerceInSafe. Fulfills the final component extraction step of #426 by decoupling layout resolution and container width calculations from GeneralKeyboardIME.kt while preserving 100% backward compatibility.
KeyboardLayoutHandlerTest.kt Added unit tests covering layout XML resolution across letter mode, symbol mode, symbol-shift mode, state-based conjugation layouts, and input type matching. Ensures unit test coverage for layout handler logic.
CHANGELOG.md Added entry under ### ♻️ Code Refactoring detailing the extraction of KeyboardLayoutHandler from GeneralKeyboardIME. Satisfies ci_changelog_check workflow requirement for pull requests targeting main.

Key Benefits

  • Decoupled Layout Resolution & Width Calculations: Removes layout XML selection, conjugation grid resolution, and container width math from GeneralKeyboardIME.kt.
  • Improved Testability & Clean Architecture: Layout selection and input-type matching can now be tested independently without instantiating full Android service components.

Related Issue

Refactors part of #426

@andrewtavis

Copy link
Copy Markdown
Member

Great that this is open, @prince-0408! Would this be the last PR to close the issue?

@prince-0408

Copy link
Copy Markdown
Collaborator Author

Great that this is open, @prince-0408! Would this be the last PR to close the issue?

Thanks @andrewtavis! Not the last one -- Part 16 (introducing a KeyboardIMEContext interface contract as suggested by @Roniscend in #689) is already raised. That should be the final PR to close #426.

} else {
when (dataSize) {
DATA_SIZE_2 -> R.xml.conjugate_view_2x1
DATA_CONSTANT_3 -> R.xml.conjugate_view_1x3

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming nit , DATA_CONSTANT_3 should be DATA_SIZE_3 to match DATA_SIZE_2 wherever data_constant is mentioned

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated DATA_CONSTANT_3 to DATA_SIZE_3 for consistency.

import android.text.InputType.TYPE_MASK_CLASS
import be.scri.R
import be.scri.models.ScribeState
import be.scri.services.GeneralKeyboardIME

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circular import: KeyboardLayoutHandler (helpers) and GeneralKeyboardIME (services) import each other, the handler isn't truly decoupled, it just holds a full ime reference.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. In this PR (Part 15), KeyboardLayoutHandler followed the same structure as previous helper extractions. In the dedicated follow-up #693 (Part 16), we introduce the KeyboardIMEContext interface contract across all handlers, removing the GeneralKeyboardIME reference from KeyboardLayoutHandler and breaking the circular import across the codebase.

TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME, TYPE_CLASS_PHONE -> true
else -> false
}
internal fun shouldUseNumericKeyboard(inputType: Int): Boolean = KeyboardLayoutHandler.shouldUseNumericKeyboard(inputType)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrappers still hang around shouldUseNumericKeyboard and getKeyboardLayoutXMLForInputType in the companion object just forward to KeyboardLayoutHandler now ,could remove them and call KeyboardLayoutHandler directly if nothing else still uses these.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the forwarding wrappers from GeneralKeyboardIME companion object and updated all call sites and unit tests to invoke KeyboardLayoutHandler directly.

@prince-0408 prince-0408 added the refactor Refactor code to improve quality label Sep 1, 2026
@andrewtavis

Copy link
Copy Markdown
Member

@prince-0408: Would you be able to rebase and resolve conflicts? Anything else needed after that, or would you say that we're ready for a final review? :)

@prince-0408
prince-0408 force-pushed the refactor/extract-keyboard-layout-handler-426 branch 2 times, most recently from 250fe75 to 2ab5b6a Compare September 5, 2026 17:56
@andrewtavis andrewtavis added the no-changelog No changelog entry is needed for this pull request label Sep 13, 2026
* Encapsulates keyboard XML layout resolution, symbol layout mapping,
* keyboard width calculations, state-based layout XML selection, and view re-creation.
*/
class KeyboardLayoutHandler(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couples to the concrete GeneralKeyboardIME instead of KeyboardIMEContext like every sibling,needs handler,getKeyboardLayoutXML(), defaultConjugateLayoutXML, enterKeyType, isFloatingMode, and isNumericKeyboardActive as a property added to the interface first.


@Test
fun testGetCurrentKeyboardLayoutXML_letterMode() {
every { mockIme.keyboardMode } returns 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stubs getKeyboardLayoutXML() to return R.xml.keys_symbols, so the assertion passes even if the mode-check branch were inverted

@Roniscend

Copy link
Copy Markdown
Collaborator

After these changes , this pr will also be good to merge also then we can ask Andrew for a final review

@andrewtavis

Copy link
Copy Markdown
Member

Looks like we're good to move to this one post resolving conflicts, @prince-0408 :) Once we're done here, maybe you and @Roniscend can support @growabeard with the upcoming PR and then we can finalize the issue! 😊

@prince-0408
prince-0408 force-pushed the refactor/extract-keyboard-layout-handler-426 branch from 625680c to e0d0c14 Compare September 26, 2026 21:57
@andrewtavis

Copy link
Copy Markdown
Member

Thanks for the rebase, @prince-0408! @Roniscend, if you have a moment for an initial review, that'd be very helplful :) I'll hopefully be done with the Scribe-Data work later today.

@Roniscend

Copy link
Copy Markdown
Collaborator

Thanks for the rebase, @prince-0408! @Roniscend, if you have a moment for an initial review, that'd be very helplful :) I'll hopefully be done with the Scribe-Data work later today.

Sure, Also I have reviewed this pr twice and after these changes we are good to merge this pr, requesting a final review from your side
Thanks

@andrewtavis

Copy link
Copy Markdown
Member

Hi @prince-0408, @Roniscend, @angrezichatterbox: We have an issue from something getting into main that is now breaking a proper keyboard load. This is likely from the refactor issues, which I seem to have not done a good enough job doing final reviews on. I assume that the issue will be easy to fix, but let's fix it as a part of this PR or send something along quickly in a different PR. See the image below, which is from a Pixel 9 Android 36 emulator:

Screenshot 2026-09-27 at 17 43 01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog No changelog entry is needed for this pull request refactor Refactor code to improve quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants