From 461b4e4fb2cc82bf5ae1ba670351af9f2d9917a6 Mon Sep 17 00:00:00 2001 From: Rocka Date: Sun, 26 Jul 2026 13:31:34 +0800 Subject: [PATCH] Add option for keyboard height percent base - resources.displayMetrics.heightPixels is unstable on some devices - maybe we should change the semantics of "height percent" to physical screen size --- .../fcitx5/android/data/prefs/AppPrefs.kt | 6 +++++ .../fcitx/fcitx5/android/input/InputView.kt | 26 ++++++++++++++++++- .../keyboard/KeyboardHeightPercentBase.kt | 14 ++++++++++ app/src/main/res/values/strings.xml | 3 +++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/fcitx/fcitx5/android/input/keyboard/KeyboardHeightPercentBase.kt diff --git a/app/src/main/java/org/fcitx/fcitx5/android/data/prefs/AppPrefs.kt b/app/src/main/java/org/fcitx/fcitx5/android/data/prefs/AppPrefs.kt index 5ec27647..bed1cbfe 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/data/prefs/AppPrefs.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/data/prefs/AppPrefs.kt @@ -16,6 +16,7 @@ import org.fcitx.fcitx5.android.input.candidates.expanded.ExpandedCandidateStyle import org.fcitx.fcitx5.android.input.candidates.floating.FloatingCandidatesMode import org.fcitx.fcitx5.android.input.candidates.floating.FloatingCandidatesOrientation import org.fcitx.fcitx5.android.input.candidates.horizontal.HorizontalCandidateMode +import org.fcitx.fcitx5.android.input.keyboard.KeyboardHeightPercentBase import org.fcitx.fcitx5.android.input.keyboard.LangSwitchBehavior import org.fcitx.fcitx5.android.input.keyboard.SpaceLongPressBehavior import org.fcitx.fcitx5.android.input.keyboard.SwipeSymbolDirection @@ -50,6 +51,11 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) { val ignoreSystemWindowInsets = switch( R.string.ignore_system_window_insets, "ignore_system_window_insets", false ) + val keyboardHeightPercentBase = enumList( + R.string.keyboard_height_percent_base, + "keyboard_height_percent_base", + KeyboardHeightPercentBase.DisplayMetrics + ) } inner class Keyboard : ManagedPreferenceCategory(R.string.virtual_keyboard, sharedPreferences) { diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/InputView.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/InputView.kt index edec4564..261d8150 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/InputView.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/InputView.kt @@ -7,6 +7,7 @@ package org.fcitx.fcitx5.android.input import android.annotation.SuppressLint import android.content.res.Configuration +import android.graphics.Point import android.os.Build import android.view.View import android.view.WindowInsets @@ -31,6 +32,8 @@ import org.fcitx.fcitx5.android.input.broadcast.PunctuationComponent import org.fcitx.fcitx5.android.input.broadcast.ReturnKeyDrawableComponent import org.fcitx.fcitx5.android.input.candidates.horizontal.HorizontalCandidateComponent import org.fcitx.fcitx5.android.input.keyboard.CommonKeyActionListener +import org.fcitx.fcitx5.android.input.keyboard.KeyboardHeightPercentBase.DisplayMetrics +import org.fcitx.fcitx5.android.input.keyboard.KeyboardHeightPercentBase.RealSize import org.fcitx.fcitx5.android.input.keyboard.KeyboardWindow import org.fcitx.fcitx5.android.input.picker.emojiPicker import org.fcitx.fcitx5.android.input.picker.emoticonPicker @@ -39,6 +42,7 @@ import org.fcitx.fcitx5.android.input.popup.PopupComponent import org.fcitx.fcitx5.android.input.preedit.PreeditComponent import org.fcitx.fcitx5.android.input.wm.InputWindowManager import org.fcitx.fcitx5.android.utils.unset +import org.fcitx.fcitx5.android.utils.windowManager import org.mechdancer.dependency.DynamicScope import org.mechdancer.dependency.manager.wrapToUniqueComponent import org.mechdancer.dependency.plusAssign @@ -61,6 +65,7 @@ import splitties.views.dsl.core.matchParent import splitties.views.dsl.core.view import splitties.views.dsl.core.wrapContent import splitties.views.imageDrawable +import timber.log.Timber @SuppressLint("ViewConstructor") class InputView( @@ -136,6 +141,9 @@ class InputView( private val keyboardBottomPadding = keyboardPrefs.keyboardBottomPadding private val keyboardBottomPaddingLandscape = keyboardPrefs.keyboardBottomPaddingLandscape + private val advancedPrefs = AppPrefs.getInstance().advanced + private val keyboardHeightPercentBase = advancedPrefs.keyboardHeightPercentBase + private val keyboardSizePrefs = listOf( keyboardHeightPercent, keyboardHeightPercentLandscape, @@ -143,15 +151,29 @@ class InputView( keyboardSidePaddingLandscape, keyboardBottomPadding, keyboardBottomPaddingLandscape, + keyboardHeightPercentBase, ) private val keyboardHeightPx: Int get() { + val baseType = keyboardHeightPercentBase.getValue() + val base = when (baseType) { + DisplayMetrics -> resources.displayMetrics.heightPixels + RealSize -> Point().also { + @Suppress("DEPRECATION") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + context.display + } else { + context.windowManager.defaultDisplay + }.getRealSize(it) + }.y + } val percent = when (resources.configuration.orientation) { Configuration.ORIENTATION_LANDSCAPE -> keyboardHeightPercentLandscape else -> keyboardHeightPercent }.getValue() - return resources.displayMetrics.heightPixels * percent / 100 + Timber.d("keyboardHeightPx get(): baseType=${baseType}, base=${base}, percent=${percent}") + return base * percent / 100 } private val keyboardSidePaddingPx: Int @@ -255,6 +277,7 @@ class InputView( }) keyboardPrefs.registerOnChangeListener(onKeyboardSizeChangeListener) + advancedPrefs.registerOnChangeListener(onKeyboardSizeChangeListener) } private fun updateKeyboardSize() { @@ -360,6 +383,7 @@ class InputView( } override fun onDetachedFromWindow() { + advancedPrefs.unregisterOnChangeListener(onKeyboardSizeChangeListener) keyboardPrefs.unregisterOnChangeListener(onKeyboardSizeChangeListener) // clear DynamicScope, implies that InputView should not be attached again after detached. scope.clear() diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/keyboard/KeyboardHeightPercentBase.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/keyboard/KeyboardHeightPercentBase.kt new file mode 100644 index 00000000..719e32b2 --- /dev/null +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/keyboard/KeyboardHeightPercentBase.kt @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * SPDX-FileCopyrightText: Copyright 2026 Fcitx5 for Android Contributors + */ + +package org.fcitx.fcitx5.android.input.keyboard + +import org.fcitx.fcitx5.android.R +import org.fcitx.fcitx5.android.data.prefs.ManagedPreferenceEnum + +enum class KeyboardHeightPercentBase(override val stringRes: Int) : ManagedPreferenceEnum { + DisplayMetrics(R.string.display_metrics), + RealSize(R.string.real_size) +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d19fe469..fe1fd3a0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -318,4 +318,7 @@ Enable stroke for key border Preferred voice input EditText Playground + Keyboard height percent base + Display metrics (Resources.getDisplayMetrics) + Real size (Display.getRealSize)