I'm still not aware of an official solution and I am starting to think this is a bug in GXT 2.x but I was able to come up with a workaround and am posting it here in case someone else should run into a similar problem.
For starters, the issue appears to occur in Firefox and not in IE. For Firefox, the following worked (example code snippets after the summary):
- Add a listener to the Events.OnContextMenu event on your component/container/panel/etc.
- Override the handleEvent method and add a native method to use JS to detect if the user has selected text on the screen. If text is selected, save it off to a JavaScriptObject (opaque wrapper of JS objects provided by GWT, see GWT documentation for details).
- Add a listener to the Events.Show event on the context menu object.
- Override the handleEvent method and add a native method to use JS to re-select the previous selection.
- Add a listener to the Events.Hide event on the context menu object.
- Override the handleEvent method and clear our your selection variable and then run a native method to clear out any remaining selection (if desired).
Using these steps I was able to keep the text selected when making a context menu appear in Firefox.
Example Code
(these are just sample code blocks to help better illustrate the steps - a copy/paste of this code won't give you everything you need)
PHP Code:
public class ContextMenuExample {
JavaScriptObject selection;
Menu contextMenu = new Menu();
public void buildPanelExample() {
ContentPanel panel = new ContentPanel();
panel.addListener(Events.onContextMenu, new Listener<BaseEvent>() {
if (!GXT.isIE) {
selection = findSelectedTextOnScreen();
}
});
contextMenu.addListener(Events.Show, new Listener<BaseEvent>() {
if (!GXT.isIE) {
reSelectText(selection);
}
});
contextMenu.addListener(Events.Hide, new Listener<BaseEvent>() {
if (!GXT.isIE) {
clearSelection();
}
});
private native JavaScriptObject findSelectedTextOnScreen() /*-{
// use JS method to get selected text as a range
return selectedText;
}-*/;
private native void reSelectedText(JavaScriptObject range) /*-{
// use JS method to find a range a select it
}-*/;
private native void clearSelection() /*-{
// us JS to clear any selected ranges
}-*/;
private void clearSelections() {
selection = null;
clearSelection();
}
}
}