diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/DynamicGridKeyboard.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/DynamicGridKeyboard.java index 528c5f1ac..79fa46ba4 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/DynamicGridKeyboard.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/DynamicGridKeyboard.java @@ -76,6 +76,15 @@ final class DynamicGridKeyboard extends Keyboard { throw new RuntimeException("Can't find template key: code=" + code); } + public int getDynamicOccupiedHeight() { + final int row = (mGridKeys.size() - 1) / mColumnsNum + 1; + return row * mVerticalStep; + } + + public int getColumnsCount() { + return mColumnsNum; + } + public void addPendingKey(final Key usedKey) { synchronized (mLock) { mPendingKeys.addLast(usedKey); diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategory.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategory.java index a5dab8d2f..1a61ed984 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategory.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategory.java @@ -21,9 +21,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Paint; import android.graphics.Rect; -import android.os.Build; import android.util.Log; -import android.util.Pair; import androidx.core.graphics.PaintCompat; import org.dslul.openboard.inputmethod.keyboard.Key; @@ -56,6 +54,8 @@ final class EmojiCategory { private static final int ID_FLAGS = 9; private static final int ID_EMOTICONS = 10; + private static final int MAX_LINE_COUNT_PER_PAGE = 3; + public final class CategoryProperties { public final int mCategoryId; public final int mPageCount; @@ -119,7 +119,7 @@ final class EmojiCategory { private final SharedPreferences mPrefs; private final Resources mRes; - private final int mMaxPageKeyCount; + private final int mMaxRecentsKeyCount; private final KeyboardLayoutSet mLayoutSet; private final HashMap mCategoryNameToIdMap = new HashMap<>(); private final int[] mCategoryTabIconId = new int[sCategoryName.length]; @@ -134,7 +134,7 @@ final class EmojiCategory { final KeyboardLayoutSet layoutSet, final TypedArray emojiPaletteViewAttr) { mPrefs = prefs; mRes = res; - mMaxPageKeyCount = res.getInteger(R.integer.config_emoji_keyboard_max_page_key_count); + mMaxRecentsKeyCount = res.getInteger(R.integer.config_emoji_keyboard_max_recents_key_count); mLayoutSet = layoutSet; for (int i = 0; i < sCategoryName.length; ++i) { mCategoryNameToIdMap.put(sCategoryName[i], i); @@ -170,7 +170,7 @@ final class EmojiCategory { mCurrentCategoryId = defaultCategoryId; } - if (mCurrentCategoryPageId >= getCategoryPageCount(mCurrentCategoryId)) { + if (mCurrentCategoryPageId >= computeCategoryPageCount(mCurrentCategoryId)) { mCurrentCategoryPageId = 0; } } @@ -179,7 +179,7 @@ final class EmojiCategory { // Load a keyboard of categoryId getKeyboard(categoryId, 0 /* categoryPageId */); final CategoryProperties properties = - new CategoryProperties(categoryId, getCategoryPageCount(categoryId)); + new CategoryProperties(categoryId, computeCategoryPageCount(categoryId)); mShownCategories.add(properties); } @@ -217,11 +217,11 @@ final class EmojiCategory { return mCurrentCategoryId; } - public int getCurrentCategoryPageSize() { - return getCategoryPageSize(mCurrentCategoryId); + public int getCurrentCategoryPageCount() { + return getCategoryPageCount(mCurrentCategoryId); } - public int getCategoryPageSize(final int categoryId) { + public int getCategoryPageCount(final int categoryId) { for (final CategoryProperties prop : mShownCategories) { if (prop.mCategoryId == categoryId) { return prop.mPageCount; @@ -283,38 +283,21 @@ final class EmojiCategory { return getTabIdFromCategoryId(EmojiCategory.ID_RECENTS); } - private int getCategoryPageCount(final int categoryId) { + private int computeCategoryPageCount(final int categoryId) { final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); - return (keyboard.getSortedKeys().size() - 1) / mMaxPageKeyCount + 1; + return (keyboard.getSortedKeys().size() - 1) / computeMaxKeyCountPerPage() + 1; } - // Returns a pair of the category id and the category page id from the view pager's page - // position. The category page id is numbered in each category. And the view page position - // is the position of the current shown page in the view pager which contains all pages of - // all categories. - public Pair getCategoryIdAndPageIdFromPagePosition(final int position) { - int sum = 0; - for (final CategoryProperties properties : mShownCategories) { - final int temp = sum; - sum += properties.mPageCount; - if (sum > position) { - return new Pair<>(properties.mCategoryId, position - temp); - } + // Returns a keyboard from the recycler view's adapter position. + public DynamicGridKeyboard getKeyboardFromAdapterPosition(final int position) { + if (position >= 0 && position < getCurrentCategoryPageCount()) { + return getKeyboard(mCurrentCategoryId, position); } + Log.w(TAG, "invalid position for categoryId : " + mCurrentCategoryId); return null; } - // Returns a keyboard from the view pager's page position. - public DynamicGridKeyboard getKeyboardFromPagePosition(final int position) { - final Pair categoryAndId = - getCategoryIdAndPageIdFromPagePosition(position); - if (categoryAndId != null) { - return getKeyboard(categoryAndId.first, categoryAndId.second); - } - return null; - } - - private static final Long getCategoryKeyboardMapKey(final int categoryId, final int id) { + private static Long getCategoryKeyboardMapKey(final int categoryId, final int id) { return (((long) categoryId) << Integer.SIZE) | id; } @@ -328,19 +311,20 @@ final class EmojiCategory { if (categoryId == EmojiCategory.ID_RECENTS) { final DynamicGridKeyboard kbd = new DynamicGridKeyboard(mPrefs, mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), - mMaxPageKeyCount, categoryId); + mMaxRecentsKeyCount, categoryId); mCategoryKeyboardMap.put(categoryKeyboardMapKey, kbd); return kbd; } final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); - final Key[][] sortedKeys = sortKeysIntoPages( - keyboard.getSortedKeys(), mMaxPageKeyCount); - for (int pageId = 0; pageId < sortedKeys.length; ++pageId) { + final int keyCountPerPage = computeMaxKeyCountPerPage(); + final Key[][] sortedKeysPages = sortKeysGrouped( + keyboard.getSortedKeys(), keyCountPerPage); + for (int pageId = 0; pageId < sortedKeysPages.length; ++pageId) { final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs, mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), - mMaxPageKeyCount, categoryId); - for (final Key emojiKey : sortedKeys[pageId]) { + keyCountPerPage, categoryId); + for (final Key emojiKey : sortedKeysPages[pageId]) { if (emojiKey == null) { break; } @@ -353,37 +337,33 @@ final class EmojiCategory { } } - public int getTotalPageCountOfAllCategories() { - int sum = 0; - for (CategoryProperties properties : mShownCategories) { - sum += properties.mPageCount; - } - return sum; + private int computeMaxKeyCountPerPage() { + final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs, + mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), + 0, 0); + return MAX_LINE_COUNT_PER_PAGE * tempKeyboard.getColumnsCount(); } - private static Comparator EMOJI_KEY_COMPARATOR = new Comparator() { - @Override - public int compare(final Key lhs, final Key rhs) { - final Rect lHitBox = lhs.getHitBox(); - final Rect rHitBox = rhs.getHitBox(); - if (lHitBox.top < rHitBox.top) { - return -1; - } else if (lHitBox.top > rHitBox.top) { - return 1; - } - if (lHitBox.left < rHitBox.left) { - return -1; - } else if (lHitBox.left > rHitBox.left) { - return 1; - } - if (lhs.getCode() == rhs.getCode()) { - return 0; - } - return lhs.getCode() < rhs.getCode() ? -1 : 1; + private static final Comparator EMOJI_KEY_COMPARATOR = (lhs, rhs) -> { + final Rect lHitBox = lhs.getHitBox(); + final Rect rHitBox = rhs.getHitBox(); + if (lHitBox.top < rHitBox.top) { + return -1; + } else if (lHitBox.top > rHitBox.top) { + return 1; } + if (lHitBox.left < rHitBox.left) { + return -1; + } else if (lHitBox.left > rHitBox.left) { + return 1; + } + if (lhs.getCode() == rhs.getCode()) { + return 0; + } + return lhs.getCode() < rhs.getCode() ? -1 : 1; }; - private static Key[][] sortKeysIntoPages(final List inKeys, final int maxPageCount) { + private static Key[][] sortKeysGrouped(final List inKeys, final int maxPageCount) { final ArrayList keys = new ArrayList<>(inKeys); Collections.sort(keys, EMOJI_KEY_COMPARATOR); final int pageCount = (keys.size() - 1) / maxPageCount + 1; diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java index da2b21dac..27c06cf66 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java @@ -61,9 +61,9 @@ public final class EmojiCategoryPageIndicatorView extends View { final float height = getHeight(); final float width = getWidth(); final float unitWidth = width / mCategoryPageSize; - final float left = unitWidth * mCurrentCategoryPageId + mOffset * unitWidth; + final float left = Math.min(unitWidth * mCurrentCategoryPageId + mOffset * unitWidth, width - unitWidth); final float top = 0.0f; - final float right = left + unitWidth; + final float right = Math.min(left + unitWidth, width); final float bottom = height * BOTTOM_MARGIN_RATIO; canvas.drawRect(left, top, right, bottom, mPaint); } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiLayoutParams.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiLayoutParams.java index 431aa5ed1..607804c7b 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiLayoutParams.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiLayoutParams.java @@ -20,17 +20,16 @@ import android.content.res.Resources; import android.view.View; import android.widget.LinearLayout; +import androidx.recyclerview.widget.RecyclerView; import org.dslul.openboard.inputmethod.latin.R; +import org.dslul.openboard.inputmethod.latin.settings.SettingsValues; import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils; -import androidx.viewpager.widget.ViewPager; -import androidx.viewpager2.widget.ViewPager2; - final class EmojiLayoutParams { private static final int DEFAULT_KEYBOARD_ROWS = 4; - public final int mEmojiPagerHeight; - private final int mEmojiPagerBottomMargin; + public final int mEmojiListHeight; + private final int mEmojiListBottomMargin; public final int mEmojiKeyboardHeight; private final int mEmojiCategoryPageIdViewHeight; public final int mEmojiActionBarHeight; @@ -56,16 +55,16 @@ final class EmojiLayoutParams { + mKeyVerticalGap; mEmojiActionBarHeight = baseheight / DEFAULT_KEYBOARD_ROWS - (mKeyVerticalGap - mBottomPadding) / 2; - mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight + mEmojiListHeight = defaultKeyboardHeight - mEmojiActionBarHeight - mEmojiCategoryPageIdViewHeight; - mEmojiPagerBottomMargin = 0; - mEmojiKeyboardHeight = mEmojiPagerHeight - mEmojiPagerBottomMargin - 1; + mEmojiListBottomMargin = 0; + mEmojiKeyboardHeight = mEmojiListHeight - mEmojiListBottomMargin - 1; } - public void setPagerProperties(final ViewPager2 vp) { + public void setEmojiListProperties(final RecyclerView vp) { final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams(); lp.height = mEmojiKeyboardHeight; - lp.bottomMargin = mEmojiPagerBottomMargin; + lp.bottomMargin = mEmojiListBottomMargin; vp.setLayoutParams(lp); } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java index 7f228e449..cf11c1d54 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java @@ -113,6 +113,20 @@ final class EmojiPageKeyboardView extends KeyboardView implements mMoreKeysKeyboardContainer = inflater.inflate(moreKeysKeyboardLayoutId, null); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final Keyboard keyboard = getKeyboard(); + if (keyboard instanceof DynamicGridKeyboard) { + final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); + final int occupiedHeight = + ((DynamicGridKeyboard) keyboard).getDynamicOccupiedHeight(); + final int height = occupiedHeight + getPaddingTop() + getPaddingBottom(); + setMeasuredDimension(width, height); + return; + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + @Override public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { super.setHardwareAcceleratedDrawingEnabled(enabled); @@ -173,9 +187,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key); if (moreKeysKeyboard == null) { final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder( - getContext(), key, getKeyboard(), - true, key.getWidth(), key.getHeight(), // TODO This is cheating - newLabelPaint(key)); + getContext(), key, getKeyboard(), false, 0, 0, newLabelPaint(key)); moreKeysKeyboard = builder.build(); mMoreKeysKeyboardCache.put(key, moreKeysKeyboard); } @@ -382,9 +394,6 @@ final class EmojiPageKeyboardView extends KeyboardView implements final Runnable pendingKeyDown = mPendingKeyDown; final Key currentKey = mCurrentKey; releaseCurrentKey(false /* withKeyRegistering */); - if (key == null) { - return false; - } final boolean isShowingMoreKeysPanel = isShowingMoreKeysPanel(); if (isShowingMoreKeysPanel) { @@ -402,7 +411,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements callListenerOnReleaseKey(key, true /* withRegistering */); } }, KEY_RELEASE_DELAY_TIME); - } else { + } else if (key != null) { callListenerOnReleaseKey(key, true /* withRegistering */); } diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java index c34b3c7a7..ec59fc0db 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java @@ -182,7 +182,7 @@ final class EmojiPalettesAdapter extends RecyclerView.Adapter newPos = - mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position); - final int newCategoryId = newPos.first; - final int newCategorySize = mEmojiCategory.getCategoryPageSize(newCategoryId); - final int currentCategoryId = mEmojiCategory.getCurrentCategoryId(); - final int currentCategoryPageId = mEmojiCategory.getCurrentCategoryPageId(); - final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageSize(); - if (newCategoryId == currentCategoryId) { - mEmojiCategoryPageIndicatorView.setCategoryPageId( - newCategorySize, newPos.second, positionOffset); - } else if (newCategoryId > currentCategoryId) { - mEmojiCategoryPageIndicatorView.setCategoryPageId( - currentCategorySize, currentCategoryPageId, positionOffset); - } else if (newCategoryId < currentCategoryId) { - mEmojiCategoryPageIndicatorView.setCategoryPageId( - currentCategorySize, currentCategoryPageId, positionOffset - 1); - } - } - - @Override - public void onPageSelected(int position) { - final Pair newPos = - mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position); - setCurrentCategoryAndPageId(newPos.first /* categoryId */, newPos.second /* categoryPageId */, - false /* force */); - updateEmojiCategoryPageIdView(); - mCurrentPagerPosition = position; - } - - @Override - public void onPageScrollStateChanged(int state) { + public void onScrollStateChanged(@NonNull @NotNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); // Ignore this message. Only want the actual page selected. } + + @Override + public void onScrolled(@NonNull @NotNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + mEmojiPalettesAdapter.onPageScrolled(); + + final int offset = recyclerView.computeVerticalScrollOffset(); + final int extent = recyclerView.computeVerticalScrollExtent(); + final int range = recyclerView.computeVerticalScrollRange(); + final float percentage = offset / (float) (range - extent); + + final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageCount(); + final int a = (int) (percentage * currentCategorySize); + final float b = percentage * currentCategorySize - a; + mEmojiCategoryPageIndicatorView.setCategoryPageId( + currentCategorySize, a, b); + + final int firstCompleteVisibleBoard = mEmojiLayoutManager.findFirstCompletelyVisibleItemPosition(); + final int firstVisibleBoard = mEmojiLayoutManager.findFirstVisibleItemPosition(); + mEmojiCategory.setCurrentCategoryPageId( + firstCompleteVisibleBoard > 0 ? firstCompleteVisibleBoard : firstVisibleBoard); + } }); - mEmojiPager.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); - mEmojiPager.setPersistentDrawingCache(PERSISTENT_NO_CACHE); - mEmojiLayoutParams.setPagerProperties(mEmojiPager); + mEmojiRecyclerView.setPersistentDrawingCache(PERSISTENT_NO_CACHE); + mEmojiLayoutParams.setEmojiListProperties(mEmojiRecyclerView); mEmojiCategoryPageIndicatorView = findViewById(R.id.emoji_category_page_id_view); @@ -283,8 +279,10 @@ public final class EmojiPalettesView extends LinearLayout AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( Constants.CODE_UNSPECIFIED, this); final int categoryId = mEmojiCategory.getCategoryId(tabId); - setCurrentCategoryAndPageId(categoryId, 0, false /* force */); - updateEmojiCategoryPageIdView(); + if (categoryId != mEmojiCategory.getCurrentCategoryId()) { + setCurrentCategoryAndPageId(categoryId, 0, false /* force */); + updateEmojiCategoryPageIdView(); + } } /** @@ -388,14 +386,17 @@ public final class EmojiPalettesView extends LinearLayout final KeyDrawParams params = new KeyDrawParams(); params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr); setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params); - mEmojiPager.setAdapter(mEmojiPalettesAdapter); - mEmojiPager.setCurrentItem(mCurrentPagerPosition, false); + if (mEmojiRecyclerView.getAdapter() == null) { + mEmojiRecyclerView.setAdapter(mEmojiPalettesAdapter); + setCurrentCategoryAndPageId(mEmojiCategory.getCurrentCategoryId(), mEmojiCategory.getCurrentCategoryPageId(), + true /* force */); + } } public void stopEmojiPalettes() { mEmojiPalettesAdapter.releaseCurrentKey(true /* withKeyRegistering */); mEmojiPalettesAdapter.flushPendingRecentKeys(); - mEmojiPager.setAdapter(null); + mEmojiRecyclerView.setAdapter(null); } public void setKeyboardActionListener(final KeyboardActionListener listener) { @@ -408,19 +409,14 @@ public final class EmojiPalettesView extends LinearLayout return; } mEmojiCategoryPageIndicatorView.setCategoryPageId( - mEmojiCategory.getCurrentCategoryPageSize(), + mEmojiCategory.getCurrentCategoryPageCount(), mEmojiCategory.getCurrentCategoryPageId(), 0.0f /* offset */); } private void setCurrentCategoryAndPageId(final int categoryId, final int categoryPageId, final boolean force) { final int oldCategoryId = mEmojiCategory.getCurrentCategoryId(); - final int oldPageId = mEmojiCategory.getCurrentCategoryPageId(); - final boolean firstPage = categoryPageId == 0; - mEmojiCategory.setCurrentCategoryPageId(categoryPageId); - if (oldCategoryId == categoryId && (!firstPage || oldPageId == 0) && !force) { - return; - } + final int oldCategoryPageId = mEmojiCategory.getCurrentCategoryPageId(); if (oldCategoryId == EmojiCategory.ID_RECENTS && categoryId != EmojiCategory.ID_RECENTS) { // Needs to save pending updates for recent keys when we get out of the recents @@ -429,13 +425,11 @@ public final class EmojiPalettesView extends LinearLayout mEmojiPalettesAdapter.flushPendingRecentKeys(); } - mEmojiCategory.setCurrentCategoryId(categoryId); - final Pair pagerIds = mEmojiCategory.getCategoryIdAndPageIdFromPagePosition( - mEmojiPager.getCurrentItem()); - if (force || pagerIds.first != categoryId || (firstPage && pagerIds.second != 0)) { - final int newPagerPageId = mEmojiCategory.getPagerPageIdFromCategoryAndPageId(categoryId, categoryPageId); - final boolean smooth = pagerIds.first == categoryId && firstPage && pagerIds.second != 0; - mEmojiPager.setCurrentItem(newPagerPageId, smooth /* smoothScroll */); + if (force || oldCategoryId != categoryId || oldCategoryPageId != categoryPageId) { + mEmojiCategory.setCurrentCategoryId(categoryId); + mEmojiCategory.setCurrentCategoryPageId(categoryPageId); + mEmojiPalettesAdapter.notifyDataSetChanged(); + mEmojiRecyclerView.scrollToPosition(categoryPageId); } final int newTabId = mEmojiCategory.getTabIdFromCategoryId(categoryId); diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java index ac6c37f55..5e2430a4f 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -52,6 +52,7 @@ public final class KeyboardIconsSet { public static final String NAME_PREVIOUS_KEY = "previous_key"; public static final String NAME_TAB_KEY = "tab_key"; public static final String NAME_SHORTCUT_KEY = "shortcut_key"; + public static final String NAME_CLIPBOARD_KEY = "clipboard_key"; public static final String NAME_INCOGNITO_KEY = "incognito_key"; public static final String NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled"; public static final String NAME_LANGUAGE_SWITCH_KEY = "language_switch_key"; @@ -80,6 +81,7 @@ public final class KeyboardIconsSet { NAME_PREVIOUS_KEY, R.styleable.Keyboard_iconPreviousKey, NAME_TAB_KEY, R.styleable.Keyboard_iconTabKey, NAME_SHORTCUT_KEY, R.styleable.Keyboard_iconShortcutKey, + NAME_CLIPBOARD_KEY, R.styleable.Keyboard_iconClipboardKey, NAME_INCOGNITO_KEY, R.styleable.Keyboard_iconIncognitoKey, NAME_SPACE_KEY_FOR_NUMBER_LAYOUT, R.styleable.Keyboard_iconSpaceKeyForNumberLayout, NAME_SHIFT_KEY_SHIFTED, R.styleable.Keyboard_iconShiftKeyShifted, diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java index bb168e0df..1285380d0 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/LatinIME.java @@ -32,6 +32,7 @@ import android.os.Build; import android.os.Debug; import android.os.IBinder; import android.os.Message; +import android.os.Process; import android.text.InputType; import android.util.Log; import android.util.PrintWriterPrinter; @@ -186,6 +187,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } final HideSoftInputReceiver mHideSoftInputReceiver = new HideSoftInputReceiver(this); + final static class RestartAfterDeviceUnlockReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + // Restart the keyboard if credential encrypted storage is unlocked. This reloads the + // dictionary and other data from credential-encrypted storage (with the onCreate() + // method). + if (Intent.ACTION_USER_UNLOCKED.equals(action)) { + final int myPid = Process.myPid(); + Log.i(TAG, "Killing my process: pid=" + myPid); + Process.killProcess(myPid); + } else { + Log.e(TAG, "Unexpected intent " + intent); + } + } + } + final RestartAfterDeviceUnlockReceiver mRestartAfterDeviceUnlockReceiver = new RestartAfterDeviceUnlockReceiver(); + private AlertDialog mOptionsDialog; private final boolean mIsHardwareAcceleratedDrawingEnabled; @@ -625,6 +644,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen registerReceiver(mHideSoftInputReceiver, hideSoftInputFilter, PERMISSION_HIDE_SOFT_INPUT, null /* scheduler */); + final IntentFilter restartAfterUnlockFilter = new IntentFilter(); + restartAfterUnlockFilter.addAction(Intent.ACTION_USER_UNLOCKED); + registerReceiver(mRestartAfterDeviceUnlockReceiver, restartAfterUnlockFilter); + StatsUtils.onCreate(mSettings.getCurrent(), mRichImm); } @@ -733,6 +756,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen unregisterReceiver(mRingerModeChangeReceiver); unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver); + unregisterReceiver(mRestartAfterDeviceUnlockReceiver); mStatsUtilsManager.onDestroy(this /* context */); super.onDestroy(); } @@ -742,6 +766,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver); unregisterReceiver(mRingerModeChangeReceiver); + unregisterReceiver(mRestartAfterDeviceUnlockReceiver); mInputLogic.recycle(); } @@ -1092,6 +1117,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } + public CharSequence getSelection() { + return mInputLogic.mConnection.getSelectedText(0); + } + /** * This is called when the user has clicked on the extracted text view, * when running in fullscreen mode. The default implementation hides @@ -1559,10 +1588,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen currentSettingsValues.mInputAttributes.mShouldShowSuggestions && currentSettingsValues.isSuggestionsEnabledPerUserSettings(); final boolean shouldShowSuggestionsStripUnlessPassword = currentSettingsValues.mShowsVoiceInputKey + || currentSettingsValues.mShowsClipboardKey || shouldShowSuggestionCandidates || currentSettingsValues.isApplicationSpecifiedCompletionsOn(); final boolean shouldShowSuggestionsStrip = shouldShowSuggestionsStripUnlessPassword - && !currentSettingsValues.mInputAttributes.mIsPasswordField; + && (!currentSettingsValues.mInputAttributes.mIsPasswordField || currentSettingsValues.mShowsClipboardKey); mSuggestionStripView.updateVisibility(shouldShowSuggestionsStrip, isFullscreenMode()); if (!shouldShowSuggestionsStrip) { return; diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java index 3b1d47b06..6522d5d7e 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/Settings.java @@ -56,6 +56,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang // PREF_VOICE_MODE_OBSOLETE is obsolete. Use PREF_VOICE_INPUT_KEY instead. public static final String PREF_VOICE_MODE_OBSOLETE = "voice_mode"; public static final String PREF_VOICE_INPUT_KEY = "pref_voice_input_key"; + public static final String PREF_CLIPBOARD_CLIPBOARD_KEY = "pref_clipboard_clipboard_key"; public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary"; // PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE is obsolete. Use PREF_AUTO_CORRECTION instead. public static final String PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE = @@ -77,6 +78,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang "pref_show_language_switch_key"; public static final String PREF_SHOW_EMOJI_KEY = "pref_show_emoji_key"; + public static final String PREF_SHOW_CLIPBOARD_KEY = + "pref_show_clipboard_key"; public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST = "pref_include_other_imes_in_language_switch_list"; public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles"; diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java index db584fb86..3db4e2449 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/settings/SettingsValues.java @@ -73,6 +73,7 @@ public class SettingsValues { public final boolean mShowsHints; public final boolean mShowsLanguageSwitchKey; public final boolean mShowsEmojiKey; + public final boolean mShowsClipboardKey; public final boolean mUsePersonalizedDicts; public final boolean mUseDoubleSpacePeriod; public final boolean mBlockPotentiallyOffensive; @@ -149,6 +150,7 @@ public class SettingsValues { mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, true); mShowsLanguageSwitchKey = prefs.getBoolean(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, false); mShowsEmojiKey = prefs.getBoolean(Settings.PREF_SHOW_EMOJI_KEY, false); + mShowsClipboardKey = prefs.getBoolean(Settings.PREF_SHOW_CLIPBOARD_KEY, false); mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true); mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true) && inputAttributes.mIsGeneralTextInput; @@ -188,7 +190,8 @@ public class SettingsValues { //&& !mInputAttributes.mInputTypeNoAutoCorrect; mSuggestionsEnabledPerUserSettings = !mInputAttributes.mIsPasswordField && readSuggestionsEnabled(prefs); - mIncognitoModeEnabled = Settings.readAlwaysIncognitoMode(prefs) || mInputAttributes.mNoLearning; + mIncognitoModeEnabled = Settings.readAlwaysIncognitoMode(prefs) || mInputAttributes.mNoLearning + || mInputAttributes.mIsPasswordField; mIsInternal = Settings.isInternal(prefs); mHasCustomKeyPreviewAnimationParams = prefs.getBoolean( DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false); diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java index 2f2400de8..e2c1a2e0c 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/suggestions/SuggestionStripView.java @@ -16,6 +16,8 @@ package org.dslul.openboard.inputmethod.latin.suggestions; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -59,6 +61,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick public interface Listener { void pickSuggestionManually(SuggestedWordInfo word); void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); + void onTextInput(final String rawText); + CharSequence getSelection(); } static final boolean DBG = DebugFlags.DEBUG_ENABLED; @@ -66,6 +70,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private final ViewGroup mSuggestionsStrip; private final ImageButton mVoiceKey; + private final ImageButton mClipboardKey; private final ImageButton mOtherKey; MainKeyboardView mMainKeyboardView; @@ -126,6 +131,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mSuggestionsStrip = findViewById(R.id.suggestions_strip); mVoiceKey = findViewById(R.id.suggestions_strip_voice_key); + mClipboardKey = findViewById(R.id.suggestions_strip_clipboard_key); mOtherKey = findViewById(R.id.suggestions_strip_other_key); mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip); @@ -161,9 +167,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick R.styleable.Keyboard, defStyle, R.style.SuggestionStripView); final Drawable iconVoice = keyboardAttr.getDrawable(R.styleable.Keyboard_iconShortcutKey); final Drawable iconIncognito = keyboardAttr.getDrawable(R.styleable.Keyboard_iconIncognitoKey); + final Drawable iconClipboard = keyboardAttr.getDrawable(R.styleable.Keyboard_iconClipboardKey); keyboardAttr.recycle(); mVoiceKey.setImageDrawable(iconVoice); mVoiceKey.setOnClickListener(this); + mClipboardKey.setImageDrawable(iconClipboard); + mClipboardKey.setOnClickListener(this); + mClipboardKey.setOnLongClickListener(this); mOtherKey.setImageDrawable(iconIncognito); } @@ -181,7 +191,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick final int visibility = shouldBeVisible ? VISIBLE : (isFullscreenMode ? GONE : INVISIBLE); setVisibility(visibility); final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent(); - mVoiceKey.setVisibility(currentSettingsValues.mShowsVoiceInputKey ? VISIBLE : INVISIBLE); + mVoiceKey.setVisibility(currentSettingsValues.mShowsVoiceInputKey ? VISIBLE : GONE); + mClipboardKey.setVisibility(currentSettingsValues.mShowsClipboardKey ? VISIBLE : (mVoiceKey.getVisibility() == GONE ? INVISIBLE : GONE)); mOtherKey.setVisibility(currentSettingsValues.mIncognitoModeEnabled ? VISIBLE : INVISIBLE); } @@ -256,6 +267,23 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick @Override public boolean onLongClick(final View view) { + if (view == mClipboardKey) { + ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = clipboardManager.getPrimaryClip(); + if (clipData != null && clipData.getItemCount() > 0 && clipData.getItemAt(0) != null) { + String clipString = clipData.getItemAt(0).coerceToText(getContext()).toString(); + if (clipString.length() == 1) { + mListener.onTextInput(clipString); + } else if (clipString.length() > 1) { + //awkward workaround + mListener.onTextInput(clipString.substring(0, clipString.length() - 1)); + mListener.onTextInput(clipString.substring(clipString.length() - 1)); + } + } + AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( + Constants.NOT_A_CODE, this); + return true; + } AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( Constants.NOT_A_CODE, this); return showMoreSuggestions(); @@ -413,6 +441,15 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick false /* isKeyRepeat */); return; } + if (view == mClipboardKey) { + CharSequence selectionSequence = mListener.getSelection(); + if (selectionSequence != null && selectionSequence.length() > 0 + && !Settings.getInstance().getCurrent().mInputAttributes.mIsPasswordField) { + ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); + clipboardManager.setPrimaryClip(ClipData.newPlainText(selectionSequence, selectionSequence)); + } + return; + } final Object tag = view.getTag(); // {@link Integer} tag is set at diff --git a/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/DeviceProtectedUtils.java b/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/DeviceProtectedUtils.java index 02a2071c5..18e5d9457 100644 --- a/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/DeviceProtectedUtils.java +++ b/app/src/main/java/org/dslul/openboard/inputmethod/latin/utils/DeviceProtectedUtils.java @@ -18,14 +18,20 @@ package org.dslul.openboard.inputmethod.latin.utils; import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.preference.PreferenceManager; import android.util.Log; +import androidx.annotation.RequiresApi; + public final class DeviceProtectedUtils { static final String TAG = DeviceProtectedUtils.class.getSimpleName(); public static SharedPreferences getSharedPreferences(final Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + return PreferenceManager.getDefaultSharedPreferences(context); + } Context deviceProtectedContext = getDeviceProtectedContext(context); SharedPreferences deviceProtectedPreferences = PreferenceManager.getDefaultSharedPreferences(deviceProtectedContext); if (deviceProtectedPreferences.getAll().isEmpty()) { @@ -35,6 +41,7 @@ public final class DeviceProtectedUtils { return deviceProtectedPreferences; } + @RequiresApi(api = Build.VERSION_CODES.N) private static Context getDeviceProtectedContext(final Context context) { return context.isDeviceProtectedStorage() ? context : context.createDeviceProtectedStorageContext(); diff --git a/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_dark.xml index 87423ed3f..91c5994b7 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_light.xml index 00f64df4d..88a2581d2 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_activities_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_dark.xml index a3e02e298..e73842412 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_light.xml index fd956bc39..44ad007ea 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_animals_nature_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_dark.xml index 566b50227..b04d78b19 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_dark.xml @@ -20,13 +20,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_light.xml index 6110deb4e..6815c864b 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_emoticons_lxx_light.xml @@ -20,13 +20,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_dark.xml index caf950f04..4cc35ca7f 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_light.xml index 8d56e7d00..44c0f699a 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_flags_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_dark.xml index 99d38c0f3..e71cdce74 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_light.xml index cdf7f2e51..1edca1ce0 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_food_drink_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_dark.xml index c8b0f4213..8b204bdc0 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_light.xml index f119f982a..83bcbdd39 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_objects_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_dark.xml index b19d7c7cf..c5c8f7c6f 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_light.xml index ec6c90fac..f7fa2deea 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_people_body_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_dark.xml index 37f08a3e7..c05788f09 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_dark.xml @@ -19,13 +19,13 @@ --> - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_light.xml index d25bc744c..6428d4cf2 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_recents_lxx_light.xml @@ -19,13 +19,13 @@ --> - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_dark.xml index b2a6f5791..0dc871b71 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_light.xml index 9e7548f97..80b5d338e 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_smileys_emotion_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_dark.xml index c49764aa7..f3786fd2d 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_light.xml index d1ec28a27..35deba050 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_symbols_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_dark.xml b/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_dark.xml index 43eaf4520..79fa2bfc3 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_dark.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_dark.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_light.xml b/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_light.xml index 3127f4e01..238a138ce 100644 --- a/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_light.xml +++ b/app/src/main/res/drawable-v31/ic_emoji_travel_places_lxx_light.xml @@ -1,13 +1,13 @@ - + - + - + diff --git a/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_dark_system_accent.xml b/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_dark_system_accent.xml index 8f2ecefd1..96232f024 100644 --- a/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_dark_system_accent.xml +++ b/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_dark_system_accent.xml @@ -1,3 +1,3 @@ + android:src="@drawable/sym_keyboard_shift_locked_lxx_dark" android:tint="@color/icon_tint_system_accent_lxx_dark" /> diff --git a/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_light_system_accent.xml b/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_light_system_accent.xml index 9e84e1d1b..86f6dd0b9 100644 --- a/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_light_system_accent.xml +++ b/app/src/main/res/drawable-v31/sym_keyboard_shift_locked_lxx_light_system_accent.xml @@ -1,3 +1,3 @@ + android:src="@drawable/sym_keyboard_shift_locked_lxx_dark" android:tint="@color/icon_tint_system_accent_lxx_light" /> diff --git a/app/src/main/res/drawable/sym_keyboard_clipboard_dark.xml b/app/src/main/res/drawable/sym_keyboard_clipboard_dark.xml new file mode 100644 index 000000000..c5bd90c58 --- /dev/null +++ b/app/src/main/res/drawable/sym_keyboard_clipboard_dark.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/sym_keyboard_clipboard_light.xml b/app/src/main/res/drawable/sym_keyboard_clipboard_light.xml new file mode 100644 index 000000000..29fa0da12 --- /dev/null +++ b/app/src/main/res/drawable/sym_keyboard_clipboard_light.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/emoji_palettes_view.xml b/app/src/main/res/layout/emoji_palettes_view.xml index 4b4fb8a2d..0b65196a5 100644 --- a/app/src/main/res/layout/emoji_palettes_view.xml +++ b/app/src/main/res/layout/emoji_palettes_view.xml @@ -59,8 +59,8 @@ - diff --git a/app/src/main/res/layout/suggestions_strip.xml b/app/src/main/res/layout/suggestions_strip.xml index c6a412e39..7f98671b5 100644 --- a/app/src/main/res/layout/suggestions_strip.xml +++ b/app/src/main/res/layout/suggestions_strip.xml @@ -20,34 +20,45 @@ - - - - + android:soundEffectsEnabled="false"> + + + + + + + diff --git a/app/src/main/res/values-land/config.xml b/app/src/main/res/values-land/config.xml index 15e1bbb67..22b811329 100644 --- a/app/src/main/res/values-land/config.xml +++ b/app/src/main/res/values-land/config.xml @@ -77,8 +77,9 @@ 15dp - 10%p - 50%p - 54%p - 20 + 8.33%p + 40%p + 70%p + 70%p + 32 diff --git a/app/src/main/res/values-sw600dp-land/config.xml b/app/src/main/res/values-sw600dp-land/config.xml index d33af2e37..4410c191b 100644 --- a/app/src/main/res/values-sw600dp-land/config.xml +++ b/app/src/main/res/values-sw600dp-land/config.xml @@ -65,8 +65,9 @@ 17dp - 10%p - 33%p - 70%p - 30 + 8.33%p + 40%p + 64%p + 64%p + 36 diff --git a/app/src/main/res/values-sw600dp/config.xml b/app/src/main/res/values-sw600dp/config.xml index 44e0d0632..860a3bcf0 100644 --- a/app/src/main/res/values-sw600dp/config.xml +++ b/app/src/main/res/values-sw600dp/config.xml @@ -82,8 +82,9 @@ 3dp - 12.5%p - 33%p - 60%p - 24 + 11.11%p + 28%p + 78%p + 78%p + 36 diff --git a/app/src/main/res/values-sw768dp-land/config.xml b/app/src/main/res/values-sw768dp-land/config.xml index fdb95c6cc..024985681 100644 --- a/app/src/main/res/values-sw768dp-land/config.xml +++ b/app/src/main/res/values-sw768dp-land/config.xml @@ -65,6 +65,7 @@ 7.69%p 33%p - 60%p - 39 + 58%p + 58%p + 39 diff --git a/app/src/main/res/values-sw768dp/config.xml b/app/src/main/res/values-sw768dp/config.xml index 13be6bedf..a50dac5cc 100644 --- a/app/src/main/res/values-sw768dp/config.xml +++ b/app/src/main/res/values-sw768dp/config.xml @@ -81,7 +81,8 @@ 10%p - 33%p - 68%p - 30 + 30%p + 64%p + 64%p + 39 diff --git a/app/src/main/res/values-v31/colors.xml b/app/src/main/res/values-v31/colors.xml index e45615c4f..78517e63e 100644 --- a/app/src/main/res/values-v31/colors.xml +++ b/app/src/main/res/values-v31/colors.xml @@ -23,19 +23,15 @@ @android:color/system_accent1_500 @android:color/system_accent1_200 @android:color/system_accent1_900 - @android:color/system_accent1_500 + @color/highlight_color_lxx_light @android:color/system_accent1_200 + @color/highlight_color_lxx_light @android:color/system_accent1_500 @android:color/system_accent1_200 @android:color/system_accent1_900 - @android:color/system_accent1_500 + @color/highlight_color_lxx_dark @android:color/system_accent1_200 - - - - @android:color/system_accent1_300 - @android:color/system_accent1_600 + @color/highlight_color_lxx_dark diff --git a/app/src/main/res/values-v31/keyboard-icons-lxx-dark.xml b/app/src/main/res/values-v31/keyboard-icons-lxx-dark.xml index 2c15a98bc..fe8cc3aee 100644 --- a/app/src/main/res/values-v31/keyboard-icons-lxx-dark.xml +++ b/app/src/main/res/values-v31/keyboard-icons-lxx-dark.xml @@ -19,29 +19,8 @@ --> - diff --git a/app/src/main/res/values-v31/keyboard-icons-lxx-light.xml b/app/src/main/res/values-v31/keyboard-icons-lxx-light.xml index 37888ece5..e362daa97 100644 --- a/app/src/main/res/values-v31/keyboard-icons-lxx-light.xml +++ b/app/src/main/res/values-v31/keyboard-icons-lxx-light.xml @@ -19,29 +19,8 @@ --> - diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 2c6db9f17..7defaf7dc 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -270,6 +270,7 @@ + diff --git a/app/src/main/res/values/config.xml b/app/src/main/res/values/config.xml index e135b318e..5dc7ea951 100644 --- a/app/src/main/res/values/config.xml +++ b/app/src/main/res/values/config.xml @@ -88,9 +88,10 @@ 12.5%p - 33%p - 68%p - 24 + 28%p + 78%p + 78%p + 32 + + + + diff --git a/app/src/main/res/values/keyboard-icons-lxx-dark.xml b/app/src/main/res/values/keyboard-icons-lxx-dark.xml index 6663cf3e7..3c47bd03a 100644 --- a/app/src/main/res/values/keyboard-icons-lxx-dark.xml +++ b/app/src/main/res/values/keyboard-icons-lxx-dark.xml @@ -19,29 +19,5 @@ --> - + + diff --git a/app/src/main/res/values/keyboard-icons-lxx-light.xml b/app/src/main/res/values/keyboard-icons-lxx-light.xml index 9dc1e6455..abbf73360 100644 --- a/app/src/main/res/values/keyboard-icons-lxx-light.xml +++ b/app/src/main/res/values/keyboard-icons-lxx-light.xml @@ -19,29 +19,5 @@ --> - +