abouttreesummaryrefslogcommitdiff
path: root/srcs/juloo.keyboard2/FoldStateTracker.java
diff options
context:
space:
mode:
authorMatej Drobnič2025-05-22 23:54:13 +0200
committerGitHub2025-05-22 23:54:13 +0200
commit97355881a855c5d2503f7e518c1e30fc03f88d4e (patch)
treef9abbdb522c1d4dfc478b6716430ef5afdceee0d /srcs/juloo.keyboard2/FoldStateTracker.java
parenta7312054b56ad3bdbc62d03c774b5942db9852e9 (diff)
downloadunexpected-keyboard-97355881a855c5d2503f7e518c1e30fc03f88d4e.tar.gz
unexpected-keyboard-97355881a855c5d2503f7e518c1e30fc03f88d4e.zip
Better support for foldable devices (#982)
* Add AndroidX WindowManager unfortunately, this seems to be the only way to get fold state, native Android APIs are internal. To add this, we need to update some dependencies, raise java version and raise compile SDK. * adds separate layouts and separate layout settings for folded and unfolded state of the device. The affected settings are: + the margin bottom settings + the horizontal margin settings + the keyboard height settings * Update shell.nix
Diffstat (limited to 'srcs/juloo.keyboard2/FoldStateTracker.java')
-rw-r--r--srcs/juloo.keyboard2/FoldStateTracker.java62
1 files changed, 62 insertions, 0 deletions
diff --git a/srcs/juloo.keyboard2/FoldStateTracker.java b/srcs/juloo.keyboard2/FoldStateTracker.java
new file mode 100644
index 0000000..60933c9
--- /dev/null
+++ b/srcs/juloo.keyboard2/FoldStateTracker.java
@@ -0,0 +1,62 @@
+package juloo.keyboard2;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import androidx.window.java.layout.WindowInfoTrackerCallbackAdapter;
+import androidx.window.layout.DisplayFeature;
+import androidx.window.layout.FoldingFeature;
+import androidx.window.layout.WindowInfoTracker;
+import androidx.window.layout.WindowLayoutInfo;
+
+import androidx.core.util.Consumer;
+
+
+public class FoldStateTracker {
+ private final Consumer<WindowLayoutInfo> _innerListener;
+ private final WindowInfoTrackerCallbackAdapter _windowInfoTracker;
+ private FoldingFeature _foldingFeature = null;
+ private Runnable _changedCallback = null;
+ public FoldStateTracker(Context context) {
+ _windowInfoTracker =
+ new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(context));
+ _innerListener = new LayoutStateChangeCallback();
+ _windowInfoTracker.addWindowLayoutInfoListener(context, Runnable::run, _innerListener);
+ }
+
+ public static boolean isFoldableDevice(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE);
+ }
+
+ public boolean isUnfolded() {
+ // FoldableFeature is only present when the device is unfolded. Otherwise, it's removed.
+ // A weird decision from Google, but that's how it works:
+ // https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:window/window/src/main/java/androidx/window/layout/adapter/sidecar/SidecarAdapter.kt;l=187?q=SidecarAdapter
+
+ return _foldingFeature != null;
+ }
+
+ public void close() {
+ _windowInfoTracker.removeWindowLayoutInfoListener(_innerListener);
+ }
+
+ public void setChangedCallback(Runnable _changedCallback) {
+ this._changedCallback = _changedCallback;
+ }
+
+ class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
+ @Override
+ public void accept(WindowLayoutInfo newLayoutInfo) {
+ FoldingFeature old = _foldingFeature;
+ _foldingFeature = null;
+ for (DisplayFeature feature: newLayoutInfo.getDisplayFeatures()) {
+ if (feature instanceof FoldingFeature) {
+ _foldingFeature = (FoldingFeature) feature;
+ }
+ }
+
+ if (old != _foldingFeature && _changedCallback != null) {
+ _changedCallback.run();
+ }
+ }
+ }
+}