Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@
# Directory _build is not used anymore
/_build
/release
/.opencode

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add these to your personal gitignore. I don't want to support dev environments in this file because it creates constant maintenance.

/openspec
5 changes: 5 additions & 0 deletions res/drawable/btn_floating_toggle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/ic_floating_toggle_selected"/>
<item android:drawable="@drawable/ic_floating_toggle"/>
</selector>
11 changes: 11 additions & 0 deletions res/drawable/ic_floating_toggle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- From materialdesignicons.com "keyboard", converted using android-studio -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorSubLabel"
android:pathData="M20,5H4A2,2 0 0,0 2,7V17A2,2 0 0,0 4,19H20A2,2 0 0,0 22,17V7A2,2 0 0,0 20,5M20,17H4V7H20V17M8,9V11H6V9H8M12,9V11H10V9H12M16,9V11H14V9H16M5,15H19V17H5V15Z"/>
</vector>
11 changes: 11 additions & 0 deletions res/drawable/ic_floating_toggle_selected.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- From materialdesignicons.com "keyboard", highlighted when floating mode is active -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorLabelActivated"
android:pathData="M20,5H4A2,2 0 0,0 2,7V17A2,2 0 0,0 4,19H20A2,2 0 0,0 22,17V7A2,2 0 0,0 20,5M20,17H4V7H20V17M8,9V11H6V9H8M12,9V11H10V9H12M16,9V11H14V9H16M5,15H19V17H5V15Z"/>
</vector>
2 changes: 2 additions & 0 deletions res/layout/keyboard.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:hardwareAccelerated="false" android:orientation="vertical" android:background="?attr/colorKeyboard">
<juloo.keyboard2.FloatingHandleView android:id="@+id/floating_handle" android:layout_width="match_parent" android:layout_height="24dp" android:visibility="gone"/>
<juloo.keyboard2.suggestions.CandidatesView android:id="@+id/candidates_view" style="@style/candidates_view">
<TextView android:id="@+id/candidates_emoji" style="@style/candidates_emoji"/>
<TextView android:id="@+id/candidates_left" style="@style/candidates_item"/>
<TextView android:id="@+id/candidates_middle" style="@style/candidates_item"/>
<TextView android:id="@+id/candidates_right" style="@style/candidates_item"/>
<Button android:id="@+id/dictionary_switch" style="@style/change_dictionary"/>
<Button android:id="@+id/floating_toggle" style="@style/change_dictionary" android:background="@drawable/btn_floating_toggle" android:contentDescription="@string/floating_toggle_description"/>
</juloo.keyboard2.suggestions.CandidatesView>
<juloo.keyboard2.Keyboard2View android:id="@+id/keyboard_view" android:layout_width="match_parent" android:layout_height="wrap_content"/>
</LinearLayout>
3 changes: 3 additions & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
<string name="pref_lock_double_tap_title">Double tap on shift for caps lock</string>
<string name="pref_lock_double_tap_summary">You can lock any modifier by holding it</string>
<string name="pref_category_behavior">Behavior</string>
<string name="pref_floating_keyboard_title">Floating keyboard</string>
<string name="pref_floating_keyboard_summary">Show the keyboard as a small movable window</string>
<string name="pref_autocapitalisation_title">Automatic capitalisation</string>
<string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string>
<string name="pref_change_method_key_replacement_title">Switching between input methods</string>
Expand Down Expand Up @@ -162,6 +164,7 @@
<string name="dictionaries_download_failed">Download failed: Please allow internet access</string>
<string name="candidates_status_click_to_install">Click to install a dictionary for %s</string>
<string name="dictionary_switcher_title">Change language</string>
<string name="floating_toggle_description">Toggle floating keyboard</string>
<string name="pref_physical_keyboard_behavior">When a physical keyboard is connected</string>
<string name="pref_physical_keyboard_behavior_hide">Hide everything</string>
<string name="pref_physical_keyboard_behavior_show">Show everything</string>
Expand Down
1 change: 1 addition & 0 deletions res/xml/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<ListPreference android:key="physical_keyboard_behavior" android:title="@string/pref_physical_keyboard_behavior" android:summary="%s" android:defaultValue="hide" android:entries="@array/pref_physical_keyboard_behavior_entries" android:entryValues="@array/pref_physical_keyboard_behavior_values"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_behavior">
<CheckBoxPreference android:key="floating_keyboard" android:title="@string/pref_floating_keyboard_title" android:summary="@string/pref_floating_keyboard_summary" android:defaultValue="false"/>
<CheckBoxPreference android:key="autocapitalisation" android:title="@string/pref_autocapitalisation_title" android:summary="@string/pref_autocapitalisation_summary" android:defaultValue="true"/>
<ListPreference android:key="change_method_key_replacement" android:title="@string/pref_change_method_key_replacement_title" android:summary="%s" android:entries="@array/pref_change_method_key_replacement_entries" android:entryValues="@array/pref_change_method_key_replacement_values" android:defaultValue="prev"/>
<CheckBoxPreference android:key="vibrate_custom" android:title="@string/pref_vibrate_custom" android:defaultValue="false"/>
Expand Down
48 changes: 48 additions & 0 deletions scripts/fix-ndk-arm64-host.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain a bit more ? I'm not sure this should live in the repo. Instead, you should distribute it to other aarch64 users separately.

#
# The official Android NDK only ships Linux x86_64 host toolchains and its
# ndk-build script rejects aarch64 hosts with:
# ERROR: Unknown host CPU architecture: aarch64
#
# On aarch64 Linux hosts with qemu-user binfmt enabled, the x86_64 toolchain
# runs fine transparently. This script patches the NDK's host detection so it
# uses the linux-x86_64 prebuilt directory on aarch64 hosts.
#
# Usage: scripts/fix-ndk-arm64-host.sh [NDK_PATH]
# NDK_PATH defaults to $ANDROID_HOME/ndk (all installed versions are patched).

set -euo pipefail

SCRIPT=$0
TARGET_LINE=' aarch64) HOST_ARCH=x86_64;;'
ANCHOR=' arm64) HOST_ARCH=arm64;;'

patch_ndk() {
local file=$1
if ! grep -qF 'aarch64) HOST_ARCH=x86_64;;' "$file"; then
sed -i "/$ANCHOR/a\\$TARGET_LINE" "$file"
echo "Patched $file"
else
echo "Already patched: $file"
fi
}

if [ $# -gt 0 ]; then
for ndk in "$@"; do
[ -f "$ndk/build/tools/ndk_bin_common.sh" ] && patch_ndk "$ndk/build/tools/ndk_bin_common.sh" \
|| echo "Skipping $ndk (not an NDK directory)"
done
exit 0
fi

if [ -z "${ANDROID_HOME:-}" ]; then
echo "ERROR: set ANDROID_HOME or pass an NDK path." >&2
exit 1
fi

if [ -d "$ANDROID_HOME/ndk" ]; then
shopt -s nullglob
for ndk in "$ANDROID_HOME"/ndk/*/; do
patch_ndk "$ndk/build/tools/ndk_bin_common.sh"
done
fi
11 changes: 11 additions & 0 deletions srcs/juloo.keyboard2/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ public final class Config
*/
public static final int WIDE_DEVICE_THRESHOLD = 600;

/** Ratio of the screen width used by the floating keyboard window. */
public static final float FLOATING_KEYBOARD_WIDTH_RATIO = 0.7f;
/** Maximum width of the floating keyboard window, in dp. */
public static final int FLOATING_KEYBOARD_MAX_WIDTH_DP = 700;
/** Height scale applied to the rows of the keyboard in floating mode. */
public static final float FLOATING_KEYBOARD_HEIGHT_SCALE = 0.75f;

private final SharedPreferences _prefs;

// From resources
Expand Down Expand Up @@ -76,6 +83,7 @@ public final class Config
public int clipboard_history_duration;
public boolean space_bar_auto_complete;
public boolean physical_keyboard_hide;
public boolean floating_keyboard;

// Dynamically set
/** Configuration options implied by the connected editor. */
Expand Down Expand Up @@ -180,7 +188,10 @@ public void refresh(Resources res, Boolean foldableUnfolded, Dictionaries dicts)
// The keyboard is keyboardHeightPercent of the screen height on 16/9
// screens (or less) and with a 3.95 high layout (in KeyboardData unit)
float base_height = Math.min(dm.heightPixels, dm.widthPixels * 16.f / 9.f);
floating_keyboard = _prefs.getBoolean("floating_keyboard", false);
keyboard_rows_height_pixels = (int)(base_height * keyboardHeightPercent / 395);
if (floating_keyboard)
keyboard_rows_height_pixels *= FLOATING_KEYBOARD_HEIGHT_SCALE;
horizontal_margin =
get_dip_pref_oriented(dm, "horizontal_margin", 3, 28);
double_tap_lock_shift = _prefs.getBoolean("lock_double_tap", false);
Expand Down
51 changes: 51 additions & 0 deletions srcs/juloo.keyboard2/FloatingHandleView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package juloo.keyboard2;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

/** A small grabber handle used to drag the floating keyboard window. */
public class FloatingHandleView extends View
{
private static final float HANDLE_WIDTH_DP = 32;
private static final float HANDLE_THICKNESS_DP = 3;
private static final float HANDLE_SPACING_DP = 6;
private static final int HANDLE_ALPHA = 120;

private final Paint _paint;

public FloatingHandleView(Context context, AttributeSet attrs)
{
super(context, attrs);
_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeCap(Paint.Cap.ROUND);
_paint.setStrokeWidth(dp(context, HANDLE_THICKNESS_DP));
TypedArray a = context.getTheme().obtainStyledAttributes(R.styleable.keyboard);
_paint.setColor(a.getColor(R.styleable.keyboard_colorLabel, 0));
a.recycle();
_paint.setAlpha(HANDLE_ALPHA);
}

@Override
protected void onDraw(Canvas canvas)
{
float width = dp(getContext(), HANDLE_WIDTH_DP);
float spacing = dp(getContext(), HANDLE_SPACING_DP);
float cx = getWidth() / 2.f;
float cy = getHeight() / 2.f;
for (int i = -1; i <= 1; i++)
{
float y = cy + i * spacing;
canvas.drawLine(cx - width / 2.f, y, cx + width / 2.f, y, _paint);
}
}

private static float dp(Context context, float value)
{
return value * context.getResources().getDisplayMetrics().density;
}
}
2 changes: 2 additions & 0 deletions srcs/juloo.keyboard2/KeyValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public static enum Event
SWITCH_VOICE_TYPING_CHOOSER,
HIDE_SELF,
CHANGE_DICTIONARY,
TOGGLE_FLOATING,
}

// Must be evaluated in the reverse order of their values.
Expand Down Expand Up @@ -663,6 +664,7 @@ public static KeyValue getSpecialKeyByName(String name)
case "complete_emoji": return statefulKey(Stateful.Complete_emoji);
case "hide_self": return eventKey("⊻", Event.HIDE_SELF, FLAG_SMALLER_FONT);
case "change_dictionary": return eventKey(0xE01D, Event.CHANGE_DICTIONARY, 0);
case "toggle_float": return eventKey("Float", Event.TOGGLE_FLOATING, FLAG_SMALLER_FONT);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You added an icon for the button in the status bar, so the key could use it too.
Add the (original) svg to srcs/special_font and run gradle buildKeyboardFont. The next available name is 01D.svg. I can run the build if the dependencies are a problem.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key should perhaps be called toggle_floating to be consistent with the event name. (or the opposite)


/* Key events */
case "esc": return keyeventKey("Esc", KeyEvent.KEYCODE_ESCAPE, FLAG_SMALLER_FONT);
Expand Down
Loading