Skip to content

[API use] fix Flutter app actions to not update template presentations #8061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pq opened this issue Apr 15, 2025 · 3 comments · Fixed by #8067
Closed

[API use] fix Flutter app actions to not update template presentations #8061

pq opened this issue Apr 15, 2025 · 3 comments · Fixed by #8067

Comments

@pq
Copy link
Contributor

pq commented Apr 15, 2025

Seeing a lot of exceptions like the following. It's not obvious from looking at the docs how to migrate what we've got.

getTemplatePresentation().setEnabled(myApp.isStarted() && myIsApplicable.compute());

@alexander-doroshko: any thoughts here?

java.lang.Throwable: Template presentations must not be used directly
	at com.intellij.openapi.actionSystem.Presentation.assertNotTemplatePresentation(Presentation.java:581)
	at com.intellij.openapi.actionSystem.Presentation.setEnabled(Presentation.java:545)
	at io.flutter.actions.FlutterAppAction$1.stateChanged(FlutterAppAction.java:29)
	at io.flutter.run.daemon.FlutterApp.addStateListener(FlutterApp.java:623)
	at io.flutter.actions.FlutterAppAction.update(FlutterAppAction.java:80)
	at io.flutter.actions.ReloadFlutterApp.update(ReloadFlutterApp.java:55)
	at io.flutter.actions.FlutterRetargetAppAction.update(FlutterRetargetAppAction.java:74)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareUpdate$lambda$2(ActionUtil.kt:226)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareUpdate(ActionUtil.kt:244)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$success$1$1$1.invoke(ActionUpdater.kt:501)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$success$1$1$1.invoke(ActionUpdater.kt:500)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$callAction$2$1.invoke(ActionUpdater.kt:145)
	at com.intellij.openapi.application.rw.InternalReadAction.insideReadAction(InternalReadAction.kt:114)
	at com.intellij.openapi.application.rw.InternalReadAction.tryReadCancellable$lambda$4(InternalReadAction.kt:104)
	at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal$lambda$3$lambda$2$lambda$1(cancellableReadAction.kt:32)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.tryRunReadAction(AnyThreadWriteThreadingSupport.kt:351)
	at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:971)
	at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal$lambda$3$lambda$2(cancellableReadAction.kt:30)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtilService.runActionAndCancelBeforeWrite(ProgressIndicatorUtilService.java:66)
	at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:157)
	at com.intellij.openapi.application.rw.CancellableReadActionKt.cancellableReadActionInternal(cancellableReadAction.kt:28)
	at com.intellij.openapi.application.rw.InternalReadAction.tryReadCancellable(InternalReadAction.kt:103)
	at com.intellij.openapi.application.rw.InternalReadAction.tryReadAction(InternalReadAction.kt:87)
	at com.intellij.openapi.application.rw.InternalReadAction.readLoop(InternalReadAction.kt:74)
	at com.intellij.openapi.application.rw.InternalReadAction.access$readLoop(InternalReadAction.kt:16)
	at com.intellij.openapi.application.rw.InternalReadAction$runReadAction$3.invokeSuspend(InternalReadAction.kt:36)
	at com.intellij.openapi.application.rw.InternalReadAction$runReadAction$3.invoke(InternalReadAction.kt)
	at com.intellij.openapi.application.rw.InternalReadAction$runReadAction$3.invoke(InternalReadAction.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:62)
	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:261)
	at com.intellij.openapi.application.rw.InternalReadAction.runReadAction(InternalReadAction.kt:35)
	at com.intellij.openapi.application.rw.PlatformReadWriteActionSupport.executeReadAction(PlatformReadWriteActionSupport.kt:38)
	at com.intellij.openapi.application.ReadWriteActionSupport.executeReadAction$default(ReadWriteActionSupport.kt:15)
	at com.intellij.openapi.application.CoroutinesKt.constrainedReadActionUndispatched(coroutines.kt:86)
	at com.intellij.openapi.application.CoroutinesKt.readActionUndispatched(coroutines.kt:73)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$callAction$$inlined$useWithScope$1.invokeSuspend(trace.kt:61)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$callAction$$inlined$useWithScope$1.invoke(trace.kt)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$callAction$$inlined$useWithScope$1.invoke(trace.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:62)
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163)
	at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater.callAction(ActionUpdater.kt:883)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater.access$callAction(ActionUpdater.kt:77)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$success$1$1.invokeSuspend(ActionUpdater.kt:500)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$success$1$1.invoke(ActionUpdater.kt)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$success$1$1.invoke(ActionUpdater.kt)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$$inlined$retryOnAwaitSharedData$1.invokeSuspend(ActionUpdater.kt:832)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$$inlined$retryOnAwaitSharedData$1.invoke(ActionUpdater.kt)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$updateAction$$inlined$retryOnAwaitSharedData$1.invoke(ActionUpdater.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:62)
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163)
	at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater.updateAction(ActionUpdater.kt:934)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater.expandGroupChild(ActionUpdater.kt:347)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater.access$expandGroupChild(ActionUpdater.kt:77)
	at com.intellij.openapi.actionSystem.impl.ActionUpdater$doExpandActionGroup$2$expandResult$1$1.invokeSuspend(ActionUpdater.kt:274)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:111)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:608)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:873)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:763)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:750)

@pq pq self-assigned this Apr 16, 2025
@pq pq added this to the M86 milestone Apr 16, 2025
@pq pq changed the title [API use] fix our use of template presentations [API use] fix Flutter app actions to not update template presentations Apr 16, 2025
@pq
Copy link
Contributor Author

pq commented Apr 16, 2025

On some more investigation, it looks like the issue is here:

  private final FlutterApp.FlutterAppListener myListener = new FlutterApp.FlutterAppListener() {
    @Override
    public void stateChanged(FlutterApp.State newState) {
      getTemplatePresentation().setEnabled(myApp.isStarted() && myIsApplicable.compute());
    }
  };

To get things working properly, we'll need to thread the action event into the listener so that we can ask it for its presentation to update.

@alexander-doroshko
Copy link
Contributor

@pq As a rule, you should neither use getTemplatePresentation(), nor store AnActionEvent as a field.

For example, you may introduce a project component that tracks the state.

void update(@NotNull final AnActionEvent e) {...} will be like:

e.getPresentation().setEnabled(FooComponent.getInstance(project).getWhatever())

(take project from e and check for null)

@pq
Copy link
Contributor Author

pq commented Apr 17, 2025

Cool. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants