From 8cd7ecd9daeb28c3bf5af7bc42bb2f16b13def49 Mon Sep 17 00:00:00 2001 From: MiMoHo <37556964+MiMoHo@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:07:03 +0200 Subject: [PATCH] don't enable long press when popup keys are empty after filtering placeholders A key with a placeholder as its only popup key (with popup key order containing only "layout") resulted in an empty but non-null popup key array, enabling long press that then crashes in PopupKeysKeyboard.Builder with a division by zero. fixes #1324 Co-Authored-By: Claude Fable 5 --- .../java/helium314/keyboard/keyboard/Key.java | 2 +- .../helium314/keyboard/KeyboardParserTest.kt | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/Key.java b/app/src/main/java/helium314/keyboard/keyboard/Key.java index e54790d13..4ea8e48ce 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/Key.java +++ b/app/src/main/java/helium314/keyboard/keyboard/Key.java @@ -1123,7 +1123,7 @@ public KeyParams( final String[] popupKeys = PopupKeysUtilsKt.createPopupKeysArray(popupSet, mKeyboardParams, label != null ? label : keySpec); mPopupKeysColumnAndFlags = getPopupKeysColumnAndFlagsAndSetNullInArray(params, popupKeys); final String[] finalPopupKeys = popupKeys == null ? null : PopupKeySpec.filterOutEmptyString(popupKeys); - if (finalPopupKeys != null) { + if (finalPopupKeys != null && finalPopupKeys.length > 0) { actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; mPopupKeys = new PopupKeySpec[finalPopupKeys.length]; for (int i = 0; i < finalPopupKeys.length; i++) { diff --git a/app/src/test/java/helium314/keyboard/KeyboardParserTest.kt b/app/src/test/java/helium314/keyboard/KeyboardParserTest.kt index 8236bf412..d5b416842 100644 --- a/app/src/test/java/helium314/keyboard/KeyboardParserTest.kt +++ b/app/src/test/java/helium314/keyboard/KeyboardParserTest.kt @@ -437,6 +437,27 @@ f""", // no newline at the end } } + @Test fun placeholderAsOnlyPopup() { // https://github.com/HeliBorg/HeliBoard/issues/1324 + val keyParams = LayoutParser.parseJsonString("""[[{ "label": "ক", "popup": { "relevant": [ + { "type": "placeholder" } + ] + } }]]""").flatMap { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } }.single() + assertEquals(null, keyParams.mPopupKeys) + keyParams.mAbsoluteWidth = 1f + keyParams.mAbsoluteHeight = 1f + val key = keyParams.createKey() + assertEquals(false, key.isLongPressEnabled) + } + + @Test fun placeholderNextToOtherPopup() { + val key = LayoutParser.parseJsonString("""[[{ "label": "ক", "popup": { "relevant": [ + { "type": "placeholder" }, { "label": "k" } + ] + } }]]""").flatMap { row -> row.mapNotNull { it.compute(params) } }.single() + assertEquals(1, key.toKeyParams(params).mPopupKeys?.size) + assertEquals("k", key.toKeyParams(params).mPopupKeys?.first()?.mLabel) + } + @Test fun popupSymbolAlpha() { val key = LayoutParser.parseJsonString("""[[{ "label": "c", "popup": { "main": { "code": -10001, "label": "x" }