Closed SebastianAigner closed 9 months ago
Reproduced with a simple button example:
import androidx.compose.material.MaterialTheme
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
@Composable
@Preview
fun App() {
val colors = listOf(Color.Red, Color.Green, Color.Blue)
val numberOfColors = colors.size
var index by remember { mutableStateOf(0) }
Row(Modifier.background(colors[index % numberOfColors]).fillMaxSize()) {
Button(onClick = { index++ }) {
Text("ClickMe")
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
MaterialTheme {
App()
}
}
}
To reproduce:
Kotlin 1.8.0 Compose 1.3.0 JDK 18
This sounds like an unintended side-effect of the synthetic events + somehow receiving/processing the mouse event before the measure/layout cycle.
On Linux Fedora 38 Gnome Desktop, I have a similar problem, but slightly different. After resizing the window, I release the mouse button and immediately move the mouse pointer into the window area, at which point the Click event is triggered.
Ok, I did some digging and what happens is that during the resizing AWT sends us MOUSE_ENTER and MOUSE_EXIT events (no press or release events though) with extModifiers=Button1
. However PointerInputScope.detectTapAndPress
doesn't look at the event type - it only cares about whether any button is pressed or released. So when it receives an event which says a button is pressed, and then another one which says it's released, it detects a tap.
@igordmn Where do you think it's best to fix/workaround this? I'm thinking we should completely filter out these MOUSE_ENTER
and MOUSE_EXIT
events because that's the root cause of the problem. AWT should not be sending us mouse events while resizing the window.
These MOUSE_ENTER
and MOUSE_EXIT
events have other undesirable effects too - a widget placed close to the edge receives them and becomes "hovered", for example.
we should completely filter out these MOUSE_ENTER and MOUSE_EXIT
I agree, this will be a good solution if we manage to do that (ideally, AWT should consume hover on resize in the first place)
But how we can know that we should filter the received event? Maybe we should filter enter's with pressed buttons?
Yes, filter enter/exit with pressed button(s) if we didn't receive the press event for those buttons.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Reproducable with experimental
ImageViewer
project. Resize the window in the gallery view while having the cursor at the height of the preview image, and sometimes, it'll trigger the transition to the Memory View.https://user-images.githubusercontent.com/2178959/223841903-55c74b1c-4c7c-4829-b187-53e2256aee72.mov