Skip to content

[GTK] Tree inset marks are cleared if feedback is updated during "drag over" event #3359

@ptziegler

Description

@ptziegler

Describe the bug

This issue was originally reported in GEF. During a drag & drop operation on a tree are explicitly set using setTreeInsets(...). However, those insets are immediately removed when updating the feedback field of the DropTargetEvent event.

To Reproduce

package org.eclipse.swt.tests.gtk.snippets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

public class Bug_TreeInsets {
	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());

		Tree tree = new Tree(shell, SWT.NONE);
		for (int i = 1; i <= 10; ++i) {
			TreeItem treeItem = new TreeItem(tree, SWT.NONE);
			treeItem.setText("Tree Item " + i);
		}

		final DragSourceListener dragListener = new DragSourceAdapter() {
			@Override
			public void dragSetData(DragSourceEvent event) {
				TreeItem[] selection = tree.getSelection();
				if (selection.length > 0) {
					event.data = selection[0].getText();
				}
			}
		};
		final DragSource dragSource = new DragSource(tree, DND.DROP_MOVE);
		dragSource.setTransfer(TextTransfer.getInstance());
		dragSource.addDragListener(dragListener);

		final DropTargetListener dropListener = new DropTargetAdapter() {
			@Override
			public void dragOver(DropTargetEvent event) {
				Point location = tree.toControl(event.x, event.y);
				TreeItem treeItem = tree.getItem(location);
				if (treeItem != null) {
					tree.setInsertMark(treeItem, false);
				}
				event.feedback = DND.FEEDBACK_SCROLL | DND.FEEDBACK_EXPAND;
			}

			@Override
			public void drop(DropTargetEvent event) {
				tree.setInsertMark(null, false);
			}
		};
		final DropTarget target = new DropTarget(tree, DND.DROP_MOVE);
		target.setTransfer(TextTransfer.getInstance());
		target.addDropListener(dropListener);


		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

Expected behavior

The insets should appear around the tree item the cursor is currently hovering over.

Screenshots

Here the expected behavior on Windows. On Linux, those insets don't appear. Or rather, they appear for a split-second before being removed again.

Recording.2026-06-03.210606.mp4

Environment:

  1. Select the platform(s) on which the behavior is seen:
    • All OS
    • Windows
    • Linux
    • macOS
  1. Additional OS info (e.g. OS version, Linux Desktop, etc)
  • Kubuntu 25.10
  1. JRE/JDK version

Version since

I became aware of this problem in the WindowBuilder project regarding a comment that was made back in 2011. So this problem exists since forever.

/*
 * Feature in Linux: during DND dragOver() operation the
 * DropTargetEvent.feedback resets all previous tree insert marks.
 */

Workaround (or) Additional context

The DND.FEEDBACK_INSERT_BEFORE or thee DND.FEEDBACK_INSERT_AFTER flag needs to be explicitly set.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Linux/GTKHappens on LinuxbugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions