Community
Participate
Working Groups
I would like a text widget that selects all of its text when it gains focus. This doesn't appear to be currently supported by SWT.
Created attachment 6654 [details] Snippet showing problem 1.) Run snippet 2.) Select left text box with the mouse. OBSERVED RESULTS: Selection expands to all of the text, and then reduces to just the cursor. DESIRED RESULTS: Selection expands to all of the text, and stays that way.
On Windows XP, the text isn't visibly selected at all.
This is a complicated problem (from my perspective), and it may be that there is a way to do it with the existing framework. Sometimes I want focus to arrive at the widget and have all the text selected. This would happen if the user clicks in the widget, or tabs into the widget themselves. However, if I programmatically set the focus into the widget, then I don't want the text selected. (While in my case I don't ever want the text selected when focus is set programmatically, I could see a case where a developer may want to chose one or the other.)
I think the following addresses all cases well... public static final void main(final String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new RowLayout()); final Text text1 = new Text(shell, SWT.NULL); text1.setText("Set focus, but select all fails."); //$NON-NLS-1$ Listener listener = new Listener() { public void handleEvent(Event event) { text1.selectAll(); } }; text1.addListener(SWT.FocusIn, listener); text1.addListener(SWT.MouseUp, listener); final Text text2 = new Text(shell, SWT.NULL); text2.setText("Use me to change focus."); //$NON-NLS-1$ text2.setFocus(); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
Close, but no cigar. It's my fault for not specifying all the scenarios. 1.) User tabs into widget -> SELECT ALL 2.) User bring focus to widget by clicking on it -> SELECT ALL 3.) User clicks in widget after focus is already on widget -> POSITION CURSOR 4.) User brings focus to widget by clicking on it and dragging to select text (all in one action) -> SELECT TEXT 5.) Program sets focus to the widget -> DO NOT MODIFY SELECTION The snippet provided I know fails on #3, and it might fail on #4 and #5 as well.
What is the status of this bug?
Grant: this is blocking a bug that I'd like to wrap up for M6. It causes accessibility problems on the keys preference page. Any chance this will be looked at before M6?
I'll look at it with SN after the OS X ctrl+space bug.
I don't know how I didn't think of this before. You need to asyncExec text1.setSelection(...) so that it's done last. The only place that this doesn't work is occasionally on gtk (~25% of time) when the MouseUp is execut after the async'd text.setSelection(...) for some reason. So I still need to look into this event ordering problem.
So, same as comment #4, but with: text1.selectAll(); changed to ... display.asyncExec(new Runnable() { public void run() { text1.selectAll() } }); But this doesn't work on GTK due to an event ordering problem. So, will Bug 46380 have to wait until post-M6?
The snippet that I used was the one that you originally attached, with the asyncExec added, so: text1.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { display.asyncExec(new Runnable() { public void run() { text1.setSelection(0, text1.getText().length()); } }); } }); I'm looking into the gtk event ordering case, and will update here this afternoon.
My last bug for M6. I wait with bated breath.... ;)
I've been looking at this with SN, and it's a timing-related problem: gtk is sometimes deferring processing the mouse events for too long. If text1.setSelection(...) is async'd, it shouldn't be possible for it to be performed before MouseUp, since these don't run until the event queue is empty. Seeing it sometimes run before MouseUp is received shows the delay that's happening in the widget, which is removing the selection that was just made. There isn't anything we can do here. So I'm looking into ways to make the snippet work, and the only one I've found so far is to Thread.sleep(100) in the FocusIn callback before doing the asyncExec, which is a pretty bad thing...
Okay, fair enough. I would have liked to have this fixed for M6, but it can wait until M7. From the sounds of things, we wouldn't be able to get something reliable by M6 anyway.
Just looking at my own bug list, and making a peep to make sure this is still being looked at.
I've revisited this, and here's what's new: 1. After playing on gtk more, it appears that when the mouseUp comes in late it's not from being deferred in gtk, but is a direct response to the length of the user's click (the margin is pretty small here). So SWT is actually behaving correctly here, though this wasn't my previous thought. 2. SSQ pointed out something interesting, that the FocusIn/MouseUp order only makes a difference on gtk if the text at the click point is already selected, otherwise it matches the other platforms. It's not clear if this is a gtk bug or expected behaviour. Anyways, I was able to make the snippet consistently work, irrespective of the length of the user click, by doing a clearSelection() on the field when it lost focus. In some contexts this would be odd, but if the field is going to have its selection set to its full text on its next FocusIn anyways then it doesn't make a difference visually. Since I don't know your full context for this, can you try this on your end and report here whether this is an acceptable solution?
The context is the keys preference page. The user needs to be able to tab traverse from a Text field on to a Button, do some work, and then tab back to the Text field. If you play around a bit, you can probably see how a person using only the keyboard cannot enter a sequence like: "Esc Backspace 0". From the sounds of things, clearSelection() might be a workable solution. I'll play around with it now.
Okay, I can't seem to get this to work. Can you show me a simple working snippet? The set up should be a Text and Button widget -- using only the keyboard to navigate. Type some text in the widget, tab traverse out, tab traverse back. In a more complex variant of this, I'm getting all of the text in the widget selected. If I could see a simple working case, then I might be able to do something.
Sure, it's the previous snippet but with the focusOut listener added, and the second text changed to a button to more closely reflect your case. public static final void main(final String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new RowLayout()); final Text text1 = new Text(shell, SWT.NULL); text1.setText("Set focus, but select all fails."); //$NON-NLS-1$ text1.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { display.asyncExec(new Runnable() { public void run() { text1.setSelection(0, text1.getText ().length()); } }); } public void focusLost(FocusEvent e) { text1.clearSelection(); } }); final Button button = new Button(shell, SWT.PUSH); button.setText("Use me to change focus."); //$NON-NLS-1$ button.setFocus(); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
With your comments, work and some fiddling, I got something workable for my situation. Thanks.
Nothing for swt to do here, so closing report.
Is there an adequate workaround for OS X? This is currently breaking our filtered tree implementation.
(In reply to Kim Horne from comment #23) > Is there an adequate workaround for OS X? This is currently breaking our > filtered tree implementation. If this bug is still an issue, please file a separate bug against SWT-OSX/Cocoa for this issue. Marking this bug as fixed, see comments for the solution.