resolveLaunchSurface function
Decides where a launch should start.
linked is what the build actually contains — resolved at build time from
the -cli/-tui suffix or a dartvel.terminal opt-in, never probed here.
The rules, in order:
- One backend means no decision. A GUI-only build starts the GUI and fails to find a display exactly as it does today; an application that opted into nothing gains no prompt, no flag and no branch.
--tuistarts the terminal. The explicit path, and the one to reach for over SSH.- A display means the GUI. A terminal is where the command was typed, not necessarily where the application belongs.
- No display, and someone is there to answer: ask. Both silent answers are wrong — quietly redrawing as text is indistinguishable from a bug at the moment it happens, and failing outright wastes a capability the application was built with.
- No display and nobody to ask: take the terminal. A prompt with no human at the other end is a hang, and the terminal is the only surface that can work.
Implementation
DVLaunchOutcome resolveLaunchSurface({
required Set<DVRenderSurface> linked,
required List<String> arguments,
required bool displayAvailable,
bool interactive = true,
}) {
if (linked.isEmpty) {
throw ArgumentError.value(
linked,
'linked',
'A build must contain at least one rendering backend. An empty set is a '
'build configuration error, not a runtime condition.',
);
}
final hasTerminal = linked.contains(DVRenderSurface.terminal);
final hasGui = linked.contains(DVRenderSurface.gui);
if (!hasTerminal) return DVLaunchOutcome.gui;
if (!hasGui) return DVLaunchOutcome.terminal;
if (arguments.contains('--tui')) return DVLaunchOutcome.terminal;
if (displayAvailable) return DVLaunchOutcome.gui;
return interactive
? DVLaunchOutcome.askToUseTerminal
: DVLaunchOutcome.terminal;
}