On an incoming call the desktop window blinked continuously (FileNotFoundException
from SoundPlayer.start writing into a missing ...\Temp\simplex).
Root cause: Files.desktop top-level val initializers run in any process that
touches the facade class, including a transient second instance (which reaches
acquireSingleInstance -> dataDir). Two of them deleted shared state used by the
running primary:
- tmpDir had .also { deleteOnExit() } - the second instance's normal exit deleted
...\Temp\simplex, so the primary then failed to write call sounds/recordings.
- preferencesTmpDir had .also { deleteRecursively() } - the second instance's
<clinit> wiped configPath\tmp (same anti-pattern, firing even earlier).
Make both declarations pure and do the destructive cleanup in Main, past the
single-instance check, so only the owning instance performs it (preferencesTmpDir
kept early, before any settings write). The remaining val-initializer side effects
are idempotent creations (mkdirs) that destroy nothing and are left in place.
* desktop: show startup errors in a copyable window instead of bare "Failed to launch JVM"
When any exception escapes main() before the app window appears - a missing
DLL, a failed migration, broken AWT init - the jpackage launcher shows only
"Failed to launch JVM" and the cause is recorded nowhere: the launcher runs
without a console, so stderr is lost. Every report in #4146 stalled on this.
Catch the error and show it in a native Win32 window laid out like a message
box: an error icon and message, two clickable report links (the GitHub issue
tracker and the support email) above a read-only selectable box with the stack
trace, and an OK button. The links are SS_NOTIFY statics opened with
ShellExecute (browser for the URL, mail client for the email). Native, not
Swing, because broken AWT initialization is one of the failure causes. On
Windows the process then exits cleanly so the launcher does not also show its
own box; on other systems the error is rethrown to stderr.
* docs: plan justifying desktop startup error window (#4146)
* desktop: bundle jdk.accessibility to fix "Failed to launch JVM" when assistive technologies are enabled (#4146)
The jlinked runtime shipped in desktop packages did not include the
jdk.accessibility module. On Windows, when Java Access Bridge is enabled
(jabswitch -enable, "Enable Java Access Bridge" in Ease of Access, or a
screen reader creating %USERPROFILE%\.accessibility.properties), AWT
throws AWTError "Assistive Technology not found:
com.sun.java.accessibility.AccessBridge" during Toolkit init, before any
window or log output, and the jpackage launcher reports "Failed to
launch JVM".
* docs: plan justifying jdk.accessibility fix for Windows JVM launch (#4146)
* desktop: bundle jdk.accessibility only when building the Windows package
* desktop: prevent duplicate launches
Acquires a file lock and listens on a loopback ServerSocket in dataDir.
A second launch signals the running instance to restore its window and
exits silently. See plans/2026-05-13-desktop-single-instance.md.
* desktop: un-minimize window in showWindow
toFront() does not un-minimize a JFrame on any AWT platform. Clear the
ICONIFIED bit so a minimized window restores; preserves MAXIMIZED_BOTH.
Also fixes the same case when restoring from the tray icon.
* desktop: move showWindow from DesktopTray to DesktopApp
It has callers outside the tray (single-instance signal) and belongs
next to simplexWindowState, which it operates on.
* simplify
* refactor
* desktop: start show-file watcher when choosing minimize from first-close dialog
The handleCloseRequest path already starts the watcher when minimizing to
tray; the Ask-dialog path did not, so the first-time user who picks
"Minimize to tray" got a hidden window with no signal handling — a
duplicate launch would not restore it.
* desktop: always watch for duplicate-launch signal, drop hung-instance alert
The watcher now runs for the JVM lifetime once the lock is acquired,
not only when minimized to tray. Duplicate launches always restore the
primary's window (un-minimize, un-tray-hide, toFront) instead of being
silently dropped when the primary is not minimized.
Drops the "may be hung, start anyway?" popup and the two strings — that
fallback was needed only because the watcher could miss signals. With
the always-on watcher there is no scenario where the primary fails to
consume simplex.show, so the escape hatch becomes dead code.
* desktop: alert when primary's watcher doesn't consume the show file
Restores the "another instance may be running" alert. Every duplicate
launch waits up to 1s for the primary's watcher to delete the show file
it just created. If the file is consumed within the window, the
duplicate exits silently. If still there after 1s the primary is hung
and the alert fires.
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* android, desktop: scrolling moves title to app bar
* one place should be without padding
* scroll related changes for both platforms
* adapt code to universal ColumnWithScrollBar
* show in center
* small adjustments
* new chat sheet fix
* divider + mix background color for desktop
* coerce
* different transition
* desktop title starts from left
* host starts from left too
* different coefficient
* settings title
* moving to mutablestate + snapshotstatelist from snapshotstatelist
* android, desktop: refactoring to use mutex when updating chats
* wrapped into class instead of object
* fix
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* desktop: in-app update functionality
* without Android
* refactor
* working windows
* tabs vs spaces
* better working mac
* changes
* repo
* undo manifest changes
* changes
* changes
* unneeded changes
* revert
* new line
* fix update notice
* different way
* changes to mac logic
* changes to mac logic
* more
* update strings
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* android, desktop: wallpapers
* changes
* removed unused
* changes
* backgrounds moved to themes. can be exported/imported
* changes and refactoring
* scrollable
* change
* reorder
* theme per background
* changes
* don't drop customization in same cases
* changes
* changes
* fix state update
* different defaults
* fix Android
* removed migration
* temporary
* returned theme name as uppercase back
* resilient to wrong preset name
* more
* live color change without button
* fix
* Revert "temporary"
This reverts commit 705c92ee56.
* changes
* changes
* almost candy
* old picker and ability to specify hex color
* different image
* picker
* user theme override, fixes, import/export theme with image
* revert when about to merge: useful layout for theming
* custom image displaying and deletion work correctly
* performance
* moved code up
* changes
* color changes in picker when changing themes
* reset color without closing modal
* unused
* log
* currentTheme instead of MaterialTheme
* different inheritance logic
* fix and move sent/received message colors to top
* remove background
* performance
* fix wrong base
* changes
* fix
* small
* custom image selection made normally
* better color picker
* better picker
* refactor, fixes, optimizations
* working with unknown base theme + tests
* change
* delete wallpaper dir when importing archive
* function rename
* fix bug with state update
* update colors
* fix text colors
* update images
* changes
* remote desktop and theme mode dropdown
* default theme
* additional accent 2 changes
* fix default wallpaper
* removed ChatListAlwaysVisible
* renaming
* update messages
* changes
* default theme
* unused
* member icon background color
* image quality
* fix wallpaper on empty notes screen
* update colors
* change
* update colors
* fix update on android
* fix update on both platforms
* update colors, remove serializable
* fix color
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* desktop: Windows build
* temp
* temp
* new way of libs loading
* new way of libs loading
* Revert "new way of libs loading"
This reverts commit 8632f8a8f7.
* made VLC working on Windows
* unused lib
* scripts
* updated script
* fix path
* fix lib loading
* fix lib loading
* packaging options
* different file manager implementation on Windows
---------
Co-authored-by: Avently <avently.local>
Co-authored-by: avently <avently@local>
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
* desktop: video and audio players
* making player working without preinstalled VLC
* mac support
* don't use vlc lib when not needed
* updated jna version
* changes in script
* video player lazy loading
* mac script changes
* updated build gradle for preserving atrributes of file while copying
* apply the same file stats on libs to make VLC checker happy
* updated script
* changes
---------
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
* desktop: creating tmpDir
* provide name for saved file
* directories only selection on Mac
* specified filename for file savers
---------
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
* multiplatform: default files and directories were changed
* changes in paths and location of declaration
* more renames
* different paths
* update linux paths
---------
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
* multiplatform: relocated code to its new place
* code becomes better
* renamed file
* fixes for BASE64 and images, and changes for appFileUri
* different Base64 for both platforms
* fix file saving on long click
* platformCallbacks refactoring
* renamed callbacks to platform
* eol
---------
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
* multiplatform: moved to Gradle KTS and common directory structure
* renamed for review
* different versions for Android and desktop
* update desktop version_name
* Revert "renamed for review"
This reverts commit 80041efe40.
* EOLs
* change version to 1.0 to appease linter
---------
Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>