{"content":"Command: cd /Users/nickchen/WorkBuddy/2026-10-23-15-17-57/cleanyourtv && head -80 themes/README.md\nStdout: # Themes\r\n\r\nA theme is a folder with a `config.json` and, optionally, a `wallpaper.jpg`. Pushing one changes the\r\nlauncher's dock, layout and look on the TV without rebuilding the APK: the launcher reads\r\n`config.json` as an overlay over its built-in `config.xml` the next time it starts.\r\nChoices made in Launcher settings take priority until you choose Follow theme. Pushing a theme or\r\nusing `tools/theme.sh --reset` also clears those on-TV column and motion choices.\r\n\r\n```bash\r\nTV_HOST=192.168.1.50 tools/theme.sh themes/aurora          # push a theme and restart Home\r\nTV_HOST=192.168.1.50 tools/theme.sh --reset                # back to the built-in config.xml\r\npowershell -ExecutionPolicy Bypass -File tools\\theme.ps1 -TvHost 192.168.1.50 themes\\aurora\r\n```\r\n\r\n| Theme | What it does | Screenshot |\r\n|---|---|---|\r\n| `default/` | The built-in look written out as JSON, as a starting point for your own | <img src=\"default/screenshot.jpg\" width=\"320\" alt=\"default theme\"> |\r\n| `aurora/` | A dark aurora wallpaper (teal and violet on navy, darker at the bottom) with a matching background colour | <img src=\"aurora/screenshot.jpg\" width=\"320\" alt=\"aurora theme\"> |\r\n| `dussehra/` | Festive skin for Dussehra (ends 21 Oct 2026): a marigold toran, a faint gold rangoli, a diya for Wi-Fi, a bell for Inputs, a marigold for Settings and a petal shower | <img src=\"dussehra/screenshot.jpg\" width=\"320\" alt=\"dussehra theme\"> |\r\n| `glass/` | Dark navy wallpaper with soft teal and violet light, the cinematic top shelf, a frosted-glass dock, icon-only buttons and the focus glow in the app's colour, gliding without overshoot | <img src=\"glass/screenshot.jpg\" width=\"320\" alt=\"glass theme\"> |\r\n| `ruska/` | A Finnish autumn (\"ruska\") dusk over a lake: spruce shoreline, birches in autumn colour, a few falling leaves, drawn in code by `make_wallpaper.py`. The app-colour glow stays off the picture so the autumn colours keep their own light; the dock is 70% opaque so the lake shows through, and the focus glows in the app's colour without overshoot | <img src=\"ruska/screenshot.jpg\" width=\"320\" alt=\"ruska theme\"> |\r\n| `scenes/` | 14 dark illustrated landscapes in `wallpapers/`, a new one every hour; drawn from code by `tools/scenes_wallpapers.py` | <img src=\"scenes/screenshot.jpg\" width=\"320\" alt=\"scenes theme\"> |\r\n| `six-columns/` | Six smaller tiles per row and one grid row visible under the dock | <img src=\"six-columns/screenshot.jpg\" width=\"320\" alt=\"six-columns theme\"> |\r\n\r\nEvery theme folder has a `screenshot.jpg` of Home with that theme on a real TV. `tools/theme.sh` never\r\npushes it; it is only here so you can see a theme before you try it.\r\n\r\n## Keys\r\n\r\nEvery key is optional; a missing key keeps the value from `config.xml`, an unknown or wrongly typed key\r\nis ignored, and a file that doesn't parse is ignored as a whole, so a theme can never break Home.\r\n\r\nEach key has (or is waiting for) a screenshot of it on a real TV in [`docs/switches.md`](../docs/switches.md).\r\nA new key needs one there in the same pull request.\r\n\r\n| Key | Type | Meaning |\r\r\n|---|---|---|\r\n| `dock_apps` | list of package names | The dock row, in order; missing apps are skipped |\r\n| `fill_dock` | bool | Fill the dock slots `dock_apps` leaves free with the first grid apps (true by default); false leaves them empty |\r\n| `hidden_apps` | list of package names | Never shown as tiles |\r\n| `live_tv_package`, `live_tv_action` | string | The Live TV app and, if it has no leanback entry, the action to start it with |\r\n| `live_tv_input_id` | string | Exact system tuner for the Inputs menu's Live TV row; opens its channel collection. Empty keeps automatic selection. Missing input or unsupported collection falls back to the app's normal launch. [HAAM satellite example](../docs/devices/haam-r4.md) |\r\n| `source_panel_service`, `source_panel_action` | string | The TV's own source panel, for sets with no TvInputManager: a service, or an activity (BYINTEK U4). Without a Live TV app, the Inputs pill opens it directly |\r\n| `source_panel_extra` | `\"name=value\"` | One int extra sent with the source panel (Coocaa OS: `control_center_command=100`) |\r\n| `coocaa_sources` | bool | Coocaa OS (Skyworth, China): list the sources from `com.skyworth.tv` in the Inputs menu, ahead of the source panel |\r\n| `launch_actions` | list of `\"package=action\"` | Tiles that open a screen of the app instead of its start screen; an action that no longer resolves opens the app normally (MagentaTV's guide: `com.telekom.onetv.tv.pl=com.telekom.onetv.tv.pl.action.PROGRAM_GUIDE`) |\r\n| `app_labels` | list of `\"package=Name\"` | A tile's name instead of the app's own (MagentaTV as `com.telekom.onetv.tv.pl=TV`) |\r\n| `app_banners` | list of `\"package=banner_name\"` | A tile's artwork from a `banner_*` drawable bundled with the launcher (`banner_tv`: magenta with the Live TV glyph) |\r\n| `input_action` | string | Action sent with an HDMI/AV row's channel URI when nothing handles the standard `VIEW` (XGIMI: `com.xgimi.action.hdmiPlayer`). Only a handler-less set gets here; any app that claims the channel MIME type takes the row instead, so check with `query-activities` ([#805](https://github.com/Gathin23/cleanyourtv/issues/805)) |\r\n| `input_uri_scheme` | string | Scheme an HDMI/AV row's passthrough URI is sent with instead of `content://`, with no MIME type (YaOS: `live-tv`, which its source player answers) |\r\n| `input_sources` | list, `config.xml` only | Vendor source numbers for the Inputs menu, `HW<n>=<number>` by the input id's last part; a mapped input opens by sending `input_action` with the number as the int extra `input`, and `HW<n>=-` leaves a port the set doesn't have out of the menu. Xiaomi/Redmi China firmware: [redmi-mitv-mftp0](../examples/redmi-mitv-mftp0/). Not read from a theme |\r\n| `columns` | 1 to 8 | Tiles per row; tiles shrink to fit from 5 up |\r\n| `rows_below_dock` | 0 to 3 | Grid rows left visible under the dock; tiles shrink if the dock, its title and that many rows would not fit the screen height |\r\n| `dock_title` | bool | The focused dock app's name in large type above the dock (`true`); `false` keeps only the glow |\r\n| `dock_row` | bool | The dock as its own row with a band (`true`); `false` makes the dock apps the first tiles of one plain grid |\r\n| `reorder_button` | bool | A reorder button in the top bar (`false` by default); reordering is always in the Settings button's long-press menu |\r\n| `show_network_pill` | bool | The Wi-Fi/Ethernet pill in the top bar (`true` by default); `false` hides it |\r\n| `show_inputs_pill` | bool | The Inputs pill in the top bar, shown when the TV has inputs (`true` by default); `false` hides it; what the remote's Input button does is unchanged |\r\n| `icon_only_buttons` | bool | Wi-Fi and Settings as round icon buttons; Inputs keeps its label (`false` by default) |\r\n| `icon_only_inputs` | bool | The Inputs pill as a round icon button too, its label kept as the TalkBack description (`false` by default). Works with or without `icon_only_buttons` |\r\n| `top_menu` | bool | Inputs, Wi-Fi and Settings folded into one round gear, centred on the header: OK drops a menu with the three, hold OK keeps the launcher menu (`false` by default) |\r\n| `launcher_settings_button` | bool | Make the header Settings action open Launcher settings directly with a matching 22dp home icon; also changes the Settings row when `top_menu` is on. Hold OK keeps module-card and ordering tools. The settings page includes Reorder apps and TV settings (`false` by default) |\r\n| `wifi_status_color` | bool | The Wi-Fi pill's icon green while the TV is online, white while it is not (`false` by default) |\r\n| `wifi_label_width` | 0 to 300 | With `icon_only_buttons`, keep the network name on the Wi-Fi pill up to this width in dp, cut with an ellipsis; 0 leaves only the icon |\r\n| `library_button` | bool | The app library as a round button in the top bar, beside Settings; needs `app_library`. Closing the library returns to it |\r\n| `always_show_names` | bool | Names under every tile, dimmed until focused, the dock included (its band grows to hold them); `false` by default shows only the focused tile's name |\r\n| `wallpaper_true_color` | bool | Decode wallpapers in 32-bit colour (8 MB at 1080p) instead of RGB_565 (4 MB), which bands dark gradients such as a night sky; for TVs with 2 GB or more (`false` by default) |\r\n| `app_library` | bool | An App library pill after the last Home row: every installed app, add one to Home or take it off (`false` by default). The choices stay on the TV when a theme is pushed or reset; see [docs/app-library.md](../docs/app-library.md) |\r\n| `app_library_selection` | bool | OK toggles Home checkmarks in the library; checked apps first, both groups alphabetized. Hiding keeps focus on the adjacent next app (previous at the end). Requires `app_library`; `false` preserves the standard open/long-press behavior |\r\n| `library_apps` | list of package names | Packages pre-seeded into the App library's \"added\" set at startup (config.xml `library_apps`, or a theme's `config.json`). They show on Home as if the owner had added them in the App library UI, and stay removable there (a removed one stays hidden); empty (off) by default |\r\n| `shamsi_date` | bool | Show the Solar Hijri date above the Gregorian one |\r\n| `greeting_name` | string | A name after the greeting, e.g. `\"Mr. Trịnh\"` for GOOD MORNING, MR. TRỊNH; empty for the greeting alone |\r\n| `module_cards` | bool | Look for module cards and ask about them (`true`); `false` turns the feature off |\r\n| `reduced_motion` | bool | Calmer motion for weak GPUs: the highlight slides without bouncing and settles within 5 frames, every animation lasts 90 ms or less, names, the top shelf, the glow and the highlight appear instead of fading, and there is no tile entrance (`false` by default) |\r\n| `boot_to_live_tv` | bool | Open the Live TV app (`live_tv_package`) on the first Home after the TV starts, once per boot |\r\n| `focus_overshoot` | bool | The highlight and the focused tile swing past their target before settling (`true` by default); `false` glides straight there with smooth scrolling |\r\n| `vpn_app` | string | App the network pill opens when a VPN is configured; also shows a red \"VPN off\" badge while no VPN is up |\r\n| `animations` | bool | Basic focus, glass, title and tile entrance motion; true by default |\r\n| `advanced_effects` | bool | Optional lifted tile, icon zoom, smooth ambient colour and app opening effects; false by default |\r\n| `show_home_settings_shortcut` | bool | Keep the optional Default-home tile visible when the TV has a home picker; false by default |\r\n\nStderr: (empty)\nExit Code: 0\nSignal: (none)","renderer":{"type":"text","value":"# Themes\r\n\r\nA theme is a folder with a `config.json` and, optionally, a `wallpaper.jpg`. Pushing one changes the\r\nlauncher's dock, layout and look on the TV without rebuilding the APK: the launcher reads\r\n`config.json` as an overlay over its built-in `config.xml` the next time it starts.\r\nChoices made in Launcher settings take priority until you choose Follow theme. Pushing a theme or\r\nusing `tools/theme.sh --reset` also clears those on-TV column and motion choices.\r\n\r\n```bash\r\nTV_HOST=192.168.1.50 tools/theme.sh themes/aurora          # push a theme and restart Home\r\nTV_HOST=192.168.1.50 tools/theme.sh --reset                # back to the built-in config.xml\r\npowershell -ExecutionPolicy Bypass -File tools\\theme.ps1 -TvHost 192.168.1.50 themes\\aurora\r\n```\r\n\r\n| Theme | What it does | Screenshot |\r\n|---|---|---|\r\n| `default/` | The built-in look written out as JSON, as a starting point for your own | <img src=\"default/screenshot.jpg\" width=\"320\" alt=\"default theme\"> |\r\n| `aurora/` | A dark aurora wallpaper (teal and violet on navy, darker at the bottom) with a matching background colour | <img src=\"aurora/screenshot.jpg\" width=\"320\" alt=\"aurora theme\"> |\r\n| `dussehra/` | Festive skin for Dussehra (ends 21 Oct 2026): a marigold toran, a faint gold rangoli, a diya for Wi-Fi, a bell for Inputs, a marigold for Settings and a petal shower | <img src=\"dussehra/screenshot.jpg\" width=\"320\" alt=\"dussehra theme\"> |\r\n| `glass/` | Dark navy wallpaper with soft teal and violet light, the cinematic top shelf, a frosted-glass dock, icon-only buttons and the focus glow in the app's colour, gliding without overshoot | <img src=\"glass/screenshot.jpg\" width=\"320\" alt=\"glass theme\"> |\r\n| `ruska/` | A Finnish autumn (\"ruska\") dusk over a lake: spruce shoreline, birches in autumn colour, a few falling leaves, drawn in code by `make_wallpaper.py`. The app-colour glow stays off the picture so the autumn colours keep their own light; the dock is 70% opaque so the lake shows through, and the focus glows in the app's colour without overshoot | <img src=\"ruska/screenshot.jpg\" width=\"320\" alt=\"ruska theme\"> |\r\n| `scenes/` | 14 dark illustrated landscapes in `wallpapers/`, a new one every hour; drawn from code by `tools/scenes_wallpapers.py` | <img src=\"scenes/screenshot.jpg\" width=\"320\" alt=\"scenes theme\"> |\r\n| `six-columns/` | Six smaller tiles per row and one grid row visible under the dock | <img src=\"six-columns/screenshot.jpg\" width=\"320\" alt=\"six-columns theme\"> |\r\n\r\nEvery theme folder has a `screenshot.jpg` of Home with that theme on a real TV. `tools/theme.sh` never\r\npushes it; it is only here so you can see a theme before you try it.\r\n\r\n## Keys\r\n\r\nEvery key is optional; a missing key keeps the value from `config.xml`, an unknown or wrongly typed key\r\nis ignored, and a file that doesn't parse is ignored as a whole, so a theme can never break Home.\r\n\r\nEach key has (or is waiting for) a screenshot of it on a real TV in [`docs/switches.md`](../docs/switches.md).\r\nA new key needs one there in the same pull request.\r\n\r\n| Key | Type | Meaning |\r\r\n|---|---|---|\r\n| `dock_apps` | list of package names | The dock row, in order; missing apps are skipped |\r\n| `fill_dock` | bool | Fill the dock slots `dock_apps` leaves free with the first grid apps (true by default); false leaves them empty |\r\n| `hidden_apps` | list of package names | Never shown as tiles |\r\n| `live_tv_package`, `live_tv_action` | string | The Live TV app and, if it has no leanback entry, the action to start it with |\r\n| `live_tv_input_id` | string | Exact system tuner for the Inputs menu's Live TV row; opens its channel collection. Empty keeps automatic selection. Missing input or unsupported collection falls back to the app's normal launch. [HAAM satellite example](../docs/devices/haam-r4.md) |\r\n| `source_panel_service`, `source_panel_action` | string | The TV's own source panel, for sets with no TvInputManager: a service, or an activity (BYINTEK U4). Without a Live TV app, the Inputs pill opens it directly |\r\n| `source_panel_extra` | `\"name=value\"` | One int extra sent with the source panel (Coocaa OS: `control_center_command=100`) |\r\n| `coocaa_sources` | bool | Coocaa OS (Skyworth, China): list the sources from `com.skyworth.tv` in the Inputs menu, ahead of the source panel |\r\n| `launch_actions` | list of `\"package=action\"` | Tiles that open a screen of the app instead of its start screen; an action that no longer resolves opens the app normally (MagentaTV's guide: `com.telekom.onetv.tv.pl=com.telekom.onetv.tv.pl.action.PROGRAM_GUIDE`) |\r\n| `app_labels` | list of `\"package=Name\"` | A tile's name instead of the app's own (MagentaTV as `com.telekom.onetv.tv.pl=TV`) |\r\n| `app_banners` | list of `\"package=banner_name\"` | A tile's artwork from a `banner_*` drawable bundled with the launcher (`banner_tv`: magenta with the Live TV glyph) |\r\n| `input_action` | string | Action sent with an HDMI/AV row's channel URI when nothing handles the standard `VIEW` (XGIMI: `com.xgimi.action.hdmiPlayer`). Only a handler-less set gets here; any app that claims the channel MIME type takes the row instead, so check with `query-activities` ([#805](https://github.com/Gathin23/cleanyourtv/issues/805)) |\r\n| `input_uri_scheme` | string | Scheme an HDMI/AV row's passthrough URI is sent with instead of `content://`, with no MIME type (YaOS: `live-tv`, which its source player answers) |\r\n| `input_sources` | list, `config.xml` only | Vendor source numbers for the Inputs menu, `HW<n>=<number>` by the input id's last part; a mapped input opens by sending `input_action` with the number as the int extra `input`, and `HW<n>=-` leaves a port the set doesn't have out of the menu. Xiaomi/Redmi China firmware: [redmi-mitv-mftp0](../examples/redmi-mitv-mftp0/). Not read from a theme |\r\n| `columns` | 1 to 8 | Tiles per row; tiles shrink to fit from 5 up |\r\n| `rows_below_dock` | 0 to 3 | Grid rows left visible under the dock; tiles shrink if the dock, its title and that many rows would not fit the screen height |\r\n| `dock_title` | bool | The focused dock app's name in large type above the dock (`true`); `false` keeps only the glow |\r\n| `dock_row` | bool | The dock as its own row with a band (`true`); `false` makes the dock apps the first tiles of one plain grid |\r\n| `reorder_button` | bool | A reorder button in the top bar (`false` by default); reordering is always in the Settings button's long-press menu |\r\n| `show_network_pill` | bool | The Wi-Fi/Ethernet pill in the top bar (`true` by default); `false` hides it |\r\n| `show_inputs_pill` | bool | The Inputs pill in the top bar, shown when the TV has inputs (`true` by default); `false` hides it; what the remote's Input button does is unchanged |\r\n| `icon_only_buttons` | bool | Wi-Fi and Settings as round icon buttons; Inputs keeps its label (`false` by default) |\r\n| `icon_only_inputs` | bool | The Inputs pill as a round icon button too, its label kept as the TalkBack description (`false` by default). Works with or without `icon_only_buttons` |\r\n| `top_menu` | bool | Inputs, Wi-Fi and Settings folded into one round gear, centred on the header: OK drops a menu with the three, hold OK keeps the launcher menu (`false` by default) |\r\n| `launcher_settings_button` | bool | Make the header Settings action open Launcher settings directly with a matching 22dp home icon; also changes the Settings row when `top_menu` is on. Hold OK keeps module-card and ordering tools. The settings page includes Reorder apps and TV settings (`false` by default) |\r\n| `wifi_status_color` | bool | The Wi-Fi pill's icon green while the TV is online, white while it is not (`false` by default) |\r\n| `wifi_label_width` | 0 to 300 | With `icon_only_buttons`, keep the network name on the Wi-Fi pill up to this width in dp, cut with an ellipsis; 0 leaves only the icon |\r\n| `library_button` | bool | The app library as a round button in the top bar, beside Settings; needs `app_library`. Closing the library returns to it |\r\n| `always_show_names` | bool | Names under every tile, dimmed until focused, the dock included (its band grows to hold them); `false` by default shows only the focused tile's name |\r\n| `wallpaper_true_color` | bool | Decode wallpapers in 32-bit colour (8 MB at 1080p) instead of RGB_565 (4 MB), which bands dark gradients such as a night sky; for TVs with 2 GB or more (`false` by default) |\r\n| `app_library` | bool | An App library pill after the last Home row: every installed app, add one to Home or take it off (`false` by default). The choices stay on the TV when a theme is pushed or reset; see [docs/app-library.md](../docs/app-library.md) |\r\n| `app_library_selection` | bool | OK toggles Home checkmarks in the library; checked apps first, both groups alphabetized. Hiding keeps focus on the adjacent next app (previous at the end). Requires `app_library`; `false` preserves the standard open/long-press behavior |\r\n| `library_apps` | list of package names | Packages pre-seeded into the App library's \"added\" set at startup (config.xml `library_apps`, or a theme's `config.json`). They show on Home as if the owner had added them in the App library UI, and stay removable there (a removed one stays hidden); empty (off) by default |\r\n| `shamsi_date` | bool | Show the Solar Hijri date above the Gregorian one |\r\n| `greeting_name` | string | A name after the greeting, e.g. `\"Mr. Trịnh\"` for GOOD MORNING, MR. TRỊNH; empty for the greeting alone |\r\n| `module_cards` | bool | Look for module cards and ask about them (`true`); `false` turns the feature off |\r\n| `reduced_motion` | bool | Calmer motion for weak GPUs: the highlight slides without bouncing and settles within 5 frames, every animation lasts 90 ms or less, names, the top shelf, the glow and the highlight appear instead of fading, and there is no tile entrance (`false` by default) |\r\n| `boot_to_live_tv` | bool | Open the Live TV app (`live_tv_package`) on the first Home after the TV starts, once per boot |\r\n| `focus_overshoot` | bool | The highlight and the focused tile swing past their target before settling (`true` by default); `false` glides straight there with smooth scrolling |\r\n| `vpn_app` | string | App the network pill opens when a VPN is configured; also shows a red \"VPN off\" badge while no VPN is up |\r\n| `animations` | bool | Basic focus, glass, title and tile entrance motion; true by default |\r\n| `advanced_effects` | bool | Optional lifted tile, icon zoom, smooth ambient colour and app opening effects; false by default |\r\n| `show_home_settings_shortcut` | bool | Keep the optional Default-home tile visible when the TV has a home picker; false by default |"}}