From 0f7c2e904e12a984e5166bf6fe2262ba37981d6f Mon Sep 17 00:00:00 2001 From: FabianZettl Date: Fri, 14 Aug 2026 23:30:07 +0200 Subject: [PATCH] Add Ctrl+1 / Ctrl+2 to Quick Keys and More Keys Adds two new bindable shortcuts to both the Command Center Quick Keys row and the classic More Keys / Special Keys sheet, following the existing Ctrl+V pattern. On SteamOS/Big Picture hosts, Ctrl+1 opens the Big Picture menu and Ctrl+2 opens the Quick Access Menu (Decky Loader, volume, chat, etc.). Both are otherwise only reachable via the physical Xbox Button + A chord, which most controllers/remotes streaming through Nova can't send. Tested on-device (AYN Thor, nonRoot_game debug build) against a Polaris host: both shortcuts fire correctly from Quick Keys and More Keys during a live session. Co-Authored-By: Claude Sonnet 5 --- app/src/main/java/com/papi/nova/GameMenu.kt | 6 ++++++ .../com/papi/nova/binding/input/KeyboardTranslator.kt | 2 ++ app/src/main/java/com/papi/nova/ui/NovaQuickMenu.kt | 2 ++ .../main/java/com/papi/nova/ui/NovaQuickMenuContent.kt | 4 +++- .../main/java/com/papi/nova/ui/NovaQuickMenuUiState.kt | 10 ++++++++++ app/src/main/res/values/strings.xml | 2 ++ .../java/com/papi/nova/ui/NovaQuickMenuUiStateTest.kt | 2 ++ 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/papi/nova/GameMenu.kt b/app/src/main/java/com/papi/nova/GameMenu.kt index d57984319..3362347c9 100644 --- a/app/src/main/java/com/papi/nova/GameMenu.kt +++ b/app/src/main/java/com/papi/nova/GameMenu.kt @@ -262,6 +262,12 @@ class GameMenu @JvmOverloads constructor( ), ) })) + options.add(MenuOption(getString(R.string.game_menu_send_keys_ctrl_1), Runnable { + sendKeys(shortArrayOf(KeyboardTranslator.VK_LCONTROL.toShort(), KeyboardTranslator.VK_1.toShort())) + })) + options.add(MenuOption(getString(R.string.game_menu_send_keys_ctrl_2), Runnable { + sendKeys(shortArrayOf(KeyboardTranslator.VK_LCONTROL.toShort(), KeyboardTranslator.VK_2.toShort())) + })) } val preferences = game.getSharedPreferences(PREF_NAME, Activity.MODE_PRIVATE) diff --git a/app/src/main/java/com/papi/nova/binding/input/KeyboardTranslator.kt b/app/src/main/java/com/papi/nova/binding/input/KeyboardTranslator.kt index 9c404d31a..b2d82eda1 100644 --- a/app/src/main/java/com/papi/nova/binding/input/KeyboardTranslator.kt +++ b/app/src/main/java/com/papi/nova/binding/input/KeyboardTranslator.kt @@ -182,6 +182,8 @@ class KeyboardTranslator(private val prefConfig: PreferenceConfiguration) : Inpu private const val KEY_PREFIX = 0x80 const val VK_0 = 48 + const val VK_1 = 49 + const val VK_2 = 50 const val VK_9 = 57 const val VK_A = 65 const val VK_Z = 90 diff --git a/app/src/main/java/com/papi/nova/ui/NovaQuickMenu.kt b/app/src/main/java/com/papi/nova/ui/NovaQuickMenu.kt index c5e89b96a..c31efca9c 100644 --- a/app/src/main/java/com/papi/nova/ui/NovaQuickMenu.kt +++ b/app/src/main/java/com/papi/nova/ui/NovaQuickMenu.kt @@ -385,6 +385,8 @@ class NovaQuickMenu(private val game: Game) : Game.GameMenuCallbacks { NovaQuickMenuActionId.QUICK_INSERT -> keys(KeyboardTranslator.VK_INSERT) NovaQuickMenuActionId.QUICK_META -> keys(KeyboardTranslator.VK_LWIN) NovaQuickMenuActionId.QUICK_CTRL_V -> keys(KeyboardTranslator.VK_LCONTROL, KeyboardTranslator.VK_V) + NovaQuickMenuActionId.QUICK_CTRL_1 -> keys(KeyboardTranslator.VK_LCONTROL, KeyboardTranslator.VK_1) + NovaQuickMenuActionId.QUICK_CTRL_2 -> keys(KeyboardTranslator.VK_LCONTROL, KeyboardTranslator.VK_2) else -> return } dismiss() diff --git a/app/src/main/java/com/papi/nova/ui/NovaQuickMenuContent.kt b/app/src/main/java/com/papi/nova/ui/NovaQuickMenuContent.kt index 03613a406..644115f13 100644 --- a/app/src/main/java/com/papi/nova/ui/NovaQuickMenuContent.kt +++ b/app/src/main/java/com/papi/nova/ui/NovaQuickMenuContent.kt @@ -109,7 +109,9 @@ data class NovaQuickMenuCallbacks( NovaQuickMenuActionId.QUICK_F11, NovaQuickMenuActionId.QUICK_INSERT, NovaQuickMenuActionId.QUICK_META, - NovaQuickMenuActionId.QUICK_CTRL_V -> onQuickKey(action.id) + NovaQuickMenuActionId.QUICK_CTRL_V, + NovaQuickMenuActionId.QUICK_CTRL_1, + NovaQuickMenuActionId.QUICK_CTRL_2 -> onQuickKey(action.id) NovaQuickMenuActionId.NOVA_HUD, NovaQuickMenuActionId.PERF_STATS, NovaQuickMenuActionId.DIAGNOSE_STREAM, diff --git a/app/src/main/java/com/papi/nova/ui/NovaQuickMenuUiState.kt b/app/src/main/java/com/papi/nova/ui/NovaQuickMenuUiState.kt index 2f96cac8c..1e0f618c6 100644 --- a/app/src/main/java/com/papi/nova/ui/NovaQuickMenuUiState.kt +++ b/app/src/main/java/com/papi/nova/ui/NovaQuickMenuUiState.kt @@ -29,6 +29,8 @@ enum class NovaQuickMenuActionId { QUICK_INSERT, QUICK_META, QUICK_CTRL_V, + QUICK_CTRL_1, + QUICK_CTRL_2, NOVA_HUD, PERF_STATS, DIAGNOSE_STREAM, @@ -892,6 +894,14 @@ data class NovaQuickMenuUiState( NovaQuickMenuAction( id = NovaQuickMenuActionId.QUICK_CTRL_V, label = context.getString(R.string.game_menu_send_keys_ctrl_v) + ), + NovaQuickMenuAction( + id = NovaQuickMenuActionId.QUICK_CTRL_1, + label = context.getString(R.string.game_menu_send_keys_ctrl_1) + ), + NovaQuickMenuAction( + id = NovaQuickMenuActionId.QUICK_CTRL_2, + label = context.getString(R.string.game_menu_send_keys_ctrl_2) ) ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7f6449dc6..3b35a445a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -889,6 +889,8 @@ Insert Alt + F4 Ctrl + V + Ctrl + 1 + Ctrl + 2 Win (Meta) Win + D ALT + B diff --git a/app/src/test/java/com/papi/nova/ui/NovaQuickMenuUiStateTest.kt b/app/src/test/java/com/papi/nova/ui/NovaQuickMenuUiStateTest.kt index f5c4573cc..dcda33195 100644 --- a/app/src/test/java/com/papi/nova/ui/NovaQuickMenuUiStateTest.kt +++ b/app/src/test/java/com/papi/nova/ui/NovaQuickMenuUiStateTest.kt @@ -162,6 +162,8 @@ class NovaQuickMenuUiStateTest { assertTrue(state.quickKeys.any { it.id == NovaQuickMenuActionId.QUICK_ESC && it.label == "ESC" }) assertTrue(state.quickKeys.any { it.id == NovaQuickMenuActionId.QUICK_CTRL_V && it.label == "Ctrl + V" }) assertTrue(state.quickKeys.any { it.id == NovaQuickMenuActionId.QUICK_INSERT && it.label == "Insert" }) + assertTrue(state.quickKeys.any { it.id == NovaQuickMenuActionId.QUICK_CTRL_1 && it.label == "Ctrl + 1" }) + assertTrue(state.quickKeys.any { it.id == NovaQuickMenuActionId.QUICK_CTRL_2 && it.label == "Ctrl + 2" }) assertTrue(state.overlayRows.any { it.id == NovaQuickMenuActionId.PERF_STATS && it.label == "Stats Overlay" }) assertTrue(state.advancedRows.any { it.id == NovaQuickMenuActionId.MANGOHUD && it.label == "MangoHud" }) assertTrue(state.sessionRows.any { it.id == NovaQuickMenuActionId.MORE_KEYS && it.label == "More Keys" })