Skip to content

Commit b9013c0

Browse files
committed
Detect and handle KDE environment in LinuxTrayManager
1 parent 08f57eb commit b9013c0

3 files changed

Lines changed: 26 additions & 6 deletions

File tree

demo/src/jvmMain/kotlin/com/kdroid/composetray/demo/DemoToggleEmptyMenu.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ fun main() = application {
5151
},
5252
tooltip = "Toggle Empty Menu"
5353
) {
54-
// When showMenuItem is false, this block remains empty by design
5554
if (showMenuItem) {
5655
Item("I'm here when toggled ON") {
5756
// Clicking this item turns the menu empty again on next open

linuxlib

src/commonMain/kotlin/com/kdroid/composetray/lib/linux/LinuxTrayManager.kt

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,25 @@ internal class LinuxTrayManager(
8585
taskQueue += action
8686
}
8787

88+
// KDE environment detection (KDE Plasma / SNI)
89+
private fun isKDEDesktop(): Boolean {
90+
return try {
91+
val xdg = System.getenv("XDG_CURRENT_DESKTOP") ?: ""
92+
val session = System.getenv("DESKTOP_SESSION") ?: ""
93+
val kdeFull = System.getenv("KDE_FULL_SESSION") ?: ""
94+
val xdgL = xdg.lowercase()
95+
val sessionL = session.lowercase()
96+
val kdeDetected =
97+
kdeFull.equals("true", ignoreCase = true) ||
98+
xdgL.contains("kde") || xdgL.contains("plasma") ||
99+
sessionL.contains("kde") || sessionL.contains("plasma")
100+
if (kdeDetected) debugln { "LinuxTrayManager: KDE environment detected (XDG='$xdg', SESSION='$session', KDE_FULL_SESSION='$kdeFull')" }
101+
kdeDetected
102+
} catch (_: Throwable) {
103+
false
104+
}
105+
}
106+
88107
// ----------------------------------------------------------------------------- menu model
89108
data class MenuItem(
90109
val text: String,
@@ -186,7 +205,8 @@ internal class LinuxTrayManager(
186205
callbackReferences.clear()
187206
menuItemReferences.clear()
188207

189-
if (menuItems.isNotEmpty()) {
208+
val effectiveItems = if (menuItems.isEmpty() && isKDEDesktop()) listOf(MenuItem("-")) else menuItems
209+
if (effectiveItems.isNotEmpty()) {
190210
// Create or clear existing menu ------------------------------------------------
191211
if (menuHandle == null) {
192212
menuHandle = sni.create_menu()
@@ -215,7 +235,7 @@ internal class LinuxTrayManager(
215235
}
216236

217237
// Add menu items --------------------------------------------------------------
218-
menuItems.forEach { addNativeMenuItem(menuHandle!!, it) }
238+
effectiveItems.forEach { addNativeMenuItem(menuHandle!!, it) }
219239
sni.set_context_menu(trayHandle, menuHandle)
220240
infoln { "LinuxTrayManager: Context menu set" }
221241
} else {
@@ -326,12 +346,13 @@ internal class LinuxTrayManager(
326346
}
327347

328348
private fun initializeTrayMenu() {
329-
if (menuItems.isEmpty()) return
349+
val effectiveItems = if (menuItems.isEmpty() && isKDEDesktop()) listOf(MenuItem("-")) else menuItems
350+
if (effectiveItems.isEmpty()) return
330351
menuHandle = sni.create_menu() ?: run {
331352
errorln { "Failed to create menu" }
332353
return
333354
}
334-
menuItems.forEach { addNativeMenuItem(menuHandle!!, it) }
355+
effectiveItems.forEach { addNativeMenuItem(menuHandle!!, it) }
335356
trayHandle?.let { sni.set_context_menu(it, menuHandle) }
336357
}
337358

0 commit comments

Comments
 (0)