Skip to content

feat: Added theme support for External Display Input#497

Open
MayRedBeWithYou wants to merge 3 commits intoutkarshdalal:masterfrom
MayRedBeWithYou:feature/external-display-input-themes
Open

feat: Added theme support for External Display Input#497
MayRedBeWithYou wants to merge 3 commits intoutkarshdalal:masterfrom
MayRedBeWithYou:feature/external-display-input-themes

Conversation

@MayRedBeWithYou
Copy link

@MayRedBeWithYou MayRedBeWithYou commented Feb 6, 2026

I recently posted a #feature-request regarding adding AMOLED theme for External Display Input mode. I decided to give it a shot - let me know what you think.

  • Settings:
Screenshot_20260206-170601
  • Default theme:
Screenshot_20260206-170624 Screenshot_20260206-170630
  • AMOLED theme:
Screenshot_20260206-170654 Screenshot_20260206-170700

Summary by cubic

Adds theme support to External Display Input with a new Black theme for true blacks and reduced glare. Themes apply across touchpad, keyboard, hybrid modes, and overlay icons.

  • New Features
    • Theme system with DEFAULT and BLACK variants for External Display Input.
    • New setting: “External Display Input Theme” (Settings → Interface); persisted via PrefManager.
    • Themed backgrounds, key highlights, and icon colors for presentation and swap overlay.
    • XServer screen reads the preference and applies the theme on start; controller can update theme at runtime.

Written for commit d62c7d1. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • External display input now supports two themes (Default and Black) with distinct color palettes applied across keyboard, overlay, and icons.
    • Theme changes are applied live to the external display experience.
  • Settings

    • Added "External Display Input Theme" dropdown in Settings to choose and persist the preferred theme.
  • UI

    • New color and string resources added to support the themes.

@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

📝 Walkthrough

Walkthrough

Adds a theming system for external display input: new Theme enum with color properties, persisted preference key in PrefManager, settings UI to choose theme, controller API to set theme, and views/presentation updated to render using theme colors and propagate updates.

Changes

Cohort / File(s) Summary
Core Theme & Prefs
app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt, app/src/main/java/app/gamenative/PrefManager.kt
Introduce Theme enum with color fields and fromConfig, add externalDisplayTheme preference, add setTheme() and internal theme on controller.
Presentation & Controller Binding
app/src/main/java/app/gamenative/externaldisplay/ExternalInputPresentation.kt, app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt
Presentation now accepts theme, exposes updateTheme(), and render paths use theme colors; controller propagates theme changes to active presentation.
Keyboard & Overlay Views
app/src/main/java/app/gamenative/externaldisplay/ExternalOnScreenKeyboardView.kt, app/src/main/java/app/gamenative/externaldisplay/SwapInputOverlayView.kt, app/src/main/java/app/gamenative/externaldisplay/HybridInputLayout.kt
View constructors accept a theme param; replace hard-coded/background resource colors with theme-based colors and apply color filters for icons/keys.
Settings UI & Screen Wiring
app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupInterface.kt, app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
Add settings dropdown bound to PrefManager.externalDisplayTheme; XServerScreen reads pref, passes theme to overlay, and calls setTheme() on controller when starting external display.
Resources
app/src/main/res/values/colors.xml, app/src/main/res/values/strings.xml
Add color resources for black theme variants and external_display_key_color; add three strings for settings label and two theme option names.

Sequence Diagram

sequenceDiagram
    actor User
    participant Settings as Settings UI
    participant PrefMgr as PrefManager
    participant XScreen as XServerScreen
    participant DisplayCtrl as ExternalDisplayInputController
    participant Presentation as ExternalInputPresentation
    participant Views as External Views

    User->>Settings: select theme option
    Settings->>PrefMgr: save externalDisplayTheme
    PrefMgr-->>Settings: persisted
    XScreen->>PrefMgr: read externalDisplayTheme
    PrefMgr-->>XScreen: return theme
    XScreen->>DisplayCtrl: start / setTheme(theme)
    DisplayCtrl->>Presentation: updateTheme(theme)
    Presentation->>Views: re-render with theme
    Views-->>User: display themed UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰✨ I hopped through pixels, nibbling on code,
A theme for displays down my rabbit road,
Prefs tucked away, controller sings,
Keys dressed in color — joyful springs,
Hop, render, repeat — hooray the shows!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature added: theme support for External Display Input. It is concise, specific, and directly related to the primary changes across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 8 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupInterface.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupInterface.kt:419">
P2: User-visible dropdown labels are hardcoded instead of using string resources, preventing localization and inconsistent with the rest of the settings UI.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/src/main/java/app/gamenative/externaldisplay/SwapInputOverlayView.kt (1)

55-60: ⚠️ Potential issue | 🟠 Major

Bug: keyboardToggleButton background color is not themed.

Line 57 uses hardcoded R.color.external_display_key_background while every other color in this file and the equivalent button in HybridInputLayout (line 291 of ExternalDisplayInputController.kt) uses theme.keyBg. This means the AMOLED theme won't apply to this button's background in SwapInputOverlayView.

🐛 Proposed fix
         background = GradientDrawable().apply {
             shape = GradientDrawable.OVAL
-            setColor(ContextCompat.getColor(context, R.color.external_display_key_background))
+            setColor(ContextCompat.getColor(context, theme.keyBg))
         }
app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt (1)

213-222: ⚠️ Potential issue | 🟡 Minor

Inconsistent icon styling: alpha = 0.35f here vs. no alpha in SwapInputOverlayView.

In the ExternalInputPresentation KEYBOARD mode, the hint icon uses both setColorFilter(theme.iconColor) (line 220) and alpha = 0.35f (line 221). In SwapInputOverlayView (line 30), only setColorFilter(theme.iconColor) is applied—no alpha. This means the hint icon will look different depending on which code path renders it.

If the intent is for the theme's iconColor to fully control opacity, remove the hardcoded alpha here. If the alpha is intentional for the external display, consider documenting why.

🤖 Fix all issues with AI agents
In
`@app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupInterface.kt`:
- Around line 415-429: The dropdown is comparing localized labels ("Default",
"AMOLED") to a stored enum name (PrefManager.externalDisplayTheme, e.g.,
"DEFAULT"), causing indexOf to return -1 and wrong persistence; change the
dropdown to be enum-backed: build a list of enum values (e.g., Theme.values())
or enum-name strings to use as the internal items for value/indexing and
persistence, and separately map those enum entries to localized display labels
for title/visible text; initialize selectedExternalDisplayTheme from
PrefManager.externalDisplayTheme (the enum name), use the enum-name list for
SettingsListDropdown.value/indexOf, and onItemSelected persist the selected
enum.name back to PrefManager.externalDisplayTheme while showing the
corresponding localized label.
🧹 Nitpick comments (2)
app/src/main/java/app/gamenative/externaldisplay/ExternalOnScreenKeyboardView.kt (1)

160-165: Hardcoded Color.WHITE for key text.

Key text color is Color.WHITE regardless of theme. This works for both current dark themes, but if a light theme is added later, this won't adapt. Consider adding a textColor property to the Theme enum for forward-compatibility.

app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt (1)

47-52: fromConfig relies on raw string matching—consider using enum name.

fromConfig matches "amoled" as a magic string. If a new theme is added, the developer must remember to update this function. Using Theme.valueOf() (with a fallback) or entries.find { it.name.equals(value, ignoreCase = true) } would auto-extend to new enum values.

♻️ Suggested refactor
         companion object {
-            fun fromConfig(value: String?): Theme = when (value?.lowercase()) {
-                "amoled" -> AMOLED
-                else -> DEFAULT
-            }
+            fun fromConfig(value: String?): Theme =
+                entries.find { it.name.equals(value, ignoreCase = true) } ?: DEFAULT
         }

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupInterface.kt">

<violation number="1" location="app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupInterface.kt:433">
P2: Dropdown selection state is no longer updated, so the displayed selection can remain stale after the user picks a theme.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt">

<violation number="1" location="app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt:49">
P2: Theme.fromConfig no longer recognizes the previously stored "AMOLED" preference value, so existing users with that saved theme will fall back to DEFAULT after the rename.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.


companion object {
fun fromConfig(value: String?): Theme = when (value?.lowercase()) {
"black" -> BLACK
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 6, 2026

Choose a reason for hiding this comment

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

P2: Theme.fromConfig no longer recognizes the previously stored "AMOLED" preference value, so existing users with that saved theme will fall back to DEFAULT after the rename.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/app/gamenative/externaldisplay/ExternalDisplayInputController.kt, line 49:

<comment>Theme.fromConfig no longer recognizes the previously stored "AMOLED" preference value, so existing users with that saved theme will fall back to DEFAULT after the rename.</comment>

<file context>
@@ -27,26 +27,26 @@ class ExternalDisplayInputController(
         companion object {
             fun fromConfig(value: String?): Theme = when (value?.lowercase()) {
-                "amoled" -> AMOLED
+                "black" -> BLACK
                 else -> DEFAULT
             }
</file context>
Fix with Cubic

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant