Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function ensureClipboardGetsEditorSelection(e: ClipboardEvent, context: V
ClipboardEventUtils.setTextData(e.clipboardData, dataToCopy.text, dataToCopy.html, storedMetadata);
}
logService.trace('ensureClipboardGetsEditorSelection with id : ', id, ' with text.length: ', dataToCopy.text.length);
performance.mark('code/nativeEditContext/ensureClipboardGetsEditorSelection', { detail: { id, length: dataToCopy.text.length } });
}

export function generateDataToCopyAndStoreInMemory(viewModel: IViewModel, options: IComputedEditorOptions, id: string | undefined, isFirefox: boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,12 @@ export class NativeEditContext extends AbstractEditContext {
this._screenReaderSupport = this._register(instantiationService.createInstance(ScreenReaderSupport, this.domNode, context, this._viewController));

this._register(addDisposableListener(this.domNode.domNode, 'copy', (e) => {
performance.mark('code/nativeEditContext/copy');
this.logService.trace('NativeEditContext#copy');
ensureClipboardGetsEditorSelection(e, this._context, this.logService, isFirefox);
}));
this._register(addDisposableListener(this.domNode.domNode, 'cut', (e) => {
performance.mark('code/nativeEditContext/cut');
this.logService.trace('NativeEditContext#cut');
// Pretend here we touched the text area, as the `cut` event will most likely
// result in a `selectionchange` event which we want to ignore
Expand Down Expand Up @@ -147,6 +149,7 @@ export class NativeEditContext extends AbstractEditContext {
}
let [text, metadata] = ClipboardEventUtils.getTextData(e.clipboardData);
this.logService.trace('NativeEditContext#paste with id : ', metadata?.id, ' with text.length: ', text.length);
performance.mark('code/nativeEditContext/paste', { detail: { id: metadata?.id, length: text.length } });
if (!text) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ export class TextAreaInput extends Disposable {

this._register(this._textArea.onCut((e) => {
this._logService.trace(`TextAreaInput#onCut`, e);
performance.mark('code/TextAreaInput/cut');
// Pretend here we touched the text area, as the `cut` event will most likely
// result in a `selectionchange` event which we want to ignore
this._textArea.setIgnoreSelectionChangeTime('received cut event');
Expand All @@ -371,6 +372,7 @@ export class TextAreaInput extends Disposable {

this._register(this._textArea.onCopy((e) => {
this._logService.trace(`TextAreaInput#onCopy`, e);
performance.mark('code/TextAreaInput/copy');
if (this._host.context) {
ensureClipboardGetsEditorSelection(e, this._host.context, this._logService, this._browser.isFirefox);
}
Expand All @@ -397,6 +399,7 @@ export class TextAreaInput extends Disposable {
// try the in-memory store
metadata = metadata || InMemoryClipboardMetadataManager.INSTANCE.get(text);

performance.mark('code/TextAreaInput/paste', { detail: { id: metadata?.id, length: text.length } });
this._logService.trace(`TextAreaInput#onPaste (before onPaste)`);
this._onPaste.fire({
text: text,
Expand Down
4 changes: 4 additions & 0 deletions src/vs/editor/contrib/clipboard/browser/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,14 @@ function executeClipboardCopyWithWorkaround(editor: IActiveCodeEditor, clipboard
// We will use this as a signal that we have executed a copy command
// !!!!!
CopyOptions.electronBugWorkaroundCopyEventHasFired = false;
performance.mark('code/registerExecCommandImpl/beforeExecCopy');
editor.getContainerDomNode().ownerDocument.execCommand('copy');
if (platform.isNative && CopyOptions.electronBugWorkaroundCopyEventHasFired === false) {
// We have encountered the Electron bug!
// As a workaround, we will write (only the plaintext data) to the clipboard in a different way
// We will use the clipboard service (which in the native case will go to electron's clipboard API)
const { dataToCopy } = generateDataToCopyAndStoreInMemory(editor._getViewModel(), editor.getOptions(), undefined, browser.isFirefox);
performance.mark('code/registerExecCommandImpl/fallback');
clipboardService.writeText(dataToCopy.text);
}
}
Expand All @@ -221,6 +223,7 @@ function registerExecCommandImpl(target: MultiCommand | undefined, browserComman
const logService = accessor.get(ILogService);
const clipboardService = accessor.get(IClipboardService);
logService.trace('registerExecCommandImpl (addImplementation code-editor for : ', browserCommand, ')');
performance.mark('code/registerExecCommandImpl/cutOrCopy', { detail: { command: browserCommand } });
// Only if editor text focus (i.e. not if editor has widget focus).
const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
if (focusedEditor && focusedEditor.hasTextFocus() && focusedEditor.hasModel()) {
Expand Down Expand Up @@ -282,6 +285,7 @@ if (PasteAction) {
PasteAction.addImplementation(10000, 'code-editor', (accessor: ServicesAccessor, args: unknown) => {
const logService = accessor.get(ILogService);
logService.trace('registerExecCommandImpl (addImplementation code-editor for : paste)');
performance.mark('code/registerExecCommandImpl/paste');
const codeEditorService = accessor.get(ICodeEditorService);
const clipboardService = accessor.get(IClipboardService);
const telemetryService = accessor.get(ITelemetryService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,10 @@ export class CopyPasteController extends Disposable implements IEditorContributi
const storedMetadata = metadata || InMemoryClipboardMetadataManager.INSTANCE.get(text);
id = storedMetadata?.id || null;
this._logService.trace('CopyPasteController#handleCopy for id : ', id, ' with text.length : ', text.length);
performance.mark('code/CopyPasteController/handleCopy', { detail: { id, length: text.length } });
} else {
this._logService.trace('CopyPasteController#handleCopy');
performance.mark('code/CopyPasteController/handleCopy');
Comment on lines +181 to +184
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performance mark placement may not accurately measure the intended operation. The mark is placed at the beginning of the function, before checking if the editor has text focus and before the actual clipboard operation. This means it will be marked even when the function returns early without performing any clipboard operation. Consider placing the mark after the early return checks (after line 187) to ensure it only measures actual clipboard copy operations.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

}
if (!this._editor.hasTextFocus()) {
return;
Expand Down Expand Up @@ -261,8 +263,10 @@ export class CopyPasteController extends Disposable implements IEditorContributi
const [text, metadata] = ClipboardEventUtils.getTextData(e.clipboardData);
const metadataComputed = metadata || InMemoryClipboardMetadataManager.INSTANCE.get(text);
this._logService.trace('CopyPasteController#handlePaste for id : ', metadataComputed?.id);
performance.mark('code/CopyPasteController/handlePaste', { detail: { id: metadataComputed?.id } });
} else {
this._logService.trace('CopyPasteController#handlePaste');
performance.mark('code/CopyPasteController/handlePaste');
Comment on lines +272 to +275
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performance mark placement may not accurately measure the intended operation. The mark is placed at the beginning of the function, before checking if clipboardData exists and if the editor has text focus. This means it will be marked even when the function returns early without performing any paste operation. Consider placing the mark after the early return checks (after line 272) to ensure it only measures actual paste operations.

Copilot uses AI. Check for mistakes.
}
if (!e.clipboardData || !this._editor.hasTextFocus()) {
return;
Expand Down
Loading