eclipse.platform.swt
eclipse.platform.swt copied to clipboard
[Win32] Showing a dialog breaks setCapture contract
Describe the bug
setCapture(true) can be used to get notified about all mouse events until setCapture(false) is invoked. This contract is broken if a dialog is shown while the user drags - the mouse-up event is not sent to the control.
To Reproduce
- launch the below snippet
- immediately start dragging by clicking (and holding) the left mouse button inside the window (a mouse-down event is logged as well as mouse-move events)
- after 2s a dialog occurs
- release the mouse and close the dialog (no mouse-up event is logged)
- try the drag again
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class DragTest {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
final Listener listener = new Listener() {
private boolean dragging;
@Override
public void handleEvent(Event event) {
if (event.type == SWT.MouseDown) {
System.out.println("mouse down " + event.button);
if (event.button == 1) {
if (dragging) {
throw new IllegalStateException();
}
dragging = true;
shell.setCapture(true);
}
}
else if (event.type == SWT.MouseUp) {
System.out.println("mouse up " + event.button);
if (event.button == 1) {
dragging = false;
shell.setCapture(false);
}
}
else if (event.type == SWT.MouseMove) {
System.out.println("mouse move " + Integer.toHexString(event.stateMask & SWT.BUTTON_MASK));
}
}
};
shell.addListener(SWT.MouseDown, listener);
shell.addListener(SWT.MouseUp, listener);
shell.addListener(SWT.MouseMove, listener);
shell.setSize(400, 300);
shell.open();
display.timerExec(2000, ()-> {
if (shell.isDisposed()) {
return;
}
final Shell shell2 = new Shell(shell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL);
shell2.setSize(200, 100);
shell2.open();
});
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Expected behavior The mouse up event is sent when releasing the mouse button (or if not possible, when showing the dialog; or allow to receive an event about showing a dialog).
Environment:
- Select the platform(s) on which the behavior is seen:
-
- [ ] All OS
-
- [x] Windows
-
- [ ] Linux
-
- [ ] macOS
- Additional OS info (e.g. OS version, Linux Desktop, etc)
Workaround (or) Additional context Maybe check the mouse move events for the mouse button to simulate a mouse-up event.
@tmssngr can you contribute a fix, please?
I doubt I'd have the required knowledge about SWT internals or Windows API to solve that correctly.