Files
openidea/src/workbench/StatusBar.module.css
T
l0ng-ai 1c46a1cd04 fix(tasks): Make every background task cancellable, queued or running (#177)
Background tasks often couldn't be cancelled, or cancelling didn't stop them:
- A cancel that arrived before the backend registered the request was dropped (build while saving files, multi-repository fetch/pull between repositories). The host now remembers early cancels (bounded, 2 min), and request ids start at a random value per page.
- There was no queue and no common cancel path: backend-reported tasks (LSP progress, deployment transfers) couldn't be cancelled, and tool installs, VCS operations and update checks had no cancel button in Background Tasks.
- Only the direct child process was killed, and JDK / tool archives were extracted without checking for cancellation.

Tool installs and JDK downloads now share a downloads queue; cancelling a queued task removes it without starting any work. Every task cancels through one path that shows "Cancelling…" and then removes it; tasks that can't be interrupted show a disabled cancel button with the reason. IdeEvent::Task carries `cancellable` with a cancel_task command, cancellable LSP progress sends window/workDoneProgress/cancel, installers, curl and tar run in their own process group and are killed as a group, and extraction checks for cancellation between entries.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
2026-10-29 09:05:12 +08:00

118 lines
2.0 KiB
CSS

/* Islands: the status bar sits on the frame background, no divider. */
.bar {
height: calc(var(--h-statusbar) + 4px);
flex: none;
display: flex;
align-items: center;
gap: 4px;
padding: 0 10px 0 12px;
font-family: var(--font-ui);
font-size: var(--fs-ui);
color: var(--fg-muted);
white-space: nowrap;
overflow: hidden;
}
/* Widgets read as plain UI text like IDEA's, whatever their own font. */
.item {
font-family: var(--font-ui);
}
.item button {
font-family: inherit;
font-size: inherit;
color: inherit;
}
.item {
flex: none;
display: flex;
align-items: center;
min-width: 0;
padding: 0 4px;
}
/* Left items (breadcrumbs…) and background tasks give way first on narrow windows. */
.shrink {
flex: 0 1 auto;
overflow: hidden;
}
.shrink > * {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.item:empty {
display: none;
}
.spacer {
flex: 1;
min-width: 8px;
}
.task {
max-width: 320px;
}
.taskTitle {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
font-family: var(--font-ui);
}
.taskBar {
width: 96px;
flex: none;
}
.taskMore {
color: var(--fg-faint);
}
.taskList {
width: 320px;
padding: 6px 0;
font-family: var(--font-ui);
}
.taskListHeader {
padding: 2px 12px 6px;
color: var(--fg-faint);
font-size: var(--fs-small);
}
.taskRow {
display: flex;
flex-direction: column;
gap: 5px;
padding: 6px 12px;
}
.taskRowHead {
display: flex;
align-items: center;
gap: 8px;
}
.taskRowTitle {
flex: 1;
min-width: 0;
color: var(--fg-emphasis);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.taskCancelOff {
display: inline-flex;
}
.taskCancelOff > button {
pointer-events: none;
}
.taskPct {
font-family: var(--font-mono);
font-size: var(--fs-small);
color: var(--fg-subtle);
}
.taskMessage {
color: var(--fg-subtle);
font-size: var(--fs-small);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.info {
color: var(--fg-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}