Skip to content

Commit 827f5f2

Browse files
authored
Merge pull request #247 from kdroidFilter/fix-246
Enhance tray properties persistence on macOS
2 parents afbde86 + 20d26f4 commit 827f5f2

1 file changed

Lines changed: 36 additions & 7 deletions

File tree

src/commonMain/kotlin/com/kdroid/composetray/utils/TrayPosition.kt

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ internal object TrayClickTracker {
3535
val screenSize = Toolkit.getDefaultToolkit().screenSize
3636
val position = convertPositionToCorner(x, y, screenSize.width, screenSize.height)
3737
lastClickPosition.set(TrayClickPosition(x, y, position))
38-
saveTrayClickPosition(x, y, position)
38+
runCatching { saveTrayClickPosition(x, y, position) }
3939
}
4040

4141
fun setClickPosition(x: Int, y: Int, position: TrayPosition) {
4242
lastClickPosition.set(TrayClickPosition(x, y, position))
43-
saveTrayClickPosition(x, y, position)
43+
runCatching { saveTrayClickPosition(x, y, position) }
4444
}
4545

4646
fun getLastClickPosition(): TrayClickPosition? = lastClickPosition.get()
@@ -62,11 +62,27 @@ private const val Y_KEY = "TrayY"
6262

6363
// Use a writable tmp/cache directory to avoid read-only filesystem issues (e.g., macOS app bundle working dir)
6464
private fun trayPropertiesFile(): File {
65+
val appId = AppIdProvider.appId()
6566
val tmpBase = System.getProperty("java.io.tmpdir") ?: "."
66-
val appDir = File(File(tmpBase, "ComposeNativeTray"), AppIdProvider.appId())
67-
// Best-effort create directory; if it fails, we will fallback to legacy file access patterns safely
68-
runCatching { if (!appDir.exists()) appDir.mkdirs() }.onFailure { /* ignore */ }
69-
return File(appDir, PROPERTIES_FILE)
67+
val tmpDir = File(File(tmpBase, "ComposeNativeTray"), appId)
68+
69+
val userHome = System.getProperty("user.home")
70+
val macCacheDir = if (userHome != null) {
71+
val base = File(File(File(userHome, "Library"), "Caches"), "ComposeNativeTray")
72+
File(base, appId)
73+
} else null
74+
75+
val candidates = listOfNotNull(tmpDir, macCacheDir)
76+
77+
for (dir in candidates) {
78+
runCatching { if (!dir.exists()) dir.mkdirs() }
79+
if (dir.exists() && dir.canWrite()) {
80+
return File(dir, PROPERTIES_FILE)
81+
}
82+
}
83+
84+
// Fallback to tmp even if not verified writable; write will be guarded by runCatching
85+
return File(tmpDir, PROPERTIES_FILE)
7086
}
7187

7288
// Legacy properties file in working directory (for backward compatibility)
@@ -79,6 +95,15 @@ private fun oldTmpPropertiesFile(): File {
7995
return File(oldDir, PROPERTIES_FILE)
8096
}
8197

98+
// macOS user cache directory location for properties (for read/write fallback)
99+
private fun macCachePropertiesFile(): File? {
100+
val userHome = System.getProperty("user.home") ?: return null
101+
val appId = AppIdProvider.appId()
102+
val base = File(File(File(userHome, "Library"), "Caches"), "ComposeNativeTray")
103+
val dir = File(base, appId)
104+
return File(dir, PROPERTIES_FILE)
105+
}
106+
82107
private fun loadPropertiesFrom(file: File): Properties? {
83108
if (!file.exists()) return null
84109
return runCatching {
@@ -96,6 +121,7 @@ private fun storePropertiesTo(file: File, props: Properties) {
96121
internal fun saveTrayPosition(position: TrayPosition) {
97122
val preferredFile = trayPropertiesFile()
98123
val properties = loadPropertiesFrom(preferredFile)
124+
?: macCachePropertiesFile()?.let { loadPropertiesFrom(it) }
99125
?: loadPropertiesFrom(oldTmpPropertiesFile())
100126
?: loadPropertiesFrom(legacyPropertiesFile())
101127
?: Properties()
@@ -106,6 +132,7 @@ internal fun saveTrayPosition(position: TrayPosition) {
106132
internal fun saveTrayClickPosition(x: Int, y: Int, position: TrayPosition) {
107133
val preferredFile = trayPropertiesFile()
108134
val properties = loadPropertiesFrom(preferredFile)
135+
?: macCachePropertiesFile()?.let { loadPropertiesFrom(it) }
109136
?: loadPropertiesFrom(oldTmpPropertiesFile())
110137
?: loadPropertiesFrom(legacyPropertiesFile())
111138
?: Properties()
@@ -116,8 +143,9 @@ internal fun saveTrayClickPosition(x: Int, y: Int, position: TrayPosition) {
116143
}
117144

118145
internal fun loadTrayClickPosition(): TrayClickPosition? {
119-
// Prefer new location, fallback to old tmp location, then legacy working dir
146+
// Prefer new location, fallback to mac cache, then old tmp location, then legacy working dir
120147
val props = loadPropertiesFrom(trayPropertiesFile())
148+
?: macCachePropertiesFile()?.let { loadPropertiesFrom(it) }
121149
?: loadPropertiesFrom(oldTmpPropertiesFile())
122150
?: loadPropertiesFrom(legacyPropertiesFile()) ?: return null
123151

@@ -184,6 +212,7 @@ fun getTrayPosition(): TrayPosition {
184212
// Legacy fallback - just position without coordinates
185213
run {
186214
val props = loadPropertiesFrom(trayPropertiesFile())
215+
?: macCachePropertiesFile()?.let { loadPropertiesFrom(it) }
187216
?: loadPropertiesFrom(oldTmpPropertiesFile())
188217
?: loadPropertiesFrom(legacyPropertiesFile())
189218
val position = props?.getProperty(POSITION_KEY, null)

0 commit comments

Comments
 (0)