3110 Commits

Author SHA1 Message Date
WhiredPlanck
9a39f49fc7 refactor(clipboard): rename UI-layer beans to entities
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.
nightly
2026-11-07 23:47:41 +08:00
WhiredPlanck
5864131d08 refactor(clipboard): split clipboard and favorites into one database
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.
2026-11-07 23:47:41 +08:00
WhiredPlanck
134030cd0e fix(worker): avoid double WorkManager initialization
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.
2026-11-06 20:47:40 +08:00
Bambooin
0f7bc782c2 build: upgrade XXPermissions to 28.3
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.
2026-11-01 18:41:34 +08:00
Bambooin
f5fc1c3794 build: update AndroidX and dependencies 2026-11-01 15:05:35 +08:00
Bambooin
adc2808f26 build: adapt native build to minSdk 26
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.
2026-11-01 15:04:38 +08:00
Bambooin
dd139de8f0 build: raise minSdk to 26
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.
2026-11-01 15:04:38 +08:00
Bambooin
5cfc1fbf08 build: upgrade Gradle wrapper to 9.8.2
Regenerate the wrapper for Gradle 9.8.2. The distribution stays the
binary-only variant.
2026-11-01 15:04:38 +08:00
X2M7
57feda7007 fix(keyboard): preserve popup keyboard grid slots
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.
2026-11-01 14:57:59 +08:00
X2M7
ae919e32f5 fix(keyboard): inherit default key width from theme style 2026-11-01 14:57:00 +08:00
X2M7
c7abdfa99a fix(popup): preserve complete action labels 2026-11-01 14:56:32 +08:00
X2M7
210275a1f1 fix(theme): fall back from unresolved key backgrounds 2026-11-01 14:55:39 +08:00
Bambooin
c612f5482c chore: bump version to 3.3.14 2026-11-01 14:47:14 +08:00
Bambooin
b5cad1a490 chore: add 3.3.13 changelog v3.3.13 2026-11-01 13:54:42 +08:00
Bambooin
7c55dd17c7 chore: upgrade librime-lua and bundled lua 2026-11-01 10:29:02 +08:00
Bambooin
25b39fdefb chore: upgrade cmake to 4.1.2
The blocking issue in librime's dependencies with leveldb and yaml-cpp
are fixed, so let's use the latest cmake in NDK.
2026-11-01 10:29:02 +08:00
Bambooin
c7c55af948 chore: upgrade librime to latest commit 2026-11-01 10:28:50 +08:00
Xumin Liang
ed54b8d95a
build(deps): update spotless to 8.10.3 2026-10-29 19:51:16 +08:00
X2M7
a2fe7e79c3 build(spotless): exclude included build outputs 2026-10-29 12:55:26 +08:00
X2M7
7fedca06ba fix(ime): declare package visibility for voice input methods 2026-10-28 21:18:24 +08:00
X2M7
e1e0ece969 fix(ime): ignore toolbar actions after candidates replace it 2026-10-28 09:56:09 +08:00
CI
a047f74757 fix(theme): send only the symbol for tongwenfeng symbol keys
The @, * and & keys on the tongwenfeng symbol keyboard also sent
Return, so they could not be used to type the symbols themselves.
2026-10-25 10:00:44 +08:00
Bambooin
c0df6d07bf fix(build): disable glog unwind support
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.
2026-10-24 19:48:44 +08:00
Bambooin
f27ea93b96 ci: install CMake via setup-android
Install cmake;3.31.6 together with platform-tools and remove the separate sdkmanager step from the build workflows.
2026-10-24 19:48:44 +08:00
Bambooin
c8b3a50c4f build: update Android Gradle Plugin to 9.4.1 2026-10-24 19:48:44 +08:00
Bambooin
7195206640 build: update Android NDK and build tools
Use NDK 30.0.16248370 and Build Tools 37.0.0. CMake remains pinned at 3.31.6.
2026-10-24 19:48:44 +08:00
Xumin Liang
57edd25ea2
refactor(ime): call AutoScaleTextView setter before invalidating caches (#2187)
* 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.
2026-10-24 00:15:51 +08:00
Bambooin
19b048494f ci: remove redundant submodule fetch
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.
2026-10-22 20:03:32 +08:00
Bambooin
9093457fac fix(build): fall back to the default when a git command fails
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.
2026-10-22 20:03:32 +08:00
Bambooin
90d3844da7 ci: gate builds on style, lint, and unit test checks
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.
2026-10-22 20:03:32 +08:00
Bambooin
35353126ac fix(theme): avoid java.nio.file APIs on API < 26
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.
2026-10-22 20:03:32 +08:00
Bambooin
a2450f9a0b build: add a make target for checks
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.
2026-10-22 20:03:32 +08:00
Bambooin
daffad6882 test(keyboard): restore key name lookup after each spec
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.
2026-10-22 20:03:32 +08:00
zianlin
a39859c16d
Revert "feat(keyboard): support double tap shift to lock caps" (#2163)
This functionality is already supported in Trime.

This reverts commit 8545278b9efccaaf5b222dd499f5954ebcf87269.
2026-10-22 19:36:47 +08:00
X2M7
a45f6d6536 fix: keep Return labels consistent with editor actions
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.
2026-10-22 19:33:55 +08:00
X2M7
b60c329942 perf: initialize input feedback resources on demand
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.
2026-10-22 19:33:29 +08:00
X2M7
02f0efa8d6 fix: constrain clipboard editor height above action buttons
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
2026-10-22 19:33:02 +08:00
X2M7
87447bd76c fix: keep setup content reachable in short viewports
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.
2026-10-22 19:32:31 +08:00
X2M7
f0f4140d44 fix: keep setup pages above visible navigation buttons
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
2026-10-22 19:32:31 +08:00
Bambooin
12ffd16fe0 chore: upgrade snappy to 1.3.1
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.
2026-10-21 18:28:14 +08:00
X2M7
8ec95f2da4 fix: detach only JNI thread attachments owned by the guard
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
2026-10-21 18:21:36 +08:00
X2M7
91750d19ba build: use mutable JNI source directories API
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.
2026-10-21 18:20:29 +08:00
X2M7
144f6111d0 fix: release JNI local references while converting string arrays
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
2026-10-20 19:43:30 +08:00
X2M7
7609c8ba1d fix: match native library license versions to pinned sources
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
2026-10-20 19:25:46 +08:00
Bambooin
a75f69b9cf fix: fix deprecated SHOW_IMPLICIT usage
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.
2026-10-18 10:33:21 +08:00
Bambooin
f5008260dc feat: use librime's bundled opencc
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.
2026-10-18 10:21:05 +08:00
Copilot
3f0eb5203b
fix: defer WorkManager startup until device unlock 2026-10-17 22:09:20 +08:00
Bambooin
693216ab7f fix(opencc): package t2s dictionary 2026-10-16 22:18:00 +08:00
Bambooin
f1f1923490 chore: upgrade opencc to 1.4.2 2026-10-16 22:18:00 +08:00
WhiredPlanck
c7f32b6cca perf(data): reuse content digests and widen hash buffer in UserDataManager
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.
2026-10-15 00:39:48 +08:00