@@ -160,27 +160,20 @@ internal class WindowsTrayManager(
160160 var consecutiveErrors = 0
161161 var initialPosCaptured = false
162162 var initialPosAttempts = 0
163+ var positionErrorCount = 0
164+ val maxPositionErrors = 3 // Stop trying after 3 errors to avoid spamming logs
163165
164166 while (running.get()) {
165167 try {
166168 // Try to capture initial precise tray icon position (per instance)
167- if (! initialPosCaptured && initialPosAttempts < 60 ) {
169+ if (! initialPosCaptured && initialPosAttempts < 60 && positionErrorCount < maxPositionErrors ) {
168170 initialPosAttempts++
169- try {
170- val xRef = IntByReference ()
171- val yRef = IntByReference ()
172- val precise = WindowsNativeTrayLibrary .tray_get_notification_icons_position(xRef, yRef) != 0
173- if (precise) {
174- val screen = java.awt.Toolkit .getDefaultToolkit().screenSize
175- val corner = com.kdroid.composetray.utils.convertPositionToCorner(xRef.value, yRef.value, screen.width, screen.height)
176- TrayClickTracker .setClickPosition(instanceId, xRef.value, yRef.value, corner)
177- initialPosCaptured = true
178- log(" Captured initial tray icon position: ${xRef.value} , ${yRef.value} " )
179- }
180- } catch (e: Exception ) {
181- // ignore and retry later
171+ if (safeGetTrayPosition(instanceId)) {
172+ initialPosCaptured = true
173+ log(" Captured initial tray icon position" )
182174 }
183175 }
176+
184177 // Check for pending updates
185178 processUpdateQueue()
186179
@@ -237,6 +230,36 @@ internal class WindowsTrayManager(
237230 log(" Message loop ended" )
238231 }
239232
233+ /* *
234+ * Safely attempts to get the tray position with error handling
235+ * @return true if position was successfully obtained, false otherwise
236+ */
237+ private fun safeGetTrayPosition (instanceId : String ): Boolean {
238+ return try {
239+ val xRef = IntByReference ()
240+ val yRef = IntByReference ()
241+ val precise = WindowsNativeTrayLibrary .tray_get_notification_icons_position(xRef, yRef) != 0
242+ if (precise) {
243+ val screen = java.awt.Toolkit .getDefaultToolkit().screenSize
244+ val corner = com.kdroid.composetray.utils.convertPositionToCorner(
245+ xRef.value, yRef.value, screen.width, screen.height
246+ )
247+ TrayClickTracker .setClickPosition(instanceId, xRef.value, yRef.value, corner)
248+ true
249+ } else {
250+ false
251+ }
252+ } catch (e: Error ) {
253+ // Handle invalid memory access error
254+ log(" Failed to get tray icon position (memory access error): ${e.message} " )
255+ false
256+ } catch (e: Exception ) {
257+ // Handle other exceptions
258+ log(" Failed to get tray icon position: ${e.message} " )
259+ false
260+ }
261+ }
262+
240263 private fun processUpdateQueue () {
241264 val update = synchronized(updateQueueLock) {
242265 if (updateQueue.isNotEmpty()) {
@@ -276,8 +299,16 @@ internal class WindowsTrayManager(
276299
277300 // Update the native tray
278301 log(" Calling tray_update()" )
279- WindowsNativeTrayLibrary .tray_update(newTray)
280- log(" tray_update() completed" )
302+ try {
303+ WindowsNativeTrayLibrary .tray_update(newTray)
304+ log(" tray_update() completed" )
305+ } catch (e: Error ) {
306+ log(" Failed to update tray (memory access error): ${e.message} " )
307+ e.printStackTrace()
308+ } catch (e: Exception ) {
309+ log(" Failed to update tray: ${e.message} " )
310+ e.printStackTrace()
311+ }
281312
282313 // Update the reference
283314 tray.set(newTray)
@@ -291,14 +322,7 @@ internal class WindowsTrayManager(
291322 log(" Left click callback invoked" )
292323 try {
293324 // Capture precise tray position on the tray thread (per-instance)
294- val xRef = IntByReference ()
295- val yRef = IntByReference ()
296- val precise = WindowsNativeTrayLibrary .tray_get_notification_icons_position(xRef, yRef) != 0
297- if (precise) {
298- val screen = java.awt.Toolkit .getDefaultToolkit().screenSize
299- val corner = com.kdroid.composetray.utils.convertPositionToCorner(xRef.value, yRef.value, screen.width, screen.height)
300- TrayClickTracker .setClickPosition(instanceId, xRef.value, yRef.value, corner)
301- }
325+ safeGetTrayPosition(instanceId)
302326
303327 // Execute callback in IO scope (like macOS)
304328 mainScope?.launch {
@@ -360,14 +384,7 @@ internal class WindowsTrayManager(
360384 log(" Menu item clicked: ${menuItem.text} " )
361385 try {
362386 // Capture precise tray position on the tray thread (per-instance)
363- val xRef = IntByReference ()
364- val yRef = IntByReference ()
365- val precise = WindowsNativeTrayLibrary .tray_get_notification_icons_position(xRef, yRef) != 0
366- if (precise) {
367- val screen = java.awt.Toolkit .getDefaultToolkit().screenSize
368- val corner = com.kdroid.composetray.utils.convertPositionToCorner(xRef.value, yRef.value, screen.width, screen.height)
369- TrayClickTracker .setClickPosition(instanceId, xRef.value, yRef.value, corner)
370- }
387+ safeGetTrayPosition(instanceId)
371388
372389 if (running.get()) {
373390 // Execute callback in IO scope (like macOS)
@@ -418,6 +435,9 @@ internal class WindowsTrayManager(
418435 try {
419436 log(" Calling tray_exit()" )
420437 WindowsNativeTrayLibrary .tray_exit()
438+ } catch (e: Error ) {
439+ log(" Error in tray_exit() (memory access): ${e.message} " )
440+ e.printStackTrace()
421441 } catch (e: Exception ) {
422442 log(" Error in tray_exit(): ${e.message} " )
423443 e.printStackTrace()
0 commit comments