void (@NotNull TerminalWidget terminalWidget, @NotNull ShellStartupOptions startupOptions) { ModalityState modalityState = ModalityState.stateForComponent(terminalWidget.getComponent()); CheckedDisposable widgetDisposable = Disposer.newCheckedDisposable(terminalWidget); ApplicationManager.getApplication().executeOnPooledThread(() -> { if (myProject.isDisposed() || widgetDisposable.isDisposed()) return; ShellStartupOptions baseOptions = startupOptions.builder().widget(terminalWidget).build(); ShellStartupOptions configuredOptions = configureStartupOptions(baseOptions); ApplicationManager.getApplication().invokeLater(() -> { if (widgetDisposable.isDisposed()) return; CompletableFuture<TermSize> initialTermSizeFuture = awaitTermSize(terminalWidget, configuredOptions); initialTermSizeFuture.whenComplete((initialTermSize, initialTermSizeError) -> { if (myProject.isDisposed() || widgetDisposable.isDisposed()) return; if (initialTermSize == null) { LOG.warn("Cannot get terminal size from component, defaulting to 80x24", initialTermSizeError); initialTermSize = new TermSize(80, 24); } TermSize resultInitialTermSize = initialTermSize; ApplicationManager.getApplication().executeOnPooledThread(() -> { if (myProject.isDisposed() || widgetDisposable.isDisposed()) return; try { T process = createProcess(configuredOptions.builder().initialTermSize(resultInitialTermSize).build()); TtyConnector connector = createTtyConnector(process); ApplicationManager.getApplication().invokeLater(() -> { if (widgetDisposable.isDisposed()) return; try { terminalWidget.connectToTty(connector, resultInitialTermSize); } catch (Exception e) { printError(terminalWidget, "Cannot create terminal session for " + terminalWidget.getTerminalTitle().buildTitle(), e); } }, modalityState, myProject.getDisposed()); } catch (Exception e) { printError(terminalWidget, "Cannot open " + terminalWidget.getTerminalTitle().buildTitle(), e); } }); }); }, modalityState, myProject.getDisposed()); }); }