1313import com .intellij .openapi .application .Application ;
1414import com .intellij .openapi .application .ApplicationManager ;
1515import com .intellij .openapi .application .ModalityState ;
16+ import com .intellij .openapi .diagnostic .Logger ;
1617import com .intellij .openapi .project .DumbAware ;
1718import com .intellij .openapi .project .Project ;
1819import com .intellij .openapi .project .ProjectManager ;
2829import com .intellij .util .ui .JBUI ;
2930import icons .FlutterIcons ;
3031import io .flutter .FlutterBundle ;
32+ import io .flutter .logging .PluginLogger ;
3133import io .flutter .run .FlutterDevice ;
3234import io .flutter .run .daemon .DeviceService ;
3335import io .flutter .sdk .AndroidEmulatorManager ;
4345import java .util .List ;
4446
4547public class DeviceSelectorAction extends AnAction implements CustomComponentAction , DumbAware {
48+ private static final @ NotNull Logger LOG = PluginLogger .createLogger (DeviceSelectorAction .class );
49+
4650 private static final Key <JButton > CUSTOM_COMPONENT_KEY = Key .create ("customComponent" );
4751 private static final Key <JBLabel > ICON_LABEL_KEY = Key .create ("iconLabel" );
4852 private static final Key <JBLabel > TEXT_LABEL_KEY = Key .create ("textLabel" );
4953 private static final Key <JBLabel > ARROW_LABEL_KEY = Key .create ("arrowLabel" );
5054 private static final @ NotNull Icon DEFAULT_DEVICE_ICON = FlutterIcons .Mobile ;
5155 private static final @ NotNull Icon DEFAULT_ARROW_ICON = IconUtil .scale (AllIcons .General .ChevronDown , null , 1.2f );
5256
53- private final List <AnAction > actions = new ArrayList <>();
57+ private volatile @ NotNull List <AnAction > actions = new ArrayList <>();
5458 private final List <Project > knownProjects = Collections .synchronizedList (new ArrayList <>());
5559
5660 private @ Nullable SelectDeviceAction selectedDeviceAction ;
@@ -386,7 +390,11 @@ private static boolean isSelectorVisible(@Nullable Project project) {
386390 }
387391
388392 private void updateActions (@ NotNull Project project , @ NotNull Presentation presentation ) {
389- actions .clear ();
393+ final String projectName = project .getName ();
394+ LOG .debug ("[" + projectName + "] Building device selector actions" );
395+
396+ // Create a new list instead of modifying the existing one
397+ final List <AnAction > newActions = new ArrayList <>();
390398
391399 final DeviceService deviceService = DeviceService .getInstance (project );
392400
@@ -399,7 +407,8 @@ private void updateActions(@NotNull Project project, @NotNull Presentation prese
399407 if (device == null ) continue ;
400408
401409 final SelectDeviceAction deviceAction = new SelectDeviceAction (device , devices );
402- actions .add (deviceAction );
410+ newActions .add (deviceAction );
411+ LOG .debug ("[" + projectName + "] Device action added for " + device );
403412
404413 if (Objects .equals (device , selectedDevice )) {
405414 selectedDeviceAction = deviceAction ;
@@ -411,37 +420,42 @@ private void updateActions(@NotNull Project project, @NotNull Presentation prese
411420 // Show the 'Open iOS Simulator' action.
412421 if (SystemInfo .isMac ) {
413422 boolean simulatorOpen = false ;
414- for (AnAction action : actions ) {
423+ for (AnAction action : newActions ) {
415424 if (action instanceof SelectDeviceAction deviceAction ) {
416425 final FlutterDevice device = deviceAction .device ;
417426 if (device .isIOS () && device .emulator ()) {
418427 simulatorOpen = true ;
428+ break ;
419429 }
420430 }
421431 }
422-
423- actions .add (new Separator ( ));
424- actions . add ( new OpenSimulatorAction (! simulatorOpen ) );
432+ newActions . add ( new Separator ());
433+ newActions .add (new OpenSimulatorAction (! simulatorOpen ));
434+ LOG . debug ( "[" + projectName + "] 'Open iOS Simulator' action added" );
425435 }
426436
427437 // Add Open Android emulators actions.
428438 final List <OpenEmulatorAction > emulatorActions = OpenEmulatorAction .getEmulatorActions (project );
429439 if (emulatorActions != null && !emulatorActions .isEmpty ()) {
430- actions .add (new Separator ());
431- actions .addAll (emulatorActions );
440+ newActions .add (new Separator ());
441+ newActions .addAll (emulatorActions );
442+ LOG .debug ("[" + projectName + "] Emulator action added: " + emulatorActions );
432443 }
433444 if (!FlutterModuleUtils .hasInternalDartSdkPath (project )) {
434- actions .add (new Separator ());
435- actions .add (RestartFlutterDaemonAction .forDeviceSelector ());
445+ newActions .add (new Separator ());
446+ newActions .add (RestartFlutterDaemonAction .forDeviceSelector ());
436447 }
437448
449+ // Atomically replace the action list
450+ LOG .debug ("[" + projectName + "] Replacing device selector actions" );
451+ this .actions = newActions ;
452+
438453 var tracker = ActivityTracker .getInstance ();
439454 if (tracker != null ) {
440455 tracker .inc ();
441456 }
442457 }
443458
444-
445459 private static class SelectDeviceAction extends AnAction {
446460 @ NotNull private final FlutterDevice device ;
447461
0 commit comments