We need to pass focus to other sessions / threads with a timeout in case a quick stop event occurs

fixes #130321
This commit is contained in:
isidor 2021-08-16 15:50:43 +02:00
parent b3a86e6fee
commit 30d73ea6df
No known key found for this signature in database
GPG key ID: F9280366A8370105

View file

@ -50,6 +50,8 @@ export class DebugSession implements IDebugSession {
private cancellationMap = new Map<number, CancellationTokenSource[]>();
private rawListeners: IDisposable[] = [];
private fetchThreadsScheduler: RunOnceScheduler | undefined;
private passFocusScheduler: RunOnceScheduler;
private lastContinuedThreadId: number | undefined;
private repl: ReplModel;
private stoppedDetails: IRawStoppedDetails[] = [];
@ -106,6 +108,24 @@ export class DebugSession implements IDebugSession {
if (compoundRoot) {
toDispose.push(compoundRoot.onDidSessionStop(() => this.terminate()));
}
this.passFocusScheduler = new RunOnceScheduler(() => {
// If there is some session or thread that is stopped pass focus to it
if (this.debugService.getModel().getSessions().some(s => s.state === State.Stopped) || this.getAllThreads().some(t => t.stopped)) {
if (typeof this.lastContinuedThreadId === 'number') {
const thread = this.debugService.getViewModel().focusedThread;
if (thread && thread.threadId === this.lastContinuedThreadId && !thread.stopped) {
const toFocusThreadId = this.getStoppedDetails()?.threadId;
const toFocusThread = typeof toFocusThreadId === 'number' ? this.getThread(toFocusThreadId) : undefined;
this.debugService.focusStackFrame(undefined, toFocusThread);
}
} else {
const session = this.debugService.getViewModel().focusedSession;
if (session && session.getId() === this.getId() && session.state !== State.Stopped) {
this.debugService.focusStackFrame(undefined);
}
}
}
}, 800);
}
getId(): string {
@ -890,6 +910,7 @@ export class DebugSession implements IDebugSession {
}));
this.rawListeners.push(this.raw.onDidStop(async event => {
this.passFocusScheduler.cancel();
this.stoppedDetails.push(event.body);
await this.fetchThreads(event.body);
const thread = typeof event.body.threadId === 'number' ? this.getThread(event.body.threadId) : undefined;
@ -945,6 +966,7 @@ export class DebugSession implements IDebugSession {
this.model.clearThreads(this.getId(), true, event.body.threadId);
const viewModel = this.debugService.getViewModel();
const focusedThread = viewModel.focusedThread;
this.passFocusScheduler.cancel();
if (focusedThread && event.body.threadId === focusedThread.threadId) {
// De-focus the thread in case it was focused
this.debugService.focusStackFrame(undefined, undefined, viewModel.focusedSession, false);
@ -974,25 +996,11 @@ export class DebugSession implements IDebugSession {
this.stoppedDetails = [];
this.cancelAllRequests();
}
this.lastContinuedThreadId = threadId;
// We need to pass focus to other sessions / threads with a timeout in case a quick stop event occurs #130321
this.passFocusScheduler.schedule();
this.model.clearThreads(this.getId(), false, threadId);
this._onDidChangeState.fire();
// If there is some session or thread that is stopped pass focus to it
if (this.debugService.getModel().getSessions().some(s => s.state === State.Stopped) || this.getAllThreads().some(t => t.stopped)) {
if (typeof threadId === 'number') {
const thread = this.debugService.getViewModel().focusedThread;
if (thread && thread.threadId === threadId && !thread.stopped) {
const toFocusThreadId = this.getStoppedDetails()?.threadId;
const toFocusThread = typeof toFocusThreadId === 'number' ? this.getThread(toFocusThreadId) : undefined;
this.debugService.focusStackFrame(undefined, toFocusThread);
}
} else {
const session = this.debugService.getViewModel().focusedSession;
if (session && session.getId() === this.getId() && session.state !== State.Stopped) {
this.debugService.focusStackFrame(undefined);
}
}
}
}));
const outputQueue = new Queue<void>();
@ -1175,7 +1183,10 @@ export class DebugSession implements IDebugSession {
this.raw.dispose();
this.raw = undefined;
}
this.fetchThreadsScheduler?.dispose();
this.fetchThreadsScheduler = undefined;
this.passFocusScheduler.cancel();
this.passFocusScheduler.dispose();
this.model.clearThreads(this.getId(), true);
this._onDidChangeState.fire();
}