Fix Drag n Drop behavior in Open Editors with multiple groups (#203330)

fix #203179
This commit is contained in:
Benjamin Simmonds 2024-01-24 13:49:21 +01:00 committed by GitHub
parent 5375e37481
commit c9040d0567
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 7 deletions

View file

@ -1221,7 +1221,7 @@ export class ListView<T> implements IListView<T> {
feedback = distinct(feedback).filter(i => i >= -1 && i < this.length).sort((a, b) => a - b);
feedback = feedback[0] === -1 ? [-1] : feedback;
const dragOverEffectPosition = typeof result !== 'boolean' && result.effect && result.effect.position ? result.effect.position : ListDragOverEffectPosition.Over;
let dragOverEffectPosition = typeof result !== 'boolean' && result.effect && result.effect.position ? result.effect.position : ListDragOverEffectPosition.Over;
if (equalsDragFeedback(this.currentDragFeedback, feedback) && this.currentDragFeedbackPosition === dragOverEffectPosition) {
return true;
@ -1244,6 +1244,15 @@ export class ListView<T> implements IListView<T> {
throw new Error('Can\'t use multiple feedbacks with position different than \'over\'');
}
// Make sure there is no flicker when moving between two items
// Always use the before feedback if possible
if (dragOverEffectPosition === ListDragOverEffectPosition.After) {
if (feedback[0] < this.length - 1) {
feedback[0] += 1;
dragOverEffectPosition = ListDragOverEffectPosition.Before;
}
}
for (const index of feedback) {
const item = this.items[index]!;
item.dropTarget = true;

View file

@ -979,14 +979,13 @@ export class DefaultStyleController implements IStyleController {
if (styles.listDropBetweenBackground) {
content.push(`
.monaco-list${suffix} .monaco-list-rows.drop-target-before .monaco-list-row:first-child::before,
.monaco-list${suffix} .monaco-list-row.drop-target-after + .monaco-list-row::before,
.monaco-list${suffix} .monaco-list-row.drop-target-before::before {
content: ""; position: absolute; top: 0px; left: 0px; width: 100%; height: 1px;
background-color: ${styles.listDropBetweenBackground};
}`);
content.push(`
.monaco-list${suffix} .monaco-list-rows.drop-target-after .monaco-list-row:last-child::after,
.monaco-list${suffix} .monaco-list-row:last-child.drop-target-after::after {
.monaco-list${suffix} .monaco-list-row.drop-target-after::after {
content: ""; position: absolute; bottom: 0px; left: 0px; width: 100%; height: 1px;
background-color: ${styles.listDropBetweenBackground};
}`);

View file

@ -53,6 +53,7 @@ import { Schemas } from 'vs/base/common/network';
import { extUriIgnorePathCase } from 'vs/base/common/resources';
import { ILocalizedString } from 'vs/platform/action/common/action';
import { mainWindow } from 'vs/base/browser/window';
import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView';
const $ = dom.$;
@ -727,7 +728,7 @@ class OpenEditorsDragAndDrop implements IListDragAndDrop<OpenEditor | IEditorGro
switch (targetSector) {
case ListViewTargetSector.TOP:
case ListViewTargetSector.CENTER_TOP:
dropEffectPosition = ListDragOverEffectPosition.Before; break;
dropEffectPosition = (_targetIndex === 0 && _targetElement instanceof EditorGroupView) ? ListDragOverEffectPosition.After : ListDragOverEffectPosition.Before; break;
case ListViewTargetSector.CENTER_BOTTOM:
case ListViewTargetSector.BOTTOM:
dropEffectPosition = ListDragOverEffectPosition.After; break;
@ -737,19 +738,29 @@ class OpenEditorsDragAndDrop implements IListDragAndDrop<OpenEditor | IEditorGro
}
drop(data: IDragAndDropData, targetElement: OpenEditor | IEditorGroup | undefined, _targetIndex: number, targetSector: ListViewTargetSector | undefined, originalEvent: DragEvent): void {
const group = targetElement instanceof OpenEditor ? targetElement.group : targetElement || this.editorGroupService.groups[this.editorGroupService.count - 1];
let group = targetElement instanceof OpenEditor ? targetElement.group : targetElement || this.editorGroupService.groups[this.editorGroupService.count - 1];
let targetEditorIndex = targetElement instanceof OpenEditor ? targetElement.group.getIndexOfEditor(targetElement.editor) : 0;
switch (targetSector) {
case ListViewTargetSector.TOP:
case ListViewTargetSector.CENTER_TOP:
if (targetElement instanceof EditorGroupView && group.index !== 0) {
group = this.editorGroupService.groups[group.index - 1];
targetEditorIndex = group.count;
}
break;
case ListViewTargetSector.BOTTOM:
case ListViewTargetSector.CENTER_BOTTOM:
targetEditorIndex++; break;
if (targetElement instanceof OpenEditor) {
targetEditorIndex++;
}
break;
}
if (data instanceof ElementsDragAndDropData) {
for (const oe of data.elements) {
const sourceEditorIndex = oe.group.getIndexOfEditor(oe.editor);
if (sourceEditorIndex < targetEditorIndex) {
if (oe.group === group && sourceEditorIndex < targetEditorIndex) {
targetEditorIndex--;
}
oe.group.moveEditor(oe.editor, group, { index: targetEditorIndex, preserveFocus: true });