diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a76585c..bee30c3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -10,11 +10,13 @@
-
+
+
+
diff --git a/res/layout/launcher_activity.xml b/res/layout/launcher_activity.xml
index 617c9ee..2273641 100644
--- a/res/layout/launcher_activity.xml
+++ b/res/layout/launcher_activity.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/res/values/styles.xml b/res/values/styles.xml
index bf4773d..f592cd7 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -80,4 +80,9 @@
- horizontal
+
diff --git a/res/values/values.xml b/res/values/values.xml
index b13296b..d506011 100644
--- a/res/values/values.xml
+++ b/res/values/values.xml
@@ -6,5 +6,9 @@
28dp
300dp
28dp
- false
+
+ 48dp
+
+ false
diff --git a/srcs/juloo.keyboard2/Config.java b/srcs/juloo.keyboard2/Config.java
index b28d2c0..9c31a6f 100644
--- a/srcs/juloo.keyboard2/Config.java
+++ b/srcs/juloo.keyboard2/Config.java
@@ -84,6 +84,7 @@ public final class Config
[get_current_layout()] and [set_current_layout()]. */
int current_layout_portrait;
int current_layout_landscape;
+ public int bottomInsetMin;
private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h)
{
@@ -187,6 +188,8 @@ public final class Config
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2"));
clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false);
+ bottomInsetMin = Utils.is_navigation_bar_gestural(res) ?
+ (int)res.getDimension(R.dimen.bottom_inset_min) : 0;
}
public int get_current_layout()
diff --git a/srcs/juloo.keyboard2/Keyboard2.java b/srcs/juloo.keyboard2/Keyboard2.java
index a68b954..201449d 100644
--- a/srcs/juloo.keyboard2/Keyboard2.java
+++ b/srcs/juloo.keyboard2/Keyboard2.java
@@ -292,6 +292,15 @@ public class Keyboard2 extends InputMethodService
private void updateSoftInputWindowLayoutParams() {
final Window window = getWindow().getWindow();
+ // On API >= 30, Keyboard2View behaves as edge-to-edge
+ if (VERSION.SDK_INT >= 30)
+ {
+ WindowManager.LayoutParams wattrs = window.getAttributes();
+ wattrs.layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ // Allow to draw behind system bars
+ wattrs.setFitInsetsTypes(0);
+ }
updateLayoutHeightOf(window, ViewGroup.LayoutParams.MATCH_PARENT);
final View inputArea = window.findViewById(android.R.id.inputArea);
diff --git a/srcs/juloo.keyboard2/Keyboard2View.java b/srcs/juloo.keyboard2/Keyboard2View.java
index 06ed677..a10dce6 100644
--- a/srcs/juloo.keyboard2/Keyboard2View.java
+++ b/srcs/juloo.keyboard2/Keyboard2View.java
@@ -42,7 +42,9 @@ public class Keyboard2View extends View
private Config _config;
private float _keyWidth;
- private float _bottomMargin;
+ private float _marginRight;
+ private float _marginLeft;
+ private float _marginBottom;
private Theme _theme;
@@ -232,7 +234,7 @@ public class Keyboard2View extends View
private KeyboardData.Key getKeyAtPosition(float tx, float ty)
{
KeyboardData.Row row = getRowAtPosition(ty);
- float x = _config.horizontal_margin;
+ float x = _marginLeft;
if (row == null || tx < x)
return null;
for (KeyboardData.Key key : row.keys)
@@ -256,28 +258,56 @@ public class Keyboard2View extends View
@Override
public void onMeasure(int wSpec, int hSpec)
{
- DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
- int width = dm.widthPixels;
- _bottomMargin = _config.margin_bottom;
- // Compatibility with display cutouts and navigation on the right
+ int width;
+ int insets_left = 0;
+ int insets_right = 0;
+ int insets_bottom = 0;
+ // LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS is set in [Keyboard2#updateSoftInputWindowLayoutParams].
+ // and keyboard is allowed do draw behind status/navigation bars
if (VERSION.SDK_INT >= 30)
{
WindowMetrics metrics =
((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE))
.getCurrentWindowMetrics();
- Insets insets = metrics.getWindowInsets().getInsetsIgnoringVisibility(
- WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars()
- | WindowInsets.Type.displayCutout());
- width = metrics.getBounds().width() - insets.right - insets.left;
- // Starting in API 35, keyboard window has LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ width = metrics.getBounds().width();
+ WindowInsets wi = metrics.getWindowInsets();
+ int insets_types =
+ WindowInsets.Type.statusBars()
+ | WindowInsets.Type.displayCutout()
+ | WindowInsets.Type.mandatorySystemGestures()
+ | WindowInsets.Type.navigationBars();
+ Insets insets = wi.getInsets(insets_types);
+ insets_left = insets.left;
+ insets_right = insets.right;
+ // On API 35, the keyboard is allowed to draw under the
+ // button-navigation bar but on lower APIs, it must be discounted from
+ // the width.
+ if (VERSION.SDK_INT < 35)
+ {
+ Insets nav_insets = wi.getInsets(WindowInsets.Type.navigationBars());
+ width -= nav_insets.left + nav_insets.right;
+ insets_left -= nav_insets.left;
+ insets_right -= nav_insets.right;
+ }
+ // [insets.bottom] doesn't take into account the buttons that appear in
+ // the gesture navigation bar when the IME is showing so ensure a minimum
+ // of margin is added.
if (VERSION.SDK_INT >= 35)
- _bottomMargin += insets.bottom;
+ insets_bottom = Math.max(insets.bottom, _config.bottomInsetMin);
+ }
+ else
+ {
+ DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
+ width = dm.widthPixels;
}
int height =
(int)(_config.keyHeight * _keyboard.keysHeight
- + _config.marginTop + _bottomMargin);
+ + _config.marginTop + _marginBottom);
setMeasuredDimension(width, height);
- _keyWidth = (width - (_config.horizontal_margin * 2)) / _keyboard.keysWidth;
+ _marginLeft = Math.max(_config.horizontal_margin, insets_left);
+ _marginRight = Math.max(_config.horizontal_margin, insets_right);
+ _marginBottom = _config.margin_bottom + insets_bottom;
+ _keyWidth = (width - _marginLeft - _marginRight) / _keyboard.keysWidth;
}
@Override
@@ -289,10 +319,10 @@ public class Keyboard2View extends View
{
// Disable the back-gesture on the keyboard area
Rect keyboard_area = new Rect(
- left + (int)_config.horizontal_margin,
+ left + (int)_marginLeft,
top + (int)_config.marginTop,
- right - (int)_config.horizontal_margin,
- bottom - (int)_bottomMargin);
+ right - (int)_marginRight,
+ bottom - (int)_marginBottom);
setSystemGestureExclusionRects(Arrays.asList(keyboard_area));
}
}
@@ -327,7 +357,7 @@ public class Keyboard2View extends View
for (KeyboardData.Row row : _keyboard.rows)
{
y += row.shift * _config.keyHeight;
- float x = _config.horizontal_margin + key_horizontal_margin / 2;
+ float x = _marginLeft + key_horizontal_margin / 2;
float keyH = row.height * _config.keyHeight - key_vertical_margin;
for (KeyboardData.Key k : row.keys)
{
diff --git a/srcs/juloo.keyboard2/Utils.java b/srcs/juloo.keyboard2/Utils.java
index f0f3036..88c865c 100644
--- a/srcs/juloo.keyboard2/Utils.java
+++ b/srcs/juloo.keyboard2/Utils.java
@@ -1,8 +1,13 @@
package juloo.keyboard2;
import android.app.AlertDialog;
+import android.content.res.Resources;
+import android.graphics.Insets;
+import android.os.Build.VERSION;
import android.os.IBinder;
+import android.view.View;
import android.view.Window;
+import android.view.WindowInsets;
import android.view.WindowManager;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -44,4 +49,14 @@ public final class Utils
out.append(buff, 0, l);
return out.toString();
}
+
+ /** Whether the thin gesture-navigation bar is used.
+ https://stackoverflow.com/questions/36514167/how-to-really-get-the-navigation-bar-height-in-android
+ */
+ public static boolean is_navigation_bar_gestural(Resources res)
+ {
+ // core/java/android/view/WindowManagerPolicyConstants.java
+ int res_id = res.getIdentifier("config_navBarInteractionMode", "integer", "android");
+ return (res_id > 0 && res.getInteger(res_id) == 2);
+ }
}