| Summary: | [GTK3] shell.traverse(SWT.TRAVERSE_RETURN) selects default button too late | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Markus Keller <markus.kell.r> |
| Component: | SWT | Assignee: | Platform-SWT-Inbox <platform-swt-inbox> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | daniel_megert, eclipse.felipe, ericwill, rthakkar |
| Version: | 3.7 | Keywords: | triaged |
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Linux-GTK | ||
| Whiteboard: | stalebug | ||
In SWT we call gtk_window_activate_default() synchronously when shell.traverse(SWT.TRAVERSE_RETURN).
This delay is in GTK, we call gtk_window_activate_default() which sends the activate signal. GtkButton has a timeout of 250ms (sorry, GTK doing it) in the activate to send click (our selection comes from the click signal).
How is this for a work around:
public static void main123(String[] args) {
Display display= new Display();
Shell shell= new Shell(display);
shell.setLayout(new GridLayout(1, false));
final boolean[] clicked = new boolean [1];
Button button= new Button(shell, SWT.PUSH);
button.setText("OK");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.out.println("OK selected");
clicked[0] = true;
}
});
shell.setDefaultButton(button);
shell.pack();
shell.open();
shell.traverse(SWT.TRAVERSE_RETURN);
long time = System.currentTimeMillis();
while (!clicked[0] && (System.currentTimeMillis() - time) < 1000) {
if (!display.readAndDispatch())
display.sleep();
}
System.out.println("after TRAVERSE_RETURN");
display.dispose();
}
Yeah, we can work around it if necessary (already released a workaround in HEAD). But we can't use "display.sleep()", since that may block forever. Still reproducible, likely broken due to GTK event caching or not flushing events quickly enough. In fact, calls like gdk_flush() are completely gone on GTK4 anyway. This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
I20100817-0800 We're having trouble with an automated test (org.eclipse.ui.workbench. texteditor.tests.FindReplaceDialogTest#testShiftEnterReversesSearchDirection()), but this problem can also hurt in real world scenarios. The snippet below calls "shell.traverse(SWT.TRAVERSE_RETURN)", which will eventually send a selection event to the default button. I can accept that the event is added to the event queue and executed from there, but I would expect that flushing the event queue makes sure the selection event is sent. This works fine on Windows (XP). But on GTK, Shell#traverse(..) does not add the event to the queue, and I found no solution to make sure the traversal is done. If you set longDelays to true in the snippet, then it kinda "works", but it's not reliable. import org.eclipse.swt.*; import org.eclipse.swt.events.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; public class Snippet { public static void main(String[] args) throws InterruptedException { Display display= new Display(); Shell shell= new Shell(display); shell.setLayout(new GridLayout(1, false)); Button button= new Button(shell, SWT.PUSH); button.setText("OK"); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { System.out.println("OK selected"); } }); shell.setDefaultButton(button); shell.pack(); shell.open(); shell.traverse(SWT.TRAVERSE_RETURN); boolean longDelays= false; if (longDelays) { for (int i= 0; i < 10; i++) { while (display.readAndDispatch()) { /* flush*/ } Thread.sleep(100); } } else { while (display.readAndDispatch()) { /* flush */ } } System.out.println("after TRAVERSE_RETURN"); display.dispose(); } }