Merge pull request #16382 from keymanapp/auto/A19S35-merge-base-into-web-core
Some checks are pending
Keyman Build Summary / Summarize build status checks (push) Waiting to run

auto: A19S35 merge master into web-core 🎼
This commit is contained in:
Marc Durdin 2026-08-18 15:39:33 +07:00 committed by GitHub
commit a650ca4ae8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
237 changed files with 5778 additions and 1780 deletions

View file

@ -1,5 +1,30 @@
# Keyman Version History
## 19.0.266 alpha 2026-08-13
* chore(deps-dev): bump esbuild from 0.25.0 to 0.28.1 (#16095)
* feat(web): add `keyman.versionInfo` API (#16351)
* fix(web): cleanup `loaduserinterface` and `unloaduserinterface` events (#16353)
* docs(web): deprecate unused and obsolete API endpoints and docs cleanup (#16354)
* chore(common): cleanup and merge Preprocessor constants (#14360)
## 19.0.265 alpha 2026-08-12
* fix(core): make coherence check a debug assert (#16343)
* feat(windows): honour Windows "metered connection" flag for downloading updates (#16099)
## 19.0.264 alpha 2026-08-11
* docs(android): update keyboardharness readme (#16220)
* feat(android): design improvement for settings, add dark mode and tool menu (#15827)
## 19.0.263 alpha 2026-08-10
* chore(deps): bump tar from 7.5.11 to 7.5.22 in /developer/src/server/src/win32/trayicon/addon-src (#16282)
* chore(deps): bump brace-expansion from 5.0.6 to 5.0.9 in /developer/src/server/src/win32/trayicon/addon-src (#16295)
* refactor(web): improve naming of `_SetTargetDir` function (#16311)
* docs(web): add language identifier to the code blocks of event docs (#16333)
## 19.0.262 alpha 2026-08-04
* chore(web): fire `keyboardloaded` event only once per keyboard (#16297)

View file

@ -1 +1 @@
19.0.263
19.0.267

View file

@ -17,21 +17,22 @@
https://support.google.com/googleplay/android-developer/answer/9214102#
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> -->
<application
android:name=".KeymanApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:theme="@style/AppTheme"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:resizeableActivity="false"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme"
android:supportsRtl="true">
android:supportsRtl="true"
>
<receiver android:name=".NetworkStateReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<!-- see the events from this app in sentry.keyman.com dashboard -->
<meta-data
android:name="io.sentry.dsn" android:value="https://2f067e5571a74974b9e210ca76ca9607@o1005580.ingest.sentry.io/5983520" />
@ -65,7 +66,7 @@
android:exported="true"
android:label="@string/app_name"
android:resizeableActivity="false"
android:theme="@style/AppTheme.BrandedLaunch">
android:theme="@style/Theme.App.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -241,23 +242,17 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/AppTheme.Light.Dialog"/>
<activity
android:name=".KeymanSettingsActivity"
android:label="@string/keyman_settings"
android:parentActivityName=".MainActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme.Base" />
android:theme="@style/AppTheme.Dialog"/>
<activity
android:name=".KeymanSettingsInstallActivity"
android:label="@string/app_name"
android:parentActivityName=".KeymanSettingsActivity"
android:parentActivityName=".MainActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme.Base" />
<activity
android:name=".KeymanSettingsLocalizeActivity"
android:label="@string/app_name"
android:parentActivityName=".KeymanSettingsActivity"
android:parentActivityName=".MainActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme.Base" />
<activity
@ -275,7 +270,7 @@
android:name=".KeyboardSettingsActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
android:label="@string/app_name"
android:theme="@style/AppTheme.Light.Dialog" />
android:theme="@style/AppTheme.Dialog" />
<activity
android:name=".SelectPackageActivity"
android:label="@string/app_name"

View file

@ -1,8 +1,18 @@
<!-- Custom banner theme -->
<div style="background: white; width: 100%; height: 100%; position: absolute; left: 0; top: 0; display: flex">
<style>
.keyman-banner { background: white; }
.keyman-banner.dark { background: #1e1e1e; }
.keyman-banner .logo-dark { display: none; }
.keyman-banner.dark .logo-light { display: none; }
.keyman-banner.dark .logo-dark { display: block; }
</style>
<div class="keyman-banner" style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; display: flex">
<!-- svg path is relative to assets/ folder -->
<img src="banner/keyman_banner.svg" style="height:60%; background: white; display: block; margin: auto 2%;">
<img class="logo-light" src="banner/keyman_banner.svg" style="height:60%; margin: auto 2%;">
<img class="logo-dark" src="banner/keyman_banner_dark.png" style="height:60%; margin: auto 2%;">
<!-- Tri-color line -->
<div style='height: 7%; left: 0; position: absolute; bottom: 0; width: 56%; background: #F68924'></div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

View file

@ -13,7 +13,7 @@ public class BannerController {
public static final String KM_BANNER_DIR = "banner";
public static final String KM_BANNER_THEME_KEYMAN = "banner.html";
public static void setHTMLBanner(Context context, KMManager.KeyboardType keyboardType) {
public static void setHTMLBanner(Context context, KMManager.KeyboardType keyboardType, boolean isDarkMode) {
if (keyboardType == KMManager.KeyboardType.KEYBOARD_TYPE_UNDEFINED) {
return;
}
@ -22,6 +22,9 @@ public class BannerController {
// Always use Keyman banner theme
String contents = FileUtils.readContents(context, KM_BANNER_THEME_KEYMAN);
if (isDarkMode) {
contents = contents.replace("class=\"keyman-banner\"", "class=\"keyman-banner dark\"");
}
KMManager.setHTMLBanner(keyboardType, contents);
KMManager.setBanner(keyboardType, KMManager.BannerType.HTML);
KMManager.showBanner(true);

View file

@ -7,7 +7,7 @@ package com.keyman.android;
import com.keyman.engine.util.DownloadFileUtils;
import com.tavultesoft.kmapro.BuildConfig;
import com.tavultesoft.kmapro.DefaultLanguageResource;
import com.tavultesoft.kmapro.KeymanSettingsActivity;
import com.tavultesoft.kmapro.KeymanSettingsKeys;
import com.tavultesoft.kmapro.PreferencesManager;
import com.keyman.engine.KMManager;
import com.keyman.engine.KMManager.KeyboardType;
@ -76,13 +76,13 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
KMManager.setInputMethodService(this); // for HW interface
SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
KMManager.SpacebarText spacebarText = KMManager.SpacebarText.fromString(prefs.getString(KeymanSettingsActivity.spacebarTextKey, KMManager.SpacebarText.LANGUAGE_KEYBOARD.toString()));
KMManager.SpacebarText spacebarText = KMManager.SpacebarText.fromString(prefs.getString(KeymanSettingsKeys.SPACEBAR_TEXT, KMManager.SpacebarText.LANGUAGE_KEYBOARD.toString()));
KMManager.setSpacebarText(spacebarText);
// Set the system keyboard HTML banner
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM);
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM, isDarkMode());
boolean mayHaveHapticFeedback = prefs.getBoolean(KeymanSettingsActivity.hapticFeedbackKey, false);
boolean mayHaveHapticFeedback = prefs.getBoolean(KeymanSettingsKeys.HAPTIC_FEEDBACK, false);
KMManager.setHapticFeedback(mayHaveHapticFeedback);
// Checking for updates should never be allowed to crash the keyboard.
@ -176,7 +176,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
if (KMManager.getPredictionsSuspended(KeyboardType.KEYBOARD_TYPE_SYSTEM)) {
KMManager.setBannerOptions(false);
// Set the system keyboard HTML banner
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM);
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM, isDarkMode());
} else if (KMManager.isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM)){
// Check if predictions needs to be re-enabled per Settings preference
Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(appContext);
@ -282,7 +282,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
@Override
public void onKeyboardChanged(String newKeyboard) {
// Refresh banner theme
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM);
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM, isDarkMode());
KMManager.showSystemKeyboard();
sendCurrentFontName();
}
@ -290,7 +290,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
@Override
public void onKeyboardShown() {
// Refresh banner theme
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM);
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM, isDarkMode());
}
@Override
@ -309,7 +309,7 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
Context context = getApplicationContext();
SharedPreferences prefs = context.getSharedPreferences(PreferencesManager.kma_prefs_name, Context.MODE_PRIVATE);
boolean showOSK = prefs.getBoolean(KeymanSettingsActivity.oskWithPhysicalKeyboardKey, false);
boolean showOSK = prefs.getBoolean(KeymanSettingsKeys.OSK_WITH_PHYSICAL_KEYBOARD, false);
return showOSK;
}
@ -349,4 +349,8 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
return interpreter.onKeyLongPress(keyCode, event);
}
private boolean isDarkMode() {
return (getResources().getConfiguration().uiMode &
Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}
}

View file

@ -16,7 +16,7 @@ import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.view.Window;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.CheckBox;
@ -24,7 +24,7 @@ import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageButton;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -36,14 +36,25 @@ public class GetStartedActivity extends BaseActivity {
private static ArrayList<HashMap<String, String>> list = null;
private static KMListAdapter listAdapter = null;
protected static final String showGetStartedKey = "ShowGetStarted";
public static final String openDefaultKeyboardPickerOnlyKey = "OpenDefaultKeyboardPickerOnly";
private final String iconKey = "icon";
private final String textKey = "text";
private final String isEnabledKey = "isEnabled";
private boolean openDefaultKeyboardPickerOnly = false;
private boolean didAutoOpenDefaultKeyboardPicker = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
openDefaultKeyboardPickerOnly = getIntent().getBooleanExtra(openDefaultKeyboardPickerOnlyKey, false);
if (openDefaultKeyboardPickerOnly) {
// Picker-only mode: intentionally skip rendering Get Started UI.
KMManager.dontCloseParentAppOnShowKeyboardPicker();
return;
}
final Context context = this;
setContentView(R.layout.get_started_list_layout);
@ -161,20 +172,40 @@ public class GetStartedActivity extends BaseActivity {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
if (openDefaultKeyboardPickerOnly) {
// When the user taps 'Set Default Keyboard' from the drawer,
// GetStartedActivity is launched in picker-only mode. But you
// can't open the system keyboard picker directly from a menu
// tap it requires a window with focus. So we use
// onWindowFocusChanged as the trigger point: first focus opens
// the picker, and when the user dismisses it and focus returns
// to this activity, we call finish() to close it. The activity
// is essentially just a invisible bridge to show the system
// picker.
if (!didAutoOpenDefaultKeyboardPicker) {
didAutoOpenDefaultKeyboardPicker = true;
InputMethodManager imManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imManager != null) {
imManager.showInputMethodPicker();
}
} else {
// Focus returned after the picker was dismissed, so close the host activity.
finish();
}
return;
}
// Enumerated steps are replaced with checkboxes when the user completes a step
String one = String.valueOf(R.drawable.ic_looks_one);
String two = String.valueOf(R.drawable.ic_looks_two);
String three = String.valueOf(R.drawable.ic_looks_three);
String checkbox_on = String.valueOf(android.R.drawable.checkbox_on_background);
String checkbox_on = String.valueOf(R.drawable.ic_checkbox);
String info = String.valueOf(R.drawable.ic_info_outline);
List<Keyboard> kbList = KMManager.getKeyboardsList(this);
@ -208,4 +239,12 @@ public class GetStartedActivity extends BaseActivity {
uncheckGetStartedIfComplete();
}
}
@Override
protected void onPause() {
super.onPause();
if (openDefaultKeyboardPickerOnly && didAutoOpenDefaultKeyboardPicker) {
finish();
}
}
}

View file

@ -81,7 +81,7 @@ public class KMPBrowserActivity extends BaseActivity {
}
setupEdgeToEdge(R.id.kmp_browser_layout);
setupStatusBarColors(R.color.complementary_5, android.R.color.white);
setupStatusBarColors(R.color.keyman_blue, android.R.color.white);
webView = (WebView) findViewById(R.id.kmpBrowserWebView);
webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);

View file

@ -96,7 +96,7 @@ public final class KeyboardSettingsActivity extends AppCompatActivity {
// Display notification to download update if available
if (kbd.hasUpdateAvailable()) {
hashMap.put(subtitleKey, context.getString(R.string.update_available, kbVersion));
icon = String.valueOf(R.drawable.ic_cloud_download);
icon = String.valueOf(R.drawable.ic_cloud_download_mode);
}
hashMap.put(iconKey, icon);
infoList.add(hashMap);
@ -105,7 +105,7 @@ public final class KeyboardSettingsActivity extends AppCompatActivity {
hashMap = new HashMap<>();
final String customHelpLink = kbd.getHelpLink();
// Check if app declared FileProvider
icon = String.valueOf(R.drawable.ic_action_forward);
icon = String.valueOf(R.drawable.ic_action_forward_mode);
// Don't show help link arrow if File Provider unavailable, or custom help doesn't exist
if ( (customHelpLink != null && !FileProviderUtils.exists(context)) ||
(customHelpLink == null && !packageID.equals(KMManager.KMDefault_UndefinedPackageID)) ) {

View file

@ -0,0 +1,25 @@
/*
* Keyman is copyright (C) SIL Global. MIT License.
*
* Created by MengchouChey on 2026-06-10
* Internship Program, 9th Feb - 27th Apr 2026
*
* This file is the Application class for Keyman, which is used to set the default night mode based on user preferences when the application starts.
*
*/
package com.tavultesoft.kmapro;
import android.app.Application;
import android.content.SharedPreferences;
import androidx.appcompat.app.AppCompatDelegate;
public class KeymanApplication extends Application {
@Override
public void onCreate() {
SharedPreferences prefs = getSharedPreferences("settings", MODE_PRIVATE);
int mode = prefs.getInt("theme_mode", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
AppCompatDelegate.setDefaultNightMode(mode);
super.onCreate();
}
}

View file

@ -1,53 +0,0 @@
package com.tavultesoft.kmapro;
import android.os.Bundle;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KMManager;
import androidx.appcompat.widget.Toolbar;
public class KeymanSettingsActivity extends BaseActivity {
protected static final String installedLanguagesKey = "InstalledLanguages";
protected static final String installKeyboardOrDictionaryKey = "InstallKeyboardOrDictionary";
protected static final String sendCrashReport = "SendCrashReport";
public static final String spacebarTextKey = "SpacebarText";
public static final String hapticFeedbackKey = "HapticFeedback";
public static final String oskWithPhysicalKeyboardKey = "ShowOSK";
protected KeymanSettingsFragment innerFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.keyman_settings_layout);
setupEdgeToEdge(R.id.keyman_settings_layout);
setupStatusBarColors(R.color.keyman_blue, android.R.color.white);
Toolbar toolbar = (Toolbar) findViewById(R.id.keyman_settings_toolbar);
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
toolbar.setTitle(R.string.keyman_settings);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(true);
}
innerFragment = (KeymanSettingsFragment) getSupportFragmentManager().findFragmentById(R.id.keyman_settings_fragment);
// For Keyman sites, disable keyboard picker task flag so keyboard picker doesn't dismiss Keyman app
KMManager.dontCloseParentAppOnShowKeyboardPicker();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus) {
innerFragment.update();
}
}
}

View file

@ -44,7 +44,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
getPreferenceManager().setSharedPreferencesName(getString(R.string.kma_prefs_name));
languagesPreference = new Preference(context);
languagesPreference.setKey(KeymanSettingsActivity.installedLanguagesKey);
languagesPreference.setKey(KeymanSettingsKeys.INSTALLED_LANGUAGES);
languagesPreference.setTitle(getInstalledLanguagesText());
languagesPreference.setWidgetLayoutResource(R.layout.preference_icon_layout);
Intent languagesIntent = new Intent(context, LanguagesSettingsActivity.class);
@ -52,7 +52,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
languagesPreference.setIntent(languagesIntent);
installKeyboardOrDictionary = new Preference(context);
installKeyboardOrDictionary.setKey(KeymanSettingsActivity.installKeyboardOrDictionaryKey);
installKeyboardOrDictionary.setKey(KeymanSettingsKeys.INSTALL_KEYBOARD_OR_DICTIONARY);
installKeyboardOrDictionary.setTitle(getString(R.string.install_keyboard_or_dictionary));
installKeyboardOrDictionary.setWidgetLayoutResource(R.layout.preference_add_icon_layout);
Intent installIntent = new Intent(context, KeymanSettingsInstallActivity.class);
@ -75,7 +75,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
};
setSystemKeyboardPreference = new CheckBoxPreference(context);
setSystemKeyboardPreference.setTitle(R.string.enable_system_keyboard);
setSystemKeyboardPreference.setTitle(R.string.system_keyboards);
setSystemKeyboardPreference.setSingleLineTitle(false);
setSystemKeyboardPreference.setDefaultValue(SystemIMESettings.isEnabledAsSystemKB(context));
setSystemKeyboardPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@ -120,7 +120,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
/* Spacebar Caption Preference */
spacebarTextPreference = new ListPreference(context);
spacebarTextPreference.setKey(KeymanSettingsActivity.spacebarTextKey);
spacebarTextPreference.setKey(KeymanSettingsKeys.SPACEBAR_TEXT);
spacebarTextPreference.setTitle(getString(R.string.spacebar_caption)); // getString(R.string.change_display_language));
@ -161,7 +161,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
});
SwitchPreference oskWithPhysicalKeyboardPreference = new SwitchPreference(context);
oskWithPhysicalKeyboardPreference.setKey(KeymanSettingsActivity.oskWithPhysicalKeyboardKey);
oskWithPhysicalKeyboardPreference.setKey(KeymanSettingsKeys.OSK_WITH_PHYSICAL_KEYBOARD);
oskWithPhysicalKeyboardPreference.setTitle(getString(R.string.show_osk));
oskWithPhysicalKeyboardPreference.setSummary(getString(R.string.show_osk_hint));
@ -169,7 +169,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
PreferencesManager.kma_prefs_name, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
boolean showOSK = prefs.getBoolean(
KeymanSettingsActivity.oskWithPhysicalKeyboardKey, false);
KeymanSettingsKeys.OSK_WITH_PHYSICAL_KEYBOARD, false);
oskWithPhysicalKeyboardPreference.setDefaultValue(showOSK);
oskWithPhysicalKeyboardPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@ -179,14 +179,14 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
return false;
}
editor.putBoolean(KeymanSettingsActivity.oskWithPhysicalKeyboardKey, (boolean)newValue);
editor.putBoolean(KeymanSettingsKeys.OSK_WITH_PHYSICAL_KEYBOARD, (boolean)newValue);
editor.commit();
return true;
}
});
SwitchPreference hapticFeedbackPreference = new SwitchPreference(context);
hapticFeedbackPreference.setKey(KeymanSettingsActivity.hapticFeedbackKey);
hapticFeedbackPreference.setKey(KeymanSettingsKeys.HAPTIC_FEEDBACK);
hapticFeedbackPreference.setTitle(getString(R.string.haptic_feedback));
hapticFeedbackPreference.setDefaultValue(false);
hapticFeedbackPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@ -212,7 +212,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
getStartedPreference.setDefaultValue(true);
SwitchPreference sendCrashReportPreference = new SwitchPreference(context);
sendCrashReportPreference.setKey(KeymanSettingsActivity.sendCrashReport);
sendCrashReportPreference.setKey(KeymanSettingsKeys.SEND_CRASH_REPORT);
sendCrashReportPreference.setTitle(getString(R.string.show_send_crash_report));
sendCrashReportPreference.setSummaryOn(getString(R.string.show_send_crash_report_on));
sendCrashReportPreference.setSummaryOff(getString(R.string.show_send_crash_report_off));

View file

@ -21,7 +21,6 @@ import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.os.Bundle;
import android.widget.SimpleAdapter;
import android.widget.TextView;
@ -71,13 +70,13 @@ public class KeymanSettingsInstallActivity extends BaseActivity {
final String noIcon = "0";
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(titleKey, getString(R.string.install_from_keyman_dot_com));
String icon = String.valueOf(R.drawable.ic_content_add);
String icon = String.valueOf(R.drawable.ic_content_add_mode);
hashMap.put(iconKey, icon);
installOptionList.add(hashMap);
hashMap = new HashMap<>();
hashMap.put(titleKey, getString(R.string.install_from_local_file));
icon = String.valueOf(R.drawable.ic_folder_open);
icon = String.valueOf(R.drawable.ic_folder_open_mode);
hashMap.put(iconKey, icon);
hashMap.put(isEnabledKey, "true");
installOptionList.add(hashMap);
@ -95,7 +94,7 @@ public class KeymanSettingsInstallActivity extends BaseActivity {
hashMap = new HashMap<>();
hashMap.put(titleKey, getString(R.string.add_languages_to_installed_keyboard));
hashMap.put(subtitleKey, getString(R.string.add_language_subtext));
icon = String.valueOf(R.drawable.ic_content_add);
icon = String.valueOf(R.drawable.ic_content_add_mode);
hashMap.put(iconKey, icon);
hashMap.put(isEnabledKey, "true");
installOptionList.add(hashMap);

View file

@ -0,0 +1,22 @@
/*
* Keyman is copyright (C) SIL Global. MIT License.
*
* Created by MengchouChey on 2026-06-10
* Internship Program, 9th Feb - 27th Apr 2026
*
* These are the keys used to replace KeymanSettingsActivity and KeymanSettingsFragment
*
*/
package com.tavultesoft.kmapro;
public final class KeymanSettingsKeys {
private KeymanSettingsKeys() {
}
public static final String INSTALLED_LANGUAGES = "InstalledLanguages";
public static final String INSTALL_KEYBOARD_OR_DICTIONARY = "InstallKeyboardOrDictionary";
public static final String SEND_CRASH_REPORT = "SendCrashReport";
public static final String SPACEBAR_TEXT = "SpacebarText";
public static final String HAPTIC_FEEDBACK = "HapticFeedback";
public static final String OSK_WITH_PHYSICAL_KEYBOARD = "ShowOSK";
}

View file

@ -153,7 +153,7 @@ public final class LanguageSettingsActivity extends BaseActivity {
updateActiveLexicalModel();
ImageView imageView = (ImageView) layout.findViewById(R.id.image1);
imageView.setImageResource(R.drawable.ic_action_forward);
imageView.setImageResource(R.drawable.ic_action_forward_mode);
layout.setEnabled(true);
layout.setOnClickListener(new View.OnClickListener() {
@Override
@ -333,7 +333,7 @@ public final class LanguageSettingsActivity extends BaseActivity {
}
holder.text.setText(kbd.getResourceName());
holder.img.setImageResource(R.drawable.ic_action_forward);
holder.img.setImageResource(R.drawable.ic_action_forward_mode);
return convertView;
}

View file

@ -205,7 +205,7 @@ public final class LanguagesSettingsActivity extends BaseActivity {
}
holder.textLang.setText(data.name);
holder.img.setImageResource(R.drawable.ic_action_forward);
holder.img.setImageResource(R.drawable.ic_action_forward_mode);
holder.textCount.setText(getContext().getResources().getQuantityString(R.plurals.keyboard_count, data.keyboards.size(), data.keyboards.size()));

View file

@ -6,7 +6,7 @@ package com.tavultesoft.kmapro;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -167,7 +167,7 @@ public final class SelectLanguageFragment extends Fragment implements BlockingSt
if (!excludeInstalledLanguages && !isInstallingPackage && KeyboardController.getInstance().keyboardExists(
k.getPackageID(), k.getKeyboardID(), k.getLanguageID())) {
// If Activity is listing an installed keyboard package, mark installed keyboards with a check
icon = String.valueOf(R.drawable.ic_check);
icon = String.valueOf(R.drawable.ic_check_mode);
enable = "false";
} else {
// Update title

View file

@ -83,7 +83,7 @@ public final class SelectPackageActivity extends BaseActivity {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(titleKey, keyboardName);
hashMap.put(subtitleKey, pkgID);
String icon = String.valueOf(R.drawable.ic_action_forward);
String icon = String.valueOf(R.drawable.ic_action_forward_mode);
hashMap.put(iconKey, icon);
list.add(hashMap);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/white" />
<corners android:radius="16dp" />
</shape>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/keyman_blue" />
</shape>

View file

@ -3,7 +3,7 @@
android:opacity="opaque">
<!-- background color -->
<item android:drawable="@android:color/white" />
<item android:drawable="@color/branded_logo_bg" />
<!-- product logos -->
<item
@ -21,4 +21,4 @@
<!-- Text will be overlayed by SplashScreenActivity -->
</layer-list>
</layer-list>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<!-- background color -->
<item android:drawable="@color/branded_logo_bg" />
<!-- product logos -->
<item
android:bottom="@dimen/product_logo_bottom"
>
<bitmap
android:src="@drawable/keyman_logo_splash_dark_mode"
android:gravity="center"/>
</item>
<item>
<bitmap
android:src="@drawable/sil_logo_color_tai_heritage_pro"
android:gravity="center"/>
</item>
<!-- Text will be overlayed by SplashScreenActivity -->
</layer-list>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_light_dialog_textsize_down"
android:tint="@android:color/black"
android:tint="@color/iconColor"
android:autoMirrored="true" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_navigation_forward"
android:tint="@color/iconColor"/>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_action_get_started"
android:tint="@color/iconColor"/>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_light_dialog_textsize_up"
android:tint="@android:color/black"
android:tint="@color/iconColor"
android:autoMirrored="true"/>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_light_action_info"
android:tint="@color/iconColor"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_action_overflow_mode_tinted"
android:insetLeft="4dp"
android:insetTop="4dp"
android:insetRight="4dp"
android:insetBottom="4dp" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_action_overflow_mode"
android:tint="@color/iconColor" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_light_action_share"
android:tint="@color/iconColor"/>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_light_action_textsize"
android:tint="@color/iconColor"/>

View file

@ -2,4 +2,4 @@
<path android:fillColor="@android:color/white" android:pathData="M16.24,7.76C15.07,6.59 13.54,6 12,6v6l-4.24,4.24c2.34,2.34 6.14,2.34 8.49,0 2.34,-2.34 2.34,-6.14 -0.01,-8.48zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
</vector>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_light_action_trash"
android:tint="@color/iconColor"/>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="@color/ms_white"
android:pathData="M15,21 Q14,21 14.5,22 L23,29 Q24,30 25,29 L33.5,22 Q34,21 33,21 Z" />
</vector>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_check"
android:tint="@color/iconColor"/>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<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="@color/iconColor"
android:pathData="M19,3H5c-1.1,0-2,0.9-2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2zM9,17l-5,-5 1.41,-1.41L9,14.17l9.59,-9.59L20,6l-11,11z"/>
</vector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_cloud_download"
android:tint="@color/iconColor">
</bitmap>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_content_add"
android:tint="@color/iconColor"/>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_folder_open"
android:tint="@color/iconColor"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<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="@android:color/white"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,880Q398,880 325,848.5Q252,817 197.5,762.5Q143,708 111.5,635Q80,562 80,480Q80,397 112.5,324Q145,251 200.5,197Q256,143 330,111.5Q404,80 488,80Q568,80 639,107.5Q710,135 763.5,183.5Q817,232 848.5,298.5Q880,365 880,442Q880,557 810,618.5Q740,680 640,680L566,680Q557,680 553.5,685Q550,690 550,696Q550,708 565,730.5Q580,753 580,782Q580,832 552.5,856Q525,880 480,880ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480ZM303,503Q320,486 320,460Q320,434 303,417Q286,400 260,400Q234,400 217,417Q200,434 200,460Q200,486 217,503Q234,520 260,520Q286,520 303,503ZM423,343Q440,326 440,300Q440,274 423,257Q406,240 380,240Q354,240 337,257Q320,274 320,300Q320,326 337,343Q354,360 380,360Q406,360 423,343ZM623,343Q640,326 640,300Q640,274 623,257Q606,240 580,240Q554,240 537,257Q520,274 520,300Q520,326 537,343Q554,360 580,360Q606,360 623,343ZM743,503Q760,486 760,460Q760,434 743,417Q726,400 700,400Q674,400 657,417Q640,434 640,460Q640,486 657,503Q674,520 700,520Q726,520 743,503ZM480,800Q489,800 494.5,795Q500,790 500,782Q500,768 485,749Q470,730 470,692Q470,650 499,625Q528,600 570,600L640,600Q706,600 753,561.5Q800,523 800,442Q800,321 707.5,240.5Q615,160 488,160Q352,160 256,253Q160,346 160,480Q160,613 253.5,706.5Q347,800 480,800Z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_settings"
android:tint="@color/iconColor"/>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- Warning triangle outline with exclamation mark -->
<path
android:fillColor="@android:color/transparent"
android:strokeColor="#000000"
android:strokeWidth="2"
android:strokeLineJoin="round"
android:strokeLineCap="round"
android:pathData="M12,2.5 L22,20.5 L2,20.5 Z" />
<!-- Exclamation mark - vertical bar -->
<path
android:fillColor="@android:color/transparent"
android:strokeColor="#000000"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M12,10 L12,15" />
<!-- Exclamation mark - dot -->
<path
android:fillColor="#000000"
android:strokeColor="#000000"
android:strokeWidth="1"
android:pathData="M12,18 m-1,0 a1,1 0 1,0 2,0 a1,1 0 1,0 -2,0" />
</vector>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/keyman_ic"
android:width="35dp"
android:height="28dp"
android:gravity="start|center_vertical"/>
<item
android:left="15dp"
android:right="15dp"
android:width="125dp"
android:height="28dp">
<bitmap
android:src="@drawable/keyman_text"
android:gravity="center_vertical"
android:tint="@color/iconColor"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- Outline of a long spacebar shape (for icon use) -->
<path
android:fillColor="@color/ms_black"
android:pathData="M2,11c0,-0.55 0.45,-1 1,-1h18c0.55,0 1,0.45 1,1v2c0,0.55 -0.45,1 -1,1H3c-0.55,0 -1,-0.45 -1,-1v-2z" />
<!-- Small center dot to indicate 'space' (optional) -->
<path
android:fillColor="@color/ms_black"
android:pathData="M12,12.5a0.5,0.5 0 1,1 0,-1a0.5,0.5 0 0,1 0,1z" />
</vector>

View file

@ -7,7 +7,11 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/titlebar" />
<include layout="@layout/titlebar"
android:id="@+id/titlebar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="@+id/adjust_instructions"
@ -18,6 +22,7 @@
android:layout_marginTop="8dp"
android:text="@string/adjust_keyboard_instructions"
android:textSize="@dimen/adjust_keyboard_height_label_textsize"
android:textColor="@color/main_text_color"
app:layout_constraintTop_toBottomOf="@id/titlebar" />
<androidx.constraintlayout.widget.ConstraintLayout

View file

@ -36,7 +36,8 @@
android:src="@drawable/ic_action_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/image_button_color" />
app:tint="@color/iconColor"
/>
<ImageButton
android:id="@+id/forward_button"
@ -59,7 +60,8 @@
android:layout_gravity="end"
android:contentDescription="@string/label_close"
android:src="@drawable/ic_action_close"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
app:tint="@color/iconColor"/>
</androidx.appcompat.widget.Toolbar>

View file

@ -1,42 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_above="@+id/KMKeyboard"
android:orientation="vertical"
android:background="@android:color/white"
tools:context=".MainActivity">
android:fitsSystemWindows="true">
<include layout="@layout/titlebar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
layout="@layout/check_chrome_webview_layout"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/titlebar"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/titlebar" />
android:layout_height="match_parent"
android:layout_above="@+id/KMKeyboard"
android:orientation="vertical"
android:background="@color/toolbarColor"
tools:context=".MainActivity"
android:fitsSystemWindows="true">
<com.keyman.engine.KMTextView
android:id="@+id/kmTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/checkWebViewChromeLayout"
android:background="@drawable/textview_bg"
android:ems="10"
android:gravity="top"
android:hint="@string/textview_hint"
android:inputType="textMultiLine|textNoSuggestions"
<include layout="@layout/titlebar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
layout="@layout/check_chrome_webview_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/titlebar"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/titlebar" />
<com.keyman.engine.KMTextView
android:id="@+id/kmTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/checkWebViewChromeLayout"
android:background="@drawable/textview_bg"
android:ems="10"
android:gravity="top"
android:hint="@string/textview_hint"
android:inputType="textMultiLine|textNoSuggestions"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="@id/checkWebViewChromeLayout">
<requestFocus />
</com.keyman.engine.KMTextView>
<LinearLayout
android:id="@+id/keyboardToolbarContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:visibility="gone"
android:padding="6dp"
android:background="@drawable/bg_keyboard_toolbar_container"
android:elevation="6dp"
android:outlineProvider="background"
app:layout_constraintBottom_toTopOf="@id/keyboardToolbarToggleButton"
app:layout_constraintStart_toStartOf="@id/keyboardToolbarToggleButton"
app:layout_constraintEnd_toEndOf="@id/keyboardToolbarToggleButton"
android:layout_marginBottom="8dp">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/keyboardToolbarShareButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginBottom="6dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_share"
android:padding="8dp"
app:srcCompat="@drawable/ic_light_action_share" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/keyboardToolbarTextSizeButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginBottom="6dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_text_size"
android:padding="8dp"
app:srcCompat="@drawable/ic_light_action_textsize" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/keyboardToolbarClearButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_clear_text"
android:padding="8dp"
app:srcCompat="@drawable/ic_light_action_trash" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/keyboardToolbarToggleButton"
android:layout_width="52dp"
android:layout_height="52dp"
android:visibility="gone"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:background="@drawable/bg_keyboard_toolbar_toggle"
android:contentDescription="@string/action_overflow"
android:padding="10dp"
android:elevation="10dp"
android:translationZ="3dp"
android:outlineProvider="background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_arrow_dropdown" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Sidebar — must be at the bottom of DrawerLayout -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:paddingHorizontal="10dp"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="@id/checkWebViewChromeLayout">
android:fadeScrollbars="false"
android:fitsSystemWindows="true"
app:itemTextAppearance="@style/NavigationDrawerItemText"
app:menu="@menu/nav_menu" />
<requestFocus />
</com.keyman.engine.KMTextView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.drawerlayout.widget.DrawerLayout>

View file

@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:layout_marginBottom="@dimen/activity_splash_bottom"
android:gravity="bottom"
android:orientation="vertical">
<!-- Overlay text fields below logos -->
<TextView
android:id="@+id/splash_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/splash_blank"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/activity_splash_textsize" />
<TextView
@ -21,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/splash_blank"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/activity_splash_textsize" />
</LinearLayout>
</LinearLayout>

View file

@ -3,20 +3,23 @@
android:id="@+id/checkWebViewChromeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:paddingVertical="4dp"
android:background="?android:attr/windowBackground"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- Banner to display if WebView is not installed/enabled or old version of Chrome installed -->
<TextView
android:id="@+id/kmWebViewChromeTextView"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/white"
android:gravity="start"
android:background="@android:color/transparent"
android:gravity="start|center_vertical"
android:layout_gravity="center_vertical"
android:text="@string/text_require_chrome_version"
android:layout_marginStart="@dimen/button_playstore_margin"
android:layout_marginEnd="@dimen/button_playstore_margin"
android:textSize="@dimen/update_chrome_label_textsize" />
<Button
@ -33,7 +36,9 @@
android:paddingEnd="@dimen/button_playstore_padding"
android:background="@color/ms_material_blue_500"
android:elevation="1dp"
android:singleLine="true"
android:minHeight="0dp"
android:singleLine="false"
android:maxLines="2"
android:text="@string/button_update_chrome"
android:textColor="@android:color/white"/>

View file

@ -11,7 +11,8 @@
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:padding="3dp"/>
<View
android:layout_width="match_parent"

View file

@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/left_icon"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/checkbox_margin"
android:layout_centerVertical="true"
android:contentDescription="@string/image_view" />
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/checkbox_margin"
android:layout_centerVertical="true"
android:contentDescription="@string/image_view"
app:tint="@color/iconColor"/>
<TextView
android:id="@+id/text"

View file

@ -18,8 +18,9 @@
android:layout_centerVertical="true"
android:contentDescription="@string/image_view"
android:paddingStart="0dp"
android:layout_marginStart="@dimen/checkbox_margin"
android:src="@drawable/ic_action_get_started" />
android:layout_marginStart="@dimen/checkbox_margin_left"
android:src="@drawable/ic_action_get_started"
app:tint="@color/iconColor"/>
<TextView
android:id="@+id/menu_title"
@ -39,7 +40,8 @@
android:layout_centerVertical="true"
android:layout_gravity="end"
android:contentDescription="@string/image_button"
android:src="@drawable/ic_action_close" />
android:src="@drawable/ic_action_close"
app:tint="@color/iconColor"/>
</androidx.appcompat.widget.Toolbar>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/list_item" >
<LinearLayout
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:orientation="vertical" >
<TextView
android:id="@+id/text1"
android:textColor="@color/iconColor"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:textSize="16sp" />
</LinearLayout>
<ImageView
android:id="@+id/image1"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="12dp"
android:contentDescription="@string/image_view"/>
</RelativeLayout>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:minHeight="48dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:focusable="false"
android:clickable="false">
<androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/nav_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:focusable="false"
android:clickable="true"
android:minWidth="32dp"
android:minHeight="32dp" />
</FrameLayout>

View file

@ -0,0 +1,10 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="2dp"
android:gravity="bottom"
android:padding="0dp"
android:orientation="vertical"
android:layout_marginBottom="2dp"
android:background="@color/keyman_orange">
</LinearLayout>

View file

@ -0,0 +1,19 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="bottom"
android:paddingVertical="10dp"
android:paddingHorizontal="5dp"
android:orientation="vertical"
android:layout_marginBottom="2dp"
>
<ImageView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:src="@drawable/keyman_logo_mode"
/>
</LinearLayout>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:minHeight="48dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:clickable="false"
android:focusable="false">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/nav_right_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:clickable="false"
android:focusable="false"
android:contentDescription="@null"
android:src="@drawable/ic_action_increment" />
</FrameLayout>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/nav_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:clickable="false"
android:minWidth="48dp"
android:minHeight="48dp" />

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_content_add" />
android:src="@drawable/ic_content_add"
app:tint="@color/iconColor"/>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_action_timelapse" />
android:src="@drawable/ic_action_timelapse"
app:tint="@color/iconColor"/>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_folder_open" />
android:src="@drawable/ic_folder_open"
app:tint="@color/iconColor"/>

View file

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_height" />
android:src="@drawable/ic_height" app:tint="@color/iconColor"/>
<ImageView
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_keyboard" />
android:src="@drawable/ic_keyboard" app:tint="@color/iconColor"/>
</LinearLayout>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_action_forward" />
android:src="@drawable/ic_action_forward" app:tint="@color/iconColor"/>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_translate" />
android:src="@drawable/ic_translate"
app:tint="@color/iconColor"/>

View file

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingBottom="25dp"
android:paddingTop="25dp" >
android:paddingTop="25dp">
<ImageButton
android:id="@+id/textSizeDownButton"
@ -15,7 +16,8 @@
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:contentDescription="@string/ic_text_size_down"
android:src="@drawable/textsize_decrease" />
android:src="@drawable/textsize_decrease"
app:tint="@color/iconColor"/>
<SeekBar
android:id="@+id/seekBar"
@ -32,6 +34,7 @@
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:contentDescription="@string/ic_text_size_up"
android:src="@drawable/textsize_increase" />
android:src="@drawable/textsize_increase"
app:tint="@color/iconColor"/>
</LinearLayout>

View file

@ -4,64 +4,10 @@
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item android:id="@+id/action_share"
app:showAsAction="always"
android:title="@string/action_share"
android:icon="@drawable/ic_light_action_share" />
<!-- Disable Web Browser to investigate Google sign-in -->
<!--item
android:id="@+id/action_web"
app:showAsAction="always"
android:title="@string/action_web"
android:icon="@drawable/ic_light_action_web" /> -->
<!-- Set showAsAction="never" for overflow -->
<item
android:id="@+id/action_overflow"
app:showAsAction="ifRoom"
android:title="@string/action_overflow"
android:icon="@drawable/ic_light_action_overflow" >
android:id="@+id/action_sidebar"
android:icon="@drawable/ic_action_overflow_mode_small"
android:title="@string/menu_title"
app:showAsAction="always" />
<menu>
<item
android:id="@+id/action_text_size"
android:title="@string/action_text_size"
app:showAsAction="always"
android:icon="@drawable/ic_light_action_textsize" />
<item
android:id="@+id/action_clear_text"
android:title="@string/action_clear_text"
app:showAsAction="always"
android:icon="@drawable/ic_light_action_trash" />
<item
android:id="@+id/action_info"
android:title="@string/action_info"
app:showAsAction="always"
android:icon="@drawable/ic_light_action_info" />
<item
android:id="@+id/action_get_started"
android:title="@string/get_started"
app:showAsAction="always"
android:icon="@drawable/ic_action_get_started" />
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
app:showAsAction="always"
android:icon="@drawable/ic_settings" />
<item
android:id="@+id/action_update_keyboards"
android:title="@string/action_install_updates"
app:showAsAction="always"
android:icon="@drawable/ic_cloud_download"
app:actionLayout="@layout/update_count_view"/>
</menu>
</item>
</menu>

View file

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item android:title="@string/keyboards_and_languages_title">
<menu>
<group android:id="@+id/nav_group_setup">
<item
android:id="@+id/nav_about_current_keyboard"
android:icon="@drawable/ic_keyboard"
android:title="@string/drawer_about_current_keyboard"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/nav_installed_languages"
android:icon="@drawable/ic_folder_open"
android:title="@string/drawer_menu_installed_languages"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/nav_install_keyboard"
android:icon="@drawable/ic_content_add"
android:title="@string/install_keyboard_or_dictionary"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/system_keyboards"
android:icon="@drawable/ic_keyboard_default"
android:title="@string/system_keyboards"
app:actionLayout="@layout/nav_right_icon_item" />
</group>
</menu>
</item>
<item android:title="@string/preferences_title">
<menu>
<group android:id="@+id/nav_group_preferences">
<item
android:id="@+id/action_get_started"
android:title="@string/get_started"
app:showAsAction="always"
android:icon="@drawable/ic_rocket" />
<item
android:id="@+id/nav_display_language"
android:icon="@drawable/ic_translate"
android:title="@string/change_display_language"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/nav_keyboard_height"
android:icon="@drawable/ic_height"
android:title="@string/adjust_keyboard_height"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/nav_longpress_delay"
android:icon="@drawable/ic_action_timelapse"
android:title="@string/adjust_longpress_delay"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/nav_spacebar_caption"
android:icon="@drawable/spacebar_key_bg"
android:title="@string/spacebar_caption" />
<item
android:id="@+id/nav_toggle_show_osk"
android:icon="@drawable/ic_keyboard_physical"
android:title="@string/show_osk"
app:actionLayout="@layout/nav_switch_item" />
<item
android:id="@+id/nav_toggle_send_crash_report"
android:icon="@drawable/ic_warning"
android:title="@string/show_send_crash_report"
app:actionLayout="@layout/nav_switch_item" />
<item
android:id="@+id/nav_palette"
android:icon="@drawable/ic_palette"
android:title="@string/theme" />
</group>
</menu>
</item>
<item android:title="@string/help_title">
<menu>
<group android:id="@+id/nav_group_help">
<item
android:id="@+id/nav_help"
android:icon="@drawable/ic_info_outline"
android:title="@string/drawer_menu_help"
app:actionLayout="@layout/nav_right_icon_item" />
<item
android:id="@+id/action_update_keyboards"
android:icon="@drawable/ic_cloud_download_mode"
android:title="@string/drawer_menu_update_keyboards" />
</group>
</menu>
</item>
</menu>

View file

@ -3,8 +3,27 @@
<!-- app_name removed in 16.0 beta. Set in build.gradle -->
<!-- Context: Menu Action -->
<string name="action_share" comment="Menu action to send text content to another app">Compartir</string>
<string name="drawer_open">Abrir el cajón de navegación</string>
<string name="drawer_close">Cerrar el cajón de navegación</string>
<string name="action_sidebar">Show sidebar menu</string>
<!-- Context: Menu Action -->
<string name="action_web" comment="Menu action to open Keyman browser">Navegador web</string>
<!-- Context: Keyman Settings menu titles -->
<string name="keyboards_and_languages_title" comment="Section title for Keyboards_and_Languages">Teclados e idiomas</string>
<string name="preferences_title" comment="Section title for Sidebar">Preferencias</string>
<string name="help_title" comment="Section title for Sidebar">Ayuda</string>
<!-- Context: Navigation drawer subtitles -->
<string name="drawer_subtitle_spacebar_caption" comment="Subtitle for Spacebar caption drawer item">Mostrar nombre del teclado en la barra espaciadora</string>
<string name="drawer_subtitle_show_osk" comment="Subtitle for Show On Screen Keyboard drawer item">Cuando se conecta el teclado físico</string>
<string name="drawer_subtitle_send_crash_report" comment="Subtitle for crash reporting drawer item">Permitir que se envíen los informes de errores al equipo Keyman</string>
<string name="drawer_subtitle_about" comment="Subtitle for About drawer item">Aprende cómo utilizar Keyman</string>
<string name="drawer_subtitle_about_current_keyboard" comment="Subtitle for current keyboard About drawer item">No hay teclado activo</string>
<string name="drawer_about_current_keyboard" comment="Title for current keyboard About drawer item">Acerca del teclado activo</string>
<string name="drawer_about_no_active_keyboard" comment="Fallback text when no active keyboard is selected">No hay teclado activo</string>
<string name="drawer_subtitle_theme" comment="Subtitle format for current theme setting">Configuración actual: %1$s</string>
<string name="drawer_subtitle_active_keyboard_help" comment="Subtitle for active keyboard help drawer item">Aprende cómo utilizar el %1$s </string>
<string name="drawer_title_active_keyboard_help" comment="Title for active keyboard help drawer item">Ayuda de %1$s</string>
<string name="drawer_title_active_keyboard_help_fallback" comment="Fallback title for active keyboard help drawer item">Ayuda de teclado activa</string>
<!-- Context: Menu Action -->
<string name="action_text_size" comment="Menu action to adjust text size">Tamaño del texto</string>
<!-- Context: Menu Action -->
@ -19,8 +38,11 @@
<string name="action_install_updates" comment="Menu notification that keyboard or dictionary updates available">Instalar actualizaciones</string>
<!-- Context: Title -->
<string name="title_version" comment="Title of Keyman for Android version">Versión: %1$s</string>
<!-- Context: Text label when old Chrome version installed -->
<string name="text_require_chrome_57" comment="Banner text when old version of Chrome is installed"> Keyman requiere Chrome versión 57 o posterior.</string>
<!-- Context: Text label when old Chrome version installed. Label replaced in Keyman 19.0 -->
<string name="text_require_chrome_57" comment="Banner text when old version of Chrome is installed">
Keyman requiere Chrome versión 57 o posterior.</string>
<string name="text_require_chrome_version" comment="Banner text when old version of Chrome is installed">
Keyman requiere Chrome versión %1$s o posterior.</string>
<!-- Context: Button label -->
<string name="button_update_chrome" comment="Prompt to upgrade Chrome in the Play Store">Actualizar Chrome</string>
<!-- Context: Textfield prompt (&#8230; is the ellipsis character "...") -->
@ -42,6 +64,8 @@
<!-- Context: Get Started menu -->
<string name="add_a_keyboard" comment="Menu item to add a keyboard">Agrega un teclado para tu idioma</string>
<!-- Context: Get Started menu -->
<string name="system_keyboards" comment="Menu item to open system keyboards">Teclados del sistema</string>
<!-- Context: Get Started menu -->
<string name="enable_system_keyboard" comment="Menu item to enable Keyman as system keyboard">Habilitar Keyman como teclado de sistema</string>
<!-- Context: Get Started menu -->
<string name="set_keyman_as_default" comment="Menu item to set Keyman as default system keyboard">Establecer teclado como teclado predeterminado</string>
@ -50,10 +74,13 @@
<!-- Context: Get Started menu -->
<string name="show_get_started" comment="Show the &quot;Get Started&quot; menu on startup">Mostrar \"%1$s\" al inicio</string>
<!-- Context: Android Storage Permission -->
<string name="request_storage_permission" comment="Request storage permission to access keyboard packages"> Para instalar los paquetes del teclado, permite que Keyman acceda al almacenamiento externo.</string>
<string name="request_storage_permission" comment="Request storage permission to access keyboard packages">
Para instalar los paquetes del teclado, permite que Keyman acceda al almacenamiento externo.</string>
<!-- Context: Android Storage Permission -->
<string name="storage_permission_denied" comment="Keyboard package installation may fail since Android storage permission not granted"> Se ha denegado la solicitud de permiso de almacenamiento. La instalación del paquete de teclado podría fallar</string>
<string name="storage_permission_denied2" comment="Keyboard package installation failed. Recommend install from local file"> Falló la solicitud de permiso de almacenamiento. Seleccione Configuración de Keyman - Instalar desde archivo local</string>
<string name="storage_permission_denied" comment="Keyboard package installation may fail since Android storage permission not granted">
Se ha denegado la solicitud de permiso de almacenamiento. La instalación del paquete de teclado podría fallar</string>
<string name="storage_permission_denied2" comment="Keyboard package installation failed. Recommend install from local file">
Falló la solicitud de permiso de almacenamiento. Seleccione Configuración de Keyman - Instalar desde archivo local</string>
<!-- Context: Keyman Settings menu -->
<string name="keyman_settings" comment="Settings menu title">Configuración</string>
<!-- Context: Keyman Settings menu -->
@ -87,6 +114,10 @@
<string name="spacebar_caption_hint_language_keyboard" comment="Spacebar caption hint - language + keyboard">Idioma y teclado en la barra espaciadora</string>
<!-- Context: Keyman Settings menu / Spacebar caption hint -->
<string name="spacebar_caption_hint_blank" comment="Spacebar caption hint - blank">No mostrar leyenda en la barra espaciadora</string>
<!-- Context: Keyman Settings menu / Show OSK with Physical Keyboard -->
<string name="show_osk" comment="show OSK when physical keyboard is connected">Mostrar el teclado en pantalla</string>
<!-- Context: Keyman Settings menu / Show OSK with Physical Keyboard hint -->
<string name="show_osk_hint" comment="When physical keyboard is connected">Cuando se conecta el teclado físico</string>
<!-- Context: Keyman Settings menu / Haptic feedback -->
<string name="haptic_feedback" comment="haptic feedback on key press">Vibrar al escribir</string>
<!-- Context: Keyman Settings menu. Removed in Keyman 18 -->
@ -96,11 +127,21 @@
<!-- Context: Keyman Settings menu. Removed in Keyman 18 -->
<string name="show_banner_off" comment="Description when toggle is off">Cuando está desactivado, solo se muestra cuando el texto predictivo está habilitado</string>
<!-- Context: Keyman Settings menu -->
<string name="show_send_crash_report" comment="permission for sending crash reports">Permitir el envío de informes de fallas a través de la red</string>
<string name="show_send_crash_report" comment="permission for sending crash reports">Informes de errores automáticos</string>
<!-- Context: Keyman Settings menu -->
<string name="show_send_crash_report_on" comment="Description when toggle is on">Cuando esté activado, se enviarán los informes de fallas</string>
<string name="show_send_crash_report_on" comment="Description when toggle is on">Permitir que se envíen los informes de errores al equipo Keyman</string>
<!-- Context: Keyman Settings menu -->
<string name="show_send_crash_report_off" comment="Description when toggle is off">Cuando esté desactivado, no se enviarán los informes de fallas</string>
<string name="show_send_crash_report_off" comment="Description when toggle is off">Los informes de error no se envían al equipo Keyman</string>
<!-- Context: Main drawer menu -->
<string name="drawer_menu_help" comment="Help drawer item title">Guía de usuario</string>
<string name="drawer_menu_update_keyboards" comment="Drawer action to update installed keyboards">Actualizar teclados</string>
<string name="drawer_menu_installed_languages" comment="Drawer title for installed languages item">Idiomas instalados</string>
<string name="drawer_menu_show_get_started" comment="Drawer title for get started startup option">Show &quot;Get Started&quot; on startup</string>
<string name="theme" comment="Menu title for theme settings">Tema</string>
<string name="theme_choose" comment="Dialog title for choosing app theme">Choose theme</string>
<string name="theme_dark_mode" comment="Theme option">Modo oscuro</string>
<string name="theme_light_mode" comment="Theme option">Modo claro</string>
<string name="theme_system_default" comment="Theme option">Predeterminada del sistema</string>
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
<string name="install_from_keyman_dot_com" comment="Install package from Keyman server">Instalar desde keyman.com</string>
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
@ -120,9 +161,11 @@
<!-- Context: Select Package and Select Languages menu -->
<string name="all_languages_installed" comment="Text when all languages from a keyboard package have been installed">Ya están instalados todos los idiomas</string>
<!-- Context: Adjust Keyboard Height menu -->
<string name="adjust_keyboard_instructions" comment="Instructions for adjusting keyboard height">Arrastra el teclado para ajustar la altura. Rota el dispositivo para ajustar el modo vertical y horizontal.</string>
<string name="adjust_keyboard_instructions" comment="Instructions for adjusting keyboard height">Arrastre el teclado para ajustar la altura. Gire el dispositivo para ajustar el modo vertical y horizontal.</string>
<!-- Context: Adjust Keyboard Height menu -->
<string name="reset_to_defaults" comment="Button to reset to default heights">Restaurar valores predeterminados</string>
<!-- Context: Keyboard height display format. %1$d = portrait percentage, %2$d = landscape percentage -->
<string name="keyboard_height_format" comment="Format for displaying keyboard height percentages">%1$d%% Modo vertical | %2$d%% Modo horizontal</string>
<!-- Context: Adjust Longpress Delay Time menu -->
<string name="longpress_delay_time" comment="Current longpress delay time (seconds)">Tiempo de retraso: %1$.1f segundos</string>
<!-- Context: Adjust Longpress Delay Time menu -->
@ -166,7 +209,10 @@
<!-- Context: KMP Package strings -->
<string name="invalid_metadata" comment="kmp.json metadata file is invalid or missing in package">Metadatos inválidos/ausentes en el paquete</string>
<!-- Context: KMP Package strings -->
<string name="minimum_keyboard_version_not_supported" comment="Notification when keyboard has functionality not supported by current Keyman"> El teclado requiere una versión más reciente de Keyman</string>
<string name="minimum_keyboard_version_not_supported" comment="Notification when keyboard has functionality not supported by current Keyman">
El teclado requiere una versión más reciente de Keyman</string>
<!-- Context: anywhere -->
<string name="unable_to_open_browser" comment="Notification when a browser activity cannot be launched">No se puede iniciar el navegador web</string>
<!-- Context: Menu title -->
<string name="menu_title" comment="Title for overflow/menu button">Menú</string>
</resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme.Base" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowLightStatusBar">false</item>
</style>
</resources>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="yellow_background">#131313</color>
<color name="iconColor">#FFFFFF</color>
<color name="toolbarColor">@color/ms_black</color>
<color name="menuBgColor">#212121</color>
<color name="checkboxTick">@color/ms_black</color>
<color name="activated_bg">#929396</color>
<color name="dialogBackground">#353535</color>
<color name="toolbar">@color/ms_black</color>
<color name="branded_logo_bg">@color/ms_black</color>
<color name="main_text_color">#FFFFFF</color>
</resources>

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="AppTheme.Base" />
<!--
Base application theme, dependent on API level. This theme is replaced
by AppTheme.Base from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppTheme.Base" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize the theme here -->
<item name="colorPrimary">@android:color/black</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">@android:color/black</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textColorPrimary">@android:color/white</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
<item name="android:windowBackground">#131313</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/black</item>
<!-- see values-night-v23/styles.xml: <item name="android:windowLightStatusBar">false</item> -->
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="actionOverflowMenuStyle">@style/AppTheme.PopupMenu</item>
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<style name="AppTheme.Dialog" parent="Theme.AppCompat.DayNight.Dialog">
<!-- Example overrides -->
<item name="colorPrimary">#424242</item>
<item name="colorPrimaryDark">#424242</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textColorPrimary">@android:color/white</item>
<item name="android:windowBackground">#424242</item>
</style>
<style name="Theme.App.Starting" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/branded_logo_dark_mode</item>
</style>
<style name="AppTheme.Toolbar" parent="Base.Widget.AppCompat.Toolbar">
<item name="android:colorPrimary">@android:color/white</item>
<item name="android:background">@android:color/white</item>
<item name="android:textColorPrimary">@android:color/black</item>
<item name="android:textColorSecondary">@android:color/black</item>
</style>
<style name="AppTheme.ToolbarBackArrow" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="colorControlNormal">@color/iconColor</item>
</style>
<style name="AppTheme.PopupMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="android:popupBackground">@color/menuBgColor</item>
</style>
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme.Base" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowLightStatusBar">true</item>
</style>
<style name="AppTheme.Toolbar" parent="Base.Widget.AppCompat.Toolbar">
<item name="android:windowLightStatusBar">true</item>
</style>
</resources>

View file

@ -13,17 +13,27 @@
<color name="complementary_4">#00735E</color>
<color name="complementary_5">#0AB8A0</color>
<color name="complementary_6">#79C3DA</color>
<color name="neutral_1">#000000</color>
<color name="neutral_1">#FFFFFF</color>
<color name="neutral_2">#6D6C6F</color>
<color name="neutral_3">#929396</color>
<color name="neutral_4">#C9CACA</color>
<color name="neutral_5">#DADDDC</color>
<color name="keyman_orange">@color/analagous_5</color>
<color name="keyman_red">@color/analagous_6</color>
<color name="keyman_blue">@color/complementary_6</color>
<color name="iconColor">#000</color>
<color name="toolbarColor">@color/neutral_1</color>
<color name="menuBgColor">@color/neutral_1</color>
<color name="checkboxTick">@color/neutral_2</color>
<color name="yellow_background">#FFFFFFCF</color>
<color name="branded_logo_bg">@color/neutral_1</color>
<color name="activated_bg">@color/complementary_1</color>
<color name="dialogBackground">#FFFFFF</color>
<color name="toolbar">@color/keyman_blue</color>
<color name="main_text_color">#000000</color>
</resources>

View file

@ -18,10 +18,12 @@
<dimen name="package_label_width">350dp</dimen>
<dimen name="keyman_bar_height">8dp</dimen>
<dimen name="checkbox_margin">8dp</dimen>
<dimen name="checkbox_margin_left">15dp</dimen>
<dimen name="checkbox_margin_left">19dp</dimen>
<dimen name="checkbox_padding">10dp</dimen>
<dimen name="preference_icon">32dp</dimen>
<dimen name="update_indicator_size">16dp</dimen>
<dimen name="update_indicator_bg_margin">0dp</dimen>
<dimen name="longpress_delay_label_textsize">24sp</dimen>
<dimen name="keyboard_toolbar_keyboard_gap">12dp</dimen>
<dimen name="keyboard_toolbar_container_bottom_margin">8dp</dimen>
</resources>

View file

@ -6,9 +6,34 @@
<!-- Context: Menu Action -->
<string name="action_share" comment="Menu action to send text content to another app">Share</string>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
<string name="action_sidebar">Show sidebar menu</string>
<!-- Context: Menu Action -->
<string name="action_web" comment="Menu action to open Keyman browser">Web Browser</string>
<!-- Context: Keyman Settings menu titles -->
<string name="keyboards_and_languages_title" comment="Section title for Keyboards_and_Languages">Keyboards and Languages</string>
<string name="preferences_title" comment="Section title for Sidebar">Preferences</string>
<string name="help_title" comment="Section title for Sidebar">Help</string>
<!-- Context: Navigation drawer subtitles -->
<string name="drawer_subtitle_spacebar_caption" comment="Subtitle for Spacebar caption drawer item">Show keyboard name on spacebar</string>
<string name="drawer_subtitle_show_osk" comment="Subtitle for Show On Screen Keyboard drawer item">When physical keyboard connected</string>
<string name="drawer_subtitle_send_crash_report" comment="Subtitle for crash reporting drawer item">Allow error reports to be sent to Keyman team</string>
<string name="drawer_subtitle_about" comment="Subtitle for About drawer item">Learn how to use Keyman</string>
<string name="drawer_subtitle_about_current_keyboard" comment="Subtitle for current keyboard About drawer item">No active keyboard</string>
<string name="drawer_about_current_keyboard" comment="Title for current keyboard About drawer item">About active keyboard</string>
<string name="drawer_about_no_active_keyboard" comment="Fallback text when no active keyboard is selected">No active keyboard</string>
<string name="drawer_subtitle_theme" comment="Subtitle format for current theme setting">Current setting: %1$s</string>
<string name="drawer_subtitle_active_keyboard_help" comment="Subtitle for active keyboard help drawer item">Learn how to use the %1$s </string>
<string name="drawer_title_active_keyboard_help" comment="Title for active keyboard help drawer item">%1$s help</string>
<string name="drawer_title_active_keyboard_help_fallback" comment="Fallback title for active keyboard help drawer item">Active keyboard help</string>
<!-- Context: Menu Action -->
<string name="action_text_size" comment="Menu action to adjust text size">Text Size</string>
@ -73,6 +98,9 @@
<!-- Context: Get Started menu -->
<string name="add_a_keyboard" comment="Menu item to add a keyboard">Add a keyboard for your language</string>
<!-- Context: Get Started menu -->
<string name="system_keyboards" comment="Menu item to open system keyboards">System keyboards</string>
<!-- Context: Get Started menu -->
<string name="enable_system_keyboard" comment="Menu item to enable Keyman as system keyboard">Enable Keyman as system-wide keyboard</string>
@ -102,12 +130,12 @@
<!-- Context: Keyman Settings menu -->
<plurals name="installed_languages">
<item quantity="zero">Installed languages</item>
<item quantity="one">Installed languages (%1$d)</item>
<item quantity="other">Installed languages (%1$d)</item>
</plurals>
<!-- Context: Keyman Settings menu -->
<string name="install_keyboard_or_dictionary" comment="Menu item to install keyboard or dictionary">Install Keyboard or Dictionary</string>
<string name="install_keyboard_or_dictionary" comment="Menu item to install keyboard or dictionary">Install keyboard or dictionary</string>
<!-- Context: Keyman Settings menu -->
<string name="change_display_language" comment="Menu action to change interface language">Display language</string>
@ -147,7 +175,7 @@
<string name="spacebar_caption_hint_blank" comment="Spacebar caption hint - blank">Do not show caption on spacebar</string>
<!-- Context: Keyman Settings menu / Show OSK with Physical Keyboard -->
<string name="show_osk" comment="show OSK when physical keyboard is connected">Show On-Screen Keyboard</string>
<string name="show_osk" comment="show OSK when physical keyboard is connected">Show on-screen keyboard</string>
<!-- Context: Keyman Settings menu / Show OSK with Physical Keyboard hint -->
<string name="show_osk_hint" comment="When physical keyboard is connected">When physical keyboard is connected</string>
@ -165,13 +193,24 @@
<string name="show_banner_off" comment="Description when toggle is off">When off, only shown when predictive text is enabled</string>
<!-- Context: Keyman Settings menu -->
<string name="show_send_crash_report" comment="permission for sending crash reports">Allow sending crash reports over network</string>
<string name="show_send_crash_report" comment="permission for sending crash reports">Automatic error reporting</string>
<!-- Context: Keyman Settings menu -->
<string name="show_send_crash_report_on" comment="Description when toggle is on">When on, crash reports will be sent</string>
<string name="show_send_crash_report_on" comment="Description when toggle is on">Allow error reports to be sent to Keyman team</string>
<!-- Context: Keyman Settings menu -->
<string name="show_send_crash_report_off" comment="Description when toggle is off">When off, crash reports won\'t be sent</string>
<string name="show_send_crash_report_off" comment="Description when toggle is off">Error reports are not sent to Keyman team</string>
<!-- Context: Main drawer menu -->
<string name="drawer_menu_help" comment="Help drawer item title">User guide</string>
<string name="drawer_menu_update_keyboards" comment="Drawer action to update installed keyboards">Update keyboards</string>
<string name="drawer_menu_installed_languages" comment="Drawer title for installed languages item">Installed languages</string>
<string name="drawer_menu_show_get_started" comment="Drawer title for get started startup option">Show &quot;Get Started&quot; on startup</string>
<string name="theme" comment="Menu title for theme settings">Theme</string>
<string name="theme_choose" comment="Dialog title for choosing app theme">Choose theme</string>
<string name="theme_dark_mode" comment="Theme option">Dark mode</string>
<string name="theme_light_mode" comment="Theme option">Light mode</string>
<string name="theme_system_default" comment="Theme option">System default</string>
<!-- Context: Keyman Settings "Install Keyboard or Dictionary" menu -->
<string name="install_from_keyman_dot_com" comment="Install package from Keyman server">Install from keyman.com</string>
@ -278,4 +317,7 @@
<!-- Context: anywhere -->
<string name="unable_to_open_browser" comment="Notification when a browser activity cannot be launched">Unable to launch web browser</string>
<!-- Context: Menu title -->
<string name="menu_title" comment="Title for overflow/menu button">Menu</string>
</resources>

View file

@ -6,7 +6,7 @@
Base application theme, dependent on API level. This theme is replaced
by AppTheme.Base from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppTheme.Base" parent="@style/Theme.AppCompat.Light.NoActionBar">
<style name="AppTheme.Base" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize the theme here -->
<item name="colorPrimary">@android:color/white</item>
<!-- colorPrimaryDark is used for the status bar -->
@ -16,9 +16,18 @@
<item name="android:textColorHint">@color/neutral_3</item>
<item name="android:textColorPrimary">@android:color/black</item>
<item name="actionOverflowMenuStyle">@style/AppTheme.PopupMenu</item>
<item name="popupMenuStyle">@style/AppTheme.PopupMenu</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
<item name="android:windowBackground">@android:color/white</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@color/toolbarColor</item>
<!-- see values-v23/styles.xml: <item name="android:windowLightStatusBar">true</item> -->
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
@ -27,7 +36,17 @@
</style>
<style name="AppTheme.BrandedLaunch" parent="Theme.AppCompat.NoActionBar">
<style name="AppTheme.Dialog" parent="AppTheme.Light.Dialog" />
<style name="Theme.App.Starting" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@android:color/white</item>
</style>
<style name="AppTheme.BrandedLaunchDark" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/branded_logo_dark_mode</item>
</style>
<style name="AppTheme.BrandedLaunchLight" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/branded_logo</item>
</style>
@ -36,6 +55,17 @@
<item name="android:background">@android:color/white</item>
<item name="android:textColorPrimary">@android:color/black</item>
<item name="android:textColorSecondary">@android:color/black</item>
<item name="android:statusBarColor">@color/toolbarColor</item>
<!-- see values-v23/styles.xml: <item name="android:windowLightStatusBar">true</item> -->
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
</style>
</resources>
<style name="AppTheme.PopupMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="android:popupBackground">@color/menuBgColor</item></style>
<style name="NavigationDrawerItemText" parent="TextAppearance.AppCompat.Body1">
<item name="android:singleLine">false</item>
<item name="android:maxLines">4</item>
<item name="android:ellipsize">end</item>
</style>
</resources>

View file

@ -61,7 +61,8 @@
<!-- Context: Keyboard Updates -->
<string name="update_available" comment="Currently installed version of a resource with an available update">%1$s (Actualización disponible)</string>
<!-- Context: Keyboard Updates -->
<string name="keyboard_update_message" comment="language name: keyboard name"> Actualizaciones disponibles para el teclado %1$s: %2$s </string>
<string name="keyboard_update_message" comment="language name: keyboard name">
Actualizaciones disponibles para el teclado %1$s: %2$s </string>
<!-- Context: Keyboard Updates -->
<string name="dictionary_update_message">Actualizaciones disponibles para el diccionario %1$s: %2$s </string>
<!-- Context: Keyboard Info and Keyboard Settings -->
@ -73,24 +74,30 @@
<!-- Context: Keyboard Info and Keyboard Settings -->
<string name="keyboard_picker_new_keyboard" comment="Mark a language name that's newly installed in keyboard list">[nuevo] %1$s</string>
<!-- Context: Keyboard Info and Keyboard Settings -->
<string name="keyboard_qr_code" comment="QR Code description"> Escanea este código par cargar este\nteclado en otro dispositivo</string>
<string name="keyboard_qr_code" comment="QR Code description">
Escanea este código par cargar este\nteclado en otro dispositivo</string>
<!-- Context: Keyboard Help welcome.htm title -->
<string name="welcome_package" comment="Title to welcome.htm page (name and version)">Bienvenido a %1$s</string>
<!-- Context: Keyboard app doesn't include FileProvider library needed to view help file -->
<string name="fileprovider_undefined" comment="FileProvider library needed to view help file"> Se necesita la librería FileProvider para ver el archivo de ayuda: %1$s</string>
<!-- Context: Fatal keyboard error. Will load default keyboard -->
<string name="fatal_keyboard_error" comment="Fatal keyboard error (keyboard ID::packageID for language). Will load default keyboard"> Error fatal del teclado con %1$s:%2$s para el idioma %3$s. Cargando teclado predeterminado.</string>
<string name="fileprovider_undefined" comment="FileProvider library needed to view help file">
Se necesita la librería FileProvider para ver el archivo de ayuda: %1$s</string>
<!-- Context: Fatal keyboard error. -->
<string name="fatal_keyboard_error" comment="Displays as a toast. Generally caused by a script error in keyboard view context, may be caused by keyboard or KeymanWeb.">
Keyman encountered an error and will restart</string>
<!-- Context: Alert Dialog body: System WebView not installed -->
<string name="body_install_webview" comment="Notification when WebView not installed"> Keyman requiere que WebView esté instalado.\"</string>
<string name="body_install_webview" comment="Notification when WebView not installed">
Keyman requiere que WebView esté instalado.\"</string>
<!-- Context: Alert Dialog body: System WebView installed but not enabled -->
<string name="body_enable_webview" comment="Notification when WebView installed but not enabled">Keyman requiere que WebView esté habilitado.\"</string>
<string name="body_enable_webview" comment="Notification when WebView installed but not enabled">
Keyman requiere que WebView esté habilitado.\"</string>
<!-- Context Button label: Install WebView -->
<string name="label_install_webview" comment="Button label to install webview">Instalar WebView</string>
<!-- Context Button label: Enable WebView -->
<string name="label_enable_webview" comment="Button label to enable webview">Habilitar WebView</string>
<!-- Context: Query for associated dictionary -->
<string name="query_associated_model" comment="Check if there's an available dictionary to download">Buscando diccionario asociado para descargar</string>
<string name="cannot_query_associated_model" comment="Cannot reach server to check if there's an available dictionary to download"> No se pudo conectar al servidor de Keyman para buscar un diccionario asociado para descargar</string>
<string name="cannot_query_associated_model" comment="Cannot reach server to check if there's an available dictionary to download">
No se pudo conectar al servidor de Keyman para buscar un diccionario asociado para descargar</string>
<!-- Context: Model Updates -->
<string name="confirm_download_model" comment="Confirmation to download a dictionary update">¿Quieres descargar la última versión de este diccionario?</string>
<!-- Context: No associated dictionary found -->
@ -100,7 +107,8 @@
<!-- Context: Background download messages-->
<string name="catalog_download_start_in_background" comment="Notification that the resource catalog update will begin">La actualización del catálogo inició en segundo plano</string>
<!-- Context: Background download messages-->
<string name="catalog_download_is_running_in_background" comment="Notification that the resource catalog update is still downloading"> El catálogo aún se está descargando; inténtalo de nuevo en un momento.</string>
<string name="catalog_download_is_running_in_background" comment="Notification that the resource catalog update is still downloading">
El catálogo aún se está descargando; inténtalo de nuevo en un momento.</string>
<!-- Context: Background download messages-->
<string name="progress_message_checking_resource_is_running" comment="Progress notification that the check for a resource is still running ">Buscando recurso</string>
<!-- Context: Background download messages-->

View file

@ -13,15 +13,9 @@ and consists of these engineering keyboards:
test9469.kmp is another engineering keyboard to show non-printing characters on the OSK.
### Compiling From Command Line
1. Launch a command prompt to the `android/` folder
2. Compile KMEA. This will build and copy `keyman-engine.aar` to the Samples and Test projects
```
cd KMEA
./build.sh
```
1. Launch a command prompt to the `android/Tests/KeyboardHarness` folder
3. Compile KeyboardHarness
```
cd ../Tests/KeyboardHarness
./build.sh
```

155
common/include/km_vkey.h Normal file
View file

@ -0,0 +1,155 @@
/*
* Keyman is copyright (C) SIL International. MIT License.
* Create Date: 2 Jul 2026
* Author: Sabine Schmitt
* VKCodes for keyman
*/
#pragma once
#define VK_LBUTTON 0x01
#define VK_RBUTTON 0x02
#define VK_CANCEL 0x03
#define VK_MBUTTON 0x04
#define VK_BACKSPACE 0x08
#define VK_BACK 0x08
#define VK_TAB 0x09
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D
#define VK_ENTER 0x0D
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define VK_KANA 0x15
#define VK_HANGEUL 0x15
#define VK_HANGUL 0x15
#define VK_IME_ON 0x16
#define VK_JUNJA 0x17
#define VK_FINAL 0x18
#define VK_HANJA 0x19
#define VK_KANJI 0x19
#define VK_IME_OFF 0x1A
#define VK_ESCAPE 0x1B
#define VK_CONVERT 0x1C
#define VK_NONCONVERT 0x1D
#define VK_ACCEPT 0x1E
#define VK_MODECHANGE 0x1F
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_KEY_0 0x30
#define VK_KEY_1 0x31
#define VK_KEY_2 0x32
#define VK_KEY_3 0x33
#define VK_KEY_4 0x34
#define VK_KEY_5 0x35
#define VK_KEY_6 0x36
#define VK_KEY_7 0x37
#define VK_KEY_8 0x38
#define VK_KEY_9 0x39
#define VK_KEY_A 0x41
#define VK_KEY_B 0x42
#define VK_KEY_C 0x43
#define VK_KEY_D 0x44
#define VK_KEY_E 0x45
#define VK_KEY_F 0x46
#define VK_KEY_G 0x47
#define VK_KEY_H 0x48
#define VK_KEY_I 0x49
#define VK_KEY_J 0x4A
#define VK_KEY_K 0x4B
#define VK_KEY_L 0x4C
#define VK_KEY_M 0x4D
#define VK_KEY_N 0x4E
#define VK_KEY_O 0x4F
#define VK_KEY_P 0x50
#define VK_KEY_Q 0x51
#define VK_KEY_R 0x52
#define VK_KEY_S 0x53
#define VK_KEY_T 0x54
#define VK_KEY_U 0x55
#define VK_KEY_V 0x56
#define VK_KEY_W 0x57
#define VK_KEY_X 0x58
#define VK_KEY_Y 0x59
#define VK_KEY_Z 0x5A
#define VK_NUMPAD0 0x60
#define VK_NUMPAD1 0x61
#define VK_NUMPAD2 0x62
#define VK_NUMPAD3 0x63
#define VK_NUMPAD4 0x64
#define VK_NUMPAD5 0x65
#define VK_NUMPAD6 0x66
#define VK_NUMPAD7 0x67
#define VK_NUMPAD8 0x68
#define VK_NUMPAD9 0x69
#define VK_NUMPAD_MULTIPLY 0x6A
#define VK_NUMPAD_ADD 0x6B
#define VK_NUMPAD_SUBTRACT 0x6D
#define VK_NUMPAD_DECIMAL 0x6E
#define VK_DECIMAL 0x6E
#define VK_NUMPAD_DIVIDE 0x6F
#define VK_DIVIDE 0x6F
#define VK_NUMLOCK 0x90
#define VK_LSHIFT 0xA0
#define VK_RSHIFT 0xA1
#define VK_LCONTROL 0xA2
#define VK_RCONTROL 0xA3
#define VK_LMENU 0xA4
#define VK_RMENU 0xA5
#define VK_OEM_1 0xBA
#define VK_COLON 0xBA
#define VK_SEMICOLON 0xBA
#define VK_OEM_PLUS 0xBB
#define VK_EQUAL 0xBB
#define VK_OEM_COMMA 0xBC
#define VK_COMMA 0xBC
#define VK_OEM_MINUS 0xBD
#define VK_HYPHEN 0xBD
#define VK_MINUS 0xBD
#define VK_OEM_PERIOD 0xBE
#define VK_PERIOD 0xBE
#define VK_OEM_2 0xBF
#define VK_SLASH 0xBF
#define VK_OEM_3 0xC0
#define VK_ACCENT 0xC0
#define VK_GRAVE 0xC0
#define VK_LEFT_BRACKET 0xDB
#define VK_LBRKT 0xDB
#define VK_OEM_4 0xDB
#define VK_BACKSLASH 0xDC
#define VK_BKSLASH 0xDC
#define VK_OEM_5 0xDC
#define VK_RIGHT_BRACKET 0xDD
#define VK_RBRKT 0xDD
#define VK_OEM_6 0xDD
#define VK_QUOTE 0xDE
#define VK_OEM_7 0xDE
#define VK_xDF 0xDF
#define VK_OEM_8 0xDF
#define VK_OEM_102 0xE2
#define VK_OEM_CLEAR 0xFE

View file

@ -42,8 +42,19 @@ export class KeymanSentryManager {
switch(location.protocol) {
case 'http:':
return 'http://' + location.host + '/' + filename;
case 'https:':
// Keyman for Android uses https://appassets.androidplatform.net
// to point to local files. See #16146.
if(this.keymanPlatform == 'android') {
return 'file:///' + filename;
} else {
return 'https://' + location.host + '/' + filename;
}
case 'file:':
return 'file:///' + filename;
// Used within the iOS Keyman engine. See #16136.
case 'keyman-engine:':
return 'file:///' + filename;
default:
return null;
}

View file

@ -103,6 +103,10 @@ bool km::core::action_item_list_to_actions_object(
break;
case KM_CORE_IT_PERSIST_OPT:
{
assert(action_items->option != nullptr);
if(action_items->option == nullptr) {
return false;
}
// TODO: lowpri: replace existing item if already present in options vector?
km::core::option opt(static_cast<km_core_option_scope>(action_items->option->scope),
action_items->option->key,

View file

@ -1,6 +1,7 @@
#pragma once
#include "keyman_core.h"
#include "km_vkey.h"
#if defined(_WIN32) || defined(_WIN64)
#define snprintf _snprintf

View file

@ -6,20 +6,6 @@ namespace km {
namespace core {
namespace kmx {
#define VK_SPACE 0x20
#define VK_COLON 0xBA
#define VK_EQUAL 0xBB
#define VK_COMMA 0xBC
#define VK_HYPHEN 0xBD
#define VK_PERIOD 0xBE
#define VK_SLASH 0xBF
#define VK_ACCENT 0xC0
#define VK_LBRKT 0xDB
#define VK_BKSLASH 0xDC
#define VK_RBRKT 0xDD
#define VK_QUOTE 0xDE
#define VK_xDF 0xDF
/**
* This maps an ASCII character corresponding to a US EN key cap to a
* Virtual Key and correctly sets the Shift BIT in the ShiftFlag DWORD.

View file

@ -6,7 +6,6 @@
using namespace km::core;
using namespace kmx;
static KMX_BOOL ContextItemsFromAppContext(KMX_WCHAR *buf, km_core_context_item** outPtr)
{
assert(buf);

View file

@ -45,12 +45,8 @@ actions::actions(actions const &other)
size_t opt_index = 0;
for (auto &item : *this) {
if (item.type == KM_CORE_IT_PERSIST_OPT) {
if (opt_index < _option_items_stack.size()) {
item.option = &_option_items_stack[opt_index++];
} else {
// no matching item in the stack; clear pointer.
item.option = nullptr;
}
assert(opt_index < _option_items_stack.size());
item.option = &_option_items_stack[opt_index++];
}
}
}

View file

@ -364,7 +364,12 @@ TEST(StateApiTests, TestStateApi) {
if (test_clone_2->actions().back().type == KM_CORE_IT_END) {
test_clone_2->actions().pop_back();
}
km_core_state_queue_action_items(test_clone_2, &action_clone);
km_core_action_item action_clone_queue[] = {
action_clone,
{KM_CORE_IT_END}
};
km_core_state_queue_action_items(test_clone_2, action_clone_queue);
test_clone_2->actions().commit();
km_core_action_item action_tp3 = {KM_CORE_IT_PERSIST_OPT, {0,}, };

View file

@ -7,6 +7,7 @@
#include <vector>
#include <codecvt>
#include <locale>
#include "../../../common/include/km_vkey.h"
BOOL LoadKeyboard(LPSTR fileName, LPKEYBOARD *lpKeyboard);
@ -600,21 +601,6 @@ void PrintTree(LPKEYBOARD kbd, GROUPTREE *t, int depth) {
}
}
// MapVirtualKeys is copied from syskbd.cpp (keyman32)
#define VK_COLON 0xBA
#define VK_EQUAL 0xBB
#define VK_COMMA 0xBC
#define VK_HYPHEN 0xBD
#define VK_PERIOD 0xBE
#define VK_SLASH 0xBF
#define VK_ACCENT 0xC0
#define VK_LBRKT 0xDB
#define VK_BKSLASH 0xDC
#define VK_RBRKT 0xDD
#define VK_QUOTE 0xDE
#define VK_xDF 0xDF
WCHAR MapVirtualKeys(WORD keyCode, UINT shiftFlags)
{
char shiftedDigit[] = ")!@#$%^&*(";

View file

@ -39,7 +39,7 @@
"@keymanapp/models-templates": "*",
"c8": "^7.12.0",
"chalk": "^2.4.2",
"esbuild": "^0.25.0"
"esbuild": "^0.28.1"
},
"mocha": {
"spec": "build/test/**/*.tests.js",

View file

@ -54,7 +54,7 @@
"devDependencies": {
"@sentry/cli": "^2.31.0",
"c8": "^7.12.0",
"esbuild": "^0.25.0",
"esbuild": "^0.28.1",
"typescript": "^5.4.5"
},
"mocha": {

Some files were not shown because too many files have changed in this diff Show more