Skip to content

Commit 09a342a

Browse files
authored
feat - add chat lifecycle handler for shutdown veto (microsoft#255617)
1 parent b8c44fb commit 09a342a

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

src/vs/platform/menubar/electron-main/menubar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,10 @@ export class Menubar extends Disposable {
467467
const { response } = await this.nativeHostMainService.showMessageBox(this.windowsMainService.getFocusedWindow()?.id, {
468468
type: 'question',
469469
buttons: [
470-
nls.localize({ key: 'quit', comment: ['&& denotes a mnemonic'] }, "&&Quit"),
470+
isMacintosh ? nls.localize({ key: 'quit', comment: ['&& denotes a mnemonic'] }, "&&Quit") : nls.localize({ key: 'exit', comment: ['&& denotes a mnemonic'] }, "&&Exit"),
471471
nls.localize('cancel', "Cancel")
472472
],
473-
message: nls.localize('quitMessage', "Are you sure you want to quit?")
473+
message: isMacintosh ? nls.localize('quitMessageMac', "Are you sure you want to quit?") : nls.localize('quitMessage', "Are you sure you want to exit?")
474474
});
475475

476476
return response === 0;

src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { ILifecycleService, ShutdownReason } from '../../../services/lifecycle/c
3030
import { IWorkingCopyService } from '../../../services/workingCopy/common/workingCopyService.js';
3131
import { OpaqueEdits, ResourceAttachmentEdit } from './opaqueEdits.js';
3232
import { TextModelEditReason } from '../../../../editor/common/textModelEditReason.js';
33+
import { isMacintosh } from '../../../../base/common/platform.js';
3334

3435
function liftEdits(edits: ResourceEdit[]): ResourceEdit[] {
3536
return edits.map(edit => {
@@ -295,30 +296,24 @@ export class BulkEditService implements IBulkEditService {
295296

296297
private async _shouldVeto(label: string | undefined, reason: ShutdownReason): Promise<boolean> {
297298
let message: string;
298-
let primaryButton: string;
299299
switch (reason) {
300300
case ShutdownReason.CLOSE:
301301
message = localize('closeTheWindow.message', "Are you sure you want to close the window?");
302-
primaryButton = localize({ key: 'closeTheWindow', comment: ['&& denotes a mnemonic'] }, "&&Close Window");
303302
break;
304303
case ShutdownReason.LOAD:
305304
message = localize('changeWorkspace.message', "Are you sure you want to change the workspace?");
306-
primaryButton = localize({ key: 'changeWorkspace', comment: ['&& denotes a mnemonic'] }, "Change &&Workspace");
307305
break;
308306
case ShutdownReason.RELOAD:
309307
message = localize('reloadTheWindow.message', "Are you sure you want to reload the window?");
310-
primaryButton = localize({ key: 'reloadTheWindow', comment: ['&& denotes a mnemonic'] }, "&&Reload Window");
311308
break;
312309
default:
313-
message = localize('quit.message', "Are you sure you want to quit?");
314-
primaryButton = localize({ key: 'quit', comment: ['&& denotes a mnemonic'] }, "&&Quit");
310+
message = isMacintosh ? localize('quitMessageMac', "Are you sure you want to quit?") : localize('quitMessage', "Are you sure you want to exit?");
315311
break;
316312
}
317313

318314
const result = await this._dialogService.confirm({
319315
message,
320316
detail: localize('areYouSureQuiteBulkEdit.detail', "'{0}' is in progress.", label || localize('fileOperation', "File operation")),
321-
primaryButton
322317
});
323318

324319
return !result.confirmed;

src/vs/workbench/contrib/chat/electron-browser/chat.contribution.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ import { ViewContainerLocation } from '../../../common/views.js';
3030
import { INativeHostService } from '../../../../platform/native/common/native.js';
3131
import { IChatService } from '../common/chatService.js';
3232
import { autorun } from '../../../../base/common/observable.js';
33+
import { ILifecycleService, ShutdownReason } from '../../../services/lifecycle/common/lifecycle.js';
34+
import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';
35+
import { isMacintosh } from '../../../../base/common/platform.js';
3336

3437
class NativeBuiltinToolsContribution extends Disposable implements IWorkbenchContribution {
3538

@@ -130,6 +133,61 @@ class ChatSuspendThrottlingHandler extends Disposable {
130133
}
131134
}
132135

136+
class ChatLifecycleHandler extends Disposable {
137+
138+
static readonly ID = 'workbench.contrib.chatLifecycleHandler';
139+
140+
constructor(
141+
@ILifecycleService lifecycleService: ILifecycleService,
142+
@IChatService private readonly chatService: IChatService,
143+
@IDialogService private readonly dialogService: IDialogService,
144+
@IViewsService private readonly viewsService: IViewsService
145+
) {
146+
super();
147+
148+
this._register(lifecycleService.onBeforeShutdown(e => {
149+
e.veto(this.shouldVetoShutdown(e.reason), 'veto.chat');
150+
}));
151+
}
152+
153+
private shouldVetoShutdown(reason: ShutdownReason): boolean | Promise<boolean> {
154+
const running = this.chatService.requestInProgressObs.read(undefined);
155+
if (!running) {
156+
return false;
157+
}
158+
159+
return this.doShouldVetoShutdown(reason);
160+
}
161+
162+
private async doShouldVetoShutdown(reason: ShutdownReason): Promise<boolean> {
163+
164+
showChatView(this.viewsService);
165+
166+
let message: string;
167+
switch (reason) {
168+
case ShutdownReason.CLOSE:
169+
message = localize('closeTheWindow.message', "A chat request is in progress. Are you sure you want to close the window?");
170+
break;
171+
case ShutdownReason.LOAD:
172+
message = localize('changeWorkspace.message', "A chat request is in progress. Are you sure you want to change the workspace?");
173+
break;
174+
case ShutdownReason.RELOAD:
175+
message = localize('reloadTheWindow.message', "A chat request is in progress. Are you sure you want to reload the window?");
176+
break;
177+
default:
178+
message = isMacintosh ? localize('quit.message', "A chat request is in progress. Are you sure you want to quit?") : localize('exit.message', "A chat request is in progress. Are you sure you want to exit?");
179+
break;
180+
}
181+
182+
const result = await this.dialogService.confirm({
183+
message,
184+
detail: localize('quit.detail', "The chat request will be cancelled if you continue.")
185+
});
186+
187+
return !result.confirmed;
188+
}
189+
}
190+
133191
registerAction2(StartVoiceChatAction);
134192
registerAction2(InstallSpeechProviderForVoiceChatAction);
135193

@@ -151,3 +209,4 @@ registerWorkbenchContribution2(KeywordActivationContribution.ID, KeywordActivati
151209
registerWorkbenchContribution2(NativeBuiltinToolsContribution.ID, NativeBuiltinToolsContribution, WorkbenchPhase.AfterRestored);
152210
registerWorkbenchContribution2(ChatCommandLineHandler.ID, ChatCommandLineHandler, WorkbenchPhase.BlockRestore);
153211
registerWorkbenchContribution2(ChatSuspendThrottlingHandler.ID, ChatSuspendThrottlingHandler, WorkbenchPhase.AfterRestored);
212+
registerWorkbenchContribution2(ChatLifecycleHandler.ID, ChatLifecycleHandler, WorkbenchPhase.AfterRestored);

0 commit comments

Comments
 (0)