From bc0c6b80bc913cd76f61dfee9e180d924db46979 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Wed, 15 Jul 2026 11:25:41 +0000 Subject: [PATCH] desktop: clarify comments in hover cursor fix --- .../chat/simplex/common/views/chat/item/TextItemView.kt | 6 +++--- .../chat/simplex/common/views/helpers/GestureDetector.kt | 5 +++-- .../kotlin/chat/simplex/common/platform/Modifier.desktop.kt | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt index 556fa04832..90c96b7ffc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/TextItemView.kt @@ -359,12 +359,12 @@ fun MarkdownText ( val hand = hasAnnotation("WEB_URL") || hasAnnotation("SIMPLEX_URL") || hasAnnotation("OTHER_URL") || hasAnnotation("SIMPLEX_NAME") || hasAnnotation("SECRET") || hasAnnotation("COMMAND") val newIcon = if (hand) PointerIcon.Hand else PointerIcon.Text icon.value = newIcon - // pointerHoverIcon alone loses updates, see desktopSetHoverCursor + // pointerHoverIcon alone is unreliable, see desktopSetHoverCursor desktopSetHoverCursor(newIcon) }, onHoverExit = { - // reset icon.value too, or its node re-displays a stale Hand on next Enter; - // Text = this node's neutral icon, Default = cursor outside the text + // reset icon.value too, or pointerHoverIcon re-displays a stale Hand on the next Enter; + // Text is the neutral icon inside text, Default is the cursor after leaving it icon.value = PointerIcon.Text desktopSetHoverCursor(PointerIcon.Default) }, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/GestureDetector.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/GestureDetector.kt index 21c450ce27..a73f1b383e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/GestureDetector.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/GestureDetector.kt @@ -93,13 +93,14 @@ suspend fun PointerInputScope.detectGesture( } suspend fun PointerInputScope.detectCursorMove(onExit: () -> Unit = {}, onMove: (Offset) -> Unit = {},) { - // Single scope: per-event scope re-entry (old forEachGesture) drops events; Enter/Release cover stationary cursors. + // One scope for all events: re-entering awaitPointerEventScope per event loses events. + // Enter/Release update hover when the pointer is stationary (content moved under it, or a click completed). awaitPointerEventScope { while (true) { val event = awaitPointerEvent() if (event.type == PointerEventType.Move || event.type == PointerEventType.Enter || event.type == PointerEventType.Release) { val pos = event.changes[0].position - // pressed nodes receive events outside their bounds (during drag and at release) + // ignore events while a button is down or outside bounds: a pressed node receives them even after the pointer leaves it if (event.changes.none { it.pressed } && pos.x >= 0 && pos.y >= 0 && pos.x < size.width && pos.y < size.height) { onMove(pos) } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Modifier.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Modifier.desktop.kt index 0049fe0a41..639b829f71 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Modifier.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Modifier.desktop.kt @@ -88,7 +88,7 @@ actual fun Modifier.onRightClick(action: () -> Unit): Modifier = contextMenuOpen actual fun Modifier.desktopPointerHoverIconHand(): Modifier = Modifier.pointerHoverIcon(PointerIcon.Hand) -// hot path: canvas lookup (and its failure) cached per window, weakly to not retain a recreated window +// called on every hover move: cache the canvas (and lookup failure) per window; weak refs let a closed window be GCed private var cachedSkiaCanvas: WeakReference? = null private var skiaCanvasMissingIn: WeakReference? = null