Open vdshb opened 1 year ago
I've faced similar behaviour when I switched between two previews:
@Preview
@Composable
fun Reproducer2(
) {
Icon(Icons.Filled.Add, contentDescription = "A")
}
@Preview
@Composable
fun Reproducer3(
) {
Icon(Icons.Filled.ArrowDropDown, contentDescription = "A")
}
First couple of renders goes fine, then it's stuck and stop previewing anything.
Maybe it's a different issue, but I believe they are related.
Yep, same thing, and I can't see the common reason in my code for this
https://github.com/JetBrains/compose-jb/issues/2156#issuecomment-1284492736
Looks like IDE somehow looses track of port used to connect to PreviewHost. If I am reading it correctly
configureDesktopPreview -Pcompose.desktop.preview.target=<MyPReviewClass> -Pcompose.desktop.preview.ide.port=36207'
If it's actually need to be the same, I am not sure. IDE exception log is in the comment above
I analyzed the error myself because my team and I are facing this issue for quite a while now. A added a few more system outputs to reduce the scope for search and ended up seeing the following for successful previews:
CONNECTION (PREVIEW) #2:SENT COMMAND 'FRAME_REQUEST com.example.common.TestUiPreviewKt.TestUiPreview 1 632 912 4607182418800017408'
SERVER:PREVIEW_HOST:GOT COMMAND 'PREVIEW_CLASSPATH'
SERVER:PREVIEW_HOST:GOT [4474]
SERVER:PREVIEW_HOST:GOT COMMAND 'FRAME_REQUEST com.example.common.TestUiPreviewKt.TestUiPreview 1 632 912 4607182418800017408'
SERVER:PREVIEW_HOST:RENDERING 'com.example.common.TestUiPreviewKt.TestUiPreview' 632x912@1.0
2023-01-28 03:36:40,770 [ 35396] WARN - GradleBuildOutputUtil.kt - Failed to read Json output file from C:\Users\Christos\workspace\temp\ide-plugin-debug\android\build\outputs\apk\debug\output-metadata.json. Build may have failed.
SERVER:PREVIEW_HOST:RENDERED [4966] in 571 ms
SERVER:PREVIEW_HOST:SENT COMMAND 'FRAME 632 912'
SERVER:PREVIEW_HOST:SENT DATA [4966]
CONNECTION (PREVIEW) #2:GOT COMMAND 'FRAME 632 912'
CONNECTION (PREVIEW) #2:GOT [4966]
When the preview fails and stops working the output is:
CONNECTION (PREVIEW) #2:SENT COMMAND 'FRAME_REQUEST com.example.common.TestUiPreviewKt.TestUiPreview 3 632 912 4607182418800017408'
SERVER:PREVIEW_HOST:GOT COMMAND 'PREVIEW_CLASSPATH'
SERVER:PREVIEW_HOST:GOT [4474]
SERVER:PREVIEW_HOST:GOT COMMAND 'FRAME_REQUEST com.example.common.TestUiPreviewKt.TestUiPreview 3 632 912 4607182418800017408'
SERVER:PREVIEW_HOST:RENDERING 'com.example.common.TestUiPreviewKt.TestUiPreview' 632x912@1.0
It never stops rendering.
In RemotePreviewHost
there is the following line:
val render = try {
previewFacade.getMethod("render", *renderArgsClasses)
} // ...
that fetches the method for rendering, and a few lines further there is the block for rendering:
val ms = measureTimeMillis {
bytes = render.invoke(previewFacade, fqName, scaledWidth, scaledHeight, scale) as ByteArray
}
So it seems like there is a bug somewhere in the preview facade class androidx.compose.desktop.ui.tooling.preview.runtime.NonInteractivePreviewFacade
. I do not know where to find the source code of this class to further analyze the bug.
I was reproducing the error with the following code snippet:
package com.example.common
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@Preview
@Composable
fun TestUiPreview() {
MaterialTheme {
ComponentUi()
}
}
@Composable
fun ComponentUi() {
Column(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 64.dp),
verticalArrangement = Arrangement.Top
){
Text(
text = "Login",
textAlign = TextAlign.Start,
style = MaterialTheme.typography.h3
)
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
value = "model.email 2",
leadingIcon = { Icon(painter = rememberVectorPainter(Icons.Default.Email), contentDescription = "") },
onValueChange = {},
placeholder = { Text("Email Address") },
singleLine = true,
)
// IMPORTANT Uncomment below text field to cause the bug
// OutlinedTextField(
// modifier = Modifier.fillMaxWidth(),
// value = "model.password",
// onValueChange = {},
// placeholder = { Text("Password") },
// singleLine = true,
// )
}
}
All compose dependencies were updated to 1.2.2 and the preview was placed in the desktopMain
modoule of a multiplatform project.
@dsvoronin I tried to analyze your statement but couldn't find any misbehavior in the connection / socket.
EDIT: The UI is not updated anymore after the bug occurs because new rendering requests are blocked due to the already running rendering process. This can be seen in PreviewManager
:
if (inProcessRequest.get() == null && request != prevRequest) { // is never true after bug
// ...
}
I wasn't able to further debug the problem because the test project with the development IDE was not using directly the preview-rpc
module for rendering and I am not aware how to setup everything to debug it properly.
However, my assumption is that it is somehow related to the rendering of a Column
with rememberVectorPainter
as a (nested) child. When the rememberVectorPainter
is not used at all or used only in the last element of the column, the rendering works just fine. Once an element comes after the element that uses rememberVectorPainter
(e.g. Icon(imageVector =...)
or OutlinedTextField(leadingIcon= ...)
, the rendering never completes and any follow-up rendering requests are skipped due to the incomplete rendering process. I was assuming that it was only happening when using rememberVectorPainter
twice, but that is not necessary.
A workaround until the bug is fixed would be to use LazyColumn
with item{...}
, or not use rememberVectorPainter
inside a Column
.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Desktop previewer fails to show a preview for this snippet:
After try, it hangs up and doesn't show any other preview as well. Only project reload helps to reset the error.
kotlin version: 1.7.20 compose version: 1.2.1 or 1.3.0-alpha01-dev853