Skip to content

Commit 2eddcc3

Browse files
committed
Enhance TrayApp dialog visibility handling and positioning
- Added macOS-specific delay to resolve concurrency issue when positioning the dialog. - Improved focus loss behavior with a startup grace period on Windows. - Enabled front positioning for dialog window upon opening. - Added fade animation for content wrapper.
1 parent c055563 commit 2eddcc3

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

  • src/commonMain/kotlin/com/kdroid/composetray/tray/api

src/commonMain/kotlin/com/kdroid/composetray/tray/api/TrayApp.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ fun ApplicationScope.TrayApp(
468468
) { }
469469

470470
// === Main popup window (ALWAYS MOUNTED) ===
471+
// === Main popup window (ALWAYS MOUNTED) ===
471472
DialogWindow(
472473
onCloseRequest = { requestHide() },
473474
title = "",
@@ -476,12 +477,21 @@ fun ApplicationScope.TrayApp(
476477
focusable = true,
477478
alwaysOnTop = true,
478479
transparent = true,
479-
visible = shouldShowWindow, // <- Toujours contrôlé par notre variable sécurisée
480+
visible = shouldShowWindow,
480481
state = dialogState,
481482
) {
482-
// Assure le positionnement correct au moment précis où on décide de montrer la fenêtre
483+
// Ensure proper initial position exactly WHEN we decide to show the window
483484
LaunchedEffect(shouldShowWindow, currentWindowSize) {
484485
if (shouldShowWindow) {
486+
// ================== CORRECTION POUR MACOS ==================
487+
// Sur macOS, il y a une condition de concurrence. On doit attendre un
488+
// instant pour que les coordonnées du clic soient mises à jour
489+
// avant de tenter de positionner la fenêtre.
490+
if (os == MACOS) {
491+
delay(30) // 30ms est suffisant et imperceptible.
492+
}
493+
// =========================================================
494+
485495
val widthPx = currentWindowSize.width.value.toInt()
486496
val heightPx = currentWindowSize.height.value.toInt()
487497
dialogState.position = getTrayWindowPositionForInstance(
@@ -490,16 +500,18 @@ fun ApplicationScope.TrayApp(
490500
}
491501
}
492502

493-
// Le reste de votre code est correct...
503+
// Attach/Detach platform listeners only while window is actually visible
494504
DisposableEffect(shouldShowWindow) {
495505
if (!shouldShowWindow) {
496506
onDispose { }
497507
return@DisposableEffect onDispose { }
498508
}
499509

510+
// Mark this as the tray popup (macOS visibility monitor)
500511
try { window.name = WindowVisibilityMonitor.TRAY_DIALOG_NAME } catch (_: Throwable) {}
501512
runCatching { WindowVisibilityMonitor.recompute() }
502513

514+
// Bring to front on open
503515
invokeLater {
504516
try {
505517
window.toFront()
@@ -513,6 +525,7 @@ fun ApplicationScope.TrayApp(
513525
override fun windowLostFocus(e: WindowEvent?) {
514526
lastFocusLostAt = System.currentTimeMillis()
515527
if (os == WINDOWS && lastFocusLostAt < autoHideEnabledAt) {
528+
// Ignore focus loss during startup grace period on Windows
516529
return
517530
}
518531
requestHide()
@@ -543,6 +556,7 @@ fun ApplicationScope.TrayApp(
543556
}
544557
}
545558

559+
// Content wrapper with fade animation (state is preserved across show/hide)
546560
Box(
547561
modifier = Modifier
548562
.fillMaxSize()

0 commit comments

Comments
 (0)