Skip to content

Commit 02806f6

Browse files
committed
Refactor window position calculation to distinguish OS-specific behavior
- Introduced distinct positioning logic for Windows and macOS/Linux. - Updated macOS/Linux to snap to bar edge, ignoring clickY height within the icon. - Preserved legacy raw offset behavior for Windows.
1 parent 52fa0c0 commit 02806f6

1 file changed

Lines changed: 30 additions & 21 deletions

File tree

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

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -328,33 +328,42 @@ private fun calculateWindowPositionFromClick(
328328
horizontalOffset: Int,
329329
verticalOffset: Int
330330
): WindowPosition {
331-
// Snap to the bar edge instead of using the raw clickY.
332-
// This removes the "top vs bottom of icon" discrepancy on GNOME.
331+
val os = getOperatingSystem()
333332
val isTop = trayPosition == TrayPosition.TOP_LEFT || trayPosition == TrayPosition.TOP_RIGHT
334333
val isRight = trayPosition == TrayPosition.TOP_RIGHT || trayPosition == TrayPosition.BOTTOM_RIGHT
335334

336-
// Heuristic bar thickness in pixels (kept conservative; scaling-safe enough in practice)
337-
val panelGuessPx = 28
338-
339-
// Horizontal: center on clickX, then apply direction-aware offset
340-
var x = clickX - (windowWidth / 2)
341-
342-
// Vertical: snap to the bar edge; ignore clickY height within the icon
343-
val anchorY = if (isTop) panelGuessPx else screenHeight - panelGuessPx
344-
var y = if (isTop) anchorY else anchorY - windowHeight
345-
346-
// Direction-aware offsets: push away from the bar/edge for a consistent "gap".
347-
x += if (isRight) -horizontalOffset else horizontalOffset
348-
y += if (isTop) verticalOffset else -verticalOffset
349-
350-
// Clamp to screen bounds
351-
if (x < 0) x = 0 else if (x + windowWidth > screenWidth) x = screenWidth - windowWidth
352-
if (y < 0) y = 0 else if (y + windowHeight > screenHeight) y = screenHeight - windowHeight
353-
354-
return WindowPosition(x = x.dp, y = y.dp)
335+
return if (os == OperatingSystem.WINDOWS) {
336+
// ---- Legacy behavior for Windows (keep exact clickY & raw offsets) ----
337+
var x = clickX - (windowWidth / 2)
338+
var y = if (isTop) clickY else clickY - windowHeight
339+
340+
x += horizontalOffset
341+
y += verticalOffset
342+
343+
if (x < 0) x = 0 else if (x + windowWidth > screenWidth) x = screenWidth - windowWidth
344+
if (y < 0) y = 0 else if (y + windowHeight > screenHeight) y = screenHeight - windowHeight
345+
WindowPosition(x = x.dp, y = y.dp)
346+
} else {
347+
// ---- New behavior for macOS & Linux: snap to bar edge (ignore clickY height within icon) ----
348+
// Conservative guess of panel thickness; works well across GNOME/KDE and typical macOS menubar heights.
349+
val panelGuessPx = 28
350+
351+
var x = clickX - (windowWidth / 2)
352+
val anchorY = if (isTop) panelGuessPx else (screenHeight - panelGuessPx)
353+
var y = if (isTop) anchorY else anchorY - windowHeight
354+
355+
// Direction-aware offsets: always push AWAY from the bar/edge for consistency.
356+
x += if (isRight) -horizontalOffset else horizontalOffset
357+
y += if (isTop) verticalOffset else -verticalOffset
358+
359+
if (x < 0) x = 0 else if (x + windowWidth > screenWidth) x = screenWidth - windowWidth
360+
if (y < 0) y = 0 else if (y + windowHeight > screenHeight) y = screenHeight - windowHeight
361+
WindowPosition(x = x.dp, y = y.dp)
362+
}
355363
}
356364

357365

366+
358367
/** Position de repli coin + offsets */
359368
private fun fallbackCornerPosition(
360369
w: Int, h: Int,

0 commit comments

Comments
 (0)