Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandr Miloslavskiy2020-07-23 09:09:07 -0400
committerNiraj Modi2020-07-28 03:56:17 -0400
commit1cc3ed9c658d7f08bfa0f8efdc8ef54147cc2ab9 (patch)
treeb0d5fd41c0a5e13a2ee2cc769280e76e3390699e
parent5284661f3c0b3bade28ab33fbe4b6f6af8bdd9ef (diff)
downloadeclipse.platform.swt-1cc3ed9c658d7f08bfa0f8efdc8ef54147cc2ab9.tar.gz
eclipse.platform.swt-1cc3ed9c658d7f08bfa0f8efdc8ef54147cc2ab9.tar.xz
eclipse.platform.swt-1cc3ed9c658d7f08bfa0f8efdc8ef54147cc2ab9.zip
Bug 565089 - [Win32] Table.selectAll quickly reverts back to previous selection
The problem happens when clicking a selected item in unfocused Table and then doing something like Ctrl+A quickly to change Table's selection. The problem was caused by early `SetFocus()` which occurred before ListView was able to process the mouse event. This caused ListView to think that the click occurred in a focused control, which changed the way it's handled. When a selected item is clicked in focused ListView, it starts a 500ms timer (WM_TIMER with ID=42). The timer's purpose is to distinguish between double-click and click-to-edit. When timer hits, it begins inplace label editing (see `LVS_EDITLABELS`). For ListView without this style (like in SWT), it merely resets selection to the item. It seems that the problem that `SetFocus()` was solving is long gone. Afterall, this code is there since the very first SWT commit! I tried the following test: 1) Use SWT ControlExample, Table page 2) Click an item 3) Press keyboard arrow down, so that item gets input focus - it seems that Windows doesn't show focus until keyboard was used. 4) Click some other control 5) Click selected item in Table which is now not focused 6) Item shows input focus rectangle again. This means that the desired behavior, as I understand it from code comment, is working even without `SetFocus()`. Even if I'm missing something, and focus rectangle will indeed be lost sometimes, this is a very marginal feature compared to (1) the problem of resetting selection and (2) having one more hack in SWT. Also, it's closer to Windows behavior and there's no reason why SWT should have its own logic unless this gives some value to users. Change-Id: I626f2520eb5b5154b2b7b8d7825c228af1ef3945 Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java12
-rw-r--r--tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug565089_TableCtrlA.java67
2 files changed, 69 insertions, 10 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java
index 3a7e079c4c..d48bd58564 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java
@@ -3751,16 +3751,6 @@ LRESULT sendMouseDownEvent (int type, int button, int msg, long wParam, long lPa
}
/*
- * Force the table to have focus so that when the user
- * reselects the focus item, the LVIS_FOCUSED state bits
- * for the item will be set. If the user did not click on
- * an item, then set focus to the table so that it will
- * come to the front and take focus in the work around
- * below.
- */
- OS.SetFocus (handle);
-
- /*
* Feature in Windows. When the user selects outside of
* a table item, Windows deselects all the items, even
* when the table is multi-select. While not strictly
@@ -3772,6 +3762,8 @@ LRESULT sendMouseDownEvent (int type, int button, int msg, long wParam, long lPa
if (!display.captureChanged && !isDisposed ()) {
if (OS.GetCapture () != handle) OS.SetCapture (handle);
}
+ /* We're skipping default processing, but at least set focus to control */
+ OS.SetFocus (handle);
return LRESULT.ZERO;
}
}
diff --git a/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug565089_TableCtrlA.java b/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug565089_TableCtrlA.java
new file mode 100644
index 0000000000..de3d446f73
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug565089_TableCtrlA.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.win32.snippets;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class Bug565089_TableCtrlA {
+ public static int counter = 0;
+
+ public static void main(String[] args) {
+ final Display display = new Display();
+
+ final Shell shell = new Shell(display);
+ shell.setLayout(new FillLayout(SWT.VERTICAL));
+
+ final Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
+ table.setHeaderVisible(true);
+ final TableColumn column = new TableColumn(table, SWT.LEFT);
+ column.setText("Column");
+ column.setWidth(200);
+
+ for (int i = 0; i < 3; i++) {
+ final TableItem item = new TableItem(table, 0);
+ item.setText(String.valueOf(i + 1));
+ }
+
+ table.select(0);
+
+ final Text text = new Text(shell, SWT.MULTI | SWT.BORDER);
+ text.setText("- select the table row 3\n"
+ + "- click into this field\n"
+ + "- quickly click at table row 3 again and press Ctrl+A\n\n"
+ + "=> for a short time all rows look selected, but then row 3 gets selected again");
+
+ table.addListener(SWT.KeyDown, event -> {
+ if (event.keyCode == 'a' && (event.stateMask & SWT.MODIFIER_MASK) == SWT.MOD1) {
+ System.out.println("Select all");
+ counter = 0;
+ table.selectAll();
+ }
+ });
+
+ shell.setSize(400, 300);
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+}

Back to the top