diff --git a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java index 10b040cc2e..913a643a80 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java +++ b/android/KMAPro/kMAPro/src/main/java/com/keyman/android/SystemKeyboard.java @@ -218,9 +218,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven super.onComputeInsets(outInsets); // We should extend the touchable region so that Keyman sub keys menu can receive touch events outside the keyboard frame - WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); - Point size = new Point(0, 0); - wm.getDefaultDisplay().getSize(size); + Point size = KMManager.getWindowSize(getApplicationContext()); int inputViewHeight = 0; if (inputView != null) { diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java index 1de7decfe0..1e5231f521 100644 --- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java +++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java @@ -603,8 +603,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene if (resourceId > 0) statusBarHeight = getResources().getDimensionPixelSize(resourceId); - Point size = new Point(0, 0); - getWindowManager().getDefaultDisplay().getSize(size); + Point size = KMManager.getWindowSize(context); int screenHeight = size.y; Log.d(TAG, "Main resizeTextView bannerHeight: " + bannerHeight); textView.setHeight(screenHeight - statusBarHeight - actionBarHeight - bannerHeight - keyboardHeight); @@ -867,9 +866,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene } public static Drawable getActionBarDrawable(Context context) { - Point size = new Point(); - WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - wm.getDefaultDisplay().getSize(size); + Point size = KMManager.getWindowSize(context); int width = size.x; TypedValue outValue = new TypedValue(); diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java index 7d741feec0..bc7dfc5cc6 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java @@ -907,10 +907,7 @@ final class KMKeyboard extends WebView { rotateSuggestions.setClickable(false); // Compute the actual display position (offset coordinate by actual screen pos of kbd) - WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - DisplayMetrics metrics = new DisplayMetrics(); - wm.getDefaultDisplay().getMetrics(metrics); - float density = metrics.density; + float density = KMManager.getWindowDensity(context); int posX, posY; if (keyboardType == KeyboardType.KEYBOARD_TYPE_INAPP) { diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index e4edeb9d82..d1a40be69a 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -25,6 +25,8 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Point; import android.graphics.Typeface; import android.inputmethodservice.InputMethodService; import android.net.ConnectivityManager; @@ -32,6 +34,7 @@ import android.net.NetworkInfo; import android.os.Build; import android.os.IBinder; import android.text.InputType; +import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.Display; @@ -39,6 +42,7 @@ import android.view.Surface; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import android.view.WindowMetrics; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; @@ -2005,7 +2009,20 @@ public final class KMManager { } public static int getOrientation(Context context) { - Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + Display display; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // https://developer.android.com/reference/android/content/Context#getDisplay() + try { + display = context.getDisplay(); + } catch (UnsupportedOperationException e) { + // if the method is called on an instance that is not associated with any display. + return context.getResources().getConfiguration().orientation; + } + } else { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + // Deprecated in API 30 + display = wm.getDefaultDisplay(); + } int rotation = display.getRotation(); if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { return Configuration.ORIENTATION_PORTRAIT; @@ -2052,6 +2069,34 @@ public final class KMManager { } } + /** + * Get the size of the area the window would occupy. + * API 30+ + * https://developer.android.com/reference/android/view/WindowManager#getCurrentWindowMetrics() + * @param context + * @return Point (width, height) + */ + public static Point getWindowSize(Context context) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + // Deprecated in API 30 + Point size = new Point(0, 0); + wm.getDefaultDisplay().getSize(size); + return size; + } + + WindowMetrics windowMetrics = wm.getCurrentWindowMetrics(); + return new Point( + windowMetrics.getBounds().width(), + windowMetrics.getBounds().height()); + } + + public static float getWindowDensity(Context context) { + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + Log.d(TAG, "KMManager: metrics.density " + metrics.density); + return metrics.density; + } + protected static void setPersistentShouldShowHelpBubble(boolean flag) { SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMPopoverView.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMPopoverView.java index 498739c334..7dcbda5ffd 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMPopoverView.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMPopoverView.java @@ -10,6 +10,7 @@ import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; +import android.graphics.Point; import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; @@ -31,13 +32,11 @@ final class KMPopoverView extends View { public KMPopoverView(Context context, AttributeSet attrs) { super(context, attrs); - WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - DisplayMetrics metrics = new DisplayMetrics(); - wm.getDefaultDisplay().getMetrics(metrics); - density = metrics.density; + Point size = KMManager.getWindowSize(context); + density = KMManager.getWindowDensity(context); - viewWidth = metrics.widthPixels; - viewHeight = metrics.heightPixels; + viewWidth = size.x; + viewHeight = size.y; borderRadius = 6 * density; strokeWidth = 2.0f; bgColor = context.getResources().getColor(R.color.popup_bg); diff --git a/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java b/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java index e4ab04e50f..4ad462a76c 100644 --- a/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java +++ b/android/Samples/KMSample2/app/src/main/java/com/keyman/kmsample2/SystemKeyboard.java @@ -176,9 +176,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven super.onComputeInsets(outInsets); // We should extend the touchable region so that Keyman sub keys menu can receive touch events outside the keyboard frame - WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); - Point size = new Point(0, 0); - wm.getDefaultDisplay().getSize(size); + Point size = KMManager.getWindowSize(getApplicationContext()); int inputViewHeight = 0; if (inputView != null) diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md new file mode 100644 index 0000000000..adb4edc687 --- /dev/null +++ b/docs/minimum-versions.md @@ -0,0 +1,68 @@ +--- +title: Keyman Minimum Versions +--- + +Changes in [minimum-versions.inc.sh](minimum-versions.inc.sh) should manually be propagated to the linked help files below: + +## Keyman 18.0 + +Target Operating System and Platform Versions + +### Keyman for Windows + +Helpfile: [os.md](../../windows/src/desktop/help/common/os.md) + +### Keyman for macOS + +Helpfile: [requirements.md](../../mac/help/about/requirements.md) + +### Keyman for Linux + +Helpfile: [common/index.md](../../linux/help/common/index.md#q-what-linux-distros-will-keyman-work-with) + +### Keyman iPhone and iPad + +Helpfile: [system-requirements.md](../../ios/help/about/system-requirements.md) + +### Keyman for Android + +Helpfile: [system-requirements.md](../../android/help/about/system-requirements.md) + +---- + +## Product Build Documentation + +[linux-ubuntu.md](../../docs/build/linux-ubuntu.md) + +[macos.md](../../docs/build/macos.md) + +[windows.md](../../docs/build/windows.md) + +## Keyman Engine Documentation + +https://help.keyman.com/developer/engine/android/latest-version/ + +---- + +## minimum-versions.inc.sh Variables + +| KEYMAN Variable | Value | +|-----------------------------------|--------------| +| KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER | noble | +| KEYMAN_MAX_VERSION_EMSCRIPTEN | 3.1.58 | +| KEYMAN_MIN_TARGET_VERSION_ANDROID | 5 | +| KEYMAN_MIN_TARGET_VERSION_CHROME | 95.0 | +| KEYMAN_MIN_TARGET_VERSION_IOS | 12.2 | +| KEYMAN_MIN_TARGET_VERSION_MAC | 10.13 | +| KEYMAN_MIN_TARGET_VERSION_UBUNTU | 20.04 | +| KEYMAN_MIN_TARGET_VERSION_WINDOWS | 10 | +| KEYMAN_MIN_VERSION_ANDROID_SDK | 21 | +| KEYMAN_MIN_VERSION_CPP | 17 | +| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.44 | +| KEYMAN_MIN_VERSION_MESON | 1.0.0 | +| KEYMAN_MIN_VERSION_NODE_MAJOR | 18 | +| KEYMAN_MIN_VERSION_NPM | 10.5.1 | +| KEYMAN_MIN_VERSION_VISUAL_STUDIO | 2019 | +| KEYMAN_VERSION_JAVA | 11 | + +> ### This file is auto-generated by min-ver.sh. Do not modify diff --git a/docs/minimum-versions.md.in b/docs/minimum-versions.md.in new file mode 100644 index 0000000000..42d04b5987 --- /dev/null +++ b/docs/minimum-versions.md.in @@ -0,0 +1,45 @@ +--- +title: Keyman Minimum Versions +--- + +Changes in [minimum-versions.inc.sh](minimum-versions.inc.sh) should manually be propagated to the linked help files below: + +## Keyman 18.0 + +Target Operating System and Platform Versions + +### Keyman for Windows + +Helpfile: [os.md](../../windows/src/desktop/help/common/os.md) + +### Keyman for macOS + +Helpfile: [requirements.md](../../mac/help/about/requirements.md) + +### Keyman for Linux + +Helpfile: [common/index.md](../../linux/help/common/index.md#q-what-linux-distros-will-keyman-work-with) + +### Keyman iPhone and iPad + +Helpfile: [system-requirements.md](../../ios/help/about/system-requirements.md) + +### Keyman for Android + +Helpfile: [system-requirements.md](../../android/help/about/system-requirements.md) + +---- + +## Product Build Documentation + +[linux-ubuntu.md](../../docs/build/linux-ubuntu.md) + +[macos.md](../../docs/build/macos.md) + +[windows.md](../../docs/build/windows.md) + +## Keyman Engine Documentation + +https://help.keyman.com/developer/engine/android/latest-version/ + +---- diff --git a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java index b2842f00bc..f047bc6c78 100644 --- a/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java +++ b/oem/firstvoices/android/app/src/main/java/com/firstvoices/keyboards/SystemKeyboard.java @@ -202,13 +202,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven super.onComputeInsets(outInsets); // We should extend the touchable region so that Keyman sub keys menu can receive touch events outside the keyboard frame - WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); - if(wm == null) return; - Point size = new Point(0, 0); - Display display = wm.getDefaultDisplay(); - if(display == null) return; - - display.getSize(size); + Point size = KMManager.getWindowSize(getApplicationContext()); int inputViewHeight = 0; if (inputView != null) diff --git a/resources/build/publish-minimum-versions.sh b/resources/build/publish-minimum-versions.sh new file mode 100755 index 0000000000..e915b84b87 --- /dev/null +++ b/resources/build/publish-minimum-versions.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -e +set -u + +# +# Usage: publish-minimum-versions.sh +# +# Parses minimum-versions.inc.sh to update template file /docs/minimum-versions.md.in. +# If /docs/minimum-versions.md is changed, commit and push changes +# + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "${KEYMAN_ROOT}/resources/build/minimum-versions.inc.sh" + +function generate_table { + echo "" + echo "## minimum-versions.inc.sh Variables" + echo "" + echo "| KEYMAN Variable | Value |" + echo "|-----------------------------------|--------------|" + + # Get all the shell variables named KEYMAN*VERSION + strarr=( $(compgen -v KEYMAN | grep VERSION) ) + # echo "${strarr[@]}" + + for n in ${!strarr[@]}; do + echo "| ${strarr[n]} | ${!strarr[n]} |" + done + + echo "" + echo "> ### This file is auto-generated by min-ver.sh. Do not modify" +} + +cp "$KEYMAN_ROOT/docs/minimum-versions.md.in" "$KEYMAN_ROOT/docs/minimum-versions.md" +generate_table >> "$KEYMAN_ROOT/docs/minimum-versions.md"