The data layer already speaks in entities, so the clipboard views were the
last place still calling a row a bean. Rename `ClipboardBeanUi` to
`ClipboardEntityUi`, `setBean` to `setEntity`, `beanId` to `entityId` and
`BEAN_ID` to `ENTITY_ID`, and pluralize the adapter, pager and submit-job
fields as `clipboardEntities*` and `favoriteEntities*`.
The intent extra key stays `"id"`, so intents already in flight are still
understood.
Clipboard history and favorites shared the generic `t_data` schema in two
separate database files, which forced every query to guess which kind of
row it was dealing with. Give each feature its own entity instead.
`clip.db` now holds both tables:
* `clipboard` keeps the event-log invariants: the history limit, eviction
of unpinned rows, recency ordering, `pinned` as an eviction exemption,
the MIME type and the sensitive flag reported by the system.
* `favorite` is a plain user library ordered by collection time only.
A single database means one `@Database`, one initialization and one
transaction, while two tables make it impossible for an eviction query to
delete a favorite by accident. The same text may exist in both, so no
foreign key ties them together.
Migration is done by hand rather than by Room, because the new file cannot
be reached by an in-place upgrade. `LegacyClipMigrator` opens the old
`clipboard.db` and `collection.db` through `SQLiteDatabase` (so WAL
contents are included and no old migration runs), reads `t_data` by column
name to support every legacy version, preserves ids, writes everything in
one transaction with `INSERT OR REPLACE`, and renames the old files and
their sidecars to `*.legacy` as a backup. A file that fails to read is
left in place and retried on the next launch.
The UI keeps a single read-only row model, `ClipboardItem`, which both
pagers map their entities into, so the adapter no longer knows about
either entity.
Sensitive clips stay sensitive: excerpts and the input bar suggestion are
masked (a new `clipboard_mask_sensitive` preference, on by default), the
collect action is hidden, and the word segment window neither offers the
star nor copies without the `EXTRA_IS_SENSITIVE` flag. Otherwise a password
would end up as plain favorite text or as an unmasked history row.
BackgroundSyncWork.internalStart() called WorkManager.initialize()
unconditionally, so a second scheduling request threw
"IllegalStateException: WorkManager is already initialized" and crashed
the app when leaving settings.
Let TrimeApplication implement Configuration.Provider and drop the
explicit initialize() call: WorkManager.getInstance() now initializes
on demand, which is idempotent and safe on repeat calls.
Keep the WorkManagerInitializer meta-data removed: the shared startup
provider is directBootAware so the IME can start before the first
unlock (#1937), which would otherwise run WorkManager in direct boot
mode, where its credential-encrypted database is unavailable (#2167).
Document this in the manifest so the removal is not reverted.
XXPermissions 28.x replaces string-based permission names with
IPermission objects and replaces the callback interface. Migrate the
notification permission check in MainActivity to the new API.
On Android 8-12 the check now reflects whether notifications are
actually enabled: the library maps POST_NOTIFICATIONS to the
notification service permission on releases before Android 13.
Stop forcing --hash-style=both: the Android dynamic linker supports GNU
hash tables since API 23, and the toolchain emits them by default at
this minimum API level. Keep --build-id=none for reproducible builds.
Include minSdk in the native cache hash so prebuilt libraries are not
reused after an API-level change.
Android 8.0 is now the minimum supported version. Remove the
compatibility branches for API 23-26 that are now dead code: runtime
guards, @RequiresApi annotations, and the java.text fallbacks in
DateTime and NativeTokenizer.
With API 26 as the floor, the app always uses device-protected storage
for its data directories, and ThemeLoader uses java.nio.file.Path for
the canonical-path containment check.
BREAKING CHANGE: Android 8.0 (API 26) is now the minimum supported
version; devices running Android 5.0-7.1 can no longer install new
builds.
Round the column count up so every configured popup action has a slot. Keep fixed-size spaces in incomplete rows so displayed keys stay aligned with horizontal focus selection.
NDK 30 ships libunwind.h but no target libunwind library, causing glog to link the host x86_64 libunwind.so for Android ABIs. Set glog's WITH_UNWIND to none so it does not search for unwind.
* fix(ime): synchronize candidate text with TextView layout
Keep the framework text and layout in sync before custom candidate drawing. Preserve the existing sizing and scaling while handling constructor-time setText safely.
* fix(ime): preserve candidate text buffer conversions
Mark custom text measurements dirty before forwarding setText to TextView.
Preserve same-content buffer changes used by accessibility traversal and let
the framework normalize null. Remove redundant layout forwarding while
retaining TextView measurement to keep its Layout synchronized.
* fix(ime): call TextView setter before invalidating caches
Forward every text and buffer type to TextView before invalidating the custom
measurement and transform caches. Drop the content comparison, which cannot
represent buffer conversions or filtering performed by the parent setter.
Keep constructor-time calls safe by marking caches dirty without reading them.
The checkout step already initializes all submodules recursively, and
the JNI cache hash step runs Gradle before this one, so the submodules
must be present regardless of the cache result. Fetching them again on
a cache miss does no useful work.
runCmd declares a default value for commands that fail, but providers.exec
throws as soon as the process exits with a non-zero value, so the fallback
was never used and the build failed while resolving the version metadata.
Ignore the exit value so that the default is applied instead. This fixes
configuration on machines without a git user name, such as GitHub Actions
runners.
Add a reusable checks workflow that runs make style-lint and make check
on Ubuntu. All build jobs now depend on it, so style, lint, or unit-test
failures block pull request, commit, nightly, and release builds instead
of only surfacing in the build matrix.
Checkout submodules recursively because build logic queries git describe
in librime and its nested opencc dependency while configuring the
project, so they are required even for style and unit test jobs.
Define CI_NAME in the reusable workflow because it does not inherit the
environment variables of its caller, which left the builder name to be
resolved from the git configuration.
ThemeLoader.isInside used File.toPath and Path.startsWith, which are
available only from API 26 while minSdk is 21. The runCatching wrapper
turned the resulting NoSuchMethodError into false, so every include was
rejected on Android 7.1 and older.
Compare canonical path strings with a separator boundary instead, which
keeps the escape check while working on all supported versions.
Expose make check for unit tests plus lint. It runs through Gradle and
needs neither the NDK nor a native build, so contributors can verify
changes without assembling an APK.
KeyCode.androidKeyNameToCode is a process-wide test seam. Specs that
replace it with a stub previously left that stub installed for later
classes, so behaviour depended on test order. Expose the real lookup as
defaultAndroidKeyNameToCode and restore it in afterSpec in all three
specs that override the seam.
Share the editor action policy between Return dispatch and labels.
Use the custom action ID when it takes precedence over imeOptions, and fall back
to the theme default instead of displaying a null app label.
Invalidate cached keyboard keys when the visible Return label changes so an
editor restart can refresh the current layout. Cover the decision policy and
real display-delegate broadcast transitions without changing key event routing.
Avoid connecting to a speech engine and allocating a custom sound pool when
feedback is disabled. Retain the application context and create each backend
only when enabled feedback needs it, waiting for initialization before use.
Confine speech requests from Rime jobs to the main thread and invalidate queued
requests at input lifecycle boundaries. Reject callbacks from released resources
and avoid retrying failed initialization on every key press. Cover resource
ownership and worker dispatch with focused regression tests.
Let the wrap-content editor respect its existing top and bottom constraints
when vertical space is limited. Keep the action row below the editor and
preserve the editor's existing internal scrolling and line limits.
Related: #2170
The footer constraint reduces the page viewport and clips the completed storage hint.
Wrap each setup page in a fill-viewport ScrollView so its content remains centered when it
fits and can scroll when it does not. Preserve the existing controls and fixed footer.
Constrain the pager to the top of the visible navigation buttons instead of
letting its content extend behind them. Use a top barrier that ignores gone
buttons so the bound follows the Next, Previous and Skip visibility changes.
Related: #2170
Bump the snappy from 1.2.1-7-g32ded45 to the 1.3.1 release.
The public API used by the bundled leveldb (RawCompress, RawUncompress,
MaxCompressedLength, GetUncompressedLength) and the CMake options are
unchanged.
Remember when JEnv successfully attaches a detached native thread and detach
that attachment on scope exit. Leave Java-owned and already-attached threads
alone. Disable ownership copying and moving to avoid duplicate detachment;
the existing factory retains mandatory C++17 return-value elision.
Related: #2170
Avoid the deprecated srcDirs call by appending prebuilt libraries through the directories API.
This preserves the default and custom JNI source directories during early plugin configuration.
Release each array element's local JNI reference at the end of its iteration.
Keep CString alive inside the JRef scope so UTF characters are released
before the element reference is deleted. Preserve converted values and order
while bounding reference accumulation within the native call.
Related: #2170
Match the library metadata to the versions reported by the pinned librime
and OpenCC sources. Keep dependency revisions and all other license fields
unchanged so the displayed versions describe the libraries being built.
Related: #2170
This constant was deprecated in API level 37. Use showSoftInput(View, int) without this flag instead. Starting in Android B, this flag has no effect anymore.
Drop the duplicated app/src/main/jni/OpenCC submodule, and build OpenCC from
librime/deps/opencc instead.
The opencc already is one dependency of librime, we should use it
instead of adding new submodule.
Hash each file at most once per sync by reusing the digest computed for the content-match check when the subsequent transfer writes that same content. Also widen the read buffer (and the input stream buffers) to 32 KB to cut syscall overhead on large files.