* feat(clipboard): optionally sync clipboard between connected sessions
Clipboard content received from a remote session is written to the local
clipboard with an owner marker, so the client clipboard loop deliberately
skips re-broadcasting it to avoid echo loops. As a result, text copied in
one remote window could not be pasted in another connected remote window.
Add an opt-in local option (allow-sync-clipboard-between-sessions) that
relays Clipboard/MultiClipboards messages received from one session to
all other connected sessions, excluding the source session. Per-session
clipboard permissions and view-only mode are still respected via the
existing send path, and the owner marker on the receiving peers prevents
any echo back.
Desktop (flutter) only; file clipboard is not affected.
* fix(lang): propagate sync-clipboard-between-sessions-tip to all locale files
Add the new key to template.rs and every locale file per the localization
convention, move the en.rs entry to the end of the list, and drop comments
that only restated the names next to them.
* fix(lang): add the 'Sync clipboard between sessions' label to the localization catalog
The checkbox label goes through translate(), so add it to template.rs
and every locale file so non-English locales can translate it. en.rs is
skipped since the English display text is identical to the key.
* fix(clipboard): check the source session's full clipboard permission before relaying
The relay was gated only by the incoming clipboard_allowed check
(!disable_clipboard && !view_only). Gate it with
is_text_clipboard_required() instead, which additionally respects the
source session's server_clipboard_enabled and server_keyboard_enabled
state, matching the predicate already applied to destination sessions.
A message arriving after the source permission was revoked (or from a
non-conforming peer) is no longer propagated to other sessions. The
existing local update_clipboard behavior is unchanged.
* fix(lang): translate the new clipboard sync entries in all locale files
Fill the 'Sync clipboard between sessions' label and its tooltip in
every locale file instead of leaving them blank, following each file's
existing terminology. template.rs keeps the empty master entries.
* fix: android: replace all-files access with scoped storage + system picker
Remove MANAGE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE, and
WRITE_EXTERNAL_STORAGE from the Android manifest. Remove
requestLegacyExternalStorage. Replace broad external storage with
app-scoped external storage for the file-transfer workspace.
File import uses the system file_picker. File export uses Android's
SAF ACTION_CREATE_DOCUMENT with path validation that restricts
export sources to app-owned directories.
Remove the external_path dependency.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android: refine file import feedback
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android: use SAF for file imports
Replace file_picker imports with Android's Storage Access Framework to avoid legacy storage permissions, stale cached files, and duplicate staging of large imports. Stream selected documents into app-scoped storage with failure-safe replacement, keep exports restricted to validated app storage roots, use filesDir for the internal fallback workspace, and remove legacy permissions contributed during manifest merging.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android: keep file imports in the selected directory
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android: reset projection and constrain file workspace
Release capture resources when media projection is revoked externally. Keep Android local file navigation within the app-scoped workspace.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android: handle scoped storage start-up regressions. Allow zero digits in POSIX filenames by rejecting NUL explicitly, and initialise the app-specific home directory before the Android service starts the native server.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: update content resolver mode to use 'wt' instead of 'w' to prevent trailing bytes from old document whilst reporting sucess
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android, enforce file workspace boundary on the server, and unblock the ui thread.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: android: validate rename destinations against the app workspace bound file-operation paths. report rename failures, general import failures, and unregister / reregister projection when its onStop callback fires.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: reconnect was refreshing the directory with net entry instances, while selected items retained the old instances, it was reporting a selected item, but checkbox statue used object identity, and appeared unchecked. Fixed by reconciling by path and entry type before replacing the directory snapshot, rebinding valid selections, and dropping missing ones.
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix: (android) add SAF folder import and multi item export - import directories using ACTION_OPEN_DOCUMENT_TREE. Export multiple files, logs, and screen recordings via export buttons, add localisation keys for new actions
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
* fix(android): harden scoped storage file handling
- create new SAF documents instead of overwriting export sources
- reject empty peer paths except for home directory reads
- report directory backup restore and cleanup failures
- resolve log export paths from the configured app name
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(android): harden scoped-storage file operations
- snapshot directory exports before writing to the destination
- query document provider metadata off the main thread
- reject invalid remote directories without read timeouts
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(android): handle SAF directory name collisions
- reject dot-segment folder names during import
- fail imports with duplicate document display names
- only reuse matching directories during export
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(android): handle SAF folder import collisions
Reject filesystem-equivalent destination names and
avoid showing a failure when folder overwrite is skipped.
Signed-off-by: fufesou <linlong1266@gmail.com>
---------
Signed-off-by: michaeljclarkk <104532890+michaeljclarkk@users.noreply.github.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
* Add Urdu language support for UI strings till 329 line
Co-authored-by: Copilot <copilot@github.com>
* Add Urdu translations for additional UI strings
* Add Urdu language support in lang.rs
* Fix Urdu translations and remove unused keys in ur.rs
---------
Co-authored-by: Copilot <copilot@github.com>
* fix(flutter): dispose the settings PageController and order dispose() correctly
`dispose()` began with `super.dispose()`, so the mixin chain marked the State
defunct before the WidgetsBindingObserver registration and the periodic timer
were released. The `PageController` was never disposed at all: `Get.delete`
only runs `onDelete()` for a `GetLifeCycleBase`, and a plain `ChangeNotifier`
is not one, so every open/close of the Settings tab leaked one controller with
its listener still attached.
Also guard `switch2page` on the `Rx<SettingsTabKey>` registration it actually
reads rather than only the `PageController` — now that both are really
deleted, a partial teardown would throw into the catch and silently open the
wrong tab — and re-check `mounted` after the await in the `_videoConnTimer`
tick, which `Timer::cancel` cannot stop once the body has started.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refact: finish the plugin-framework removal sweep
#15854 removed the feature but stopped short of its leftovers:
- `Uninstall`, `Enable`, `Disable`, `Options` and `Please install plugins`
were consumed only by the deleted `flutter/lib/plugin/**`; drop them from
template.rs and the 50 locale files (250 dead entries). `Update` and
`Install` stay, still used by desktop_home_page.dart.
- The server no longer sends `PrvOnFailedPlugin`, and the client no longer
offers to install plugins when privacy mode fails to turn on.
- Drop the MSI `F_Client_Plugins` / `F_Server_Plugins` localization strings;
no `.wxs` references them.
- `_DisplayMenu`'s constructor became a pure pass-through once `pluginItem`
was removed, and the cfg inside `handle_input` repeats the one on the
function itself.
- Normalize `src/lang/sl.rs` to 0644, the only executable file under src/.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(client): handle legacy privacy mode plugin failures
Signed-off-by: fufesou <linlong1266@gmail.com>
---------
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
* Update nl.rs
Updates plus a small improvement to the Dutch language file
* Update nl.rs
Now including fixes for coderabbit reportings
* Update nl.rs
Three more fixes re. greptile
* Update nl.rs
typo 'loskoppelenn' fixed as well
* Update translation for remote toolbar docking message
Update translation for remote toolbar docking message
* Translate 'Display' to 'Tela' in Portuguese locale
* Change translation of 'Display' to 'Exibição'
* Update Portuguese translations for clarity
Update Portuguese translations for clarity
* Update ptbr.rs
* Update Portuguese translations for clarity
* Update Portuguese translation for version warning
* Refine Portuguese translations in ptbr.rs
Updated translations for user input blocking and OS password.
* Fix translation for 'Take screenshot' in Portuguese
* Change translation for 'Note' to 'Anotações'
* Update translation from 'nota' to 'anotação'